Kestrel ASP.NET Core 中的網頁伺服器實作
作者:Tom Dykstra、Chris Ross 和 Stephen Halter
Kestrel 是 適用于 ASP.NET Core的跨平臺 Web 服務器。 Kestrel 是 ASP.NET Core 專案範本中預設包含並啟用的網頁伺服器。
Kestrel 支援以下案例:
- HTTPS
- 除了 macOS 上的HTTP/2 (以外†)
- 用來啟用 WebSockets 的不透明升級
- Nginx 背後的高效能 Unix 通訊端
†HTTP/2 將在未來的版本中支援 macOS。
Kestrel 支援 .NET Core 支援的所有平臺和版本。
開始使用
ASP.NET 未裝載 IIS 時,預設會使用 Kestrel Core 專案範本。 在下列範本產生的 Program.cs
中,方法會在 WebApplication.CreateBuilder 內部呼叫 UseKestrel :
var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();
app.MapGet("/", () => "Hello World!");
app.Run();
如需設定 WebApplication
和 WebApplicationBuilder
的詳細資訊,請參閱 基本 API 概觀。
選擇性用戶端憑證
如需必須使用憑證保護應用程式子集之應用程式的相關資訊,請參閱 選擇性用戶端憑證。
其他資源
- 設定 ASP.NET Core Kestrel 網頁伺服器的端點
WebApplication.CreateBuilder
方法呼叫UseKestrel
的來源- 設定 ASP.NET Core Kestrel 網頁伺服器的選項
- 搭配 ASP.NET Core Kestrel Web 服務器使用 HTTP/2
- 搭配 ASP.NET Core Kestrel 網頁伺服器使用反向 Proxy 的時機
- 使用 ASP.NET Core Kestrel 網頁伺服器進行主機篩選
- 針對核心專案進行疑難排解和偵錯 ASP.NET
- 在 ASP.NET Core 中強制執行 HTTPS
- 設定 ASP.NET Core 以處理 Proxy 伺服器和負載平衡器
- RFC 7230:訊息語法和路由 (第 5.4 節:主機)
- 在 Linux 上使用 UNIX 通訊端時,不會在應用程式關機時自動刪除通訊端。 如需詳細資訊,請參閱這個 GitHub 問題 \(英文\)。
注意
自 ASP.NET Core 5.0 起, Kestrel 's libuv transport is obsolete. libuv 傳輸不會收到支援新 OS 平臺的更新,例如 Windows ARM64,未來版本將會移除。 移除對過時 UseLibuv 方法的任何呼叫,並改用 Kestrel 的預設 Socket 傳輸。
Kestrel 是 適用于 ASP.NET Core的跨平臺 Web 服務器。 Kestrel 是 ASP.NET Core 專案範本中預設包含並啟用的網頁伺服器。
Kestrel 支援以下案例:
- HTTPS
- 除了 macOS 上的HTTP/2 (以外†)
- 用來啟用 WebSockets 的不透明升級
- Nginx 背後的高效能 Unix 通訊端
†HTTP/2 將在未來的版本中支援 macOS。
Kestrel 支援 .NET Core 支援的所有平臺和版本。
開始使用
ASP.NET 未裝載 IIS 時,預設會使用 Kestrel Core 專案範本。 在 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 網頁伺服器的端點
- 設定 ASP.NET Core Kestrel 網頁伺服器的選項
- 搭配 ASP.NET Core Kestrel Web 服務器使用 HTTP/2
- 搭配 ASP.NET Core Kestrel 網頁伺服器使用反向 Proxy 的時機
- 使用 ASP.NET Core Kestrel 網頁伺服器進行主機篩選
- 針對核心專案進行疑難排解和偵錯 ASP.NET
- 在 ASP.NET Core 中強制執行 HTTPS
- 設定 ASP.NET Core 以處理 Proxy 伺服器和負載平衡器
- RFC 7230:訊息語法和路由 (第 5.4 節:主機)
- 在 Linux 上使用 UNIX 通訊端時,不會在應用程式關機時自動刪除通訊端。 如需詳細資訊,請參閱這個 GitHub 問題 \(英文\)。
注意
自 ASP.NET Core 5.0 起, Kestrel 's libuv transport is obsolete. libuv 傳輸不會收到支援新 OS 平臺的更新,例如 Windows ARM64,未來版本將會移除。 移除對過時 UseLibuv 方法的任何呼叫,並改用 Kestrel 的預設 Socket 傳輸。
Kestrel 是 適用于 ASP.NET Core的跨平臺 Web 服務器。 Kestrel 是預設包含在 ASP.NET Core 專案範本中的網頁伺服器。
Kestrel 支援以下案例:
- HTTPS
- 用來啟用 WebSockets 的不透明升級
- Nginx 背後的高效能 Unix 通訊端
- 除了 macOS 上的 HTTP/2 (以外†)
†HTTP/2 將在未來的版本中支援 macOS。
Kestrel 支援 .NET Core 支援的所有平臺和版本。
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 或更新版本連線
†HTTP/2 將在未來的版本中支援 macOS。 ≦ 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一節。
搭配反向 Proxy 使用 Kestrel 時機
Kestrel 可以單獨使用,或搭配 反向 Proxy 伺服器使用。 反向 Proxy 伺服器會接收來自網路的 HTTP 要求,並將其轉送至 Kestrel 。 反向 Proxy 伺服器的範例包括:
Kestrel 作為網際網路對向) 網頁伺服器的邊緣 (:
Kestrel 用於反向 Proxy 組態:
不論是否具有反向 Proxy 伺服器的組態,都是支援的裝載組態。
Kestrel 當做沒有反向 Proxy 伺服器的邊緣伺服器,不支援在多個進程之間共用相同的 IP 和埠。 當 設定為接聽埠時 Kestrel ,不論要求的 Host
標頭為何, Kestrel 處理該埠的所有流量。 可以共用埠的反向 Proxy 能夠將要求轉送至 Kestrel 唯一 IP 和埠。
即使不需要反向 Proxy 伺服器,使用反向 Proxy 伺服器也是不錯的選擇。
反向 Proxy:
- 可以限制它所主控之應用程式的公開介面區。
- 提供額外的組態和防禦層。
- 能夠與現有基礎結構更好地整合。
- 簡化負載平衡和安全通訊 (HTTPS) 組態。 只有反向 Proxy 伺服器需要 X.509 憑證,而且該伺服器可以使用一般 HTTP 與內部網路上的應用程式伺服器通訊。
警告
在反向 Proxy 設定中裝載需要 轉送標頭中介軟體組態。
Kestrel 在 ASP.NET Core 應用程式中
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 選項
KestrelWeb 服務器具有條件約束組態選項,在網際網路面向部署中特別有用。
請在 KestrelServerOptions 類別的 Limits 屬性上設定條件約束。 Limits
屬性會保存 KestrelServerLimits 類別的執行個體。
下列範例會使用 Microsoft.AspNetCore.Server.Kestrel.Core 命名空間;
using Microsoft.AspNetCore.Server.Kestrel.Core;
在本文稍後所示的範例中, Kestrel 會在 C# 程式碼中設定選項。 Kestrel 您也可以使用組 態提供者來設定選項。 例如,檔案組態提供者可以從 或 appsettings.{Environment}.json
檔案載入組 Kestrel 態 appsettings.json
:
{
"Kestrel": {
"Limits": {
"MaxConcurrentConnections": 100,
"MaxConcurrentUpgradedConnections": 100
},
"DisableStringReuse": true
}
}
注意
KestrelServerOptions 和 端點組態 可從組態提供者進行設定。 其餘 Kestrel 組態必須在 C# 程式碼中設定。
使用下列 其中一 種方法:
在 中設定 Kestrel
Startup.ConfigureServices
:將 的
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 核心模組後方用盡進程時,會停用要求本文限制, 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 標頭,不同之處在于它們會在傳送回應本文之後傳送。 針對 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
附加預告片。
重設
重設可讓伺服器重設具有指定錯誤碼的 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 支援。
呼叫 Listen 或 ListenUnixSocket 方法 KestrelServerOptions ,以設定 的 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
});
});
注意
呼叫之前ConfigureEndpointDefaults 呼叫 Listen 所建立的端點不會套用預設值。
ConfigureHttpsDefaults(Action<HttpsConnectionAdapterOptions>)
指定組態 Action
以針對每個 HTTPS 端點執行。 呼叫 ConfigureHttpsDefaults
多次會以最後一個指定的 Action
取代之前的 Action
。
webBuilder.ConfigureKestrel(serverOptions =>
{
serverOptions.ConfigureHttpsDefaults(listenOptions =>
{
// certificate is an X509Certificate2
listenOptions.ServerCertificate = certificate;
});
});
注意
呼叫之前ConfigureHttpsDefaults 呼叫 Listen 所建立的端點不會套用預設值。
Configure(IConfiguration)
建立組態載入器,以設定 Kestrel 接受 IConfiguration 做為輸入的 。 設定的範圍必須限定為 的 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 態。 預設的 HTTPS 應用程式設定組態架構可供 使用 Kestrel 。 設定多個端點,包括 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;
});
});
Kestrel 支援 SNI
伺服器名稱指示 (SNI) 可以用於在相同的 IP 位址和連接埠上裝載多個網域。 SNI 若要運作,用戶端會在 TLS 信號交換期間傳送安全工作階段的主機名稱給伺服器,讓伺服器可以提供正確的憑證。 用戶端在 TLS 信號交換之後的安全工作階段期間,會使用所提供的憑證與伺服器進行加密通訊。
Kestrel 透過回呼支援 SNI ServerCertificateSelector
。 回呼會針對每個連線叫用一次,允許應用程式檢查主機名稱並選取適當的憑證。
SNI 支援需要:
- 在目標 Framework
netcoreapp2.1
或更新版本上執行。 在net461
或更新版本上,會叫用回呼,但name
一律null
為 。 如果用戶端不在 TLS 信號交換中提供主機名稱參數,則name
也是null
。 - 所有網站都會在相同的 Kestrel 實例上執行。 Kestrel 不支援在沒有反向 Proxy 的情況下,跨多個實例共用 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。 使用相同的 API 來設定特定端點的其他 Kestrel 設定。
在 Windows 上,您可以使用PowerShell Cmdlet 來建立 New-SelfSignedCertificate
自我簽署憑證。 如需不支援的範例,請參閱 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 應用層通訊協定交涉中選取 HTTP/2 (ALPN) 交握;否則,連線預設為 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
預設支援 P-256 橢圓曲線 [] 的 [ TLS-ECDHE
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 前置詞有效。 Kestrel 使用 UseUrls
設定 URL 系結時不支援 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
。 使用主機篩選中介軟體進行設定 AllowedHosts
適合 Kestrel 當做公開邊緣伺服器或直接轉送標頭時 Host
。
如需轉送標頭中介軟體的詳細資訊,請參閱設定 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 通訊協定重複使用連線。 必須完全取用要求本文,才能重複使用連線。 應用程式不一定會取用要求本文,例如 POST
伺服器傳回重新導向或 404 回應的要求。 在 -redirect 案例中 POST
:
- 用戶端可能已經傳送部分
POST
資料。 - 伺服器會寫入 301 回應。
- 除非已完整讀取上一個要求本文中的資料,否則
POST
無法將連線用於新要求。 - Kestrel 會嘗試清空要求本文。 清空要求本文表示讀取和捨棄資料,而不需加以處理。
清空程式會在允許重複使用連線,以及清空任何剩餘資料所需的時間之間做出取捨:
- 清空逾時為五秒,無法設定。
- 如果在逾時之前尚未讀取 或
Transfer-Encoding
標頭所Content-Length
指定的所有資料,連線就會關閉。
有時候,您可能想要在撰寫回應之前或之後立即終止要求。 例如,用戶端可能會有嚴格的資料上限,因此限制上傳的資料可能是優先順序。 在這種情況下,若要終止要求,請從控制器、 Razor 頁面或中介軟體呼叫HttpCoNtext.Abort。
呼叫 有一些注意事項 Abort
:
- 建立新連線的速度可能會變慢且昂貴。
- 不保證用戶端在連線關閉之前已讀取回應。
- 呼叫
Abort
應該很少見,並保留給嚴重錯誤案例,而不是常見的錯誤。- 只有在需要解決特定問題時,才呼叫
Abort
。 例如,如果惡意用戶端嘗試POST
資料,或用戶端程式代碼中有造成大量或大量要求的 Bug,請呼叫Abort
。 - 請勿針對常見的錯誤狀況呼叫
Abort
,例如 HTTP 404 (找不到) 。
- 只有在需要解決特定問題時,才呼叫
在呼叫 Abort
之前呼叫HttpResponse.CompleteAsync可確保伺服器已完成寫入回應。 不過,用戶端行為無法預測,而且在中止連線之前可能不會讀取回應。
此程式與 HTTP/2 不同,因為通訊協定支援中止個別要求資料流程,而不需要關閉連線。 不適用五秒的清空逾時。 如果在完成回應之後有任何未讀取的要求本文資料,則伺服器會傳送 HTTP/2 RST 框架。 系統會忽略其他要求本文資料框架。
可能的話,用戶端最好使用 Expect:100-continue 要求標頭,並等候伺服器回應,再開始傳送要求本文。 這可讓用戶端有機會在傳送不需要的資料之前檢查回應和中止。
其他資源
- 在 Linux 上使用 UNIX 通訊端時,不會在應用程式關機時自動刪除通訊端。 如需詳細資訊,請參閱這個 GitHub 問題 \(英文\)。
- 針對核心專案進行疑難排解和偵錯 ASP.NET
- 在 ASP.NET Core 中強制執行 HTTPS
- 設定 ASP.NET Core 以處理 Proxy 伺服器和負載平衡器
- RFC 7230:訊息語法和路由 (第 5.4 節:主機)