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

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

呼叫 ListenListenUnixSocket 方法 KestrelServerOptions ,以設定 的 Kestrel URL 前置詞和埠。

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

KestrelServerOptions 配置:

ConfigureEndpointDefaults(Action<ListenOptions>)

指定組態 Action 以針對每個指定端點執行。 呼叫 ConfigureEndpointDefaults 多次會將先前 Action 的 取代為最後一個 Action 指定的 :

var builder = WebApplication.CreateBuilder(args);

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

注意

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

Configure(IConfiguration)

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

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

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

如果已啟用重載設定併發出變更訊號,則會採取下列步驟:

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

連線到已修改端點的用戶端可能會在端點重新開機時中斷連線或拒絕。

ConfigureHttpsDefaults(Action<HttpsConnectionAdapterOptions>)

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

var builder = WebApplication.CreateBuilder(args);

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

注意

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

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 應用程式設定組態架構可供 使用 Kestrel 。 設定多個端點,包括 URL 和要使用的憑證-從磁碟上的檔案,或是從憑證存放區。

在下列 appsettings.json 範例中:

  • 設定 AllowInvalidtrue 以允許使用無效憑證 (例如自我簽署憑證) 。
  • 在下列範例中,未指定憑證的任何 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 金鑰保存庫設定提供者。 開發秘密不應該用於生產或測試。

結構描述附註:

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

憑證來源

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

  • PathPassword 以載入 .pfx 檔案。
  • PathKeyPathPassword 以載入.pem.crt/ 和.key檔案。
  • Subject 從憑證存放區載入 和 Store

例如, 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 選項之間的對應。 例如, JS 檔案中的 appsettings.json ON。

SNI with 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 with ServerOptionsSelectionCallback

Kestrel 支援透過回呼進行其他動態 TLS 組 ServerOptionsSelectionCallback 態。 每個連線會叫用回呼一次,以允許應用程式檢查主機名稱,並選取適當的憑證和 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 with TlsHandshakeCallbackOptions

Kestrel 支援透過回呼進行其他動態 TLS 組 TlsHandshakeCallbackOptions.OnConnection 態。 每個連線會叫用回呼一次,以允許應用程式檢查主機名稱,並選取適當的憑證、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 金鑰保存庫設定提供者。 開發秘密不應該用於生產或測試。

SNI 可以覆寫的 HTTPS 選項:

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

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

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

SNI 需求

所有網站都必須在相同的 Kestrel 實例上執行。 Kestrel 不支援跨多個實例共用 IP 位址和埠,而不需要反向 Proxy。

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 金鑰保存庫設定提供者。 開發秘密不應該用於生產或測試。

預設值 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 金鑰保存庫設定提供者

預設值是 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。 使用相同的 API 來設定特定端點的其他 Kestrel 設定。

在 Windows 上,可以使用PowerShell Cmdlet 建立 New-SelfSignedCertificate自我簽署憑證。 如需不支援的範例,請參閱 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");
    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 :

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 的情況下使用。
Http1AndHttp2 HTTP/1.1 和 HTTP/2。 HTTP/2 要求用戶端在 TLS 應用層通訊協定交涉 (ALPN) 交握中選取 HTTP/2;否則,連線預設為 HTTP/1.1。

任何端點的預設值 ListenOptions.ProtocolsHttpProtocols.Http1AndHttp2

HTTP/2 的 TLS 限制:

  • TLS 1.2 版或更新版本
  • 已停用重新交涉
  • 已停用壓縮
  • 暫時金鑰交換大小下限:
    • ECDHE Diffie-Hellman (橢圓曲線) [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 保護:

var builder = WebApplication.CreateBuilder(args);

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

在 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 前置詞有效。 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 伺服器。 反向 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 支援

呼叫 ListenListenUnixSocket 方法 KestrelServerOptions ,以設定 的 Kestrel URL 前置詞和埠。

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

KestrelServerOptions 配置:

ConfigureEndpointDefaults(Action<ListenOptions>)

指定組態 Action 以針對每個指定端點執行。 呼叫 ConfigureEndpointDefaults 多次會將先前 Action 的 取代為最後一個 Action 指定的 :

var builder = WebApplication.CreateBuilder(args);

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

注意

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

Configure(IConfiguration)

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

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

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

如果已啟用重載設定併發出變更訊號,則會採取下列步驟:

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

連線到已修改端點的用戶端可能會在端點重新開機時中斷連線或拒絕。

ConfigureHttpsDefaults(Action<HttpsConnectionAdapterOptions>)

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

var builder = WebApplication.CreateBuilder(args);

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

注意

呼叫之前呼叫 ListenConfigureHttpsDefaults 建立的端點不會套用預設值。

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

支援的組態描述如下:

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

無組態

Kestrelhttp://localhost:5000如果預設憑證可供使用) ,則會接聽 和 https://localhost:5001 (。

從組態取代預設憑證

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

在下列 appsettings.json 範例中:

  • true設定 AllowInvalid 為 允許使用無效憑證 (例如自我簽署憑證) 。
  • 在下列範例中,未指定憑證的任何 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 金鑰保存庫組態提供者。 開發秘密不應該用於生產或測試。

結構描述附註:

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

憑證來源

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

  • PathPassword 以載入 .pfx 檔案。
  • PathKeyPath 以及 Password 載入.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 選項之間的對應。 例如, JS 檔案中的 appsettings.json ON。

SNI 與 ServerCertificateSelector

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

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 透過回呼支援額外的動態 TLS 組 ServerOptionsSelectionCallback 態。 每個連線會叫用回呼一次,以允許應用程式檢查主機名稱,並選取適當的憑證和 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 透過回呼支援額外的動態 TLS 組 TlsHandshakeCallbackOptions.OnConnection 態。 每個連線會叫用回呼一次,以允許應用程式檢查主機名稱,並選取適當的憑證、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 金鑰保存庫組態提供者。 開發秘密不應該用於生產或測試。

SNI 可以覆寫的 HTTPS 選項:

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

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

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

SNI 需求

所有網站都必須在相同的 Kestrel 實例上執行。 Kestrel 不支援在沒有反向 Proxy 的情況下,跨多個實例共用 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 金鑰保存庫組態提供者。 開發秘密不應該用於生產或測試。

預設值 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 金鑰保存庫組態提供者

預設值是 ClientCertificateMode.NoCertificateKestrel 不會向用戶端要求或要求憑證的位置。

如需詳細資訊,請參閱在 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。 使用相同的 API 來設定特定端點的其他 Kestrel 設定。

在 Windows 上,您可以使用PowerShell Cmdlet 來建立 New-SelfSignedCertificate自我簽署憑證。 如需不支援的範例,請參閱 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");
    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 :

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 應用層通訊協定交涉中選取 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 保護:

var builder = WebApplication.CreateBuilder(args);

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

在 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 前置詞有效。 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 伺服器。 反向 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 支援

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

注意

呼叫之前呼叫 ListenConfigureEndpointDefaults 建立的端點不會套用預設值。

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(Action<HttpsConnectionAdapterOptions>)

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

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

注意

呼叫之前呼叫 ListenConfigureHttpsDefaults 建立的端點不會套用預設值。

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

支援的組態描述如下:

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

無組態

Kestrelhttp://localhost:5000如果預設憑證可供使用) ,則會接聽 和 https://localhost:5001 (。

從組態取代預設憑證

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

在下列 appsettings.json 範例中:

  • true設定 AllowInvalid 為 允許使用無效憑證 (例如自我簽署憑證) 。
  • 在下列範例中,未指定憑證的任何 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 金鑰保存庫組態提供者。 開發秘密不應該用於生產或測試。

結構描述附註:

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

憑證來源

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

  • PathPassword 以載入 .pfx 檔案。
  • PathKeyPathPassword 以載入.pem.crt/ 和.key檔案。
  • Subject 從憑證存放區載入 和 Store

例如, 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 選項之間的對應。 例如, JS 檔案中的 appsettings.json ON。

SNI with ServerCertificateSelector

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

// 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 with ServerOptionsSelectionCallback

Kestrel 支援透過回呼進行其他動態 TLS 組 ServerOptionsSelectionCallback 態。 每個連線會叫用回呼一次,以允許應用程式檢查主機名稱,並選取適當的憑證和 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 金鑰保存庫設定提供者。 開發秘密不應該用於生產或測試。

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 實例上執行。 Kestrel 不支援跨多個實例共用 IP 位址和埠,而不需要反向 Proxy。

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 金鑰保存庫設定提供者。 開發秘密不應該用於生產或測試。

預設值 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 金鑰保存庫設定提供者。 開發秘密不應該用於生產或測試。

預設值是 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。 使用相同的 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 應用層通訊協定交涉 (ALPN) 交握中選取 HTTP/2;否則,連線預設為 HTTP/1.1。

任何端點的預設值 ListenOptions.ProtocolsHttpProtocols.Http1AndHttp2

HTTP/2 的 TLS 限制:

  • TLS 1.2 版或更新版本
  • 已停用重新交涉
  • 已停用壓縮
  • 暫時金鑰交換大小下限:
    • ECDHE Diffie-Hellman (橢圓曲線) [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");
    });
});

在 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 前置詞有效。 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 伺服器。 反向 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 記錄警告。