在 ASP.NET MVC 中实现请求限制的最佳方法?

发布于 2024-07-04 17:04:59 字数 271 浏览 6 评论 0原文

我们正在尝试各种方法来限制给定时间段内的用户操作:

  • 限制问题/答案帖子
  • 限制编辑
  • 限制提要检索

目前,我们使用缓存来简单地插入记录用户活动 - 如果该记录存​​在,如果/当用户执行相同的活动时,我们会进行限制。

使用缓存会自动为我们提供陈旧数据清理和用户滑动活动窗口,但它如何扩展可能是一个问题。

还有哪些其他方法可以确保有效限制请求/用户操作(强调稳定性)?

We're experimenting with various ways to throttle user actions in a given time period:

  • Limit question/answer posts
  • Limit edits
  • Limit feed retrievals

For the time being, we're using the Cache to simply insert a record of user activity - if that record exists if/when the user does the same activity, we throttle.

Using the Cache automatically gives us stale data cleaning and sliding activity windows of users, but how it will scale could be a problem.

What are some other ways of ensuring that requests/user actions can be effectively throttled (emphasis on stability)?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

怪我入戏太深 2024-07-11 17:05:01

创建了 ThrotdlingTroll - 我对 ASP.NET Core 中的节流/速率限制的看法。

它类似于 Stefan Prodan 的 AspNetCoreRateLimit 和 ASP.NET 7 的 速率限制中间件,但具有优点:

  • 入口和出口限制(出口意味着您专门配置的 HttpClient 每秒不会发出超过 N 个请求,而是会自行生成 429 状态代码)。
  • 分布式费率计数器存储(包括但不限于Redis)。
  • 动态(重新)配置 - 允许调整限制而无需重新启动服务。
  • 将 429 状态从出口传播到入口。

在存储库中查看更多信息。

Created ThrottlingTroll - my take on throttling/rate limiting in ASP.NET Core.

It is similar to Stefan Prodan's AspNetCoreRateLimit and ASP.NET 7's Rate Limiting Middleware, but has advantages:

  • Both ingress and egress throttling (egress means that your specially configured HttpClient won't make more than N requests per second and will instead produce 429 status code by itself).
  • Distributed rate counter stores (including, but not limited to Redis).
  • Dynamic (re)configuration - allows to adjust limits without restarting the service.
  • Propagating 429 statuses from egress to ingress.

Check out more in the repo.

孤独难免 2024-07-11 17:05:01

由于这个问题的高票答案太旧了,我正在分享对我有用的最新解决方案。

我尝试使用此页面上的答案中给出的动态IP限制,但是当我尝试使用该扩展时,我发现Microsoft 已停止使用此扩展,并且在下载页面上显示已经清楚地写下了以下消息。

Microsoft has discontinued the Dynamic IP Restrictions extension and this download is no longer available.

所以我进一步研究发现,动态IP限制现在默认包含在IIS 8.0及更高版本中。 以下信息取自 Microsoft 动态 IP 限制页面。

在 IIS 8.0 中,Microsoft 扩展了内置功能,包括多项新功能:

  • 动态 IP 地址过滤,允许管理员
    将其服务器配置为阻止超过 IP 地址的访问
    指定的请求数量。
  • IP 地址过滤功能现在允许管理员指定
    IIS 阻止 IP 地址时的行为,因此来自
    恶意客户端可以被服务器中止而不是返回
    对客户端的 HTTP 403.6 响应。
  • IP 过滤现在具有代理模式,允许 IP 地址
    不仅会被 IIS 看到的客户端 IP 阻止,还会被
    x-forwarded-for HTTP 标头中收到的值

有关实施动态 IP 限制的分步说明,请访问以下链接:

https://learn.microsoft.com/en-us/iis /get-started/whats-new-in-iis-8/iis-80-dynamic-ip-address-restrictions

我希望它可以帮助遇到类似问题的人。

Since the highly voted answers to this question are too old, I am sharing the latest solution which worked for me.

I tried using the Dynamic IP restrictions as given in an answer on this page but when I tried to use that extension, I found that this extension has been discontinued by Microsoft and on the download page they have clearly written the below message.

Microsoft has discontinued the Dynamic IP Restrictions extension and this download is no longer available.

So I researched further and found that the Dynamic IP Restrictions is now by default included in IIS 8.0 and above. The below information is fetched from the Microsoft Dynamic IP Restrictions page.

In IIS 8.0, Microsoft has expanded the built-in functionality to include several new features:

  • Dynamic IP address filtering, which allows administrators to
    configure their server to block access for IP addresses that exceed
    the specified number of requests.
  • The IP address filtering features now allow administrators to specify
    the behavior when IIS blocks an IP address, so requests from
    malicious clients can be aborted by the server instead of returning
    HTTP 403.6 responses to the client.
  • IP filtering now feature a proxy mode, which allows IP addresses to
    be blocked not only by the client IP that is seen by IIS but also by
    the values that are received in the x-forwarded-for HTTP header

For step by step instructions to implement Dynamic IP Restrictions, please visit the below link:

https://learn.microsoft.com/en-us/iis/get-started/whats-new-in-iis-8/iis-80-dynamic-ip-address-restrictions

I hope it helps someone stuck in a similar problem.

萌无敌 2024-07-11 17:05:00

我们使用从此 URL http://www.codeproject.com/KB/aspnet 借用的技术/10ASPNetPerformance.aspx,不是为了限制,而是为了穷人的拒绝服务(DOS)。 这也是基于缓存的,可能与您正在做的类似。 您是否进行了限制以防止 DOS 攻击? 路由器当然可以用来减少 DOS; 您认为路由器可以处理您需要的限制吗?

We use the technique borrowed from this URL http://www.codeproject.com/KB/aspnet/10ASPNetPerformance.aspx, not for throttling, but for a poor man's Denial Of Service (D.O.S). This is also cache-based, and may be similar to what you are doing. Are you throttling to prevent D.O.S. attacks? Routers can certainly be used to reduce D.O.S; do you think a router could handle the throttling you need?

如若梦似彩虹 2024-07-11 17:05:00

我花了一些时间才找到 .NET 5+(以前称为 .NET Core)的等效项,所以这里是一个起点。

旧的缓存方式已经消失,并被 Microsoft.Extensions.Caching.MemoryIMemoryCache

我将它分开了一些,所以这就是您需要的...

缓存管理类

我已经在此处添加了整个内容,因此您可以看到 using 语句。

using Microsoft.Extensions.Caching.Memory;
using Microsoft.Extensions.Primitives;
using System;
using System.Threading;

namespace MyWebApplication
{
    public interface IThrottleCache
    {
        bool AddToCache(string key, int expriryTimeInSeconds);

        bool AddToCache<T>(string key, T value, int expriryTimeInSeconds);

        T GetFromCache<T>(string key);

        bool IsInCache(string key);
    }

    /// <summary>
    /// A caching class, based on the docs
    /// https://learn.microsoft.com/en-us/aspnet/core/performance/caching/memory?view=aspnetcore-6.0
    /// Uses the recommended library "Microsoft.Extensions.Caching.Memory"
    /// </summary>
    public class ThrottleCache : IThrottleCache
    {
        private IMemoryCache _memoryCache;

        public ThrottleCache(IMemoryCache memoryCache)
        {
            _memoryCache = memoryCache;
        }

        public bool AddToCache(string key, int expriryTimeInSeconds)
        {
            bool isSuccess = false; // Only a success if a new value gets added.

            if (!IsInCache(key))
            {
                var cancellationTokenSource = new CancellationTokenSource(
                                                     TimeSpan.FromSeconds(expriryTimeInSeconds));

                var cacheEntryOptions = new MemoryCacheEntryOptions()
                    .SetSize(1)
                    .AddExpirationToken(
                        new CancellationChangeToken(cancellationTokenSource.Token));

                _memoryCache.Set(key, DateTime.Now, cacheEntryOptions);

                isSuccess = true;
            }

            return isSuccess;
        }

        public bool AddToCache<T>(string key, T value, int expriryTimeInSeconds)
        {
            bool isSuccess = false;

            if (!IsInCache(key))
            {
                var cancellationTokenSource = new CancellationTokenSource(
                                                     TimeSpan.FromSeconds(expriryTimeInSeconds));

                var cacheEntryOptions = new MemoryCacheEntryOptions()
                    .SetAbsoluteExpiration(DateTimeOffset.Now.AddSeconds(expriryTimeInSeconds))
                    .SetSize(1)
                    .AddExpirationToken(
                        new CancellationChangeToken(cancellationTokenSource.Token));

                _memoryCache.Set<T>(key, value, cacheEntryOptions);

                isSuccess = true;
            }

            return isSuccess;
        }

        public T GetFromCache<T>(string key)
        {
            return _memoryCache.Get<T>(key);
        }

        public bool IsInCache(string key)
        {
            var item = _memoryCache.Get(key);

            return item != null;
        }
    }
}

属性本身

using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
using System;
using System.Net;

namespace MyWebApplication
{
    /// <summary>
    /// Decorates any MVC route that needs to have client requests limited by time.
    /// Based on how they throttle at stack overflow (updated for .NET5+)
    /// https://stackoverflow.com/questions/33969/best-way-to-implement-request-throttling-in-asp-net-mvc/1318059#1318059
    /// </summary>
    /// <remarks>
    /// Uses the current System.Web.Caching.Cache to store each client request to the decorated route.
    /// </remarks>
    [AttributeUsage(AttributeTargets.Method, AllowMultiple = false)]
    public class ThrottleByIPAddressAttribute : ActionFilterAttribute
    {
        /// <summary>
        /// The caching class (which will be instantiated as a singleton)
        /// </summary>
        private IThrottleCache _throttleCache;

        /// <summary>
        /// A unique name for this Throttle.
        /// </summary>
        /// <remarks>
        /// We'll be inserting a Cache record based on this name and client IP, e.g. "Name-192.168.0.1"
        /// </remarks>
        public string Name { get; set; }

        /// <summary>
        /// The number of seconds clients must wait before executing this decorated route again.
        /// </summary>
        public int Seconds { get; set; }

        /// <summary>
        /// A text message that will be sent to the client upon throttling.  You can include the token {n} to
        /// show this.Seconds in the message, e.g. "Wait {n} seconds before trying again".
        /// </summary>
        public string Message { get; set; } = "You may only perform this action every {n} seconds.";

        public override void OnActionExecuting(ActionExecutingContext c)
        {
            if(_throttleCache == null)
            {
                var cache = c.HttpContext.RequestServices.GetService(typeof(IThrottleCache));
                _throttleCache = (IThrottleCache)cache;
            }
            
            var key = string.Concat(Name, "-", c.HttpContext.Request.HttpContext.Connection.RemoteIpAddress);

            var allowExecute = _throttleCache.AddToCache(key, Seconds);

            if (!allowExecute)
            {
                if (String.IsNullOrEmpty(Message))
                    Message = "You may only perform this action every {n} seconds.";

                c.Result = new ContentResult { Content = Message.Replace("{n}", Seconds.ToString()) };
                // see 409 - http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html
                c.HttpContext.Response.StatusCode = (int)HttpStatusCode.Conflict;
            }
        }
    }
}

Startup.cs 或 Program.cs - 使用 DI 注册服务

此示例使用 Startup.cs/ConfigureServices - 将代码放在 AddControllersWithViews)。

对于在 .NET6+ 中创建的项目,我认为您应该在程序中的 builder.Services.AddRazorPages();var app = builder.Build(); 之间添加等效项。CS。 services 将是 builder.Services

如果您没有正确放置此代码,则每次检查时缓存都会为空。

// The cache for throttling must be a singleton and requires IMemoryCache to be set up.
// Place it after AddControllersWithViews or AddRazorPages as they build a cache themselves

// Need this for IThrottleCache to work.
services.AddMemoryCache(_ => new MemoryCacheOptions
{
    SizeLimit = 1024, /* TODO: CHECK THIS IS THE RIGHT SIZE FOR YOU! */
    CompactionPercentage = .3,
    ExpirationScanFrequency = TimeSpan.FromSeconds(30),
});
services.AddSingleton<IThrottleCache, ThrottleCache>();

示例用法

[HttpGet, Route("GetTest")]
[ThrottleByIPAddress(Name = "MyControllerGetTest", Seconds = 5)]
public async Task<ActionResult<string>> GetTest()
{
    return "Hello world";
}

为了帮助理解 .NET 5+ 中的缓存,我还制作了 缓存控制台演示

It took me some time to work out an equivalent for .NET 5+ (formerly .NET Core), so here's a starting point.

The old way of caching has gone and been replaced by Microsoft.Extensions.Caching.Memory with IMemoryCache.

I separated it out a bit more, so here's what you need...

The Cache Management Class

I've added the whole thing here, so you can see the using statements.

using Microsoft.Extensions.Caching.Memory;
using Microsoft.Extensions.Primitives;
using System;
using System.Threading;

namespace MyWebApplication
{
    public interface IThrottleCache
    {
        bool AddToCache(string key, int expriryTimeInSeconds);

        bool AddToCache<T>(string key, T value, int expriryTimeInSeconds);

        T GetFromCache<T>(string key);

        bool IsInCache(string key);
    }

    /// <summary>
    /// A caching class, based on the docs
    /// https://learn.microsoft.com/en-us/aspnet/core/performance/caching/memory?view=aspnetcore-6.0
    /// Uses the recommended library "Microsoft.Extensions.Caching.Memory"
    /// </summary>
    public class ThrottleCache : IThrottleCache
    {
        private IMemoryCache _memoryCache;

        public ThrottleCache(IMemoryCache memoryCache)
        {
            _memoryCache = memoryCache;
        }

        public bool AddToCache(string key, int expriryTimeInSeconds)
        {
            bool isSuccess = false; // Only a success if a new value gets added.

            if (!IsInCache(key))
            {
                var cancellationTokenSource = new CancellationTokenSource(
                                                     TimeSpan.FromSeconds(expriryTimeInSeconds));

                var cacheEntryOptions = new MemoryCacheEntryOptions()
                    .SetSize(1)
                    .AddExpirationToken(
                        new CancellationChangeToken(cancellationTokenSource.Token));

                _memoryCache.Set(key, DateTime.Now, cacheEntryOptions);

                isSuccess = true;
            }

            return isSuccess;
        }

        public bool AddToCache<T>(string key, T value, int expriryTimeInSeconds)
        {
            bool isSuccess = false;

            if (!IsInCache(key))
            {
                var cancellationTokenSource = new CancellationTokenSource(
                                                     TimeSpan.FromSeconds(expriryTimeInSeconds));

                var cacheEntryOptions = new MemoryCacheEntryOptions()
                    .SetAbsoluteExpiration(DateTimeOffset.Now.AddSeconds(expriryTimeInSeconds))
                    .SetSize(1)
                    .AddExpirationToken(
                        new CancellationChangeToken(cancellationTokenSource.Token));

                _memoryCache.Set<T>(key, value, cacheEntryOptions);

                isSuccess = true;
            }

            return isSuccess;
        }

        public T GetFromCache<T>(string key)
        {
            return _memoryCache.Get<T>(key);
        }

        public bool IsInCache(string key)
        {
            var item = _memoryCache.Get(key);

            return item != null;
        }
    }
}

The attribute itself

using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
using System;
using System.Net;

namespace MyWebApplication
{
    /// <summary>
    /// Decorates any MVC route that needs to have client requests limited by time.
    /// Based on how they throttle at stack overflow (updated for .NET5+)
    /// https://stackoverflow.com/questions/33969/best-way-to-implement-request-throttling-in-asp-net-mvc/1318059#1318059
    /// </summary>
    /// <remarks>
    /// Uses the current System.Web.Caching.Cache to store each client request to the decorated route.
    /// </remarks>
    [AttributeUsage(AttributeTargets.Method, AllowMultiple = false)]
    public class ThrottleByIPAddressAttribute : ActionFilterAttribute
    {
        /// <summary>
        /// The caching class (which will be instantiated as a singleton)
        /// </summary>
        private IThrottleCache _throttleCache;

        /// <summary>
        /// A unique name for this Throttle.
        /// </summary>
        /// <remarks>
        /// We'll be inserting a Cache record based on this name and client IP, e.g. "Name-192.168.0.1"
        /// </remarks>
        public string Name { get; set; }

        /// <summary>
        /// The number of seconds clients must wait before executing this decorated route again.
        /// </summary>
        public int Seconds { get; set; }

        /// <summary>
        /// A text message that will be sent to the client upon throttling.  You can include the token {n} to
        /// show this.Seconds in the message, e.g. "Wait {n} seconds before trying again".
        /// </summary>
        public string Message { get; set; } = "You may only perform this action every {n} seconds.";

        public override void OnActionExecuting(ActionExecutingContext c)
        {
            if(_throttleCache == null)
            {
                var cache = c.HttpContext.RequestServices.GetService(typeof(IThrottleCache));
                _throttleCache = (IThrottleCache)cache;
            }
            
            var key = string.Concat(Name, "-", c.HttpContext.Request.HttpContext.Connection.RemoteIpAddress);

            var allowExecute = _throttleCache.AddToCache(key, Seconds);

            if (!allowExecute)
            {
                if (String.IsNullOrEmpty(Message))
                    Message = "You may only perform this action every {n} seconds.";

                c.Result = new ContentResult { Content = Message.Replace("{n}", Seconds.ToString()) };
                // see 409 - http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html
                c.HttpContext.Response.StatusCode = (int)HttpStatusCode.Conflict;
            }
        }
    }
}

Startup.cs or Program.cs - Register the services with DI

This example uses Startup.cs/ConfigureServices - Put the code somewhere after AddControllersWithViews).

For a project created in .NET6+ I think you'd add the equivalent between builder.Services.AddRazorPages(); and var app = builder.Build(); in program.cs. services would be builder.Services.

If you don't get the placement of this code right, the cache will be empty every time you check it.

// The cache for throttling must be a singleton and requires IMemoryCache to be set up.
// Place it after AddControllersWithViews or AddRazorPages as they build a cache themselves

// Need this for IThrottleCache to work.
services.AddMemoryCache(_ => new MemoryCacheOptions
{
    SizeLimit = 1024, /* TODO: CHECK THIS IS THE RIGHT SIZE FOR YOU! */
    CompactionPercentage = .3,
    ExpirationScanFrequency = TimeSpan.FromSeconds(30),
});
services.AddSingleton<IThrottleCache, ThrottleCache>();

Example Usage

[HttpGet, Route("GetTest")]
[ThrottleByIPAddress(Name = "MyControllerGetTest", Seconds = 5)]
public async Task<ActionResult<string>> GetTest()
{
    return "Hello world";
}

To help understand caching in .NET 5+, I've also made a caching console demo.

凡间太子 2024-07-11 17:04:59

以下是我们过去一年在 Stack Overflow 上使用的通用版本:

/// <summary>
/// Decorates any MVC route that needs to have client requests limited by time.
/// </summary>
/// <remarks>
/// Uses the current System.Web.Caching.Cache to store each client request to the decorated route.
/// </remarks>
[AttributeUsage(AttributeTargets.Method, AllowMultiple = false)]
public class ThrottleAttribute : ActionFilterAttribute
{
    /// <summary>
    /// A unique name for this Throttle.
    /// </summary>
    /// <remarks>
    /// We'll be inserting a Cache record based on this name and client IP, e.g. "Name-192.168.0.1"
    /// </remarks>
    public string Name { get; set; }

    /// <summary>
    /// The number of seconds clients must wait before executing this decorated route again.
    /// </summary>
    public int Seconds { get; set; }

    /// <summary>
    /// A text message that will be sent to the client upon throttling.  You can include the token {n} to
    /// show this.Seconds in the message, e.g. "Wait {n} seconds before trying again".
    /// </summary>
    public string Message { get; set; }

    public override void OnActionExecuting(ActionExecutingContext c)
    {
        var key = string.Concat(Name, "-", c.HttpContext.Request.UserHostAddress);
        var allowExecute = false;

        if (HttpRuntime.Cache[key] == null)
        {
            HttpRuntime.Cache.Add(key,
                true, // is this the smallest data we can have?
                null, // no dependencies
                DateTime.Now.AddSeconds(Seconds), // absolute expiration
                Cache.NoSlidingExpiration,
                CacheItemPriority.Low,
                null); // no callback

            allowExecute = true;
        }

        if (!allowExecute)
        {
            if (String.IsNullOrEmpty(Message))
                Message = "You may only perform this action every {n} seconds.";

            c.Result = new ContentResult { Content = Message.Replace("{n}", Seconds.ToString()) };
            // see 409 - http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html
            c.HttpContext.Response.StatusCode = (int)HttpStatusCode.Conflict;
        }
    }
}

示例用法:

[Throttle(Name="TestThrottle", Message = "You must wait {n} seconds before accessing this url again.", Seconds = 5)]
public ActionResult TestThrottle()
{
    return Content("TestThrottle executed");
}

ASP.NET 缓存在这里表现出色 - 通过使用它,您可以自动清理节流条目。 随着我们的流量不断增长,我们并没有发现这是服务器上的问题。

请随意提供有关此方法的反馈; 当我们改进 Stack Overflow 时,您可以更快地获得 Ewok 修复 :)

Here's a generic version of what we've been using on Stack Overflow for the past year:

/// <summary>
/// Decorates any MVC route that needs to have client requests limited by time.
/// </summary>
/// <remarks>
/// Uses the current System.Web.Caching.Cache to store each client request to the decorated route.
/// </remarks>
[AttributeUsage(AttributeTargets.Method, AllowMultiple = false)]
public class ThrottleAttribute : ActionFilterAttribute
{
    /// <summary>
    /// A unique name for this Throttle.
    /// </summary>
    /// <remarks>
    /// We'll be inserting a Cache record based on this name and client IP, e.g. "Name-192.168.0.1"
    /// </remarks>
    public string Name { get; set; }

    /// <summary>
    /// The number of seconds clients must wait before executing this decorated route again.
    /// </summary>
    public int Seconds { get; set; }

    /// <summary>
    /// A text message that will be sent to the client upon throttling.  You can include the token {n} to
    /// show this.Seconds in the message, e.g. "Wait {n} seconds before trying again".
    /// </summary>
    public string Message { get; set; }

    public override void OnActionExecuting(ActionExecutingContext c)
    {
        var key = string.Concat(Name, "-", c.HttpContext.Request.UserHostAddress);
        var allowExecute = false;

        if (HttpRuntime.Cache[key] == null)
        {
            HttpRuntime.Cache.Add(key,
                true, // is this the smallest data we can have?
                null, // no dependencies
                DateTime.Now.AddSeconds(Seconds), // absolute expiration
                Cache.NoSlidingExpiration,
                CacheItemPriority.Low,
                null); // no callback

            allowExecute = true;
        }

        if (!allowExecute)
        {
            if (String.IsNullOrEmpty(Message))
                Message = "You may only perform this action every {n} seconds.";

            c.Result = new ContentResult { Content = Message.Replace("{n}", Seconds.ToString()) };
            // see 409 - http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html
            c.HttpContext.Response.StatusCode = (int)HttpStatusCode.Conflict;
        }
    }
}

Sample usage:

[Throttle(Name="TestThrottle", Message = "You must wait {n} seconds before accessing this url again.", Seconds = 5)]
public ActionResult TestThrottle()
{
    return Content("TestThrottle executed");
}

The ASP.NET Cache works like a champ here - by using it, you get automatic clean-up of your throttle entries. And with our growing traffic, we're not seeing that this is an issue on the server.

Feel free to give feedback on this method; when we make Stack Overflow better, you get your Ewok fix even faster :)

一绘本一梦想 2024-07-11 17:04:59

Microsoft 为 IIS 7 提供了一个新扩展,称为 IIS 7.0 的动态 IP 限制扩展 - Beta。

“IIS 7.0 的动态 IP 限制是一个模块,可提供针对 Web 服务器和网站的拒绝服务和强力攻击的保护。这种保护是通过暂时阻止 HTTP 客户端的 IP 地址来提供的,这些客户端的 IP 地址异常高。并发请求或在短时间内发出大量请求的人。”
http://learn.iis.net/page.aspx/ 548/使用动态IP限制/

示例:

如果您将条件设置为在 Y 毫秒内的 X 个请求Y 毫秒内的 X 个并发连接后阻止IP 地址将被阻止 Y 毫秒,然后请求将再次被允许。

Microsoft has a new extension for IIS 7 called Dynamic IP Restrictions Extension for IIS 7.0 - Beta.

"The Dynamic IP Restrictions for IIS 7.0 is a module that provides protection against denial of service and brute force attacks on web server and web sites. Such protection is provided by temporarily blocking IP addresses of the HTTP clients who make unusually high number of concurrent requests or who make large number of requests over small period of time."
http://learn.iis.net/page.aspx/548/using-dynamic-ip-restrictions/

Example:

If you set the criteria to block after X requests in Y milliseconds or X concurrent connections in Y milliseconds the IP address will be blocked for Y milliseconds then requests will be permitted again.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文