歡迎光臨
每天分享高質量文章

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(Configuration.GetSection(“IpRateLimiting”));

services.AddSingleton();

services.AddSingleton();

// 按照檔案,這兩個是3.x版的breaking change,要加上

services.AddSingleton();

services.AddSingleton();

}

以及

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 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

會發現伺服器傳回的essay-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

贊(0)

分享創造快樂