ASP.NET Core IP 请求频率限制
在網(wǎng)站或API應(yīng)用中,我們?yōu)榱朔乐篃o(wú)聊人士或惡意攻擊,通常希望屏蔽某一IP短時(shí)間的內(nèi)高頻率請(qǐng)求。在ASP.NET Core中,限制IP請(qǐng)求頻率非常簡(jiǎn)單,我們來(lái)看看吧。
輪子一個(gè)
.NET Core 目前的生態(tài)發(fā)展十分迅猛,輪子也越來(lái)越多。只要輪子不爆胎,本來(lái)就不需要996的.NET開發(fā)者就能繼續(xù)10 5 5!這不,為了限制IP請(qǐng)求頻率,我找到了一個(gè)不錯(cuò)的輪子:
AspNetCoreRateLimit
GitHub鏈接:https://github.com/stefanprodan/AspNetCoreRateLimit
安裝輪子
我的應(yīng)用目前一個(gè)ASP.NET Core 2.2 MVC的網(wǎng)站,我們可以通過(guò)NuGet安裝這個(gè)輪子,截至本文,它的最新版是3.0.5。
Install-Package AspNetCoreRateLimit
或 .NET Core CLI
dotnet add package AspNetCoreRateLimit
修改Startup.cs
public void ConfigureServices(IServiceCollection services)
{
// 需要從appsettings.json中加載配置
services.AddOptions();
// 存儲(chǔ)IP計(jì)數(shù)器及配置規(guī)則
services.AddMemoryCache();
services.Configure<IpRateLimitOptions>(Configuration.GetSection("IpRateLimiting"));
services.AddSingleton<IIpPolicyStore, MemoryCacheIpPolicyStore>();
services.AddSingleton<IRateLimitCounterStore, MemoryCacheRateLimitCounterStore>();
// 按照文檔,這兩個(gè)是3.x版的breaking change,要加上
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
services.AddSingleton<IRateLimitConfiguration, RateLimitConfiguration>();
}
以及
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
? ? // 注意順序,放在 UseMvc 上面
? ? app.UseIpRateLimiting();
? ? app.UseMvc();
}
配置輪子
我的網(wǎng)站有一個(gè)URL(/fw/{token}),我希望限制1分鐘內(nèi)一個(gè)IP最多訪問30次。但是對(duì)于其他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設(shè)置為true,意思是IP限制會(huì)應(yīng)用于單個(gè)配置的Endpoint上。如果是false的話,只會(huì)限制所有 * 的規(guī)則,而不能達(dá)到針對(duì)單個(gè)Endpoint配置的目的。
HttpStatusCode設(shè)置為429,意思是觸發(fā)限制之后給客戶端返回的HTTP狀態(tài)碼。
GeneralRules里我只配置了一條,針對(duì)/fw這URL的限制。其中,開頭的 *: 表示任何HTTP VERB,如GET/POST,而結(jié)尾的 /* 表示需要考慮/fw后面的參數(shù),也就是我MVC Action參數(shù)里的route參數(shù)。
針對(duì)不同token,會(huì)有不同的計(jì)數(shù)。比如IP為127.0.0.1的用戶在1分鐘內(nèi)請(qǐng)求了 /fw/abcd 10次,又請(qǐng)求了 /fw/qwer 25次,也請(qǐng)求了 /fw/996icu 32次。那么對(duì)于該用戶,/fw/abcd 的機(jī)會(huì)還剩下20次,/fw/qwer 的機(jī)會(huì)還剩下5次,而?/fw/996icu 在第31次請(qǐng)求時(shí)會(huì)返回429。
這里一定要注意,對(duì)于有參數(shù)的URL,如果不加結(jié)尾的 /* 那么輪子就會(huì)爆胎,并且把.NET程序員炸進(jìn)ICU!
測(cè)試輪子
我們可以通過(guò)瀏覽器或CRUL測(cè)試IP限制。為了方便測(cè)試,我暫時(shí)把1分鐘的請(qǐng)求頻率限制為3次。
第一次請(qǐng)求?https://localhost:5001/fw/某token:
會(huì)發(fā)現(xiàn)服務(wù)器返回的header里多了3個(gè)東西:
X-Rate-Limit-Limit: 1m,表示該限制是1分鐘以內(nèi)
X-Rate-Limit-Remaining:?2,表示當(dāng)前還剩2次機(jī)會(huì)
X-Rate-Limit-Reset 表示限制的重置時(shí)間
而1分鐘內(nèi)第三次訪問該URL,就會(huì)觸發(fā)限制,并且返回429
更多高級(jí)配置
AspNetCoreRateLimit 還有許多更高級(jí)的用法。比如針對(duì)Client ID而不是IP做限制、白名單、分布式計(jì)數(shù)器存儲(chǔ)、自定義返回內(nèi)容等等,可以參見官網(wǎng)文檔:
https://github.com/stefanprodan/AspNetCoreRateLimit/wiki/IpRateLimitMiddleware#setup
總結(jié)
以上是生活随笔為你收集整理的ASP.NET Core IP 请求频率限制的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: [译]C#中的条件断点
- 下一篇: Exceptionless - .Net