ASP.NET Core IP 请求频率限制

在网站或API应用中,我们为了防止无聊人士或恶意攻击,通常希望屏蔽某一IP短时间的内高频率请求。在ASP.NET Core中,限制IP请求频率非常简单,我们来看看吧。

轮子一个

.NET Core 目前的生态发展十分迅猛,轮子也越来越多。只要轮子不爆胎,本来就不需要996的.NET开发者就能继续10 5 5!这不,为了限制IP请求频率,我找到了一个不错的轮子:

AspNetCoreRateLimit

GitHub链接:https://github.com/stefanprodan/AspNetCoreRateLimit

640?wx_fmt=gif

安装轮子

我的应用目前一个ASP.NET Core 2.2 MVC的网站,我们可以通过NuGet安装这个轮子,截至本文,它的最新版是3.0.5。

Install-Package AspNetCoreRateLimit

或 .NET Core CLI

dotnet add package AspNetCoreRateLimit

修改Startup.cs

public void ConfigureServices(IServiceCollection services)

{

// 需要从appsettings.json中加载配置

services.AddOptions();

// 存储IP计数器及配置规则

services.AddMemoryCache();


services.Configure<IpRateLimitOptions>(Configuration.GetSection("IpRateLimiting"));

services.AddSingleton<IIpPolicyStore, MemoryCacheIpPolicyStore>();

services.AddSingleton<IRateLimitCounterStore, MemoryCacheRateLimitCounterStore>();


// 按照文档,这两个是3.x版的breaking change,要加上

services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();

services.AddSingleton<IRateLimitConfiguration, RateLimitConfiguration>();

}

以及

public void Configure(IApplicationBuilder app, IHostingEnvironment env)

{

    // 注意顺序,放在 UseMvc 上面

    app.UseIpRateLimiting();

    app.UseMvc();

}

配置轮子

我的网站有一个URL(/fw/{token}),我希望限制1分钟内一个IP最多访问30次。但是对于其他URL,我并不想做任何限制。

[Route("/fw/{token}")]

public async Task<IActionResult> Forward(string token)

在 appsettings.json 里加入

"IpRateLimiting": {

  "EnableEndpointRateLimiting": true,

  "StackBlockedRequests": false,

  "RealIpHeader": "X-Real-IP",

  "ClientIdHeader": "X-ClientId",

  "HttpStatusCode": 429,

  "GeneralRules": [

    {

      "Endpoint": "*:/fw/*",

      "Period": "1m",

      "Limit": 30

    }

  ]

}

EnableEndpointRateLimiting设置为true,意思是IP限制会应用于单个配置的Endpoint上。如果是false的话,只会限制所有 * 的规则,而不能达到针对单个Endpoint配置的目的。

HttpStatusCode设置为429,意思是触发限制之后给客户端返回的HTTP状态码。

GeneralRules里我只配置了一条,针对/fw这URL的限制。其中,开头的 *: 表示任何HTTP VERB,如GET/POST,而结尾的 /* 表示需要考虑/fw后面的参数,也就是我MVC Action参数里的route参数。

针对不同token,会有不同的计数。比如IP为127.0.0.1的用户在1分钟内请求了 /fw/abcd 10次,又请求了 /fw/qwer 25次,也请求了 /fw/996icu 32次。那么对于该用户,/fw/abcd 的机会还剩下20次,/fw/qwer 的机会还剩下5次,而 /fw/996icu 在第31次请求时会返回429。

这里一定要注意,对于有参数的URL,如果不加结尾的 /* 那么轮子就会爆胎,并且把.NET程序员炸进ICU!

640?wx_fmt=gif

测试轮子

我们可以通过浏览器或CRUL测试IP限制。为了方便测试,我暂时把1分钟的请求频率限制为3次。

第一次请求 https://localhost:5001/fw/某token

640?wx_fmt=png

会发现服务器返回的header里多了3个东西:

X-Rate-Limit-Limit: 1m,表示该限制是1分钟以内

X-Rate-Limit-Remaining: 2,表示当前还剩2次机会

X-Rate-Limit-Reset 表示限制的重置时间

而1分钟内第三次访问该URL,就会触发限制,并且返回429

640?wx_fmt=png640?wx_fmt=png

更多高级配置

AspNetCoreRateLimit 还有许多更高级的用法。比如针对Client ID而不是IP做限制、白名单、分布式计数器存储、自定义返回内容等等,可以参见官网文档:

https://github.com/stefanprodan/AspNetCoreRateLimit/wiki/IpRateLimitMiddleware#setup

640?wx_fmt=jpeg

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值