ASP.NET Core 託管和部署(一)【Kestrel】
ASP.NET Core 中的 Kestrel Web 伺服器實現
ASP.NET Core 中的 Kestrel Web 伺服器實現
Kestrel
是一個跨平臺的適用於 ASP.NET Core
的 Web 伺服器。 Kestrel
是 Web 伺服器,預設包括在 ASP.NET Core
專案模板中。
Kestrel
支援以下方案:
HTTPS
- 用於啟用
WebSocket
的不透明升級 - 用於獲得
Nginx
高效能的 Unix 套接字 HTTP/2
(除 macOS以外)
macOS
的未來版本將支援HTTP/2。
.NET Core 支援的所有平臺和版本均支援 Kestrel
。
HTTP/2
支援
如果滿足以下基本要求,將為 ASP.NET Core
應用提供 HTTP/2
:
- 作業系統
Windows Server 2016/Windows 10
或更高版本- 具有
OpenSSL 1.0.2
或更高版本的Linux
(例如,Ubuntu 16.04 或更高版本)
- 目標框架:
.NET Core 2.2
或更高版本 - 應用程式層協議協商 (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
。
預設情況下,禁用 HTTP/2
。 有關配置的詳細資訊,請參閱 Kestrel
選項和 ListenOptions.Protocols
部分。
何時結合使用 Kestrel
和反向代理
可以單獨使用 Kestrel
,也可以將其與反向代理伺服器(如 Internet Information Services
(IIS)、Nginx
或 Apache
)結合使用。 反向代理伺服器接收來自網路的 HTTP
請求,並將這些請求轉發到 Kestrel
。
Kestrel 用作邊緣(面向 Internet)Web 伺服器:
Kestrel 用於反向代理配置:
無論配置是否使用反向代理伺服器——,都是從 Internet
接收請求的 ASP.NET Core 2.1
或更高版本應用的支援託管配置。
在沒有反向代理伺服器的情況下用作邊緣伺服器的 Kestrel
不支援在多個程式間共享相同的 IP 和埠。 如果將 Kestrel
配置為偵聽某個埠,Kestrel
會處理該埠的所有流量(無視請求的 Host
標頭)。 可以共享埠的反向代理能在唯一的 IP
和埠上將請求轉發至 Kestrel
。
即使不需要反向代理伺服器,使用反向代理伺服器可能也是個不錯的選擇。
反向代理:
- 可以限制所承載的應用中的公開的公共外圍應用。
- 提供額外的配置和防護層。
- 可以更好地與現有基礎結構整合。
- 簡化了負載均和和安全通訊 (
HTTPS
) 配置。 僅反向代理伺服器需要X.509
證書,並且該伺服器可使用普通 HTTP在內部網路上與應用伺服器通訊。
警告
採用反向代理配置進行託管需要主機篩選。
如何在 ASP.NET Core
應用中使用Kestrel
Microsoft.AspNetCore.App
元包中包括 Microsoft.AspNetCore.Server.Kestrel
包(ASP.NET Core 2.1
或更高版本)。
預設情況下,ASP.NET Core
專案模板使用 Kestrel
。 在 Program.cs
中,模板程式碼呼叫 CreateDefaultBuilder
,後者在後臺呼叫 UseKestrel
。
public static void Main(string[] args)
{
CreateWebHostBuilder(args).Build().Run();
}
public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>();
若要在呼叫 CreateDefaultBuilder
後提供其他配置,請使用 ConfigureKestrel
:
public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>()
.ConfigureKestrel((context, options) =>
{
// Set properties and call methods on options
});
如果應用未呼叫 CreateDefaultBuilder
來設定主機,請在呼叫 ConfigureKestrel
之前先呼叫 UseKestrel
:
public static void Main(string[] args)
{
var host = new WebHostBuilder()
.UseContentRoot(Directory.GetCurrentDirectory())
.UseKestrel()
.UseIISIntegration()
.UseStartup<Startup>()
.ConfigureKestrel((context, options) =>
{
// Set properties and call methods on options
})
.Build();
host.Run();
}
Kestrel
選項
Kestrel Web
伺服器具有約束配置選項,這些選項在面向 Internet
的部署中尤其有用。
可在 KestrelServerOptions
類的 Limits
屬性上設定約束。 Limits
屬性包含 KestrelServerLimits
類的例項。
客戶端最大連線數
MaxConcurrentConnections
MaxConcurrentUpgradedConnections
可使用以下程式碼為整個應用設定併發開啟的最大 TCP 連線數:
.ConfigureKestrel((context, options) =>
{
options.Limits.MaxConcurrentConnections = 100;
options.Limits.MaxConcurrentUpgradedConnections = 100;
options.Limits.MaxRequestBodySize = 10 * 1024;
options.Limits.MinRequestBodyDataRate =
new MinDataRate(bytesPerSecond: 100, gracePeriod: TimeSpan.FromSeconds(10));
options.Limits.MinResponseDataRate =
new MinDataRate(bytesPerSecond: 100, gracePeriod: TimeSpan.FromSeconds(10));
options.Listen(IPAddress.Loopback, 5000);
options.Listen(IPAddress.Loopback, 5001, listenOptions =>
{
listenOptions.UseHttps("testCert.pfx", "testPassword");
});
});
對於已從 HTTP
或 HTTPS
升級到另一個協議(例如,Websocket
請求)的連線,有一個單獨的限制。 連線升級後,不會計入 MaxConcurrentConnections
限制。
.ConfigureKestrel((context, options) =>
{
options.Limits.MaxConcurrentConnections = 100;
options.Limits.MaxConcurrentUpgradedConnections = 100;
options.Limits.MaxRequestBodySize = 10 * 1024;
options.Limits.MinRequestBodyDataRate =
new MinDataRate(bytesPerSecond: 100, gracePeriod: TimeSpan.FromSeconds(10));
options.Limits.MinResponseDataRate =
new MinDataRate(bytesPerSecond: 100, gracePeriod: TimeSpan.FromSeconds(10));
options.Listen(IPAddress.Loopback, 5000);
options.Listen(IPAddress.Loopback, 5001, listenOptions =>
{
listenOptions.UseHttps("testCert.pfx", "testPassword");
});
});
預設情況下,最大連線數不受限制 (NULL
)。
請求正文最大大小
MaxRequestBodySize
預設的請求正文最大大小為 30,000,000 位元組,大約 28.6 MB。
在 ASP.NET Core MVC
應用中替代限制的推薦方法是在操作方法上使用 RequestSizeLimit
屬性:
[RequestSizeLimit(100000000)]
public IActionResult MyActionMethod()
以下示例演示如何為每個請求上的應用配置約束:
.ConfigureKestrel((context, options) =>
{
options.Limits.MaxConcurrentConnections = 100;
options.Limits.MaxConcurrentUpgradedConnections = 100;
options.Limits.MaxRequestBodySize = 10 * 1024;
options.Limits.MinRequestBodyDataRate =
new MinDataRate(bytesPerSecond: 100, gracePeriod: TimeSpan.FromSeconds(10));
options.Limits.MinResponseDataRate =
new MinDataRate(bytesPerSecond: 100, gracePeriod: TimeSpan.FromSeconds(10));
options.Listen(IPAddress.Loopback, 5000);
options.Listen(IPAddress.Loopback, 5001, listenOptions =>
{
listenOptions.UseHttps("testCert.pfx", "testPassword");
});
});
如果在應用開始讀取請求後嘗試配置請求限制,則會引發異常。 IsReadOnly
屬性指示 MaxRequestBodySize
屬性處於只讀狀態,意味已經無法再配置限制。
請求正文最小資料速率
MinRequestBodyDataRate
MinResponseDataRate
Kestrel
每秒檢查一次資料是否以指定的速率(位元組/秒)傳入。 如果速率低於最小值,則連線超時。寬限期是 Kestrel
提供給客戶端用於將其傳送速率提升到最小值的時間量;在此期間不會檢查速率。 寬限期有助於避免最初由於 TCP
慢啟動而以較慢速率傳送資料的連線中斷。
預設的最小速率為 240
位元組/秒,包含 5 秒的寬限期。
最小速率也適用於響應。 除了屬性和介面名稱中具有 RequestBody
或 Response
以外,用於設定請求限制和響應限制的程式碼相同。
以下示例演示如何在 Program.cs
中配置最小資料速率:
.ConfigureKestrel((context, options) =>
{
options.Limits.MaxConcurrentConnections = 100;
options.Limits.MaxConcurrentUpgradedConnections = 100;
options.Limits.MaxRequestBodySize = 10 * 1024;
options.Limits.MinRequestBodyDataRate =
new MinDataRate(bytesPerSecond: 100, gracePeriod: TimeSpan.FromSeconds(10));
options.Limits.MinResponseDataRate =
new MinDataRate(bytesPerSecond: 100, gracePeriod: TimeSpan.FromSeconds(10));
options.Listen(IPAddress.Loopback, 5000);
options.Listen(IPAddress.Loopback, 5001, listenOptions =>
{
listenOptions.UseHttps("testCert.pfx", "testPassword");
});
});
可以在中介軟體中替代每個請求的最低速率限制:
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
不支援基於每個請求修改速率限制,因此 HTTP/2
請求的 HttpContext.Features
中不存在前面示例中引用的速率特性。 通過 KestrelServerOptions.Limits
配置的伺服器範圍的速率限制仍適用於 HTTP/1.x
和 HTTP/2
連線。
每個連線的最大流
Http2.MaxStreamsPerConnection
限制每個 HTTP/2
連線的併發請求流的數量。 拒絕過多的流。
public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>()
.ConfigureKestrel((context, options) =>
{
options.Limits.Http2.MaxStreamsPerConnection = 100;
});
預設值為 100。
標題表大小
HPACK
解碼器解壓縮 HTTP/2
連線的 HTTP
標頭。 Http2.HeaderTableSize
限制 HPACK
解碼器使用的標頭壓縮表的大小。 該值以八位位元組提供,且必須大於零 (0)。
public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>()
.ConfigureKestrel((context, options) =>
{
options.Limits.Http2.HeaderTableSize = 4096;
});
預設值為 4096。
最大幀大小
Http2.MaxFrameSize
指示要接收的 HTTP/2
連線幀有效負載的最大大小。 該值以八位位元組提供,必須介於 2^14 (16,384)
和 2^24-1 (16,777,215)
之間。
public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>()
.ConfigureKestrel((context, options) =>
{
options.Limits.Http2.MaxFrameSize = 16384;
});
預設值為 2^14 (16,384)
。
最大請求標頭大小
Http2.MaxRequestHeaderFieldSize
表示請求標頭值的允許的最大大小(用八進位制表示)。 此限制同時適用於壓縮和未壓縮表示形式中的名稱和值。 該值必須大於零 (0)。
public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>()
.ConfigureKestrel((context, options) =>
{
options.Limits.Http2.MaxRequestHeaderFieldSize = 8192;
});
預設值為 8,192。
初始連線視窗大小
Http2.InitialConnectionWindowSize
表示伺服器一次性快取的最大請求主體資料大小(每次連線時在所有請求(流)中彙總,以位元組為單位)。 請求也受 Http2.InitialStreamWindowSize
限制。 該值必須大於或等於 65,535
,並小於 2^31
(2,147,483,648)。
public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>()
.ConfigureKestrel((context, options) =>
{
options.Limits.Http2.InitialConnectionWindowSize = 131072;
});
預設值為 128 KB (131,072)。
初始流視窗大小
Http2.InitialStreamWindowSize
表示伺服器針對每個請求(流)的一次性快取的最大請求主體資料大小(以位元組為單位)。 請求也受 Http2.InitialStreamWindowSize
限制。 該值必須大於或等於 65,535
,並小於 2^31
(2,147,483,648)。
public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>()
.ConfigureKestrel((context, options) =>
{
options.Limits.Http2.InitialStreamWindowSize = 98304;
});
預設值為 96 KB (98,304)。
有關其他 Kestrel
選項和限制的資訊,請參閱:
KestrelServerOptions
KestrelServerLimits
ListenOptions
終結點配置
預設情況下,ASP.NET Core 繫結到:
- http://localhost:5000
- https://localhost:5001(存在本地開發證書時)
開發證書會建立於以下情況:
- 安裝了 .NET Core SDK 時。
- dev-certs tool 用於建立證書。
部分瀏覽器需要獲取信任本地開發證書的顯示許可權。
ASP.NET Core 2.1 及更高版本的專案模板將應用配置為預設情況下在 HTTPS 上執行,幷包括 HTTPS 重定向和 HSTS 支援。
在 KestrelServerOptions
上呼叫 Listen
或 ListenUnixSocket
方法,從而配置 Kestrel
的 URL
字首和埠。
UseUrls
、--urls
命令列引數、urls
主機配置鍵以及 ASPNETCORE_URLS
環境變數也有用,但具有本節後面註明的限制(必須要有可用於 HTTPS
終結點配置的預設證書)。
ASP.NET Core 2.1 KestrelServerOptions
配置:
ConfigureEndpointDefaults(Action<ListenOptions>)
指定一個為每個指定的終結點執行的配置 Action
。 多次呼叫 ConfigureEndpointDefaults
,用最新指定的 Action
替換之前的 Action
。
ConfigureHttpsDefaults(Action<HttpsConnectionAdapterOptions>)
指定一個為每個 HTTPS
終結點執行的配置 Action
。 多次呼叫 ConfigureHttpsDefaults
,用最新指定的 Action
替換之前的 Action
。
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 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 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 上進行偵聽(如果預設證書可用)。
使用以下內容指定 URL:
ASPNETCORE_URLS 環境變數。
--urls 命令列引數。
urls 主機配置鍵。
UseUrls 擴充套件方法。
有關詳細資訊,請參閱伺服器 URL 和重寫配置。
採用這些方法提供的值可以是一個或多個 HTTP 和 HTTPS 終結點(如果預設證書可用,則為 HTTPS)。 將值配置為以分號分隔的列表(例如 “Urls”: “http://localhost:8000;http://localhost:8001”)。
從配置中替換預設證書
WebHost.CreateDefaultBuilder
在預設情況下呼叫 serverOptions.Configure(context.Configuration.GetSection("Kestrel"))
來載入 Kestrel
配置。 Kestrel
可以使用預設 HTTPS
應用設定配置架構。 從磁碟上的檔案或從證書儲存中配置多個終結點,包括要使用的 URL
和證書。
在以下 appsettings.json
示例中:
將 AllowInvalid 設定為 true,從而允許使用無效證書(例如自簽名證書)。
任何未指定證書的 HTTPS 終結點(下例中的 HttpsDefaultCert)會回退至在 Certificates > Default 下定義的證書或開發證書。
{
"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; defaults to My>",
"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>"
}
}
}
}
此外還可以使用任何證書節點的 Path 和 Password,採用證書儲存欄位指定證書。 例如,可將 Certificates > Default 證書指定為:
"Default": {
"Subject": "<subject; required>",
"Store": "<cert store; defaults to My>",
"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("Kestrel")) 通過 .Endpoint(string name, options => { }) 方法返回 KestrelConfigurationLoader,可以用於補充已配置的終結點設定:
C#
options.Configure(context.Configuration.GetSection("Kestrel"))
.Endpoint("HTTPS", opt =>
{
opt.HttpsOptions.SslProtocols = SslProtocols.Tls12;
});
也可以直接訪問 KestrelServerOptions.ConfigurationLoader 在現有載入程式上保持迭代,例如由 WebHost.CreateDefaultBuilder 提供的載入程式。
每個終結點的配置節都可用於 Endpoint 方法中的選項,以便讀取自定義設定。
通過另一節再次呼叫 options.Configure(context.Configuration.GetSection("Kestrel")) 可能載入多個配置。 只使用最新配置,除非之前的例項上顯式呼叫了 Load。 元包不會呼叫 Load,所以可能會替換它的預設配置節。
KestrelConfigurationLoader 從 KestrelServerOptions 將 API 的 Listen 簇反射為 Endpoint 過載,因此可在同樣的位置配置程式碼和配置終結點。 這些過載不使用名稱,且只使用配置中的預設設定。
更改程式碼中的預設值
可以使用 ConfigureEndpointDefaults
和 ConfigureHttpsDefaults
更改 ListenOptions
和 HttpsConnectionAdapterOptions
的預設設定,包括重寫之前的方案指定的預設證書。 需要在配置任何終結點之前呼叫 ConfigureEndpointDefaults
和 ConfigureHttpsDefaults
。
options.ConfigureEndpointDefaults(opt =>
{
opt.NoDelay = true;
});
options.ConfigureHttpsDefaults(httpsOptions =>
{
httpsOptions.SslProtocols = SslProtocols.Tls12;
});
SNI
的 Kestrel
支援
伺服器名稱指示 (SNI
) 可用於承載相同 IP 地址和埠上的多個域。 為了執行 SNI,客戶端在 TLS 握手過程中將進行安全會話的主機名傳送至伺服器,從而讓伺服器可以提供正確的證書。 在 TLS 握手後的安全會話期間,客戶端將伺服器提供的證書用於與伺服器進行加密通訊。
Kestrel
通過 ServerCertificateSelector
回撥支援 SNI
。 每次連線呼叫一次回撥,從而允許應用檢查主機名並選擇合適的證書。
SNI 支援要求:
- 在目標框架
netcoreapp2.1
上執行。 在netcoreapp2.0
和net461
上,回撥也會呼叫,但是name
始終為null
。 如果客戶端未在 TLS 握手過程中提供主機名引數,則name
也為null
。 - 所有網站在相同的
Kestrel
例項上執行。Kestrel
在無反向代理時不支援跨多個例項共享一個IP
地址和埠。
public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>()
.ConfigureKestrel((context, options) =>
{
options.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;
};
});
});
});
繫結到 TCP 套接字
Listen
方法繫結至 TCP 套接字,且 options lambda 允許 X.509 證書配置:
C#
public static void Main(string[] args)
{
CreateWebHostBuilder(args).Build().Run();
}
public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseStartup()
.ConfigureKestrel((context, options) =>
{
options.Listen(IPAddress.Loopback, 5000);
options.Listen(IPAddress.Loopback, 5001, listenOptions =>
{
listenOptions.UseHttps(“testCert.pfx”, “testPassword”);
});
});
示例程式碼使用 ListenOptions 為終結點配置 HTTPS。 可使用相同 API 為特定終結點配置其他 Kestrel 設定。
在 Windows 上,可以使用 New-SelfSignedCertificate PowerShell cmdlet 建立自簽名證書。 有關不支援的示例,請參閱 UpdateIISExpressSSLForChrome.ps1。
在 macOS、Linux 和 Windows 上,可以使用 OpenSSL 建立證書。
繫結到 Unix 套接字
可通過 ListenUnixSocket 偵聽 Unix 套接字以提高 Nginx 的效能,如以下示例所示:
C#
.ConfigureKestrel((context, options) =>
{
options.ListenUnixSocket("/tmp/kestrel-test.sock");
options.ListenUnixSocket("/tmp/kestrel-test.sock", listenOptions =>
{
listenOptions.UseHttps(“testCert.pfx”, “testpassword”);
});
});
埠 0
如果指定埠號 0,Kestrel 將動態繫結到可用埠。 以下示例演示如何確定 Kestrel 在執行時實際繫結到的埠:
C#
public void Configure(IApplicationBuilder app)
{
var serverAddressesFeature =
app.ServerFeatures.Get();
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>");
});
}
在應用執行時,控制檯視窗輸出指示可用於訪問應用的動態埠:
console
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 時,由 Listen 或 UseUrls 設定用於 IIS 覆蓋繫結的 URL 繫結。 有關詳細資訊,請參閱 ASP.NET Core 模組主題。
ListenOptions.Protocols
Protocols 屬性建立在連線終結點上或為伺服器啟用的 HTTP 協議(HttpProtocols)。 從 HttpProtocols 列舉向 Protocols 屬性賦值。
HttpProtocols 列舉值 允許的連線協議
Http1 僅 HTTP/1.1。 可以在具有 TLS 或沒有 TLS 的情況下使用。
Http2 僅 HTTP/2。 主要在具有 TLS 的情況下使用。 僅當客戶端支援先驗知識模式時,才可以在沒有 TLS 的情況下使用。
Http1AndHttp2 HTTP/1.1 和 HTTP/2。 需要 TLS 和應用程式層協議協商 (ALPN) 連線來協商 HTTP/2;否則,連線預設為 HTTP/1.1。
預設協議是 HTTP/1.1。
HTTP/2 的 TLS 限制:
TLS 版本 1.2 或更高版本
重新協商已禁用
壓縮已禁用
最小的臨時金鑰交換大小:
橢圓曲線 Diffie-Hellman (ECDHE) [RFC4492] –最小 224 位
有限欄位 Diffie-Hellman (DHE) [TLS12] – 最小 2048 位
密碼套件未列入阻止列表
預設情況下,支援具有 P-256 橢圓曲線 [FIPS186] 的 TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 [TLS-ECDHE]。
以下示例允許埠 8000 上的 HTTP/1.1 和 HTTP/2 連線。 TLS 使用提供的證書來保護連線:
C#
public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseStartup()
.ConfigureKestrel((context, options) =>
{
options.Listen(IPAddress.Any, 8000, listenOptions =>
{
listenOptions.Protocols = HttpProtocols.Http1AndHttp2;
listenOptions.UseHttps(“testCert.pfx”, “testPassword”);
});
});
(可選)建立 IConnectionAdapter 實現,以針對特定密碼的每個連線篩選 TLS 握手:
C#
public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseStartup()
.ConfigureKestrel((context, options) =>
{
options.Listen(IPAddress.Any, 8000, listenOptions =>
{
listenOptions.Protocols = HttpProtocols.Http1AndHttp2;
listenOptions.UseHttps(“testCert.pfx”, “testPassword”);
listenOptions.ConnectionAdapters.Add(new TlsFilterAdapter());
});
});
C#
private class TlsFilterAdapter : IConnectionAdapter
{
public bool IsHttps => false;
public Task<IAdaptedConnection> OnConnectionAsync(ConnectionAdapterContext context)
{
var tlsFeature = context.Features.Get<ITlsHandshakeFeature>();
// Throw NotSupportedException for any cipher algorithm that you don't
// wish to support. Alternatively, define and compare
// ITlsHandshakeFeature.CipherAlgorithm to a list of acceptable cipher
// suites.
//
// A ITlsHandshakeFeature.CipherAlgorithm of CipherAlgorithmType.Null
// indicates that no cipher algorithm supported by Kestrel matches the
// requested algorithm(s).
if (tlsFeature.CipherAlgorithm == CipherAlgorithmType.Null)
{
throw new NotSupportedException("Prohibited cipher: " + tlsFeature.CipherAlgorithm);
}
return Task.FromResult<IAdaptedConnection>(new AdaptedConnection(context.ConnectionStream));
}
private class AdaptedConnection : IAdaptedConnection
{
public AdaptedConnection(Stream adaptedStream)
{
ConnectionStream = adaptedStream;
}
public Stream ConnectionStream { get; }
public void Dispose()
{
}
}
}
從配置中設定協議
WebHost.CreateDefaultBuilder 在預設情況下呼叫 serverOptions.Configure(context.Configuration.GetSection(“Kestrel”)) 來載入 Kestrel 配置。
在以下 appsettings.json 示例中,為 Kestrel 的所有終結點建立預設的連線協議(HTTP/1.1 和 HTTP/2):
JSON
{
“Kestrel”: {
“EndPointDefaults”: {
“Protocols”: “Http1AndHttp2”
}
}
}
以下配置檔案示例為特定終結點建立了連線協議:
JSON
{
“Kestrel”: {
“EndPoints”: {
“HttpsDefaultCert”: {
“Url”: “https://localhost:5001”,
“Protocols”: “Http1AndHttp2”
}
}
}
}
程式碼中指定的協議覆蓋了由配置設定的值。
傳輸配置
對於 ASP.NET Core 2.1 版,Kestrel 預設傳輸不再基於 Libuv,而是基於託管的套接字。 這是 ASP.NET Core 2.0 應用升級到 2.1 時的一個重大更改,它呼叫 WebHostBuilderLibuvExtensions.UseLibuv 並依賴於以下包中的一個:
Microsoft.AspNetCore.Server.Kestrel(直接包引用)
Microsoft.AspNetCore.App
對於使用 Microsoft.AspNetCore.App 元包且需要使用 Libuv 的 ASP.NET Core 2.1 或更高版本的專案:
將用於 Microsoft.AspNetCore.Server.Kestrel.Transport.Libuv 包的依賴項新增到應用的專案檔案:
XML
呼叫 WebHostBuilderLibuvExtensions.UseLibuv:
C#
public class Program
{
public static void Main(string[] args)
{
CreateWebHostBuilder(args).Build().Run();
}
public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseLibuv()
.UseStartup<Startup>();
}
URL 字首
如果使用 UseUrls、–urls 命令列引數、urls 主機配置鍵或 ASPNETCORE_URLS 環境變數,URL 字首可採用以下任意格式。
僅 HTTP URL 字首是有效的。 使用 UseUrls 配置 URL 繫結時,Kestrel 不支援 HTTPS。
包含埠號的 IPv4 地址
0.0.0.0 是一種繫結到所有 IPv4 地址的特殊情況。
包含埠號的 IPv6 地址
http://[0:0:0:0:0:ffff:4137:270a]:80/
[::] 是 IPv4 0.0.0.0 的 IPv6 等效項。
包含埠號的主機名
http://contoso.com:80/
http://*:80/
主機名、*和 + 並不特殊。 沒有識別為有效 IP 地址或 localhost 的任何內容都將繫結到所有 IPv4 和 IPv6 IP。 若要將不同主機名繫結到相同埠上的不同 ASP.NET Core 應用,請使用 HTTP.sys 或 IIS、Nginx 或 Apache 等反向代理伺服器。
警告
採用反向代理配置進行託管需要主機篩選。
包含埠號的主機 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 包提供,此包包含在 Microsoft.AspNetCore.App 元包中(ASP.NET Core 2.1 或更高版本)。 該中介軟體由 CreateDefaultBuilder 新增,可呼叫 AddHostFiltering:
C#
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..json 中定義一個 AllowedHosts 鍵。 此值是以分號分隔的不帶埠號的主機名列表:
appsettings.json:
JSON
{
“AllowedHosts”: “example.com;localhost”
}
備註
轉接頭中介軟體同樣提供 ForwardedHeadersOptions.AllowedHosts 選項。 轉接頭中介軟體和主機篩選中介軟體具有適合不同方案的相似功能。 如果未保留 Host 標頭,並且使用反向代理伺服器或負載均衡器轉接請求,則使用轉接頭中介軟體設定 AllowedHosts 比較合適。 將 Kestrel 用作面向公眾的邊緣伺服器或直接轉接 Host 標頭時,使用主機篩選中介軟體設定 AllowedHosts 比較合適。
有關轉接頭中介軟體的詳細資訊,請參閱 配置 ASP.NET Core 以使用代理伺服器和負載均衡器。
相關文章
- ASP.NET Core 託管和部署(二)【HTTP.sys】ASP.NETHTTP
- 翻譯 - ASP.NET Core 託管和部署 - 在 Linux 上使用 Nginx 託管 ASP.NET Core 網站ASP.NETLinuxNginx網站
- windows 服務中託管asp.net coreWindowsASP.NET
- ASP.NET Core Kestrel 中使用 HTTPS (SSL)ASP.NETHTTP
- ASP.NET Core託管執行Quartz.NET作業排程詳解ASP.NETquartz
- C# 託管資源和非託管資源C#
- ASP.NET Core技術研究-全面認識Web伺服器KestrelASP.NETWeb伺服器
- .NET 6學習筆記(3)——在Windows Service中託管ASP.NET Core並指定埠筆記WindowsASP.NET
- Linux透過 Docker 可以託管 .NET Core啦!LinuxDocker
- 管中窺豹----.NET Core到.NET 8 託管堆的變遷
- 託管堆和垃圾回收(GC)GC
- 重學c#系列——c# 託管和非託管資源(三)C#
- Asp.Net Core Blazor之容器部署ASP.NETBlazor
- 託管與非託管的混合程式設計程式設計
- Spring Boot專案微信雲託管入門部署Spring Boot
- asp.net core 2.1 部署 centos7ASP.NETCentOS
- 新手指南:透過 Docker 在 Linux 上託管 .NET CoreDockerLinux
- NET Core Kestrel部署HTTPS 一個伺服器綁一個證書 一個伺服器綁多個證書HTTP伺服器
- ASP.NET談委託和事件ASP.NET事件
- 部署型CRM系統和託管型CRM系統的優缺點有哪些
- Linux Docker 部署 ASP.NET Core應用LinuxDockerASP.NET
- 在 Docker 中部署 ASP.NET CORE 應用DockerASP.NET
- 在 Azure 上部署 Asp.NET Core Web AppASP.NETWebAPP
- 《從零開始學Swift》學習筆記(Day 62)——Core Foundation框架之記憶體託管物件與非託管物件Swift筆記框架記憶體物件
- 生態速遞丨微擎系統已支援一鍵部署至雲託管
- 重學c#系列——c# 託管和非託管資源與程式碼相關(四)C#
- .NET Core 3.0之深入原始碼理解Kestrel的整合與應用(一)原始碼
- 藉助雲託管低成本部署企業微信應用
- 伺服器託管伺服器
- Oracle 託管檔案Oracle
- 華為開發者 雲託管
- 伺服器託管是什麼意思,為什麼要託管?伺服器
- Asp.Net Core WebAPI+PostgreSQL部署在Docker中ASP.NETWebAPISQLDocker
- Jenkins + Docker + ASP.NET Core自動化部署JenkinsDockerASP.NET
- Kubernetes 實戰 —— 04. 副本機制和其他控制器:部署託管的 pod
- [.net 物件導向程式設計進階] (8) 託管與非託管物件程式設計
- Asp.Net中的Action和Func委託ASP.NET
- .NET Core 1.0、ASP.NET Core 1.0和EF Core 1.0簡介ASP.NET