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
安裝輪子
我的應用目前一個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!
測試輪子
我們可以通過瀏覽器或CRUL測試IP限制。為了方便測試,我暫時把1分鐘的請求頻率限制為3次。
第一次請求?https://localhost:5001/fw/某token:
會發現服務器返回的header里多了3個東西:
X-Rate-Limit-Limit: 1m,表示該限制是1分鐘以內
X-Rate-Limit-Remaining:?2,表示當前還剩2次機會
X-Rate-Limit-Reset 表示限制的重置時間
而1分鐘內第三次訪問該URL,就會觸發限制,并且返回429
更多高級配置
AspNetCoreRateLimit 還有許多更高級的用法。比如針對Client ID而不是IP做限制、白名單、分布式計數器存儲、自定義返回內容等等,可以參見官網文檔:
https://github.com/stefanprodan/AspNetCoreRateLimit/wiki/IpRateLimitMiddleware#setup
總結
以上是生活随笔為你收集整理的ASP.NET Core IP 请求频率限制的全部內容,希望文章能夠幫你解決所遇到的問題。
                            
                        - 上一篇: [译]C#中的条件断点
 - 下一篇: Exceptionless - .Net