前言
開發者都知道系統上線後才是挑戰的開始,舉例來說像是每天不斷的有爬蟲程式來抓取網站資料,或是對外開放的 API 服務遭到攻擊事件,若沒有良好的防範機制很有可能造成 Server 因為攻擊無法正常服務,甚至引起雪崩效應影響到其他系統服務,在 ASP.NET Core 中可以透過 AspNetCoreRateLimit 框架根據 Request 的 IP 或是 ClientID 來達到限制流量的效果,這篇就來簡單分享一下有關 AspNetCoreRateLimit 的安裝與基本使用,若有問題或是錯誤的地方歡迎網路的高手大大給予指導。
安裝
首先,為了方便大家更容易了解,建立一個 ASP.NET Core Web Application 應用程式來作範例,接著開啟 Nuget Package Mnage 輸入 AspNetCoreRateLimit 搜尋,安裝目前最新版的 AspNetCoreRateLimit 套件
或是透過 Nuget Package Console 輸入下列指令
使用與設定
AspNetCoreRateLimit 可以根據 IP 或是客戶 ID 來作為限速依據,也可以指定 API 中某一個對外接口或是 Http Method 分別設定其限制,兩者皆是在中間件 ( Middleware) 判斷其請求率是否達到設定的上限,分別是 IpRateLimitMiddleware 與 ClientRateLimitMiddleware ,再來決定是否要讓此 Request 繼續下一步或是返回的動作,這裡以限制 IP 為範例,安裝完後接下來就是到 start.cs 中加入下列代碼
IpRateLimiting
EnableEndpointRateLimiting : 全部套用為 false,設定為 true 則 適用於每個 endPoint 。
StackBlockedRequests : false 代表拒絕的呼叫不會加入計數器中,如果希望被拒絕的請求也要包含在計數器中則要設定為 true。
ClientIdHeader : 如果 Request 請求中的 Head 客戶 ID 與 ClientWhitelist 相同的話就不受限流設定影響。
GeneralRules : Period 設定可以包含天(d)、小時(h)、分鐘(m) 以及秒(s) 等設定值,舉例來說第一個區段設定限制為 1 秒限定 2 次,超過就會開始限流。
IpRateLimitPolicics
在 appSettings.json 加入下列設定資訊
限流規則
使用 Throttling 最重要的是了解限速的規則設定,才可以因應不同的情境調整需要的限速(流)設定,這裡直接來看一下官方說明文件提到的 Throttling 規則與 Rule,有 EndPoint Format、Period 與 Limit 等三種格式
廢話不多說直接看範例更容易了解
Sample 1 :
使用 GET 方法發送 api / Values 一秒三個 Request,前 2 個 Request 會 pass,第 3 個 request 會無法使用,如果同時間使用 PUT 方法呼叫相同 api / values 則會 pass,因為 GET 與 PUT 分別加總不會混和計算。
Sample 2 :
Sample 3 :
每小時呼叫 5 次,PASS
每小時呼叫 6 次,第六次則會正常取得正確資料
當超過我們定義的次數限制時會顯示
可以從開發者工具看到 Response 的資訊,在 Response Header 中 StatusCode 為 429,retry-after 為 9,如果不希望在 Response Header 中顯示 retry 次數,可以在 appsettings.json 設定檔中加上 DisableRateLimitHeaders 為 true 隱藏 retry 資訊,如果想要自訂 Response 時的訊息內容可以參考官網的說明 : 傳送門
開發者都知道系統上線後才是挑戰的開始,舉例來說像是每天不斷的有爬蟲程式來抓取網站資料,或是對外開放的 API 服務遭到攻擊事件,若沒有良好的防範機制很有可能造成 Server 因為攻擊無法正常服務,甚至引起雪崩效應影響到其他系統服務,在 ASP.NET Core 中可以透過 AspNetCoreRateLimit 框架根據 Request 的 IP 或是 ClientID 來達到限制流量的效果,這篇就來簡單分享一下有關 AspNetCoreRateLimit 的安裝與基本使用,若有問題或是錯誤的地方歡迎網路的高手大大給予指導。
首先,為了方便大家更容易了解,建立一個 ASP.NET Core Web Application 應用程式來作範例,接著開啟 Nuget Package Mnage 輸入 AspNetCoreRateLimit 搜尋,安裝目前最新版的 AspNetCoreRateLimit 套件
或是透過 Nuget Package Console 輸入下列指令
Install-Package AspNetCoreRateLimit -Version 3.0.5安裝完畢之後到專案檔底下確認是否有安裝成功
使用與設定
AspNetCoreRateLimit 可以根據 IP 或是客戶 ID 來作為限速依據,也可以指定 API 中某一個對外接口或是 Http Method 分別設定其限制,兩者皆是在中間件 ( Middleware) 判斷其請求率是否達到設定的上限,分別是 IpRateLimitMiddleware 與 ClientRateLimitMiddleware ,再來決定是否要讓此 Request 繼續下一步或是返回的動作,這裡以限制 IP 為範例,安裝完後接下來就是到 start.cs 中加入下列代碼
public void ConfigureServices(IServiceCollection services)
{
// 將速限計數器資料儲存在 Memory 中
services.AddMemoryCache();
// 從 appsettings.json 讀取 IpRateLimiting 設定
services.Configure<IpRateLimitOptions>(Configuration.GetSection("IpRateLimiting"));
// 從 appsettings.json 讀取 Ip Rule 設定
services.Configure<IpRateLimitPolicies>(Configuration.GetSection("IpRateLimitPolicies"));
// 注入 counter and IP Rules
services.AddSingleton<IIpPolicyStore, MemoryCacheIpPolicyStore>();
services.AddSingleton<IRateLimitCounterStore, MemoryCacheRateLimitCounterStore>();
// Add framework services.
services.AddMvc();
// the clientId/clientIp resolvers use it.
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
// Rate Limit configuration 設定
services.AddSingleton<IRateLimitConfiguration, RateLimitConfiguration>();
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
}
app.UseIpRateLimiting();
app.UseMvc();
}
代碼中的 Code 都有加上註解跟說明,這裡就不在詳細說明,在上述代碼中可以看到 Policy 與 IP Rule 都是從 appSettings.json 設定檔中取得,因此下一步就是在設定檔中加上限流相關的設定資訊IpRateLimiting
"IpRateLimiting": {
"EnableEndpointRateLimiting": false,
"StackBlockedRequests": false,
"RealIpHeader": "X-Real-IP",
"ClientIdHeader": "X-ClientId",
"HttpStatusCode": 429,
"IpWhitelist": [ "127.0.0.1", "::1/10", "192.168.0.0/24" ],
"EndpointWhitelist": [ "get:/api/license", "*:/api/status" ],
"ClientWhitelist": [ "dev-id-1", "dev-id-2" ],
"GeneralRules": [
{
"Endpoint": "*",
"Period": "1s",
"Limit": 2
},
{
"Endpoint": "*",
"Period": "15m",
"Limit": 100
},
{
"Endpoint": "*",
"Period": "12h",
"Limit": 1000
},
{
"Endpoint": "*",
"Period": "7d",
"Limit": 10000
}
]
}
IpRateLimiting 區塊設定 :
IpRateLimitPolicics
在 appSettings.json 加入下列設定資訊
"IpRateLimitPolicies": {
"IpRules": [
{
"Ip": "84.247.85.224",
"Rules": [
{
"Endpoint": "*",
"Period": "1s",
"Limit": 10
},
{
"Endpoint": "*",
"Period": "15m",
"Limit": 200
}
]
},
{
"Ip": "192.168.3.22/25",
"Rules": [
{
"Endpoint": "*",
"Period": "1s",
"Limit": 5
},
{
"Endpoint": "*",
"Period": "15m",
"Limit": 150
},
{
"Endpoint": "*",
"Period": "12h",
"Limit": 500
}
]
}
]
}
備註 : 這裡 IP 支援 IPv4 & IPv6 限流規則
使用 Throttling 最重要的是了解限速的規則設定,才可以因應不同的情境調整需要的限速(流)設定,這裡直接來看一下官方說明文件提到的 Throttling 規則與 Rule,有 EndPoint Format、Period 與 Limit 等三種格式
廢話不多說直接看範例更容易了解
Sample 1 :
{
"Endpoint": "*",
"Period": "1s",
"Limit": 2
}
目的 : 所有端點每秒鐘允許 2 次呼叫 使用 GET 方法發送 api / Values 一秒三個 Request,前 2 個 Request 會 pass,第 3 個 request 會無法使用,如果同時間使用 PUT 方法呼叫相同 api / values 則會 pass,因為 GET 與 PUT 分別加總不會混和計算。
Sample 2 :
{
"Endpoint": "*:/api/values",
"Period": "15m",
"Limit": 5
}
目的 : api / Values 用 HTTP 所有 Method 的設定為每 15 分鐘允許呼叫 5 次 Sample 3 :
{
"Endpoint": "get:/api/values",
"Period": "1h",
"Limit": 5
}
目的 : api / Values 用 HTTP GET Method 的設定為每小時允許呼叫 5 次每小時呼叫 5 次,PASS
每小時呼叫 6 次,第六次則會正常取得正確資料
當超過我們定義的次數限制時會顯示
API calls quota exceeded! maximum admitted 2 per 10s.打開 Chrome 瀏覽器透過 Network 可以看到回傳的內容細節
可以從開發者工具看到 Response 的資訊,在 Response Header 中 StatusCode 為 429,retry-after 為 9,如果不希望在 Response Header 中顯示 retry 次數,可以在 appsettings.json 設定檔中加上 DisableRateLimitHeaders 為 true 隱藏 retry 資訊,如果想要自訂 Response 時的訊息內容可以參考官網的說明 : 傳送門
感想
除了在 ASP.NET Core 有限流以外,作者也有提供 .NET Framework 版本的限流框架 WebApiThrottle,可以省下自己開發時間,也可以快速地將限流機制套用在需要的專案上,另外在本篇中提到的都是以 IP 為出發作為限制,在 AspNetCoreRateLimit 也有提供使用 Client 作為設定的機制,如有需要可以參考 ClientRateLimitMiddleware 相關說明,希望這篇介紹可以有幫助到有需要的朋友,謝謝
參考
AspNetCoreRateLimit
Throttling your API in ASP.NET
除了在 ASP.NET Core 有限流以外,作者也有提供 .NET Framework 版本的限流框架 WebApiThrottle,可以省下自己開發時間,也可以快速地將限流機制套用在需要的專案上,另外在本篇中提到的都是以 IP 為出發作為限制,在 AspNetCoreRateLimit 也有提供使用 Client 作為設定的機制,如有需要可以參考 ClientRateLimitMiddleware 相關說明,希望這篇介紹可以有幫助到有需要的朋友,謝謝
參考
AspNetCoreRateLimit
Throttling your API in ASP.NET















