ASP.NET Core 中的 Kestrel Web 伺服器
注意
這不是這篇文章的最新版本。 如需目前的版本,請參閱 本文的 .NET 9 版本。
警告
不再支援此版本的 ASP.NET Core。 如需詳細資訊,請參閱 .NET 和 .NET Core 支持原則。 如需目前的版本,請參閱 本文的 .NET 9 版本。
作者:Tom Dykstra、Chris Ross 和 Stephen Halter
Kestrel 是 ASP.NET Core 的跨平台 Web 伺服器。 Kestrel 是 ASP.NET Core 的建議伺服器,預設會在 ASP.NET Core 專案範本中進行設定。
Kestrel 的功能包括:
- 跨平台:Kestrel 是一個跨平台 Web 伺服器,可在 Windows、Linux 和 macOS 上執行。
- 高效能:Kestrel 已最佳化,可以有效地處理大量並行連線。
- 輕量型:為了在資源受限的環境 (例如容器和邊緣裝置) 中執行而進行的最佳化。
- 安全性強化:Kestrel 支援 HTTPS,並針對 Web 伺服器弱點進行強化。
- 廣泛的通訊協定支援:Kestrel 支援常見的 Web 通訊協定,包括:
- 與 ASP.NET Core 整合: 與其他 ASP.NET Core 元件 (例如中介軟體管道、相依性插入和組態系統) 緊密整合。
- 彈性工作負載:Kestrel 支援多種工作負載:
- ASP.NET 應用程式架構,例如最小 API、MVC、Razor Pages、SignalR、Blazor 和 gRPC。
- 使用 YARP 建置反向 Proxy。
- 擴充性:Kestrel 透過組態、中介軟體和自訂傳輸進行自訂。
- 效能診斷:Kestrel 提供內建的效能診斷功能,例如記錄和計量。
開始使用
在未使用 IIS 裝載時,ASP.NET Core 專案範本預設會使用 Kestrel。 在下列範本產生的 Program.cs
中,WebApplication.CreateBuilder 方法會在內部呼叫 UseKestrel:
var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();
app.MapGet("/", () => "Hello World!");
app.Run();
如需設定 WebApplication
和 WebApplicationBuilder
的詳細資訊,請參閱基本 API 快速參考。
選擇性用戶端憑證
如需必須使用憑證來保護應用程式子集的應用程式相關資訊,請參閱選擇性用戶端憑證。
附加偵錯工具的行為
將偵錯工具附加至 Kestrel 處理序時,不會強制執行下列逾時和速率限制:
- KestrelServerLimits.KeepAliveTimeout
- KestrelServerLimits.RequestHeadersTimeout
- KestrelServerLimits.MinRequestBodyDataRate
- KestrelServerLimits.MinResponseDataRate
- IConnectionTimeoutFeature
- IHttpMinRequestBodyDataRateFeature
- IHttpMinResponseDataRateFeature
其他資源
- 設定 ASP.NET Core Kestrel 網路伺服器的端點
- 對
UseKestrel
的WebApplication.CreateBuilder
方法呼叫的來源 - 設定 ASP.NET Core Kestrel Web 伺服器的選項
- 將 HTTP/2 與 ASP.NET Core Kestrel Web 伺服器搭配使用
- 何時將反向 Proxy 與 ASP.NET Core Kestrel Web 伺服器搭配使用
- 使用 ASP.NET Core Kestrel Web 伺服器進行主機篩選
- 針對 ASP.NET Core 專案進行疑難排解和偵錯
- 在 ASP.NET Core 中強制執行 HTTPS
- 設定 ASP.NET Core 以處理 Proxy 伺服器和負載平衡器
- RFC 9110:HTTP 語意 (第 7.2 節:主機和 :authority)
- 在 Linux 上使用 UNIX 通訊端時,在應用程式關閉時不會自動刪除通訊端。 如需詳細資訊,請參閱這個 GitHub 問題。
注意
自 ASP.NET Core 5.0 起,Kestrel 的 Libuv 傳輸已淘汰。 Libuv 傳輸不會收到支援新 OS 平台 (例如 Windows ARM64) 的更新,且在未來版本中將被移除。 移除對過時 UseLibuv 方法的所有呼叫,並改用 Kestrel 的預設 Socket 傳輸。
Kestrel 是 ASP.NET Core 的跨平台 Web 伺服器。 Kestrel 是 ASP.NET Core 專案範本中預設包含並啟用的 Web 伺服器。
Kestrel 支援下列案例:
- HTTPS
- HTTP/2 (macOS 除外†)
- 用來啟用 WebSockets 的不透明升級
- Nginx 背後的高效能 Unix 通訊端
†未來版本的 macOS 將支援 HTTP/2。
.NET Core 支援的所有平台和版本都支援 Kestrel。
開始使用
在未使用 IIS 裝載時,ASP.NET Core 專案範本預設會使用 Kestrel。 在下列範本產生的 Program.cs
中,WebApplication.CreateBuilder 方法會在內部呼叫 UseKestrel:
var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();
app.MapGet("/", () => "Hello World!");
app.Run();
如需設定 WebApplication
和 WebApplicationBuilder
的詳細資訊,請參閱基本 API 快速參考。
選擇性用戶端憑證
如需必須使用憑證來保護應用程式子集的應用程式相關資訊,請參閱選擇性用戶端憑證。
附加偵錯工具的行為
將偵錯工具附加至 Kestrel 處理序時,不會強制執行下列逾時和速率限制:
- KestrelServerLimits.KeepAliveTimeout
- KestrelServerLimits.RequestHeadersTimeout
- KestrelServerLimits.MinRequestBodyDataRate
- KestrelServerLimits.MinResponseDataRate
- IConnectionTimeoutFeature
- IHttpMinRequestBodyDataRateFeature
- IHttpMinResponseDataRateFeature
其他資源
- 設定 ASP.NET Core Kestrel 網路伺服器的端點
- 對
UseKestrel
的WebApplication.CreateBuilder
方法呼叫的來源 - 設定 ASP.NET Core Kestrel Web 伺服器的選項
- 將 HTTP/2 與 ASP.NET Core Kestrel Web 伺服器搭配使用
- 何時將反向 Proxy 與 ASP.NET Core Kestrel Web 伺服器搭配使用
- 使用 ASP.NET Core Kestrel Web 伺服器進行主機篩選
- 針對 ASP.NET Core 專案進行疑難排解和偵錯
- 在 ASP.NET Core 中強制執行 HTTPS
- 設定 ASP.NET Core 以處理 Proxy 伺服器和負載平衡器
- RFC 9110:HTTP 語意 (第 7.2 節:主機和 :authority)
- 在 Linux 上使用 UNIX 通訊端時,在應用程式關閉時不會自動刪除通訊端。 如需詳細資訊,請參閱這個 GitHub 問題。
注意
自 ASP.NET Core 5.0 起,Kestrel 的 Libuv 傳輸已淘汰。 Libuv 傳輸不會收到支援新 OS 平台 (例如 Windows ARM64) 的更新,且在未來版本中將被移除。 移除對過時 UseLibuv 方法的所有呼叫,並改用 Kestrel 的預設 Socket 傳輸。
Kestrel 是 ASP.NET Core 的跨平台 Web 伺服器。 Kestrel 是 ASP.NET Core 專案範本中預設包含並啟用的 Web 伺服器。
Kestrel 支援下列案例:
- HTTPS
- HTTP/2 (macOS 除外†)
- 用來啟用 WebSockets 的不透明升級
- Nginx 背後的高效能 Unix 通訊端
†未來版本的 macOS 將支援 HTTP/2。
.NET Core 支援的所有平台和版本都支援 Kestrel。
檢視或下載範例程式碼 \(英文\) (如何下載)
開始使用
在未使用 IIS 裝載時,ASP.NET Core 專案範本預設會使用 Kestrel。 在 Program.cs
中,ConfigureWebHostDefaults 方法會呼叫 UseKestrel:
public static void Main(string[] args)
{
CreateHostBuilder(args).Build().Run();
}
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
});
如需建置主機的詳細資訊,請參閱 ASP.NET Core 中的 .NET 泛型主機的設定主機和預設建置器設定章節。
選擇性用戶端憑證
如需必須使用憑證來保護應用程式子集的應用程式相關資訊,請參閱選擇性用戶端憑證。
其他資源
- 設定 ASP.NET Core Kestrel Web 伺服器的端點
- 設定 ASP.NET Core Kestrel Web 伺服器的選項
- 將 HTTP/2 與 ASP.NET Core Kestrel Web 伺服器搭配使用
- 何時將反向 Proxy 與 ASP.NET Core Kestrel Web 伺服器搭配使用
- 使用 ASP.NET Core Kestrel Web 伺服器進行主機篩選
- 針對 ASP.NET Core 專案進行疑難排解和偵錯
- 在 ASP.NET Core 中強制執行 HTTPS
- 設定 ASP.NET Core 以處理 Proxy 伺服器和負載平衡器
- RFC 9110:HTTP 語意 (第 7.2 節:主機和 :authority)
- 在 Linux 上使用 UNIX 通訊端時,在應用程式關閉時不會自動刪除通訊端。 如需詳細資訊,請參閱這個 GitHub 問題。
注意
自 ASP.NET Core 5.0 起,Kestrel 的 Libuv 傳輸已淘汰。 Libuv 傳輸不會收到支援新 OS 平台 (例如 Windows ARM64) 的更新,且在未來版本中將被移除。 移除對過時 UseLibuv 方法的所有呼叫,並改用 Kestrel 的預設 Socket 傳輸。
Kestrel 是 ASP.NET Core 的跨平台 Web 伺服器。 Kestrel 是 ASP.NET Core 專案範本中預設包含的 Web 伺服器。
Kestrel 支援下列案例:
- HTTPS
- 用來啟用 WebSockets 的不透明升級
- Nginx 背後的高效能 Unix 通訊端
- HTTP/2 (macOS 除外†)
†未來版本的 macOS 將支援 HTTP/2。
.NET Core 支援的所有平台和版本都支援 Kestrel。
檢視或下載範例程式碼 \(英文\) (如何下載)
HTTP/2 支援
如果符合下列基本需求,則可以針對 ASP.NET Core 應用程式使用 HTTP/2:
- 作業系統†
- Windows Server 2016/Windows 10 或更新版本‡
- Linux 含 OpenSSL 1.0.2 或更新版本 (例如 Ubuntu 16.04 或更新版本)
- 目標 Framework:.NET Core 2.2 或更新版本
- Application-Layer Protocol Negotiation (ALPN) 連線
- TLS 1.2 或更新版本連線
†未來版本的 macOS 將支援 HTTP/2。 ‡Kestrel 在 Windows Server 2012 R2 與 Windows 8.1 上對 HTTP/2 的支援有限。 支援有限的原因是這些作業系統上的支援 TLS 密碼編譯套件清單有限。 可能需要使用橢圓曲線數位簽章演算法 (ECDSA) 產生的憑證來保護 TLS 連線。
如果已建立 HTTP/2 連線,則 HttpRequest.Protocol 會報告 HTTP/2
。
從 .NET Core 3.0 開始,預設會啟用 HTTP/2。 如需組態的詳細資訊,請參閱以下章節:Kestrel 選項和 ListenOptions.Protocols。
何時將 Kestrel 與反向 Proxy 搭配使用
Kestrel 可以單獨使用,也可以與反向 Proxy 伺服器搭配使用。 反向 Proxy 伺服器會接收來自網路的 HTTP 要求,並將要求轉送到 Kestrel。 反向 Proxy 伺服器的範例包括:
Kestrel 用作 Edge (網際網路對應) 網頁伺服器:
Kestrel 用於反向 Proxy 組態:
不論是否具有反向 Proxy 伺服器,這兩種組態都是受支援的裝載組態。
Kestrel 用作沒有反向 Proxy 伺服器的 Edge Server 時,不支援在多個處理序之間共用相同的 IP 和連接埠。 不論要求的 Host
標頭為何,在 Kestrel 設定為接聽連接埠的情況下,Kestrel 都會處理該連接埠的所有流量。 可以共用連接埠的反向 Proxy 能夠用唯一的 IP 和連接埠將要求轉送到 Kestrel。
即使不需要反向 Proxy 伺服器,使用反向 Proxy 伺服器也是不錯的選擇。
反向 Proxy:
- 可以限制它所主控之應用程式的公開介面區。
- 提供額外的設定層和深度防禦網路安全性。
- 能夠與現有基礎結構更好地整合。
- 簡化負載平衡和安全通訊 (HTTPS) 組態。 只有反向 Proxy 伺服器需要 X.509 憑證,而且該伺服器可以使用一般 HTTP 與內部網路上的應用程式伺服器通訊。
警告
在反向 Proxy 組態中裝載,需要轉送標頭中介軟體組態。
ASP.NET Core 應用程式中的 Kestrel
ASP.NET Core 專案範本預設會使用 Kestrel。 在 Program.cs
中,ConfigureWebHostDefaults 方法會呼叫 UseKestrel:
public static void Main(string[] args)
{
CreateHostBuilder(args).Build().Run();
}
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
});
如需建置主機的詳細資訊,請參閱 ASP.NET Core 中的 .NET 泛型主機的設定主機和預設建置器設定章節。
若要在呼叫 ConfigureWebHostDefaults
之後提供額外的設定,請使用 ConfigureKestrel
:
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.ConfigureKestrel(serverOptions =>
{
// Set properties and call methods on options
})
.UseStartup<Startup>();
});
Kestrel 選項
Kestrel Web 伺服器所含的限制式組態選項,在網際網路對應部署方面特別有用。
請在 KestrelServerOptions 類別的 Limits 屬性上設定條件約束。 Limits
屬性會保存 KestrelServerLimits 類別的執行個體。
下列範例會使用 Microsoft.AspNetCore.Server.Kestrel.Core 命名空間;
using Microsoft.AspNetCore.Server.Kestrel.Core;
在本文稍後所示的範例中,Kestrel 選項是以 C# 程式碼設定。 您也可以使用 組態提供者 來設定 Kestrel 選項。 例如,檔案組態提供者 可以從 appsettings.json
或 appsettings.{Environment}.json
檔案載入 Kestrel 組態:
{
"Kestrel": {
"Limits": {
"MaxConcurrentConnections": 100,
"MaxConcurrentUpgradedConnections": 100
},
"DisableStringReuse": true
}
}
注意
KestrelServerOptions 和端點組態可從組態提供者進行設定。 其餘 Kestrel 組態必須以 C# 程式碼設定。
使用下列其中一個方法:
在
Startup.ConfigureServices
中設定 Kestrel:將
IConfiguration
的執行個體插入Startup
類別。 下列範例假設插入的組態已指派給Configuration
屬性。在
Startup.ConfigureServices
中,將組態的Kestrel
區段載入至 Kestrel 的組態中:using Microsoft.Extensions.Configuration public class Startup { public Startup(IConfiguration configuration) { Configuration = configuration; } public IConfiguration Configuration { get; } public void ConfigureServices(IServiceCollection services) { services.Configure<KestrelServerOptions>( Configuration.GetSection("Kestrel")); } public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { ... } }
在建置主機時設定 Kestrel:
在
Program.cs
中,將組態的Kestrel
區段載入至 Kestrel 的組態中:// using Microsoft.Extensions.DependencyInjection; public static IHostBuilder CreateHostBuilder(string[] args) => Host.CreateDefaultBuilder(args) .ConfigureServices((context, services) => { services.Configure<KestrelServerOptions>( context.Configuration.GetSection("Kestrel")); }) .ConfigureWebHostDefaults(webBuilder => { webBuilder.UseStartup<Startup>(); });
上述兩種方法都可與任何組態提供者搭配使用。
Keep-alive 逾時
取得或設定 Keep-alive 逾時 \(英文\)。 預設為 2 分鐘。
webBuilder.ConfigureKestrel(serverOptions =>
{
serverOptions.Limits.MaxConcurrentConnections = 100;
serverOptions.Limits.MaxConcurrentUpgradedConnections = 100;
serverOptions.Limits.MaxRequestBodySize = 10 * 1024;
serverOptions.Limits.MinRequestBodyDataRate =
new MinDataRate(bytesPerSecond: 100,
gracePeriod: TimeSpan.FromSeconds(10));
serverOptions.Limits.MinResponseDataRate =
new MinDataRate(bytesPerSecond: 100,
gracePeriod: TimeSpan.FromSeconds(10));
serverOptions.Listen(IPAddress.Loopback, 5000);
serverOptions.Listen(IPAddress.Loopback, 5001,
listenOptions =>
{
listenOptions.UseHttps("testCert.pfx",
"testPassword");
});
serverOptions.Limits.KeepAliveTimeout =
TimeSpan.FromMinutes(2);
serverOptions.Limits.RequestHeadersTimeout =
TimeSpan.FromMinutes(1);
})
用戶端連線數目上限
MaxConcurrentConnections MaxConcurrentUpgradedConnections
可以使用下列程式碼,針對整個應用程式設定同時開啟的 TCP 連線數目上限:
webBuilder.ConfigureKestrel(serverOptions =>
{
serverOptions.Limits.MaxConcurrentConnections = 100;
serverOptions.Limits.MaxConcurrentUpgradedConnections = 100;
serverOptions.Limits.MaxRequestBodySize = 10 * 1024;
serverOptions.Limits.MinRequestBodyDataRate =
new MinDataRate(bytesPerSecond: 100,
gracePeriod: TimeSpan.FromSeconds(10));
serverOptions.Limits.MinResponseDataRate =
new MinDataRate(bytesPerSecond: 100,
gracePeriod: TimeSpan.FromSeconds(10));
serverOptions.Listen(IPAddress.Loopback, 5000);
serverOptions.Listen(IPAddress.Loopback, 5001,
listenOptions =>
{
listenOptions.UseHttps("testCert.pfx",
"testPassword");
});
serverOptions.Limits.KeepAliveTimeout =
TimeSpan.FromMinutes(2);
serverOptions.Limits.RequestHeadersTimeout =
TimeSpan.FromMinutes(1);
})
已經從 HTTP 或 HTTPS 升級為另一個通訊協定 (例如,在 WebSocket 要求中) 的連線,有其個別限制。 升級連線之後,它不會納入 MaxConcurrentConnections
限制。
webBuilder.ConfigureKestrel(serverOptions =>
{
serverOptions.Limits.MaxConcurrentConnections = 100;
serverOptions.Limits.MaxConcurrentUpgradedConnections = 100;
serverOptions.Limits.MaxRequestBodySize = 10 * 1024;
serverOptions.Limits.MinRequestBodyDataRate =
new MinDataRate(bytesPerSecond: 100,
gracePeriod: TimeSpan.FromSeconds(10));
serverOptions.Limits.MinResponseDataRate =
new MinDataRate(bytesPerSecond: 100,
gracePeriod: TimeSpan.FromSeconds(10));
serverOptions.Listen(IPAddress.Loopback, 5000);
serverOptions.Listen(IPAddress.Loopback, 5001,
listenOptions =>
{
listenOptions.UseHttps("testCert.pfx",
"testPassword");
});
serverOptions.Limits.KeepAliveTimeout =
TimeSpan.FromMinutes(2);
serverOptions.Limits.RequestHeadersTimeout =
TimeSpan.FromMinutes(1);
})
連線數目上限預設為無限制 (null)。
要求主體大小上限
預設的要求主體大小上限是 30,000,000 個位元組,大約 28.6 MB。
若要覆寫 ASP.NET Core MVC 應用程式中的限制,建議的方式是在動作方法上使用 RequestSizeLimitAttribute屬性:
[RequestSizeLimit(100000000)]
public IActionResult MyActionMethod()
以下範例會示範如何設定應用程式、每個要求的條件約束:
webBuilder.ConfigureKestrel(serverOptions =>
{
serverOptions.Limits.MaxConcurrentConnections = 100;
serverOptions.Limits.MaxConcurrentUpgradedConnections = 100;
serverOptions.Limits.MaxRequestBodySize = 10 * 1024;
serverOptions.Limits.MinRequestBodyDataRate =
new MinDataRate(bytesPerSecond: 100,
gracePeriod: TimeSpan.FromSeconds(10));
serverOptions.Limits.MinResponseDataRate =
new MinDataRate(bytesPerSecond: 100,
gracePeriod: TimeSpan.FromSeconds(10));
serverOptions.Listen(IPAddress.Loopback, 5000);
serverOptions.Listen(IPAddress.Loopback, 5001,
listenOptions =>
{
listenOptions.UseHttps("testCert.pfx",
"testPassword");
});
serverOptions.Limits.KeepAliveTimeout =
TimeSpan.FromMinutes(2);
serverOptions.Limits.RequestHeadersTimeout =
TimeSpan.FromMinutes(1);
})
覆寫中介軟體中特定要求的設定:
app.Run(async (context) =>
{
context.Features.Get<IHttpMaxRequestBodySizeFeature>()
.MaxRequestBodySize = 10 * 1024;
var minRequestRateFeature =
context.Features.Get<IHttpMinRequestBodyDataRateFeature>();
var minResponseRateFeature =
context.Features.Get<IHttpMinResponseDataRateFeature>();
if (minRequestRateFeature != null)
{
minRequestRateFeature.MinDataRate = new MinDataRate(
bytesPerSecond: 100, gracePeriod: TimeSpan.FromSeconds(10));
}
if (minResponseRateFeature != null)
{
minResponseRateFeature.MinDataRate = new MinDataRate(
bytesPerSecond: 100, gracePeriod: TimeSpan.FromSeconds(10));
}
如果應用程式在開始讀取要求之後才設定要求的限制,則會擲回例外狀況。 有一個 IsReadOnly
屬性會指出 MaxRequestBodySize
屬性處於唯讀狀態,這表示要設定限制已經太遲。
當應用程式是在 ASP.NET Core 模組後方於處理序外執行時,Kestrel 的要求本文大小限制將被停用,因為 IIS 已經設定限制。
要求主體資料速率下限
MinRequestBodyDataRate MinResponseDataRate
Kestrel 會每秒檢查一次,以確認資料是否以指定的速率 (位元組/秒) 送達。 如果速率低於下限值,則連線會逾時。寬限期是 Kestrel 提供給用戶端的時間量,以便將資料傳送速率提高到下限值;在這段期間不會檢查速率。 寬限期可協助避免中斷連線,這是由於 TCP 緩慢啟動而一開始以低速傳送資料所造成。
預設速率下限為 240 個位元組/秒,寬限期為 5 秒。
速率下限也適用於回應。 除了屬性中具有 RequestBody
或 Response
以及介面名稱之外,用來設定要求限制和回應限制的程式碼都相同。
以下範例顯示如何在 Program.cs
中設定資料速率下限:
webBuilder.ConfigureKestrel(serverOptions =>
{
serverOptions.Limits.MaxConcurrentConnections = 100;
serverOptions.Limits.MaxConcurrentUpgradedConnections = 100;
serverOptions.Limits.MaxRequestBodySize = 10 * 1024;
serverOptions.Limits.MinRequestBodyDataRate =
new MinDataRate(bytesPerSecond: 100,
gracePeriod: TimeSpan.FromSeconds(10));
serverOptions.Limits.MinResponseDataRate =
new MinDataRate(bytesPerSecond: 100,
gracePeriod: TimeSpan.FromSeconds(10));
serverOptions.Listen(IPAddress.Loopback, 5000);
serverOptions.Listen(IPAddress.Loopback, 5001,
listenOptions =>
{
listenOptions.UseHttps("testCert.pfx",
"testPassword");
});
serverOptions.Limits.KeepAliveTimeout =
TimeSpan.FromMinutes(2);
serverOptions.Limits.RequestHeadersTimeout =
TimeSpan.FromMinutes(1);
})
覆寫中介軟體中每個要求的速率限制下限:
app.Run(async (context) =>
{
context.Features.Get<IHttpMaxRequestBodySizeFeature>()
.MaxRequestBodySize = 10 * 1024;
var minRequestRateFeature =
context.Features.Get<IHttpMinRequestBodyDataRateFeature>();
var minResponseRateFeature =
context.Features.Get<IHttpMinResponseDataRateFeature>();
if (minRequestRateFeature != null)
{
minRequestRateFeature.MinDataRate = new MinDataRate(
bytesPerSecond: 100, gracePeriod: TimeSpan.FromSeconds(10));
}
if (minResponseRateFeature != null)
{
minResponseRateFeature.MinDataRate = new MinDataRate(
bytesPerSecond: 100, gracePeriod: TimeSpan.FromSeconds(10));
}
因為通訊協定對要求多工的支援,所以 HTTP/2 一般不支援以每一要求基礎修改速率限制,進而使先前範例中所參考的 IHttpMinResponseDataRateFeature 不會出現在 HTTP/2 要求的 HttpContext.Features
中。 不過,IHttpMinRequestBodyDataRateFeature 仍存在 HTTP/2 要求的 HttpContext.Features
您仍能透過將 IHttpMinRequestBodyDataRateFeature.MinDataRate
設定為 null
(即使是針對 HTTP/2 要求),以個別要求基礎來「完全停用」讀取素率限制。 嘗試讀取 IHttpMinRequestBodyDataRateFeature.MinDataRate
或嘗試將它設定為 null
以外的值將會導致擲回 NotSupportedException
(假設要求是 HTTP/2 要求)。
透過 KestrelServerOptions.Limits
設定的全伺服器速率限制皆仍套用至 HTTP/1.x 及 HTTP/2 連線。
要求標頭逾時
取得或設定伺服器花費在接收要求標頭的時間上限。 預設為 30 秒。
webBuilder.ConfigureKestrel(serverOptions =>
{
serverOptions.Limits.MaxConcurrentConnections = 100;
serverOptions.Limits.MaxConcurrentUpgradedConnections = 100;
serverOptions.Limits.MaxRequestBodySize = 10 * 1024;
serverOptions.Limits.MinRequestBodyDataRate =
new MinDataRate(bytesPerSecond: 100,
gracePeriod: TimeSpan.FromSeconds(10));
serverOptions.Limits.MinResponseDataRate =
new MinDataRate(bytesPerSecond: 100,
gracePeriod: TimeSpan.FromSeconds(10));
serverOptions.Listen(IPAddress.Loopback, 5000);
serverOptions.Listen(IPAddress.Loopback, 5001,
listenOptions =>
{
listenOptions.UseHttps("testCert.pfx",
"testPassword");
});
serverOptions.Limits.KeepAliveTimeout =
TimeSpan.FromMinutes(2);
serverOptions.Limits.RequestHeadersTimeout =
TimeSpan.FromMinutes(1);
})
每個連線的資料流數目上限
Http2.MaxStreamsPerConnection
會限制每個 HTTP/2 連線的同時要求資料流數目。 超出的資料流會被拒絕。
webBuilder.ConfigureKestrel(serverOptions =>
{
serverOptions.Limits.Http2.MaxStreamsPerConnection = 100;
});
預設值是 100。
標頭表格大小
HPACK 解碼器可解壓縮 HTTP/2 連線的 HTTP 標頭。 Http2.HeaderTableSize
會限制 HPACK 解碼器所使用的標頭壓縮表格大小。 這個值是以八位元提供,而且必須大於零 (0)。
webBuilder.ConfigureKestrel(serverOptions =>
{
serverOptions.Limits.Http2.HeaderTableSize = 4096;
});
預設值為 4096。
框架大小上限
Http2.MaxFrameSize
表示伺服器接收或傳送的 HTTP/2 連線框架承載允許的大小上限。 這個值是以八位元提供,而且必須介於 2^14 (16,384) 到 2^24-1 (16,777,215) 之間。
webBuilder.ConfigureKestrel(serverOptions =>
{
serverOptions.Limits.Http2.MaxFrameSize = 16384;
});
預設值為 2^14 (16,384)。
要求標頭大小上限
Http2.MaxRequestHeaderFieldSize
以八位元表示要求標頭值的允許大小上限。 此限制會套用至已壓縮及未壓縮表示法中的名稱和值。 此值必須大於零 (0)。
webBuilder.ConfigureKestrel(serverOptions =>
{
serverOptions.Limits.Http2.MaxRequestHeaderFieldSize = 8192;
});
預設值為 8,192。
初始連線視窗大小
Http2.InitialConnectionWindowSize
會以位元組表示伺服器緩衝每個連線之所有要求 (資料流) 單次彙總的要求內容資料上限。 要求也皆受 Http2.InitialStreamWindowSize
所限制。 此值必須大於或等於 65,535,且小於 2^31 (2,147,483,648)。
webBuilder.ConfigureKestrel(serverOptions =>
{
serverOptions.Limits.Http2.InitialConnectionWindowSize = 131072;
});
預設值為 128 KB (131,072)。
初始資料流視窗大小
Http2.InitialStreamWindowSize
會以位元組表示每個要求 (資料流) 單次伺服器緩衝的要求內容資料上限。 要求也皆受 Http2.InitialConnectionWindowSize
所限制。 此值必須大於或等於 65,535,且小於 2^31 (2,147,483,648)。
webBuilder.ConfigureKestrel(serverOptions =>
{
serverOptions.Limits.Http2.InitialStreamWindowSize = 98304;
});
預設值為 96 KB (98,304)。
結尾
HTTP 結尾與 HTTP 標頭類似,差別在於 HTTP 結尾是在傳送回應本文之後傳送。 對於 IIS 和 HTTP.sys,僅支援 HTTP/2 回應結尾。
if (httpContext.Response.SupportsTrailers())
{
httpContext.Response.DeclareTrailer("trailername");
// Write body
httpContext.Response.WriteAsync("Hello world");
httpContext.Response.AppendTrailer("trailername", "TrailerValue");
}
在上述範例程式碼中:
SupportsTrailers
確保回應支援結尾。DeclareTrailer
將指定的結尾名稱新增至Trailer
回應標頭。 宣告回應的結尾是選用項目,但建議使用。 如果呼叫DeclareTrailer
,則必須在傳送回應標頭之前進行。AppendTrailer
會附加結尾。
Reset
重設允許伺服器重置具有指定錯誤碼的 HTTP/2 要求。 重設要求被視為已中止。
var resetFeature = httpContext.Features.Get<IHttpResetFeature>();
resetFeature.Reset(errorCode: 2);
Reset
在上述程式碼範例中,指定 INTERNAL_ERROR
錯誤碼。 如需 HTTP/2 錯誤碼的詳細資訊,請瀏覽 HTTP/2 規格錯誤碼一節。
同步 I/O
AllowSynchronousIO 控制是否允許要求與回應的同步 I/O。 預設值是 false
。
警告
大量的封鎖同步 I/O 作業會導致執行緒集區耗盡,這會使得應用程式沒有回應。 僅在使用不支援非同步 I/O 的程式庫時才啟用 AllowSynchronousIO
。
下列範例會啟用同步 I/O:
webBuilder.ConfigureKestrel(serverOptions =>
{
serverOptions.AllowSynchronousIO = true;
})
如需其他 Kestrel 選項和限制的相關資訊,請參閱:
端點設定
ASP.NET Core 預設會繫結至:
http://localhost:5000
https://localhost:5001
(當有本機開發憑證存在時)
使用以下各項指定 URL:
ASPNETCORE_URLS
環境變數。--urls
命令列引數。urls
主機組態索引鍵。UseUrls
擴充方法。
使用這些方法提供的值可以是一或多個 HTTP 和 HTTPS 端點 (如果有預設憑證可用則為 HTTPS)。 將值設定為以分號分隔的清單 (例如,"Urls": "http://localhost:8000;http://localhost:8001"
)。
如需有關這些方法的詳細資訊,請參閱伺服器 URL 和覆寫設定。
開發憑證會建立於:
- 已安裝 .NET Core SDK 時。
- dev-certs 工具用來建立憑證。
某些瀏覽器需要授與明確許可權,才能信任本機開發憑證。
專案範本會將應用程式設定為預設於 HTTPS 上執行,並包含 HTTPS 重新導向和 HSTS 支援。
請在 KestrelServerOptions 上呼叫 Listen 或 ListenUnixSocket 方法,來為 Kestrel 設定 URL 首碼和連接埠。
UseUrls
、--urls
命令列引數、urls
主機組態索引鍵和 ASPNETCORE_URLS
環境變數同樣有效,但卻有本節稍後註明的限制 (針對 HTTPS 端點組態必須有預設憑證可用)。
KestrelServerOptions
組態:
ConfigureEndpointDefaults(Action<ListenOptions>)
指定組態 Action
以針對每個指定端點執行。 呼叫 ConfigureEndpointDefaults
多次會以最後一個指定的 Action
取代之前的 Action
。
webBuilder.ConfigureKestrel(serverOptions =>
{
serverOptions.ConfigureEndpointDefaults(listenOptions =>
{
// Configure endpoint defaults
});
});
注意
透過呼叫 Listen 之前呼叫 ConfigureEndpointDefaults 所建立的端點,不會套用預設值。
ConfigureHttpsDefaults(Action<HttpsConnectionAdapterOptions>)
指定組態 Action
以針對每個 HTTPS 端點執行。 呼叫 ConfigureHttpsDefaults
多次會以最後一個指定的 Action
取代之前的 Action
。
webBuilder.ConfigureKestrel(serverOptions =>
{
serverOptions.ConfigureHttpsDefaults(listenOptions =>
{
// certificate is an X509Certificate2
listenOptions.ServerCertificate = certificate;
});
});
注意
透過呼叫 Listen 之前呼叫 ConfigureHttpsDefaults 所建立的端點,不會套用預設值。
Configure(IConfiguration)
建立組態載入器,用來設定以 IConfiguration 作為輸入的 Kestrel。 組態的範圍必須限定為 Kestrel 的組態區段。
ListenOptions.UseHttps
將 Kestrel 設定為使用 HTTPS。
ListenOptions.UseHttps
延伸模組:
UseHttps
:設定 Kestrel,以搭配使用 HTTPS 與預設憑證。 如果未設定預設憑證,會擲回例外狀況。UseHttps(string fileName)
UseHttps(string fileName, string password)
UseHttps(string fileName, string password, Action<HttpsConnectionAdapterOptions> configureOptions)
UseHttps(StoreName storeName, string subject)
UseHttps(StoreName storeName, string subject, bool allowInvalid)
UseHttps(StoreName storeName, string subject, bool allowInvalid, StoreLocation location)
UseHttps(StoreName storeName, string subject, bool allowInvalid, StoreLocation location, Action<HttpsConnectionAdapterOptions> configureOptions)
UseHttps(X509Certificate2 serverCertificate)
UseHttps(X509Certificate2 serverCertificate, Action<HttpsConnectionAdapterOptions> configureOptions)
UseHttps(Action<HttpsConnectionAdapterOptions> configureOptions)
ListenOptions.UseHttps
參數:
filename
是憑證檔案的路徑和檔案名稱,它相對於包含應用程式內容檔案的目錄。password
是存取 X.509 憑證資料所需的密碼。configureOptions
是設定HttpsConnectionAdapterOptions
的Action
。 傳回ListenOptions
。storeName
是要從中載入憑證的憑證存放區。subject
是憑證的主體名稱。allowInvalid
表示是否應該考慮無效的憑證,例如自我簽署憑證。location
是要從中載入憑證的存放區位置。serverCertificate
是 X.509 憑證。
在生產環境中,必須明確設定 HTTPS。 至少必須提供預設憑證。
支援的組態描述如下:
- 無組態
- 從組態取代預設憑證
- 變更程式碼中的預設值
無組態
Kestrel 會接聽 http://localhost:5000
和 https://localhost:5001
(如果預設憑證可用)。
從組態取代預設憑證
CreateDefaultBuilder
預設會呼叫 Configure(context.Configuration.GetSection("Kestrel"))
,以載入 Kestrel 組態。 Kestrel 可以使用預設的 HTTPS 應用程式設定組態結構描述。 設定多個端點,包括 URL 和要使用的憑證-從磁碟上的檔案,或是從憑證存放區。
在下列 appsettings.json
範例中:
- 將 AllowInvalid 設定為
true
,允許使用無效的憑證 (例如,自我簽署憑證)。 - 任何未指定憑證 (接下來範例中的 HttpsDefaultCert) 的 HTTPS 端點會回復為 [憑證]>[預設] 下定義的憑證或開發憑證。
{
"Kestrel": {
"Endpoints": {
"Http": {
"Url": "http://localhost:5000"
},
"HttpsInlineCertFile": {
"Url": "https://localhost:5001",
"Certificate": {
"Path": "<path to .pfx file>",
"Password": "<certificate password>"
}
},
"HttpsInlineCertStore": {
"Url": "https://localhost:5002",
"Certificate": {
"Subject": "<subject; required>",
"Store": "<certificate store; required>",
"Location": "<location; defaults to CurrentUser>",
"AllowInvalid": "<true or false; defaults to false>"
}
},
"HttpsDefaultCert": {
"Url": "https://localhost:5003"
},
"Https": {
"Url": "https://*:5004",
"Certificate": {
"Path": "<path to .pfx file>",
"Password": "<certificate password>"
}
}
},
"Certificates": {
"Default": {
"Path": "<path to .pfx file>",
"Password": "<certificate password>"
}
}
}
}
除了針對任何憑證節點使用 [路徑] 和 [密碼],還可以使用憑證存放區欄位指定憑證。 例如,[憑證]>[預設] 憑證可以指定為:
"Default": {
"Subject": "<subject; required>",
"Store": "<cert store; required>",
"Location": "<location; defaults to CurrentUser>",
"AllowInvalid": "<true or false; defaults to false>"
}
結構描述附註:
- 端點名稱不區分大小寫。 例如,
HTTPS
和Https
都有效。 Url
參數對每個端點而言都是必要的。 此參數的格式等同於最上層Urls
組態參數,但是它限制為單一值。- 這些端點會取代最上層
Urls
組態中定義的端點,而不是新增至其中。 透過Listen
在程式碼中定義的端點,會與組態區段中定義的端點累計。 Certificate
區段是選擇性的。 如果未指定Certificate
區段,則會使用先前案例中所定義的預設值。 如果沒有預設值可供使用,伺服器就會擲回例外狀況,且無法啟動。Certificate
區段支援 Path–Password 和 Subject–Store 憑證。- 可以用這種方式定義任何數目的端點,只要它們不會導致連接埠衝突即可。
options.Configure(context.Configuration.GetSection("{SECTION}"))
會傳回KestrelConfigurationLoader
與.Endpoint(string name, listenOptions => { })
方法,此方法可用來補充已設定的端點設定:
webBuilder.UseKestrel((context, serverOptions) =>
{
serverOptions.Configure(context.Configuration.GetSection("Kestrel"))
.Endpoint("HTTPS", listenOptions =>
{
listenOptions.HttpsOptions.SslProtocols = SslProtocols.Tls12;
});
});
您可以直接存取 KestrelServerOptions.ConfigurationLoader
,以繼續逐一查看現有的載入器,例如 CreateDefaultBuilder 所提供的載入器。
- 每個端點的組態區段可用於
Endpoint
方法的選項,因此可讀取自訂設定。 - 可以藉由使用另一個區段再次呼叫
options.Configure(context.Configuration.GetSection("{SECTION}"))
而載入多個組態。 只會使用最後一個組態,除非在先前的執行個體上已明確呼叫Load
。 中繼套件不會呼叫Load
,如此可能會取代其預設組態區段。 KestrelConfigurationLoader
會將來自KestrelServerOptions
的 API 的Listen
系列鏡像為Endpoint
多載,所以可在相同的位置設定程式碼和設定端點。 這些多載不使用名稱,並且只使用來自組態的預設組態。
變更程式碼中的預設值
ConfigureEndpointDefaults
和 ConfigureHttpsDefaults
可以用來變更 ListenOptions
和 HttpsConnectionAdapterOptions
的預設設定,包括覆寫先前案例中指定的預設憑證。 ConfigureEndpointDefaults
和 ConfigureHttpsDefaults
應該在設定任何端點之前呼叫。
webBuilder.ConfigureKestrel(serverOptions =>
{
serverOptions.ConfigureEndpointDefaults(listenOptions =>
{
// Configure endpoint defaults
});
serverOptions.ConfigureHttpsDefaults(listenOptions =>
{
listenOptions.SslProtocols = SslProtocols.Tls12;
});
});
SNI 的 Kestrel 支援
伺服器名稱指示 (SNI) 可以用於在相同的 IP 位址和連接埠上裝載多個網域。 SNI 若要運作,用戶端會在 TLS 信號交換期間傳送安全工作階段的主機名稱給伺服器,讓伺服器可以提供正確的憑證。 用戶端在 TLS 信號交換之後的安全工作階段期間,會使用所提供的憑證與伺服器進行加密通訊。
Kestrel 透過 ServerCertificateSelector
回呼來支援 SNI。 回呼會針對每個連線叫用一次,允許應用程式檢查主機名稱並選取適當的憑證。
SNI 支援需要:
- 在目標 Framework
netcoreapp2.1
或更新版本上執行。 在net461
或更新版本上會叫用回呼,但name
一律為null
。 如果用戶端不在 TLS 信號交換中提供主機名稱參數,則name
也是null
。 - 所有網站都在相同的 Kestrel 執行個體上執行。 在不使用反向 Proxy 的情況下,Kestrel 不支援跨多個執行個體共用 IP 位址和連接埠。
webBuilder.ConfigureKestrel(serverOptions =>
{
serverOptions.ListenAnyIP(5005, listenOptions =>
{
listenOptions.UseHttps(httpsOptions =>
{
var localhostCert = CertificateLoader.LoadFromStoreCert(
"localhost", "My", StoreLocation.CurrentUser,
allowInvalid: true);
var exampleCert = CertificateLoader.LoadFromStoreCert(
"example.com", "My", StoreLocation.CurrentUser,
allowInvalid: true);
var subExampleCert = CertificateLoader.LoadFromStoreCert(
"sub.example.com", "My", StoreLocation.CurrentUser,
allowInvalid: true);
var certs = new Dictionary<string, X509Certificate2>(
StringComparer.OrdinalIgnoreCase);
certs["localhost"] = localhostCert;
certs["example.com"] = exampleCert;
certs["sub.example.com"] = subExampleCert;
httpsOptions.ServerCertificateSelector = (connectionContext, name) =>
{
if (name != null && certs.TryGetValue(name, out var cert))
{
return cert;
}
return exampleCert;
};
});
});
});
連線記錄
呼叫 UseConnectionLogging,以在連線上發出位元組層級通訊的偵錯層級記錄。 連線記錄有助於對低階通訊中的問題進行疑難排解,例如 TLS 加密期間和 Proxy 後面的問題。 如果將 UseConnectionLogging
放在 UseHttps
之前,則會記錄加密流量。 如果將 UseConnectionLogging
放在 UseHttps
立後,則會記錄解密流量。
webBuilder.ConfigureKestrel(serverOptions =>
{
serverOptions.Listen(IPAddress.Any, 8000, listenOptions =>
{
listenOptions.UseConnectionLogging();
});
});
繫結至 TCP 通訊端
Listen 方法會繫結至 TCP 通訊端,而選項 Lambda 則會允許 X.509 憑證設定:
public static void Main(string[] args)
{
CreateHostBuilder(args).Build().Run();
}
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.ConfigureKestrel(serverOptions =>
{
serverOptions.Listen(IPAddress.Loopback, 5000);
serverOptions.Listen(IPAddress.Loopback, 5001,
listenOptions =>
{
listenOptions.UseHttps("testCert.pfx",
"testPassword");
});
})
.UseStartup<Startup>();
});
此範例使用 ListenOptions來為端點設定 HTTPS。 若要設定特定端點的其他 Kestrel 設定,請使用相同的 API。
在 Windows 上,可以使用 New-SelfSignedCertificate
PowerShell Cmdlet 建立自我簽署憑證。 如需不支援的範例,請參閱 UpdateIISExpressSSLForChrome.ps1
。
在 macOS、Linux 和 Windows 上,可以使用 OpenSSL \(英文\) 建立憑證。
繫結至 Unix 通訊端
請使用 ListenUnixSocket 在 Unix 通訊端上進行接聽以改善 Nginx 的效能,如此範例所示:
webBuilder.ConfigureKestrel(serverOptions =>
{
serverOptions.ListenUnixSocket("/tmp/kestrel-test.sock");
serverOptions.ListenUnixSocket("/tmp/kestrel-test.sock",
listenOptions =>
{
listenOptions.UseHttps("testCert.pfx",
"testpassword");
});
})
- 在 Nginx 組態檔中,將
server
>location
>proxy_pass
項目設定為http://unix:/tmp/{KESTREL SOCKET}:/;
。{KESTREL SOCKET}
是提供給 ListenUnixSocket 的通訊端名稱 (例如,上述範例中的kestrel-test.sock
)。 - 請確定通訊端可由 Nginx 寫入 (例如,
chmod go+w /tmp/kestrel-test.sock
)。
連接埠 0
指定連接埠號碼 0
時,Kestrel 會動態繫結至可用的連接埠。 下列範例顯示如何判斷 Kestrel 在執行階段實際上繫結至哪一個連接埠:
public void Configure(IApplicationBuilder app)
{
var serverAddressesFeature =
app.ServerFeatures.Get<IServerAddressesFeature>();
app.UseStaticFiles();
app.Run(async (context) =>
{
context.Response.ContentType = "text/html";
await context.Response
.WriteAsync("<!DOCTYPE html><html lang=\"en\"><head>" +
"<title></title></head><body><p>Hosted by Kestrel</p>");
if (serverAddressesFeature != null)
{
await context.Response
.WriteAsync("<p>Listening on the following addresses: " +
string.Join(", ", serverAddressesFeature.Addresses) +
"</p>");
}
await context.Response.WriteAsync("<p>Request URL: " +
$"{context.Request.GetDisplayUrl()}<p>");
});
}
當應用程式執行時,主控台視窗輸出會指出可以連線到應用程式的動態連接埠:
Listening on the following addresses: http://127.0.0.1:48508
限制
使用下列方法來設定端點:
- UseUrls
--urls
命令列引數urls
主機組態索引鍵ASPNETCORE_URLS
環境變數
要讓程式碼使用 Kestrel 以外的伺服器,這些方法會很有用。 不過,請注意下列限制:
- HTTPS 無法與這些方法搭配使用,除非在 HTTPS 端點設定中提供預設憑證 (例如,使用
KestrelServerOptions
設定或設定檔,如本主題稍早所示)。 - 當同時使用
Listen
和UseUrls
方法時,Listen
端點會覆寫UseUrls
端點。
IIS 端點設定
使用 IIS 時,IIS 覆寫繫結的 URL 繫結是由 Listen
或 UseUrls
設定。 如需詳細資訊,請參閱 ASP.NET Core 模組主題。
ListenOptions.Protocols
Protocols
屬性會建立在連線端點上或針對伺服器啟用的 HTTP 通訊協定 (HttpProtocols
)。 從 HttpProtocols
列舉中指派一個值給 Protocols
屬性。
HttpProtocols 列舉值 |
允許的連線通訊協定 |
---|---|
Http1 |
僅限 HTTP/1.1。 可在具有或沒有 TLS 的情況下使用。 |
Http2 |
僅限 HTTP/2。 只有在用戶端支援先備知識模式時,才可以在沒有 TLS 的情況下使用。 |
Http1AndHttp2 |
HTTP/1.1 和 HTTP/2。 HTTP/2 要求用戶端在 TLS 應用程式層通訊協定交涉 (ALPN) 交握中選取 HTTP/2;否則,連線會預設為 HTTP/1.1。 |
任何端點的預設 ListenOptions.Protocols
值為 HttpProtocols.Http1AndHttp2
。
HTTP/2 的 TLS 限制:
- TLS 1.2 版或更新版本
- 已停用重新交涉
- 已停用壓縮
- 暫時金鑰交換大小下限:
- 橢圓曲線 Diffie-Hellman (ECDHE) [RFC4492]:最小 224 個位元
- 有限欄位 Diffie-Hellman (DHE) [
TLS12
]:最小 2048 個位元
- 未禁止使用加密套件。
預設支援 TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
[TLS-ECDHE
] 與 P-256 橢圓曲線 [FIPS186
]。
下列範例會允許連接埠 8000 上的 HTTP/1.1 和 HTTP/2 連線。 這些連線使用提供的憑證受到 TLS 保護:
webBuilder.ConfigureKestrel(serverOptions =>
{
serverOptions.Listen(IPAddress.Any, 8000, listenOptions =>
{
listenOptions.UseHttps("testCert.pfx", "testPassword");
});
});
如有需要,請使用連線中介軟體來篩選個別連線上特定密碼的 TLS 交握。
下列範例會針對應用程式不支援的任何加密演算法擲回 NotSupportedException。 或者,定義 ITlsHandshakeFeature.CipherAlgorithm 並與可接受的加密套件清單比較。
CipherAlgorithmType.Null 加密演算法不使用任何加密。
// using System.Net;
// using Microsoft.AspNetCore.Connections;
webBuilder.ConfigureKestrel(serverOptions =>
{
serverOptions.Listen(IPAddress.Any, 8000, listenOptions =>
{
listenOptions.UseHttps("testCert.pfx", "testPassword");
listenOptions.UseTlsFilter();
});
});
using System;
using System.Security.Authentication;
using Microsoft.AspNetCore.Connections.Features;
namespace Microsoft.AspNetCore.Connections
{
public static class TlsFilterConnectionMiddlewareExtensions
{
public static IConnectionBuilder UseTlsFilter(
this IConnectionBuilder builder)
{
return builder.Use((connection, next) =>
{
var tlsFeature = connection.Features.Get<ITlsHandshakeFeature>();
if (tlsFeature.CipherAlgorithm == CipherAlgorithmType.Null)
{
throw new NotSupportedException("Prohibited cipher: " +
tlsFeature.CipherAlgorithm);
}
return next();
});
}
}
}
您也可以透過 IConnectionBuilder Lambda 設定連線篩選條件:
// using System;
// using System.Net;
// using System.Security.Authentication;
// using Microsoft.AspNetCore.Connections;
// using Microsoft.AspNetCore.Connections.Features;
webBuilder.ConfigureKestrel(serverOptions =>
{
serverOptions.Listen(IPAddress.Any, 8000, listenOptions =>
{
listenOptions.UseHttps("testCert.pfx", "testPassword");
listenOptions.Use((context, next) =>
{
var tlsFeature = context.Features.Get<ITlsHandshakeFeature>();
if (tlsFeature.CipherAlgorithm == CipherAlgorithmType.Null)
{
throw new NotSupportedException(
$"Prohibited cipher: {tlsFeature.CipherAlgorithm}");
}
return next();
});
});
});
在 Linux 上,CipherSuitesPolicy 可用來篩選個別連線上的 TLS 交握:
// using System.Net.Security;
// using Microsoft.AspNetCore.Hosting;
// using Microsoft.AspNetCore.Server.Kestrel.Core;
// using Microsoft.Extensions.DependencyInjection;
// using Microsoft.Extensions.Hosting;
webBuilder.ConfigureKestrel(serverOptions =>
{
serverOptions.ConfigureHttpsDefaults(listenOptions =>
{
listenOptions.OnAuthenticate = (context, sslOptions) =>
{
sslOptions.CipherSuitesPolicy = new CipherSuitesPolicy(
new[]
{
TlsCipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
TlsCipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
// ...
});
};
});
});
從設定進行通訊協定設定
CreateDefaultBuilder
預設會呼叫 serverOptions.Configure(context.Configuration.GetSection("Kestrel"))
,以載入 Kestrel 組態。
下列 appsettings.json
範例會建立 HTTP/1.1 作為所有端點的預設連線通訊協定:
{
"Kestrel": {
"EndpointDefaults": {
"Protocols": "Http1"
}
}
}
下列 appsettings.json
範例會針對特定端點建立 HTTP/1.1 連線通訊協定:
{
"Kestrel": {
"Endpoints": {
"HttpsDefaultCert": {
"Url": "https://localhost:5001",
"Protocols": "Http1"
}
}
}
}
程式碼中指定的通訊協定會覆寫設定所設定的值。
URL 前置詞
使用 UseUrls
、--urls
命令列引數、urls
主機組態索引鍵或 ASPNETCORE_URLS
環境變數時,URL 前置詞可以採用下列任一格式。
只有 HTTP URL 前置詞有效。 使用 UseUrls
設定 URL 繫結時,Kestrel 不支援 HTTPS。
IPv4 位址與連接埠號碼
http://65.55.39.10:80/
0.0.0.0
是繫結至所有 IPv4 位址的特殊情況。IPv6 位址與連接埠號碼
http://[0:0:0:0:0:ffff:4137:270a]:80/
[::]
是相當於 IPv40.0.0.0
的 IPv6 對等項目。主機名稱與連接埠號碼
http://contoso.com:80/ http://*:80/
主機名稱
*
和+
並不特殊。 無法辨識為有效 IP 位址或localhost
的任何項目,都會繫結至所有 IPv4 和 IPv6 IP。 若要在相同連接埠上將不同的主機名稱繫結至不同的 ASP.NET Core 應用程式,請使用 HTTP.sys 或反向 Proxy 伺服器 (例如 IIS、Nginx 或 Apache)。警告
在反向 Proxy 組態中裝載,需要轉送標頭中介軟體組態。
主機
localhost
名稱與連接埠號碼,或回送 IP 與連接埠號碼http://localhost:5000/ http://127.0.0.1:5000/ http://[::1]:5000/
指定
localhost
時,Kestrel 會嘗試同時繫結至 IPv4 和 IPv6 回送介面。 如果所要求的連接埠由任一回送介面上的另一個服務使用,Kestrel 即無法啟動。 如果任一回送介面因為任何其他原因 (最常見的原因是不支援 IPv6) 而無法使用,Kestrel 就會記錄警告。
主機篩選
雖然 Kestrel 根據前置詞 (例如 http://example.com:5000
) 來支援組態,但 Kestrel 大多會忽略主機名稱。 主機 localhost
是特殊情況,用來繫結到回送位址。 任何非明確 IP 位址的主機,會繫結至所有公用 IP 位址。 Host
標頭未驗證。
因應措施是使用主機篩選中介軟體。 主機篩選中介軟體是由 Microsoft.AspNetCore.HostFiltering 套件提供,該套件會隱含地提供給 ASP.NET Core 應用程式。 中介軟體是由 CreateDefaultBuilder 所新增,它會呼叫 AddHostFiltering:
public class Program
{
public static void Main(string[] args)
{
CreateWebHostBuilder(args).Build().Run();
}
public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>();
}
預設停用主機篩選中介軟體。 若要啟用中介軟體,請在 appsettings.json
/appsettings.{Environment}.json
中定義 AllowedHosts
索引鍵。 此值是以分號分隔的主機名稱清單,不含連接埠號碼:
appsettings.json
:
{
"AllowedHosts": "example.com;localhost"
}
注意
轉送的標頭中介軟體也有 AllowedHosts 選項。 在不同的案例中,轉送標頭中介軟體和主機篩選中介軟體有類似的功能。 當不保留 Host
標頭,卻使用反向 Proxy 伺服器或負載平衡器轉送要求時,可使用轉送標頭中介軟體設定 AllowedHosts
。 使用 Kestrel 作為公眾對應 Edge Server,或直接轉送 Host
標頭時,可使用主機篩選中介軟體設定 AllowedHosts
。
如需轉送標頭中介軟體的詳細資訊,請參閱設定 ASP.NET Core 以與 Proxy 伺服器和負載平衡器搭配運作。
Libuv 傳輸組態
對於需要使用 Libuv (UseLibuv) 的專案:
將
Microsoft.AspNetCore.Server.Kestrel.Transport.Libuv
套件的相依性新增至應用程式的專案檔:<PackageReference Include="Microsoft.AspNetCore.Server.Kestrel.Transport.Libuv" Version="{VERSION}" />
在
IWebHostBuilder
上呼叫 UseLibuv:public class Program { public static void Main(string[] args) { CreateHostBuilder(args).Build().Run(); } public static IHostBuilder CreateHostBuilder(string[] args) => Host.CreateDefaultBuilder(args) .ConfigureWebHostDefaults(webBuilder => { webBuilder.UseLibuv(); webBuilder.UseStartup<Startup>(); }); }
HTTP/1.1 要求清空
開啟 HTTP 連線相當耗時。 針對 HTTPS,它也需要大量資源。 因此,Kestrel 會嘗試根據 HTTP/1.1 通訊協定重複使用連線。 要求本文必須完全取用,才能重複使用連線。 應用程式不一定會取用要求本文,例如伺服器傳回重新導向或 404 回應的 POST
要求。 在 POST
重新導向案例中:
- 用戶端可能已經傳送部分
POST
資料。 - 伺服器會寫入 301 回應。
- 在完整讀取先前要求本文中的
POST
資料之前,無法將連線用於新的要求。 - Kestrel 會嘗試清空要求本文。 清空要求本文表示在不處理資料的情況下讀取和捨棄資料。
清空流程會衡量允許重複使用連線的必要性與清空剩餘資料所需的時間,並在兩者之間做出取捨:
- 清空有五秒的逾時限制,您無法設定這個時間。
- 如果在逾時之前尚未讀取
Content-Length
或Transfer-Encoding
標頭指定的所有資料,連線就會關閉。
有時,您可能希望在寫入回應之前或之後,立即終止要求。 例如,用戶端可能具有限制性的資料上限,因此可能會優先限制上傳的資料。 在這種情況下,若要終止要求,請從控制器、Razor Page 或中介軟體中呼叫 HttpCoNtext.Abort。
呼叫 Abort
有一些注意事項:
- 建立新連線可能既緩慢又很昂貴。
- 無法保證用戶端在連線關閉之前已讀取回應。
- 呼叫
Abort
的情況應該很少見,並且保留用於嚴重的錯誤案例,而不是常見的錯誤。- 只有在需要解決特定問題時,才呼叫
Abort
。 例如,如果惡意用戶端嘗試存取POST
資料,或用戶端程式碼中存在造成大規模或大量要求的錯誤,請呼叫Abort
。 - 請不要因為常見的錯誤情況而呼叫
Abort
:例如 HTTP 404 (找不到)。
- 只有在需要解決特定問題時,才呼叫
呼叫 Abort
之前呼叫 HttpResponse.CompleteAsync,可確保伺服器已完成寫入回應。 不過,用戶端行為是無法預測的,它們在連線中止之前可能並未讀取回應。
此流程與 HTTP/2 不同,因為該通訊協定支援在不關閉連線的情況下中止個別要求資料流。 五秒清空逾時並不適用。 如果在完成回應之後有任何未讀取的要求本文資料,則伺服器會傳送 HTTP/2 RST 框架。 系統會忽略其他要求本文資料框架。
可能的話,用戶端最好使用 Expect:100-continue 要求標頭,並等待伺服器回應,然後再開始傳送要求本文。 這使得用戶端有機會檢查回應,並在傳送不需要的資料之前中止。
其他資源
- 在 Linux 上使用 UNIX 通訊端時,在應用程式關閉時不會自動刪除通訊端。 如需詳細資訊,請參閱這個 GitHub 問題。
- 針對 ASP.NET Core 專案進行疑難排解和偵錯
- 在 ASP.NET Core 中強制執行 HTTPS
- 設定 ASP.NET Core 以處理 Proxy 伺服器和負載平衡器
- RFC 9110:HTTP 語意 (第 7.2 節:主機和 :authority)