共用方式為


設定 ASP.NET Core Kestrel Web 伺服器的端點

注意

這不是這篇文章的最新版本。 如需目前的版本,請參閱 本文的 .NET 9 版本。

警告

不再支援此版本的 ASP.NET Core。 如需詳細資訊,請參閱 .NET 和 .NET Core 支持原則。 如需目前的版本,請參閱 本文的 .NET 9 版本。

重要

這些發行前產品的相關資訊在產品正式發行前可能會有大幅修改。 Microsoft 對此處提供的資訊,不做任何明確或隱含的瑕疵擔保。

如需目前的版本,請參閱 本文的 .NET 9 版本。

注意

這不是這篇文章的最新版本。 如需目前的版本,請參閱 本文的 .NET 9 版本。

警告

不再支援此版本的 ASP.NET Core。 如需詳細資訊,請參閱 .NET 和 .NET Core 支持原則。 如需目前的版本,請參閱 本文的 .NET 9 版本。

重要

這些發行前產品的相關資訊在產品正式發行前可能會有大幅修改。 Microsoft 對此處提供的資訊,不做任何明確或隱含的瑕疵擔保。

如需目前的版本,請參閱 本文的 .NET 9 版本。

Kestrel 端點提供基礎結構來接聽傳入要求,並將其路由至適當的中介軟體。 位址和通訊協定兩者的組合可定義端點。

  • 位址會指定伺服器據以接聽傳入要求的網路介面,TCP 通訊埠。
  • 通訊協定則指定用戶端與伺服器之間的通訊,例如 HTTP/1.1、HTTP/2 或 HTTP/3。
  • 您可以使用 https URL 配置或 UseHttps 方法來保護端點。

您可以使用 URL、appsettings.json 中的 JSON 以及程式碼來設定端點。 本文討論如何使用各選項來設定端點:

預設端點

新的 ASP.NET Core 專案設定為繫結至 5000-5300 之間的隨機 HTTP 連接埠,以及介於 7000-7300 之間的隨機 HTTPS 連接埠。 選取的連接埠會儲存在產生的 Properties/launchSettings.json 檔案中,而且可由開發人員修改。 launchSetting.json 檔案只會用於本機開發。

如果沒有端點組態,則 Kestrel 會繫結至 http://localhost:5000

設定端點

Kestrel 端點會接聽連入連線。 建立端點時,必須為其設定要接聽的位址。 這通常是 TCP 位址和連接埠號碼。

有幾種方法設定端點:

使用 URL 設定端點

以下各節說明如何使用下列項目來設定端點:

  • ASPNETCORE_URLS 環境變數。
  • --urls 命令列引數。
  • urls 主機組態索引鍵。
  • UseUrls 擴充方法。
  • WebApplication.Urls 屬性。

URL 格式

URL 指明了 IP 或主機地位,內含伺服器應接聽的連接埠和通訊協議。 如果連接埠是通訊協定的預設連接埠 (通常為 80 和 443),則可以省略。 URL 可以是下列任何格式。

  • 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 位址的萬用字元。 為求更加明確,有些人喜歡使用 *+。 若要將不同主機名稱繫結至同一連接埠上的不同 ASP.NET Core 應用程式,請使用 HTTP.sys 或反向 Proxy 伺服器。

    反向 Proxy 伺服器範例包括 IIS、YARP、Nginx 和 Apache。

  • 主機名稱 localhost 與連接埠號碼,或回送 IP 與連接埠號碼

    http://localhost:5000/
    http://127.0.0.1:5000/
    http://[::1]:5000/
    

    指定 localhost 時,Kestrel 會嘗試同時繫結至 IPv4 和 IPv6 回送介面。 如果所要求的連接埠由任一回送介面上的另一個服務使用,Kestrel 即無法啟動。 如果任一回送介面由於任何其他原因 (最常見的原因是不支援 IPv6) 而無法使用,Kestrel 就會記錄警告。

您可以使用分號 (;) 分隔符號來指定多個 URL 首碼:

http://*:5000;http://localhost:5001;https://hostname:5002

如需詳細資訊,請參閱覆寫組態

HTTPS URL 首碼

唯有已在 HTTPS 端點組態中提供預設憑證時,才能使用 HTTPS URL 首碼來定義端點。 例如,使用 KestrelServerOptions 組態或組態檔,如本文稍後所示

如需詳細資訊,請參閱設定 HTTPS

僅指定連接埠

應用程式和容器通常只被分配一個連接埠來接聽,例如埠 80,而不需要像主機或路徑這樣的額外限制。 HTTP_PORTS 和 HTTPS_PORTS 是組態索引鍵,用於指定 Kestrel 和 HTTP.sys 伺服器的接聽連接埠。 這些索引鍵可以作為使用 DOTNET_ASPNETCORE_ 首碼所定義的環境變數,或者直接透過任何其他組態輸入 (例如 appsettings.json) 來指定。 每一個都是以分號分隔的埠值清單,如下列範例所示:

ASPNETCORE_HTTP_PORTS=80;8080
ASPNETCORE_HTTPS_PORTS=443;8081

上述範例是下列組態的速記,它會指定配置 (HTTP 或 HTTPS) 和任何主機或 IP。

ASPNETCORE_URLS=http://*:80/;http://*:8080/;https://*:443/;https://*:8081/

HTTP_PORTS 和 HTTPS_PORTS 組態索引鍵的優先順序較低,會以直接在程式碼中提供的 URLS 或值覆寫。 憑證仍然需要透過 HTTPS 的伺服器專有機制來個別設定。

在 appsettings.json 中設定端點

Kestrel 可以從 IConfiguration 執行個體載入端點。 根據預設,會從 Kestrel 區段載入 Kestrel 組態,並在 Kestrel:Endpoints 中設定端點:

{
  "Kestrel": {
    "Endpoints": {
      "MyHttpEndpoint": {
        "Url": "http://localhost:8080"
      }
    }
  }
}

上述範例:

  • 使用 appsettings.json 做為組態來源。 不過,可以使用任何 IConfiguration 來源。
  • 在埠 8080 上新增名為 MyHttpEndpoint 的端點。

如需使用 JSON 設定端點的詳細資訊,請參閱本文稍後的章節,討論在 appsettings.json 中設定 HTTPS設定 HTTP 通訊協定

從組態重新載入端點

預設會啟用組態來源變更時重新載入端點組態。 可以使用 KestrelServerOptions.Configure(IConfiguration, Boolean) 來加以停用。

如果發出變更訊號,則會採取下列步驟:

  • 新的組態會與舊的組態進行比較,而且不會修改任何沒有組態變更的端點。
  • 移除或修改的端點會分配 5 秒的時間來完成處理要求並關閉。
  • 啟動新的或修改的端點。

重新啟動端點時,連線到修改後端點的用戶端可能會中斷連線或遭拒絕。

ConfigurationLoader

KestrelServerOptions.Configure 會傳回 KestrelConfigurationLoader。 載入器的 Endpoint(String, Action<EndpointConfiguration>) 方法,可用來補充已設定端點的設定:

var builder = WebApplication.CreateBuilder(args);

builder.WebHost.ConfigureKestrel((context, serverOptions) =>
{
    var kestrelSection = context.Configuration.GetSection("Kestrel");

    serverOptions.Configure(kestrelSection)
        .Endpoint("HTTPS", listenOptions =>
        {
            // ...
        });
});

您可以直接存取 KestrelServerOptions.ConfigurationLoader,以繼續逐一查看現有的載入器,例如 WebApplicationBuilder.WebHost 所提供的載入器。

  • 每個端點的組態區段都可以在 Endpoint 方法中的選項上獲取,以便讀取自訂設定。
  • 您可以多次呼叫 KestrelServerOptions.Configure(IConfiguration),但除非在先前的執行個體上明確呼叫 Load,否則只會使用最後一個組態。 預設主控件不會呼叫 Load,因此其預設組態區段可能會被取代。
  • KestrelConfigurationLoader 會將來自 KestrelServerOptions 的 API Listen 系列鏡像為 Endpoint 多載,所以可在相同的位置設定程式碼和組態端點。 這些多載不使用名稱,並且只使用來自組態的預設組態。

在程式碼中設定端點

KestrelServerOptions 會提供在程式碼中設定端點的方法:

同時使用 ListenUseUrls API 時,Listen 端點會覆寫 UseUrls 端點。

繫結至 TCP 通訊端

ListenListenLocalhostListenAnyIP 方法會繫結至 TCP 通訊端:

var builder = WebApplication.CreateBuilder(args);

builder.WebHost.ConfigureKestrel((context, serverOptions) =>
{
    serverOptions.Listen(IPAddress.Loopback, 5000);
    serverOptions.Listen(IPAddress.Loopback, 5001, listenOptions =>
    {
        listenOptions.UseHttps("testCert.pfx", "testPassword");
    });
});

上述範例:

在 Windows 上,可以使用 New-SelfSignedCertificate PowerShell Cmdlet 建立自我簽署憑證。 如需不支援的範例,請參閱 UpdateIISExpressSSLForChrome.ps1

在 macOS、Linux 和 Windows 上,可以使用 OpenSSL \(英文\) 建立憑證。

繫結至 Unix 通訊端

請使用 ListenUnixSocket 在 Unix 通訊端上進行接聽以改善 Nginx 的效能,如此範例所示:

var builder = WebApplication.CreateBuilder(args);

builder.WebHost.ConfigureKestrel((context, serverOptions) =>
{
    serverOptions.ListenUnixSocket("/tmp/kestrel-test.sock");
});
  • 在 Nginx 組態檔中,將 server>location>proxy_pass 項目設定為 http://unix:/tmp/{KESTREL SOCKET}:/;{KESTREL SOCKET} 是提供給 ListenUnixSocket 的通訊端名稱 (例如,上述範例中的 kestrel-test.sock)。
  • 請確定通訊端可由 Nginx 寫入 (例如,chmod go+w /tmp/kestrel-test.sock)。

設定端點預設值

ConfigureEndpointDefaults(Action<ListenOptions>) 會指定針對每個指定端點執行的組態。 呼叫 ConfigureEndpointDefaults 多次會取代先前的組態。

var builder = WebApplication.CreateBuilder(args);

builder.WebHost.ConfigureKestrel(serverOptions =>
{
    serverOptions.ConfigureEndpointDefaults(listenOptions =>
    {
        // ...
    });
});

注意

透過呼叫 Listen 之前呼叫 ConfigureEndpointDefaults 所建立的端點,不會套用預設值。

動態連接埠繫結

指定連接埠號碼 0 時,Kestrel 會動態繫結至可用的埠。 下列範例示範如何判斷 Kestrel 在執行階段繫結至哪一個連接埠:

app.Run(async (context) =>
{
    var serverAddressFeature = context.Features.Get<IServerAddressesFeature>();

    if (serverAddressFeature is not null)
    {
        var listenAddresses = string.Join(", ", serverAddressFeature.Addresses);

        // ...
    }
});

在某些情況下,無法使用連接埠動態繫結:

設定 HTTPS

Kestrel 支援使用 HTTPS 保護端點。 透過 HTTPS 傳送的資料會使用傳輸層安全性 (TLS) 進行加密,來提高用戶端與伺服器之間傳輸資料的安全性。

HTTPS 需要 TLS 憑證。 TLS 憑證會儲存在伺服器上,且 Kestrel 會設定為使用該憑證。 應用程式可以在本機開發環境中使用 ASP.NET Core HTTPS 開發憑證。 該開發憑證並未安裝在非開發環境中。 在生產環境中,必須明確設定 TLS 憑證。 至少必須提供預設憑證。

HTTPS 和 TLS 憑證的設定方式取決於端點的設定方式:

在 appsettings.json 中設定 HTTPS

Kestrel 可以使用預設的 HTTPS 應用程式設定組態結構描述。 設定多個端點,包括 URL 和要使用的憑證-從磁碟上的檔案,或是從憑證存放區。

任何未指定憑證 (接下來範例中的 HttpsDefaultCert) 的 HTTPS 端點會回復為在 Certificates:Default 或開發憑證下所定義的憑證。

下列範例適用於 appsettings.json,但可以使用任何組態來源:

{
  "Kestrel": {
    "Endpoints": {
      "Http": {
        "Url": "http://localhost:5000"
      },
      "HttpsInlineCertFile": {
        "Url": "https://localhost:5001",
        "Certificate": {
          "Path": "<path to .pfx file>",
          "Password": "$CREDENTIAL_PLACEHOLDER$"
        }
      },
      "HttpsInlineCertAndKeyFile": {
        "Url": "https://localhost:5002",
        "Certificate": {
          "Path": "<path to .pem/.crt file>",
          "KeyPath": "<path to .key file>",
          "Password": "$CREDENTIAL_PLACEHOLDER$"
        }
      },
      "HttpsInlineCertStore": {
        "Url": "https://localhost:5003",
        "Certificate": {
          "Subject": "<subject; required>",
          "Store": "<certificate store; required>",
          "Location": "<location; defaults to CurrentUser>",
          "AllowInvalid": "<true or false; defaults to false>"
        }
      },
      "HttpsDefaultCert": {
        "Url": "https://localhost:5004"
      }
    },
    "Certificates": {
      "Default": {
        "Path": "<path to .pfx file>",
        "Password": "$CREDENTIAL_PLACEHOLDER$"
      }
    }
  }
}

警告

在上述範例中,憑證密碼會以純文字形式儲存在 appsettings.json 中。 $CREDENTIAL_PLACEHOLDER$ 權杖會作為憑證密碼的預留位置。 若要安全地將憑證密碼儲存在開發環境中,請參閱在開發過程中保護祕密。 若要安全地將憑證密碼儲存在生產環境中,請參閱 Azure Key Vault 組態提供者。 開發秘密不應該用於生產或測試。

結構描述附註

  • 端點名稱不區分大小寫。 例如,HTTPSHttps 彼此相等。
  • Url 參數對每個端點而言都是必要的。 此參數的格式等同於最上層 Urls 組態參數,但是它限制為單一值。 請參閱本文稍早所述的 URL 格式
  • 這些端點會取代最上層 Urls 組態中定義的端點,而不是新增至其中。 透過 Listen 在程式碼中定義的端點,會與組態區段中定義的端點累計。
  • Certificate 區段是選擇性的。 如果未指定 Certificate 區段,則會使用 Certificates:Default 中定義的預設值。 如果沒有可用的預設值,則會使用開發憑證。 如果沒有預設值且開發憑證不存在,伺服器會擲回例外狀況,且無法啟動。
  • Certificate 區段支援多個憑證來源。
  • Configuration 中可以定義任何數目的端點,只要不會導致連接埠衝突即可。

憑證來源

憑證節點可以設定為從許多來源載入憑證:

  • PathPassword,供載入 .pfx 檔案。
  • PathKeyPathPassword,供載入 .pem/.crt.key 檔案。
  • SubjectStore,從憑證存放區載入。

例如,可將 Certificates:Default 憑證指定為:

"Default": {
  "Subject": "<subject; required>",
  "Store": "<cert store; required>",
  "Location": "<location; defaults to CurrentUser>",
  "AllowInvalid": "<true or false; defaults to false>"
}

在 appsettings.json 中設定用戶端憑證

ClientCertificateMode 可用來設定用戶端憑證行為。

{
  "Kestrel": {
    "Endpoints": {
      "MyHttpsEndpoint": {
        "Url": "https://localhost:5001",
        "ClientCertificateMode": "AllowCertificate",
        "Certificate": {
          "Path": "<path to .pfx file>",
          "Password": "$CREDENTIAL_PLACEHOLDER$"
        }
      }
    }
  }
}

警告

在上述範例中,憑證密碼會以純文字形式儲存在 appsettings.json 中。 $CREDENTIAL_PLACEHOLDER$ 權杖會作為憑證密碼的預留位置。 若要安全地將憑證密碼儲存在開發環境中,請參閱在開發過程中保護祕密。 若要安全地將憑證密碼儲存在生產環境中,請參閱 Azure Key Vault 組態提供者。 開發秘密不應該用於生產或測試。

預設值為 ClientCertificateMode.NoCertificate,其中 Kestrel 不會向用戶端要求憑證。

如需詳細資訊,請參閱在 ASP.NET Core 中設定憑證驗證

在 appsettings.json 中設定 SSL/TLS 通訊協定

SSL 通訊協定是用來加密和解密兩個同儕節點 (傳統上是用戶端與伺服器) 之間流量的通訊協定。

{
  "Kestrel": {
    "Endpoints": {
      "MyHttpsEndpoint": {
        "Url": "https://localhost:5001",
        "SslProtocols": ["Tls12", "Tls13"],
        "Certificate": {
          "Path": "<path to .pfx file>",
          "Password": "$CREDENTIAL_PLACEHOLDER$"
        }
      }
    }
  }
}

警告

在上述範例中,憑證密碼會以純文字形式儲存在 appsettings.json 中。 $CREDENTIAL_PLACEHOLDER$ 權杖會作為憑證密碼的預留位置。 若要安全地將憑證密碼儲存在開發環境中,請參閱在開發過程中保護祕密。 若要安全地將憑證密碼儲存在生產環境中,請參閱 Azure Key Vault 組態提供者。 開發秘密不應該用於生產或測試。

預設值 SslProtocols.None 會導致 Kestrel 使用作業系統預設值來選擇最佳通訊協定。 除非您有特殊原因要選取某一通訊協定,否則請使用預設值。

在程式碼中設定 HTTPS

使用 Listen API 時,ListenOptions 上的 UseHttps 擴充方法可用來設定 HTTPS。

var builder = WebApplication.CreateBuilder(args);

builder.WebHost.ConfigureKestrel((context, serverOptions) =>
{
    serverOptions.Listen(IPAddress.Loopback, 5000);
    serverOptions.Listen(IPAddress.Loopback, 5001, listenOptions =>
    {
        listenOptions.UseHttps("testCert.pfx", "testPassword");
    });
});

ListenOptions.UseHttps 參數:

  • filename 是憑證檔案的路徑和檔案名稱,它相對於包含應用程式內容檔案的目錄。
  • password 是存取 X.509 憑證資料所需的密碼。
  • configureOptions 是設定 HttpsConnectionAdapterOptionsAction。 傳回 ListenOptions
  • storeName 是要從中載入憑證的憑證存放區。
  • subject 是憑證的主體名稱。
  • allowInvalid 表示是否應該考慮無效的憑證,例如自我簽署憑證。
  • location 是要從中載入憑證的存放區位置。
  • serverCertificate 是 X.509 憑證。

如需 UseHttps 多載的完整清單,請參閱 UseHttps

在程式碼中設定用戶端憑證

ClientCertificateMode 會設定用戶端憑證需求。

var builder = WebApplication.CreateBuilder(args);

builder.WebHost.ConfigureKestrel(serverOptions =>
{
    serverOptions.ConfigureHttpsDefaults(listenOptions =>
    {
        listenOptions.ClientCertificateMode = ClientCertificateMode.AllowCertificate;
    });
});

預設值為 NoCertificate,其中 Kestrel 不會向用戶端要求憑證。

如需詳細資訊,請參閱在 ASP.NET Core 中設定憑證驗證

在程式碼中設定 HTTPS 預設值

ConfigureHttpsDefaults(Action<HttpsConnectionAdapterOptions>) 會指定組態 Action,來針對每個 HTTPS 端點執行。 呼叫 ConfigureHttpsDefaults 多次,即會以最後指定的 Action 取代之前的 Action 執行個體。

var builder = WebApplication.CreateBuilder(args);

builder.WebHost.ConfigureKestrel(serverOptions =>
{
    serverOptions.ConfigureHttpsDefaults(listenOptions =>
    {
        // ...
    });
});

注意

透過呼叫 Listen 之前呼叫 ConfigureHttpsDefaults 所建立的端點,不會套用預設值。

在程式碼中設定 SSL/TLS 通訊協定

SSL 通訊協定是用來加密和解密兩個同儕節點 (傳統上是用戶端與伺服器) 之間流量的通訊協定。

var builder = WebApplication.CreateBuilder(args);

builder.WebHost.ConfigureKestrel(serverOptions =>
{
    serverOptions.ConfigureHttpsDefaults(listenOptions =>
    {
        listenOptions.SslProtocols = SslProtocols.Tls13;
    });
});

在程式碼中設定 TLS 加密套件篩選

在 Linux 上,可以使用 CipherSuitesPolicy 來根據每個連線篩選 TLS 交握:

var builder = WebApplication.CreateBuilder(args);

builder.WebHost.ConfigureKestrel((context, 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,
                    // ...
                });
        };
    });
});

設定伺服器名稱指示

伺服器名稱指示 (SNI) 可以用於在相同的 IP 位址和連接埠上裝載多個網域。 SNI 可據以從一部伺服器來服務多個網站以節省資源。

SNI 若要運作,用戶端會在 TLS 信號交換期間傳送安全工作階段的主機名稱給伺服器,讓伺服器可以提供正確的憑證。 用戶端在 TLS 信號交換之後的安全工作階段期間,會使用所提供的憑證與伺服器進行加密通訊。

所有網站都必須在相同的 Kestrel 執行個體上執行。 在不使用反向 Proxy 的情況下,Kestrel 不支援跨多個執行個體共用 IP 位址和連接埠。

SNI 有兩種設定方式:

  • [組態] 中設定主機名稱與 HTTPS 選項之間的對應。 例如,appsettings.json 檔案中的 JSON。
  • 在程式碼中建立端點,並使用主機名稱搭配 ServerCertificateSelector 回呼來選取憑證。

在 appsettings.json 中設定 SNI

Kestrel 支援在組態中定義的 SNI。 您可以使用 Sni 物件來設定端點,該物件中包含主機名稱與 HTTPS 選項之間的對應。 連線主機名稱會與選項進行比對,然後用於該連線。

下列組態會新增名為 MySniEndpoint 的端點,該端點會使用 SNI 來根據主機名稱選取 HTTPS 選項:

{
  "Kestrel": {
    "Endpoints": {
      "MySniEndpoint": {
        "Url": "https://*",
        "SslProtocols": ["Tls11", "Tls12"],
        "Sni": {
          "a.example.org": {
            "Protocols": "Http1AndHttp2",
            "SslProtocols": ["Tls11", "Tls12", "Tls13"],
            "Certificate": {
              "Subject": "<subject; required>",
              "Store": "<certificate store; required>",
            },
            "ClientCertificateMode" : "NoCertificate"
          },
          "*.example.org": {
            "Certificate": {
              "Path": "<path to .pfx file>",
              "Password": "$CREDENTIAL_PLACEHOLDER$"
            }
          },
          "*": {
            // At least one subproperty needs to exist per SNI section or it
            // cannot be discovered via IConfiguration
            "Protocols": "Http1",
          }
        }
      }
    },
    "Certificates": {
      "Default": {
        "Path": "<path to .pfx file>",
        "Password": "$CREDENTIAL_PLACEHOLDER$"
      }
    }
  }
}

警告

在上述範例中,憑證密碼會以純文字形式儲存在 appsettings.json 中。 $CREDENTIAL_PLACEHOLDER$ 權杖會作為憑證密碼的預留位置。 若要安全地將憑證密碼儲存在開發環境中,請參閱在開發過程中保護祕密。 若要安全地將憑證密碼儲存在生產環境中,請參閱 Azure Key Vault 組態提供者。 開發秘密不應該用於生產或測試。

SNI 可以覆寫的 HTTPS 選項:

主機名稱支援萬用字元比對:

  • 完全相符。 例如,a.example.org 符合 a.example.org
  • 萬用字元首碼。 如果有多個萬用字元相符,則會選擇最長的模式。 例如,*.example.org 符合 b.example.orgc.example.org
  • 完整萬用字元。 * 會比對其他所有內容,包括未使用 SNI 且不會傳送主機名稱的用戶端。

相符的 SNI 組態會套用至連線的端點,並覆寫端點上的值。 如果連線不符合設定的 SNI 主機名稱,則會拒絕連線。

使用程式碼設定 SNI

Kestrel 支援具有數個回呼 API 的 SNI:

  • ServerCertificateSelector
  • ServerOptionsSelectionCallback
  • TlsHandshakeCallbackOptions

SNI 搭配 ServerCertificateSelector

Kestrel 透過 ServerCertificateSelector 回呼來支援 SNI。 每個連線會叫用回呼一次,以允許應用程式檢查主機名稱並選取適當的憑證。

var builder = WebApplication.CreateBuilder(args);

builder.WebHost.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)
            {
                ["localhost"] = localhostCert,
                ["example.com"] = exampleCert,
                ["sub.example.com"] = subExampleCert
            };

            httpsOptions.ServerCertificateSelector = (connectionContext, name) =>
            {
                if (name is not null && certs.TryGetValue(name, out var cert))
                {
                    return cert;
                }

                return exampleCert;
            };
        });
    });
});

SNI 搭配 ServerOptionsSelectionCallback

Kestrel 透過 ServerOptionsSelectionCallback 回呼支援其他動態 TLS 組態。 每個連線會叫用回呼一次,以允許應用程式檢查主機名稱,並選取適當的憑證和 TLS 組態。 預設憑證和 ConfigureHttpsDefaults 不會與此回呼搭配使用。

var builder = WebApplication.CreateBuilder(args);

builder.WebHost.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);

            listenOptions.UseHttps((stream, clientHelloInfo, state, cancellationToken) =>
            {
                if (string.Equals(clientHelloInfo.ServerName, "localhost",
                    StringComparison.OrdinalIgnoreCase))
                {
                    return new ValueTask<SslServerAuthenticationOptions>(
                        new SslServerAuthenticationOptions
                        {
                            ServerCertificate = localhostCert,
                            // Different TLS requirements for this host
                            ClientCertificateRequired = true
                        });
                }

                return new ValueTask<SslServerAuthenticationOptions>(
                    new SslServerAuthenticationOptions
                    {
                        ServerCertificate = exampleCert
                    });
            }, state: null!);
        });
    });
});

SNI 搭配 TlsHandshakeCallbackOptions

Kestrel 透過 TlsHandshakeCallbackOptions.OnConnection 回呼來支援其他動態 TLS 組態。 每個連線會叫用回呼一次,以允許應用程式檢查主機名稱,並選取適當的憑證、TLS 組態和其他伺服器選項。 預設憑證和 ConfigureHttpsDefaults 不會與此回呼搭配使用。

var builder = WebApplication.CreateBuilder(args);

builder.WebHost.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);

            listenOptions.UseHttps(new TlsHandshakeCallbackOptions
            {
                OnConnection = context =>
                {
                    if (string.Equals(context.ClientHelloInfo.ServerName, "localhost",
                        StringComparison.OrdinalIgnoreCase))
                    {
                        // Different TLS requirements for this host
                        context.AllowDelayedClientCertificateNegotation = true;

                        return new ValueTask<SslServerAuthenticationOptions>(
                            new SslServerAuthenticationOptions
                            {
                                ServerCertificate = localhostCert
                            });
                    }

                    return new ValueTask<SslServerAuthenticationOptions>(
                        new SslServerAuthenticationOptions
                        {
                            ServerCertificate = exampleCert
                        });
                }
            });
        });
    });
});

設定 HTTP 通訊協定

Kestrel 支援所有常用的 HTTP 版本。 您可以使用 HttpProtocols 列舉來設定端點以支援不同的 HTTP 版本,該列舉會指定可用的 HTTP 版本選項。

需要 TLS 才能支援多個 HTTP 版本。 當端點支援多個通訊協定時,TLS 應用程式層通訊協定交涉 (ALPN) 交握可用來交涉用戶端與伺服器之間的連線通訊協定。

HttpProtocols 允許的連線通訊協定
Http1 僅限 HTTP/1.1。 可在具有或沒有 TLS 的情況下使用。
Http2 僅限 HTTP/2。 只有在用戶端支援先備知識模式時,才可以在沒有 TLS 的情況下使用。
Http3 僅限 HTTP/3。 需要 TLS。 用戶端可能需要設定為僅使用 HTTP/3。
Http1AndHttp2 HTTP/1.1 和 HTTP/2。 HTTP/2 要求用戶端在 TLS 應用程式層通訊協定交涉 (ALPN) 交握中選取 HTTP/2;否則,連線會預設為 HTTP/1.1。
Http1AndHttp2AndHttp3 HTTP/1.1、HTTP/2 和 HTTP/3。 第一個用戶端要求通常會使用 HTTP/1.1 或 HTTP/2,而 alt-svc 回應標頭會提示用戶端升級至 HTTP/3。 HTTP/2 和 HTTP/3 需要 TLS;否則,連線會預設為 HTTP/1.1。

端點的預設通訊協定值為 HttpProtocols.Http1AndHttp2

HTTP/2 的 TLS 限制:

  • TLS 1.2 版或更新版本
  • 已停用重新交涉
  • 已停用壓縮
  • 暫時金鑰交換大小下限:
    • 橢圓曲線 Diffie-Hellman (ECDHE) [RFC4492]:最小 224 個位元
    • 有限欄位 Diffie-Hellman (DHE) [TLS12]:最小 2048 個位元
  • 未禁止使用加密套件。

預設支援 TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 [TLS-ECDHE] 與 P-256 橢圓曲線 [FIPS186]。

在 appsettings.json 中設定 HTTP 通訊協定

下列 appsettings.json 範例會針對特定端點建立 HTTP/1.1 連線通訊協定:

{
  "Kestrel": {
    "Endpoints": {
      "HttpsDefaultCert": {
        "Url": "https://localhost:5001",
        "Protocols": "Http1"
      }
    }
  }
}

您可以在 Kestrel:EndpointDefaults 區段中設定預設通訊協定。 下列 appsettings.json 範例會建立 HTTP/1.1 作為所有端點的預設連線通訊協定:

{
  "Kestrel": {
    "EndpointDefaults": {
      "Protocols": "Http1"
    }
  }
}

程式碼中指定的通訊協定會覆寫設定所設定的值。

在程式碼中設定 HTTP 通訊協定

ListenOptions.Protocols 是用來指定具有 HttpProtocols 列舉的通訊協定。

下列範例會為埠 8000 上的 HTTP/1.1、HTTP/2 和 HTTP/3 等連線設定端點。 這些連線使用提供的憑證受到 TLS 保護:

var builder = WebApplication.CreateBuilder(args);

builder.WebHost.ConfigureKestrel((context, serverOptions) =>
{
    serverOptions.Listen(IPAddress.Any, 8000, listenOptions =>
    {
        listenOptions.UseHttps("testCert.pfx", "testPassword");
        listenOptions.Protocols = HttpProtocols.Http1AndHttp2AndHttp3;
    });
});

另請參閱

ASP.NET Core 專案設定為繫結至介於 5000-5300 之間的隨機 HTTP 連接埠,以及介於 7000-7300 之間的隨機 HTTPS 連接埠。 這個預設組態是在產生的 Properties/launchSettings.json 檔案中指定,而且可以覆寫。 如果未指定任何連接埠,Kestrel 會繫結至 http://localhost:5000

使用以下各項指定 URL:

  • ASPNETCORE_URLS 環境變數。
  • --urls 命令列引數。
  • urls 主機組態索引鍵。
  • UseUrls 擴充方法。

使用這些方法提供的值可以是一或多個 HTTP 和 HTTPS 端點 (如果有預設憑證可用則為 HTTPS)。 將值設定為以分號分隔的清單 (例如,"Urls": "http://localhost:8000;http://localhost:8001")。

如需有關這些方法的詳細資訊,請參閱伺服器 URL覆寫設定

開發憑證會建立於:

開發憑證僅適用於產生憑證的使用者。 某些瀏覽器需要授與明確許可權,才能信任本機開發憑證。

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

請在 KestrelServerOptions 上呼叫 ListenListenUnixSocket 方法,來為 Kestrel 設定 URL 首碼和連接埠。

UseUrls--urls 命令列引數、urls 主機組態索引鍵和 ASPNETCORE_URLS 環境變數同樣有效,但卻有本節稍後註明的限制 (針對 HTTPS 端點組態必須有預設憑證可用)。

KestrelServerOptions 組態:

ConfigureEndpointDefaults

ConfigureEndpointDefaults(Action<ListenOptions>) 會指定組態 Action 以針對每個指定端點執行。 呼叫 ConfigureEndpointDefaults 多次會以最後指定的 Action 取代之前的 Action

var builder = WebApplication.CreateBuilder(args);

builder.WebHost.ConfigureKestrel(serverOptions =>
{
    serverOptions.ConfigureEndpointDefaults(listenOptions =>
    {
        // ...
    });
});

注意

透過呼叫 Listen 之前呼叫 ConfigureEndpointDefaults 所建立的端點,不會套用預設值。

Configure(IConfiguration)

允許 Kestrel 從 IConfiguration 載入端點。 組態的範圍必須限定為 Kestrel 的組態區段。 Configure(IConfiguration, bool) 多載可用來在組態來源變更時啟用重載端點。

根據預設,會從 Kestrel 區段載入 Kestrel 組態,並啟用重載變更:

{
  "Kestrel": {
    "Endpoints": {
      "Http": {
        "Url": "http://localhost:5000"
      },
      "Https": {
        "Url": "https://localhost:5001"
      }
    }
  }
}

如果已啟用重載組態並發出變更訊號,則會採取下列步驟:

  • 新的組態會與舊組態進行比較,不會修改任何沒有組態變更的端點。
  • 移除或修改的端點會分配 5 秒的時間來完成處理要求並關閉。
  • 啟動新的或修改的端點。

重新啟動端點時,連線到修改後端點的用戶端可能會中斷連線或遭拒絕。

ConfigureHttpsDefaults

ConfigureHttpsDefaults(Action<HttpsConnectionAdapterOptions>) 會指定組態 Action 以針對每個 HTTPS 端點執行。 呼叫 ConfigureHttpsDefaults 多次會以最後一個指定的 Action 取代之前的 Action

var builder = WebApplication.CreateBuilder(args);

builder.WebHost.ConfigureKestrel(serverOptions =>
{
    serverOptions.ConfigureHttpsDefaults(listenOptions =>
    {
        // ...
    });
});

注意

透過呼叫 Listen 之前呼叫 ConfigureHttpsDefaults 所建立的端點,不會套用預設值。

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。 至少必須提供預設憑證。

如果憑證是從磁碟讀取,而不是從 Windows 憑證存放區,則包含的目錄必須具有適當的許可權,以防止未經授權的存取。

支援的組態描述如下:

  • 無組態
  • 從組態取代預設憑證
  • 變更程式碼中的預設值

無組態

Kestrel 會接聽 http://localhost:5000

從組態取代預設憑證

Kestrel 可以使用預設的 HTTPS 應用程式設定組態結構描述。 設定多個端點,包括 URL 和要使用的憑證-從磁碟上的檔案,或是從憑證存放區。

在下列 appsettings.json 範例中:

  • AllowInvalid 設定為 true,允許使用無效的憑證 (例如,自我簽署憑證)。
  • 任何未指定憑證 (接下來範例中的 HttpsDefaultCert) 的 HTTPS 端點會回復為在 Certificates:Default 或開發憑證下定義的憑證。
{
  "Kestrel": {
    "Endpoints": {
      "Http": {
        "Url": "http://localhost:5000"
      },
      "HttpsInlineCertFile": {
        "Url": "https://localhost:5001",
        "Certificate": {
          "Path": "<path to .pfx file>",
          "Password": "$CREDENTIAL_PLACEHOLDER$"
        }
      },
      "HttpsInlineCertAndKeyFile": {
        "Url": "https://localhost:5002",
        "Certificate": {
          "Path": "<path to .pem/.crt file>",
          "KeyPath": "<path to .key file>",
          "Password": "$CREDENTIAL_PLACEHOLDER$"
        }
      },
      "HttpsInlineCertStore": {
        "Url": "https://localhost:5003",
        "Certificate": {
          "Subject": "<subject; required>",
          "Store": "<certificate store; required>",
          "Location": "<location; defaults to CurrentUser>",
          "AllowInvalid": "<true or false; defaults to false>"
        }
      },
      "HttpsDefaultCert": {
        "Url": "https://localhost:5004"
      }
    },
    "Certificates": {
      "Default": {
        "Path": "<path to .pfx file>",
        "Password": "$CREDENTIAL_PLACEHOLDER$"
      }
    }
  }
}

警告

在上述範例中,憑證密碼會以純文字形式儲存在 appsettings.json中。 $CREDENTIAL_PLACEHOLDER$ 權杖會作為每個憑證密碼的預留位置。 若要安全地將憑證密碼儲存在開發環境中,請參閱在開發過程中保護祕密。 若要安全地將憑證密碼儲存在生產環境中,請參閱 Azure Key Vault 組態提供者。 開發秘密不應該用於生產或測試。

結構描述附註:

  • 端點名稱不區分大小寫。 例如,HTTPSHttps 彼此相等。
  • Url 參數對每個端點而言都是必要的。 此參數的格式等同於最上層 Urls 組態參數,但是它限制為單一值。
  • 這些端點會取代最上層 Urls 組態中定義的端點,而不是新增至其中。 透過 Listen 在程式碼中定義的端點,會與組態區段中定義的端點累計。
  • Certificate 區段是選擇性的。 如果未指定 Certificate 區段,則會使用 Certificates:Default 中定義的預設值。 如果沒有可用的預設值,則會使用開發憑證。 如果沒有預設值且開發憑證不存在,伺服器會擲回例外狀況,且無法啟動。
  • Certificate 區段支援多個憑證來源
  • 只要不會造成連接埠衝突,就可以在組態中定義任何數目的端點。

憑證來源

憑證節點可以設定為從許多來源載入憑證:

  • PathPassword,供載入 .pfx 檔案。
  • PathKeyPathPassword,供載入 .pem/.crt.key 檔案。
  • SubjectStore,從憑證存放區載入。

例如,可將 Certificates:Default 憑證指定為:

"Default": {
  "Subject": "<subject; required>",
  "Store": "<cert store; required>",
  "Location": "<location; defaults to CurrentUser>",
  "AllowInvalid": "<true or false; defaults to false>"
}

ConfigurationLoader

Configure(IConfiguration) 會傳回 KestrelConfigurationLoaderEndpoint(String, Action<EndpointConfiguration>) 方法,此方法可用來補充已設定的端點設定:

var builder = WebApplication.CreateBuilder(args);

builder.WebHost.ConfigureKestrel((context, serverOptions) =>
{
    var kestrelSection = context.Configuration.GetSection("Kestrel");

    serverOptions.Configure(kestrelSection)
        .Endpoint("HTTPS", listenOptions =>
        {
            // ...
        });
});

您可以直接存取 KestrelServerOptions.ConfigurationLoader,以繼續逐一查看現有的載入器,例如 WebApplicationBuilder.WebHost 所提供的載入器。

  • 每個端點的組態區段可用於 Endpoint 方法的選項,因此可讀取自訂設定。
  • 可以藉由使用另一個區段再次呼叫 Configure(IConfiguration) 而載入多個組態。 只會使用最後一個組態,除非在先前的執行個體上已明確呼叫 Load。 中繼套件不會呼叫 Load,如此可能會取代其預設組態區段。
  • KestrelConfigurationLoader 會將來自 KestrelServerOptions 的 API 的 Listen 系列鏡像為 Endpoint 多載,所以可在相同的位置設定程式碼和設定端點。 這些多載不使用名稱,並且只使用來自組態的預設組態。

變更程式碼中的預設值

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

var builder = WebApplication.CreateBuilder(args);

builder.WebHost.ConfigureKestrel((context, serverOptions) =>
{
    serverOptions.ConfigureEndpointDefaults(listenOptions =>
    {
        // ...
    });

    serverOptions.ConfigureHttpsDefaults(listenOptions =>
    {
        // ...
    });
});

使用伺服器名稱指示以設定端點

伺服器名稱指示 (SNI) 可以用於在相同的 IP 位址和連接埠上裝載多個網域。 SNI 若要運作,用戶端會在 TLS 信號交換期間傳送安全工作階段的主機名稱給伺服器,讓伺服器可以提供正確的憑證。 用戶端在 TLS 信號交換之後的安全工作階段期間,會使用所提供的憑證與伺服器進行加密通訊。

SNI 有兩種設定方式:

  • 在程式碼中建立端點,並使用主機名稱搭配 ServerCertificateSelector 回呼來選取憑證。
  • [組態] 中設定主機名稱與 HTTPS 選項之間的對應。 例如,appsettings.json 檔案中的 JSON。

SNI 搭配 ServerCertificateSelector

Kestrel 透過 ServerCertificateSelector 回呼來支援 SNI。 每個連線會叫用回呼一次,以允許應用程式檢查主機名稱並選取適當的憑證。

var builder = WebApplication.CreateBuilder(args);

builder.WebHost.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)
            {
                ["localhost"] = localhostCert,
                ["example.com"] = exampleCert,
                ["sub.example.com"] = subExampleCert
            };

            httpsOptions.ServerCertificateSelector = (connectionContext, name) =>
            {
                if (name is not null && certs.TryGetValue(name, out var cert))
                {
                    return cert;
                }

                return exampleCert;
            };
        });
    });
});

SNI 搭配 ServerOptionsSelectionCallback

Kestrel 透過 ServerOptionsSelectionCallback 回呼支援其他動態 TLS 組態。 每個連線會叫用回呼一次,以允許應用程式檢查主機名稱,並選取適當的憑證和 TLS 組態。 預設憑證和 ConfigureHttpsDefaults 不會與這個回呼搭配使用。

var builder = WebApplication.CreateBuilder(args);

builder.WebHost.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);

            listenOptions.UseHttps((stream, clientHelloInfo, state, cancellationToken) =>
            {
                if (string.Equals(clientHelloInfo.ServerName, "localhost",
                    StringComparison.OrdinalIgnoreCase))
                {
                    return new ValueTask<SslServerAuthenticationOptions>(
                        new SslServerAuthenticationOptions
                        {
                            ServerCertificate = localhostCert,
                            // Different TLS requirements for this host
                            ClientCertificateRequired = true
                        });
                }

                return new ValueTask<SslServerAuthenticationOptions>(
                    new SslServerAuthenticationOptions
                    {
                        ServerCertificate = exampleCert
                    });
            }, state: null!);
        });
    });
});

SNI 搭配 TlsHandshakeCallbackOptions

Kestrel 透過 TlsHandshakeCallbackOptions.OnConnection 回呼來支援其他動態 TLS 組態。 每個連線會叫用回呼一次,以允許應用程式檢查主機名稱,並選取適當的憑證、TLS 組態和其他伺服器選項。 預設憑證和 ConfigureHttpsDefaults 不會與這個回呼搭配使用。

var builder = WebApplication.CreateBuilder(args);

builder.WebHost.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);

            listenOptions.UseHttps(new TlsHandshakeCallbackOptions
            {
                OnConnection = context =>
                {
                    if (string.Equals(context.ClientHelloInfo.ServerName, "localhost",
                        StringComparison.OrdinalIgnoreCase))
                    {
                        // Different TLS requirements for this host
                        context.AllowDelayedClientCertificateNegotation = true;

                        return new ValueTask<SslServerAuthenticationOptions>(
                            new SslServerAuthenticationOptions
                            {
                                ServerCertificate = localhostCert
                            });
                    }

                    return new ValueTask<SslServerAuthenticationOptions>(
                        new SslServerAuthenticationOptions
                        {
                            ServerCertificate = exampleCert
                        });
                }
            });
        });
    });
});

組態中的 SNI

Kestrel 支援在組態中定義的 SNI。 您可以使用 Sni 物件來設定端點,該物件中包含主機名稱與 HTTPS 選項之間的對應。 連線主機名稱會與選項進行比對,然後用於該連線。

下列組態會新增名為 MySniEndpoint 的端點,該端點會使用 SNI 來根據主機名稱選取 HTTPS 選項:

{
  "Kestrel": {
    "Endpoints": {
      "MySniEndpoint": {
        "Url": "https://*",
        "SslProtocols": ["Tls11", "Tls12"],
        "Sni": {
          "a.example.org": {
            "Protocols": "Http1AndHttp2",
            "SslProtocols": ["Tls11", "Tls12", "Tls13"],
            "Certificate": {
              "Subject": "<subject; required>",
              "Store": "<certificate store; required>",
            },
            "ClientCertificateMode" : "NoCertificate"
          },
          "*.example.org": {
            "Certificate": {
              "Path": "<path to .pfx file>",
              "Password": "$CREDENTIAL_PLACEHOLDER$"
            }
          },
          "*": {
            // At least one subproperty needs to exist per SNI section or it
            // cannot be discovered via IConfiguration
            "Protocols": "Http1",
          }
        }
      }
    },
    "Certificates": {
      "Default": {
        "Path": "<path to .pfx file>",
        "Password": "$CREDENTIAL_PLACEHOLDER$"
      }
    }
  }
}

警告

在上述範例中,憑證密碼會以純文字形式儲存在 appsettings.json中。 $CREDENTIAL_PLACEHOLDER$ 權杖會作為每個憑證密碼的預留位置。 若要安全地將憑證密碼儲存在開發環境中,請參閱在開發過程中保護祕密。 若要安全地將憑證密碼儲存在生產環境中,請參閱 Azure Key Vault 組態提供者。 開發秘密不應該用於生產或測試。

SNI 可以覆寫的 HTTPS 選項:

主機名稱支援萬用字元比對:

  • 完全相符。 例如,a.example.org 符合 a.example.org
  • 萬用字元首碼。 如果有多個萬用字元相符,則會選擇最長的模式。 例如,*.example.org 符合 b.example.orgc.example.org
  • 完整萬用字元。 * 會比對其他所有內容,包括未使用 SNI 且不會傳送主機名稱的用戶端。

相符的 SNI 組態會套用至連線的端點,並覆寫端點上的值。 如果連線不符合設定的 SNI 主機名稱,則會拒絕連線。

SNI 需求

所有網站都必須在相同的 Kestrel 執行個體上執行。 在不使用反向 Proxy 的情況下,Kestrel 不支援跨多個執行個體共用 IP 位址和連接埠。

SSL/TLS 通訊協定

SSL 通訊協定是用來加密和解密兩個同儕節點 (傳統上是用戶端與伺服器) 之間流量的通訊協定。

var builder = WebApplication.CreateBuilder(args);

builder.WebHost.ConfigureKestrel(serverOptions =>
{
    serverOptions.ConfigureHttpsDefaults(listenOptions =>
    {
        listenOptions.SslProtocols = SslProtocols.Tls13;
    });
});
{
  "Kestrel": {
    "Endpoints": {
      "MyHttpsEndpoint": {
        "Url": "https://localhost:5001",
        "SslProtocols": ["Tls12", "Tls13"],
        "Certificate": {
          "Path": "<path to .pfx file>",
          "Password": "$CREDENTIAL_PLACEHOLDER$"
        }
      }
    }
  }
}

警告

在上述範例中,憑證密碼會以純文字形式儲存在 appsettings.json 中。 $CREDENTIAL_PLACEHOLDER$ 權杖會作為憑證密碼的預留位置。 若要安全地將憑證密碼儲存在開發環境中,請參閱在開發過程中保護祕密。 若要安全地將憑證密碼儲存在生產環境中,請參閱 Azure Key Vault 組態提供者。 開發秘密不應該用於生產或測試。

預設值 SslProtocols.None 會導致 Kestrel 使用作業系統預設值來選擇最佳通訊協定。 除非您有特殊原因要選取某一通訊協定,否則請使用預設值。

用戶端憑證

ClientCertificateMode 會設定用戶端憑證需求

var builder = WebApplication.CreateBuilder(args);

builder.WebHost.ConfigureKestrel(serverOptions =>
{
    serverOptions.ConfigureHttpsDefaults(listenOptions =>
    {
        listenOptions.ClientCertificateMode = ClientCertificateMode.AllowCertificate;
    });
});
{
  "Kestrel": {
    "Endpoints": {
      "MyHttpsEndpoint": {
        "Url": "https://localhost:5001",
        "ClientCertificateMode": "AllowCertificate",
        "Certificate": {
          "Path": "<path to .pfx file>",
          "Password": "$CREDENTIAL_PLACEHOLDER$"
        }
      }
    }
  }
}

警告

在上述範例中,憑證密碼會以純文字形式儲存在 appsettings.json 中。 $CREDENTIAL_PLACEHOLDER$ 權杖會作為憑證密碼的預留位置。 若要安全地將憑證密碼儲存在開發環境中,請參閱在開發過程中保護祕密。 若要安全地將憑證密碼儲存在生產環境中,請參閱 Azure Key Vault 組態提供者

預設值為 ClientCertificateMode.NoCertificate,其中 Kestrel 不會向用戶端要求憑證。

如需詳細資訊,請參閱在 ASP.NET Core 中設定憑證驗證

連線記錄

呼叫 UseConnectionLogging,以在連線上發出位元組層級通訊的偵錯層級記錄。 連線記錄有助於對低階通訊中的問題進行疑難排解,例如 TLS 加密期間和 Proxy 後面的問題。 如果將 UseConnectionLogging 放在 UseHttps 之前,則會記錄加密流量。 如果將 UseConnectionLogging 放在 UseHttps 之後,則會記錄解密流量。 這是內建的連線中介軟體

var builder = WebApplication.CreateBuilder(args);

builder.WebHost.ConfigureKestrel((context, serverOptions) =>
{
    serverOptions.Listen(IPAddress.Any, 8000, listenOptions =>
    {
        listenOptions.UseConnectionLogging();
    });
});

繫結至 TCP 通訊端

Listen 方法會繫結至 TCP 通訊端,而選項 Lambda 則會允許 X.509 憑證設定:

var builder = WebApplication.CreateBuilder(args);

builder.WebHost.ConfigureKestrel((context, serverOptions) =>
{
    serverOptions.Listen(IPAddress.Loopback, 5000);
    serverOptions.Listen(IPAddress.Loopback, 5001, listenOptions =>
    {
        listenOptions.UseHttps("testCert.pfx", "testPassword");
    });
});

此範例使用 ListenOptions來為端點設定 HTTPS。 若要設定特定端點的其他 Kestrel 設定,請使用相同的 API。

在 Windows 上,可以使用 New-SelfSignedCertificate PowerShell Cmdlet 建立自我簽署憑證。 如需不支援的範例,請參閱 UpdateIISExpressSSLForChrome.ps1

在 macOS、Linux 和 Windows 上,可以使用 OpenSSL \(英文\) 建立憑證。

繫結至 Unix 通訊端

請使用 ListenUnixSocket 在 Unix 通訊端上進行接聽以改善 Nginx 的效能,如此範例所示:

var builder = WebApplication.CreateBuilder(args);

builder.WebHost.ConfigureKestrel((context, serverOptions) =>
{
    serverOptions.ListenUnixSocket("/tmp/kestrel-test.sock");
});
  • 在 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 在執行階段繫結至哪一個連接埠:

app.Run(async (context) =>
{
    var serverAddressFeature = context.Features.Get<IServerAddressesFeature>();

    if (serverAddressFeature is not null)
    {
        var listenAddresses = string.Join(", ", serverAddressFeature.Addresses);

        // ...
    }
});

在某些情況下,無法使用連接埠動態繫結:

  • ListenLocalhost
  • 將 TCP 型 HTTP/1.1 或 HTTP/2 與 QUIC 型 HTTP/3 繫結在一起。

限制

使用下列方法來設定端點:

  • 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 的情況下使用。
Http3 僅限 HTTP/3。 需要 TLS。 用戶端可能需要設定為僅使用 HTTP/3。
Http1AndHttp2 HTTP/1.1 和 HTTP/2。 HTTP/2 要求用戶端在 TLS 應用程式層通訊協定交涉 (ALPN) 交握中選取 HTTP/2;否則,連線會預設為 HTTP/1.1。
Http1AndHttp2AndHttp3 HTTP/1.1、HTTP/2 和 HTTP/3。 第一個用戶端要求通常會使用 HTTP/1.1 或 HTTP/2,而 alt-svc 回應標頭會提示用戶端升級至 HTTP/3。 HTTP/2 和 HTTP/3 需要 TLS;否則,連線會預設為 HTTP/1.1。

任何端點的預設 ListenOptions.Protocols 值為 HttpProtocols.Http1AndHttp2

HTTP/2 的 TLS 限制:

  • TLS 1.2 版或更新版本
  • 已停用重新交涉
  • 已停用壓縮
  • 暫時金鑰交換大小下限:
    • 橢圓曲線 Diffie-Hellman (ECDHE) [RFC4492]:最小 224 個位元
    • 有限欄位 Diffie-Hellman (DHE) [TLS12]:最小 2048 個位元
  • 未禁止使用加密套件。

預設支援 TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 [TLS-ECDHE] 與 P-256 橢圓曲線 [FIPS186]。

下列範例會允許連接埠 8000 上的 HTTP/1.1 和 HTTP/2 連線。 這些連線使用提供的憑證受到 TLS 保護:

var builder = WebApplication.CreateBuilder(args);

builder.WebHost.ConfigureKestrel((context, serverOptions) =>
{
    serverOptions.Listen(IPAddress.Any, 8000, listenOptions =>
    {
        listenOptions.UseHttps("testCert.pfx", "testPassword");
        listenOptions.Protocols = HttpProtocols.Http1AndHttp2AndHttp3;
    });
});

在 Linux 上,可以使用 CipherSuitesPolicy 來根據每個連線篩選 TLS 交握:

var builder = WebApplication.CreateBuilder(args);

builder.WebHost.ConfigureKestrel((context, 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,
                    // ...
                });
        };
    });
});

連線中介軟體

必要時,自訂連線中介軟體可以依據個別連線篩選 TLS 交握。

下列範例會針對應用程式不支援的任何加密演算法擲回 NotSupportedException。 或者,定義 ITlsHandshakeFeature.CipherAlgorithm 並將其與可接受的加密套件清單進行比較。

CipherAlgorithmType.Null 加密演算法不會使用任何加密。

var builder = WebApplication.CreateBuilder(args);

builder.WebHost.ConfigureKestrel((context, 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();
        });
    });
});

從組態設定 HTTP 通訊協定

根據預設,會從 Kestrel 區段載入 Kestrel 組態。 下列 appsettings.json 範例會建立 HTTP/1.1 作為所有端點的預設連線通訊協定:

{
  "Kestrel": {
    "EndpointDefaults": {
      "Protocols": "Http1"
    }
  }
}

下列 appsettings.json 範例會針對特定端點建立 HTTP/1.1 連線通訊協定:

{
  "Kestrel": {
    "Endpoints": {
      "HttpsDefaultCert": {
        "Url": "https://localhost:5001",
        "Protocols": "Http1"
      }
    }
  }
}

程式碼中指定的通訊協定會覆寫設定所設定的值。

URL 前置詞

使用 UseUrls--urls 命令列引數、urls 主機組態索引鍵或 ASPNETCORE_URLS 環境變數時,URL 前置詞可以採用下列任一格式。

只有 HTTP URL 前置詞有效。 使用 UseUrls 設定 URL 繫結時,Kestrel 不支援 HTTPS。

  • IPv4 位址與連接埠號碼

    http://65.55.39.10:80/
    

    0.0.0.0 是繫結至所有 IPv4 位址的特殊情況。

  • IPv6 位址與連接埠號碼

    http://[0:0:0:0:0:ffff:4137:270a]:80/
    

    [::] 是相當於 IPv4 0.0.0.0 的 IPv6 對等項目。

  • 主機名稱與連接埠號碼

    http://contoso.com:80/
    http://*:80/
    

    主機名稱 *+ 並不特殊。 無法辨識為有效 IP 位址或 localhost 的任何項目,都會繫結至所有 IPv4 和 IPv6 IP。 若要將不同主機名稱繫結至同一連接埠上的不同 ASP.NET Core 應用程式,請使用 HTTP.sys 或反向 Proxy 伺服器。 反向 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 就會記錄警告。

ASP.NET Core 專案設定為繫結至介於 5000-5300 之間的隨機 HTTP 連接埠,以及介於 7000-7300 之間的隨機 HTTPS 連接埠。 這個預設組態是在產生的 Properties/launchSettings.json 檔案中指定,而且可以覆寫。 如果未指定任何連接埠,Kestrel 會繫結至:

  • 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 支援

請在 KestrelServerOptions 上呼叫 ListenListenUnixSocket 方法,來為 Kestrel 設定 URL 首碼和連接埠。

UseUrls--urls 命令列引數、urls 主機組態索引鍵和 ASPNETCORE_URLS 環境變數同樣有效,但卻有本節稍後註明的限制 (針對 HTTPS 端點組態必須有預設憑證可用)。

KestrelServerOptions 組態:

ConfigureEndpointDefaults

ConfigureEndpointDefaults(Action<ListenOptions>) 會指定組態 Action 以針對每個指定端點執行。 呼叫 ConfigureEndpointDefaults 多次會以最後指定的 Action 取代之前的 Action

var builder = WebApplication.CreateBuilder(args);

builder.WebHost.ConfigureKestrel(serverOptions =>
{
    serverOptions.ConfigureEndpointDefaults(listenOptions =>
    {
        // ...
    });
});

注意

透過呼叫 Listen 之前呼叫 ConfigureEndpointDefaults 所建立的端點,不會套用預設值。

Configure(IConfiguration)

允許 Kestrel 從 IConfiguration 載入端點。 組態的範圍必須限定為 Kestrel 的組態區段。 Configure(IConfiguration, bool) 多載可用來在組態來源變更時啟用重載端點。

根據預設,會從 Kestrel 區段載入 Kestrel 組態,並啟用重載變更:

{
  "Kestrel": {
    "Endpoints": {
      "Http": {
        "Url": "http://localhost:5000"
      },
      "Https": {
        "Url": "https://localhost:5001"
      }
    }
  }
}

如果已啟用重載組態並發出變更訊號,則會採取下列步驟:

  • 新的組態會與舊組態進行比較,不會修改任何沒有組態變更的端點。
  • 移除或修改的端點會分配 5 秒的時間來完成處理要求並關閉。
  • 啟動新的或修改的端點。

重新啟動端點時,連線到修改後端點的用戶端可能會中斷連線或遭拒絕。

ConfigureHttpsDefaults

ConfigureHttpsDefaults(Action<HttpsConnectionAdapterOptions>) 會指定組態 Action 以針對每個 HTTPS 端點執行。 呼叫 ConfigureHttpsDefaults 多次會以最後一個指定的 Action 取代之前的 Action

var builder = WebApplication.CreateBuilder(args);

builder.WebHost.ConfigureKestrel(serverOptions =>
{
    serverOptions.ConfigureHttpsDefaults(listenOptions =>
    {
        // ...
    });
});

注意

透過呼叫 Listen 之前呼叫 ConfigureHttpsDefaults 所建立的端點,不會套用預設值。

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:5000https://localhost:5001 (如果預設憑證可用)。

從組態取代預設憑證

Kestrel 可以使用預設的 HTTPS 應用程式設定組態結構描述。 設定多個端點,包括 URL 和要使用的憑證-從磁碟上的檔案,或是從憑證存放區。

在下列 appsettings.json 範例中:

  • AllowInvalid 設定為 true,允許使用無效的憑證 (例如,自我簽署憑證)。
  • 任何未指定憑證 (接下來範例中的 HttpsDefaultCert) 的 HTTPS 端點會回復為在 Certificates:Default 或開發憑證下定義的憑證。
{
  "Kestrel": {
    "Endpoints": {
      "Http": {
        "Url": "http://localhost:5000"
      },
      "HttpsInlineCertFile": {
        "Url": "https://localhost:5001",
        "Certificate": {
          "Path": "<path to .pfx file>",
          "Password": "$CREDENTIAL_PLACEHOLDER$"
        }
      },
      "HttpsInlineCertAndKeyFile": {
        "Url": "https://localhost:5002",
        "Certificate": {
          "Path": "<path to .pem/.crt file>",
          "KeyPath": "<path to .key file>",
          "Password": "$CREDENTIAL_PLACEHOLDER$"
        }
      },
      "HttpsInlineCertStore": {
        "Url": "https://localhost:5003",
        "Certificate": {
          "Subject": "<subject; required>",
          "Store": "<certificate store; required>",
          "Location": "<location; defaults to CurrentUser>",
          "AllowInvalid": "<true or false; defaults to false>"
        }
      },
      "HttpsDefaultCert": {
        "Url": "https://localhost:5004"
      }
    },
    "Certificates": {
      "Default": {
        "Path": "<path to .pfx file>",
        "Password": "$CREDENTIAL_PLACEHOLDER$"
      }
    }
  }
}

警告

在上述範例中,憑證密碼會以純文字形式儲存在 appsettings.json中。 $CREDENTIAL_PLACEHOLDER$ 權杖會作為每個憑證密碼的預留位置。 若要安全地將憑證密碼儲存在開發環境中,請參閱在開發過程中保護祕密。 若要安全地將憑證密碼儲存在生產環境中,請參閱 Azure Key Vault 組態提供者。 開發秘密不應該用於生產或測試。

結構描述附註:

  • 端點名稱不區分大小寫。 例如,HTTPSHttps 彼此相等。
  • Url 參數對每個端點而言都是必要的。 此參數的格式等同於最上層 Urls 組態參數,但是它限制為單一值。
  • 這些端點會取代最上層 Urls 組態中定義的端點,而不是新增至其中。 透過 Listen 在程式碼中定義的端點,會與組態區段中定義的端點累計。
  • Certificate 區段是選擇性的。 如果未指定 Certificate 區段,則會使用 Certificates:Default 中定義的預設值。 如果沒有可用的預設值,則會使用開發憑證。 如果沒有預設值且開發憑證不存在,伺服器會擲回例外狀況,且無法啟動。
  • Certificate 區段支援多個憑證來源
  • 只要不會造成連接埠衝突,就可以在組態中定義任何數目的端點。

憑證來源

憑證節點可以設定為從許多來源載入憑證:

  • PathPassword,供載入 .pfx 檔案。
  • PathKeyPathPassword,供載入 .pem/.crt.key 檔案。
  • SubjectStore,從憑證存放區載入。

例如,可將 Certificates:Default 憑證指定為:

"Default": {
  "Subject": "<subject; required>",
  "Store": "<cert store; required>",
  "Location": "<location; defaults to CurrentUser>",
  "AllowInvalid": "<true or false; defaults to false>"
}

ConfigurationLoader

Configure(IConfiguration) 會傳回 KestrelConfigurationLoaderEndpoint(String, Action<EndpointConfiguration>) 方法,此方法可用來補充已設定的端點設定:

var builder = WebApplication.CreateBuilder(args);

builder.WebHost.ConfigureKestrel((context, serverOptions) =>
{
    var kestrelSection = context.Configuration.GetSection("Kestrel");

    serverOptions.Configure(kestrelSection)
        .Endpoint("HTTPS", listenOptions =>
        {
            // ...
        });
});

您可以直接存取 KestrelServerOptions.ConfigurationLoader,以繼續逐一查看現有的載入器,例如 WebApplicationBuilder.WebHost 所提供的載入器。

  • 每個端點的組態區段可用於 Endpoint 方法的選項,因此可讀取自訂設定。
  • 可以藉由使用另一個區段再次呼叫 Configure(IConfiguration) 而載入多個組態。 只會使用最後一個組態,除非在先前的執行個體上已明確呼叫 Load。 中繼套件不會呼叫 Load,如此可能會取代其預設組態區段。
  • KestrelConfigurationLoader 會將來自 KestrelServerOptions 的 API 的 Listen 系列鏡像為 Endpoint 多載,所以可在相同的位置設定程式碼和設定端點。 這些多載不使用名稱,並且只使用來自組態的預設組態。

變更程式碼中的預設值

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

var builder = WebApplication.CreateBuilder(args);

builder.WebHost.ConfigureKestrel((context, serverOptions) =>
{
    serverOptions.ConfigureEndpointDefaults(listenOptions =>
    {
        // ...
    });

    serverOptions.ConfigureHttpsDefaults(listenOptions =>
    {
        // ...
    });
});

使用伺服器名稱指示以設定端點

伺服器名稱指示 (SNI) 可以用於在相同的 IP 位址和連接埠上裝載多個網域。 SNI 若要運作,用戶端會在 TLS 信號交換期間傳送安全工作階段的主機名稱給伺服器,讓伺服器可以提供正確的憑證。 用戶端在 TLS 信號交換之後的安全工作階段期間,會使用所提供的憑證與伺服器進行加密通訊。

SNI 有兩種設定方式:

  • 在程式碼中建立端點,並使用主機名稱搭配 ServerCertificateSelector 回呼來選取憑證。
  • [組態] 中設定主機名稱與 HTTPS 選項之間的對應。 例如,appsettings.json 檔案中的 JSON。

SNI 搭配 ServerCertificateSelector

Kestrel 透過 ServerCertificateSelector 回呼來支援 SNI。 每個連線會叫用回呼一次,以允許應用程式檢查主機名稱並選取適當的憑證。

var builder = WebApplication.CreateBuilder(args);

builder.WebHost.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)
            {
                ["localhost"] = localhostCert,
                ["example.com"] = exampleCert,
                ["sub.example.com"] = subExampleCert
            };

            httpsOptions.ServerCertificateSelector = (connectionContext, name) =>
            {
                if (name is not null && certs.TryGetValue(name, out var cert))
                {
                    return cert;
                }

                return exampleCert;
            };
        });
    });
});

SNI 搭配 ServerOptionsSelectionCallback

Kestrel 透過 ServerOptionsSelectionCallback 回呼支援其他動態 TLS 組態。 每個連線會叫用回呼一次,以允許應用程式檢查主機名稱,並選取適當的憑證和 TLS 組態。 預設憑證和 ConfigureHttpsDefaults 不會與這個回呼搭配使用。

var builder = WebApplication.CreateBuilder(args);

builder.WebHost.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);

            listenOptions.UseHttps((stream, clientHelloInfo, state, cancellationToken) =>
            {
                if (string.Equals(clientHelloInfo.ServerName, "localhost",
                    StringComparison.OrdinalIgnoreCase))
                {
                    return new ValueTask<SslServerAuthenticationOptions>(
                        new SslServerAuthenticationOptions
                        {
                            ServerCertificate = localhostCert,
                            // Different TLS requirements for this host
                            ClientCertificateRequired = true
                        });
                }

                return new ValueTask<SslServerAuthenticationOptions>(
                    new SslServerAuthenticationOptions
                    {
                        ServerCertificate = exampleCert
                    });
            }, state: null!);
        });
    });
});

SNI 搭配 TlsHandshakeCallbackOptions

Kestrel 透過 TlsHandshakeCallbackOptions.OnConnection 回呼來支援其他動態 TLS 組態。 每個連線會叫用回呼一次,以允許應用程式檢查主機名稱,並選取適當的憑證、TLS 組態和其他伺服器選項。 預設憑證和 ConfigureHttpsDefaults 不會與這個回呼搭配使用。

var builder = WebApplication.CreateBuilder(args);

builder.WebHost.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);

            listenOptions.UseHttps(new TlsHandshakeCallbackOptions
            {
                OnConnection = context =>
                {
                    if (string.Equals(context.ClientHelloInfo.ServerName, "localhost",
                        StringComparison.OrdinalIgnoreCase))
                    {
                        // Different TLS requirements for this host
                        context.AllowDelayedClientCertificateNegotation = true;

                        return new ValueTask<SslServerAuthenticationOptions>(
                            new SslServerAuthenticationOptions
                            {
                                ServerCertificate = localhostCert
                            });
                    }

                    return new ValueTask<SslServerAuthenticationOptions>(
                        new SslServerAuthenticationOptions
                        {
                            ServerCertificate = exampleCert
                        });
                }
            });
        });
    });
});

組態中的 SNI

Kestrel 支援在組態中定義的 SNI。 您可以使用 Sni 物件來設定端點,該物件中包含主機名稱與 HTTPS 選項之間的對應。 連線主機名稱會與選項進行比對,然後用於該連線。

下列組態會新增名為 MySniEndpoint 的端點,該端點會使用 SNI 來根據主機名稱選取 HTTPS 選項:

{
  "Kestrel": {
    "Endpoints": {
      "MySniEndpoint": {
        "Url": "https://*",
        "SslProtocols": ["Tls11", "Tls12"],
        "Sni": {
          "a.example.org": {
            "Protocols": "Http1AndHttp2",
            "SslProtocols": ["Tls11", "Tls12", "Tls13"],
            "Certificate": {
              "Subject": "<subject; required>",
              "Store": "<certificate store; required>",
            },
            "ClientCertificateMode" : "NoCertificate"
          },
          "*.example.org": {
            "Certificate": {
              "Path": "<path to .pfx file>",
              "Password": "$CREDENTIAL_PLACEHOLDER$"
            }
          },
          "*": {
            // At least one subproperty needs to exist per SNI section or it
            // cannot be discovered via IConfiguration
            "Protocols": "Http1",
          }
        }
      }
    },
    "Certificates": {
      "Default": {
        "Path": "<path to .pfx file>",
        "Password": "$CREDENTIAL_PLACEHOLDER$"
      }
    }
  }
}

警告

在上述範例中,憑證密碼會以純文字形式儲存在 appsettings.json中。 $CREDENTIAL_PLACEHOLDER$ 權杖會作為每個憑證密碼的預留位置。 若要安全地將憑證密碼儲存在開發環境中,請參閱在開發過程中保護祕密。 若要安全地將憑證密碼儲存在生產環境中,請參閱 Azure Key Vault 組態提供者。 開發秘密不應該用於生產或測試。

SNI 可以覆寫的 HTTPS 選項:

主機名稱支援萬用字元比對:

  • 完全相符。 例如,a.example.org 符合 a.example.org
  • 萬用字元首碼。 如果有多個萬用字元相符,則會選擇最長的模式。 例如,*.example.org 符合 b.example.orgc.example.org
  • 完整萬用字元。 * 會比對其他所有內容,包括未使用 SNI 且不會傳送主機名稱的用戶端。

相符的 SNI 組態會套用至連線的端點,並覆寫端點上的值。 如果連線不符合設定的 SNI 主機名稱,則會拒絕連線。

SNI 需求

所有網站都必須在相同的 Kestrel 執行個體上執行。 在不使用反向 Proxy 的情況下,Kestrel 不支援跨多個執行個體共用 IP 位址和連接埠。

SSL/TLS 通訊協定

SSL 通訊協定是用來加密和解密兩個同儕節點 (傳統上是用戶端與伺服器) 之間流量的通訊協定。

var builder = WebApplication.CreateBuilder(args);

builder.WebHost.ConfigureKestrel(serverOptions =>
{
    serverOptions.ConfigureHttpsDefaults(listenOptions =>
    {
        listenOptions.SslProtocols = SslProtocols.Tls13;
    });
});
{
  "Kestrel": {
    "Endpoints": {
      "MyHttpsEndpoint": {
        "Url": "https://localhost:5001",
        "SslProtocols": ["Tls12", "Tls13"],
        "Certificate": {
          "Path": "<path to .pfx file>",
          "Password": "$CREDENTIAL_PLACEHOLDER$"
        }
      }
    }
  }
}

警告

在上述範例中,憑證密碼會以純文字形式儲存在 appsettings.json 中。 $CREDENTIAL_PLACEHOLDER$ 權杖會作為憑證密碼的預留位置。 若要安全地將憑證密碼儲存在開發環境中,請參閱在開發過程中保護祕密。 若要安全地將憑證密碼儲存在生產環境中,請參閱 Azure Key Vault 組態提供者。 開發秘密不應該用於生產或測試。

預設值 SslProtocols.None 會導致 Kestrel 使用作業系統預設值來選擇最佳通訊協定。 除非您有特殊原因要選取某一通訊協定,否則請使用預設值。

用戶端憑證

ClientCertificateMode 會設定用戶端憑證需求

var builder = WebApplication.CreateBuilder(args);

builder.WebHost.ConfigureKestrel(serverOptions =>
{
    serverOptions.ConfigureHttpsDefaults(listenOptions =>
    {
        listenOptions.ClientCertificateMode = ClientCertificateMode.AllowCertificate;
    });
});
{
  "Kestrel": {
    "Endpoints": {
      "MyHttpsEndpoint": {
        "Url": "https://localhost:5001",
        "ClientCertificateMode": "AllowCertificate",
        "Certificate": {
          "Path": "<path to .pfx file>",
          "Password": "$CREDENTIAL_PLACEHOLDER$"
        }
      }
    }
  }
}

警告

在上述範例中,憑證密碼會以純文字形式儲存在 appsettings.json 中。 $CREDENTIAL_PLACEHOLDER$ 權杖會作為憑證密碼的預留位置。 若要安全地將憑證密碼儲存在開發環境中,請參閱在開發過程中保護祕密。 若要安全地將憑證密碼儲存在生產環境中,請參閱 Azure Key Vault 組態提供者

預設值為 ClientCertificateMode.NoCertificate,其中 Kestrel 不會向用戶端要求憑證。

如需詳細資訊,請參閱在 ASP.NET Core 中設定憑證驗證

連線記錄

呼叫 UseConnectionLogging,以在連線上發出位元組層級通訊的偵錯層級記錄。 連線記錄有助於對低階通訊中的問題進行疑難排解,例如 TLS 加密期間和 Proxy 後面的問題。 如果將 UseConnectionLogging 放在 UseHttps 之前,則會記錄加密流量。 如果將 UseConnectionLogging 放在 UseHttps 之後,則會記錄解密流量。 這是內建的連線中介軟體

var builder = WebApplication.CreateBuilder(args);

builder.WebHost.ConfigureKestrel((context, serverOptions) =>
{
    serverOptions.Listen(IPAddress.Any, 8000, listenOptions =>
    {
        listenOptions.UseConnectionLogging();
    });
});

繫結至 TCP 通訊端

Listen 方法會繫結至 TCP 通訊端,而選項 Lambda 則會允許 X.509 憑證設定:

var builder = WebApplication.CreateBuilder(args);

builder.WebHost.ConfigureKestrel((context, serverOptions) =>
{
    serverOptions.Listen(IPAddress.Loopback, 5000);
    serverOptions.Listen(IPAddress.Loopback, 5001, listenOptions =>
    {
        listenOptions.UseHttps("testCert.pfx", "testPassword");
    });
});

此範例使用 ListenOptions來為端點設定 HTTPS。 若要設定特定端點的其他 Kestrel 設定,請使用相同的 API。

在 Windows 上,可以使用 New-SelfSignedCertificate PowerShell Cmdlet 建立自我簽署憑證。 如需不支援的範例,請參閱 UpdateIISExpressSSLForChrome.ps1

在 macOS、Linux 和 Windows 上,可以使用 OpenSSL \(英文\) 建立憑證。

繫結至 Unix 通訊端

請使用 ListenUnixSocket 在 Unix 通訊端上進行接聽以改善 Nginx 的效能,如此範例所示:

var builder = WebApplication.CreateBuilder(args);

builder.WebHost.ConfigureKestrel((context, serverOptions) =>
{
    serverOptions.ListenUnixSocket("/tmp/kestrel-test.sock");
});
  • 在 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 在執行階段繫結至哪一個連接埠:

app.Run(async (context) =>
{
    var serverAddressFeature = context.Features.Get<IServerAddressesFeature>();

    if (serverAddressFeature is not null)
    {
        var listenAddresses = string.Join(", ", serverAddressFeature.Addresses);

        // ...
    }
});

限制

使用下列方法來設定端點:

  • 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 應用程式層通訊協定交涉 (ALPN) 交握中選取 HTTP/2;否則,連線會預設為 HTTP/1.1。

任何端點的預設 ListenOptions.Protocols 值為 HttpProtocols.Http1AndHttp2

HTTP/2 的 TLS 限制:

  • TLS 1.2 版或更新版本
  • 已停用重新交涉
  • 已停用壓縮
  • 暫時金鑰交換大小下限:
    • 橢圓曲線 Diffie-Hellman (ECDHE) [RFC4492]:最小 224 個位元
    • 有限欄位 Diffie-Hellman (DHE) [TLS12]:最小 2048 個位元
  • 未禁止使用加密套件。

預設支援 TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 [TLS-ECDHE] 與 P-256 橢圓曲線 [FIPS186]。

下列範例會允許連接埠 8000 上的 HTTP/1.1 和 HTTP/2 連線。 這些連線使用提供的憑證受到 TLS 保護:

var builder = WebApplication.CreateBuilder(args);

builder.WebHost.ConfigureKestrel((context, serverOptions) =>
{
    serverOptions.Listen(IPAddress.Any, 8000, listenOptions =>
    {
        listenOptions.UseHttps("testCert.pfx", "testPassword");
        listenOptions.Protocols = HttpProtocols.Http1AndHttp2AndHttp3;
    });
});

在 Linux 上,可以使用 CipherSuitesPolicy 來根據每個連線篩選 TLS 交握:

var builder = WebApplication.CreateBuilder(args);

builder.WebHost.ConfigureKestrel((context, 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,
                    // ...
                });
        };
    });
});

連線中介軟體

必要時,自訂連線中介軟體可以依據個別連線篩選 TLS 交握。

下列範例會針對應用程式不支援的任何加密演算法擲回 NotSupportedException。 或者,定義 ITlsHandshakeFeature.CipherAlgorithm 並將其與可接受的加密套件清單進行比較。

CipherAlgorithmType.Null 加密演算法不會使用任何加密。

var builder = WebApplication.CreateBuilder(args);

builder.WebHost.ConfigureKestrel((context, 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();
        });
    });
});

從組態設定 HTTP 通訊協定

根據預設,會從 Kestrel 區段載入 Kestrel 組態。 下列 appsettings.json 範例會建立 HTTP/1.1 作為所有端點的預設連線通訊協定:

{
  "Kestrel": {
    "EndpointDefaults": {
      "Protocols": "Http1"
    }
  }
}

下列 appsettings.json 範例會針對特定端點建立 HTTP/1.1 連線通訊協定:

{
  "Kestrel": {
    "Endpoints": {
      "HttpsDefaultCert": {
        "Url": "https://localhost:5001",
        "Protocols": "Http1"
      }
    }
  }
}

程式碼中指定的通訊協定會覆寫設定所設定的值。

URL 前置詞

使用 UseUrls--urls 命令列引數、urls 主機組態索引鍵或 ASPNETCORE_URLS 環境變數時,URL 前置詞可以採用下列任一格式。

只有 HTTP URL 前置詞有效。 使用 UseUrls 設定 URL 繫結時,Kestrel 不支援 HTTPS。

  • IPv4 位址與連接埠號碼

    http://65.55.39.10:80/
    

    0.0.0.0 是繫結至所有 IPv4 位址的特殊情況。

  • IPv6 位址與連接埠號碼

    http://[0:0:0:0:0:ffff:4137:270a]:80/
    

    [::] 是相當於 IPv4 0.0.0.0 的 IPv6 對等項目。

  • 主機名稱與連接埠號碼

    http://contoso.com:80/
    http://*:80/
    

    主機名稱 *+ 並不特殊。 無法辨識為有效 IP 位址或 localhost 的任何項目,都會繫結至所有 IPv4 和 IPv6 IP。 若要將不同主機名稱繫結至同一連接埠上的不同 ASP.NET Core 應用程式,請使用 HTTP.sys 或反向 Proxy 伺服器。 反向 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 就會記錄警告。

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 支援

請在 KestrelServerOptions 上呼叫 ListenListenUnixSocket 方法,來為 Kestrel 設定 URL 首碼和連接埠。

UseUrls--urls 命令列引數、urls 主機組態索引鍵和 ASPNETCORE_URLS 環境變數同樣有效,但卻有本節稍後註明的限制 (針對 HTTPS 端點組態必須有預設憑證可用)。

KestrelServerOptions 組態:

ConfigureEndpointDefaults

ConfigureEndpointDefaults(Action<ListenOptions>) 會指定組態 Action 以針對每個指定端點執行。 呼叫 ConfigureEndpointDefaults 多次會以最後一個指定的 Action 取代之前的 Action

webBuilder.ConfigureKestrel(serverOptions =>
{
    serverOptions.ConfigureEndpointDefaults(listenOptions =>
    {
        // Configure endpoint defaults
    });
});

注意

透過呼叫 Listen 之前呼叫 ConfigureEndpointDefaults 所建立的端點,不會套用預設值。

Configure(IConfiguration)

允許 Kestrel 從 IConfiguration 載入端點。 組態的範圍必須限定為 Kestrel 的組態區段。

Configure(IConfiguration, bool) 多載可用來在組態來源變更時啟用重載端點。

IHostBuilder.ConfigureWebHostDefaults 預設會呼叫 Configure(context.Configuration.GetSection("Kestrel"), reloadOnChange: true) 以載入 Kestrel 組態並啟用重載。

{
  "Kestrel": {
    "Endpoints": {
      "Http": {
        "Url": "http://localhost:5000"
      },
      "Https": {
        "Url": "https://localhost:5001"
      }
    }
  }
}

如果已啟用重載組態並發出變更訊號,則會採取下列步驟:

  • 新的組態會與舊組態進行比較,不會修改任何沒有組態變更的端點。
  • 移除或修改的端點會分配 5 秒的時間來完成處理要求並關閉。
  • 啟動新的或修改的端點。

重新啟動端點時,連線到修改後端點的用戶端可能會中斷連線或遭拒絕。

ConfigureHttpsDefaults

ConfigureHttpsDefaults(Action<HttpsConnectionAdapterOptions>) 會指定組態 Action 以針對每個 HTTPS 端點執行。 呼叫 ConfigureHttpsDefaults 多次會以最後一個指定的 Action 取代之前的 Action

webBuilder.ConfigureKestrel(serverOptions =>
{
    serverOptions.ConfigureHttpsDefaults(listenOptions =>
    {
        // certificate is an X509Certificate2
        listenOptions.ServerCertificate = certificate;
    });
});

注意

透過呼叫 Listen 之前呼叫 ConfigureHttpsDefaults 所建立的端點,不會套用預設值。

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:5000https://localhost:5001 (如果預設憑證可用)。

從組態取代預設憑證

Kestrel 可以使用預設的 HTTPS 應用程式設定組態結構描述。 設定多個端點,包括 URL 和要使用的憑證-從磁碟上的檔案,或是從憑證存放區。

在下列 appsettings.json 範例中:

  • AllowInvalid 設定為 true,允許使用無效的憑證 (例如,自我簽署憑證)。
  • 任何未指定憑證 (接下來範例中的 HttpsDefaultCert) 的 HTTPS 端點會回復為在 Certificates:Default 或開發憑證下定義的憑證。
{
  "Kestrel": {
    "Endpoints": {
      "Http": {
        "Url": "http://localhost:5000"
      },
      "HttpsInlineCertFile": {
        "Url": "https://localhost:5001",
        "Certificate": {
          "Path": "<path to .pfx file>",
          "Password": "$CREDENTIAL_PLACEHOLDER$"
        }
      },
      "HttpsInlineCertAndKeyFile": {
        "Url": "https://localhost:5002",
        "Certificate": {
          "Path": "<path to .pem/.crt file>",
          "KeyPath": "<path to .key file>",
          "Password": "$CREDENTIAL_PLACEHOLDER$"
        }
      },
      "HttpsInlineCertStore": {
        "Url": "https://localhost:5003",
        "Certificate": {
          "Subject": "<subject; required>",
          "Store": "<certificate store; required>",
          "Location": "<location; defaults to CurrentUser>",
          "AllowInvalid": "<true or false; defaults to false>"
        }
      },
      "HttpsDefaultCert": {
        "Url": "https://localhost:5004"
      }
    },
    "Certificates": {
      "Default": {
        "Path": "<path to .pfx file>",
        "Password": "$CREDENTIAL_PLACEHOLDER$"
      }
    }
  }
}

警告

在上述範例中,憑證密碼會以純文字形式儲存在 appsettings.json中。 $CREDENTIAL_PLACEHOLDER$ 權杖會作為每個憑證密碼的預留位置。 若要安全地將憑證密碼儲存在開發環境中,請參閱在開發過程中保護祕密。 若要安全地將憑證密碼儲存在生產環境中,請參閱 Azure Key Vault 組態提供者。 開發秘密不應該用於生產或測試。

結構描述附註:

  • 端點名稱不區分大小寫。 例如,HTTPSHttps 彼此相等。
  • Url 參數對每個端點而言都是必要的。 此參數的格式等同於最上層 Urls 組態參數,但是它限制為單一值。
  • 這些端點會取代最上層 Urls 組態中定義的端點,而不是新增至其中。 透過 Listen 在程式碼中定義的端點,會與組態區段中定義的端點累計。
  • Certificate 區段是選擇性的。 如果未指定 Certificate 區段,則會使用 Certificates:Default 中定義的預設值。 如果沒有可用的預設值,則會使用開發憑證。 如果沒有預設值且開發憑證不存在,伺服器會擲回例外狀況,且無法啟動。
  • Certificate 區段支援多個憑證來源
  • 只要不會造成連接埠衝突,就可以在組態中定義任何數目的端點。

憑證來源

憑證節點可以設定為從許多來源載入憑證:

  • PathPassword,供載入 .pfx 檔案。
  • PathKeyPathPassword,供載入 .pem/.crt.key 檔案。
  • SubjectStore,從憑證存放區載入。

例如,可將 Certificates:Default 憑證指定為:

"Default": {
  "Subject": "<subject; required>",
  "Store": "<cert store; required>",
  "Location": "<location; defaults to CurrentUser>",
  "AllowInvalid": "<true or false; defaults to false>"
}

ConfigurationLoader

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;
    });
});

使用伺服器名稱指示以設定端點

伺服器名稱指示 (SNI) 可以用於在相同的 IP 位址和連接埠上裝載多個網域。 SNI 若要運作,用戶端會在 TLS 信號交換期間傳送安全工作階段的主機名稱給伺服器,讓伺服器可以提供正確的憑證。 用戶端在 TLS 信號交換之後的安全工作階段期間,會使用所提供的憑證與伺服器進行加密通訊。

SNI 有兩種設定方式:

  • 在程式碼中建立端點,並使用主機名稱搭配 ServerCertificateSelector 回呼來選取憑證。
  • [組態] 中設定主機名稱與 HTTPS 選項之間的對應。 例如,appsettings.json 檔案中的 JSON。

SNI 搭配 ServerCertificateSelector

Kestrel 透過 ServerCertificateSelector 回呼來支援 SNI。 回呼會針對每個連線叫用一次,允許應用程式檢查主機名稱並選取適當的憑證。 下列回呼程式碼可用於專案 Program.cs 檔案的 ConfigureWebHostDefaults 方法呼叫中:

// using System.Security.Cryptography.X509Certificates;
// using Microsoft.AspNetCore.Server.Kestrel.Https;

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)
            {
                { "localhost", localhostCert },
                { "example.com", exampleCert },
                { "sub.example.com", subExampleCert },
            };            

            httpsOptions.ServerCertificateSelector = (connectionContext, name) =>
            {
                if (name != null && certs.TryGetValue(name, out var cert))
                {
                    return cert;
                }

                return exampleCert;
            };
        });
    });
});

SNI 搭配 ServerOptionsSelectionCallback

Kestrel 透過 ServerOptionsSelectionCallback 回呼支援其他動態 TLS 組態。 每個連線會叫用回呼一次,以允許應用程式檢查主機名稱,並選取適當的憑證和 TLS 組態。 預設憑證和 ConfigureHttpsDefaults 不會與這個回呼搭配使用。

// using System.Security.Cryptography.X509Certificates;
// using Microsoft.AspNetCore.Server.Kestrel.Https;

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);

            listenOptions.UseHttps((stream, clientHelloInfo, state, cancellationToken) =>
            {
                if (string.Equals(clientHelloInfo.ServerName, "localhost", StringComparison.OrdinalIgnoreCase))
                {
                    return new ValueTask<SslServerAuthenticationOptions>(new SslServerAuthenticationOptions
                    {
                        ServerCertificate = localhostCert,
                        // Different TLS requirements for this host
                        ClientCertificateRequired = true,
                    });
                }

                return new ValueTask<SslServerAuthenticationOptions>(new SslServerAuthenticationOptions
                {
                    ServerCertificate = exampleCert,
                });
            }, state: null);
        });
    });
});

組態中的 SNI

Kestrel 支援在組態中定義的 SNI。 您可以使用 Sni 物件來設定端點,該物件中包含主機名稱與 HTTPS 選項之間的對應。 連線主機名稱會與選項進行比對,然後用於該連線。

下列組態會新增名為 MySniEndpoint 的端點,該端點會使用 SNI 來根據主機名稱選取 HTTPS 選項:

{
  "Kestrel": {
    "Endpoints": {
      "MySniEndpoint": {
        "Url": "https://*",
        "SslProtocols": ["Tls11", "Tls12"],
        "Sni": {
          "a.example.org": {
            "Protocols": "Http1AndHttp2",
            "SslProtocols": ["Tls11", "Tls12", "Tls13"],
            "Certificate": {
              "Subject": "<subject; required>",
              "Store": "<certificate store; required>",
            },
            "ClientCertificateMode" : "NoCertificate"
          },
          "*.example.org": {
            "Certificate": {
              "Path": "<path to .pfx file>",
              "Password": "$CREDENTIAL_PLACEHOLDER$"
            }
          },
          "*": {
            // At least one subproperty needs to exist per SNI section or it
            // cannot be discovered via IConfiguration
            "Protocols": "Http1",
          }
        }
      }
    },
    "Certificates": {
      "Default": {
        "Path": "<path to .pfx file>",
        "Password": "$CREDENTIAL_PLACEHOLDER$"
      }
    }
  }
}

警告

在上述範例中,憑證密碼會以純文字形式儲存在 appsettings.json中。 $CREDENTIAL_PLACEHOLDER$ 權杖會作為每個憑證密碼的預留位置。 若要安全地將憑證密碼儲存在開發環境中,請參閱在開發過程中保護祕密。 若要安全地將憑證密碼儲存在生產環境中,請參閱 Azure Key Vault 組態提供者。 開發秘密不應該用於生產或測試。

SNI 可以覆寫的 HTTPS 選項:

主機名稱支援萬用字元比對:

  • 完全相符。 例如,a.example.org 符合 a.example.org
  • 萬用字元首碼。 如果有多個萬用字元相符,則會選擇最長的模式。 例如,*.example.org 符合 b.example.orgc.example.org
  • 完整萬用字元。 * 會比對其他所有內容,包括未使用 SNI 且不會傳送主機名稱的用戶端。

相符的 SNI 組態會套用至連線的端點,並覆寫端點上的值。 如果連線不符合設定的 SNI 主機名稱,則會拒絕連線。

SNI 需求

  • 在目標 Framework netcoreapp2.1 或更新版本上執行。 在 net461 或更新版本上會叫用回呼,但 name 一律為 null。 如果用戶端不在 TLS 信號交換中提供主機名稱參數,則 name 也是 null
  • 所有網站都在相同的 Kestrel 執行個體上執行。 在不使用反向 Proxy 的情況下,Kestrel 不支援跨多個執行個體共用 IP 位址和連接埠。

SSL/TLS 通訊協定

SSL 通訊協定是用來加密和解密兩個同儕節點 (傳統上是用戶端與伺服器) 之間流量的通訊協定。

webBuilder.ConfigureKestrel(serverOptions =>
{
    serverOptions.ConfigureHttpsDefaults(listenOptions =>
    {
        listenOptions.SslProtocols = SslProtocols.Tls13;
    });
});
{
  "Kestrel": {
    "Endpoints": {
      "MyHttpsEndpoint": {
        "Url": "https://localhost:5001",
        "SslProtocols": ["Tls12", "Tls13"],
        "Certificate": {
          "Path": "<path to .pfx file>",
          "Password": "$CREDENTIAL_PLACEHOLDER$"
        }
      }
    }
  }
}

警告

在上述範例中,憑證密碼會以純文字形式儲存在 appsettings.json 中。 $CREDENTIAL_PLACEHOLDER$ 權杖會作為憑證密碼的預留位置。 若要安全地將憑證密碼儲存在開發環境中,請參閱在開發過程中保護祕密。 若要安全地將憑證密碼儲存在生產環境中,請參閱 Azure Key Vault 組態提供者。 開發秘密不應該用於生產或測試。

預設值 SslProtocols.None 會導致 Kestrel 使用作業系統預設值來選擇最佳通訊協定。 除非您有特殊原因要選取某一通訊協定,否則請使用預設值。

用戶端憑證

ClientCertificateMode 會設定用戶端憑證需求

webBuilder.ConfigureKestrel(serverOptions =>
{
    serverOptions.ConfigureHttpsDefaults(listenOptions =>
    {
        listenOptions.ClientCertificateMode = ClientCertificateMode.AllowCertificate;
    });
});
{
  "Kestrel": {
    "Endpoints": {
      "MyHttpsEndpoint": {
        "Url": "https://localhost:5001",
        "ClientCertificateMode": "AllowCertificate",
        "Certificate": {
          "Path": "<path to .pfx file>",
          "Password": "$CREDENTIAL_PLACEHOLDER$"
        }
      }
    }
  }
}

警告

在上述範例中,憑證密碼會以純文字形式儲存在 appsettings.json 中。 $CREDENTIAL_PLACEHOLDER$ 權杖會作為憑證密碼的預留位置。 若要安全地將憑證密碼儲存在開發環境中,請參閱在開發過程中保護祕密。 若要安全地將憑證密碼儲存在生產環境中,請參閱 Azure Key Vault 組態提供者。 開發秘密不應該用於生產或測試。

預設值為 ClientCertificateMode.NoCertificate,其中 Kestrel 不會向用戶端要求憑證。

如需詳細資訊,請參閱在 ASP.NET Core 中設定憑證驗證

連線記錄

呼叫 UseConnectionLogging,以在連線上發出位元組層級通訊的偵錯層級記錄。 連線記錄有助於對低階通訊中的問題進行疑難排解,例如 TLS 加密期間和 Proxy 後面的問題。 如果將 UseConnectionLogging 放在 UseHttps 之前,則會記錄加密流量。 如果將 UseConnectionLogging 放在 UseHttps 之後,則會記錄解密流量。 這是內建的連線中介軟體

webBuilder.ConfigureKestrel(serverOptions =>
{
    serverOptions.Listen(IPAddress.Any, 8000, listenOptions =>
    {
        listenOptions.UseConnectionLogging();
    });
});

繫結至 TCP 通訊端

Listen 方法會繫結至 TCP 通訊端,而選項 Lambda 則會允許 X.509 憑證設定:

public static void Main(string[] args)
{
    CreateHostBuilder(args).Build().Run();
}

public static IHostBuilder CreateHostBuilder(string[] args) =>
    Host.CreateDefaultBuilder(args)
        .ConfigureWebHostDefaults(webBuilder =>
        {
            webBuilder.ConfigureKestrel(serverOptions =>
            {
                serverOptions.Listen(IPAddress.Loopback, 5000);
                serverOptions.Listen(IPAddress.Loopback, 5001, 
                    listenOptions =>
                    {
                        listenOptions.UseHttps("testCert.pfx", 
                            "testPassword");
                    });
            })
            .UseStartup<Startup>();
        });

此範例使用 ListenOptions來為端點設定 HTTPS。 若要設定特定端點的其他 Kestrel 設定,請使用相同的 API。

在 Windows 上,可以使用 New-SelfSignedCertificate PowerShell Cmdlet 建立自我簽署憑證。 如需不支援的範例,請參閱 UpdateIISExpressSSLForChrome.ps1

在 macOS、Linux 和 Windows 上,可以使用 OpenSSL \(英文\) 建立憑證。

繫結至 Unix 通訊端

請使用 ListenUnixSocket 在 Unix 通訊端上進行接聽以改善 Nginx 的效能,如此範例所示:

webBuilder.ConfigureKestrel(serverOptions =>
{
    serverOptions.ListenUnixSocket("/tmp/kestrel-test.sock");
    serverOptions.ListenUnixSocket("/tmp/kestrel-test.sock", 
        listenOptions =>
        {
            listenOptions.UseHttps("testCert.pfx", 
                "testpassword");
        });
})
  • 在 Nginx 組態檔中,將 server>location>proxy_pass 項目設定為 http://unix:/tmp/{KESTREL SOCKET}:/;{KESTREL SOCKET} 是提供給 ListenUnixSocket 的通訊端名稱 (例如,上述範例中的 kestrel-test.sock)。
  • 請確定通訊端可由 Nginx 寫入 (例如,chmod go+w /tmp/kestrel-test.sock)。

連接埠 0

指定連接埠號碼 0 時,Kestrel 會動態繫結至可用的連接埠。 下列範例示範如何判斷 Kestrel 在執行階段繫結至哪一個連接埠:

public void Configure(IApplicationBuilder app)
{
    var serverAddressesFeature =
        app.ServerFeatures.Get<IServerAddressesFeature>();

    app.UseStaticFiles();

    app.Run(async (context) =>
    {
        context.Response.ContentType = "text/html";
        await context.Response
            .WriteAsync("<!DOCTYPE html><html lang=\"en\"><head>" +
                "<title></title></head><body><p>Hosted by Kestrel</p>");

        if (serverAddressesFeature != null)
        {
            await context.Response
                .WriteAsync("<p>Listening on the following addresses: " +
                    string.Join(", ", serverAddressesFeature.Addresses) +
                    "</p>");
        }

        await context.Response.WriteAsync("<p>Request URL: " +
            $"{context.Request.GetDisplayUrl()}<p>");
    });
}

當應用程式執行時,主控台視窗輸出會指出可以連線到應用程式的動態連接埠:

Listening on the following addresses: http://127.0.0.1:48508

限制

使用下列方法來設定端點:

  • UseUrls
  • --urls 命令列引數
  • urls 主機組態索引鍵
  • ASPNETCORE_URLS 環境變數

要讓程式碼使用 Kestrel 以外的伺服器,這些方法會很有用。 不過,請注意下列限制:

  • HTTPS 無法與這些方法搭配使用,除非在 HTTPS 端點組態中提供預設憑證 (例如,使用 KestrelServerOptions 組態或組態檔,如本文稍早所示)。
  • 當同時使用 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 應用程式層通訊協定交涉 (ALPN) 交握中選取 HTTP/2;否則,連線會預設為 HTTP/1.1。

任何端點的預設 ListenOptions.Protocols 值為 HttpProtocols.Http1AndHttp2

HTTP/2 的 TLS 限制:

  • TLS 1.2 版或更新版本
  • 已停用重新交涉
  • 已停用壓縮
  • 暫時金鑰交換大小下限:
    • 橢圓曲線 Diffie-Hellman (ECDHE) [RFC4492]:最小 224 個位元
    • 有限欄位 Diffie-Hellman (DHE) [TLS12]:最小 2048 個位元
  • 未禁止使用加密套件。

預設支援 TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 [TLS-ECDHE] 與 P-256 橢圓曲線 [FIPS186]。

下列範例會允許連接埠 8000 上的 HTTP/1.1 和 HTTP/2 連線。 這些連線使用提供的憑證受到 TLS 保護:

webBuilder.ConfigureKestrel(serverOptions =>
{
    serverOptions.Listen(IPAddress.Any, 8000, listenOptions =>
    {
        listenOptions.UseHttps("testCert.pfx", "testPassword");
    });
});

在 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,
                    // ...
                });
        };
    });
});

連線中介軟體

必要時,自訂連線中介軟體可以依據個別連線篩選 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();
        });
    });
});

從組態設定 HTTP 通訊協定

CreateDefaultBuilder 預設會呼叫 serverOptions.Configure(context.Configuration.GetSection("Kestrel")),以載入 Kestrel 組態。

下列 appsettings.json 範例會建立 HTTP/1.1 作為所有端點的預設連線通訊協定:

{
  "Kestrel": {
    "EndpointDefaults": {
      "Protocols": "Http1"
    }
  }
}

下列 appsettings.json 範例會針對特定端點建立 HTTP/1.1 連線通訊協定:

{
  "Kestrel": {
    "Endpoints": {
      "HttpsDefaultCert": {
        "Url": "https://localhost:5001",
        "Protocols": "Http1"
      }
    }
  }
}

程式碼中指定的通訊協定會覆寫設定所設定的值。

URL 前置詞

使用 UseUrls--urls 命令列引數、urls 主機組態索引鍵或 ASPNETCORE_URLS 環境變數時,URL 前置詞可以採用下列任一格式。

只有 HTTP URL 前置詞有效。 使用 UseUrls 設定 URL 繫結時,Kestrel 不支援 HTTPS。

  • IPv4 位址與連接埠號碼

    http://65.55.39.10:80/
    

    0.0.0.0 是繫結至所有 IPv4 位址的特殊情況。

  • IPv6 位址與連接埠號碼

    http://[0:0:0:0:0:ffff:4137:270a]:80/
    

    [::] 是相當於 IPv4 0.0.0.0 的 IPv6 對等項目。

  • 主機名稱與連接埠號碼

    http://contoso.com:80/
    http://*:80/
    

    主機名稱 *+ 並不特殊。 無法辨識為有效 IP 位址或 localhost 的任何項目,都會繫結至所有 IPv4 和 IPv6 IP。 若要將不同主機名稱繫結至同一連接埠上的不同 ASP.NET Core 應用程式,請使用 HTTP.sys 或反向 Proxy 伺服器。 反向 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 就會記錄警告。