Kestrel ASP.NET Core 中的網頁伺服器實作

作者:Tom DykstraChris RossStephen 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();

如需設定 WebApplicationWebApplicationBuilder 的詳細資訊,請參閱 基本 API 概觀

選擇性用戶端憑證

如需必須使用憑證保護應用程式子集之應用程式的相關資訊,請參閱 選擇性用戶端憑證

其他資源

注意

自 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 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 communicates directly with the Internet without a reverse proxy server

Kestrel 用於反向 Proxy 組態:

Kestrel communicates indirectly with the Internet through a reverse proxy server, such as IIS, Nginx, or Apache

不論是否具有反向 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# 程式碼中設定。

使用下列 其中一 種方法:

  • 在 中設定 KestrelStartup.ConfigureServices

    1. 將 的 IConfiguration 實例插入 Startup 類別。 下列範例假設已將插入的組態指派給 Configuration 屬性。

    2. 在 中 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 逾時

KeepAliveTimeout

取得或設定 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)。

要求主體大小上限

MaxRequestBodySize

預設的要求主體大小上限是 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 秒。

速率下限也適用於回應。 除了屬性中具有 RequestBodyResponse 以及介面名稱之外,用來設定要求限制和回應限制的程式碼都相同。

以下是示範如何在 中 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 連線。

要求標頭逾時

RequestHeadersTimeout

取得或設定伺服器花費在接收要求標頭的時間上限。 預設為 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覆寫設定

開發憑證會建立於:

某些瀏覽器需要授與明確許可權,才能信任本機開發憑證。

專案範本會設定應用程式預設在 HTTPS 上執行,並包含 HTTPS 重新導向和 HSTS 支援

呼叫 ListenListenUnixSocket 方法 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 是設定 HttpsConnectionAdapterOptionsAction。 傳回 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>"
}

結構描述附註:

  • 端點名稱不區分大小寫。 例如,HTTPSHttps 都有效。
  • Url 參數對每個端點而言都是必要的。 此參數的格式等同於最上層 Urls 組態參數,但是它限制為單一值。
  • 這些端點會取代最上層 Urls 組態中定義的端點,而不是新增至其中。 透過 Listen 在程式碼中定義的端點,會與組態區段中定義的端點累計。
  • Certificate 區段是選擇性的。 如果未指定 Certificate 區段,則會使用先前案例中所定義的預設值。 如果沒有預設值可供使用,伺服器就會擲回例外狀況,且無法啟動。
  • Certificate 段同時支援Path-PasswordSubject-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 多載,所以可在相同的位置設定程式碼和設定端點。 這些多載不使用名稱,並且只使用來自組態的預設組態。

變更程式碼中的預設值

ConfigureEndpointDefaultsConfigureHttpsDefaults 可以用來變更 ListenOptionsHttpsConnectionAdapterOptions 的預設設定,包括覆寫先前案例中指定的預設憑證。 ConfigureEndpointDefaultsConfigureHttpsDefaults 應該在設定任何端點之前呼叫。

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>>locationproxy_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 設定或設定檔,如本主題稍早所示)。
  • 當同時使用 ListenUseUrls 方法時,Listen 端點會覆寫 UseUrls 端點。

IIS 端點設定

使用 IIS 時,IIS 覆寫繫結的 URL 繫結是由 ListenUseUrls 設定。 如需詳細資訊,請參閱 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.ProtocolsHttpProtocols.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-ECDHEFIPS186 ]。

下列範例會允許連接埠 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/
    

    [::] 是相當於 IPv4 0.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 要求標頭,並等候伺服器回應,再開始傳送要求本文。 這可讓用戶端有機會在傳送不需要的資料之前檢查回應和中止。

其他資源