Note
これは、この記事の最新バージョンではありません。 現在のリリースについては、 この記事の .NET 10 バージョンを参照してください。
警告
このバージョンの ASP.NET Core はサポート対象から除外されました。 詳細については、 .NET および .NET Core サポート ポリシーを参照してください。 現在のリリースについては、この記事の .NET 9 バージョンを参照してください。
Kestrel エンドポイントは、受信要求をリッスンし、適切なミドルウェアにルーティングするためのインフラストラクチャを提供します。 アドレスとプロトコルの組み合わせによってエンドポイントが定義されます。
- アドレスによって、サーバーが受信要求をリッスンするネットワーク インターフェイスが指定されます (TCP ポートなど)。
- プロトコルによって、HTTP/1.1、HTTP/2、HTTP/3 など、クライアントとサーバー間の通信が指定されます。
- エンドポイントは、
httpsURL スキームまたは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/IPv6 の
[::]は IPv4 の0.0.0.0に相当します。ワイルドカード ホストとポート番号
http://contoso.com:80/ http://*:80/有効な IP アドレスまたは
localhostと認識されないものはすべて、IPv4 と IPv6 のすべてのアドレスにバインドされるワイルドカードとして扱われます。 より明示的になるように*または+を使うことを好む人もいます。 さまざまなホスト名を、同じポート上のさまざまな ASP.NET Core アプリにバインドするには、HTTP.sys かリバース プロキシ サーバーを使用します。リバース プロキシ サーバーの例としては、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 URL プレフィックスを使ってエンドポイントを定義できるのは、HTTPS エンドポイント構成で既定の証明書が指定されている場合のみです。 たとえば、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 構成キーは優先度が低く、コードで直接指定された URL または値によってオーバーライドされます。 証明書は引き続き、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は、Listenから API のKestrelServerOptionsファミリをEndpointオーバーロードとしてミラーリングするので、コードと構成のエンドポイントを同じ場所で構成できます。 これらのオーバーロードでは名前は使用されず、構成からの既定の設定のみが使用されます。
コードでエンドポイントを構成する
KestrelServerOptions には、コードでエンドポイントを構成するためのメソッドが用意されています。
Listen と UseUrls 両方の API を同時に使用すると、Listen エンドポイントが UseUrls エンドポイントをオーバーライドします。
TCP ソケットにバインドする
Listen、ListenLocalhost、ListenAnyIP の各メソッドは、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");
});
});
上記の例の場合:
- ポート 5000 と 5001 でリッスンするエンドポイントを構成します。
- UseHttps の ListenOptions 拡張メソッドを使って、エンドポイントに対して HTTPS を構成します。 詳しくは、「コードで HTTPS を構成する」を参照してください。
Windows の場合は、New-SelfSignedCertificate PowerShell コマンドレットを使用して自己署名証明書を作成できます。 サポート対象外の例については、UpdateIISExpressSSLForChrome.ps1 を参照してください。
macOS、Linux、および Windows の場合は、OpenSSL を使用して証明書を作成できます。
UNIX ソケットにバインドする
Nginxと組み合わせてパフォーマンスを向上させるために、次の例に示すようにListenUnixSocketを使ってUNIXソケットでリッスンします。
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 =>
{
// ...
});
});
Note
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);
// ...
}
});
状況によっては、ポートを動的にバインドできない場合があります。
- KestrelServerOptions.ListenLocalhost
- TCP ベースの HTTP/1.1 または HTTP/2 と、QUIC ベースの HTTP/3 を一緒にバインドする。
HTTPS の構成
Kestrel では、HTTPS を使用したエンドポイントのセキュリティ保護がサポートされています。 HTTPS 経由で送信されるデータは、トランスポート層セキュリティ (TLS) を使って暗号化され、クライアントとサーバーの間で転送されるデータのセキュリティが強化されます。
HTTPS には TLS 証明書が必要です。 TLS 証明書はサーバーに格納され、Kestrel はそれを使うように構成されます。 アプリでは、ローカル開発環境で ASP.NET Core HTTPS 開発証明書を使用できます。 開発証明書は、開発以外の環境にはインストールされません。 運用環境では、TLS 証明書を明示的に構成する必要があります。 少なくとも、既定の証明書を指定する必要があります。
HTTPS と TLS 証明書の構成方法は、エンドポイントの構成方法によって異なります。
- URL プレフィックスまたはポートのみを指定を使ってエンドポイントを定義する場合は、HTTPS エンドポイント構成で既定の証明書が指定されている場合にのみ HTTPS を使用できます。 既定の証明書は、次のいずれかのオプションで構成できます。
- appsettings.json で HTTPS を構成する
- コードで HTTPS を構成する
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 構成プロバイダーに関するページを参照してください。 開発用のシークレットは、運用またはテストには使用しないでください。
スキーマに関する注意事項
- エンドポイント名は大文字と小文字が区別されます。 たとえば、
HTTPSandHttpsは同等です。 -
Urlパラメーターは、エンドポイントごとに必要です。 このパラメーターの形式は、1 つの値に制限されることを除き、最上位レベルのUrls構成パラメーターと同じです。 この記事の前半の「URL の形式」を参照してください。 - これらのエンドポイントは、最上位レベルの
Urls構成での定義に追加されるのではなく、それを置き換えます。 コードでListenを使用して定義されているエンドポイントは、構成セクションで定義されているエンドポイントに累積されます。 -
Certificateセクションは省略可能です。Certificateセクションを指定しないと、Certificates:Defaultで定義した既定値が使用されます。 既定値を使用できない場合は、開発証明書が使用されます。 既定値がなく、開発証明書も存在しない場合、サーバーは例外を発生させ、起動に失敗します。 -
Certificateセクションでは、複数の証明書のソースがサポートされています。 - ポートが競合しない限り、
Configurationで任意の数のエンドポイントを定義できます。
証明書のソース
さまざまなソースから証明書を読み込むように証明書ノードを構成することができます。
-
PathとPasswordを使用して .pfx ファイルを読み込みます。 -
Path、KeyPath、およびPasswordを使用して .pem、/、および .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>"
}
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 プロトコルは、2 つのピア (伝統的にはクライアントとサーバー) 間のトラフィックの暗号化と暗号化解除に使用されるプロトコルです。
{
"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 を使う場合は、UseHttps の ListenOptions 拡張メソッドを使って 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は、Actionを構成するためのHttpsConnectionAdapterOptionsです。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>) を使うと、HTTPS エンドポイントごとに実行する構成 Action を指定できます。
ConfigureHttpsDefaults を複数回呼び出すと、前の Action インスタンスが最後に指定した Action で置き換えられます。
var builder = WebApplication.CreateBuilder(args);
builder.WebHost.ConfigureKestrel(serverOptions =>
{
serverOptions.ConfigureHttpsDefaults(listenOptions =>
{
// ...
});
});
Note
Listen を呼び出す前にConfigureHttpsDefaults を呼び出すことで作成されるエンドポイントには既定値が適用されません。
コードで SSL/TLS プロトコルを構成する
SSL プロトコルは、2 つのピア (伝統的にはクライアントとサーバー) 間のトラフィックの暗号化と暗号化解除に使用されるプロトコルです。
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,
// ...
});
};
});
});
Server Name Indication を構成する
Server Name Indication (SNI) を使用すると、同じ IP アドレスとポートで複数のドメインをホストできます。 SNI を使うと、1 台のサーバーから複数のサイトを提供することで、リソースを節約できます。
SNI が機能するためには、サーバーが正しい証明書を提供できるように、クライアントは TLS ハンドシェイクの間にセキュリティで保護されたセッションのホスト名をサーバーに送信します。 クライアントは、TLS ハンドシェイクに続くセキュリティで保護されたセッション中に、提供された証明書をサーバーとの暗号化された通信に使用します。
すべての Web サイトは、同じ Kestrel インスタンス上で実行する必要があります。 Kestrel は、リバースプロキシなしでは、複数のインスタンス間で IP アドレスとポートを共有することをサポートしていません。
SNI は次の 2 種類の方法で設定できます。
-
構成で、ホスト名と HTTPS オプションの間のマッピングを構成します。 たとえば、
appsettings.jsonファイルの JSON です。 - コードでエンドポイントを作成し、ServerCertificateSelector コールバックでホスト名を使用して証明書を選択します。
appsettings.json で SNI を構成する
Kestrel は、構成で定義された SNI をサポートします。 エンドポイントは、ホスト名と HTTPS オプションの間のマッピングを含む Sni オブジェクトを使用して構成できます。 接続ホスト名はオプションと照合され、その接続に使用されます。
次の構成では、SNI を使用してホスト名に基づいて HTTPS オプションを選択する、MySniEndpoint という名前のエンドポイントを追加します。
{
"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 オプション:
-
Certificateは、証明書ソースを構成します。 -
Protocolsは、許可されている HTTP プロトコルを構成します。 -
SslProtocolsは、許可されている SSL プロトコルを構成します。 -
ClientCertificateModeは、クライアント証明書の要件を構成します。
ホスト名は、ワイルドカードの照合をサポートしています。
- 完全一致。 たとえば、
a.example.orgはa.example.orgと一致します。 - ワイルドカードのプレフィックス。 複数のワイルドカードが一致する場合は、最も長いパターンが選択されます。 たとえば、
*.example.orgはb.example.orgおよびc.example.orgと一致します。 - 完全なワイルドカード。
*は、SNI を使用せずホスト名を送信しないクライアントを含む、他のすべてのものと一致します。
一致した SNI 構成が接続のエンドポイントに適用され、エンドポイントの値がオーバーライドされます。 構成済みの SNI ホスト名と接続が一致しない場合、接続は拒否されます。
コードで SNI を構成する
Kestrel では、いくつかのコールバック API で SNI がサポートされています。
ServerCertificateSelectorServerOptionsSelectionCallbackTlsHandshakeCallbackOptions
ServerCertificateSelector による SNI
Kestrel は、ServerCertificateSelector コールバックによって SNI をサポートします。 コールバックは接続ごとに 1 回呼び出されるので、アプリはそれを使って、ホスト名を検査し、適切な証明書を選択できます。
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;
};
});
});
});
ServerOptionsSelectionCallback による SNI
Kestrel は、ServerOptionsSelectionCallback コールバックによって追加の動的な TLS 構成をサポートします。 コールバックは接続ごとに 1 回呼び出されるので、アプリはそれを使って、ホスト名を検査し、適切な証明書と 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!);
});
});
});
TlsHandshakeCallbackOptions による SNI
Kestrel は、TlsHandshakeCallbackOptions.OnConnection コールバックによって追加の動的な TLS 構成をサポートします。 コールバックは接続ごとに 1 回呼び出されるので、アプリはそれを使って、ホスト名を検査し、適切な証明書、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 バージョンがサポートされています。 エンドポイントは、使用できる HTTP バージョンのオプションを指定する HttpProtocols 列挙型を使って、さまざまな HTTP バージョンをサポートするように構成できます。
複数の HTTP バージョンをサポートするには、TLS が必要です。 エンドポイントで複数のプロトコルがサポートされている場合、クライアントとサーバー間の接続プロトコルをネゴシエートするために TLS ALPN (Application-Layer Protocol Negotiation) ハンドシェイクが使用されます。
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 以降
- 再ネゴシエーションは無効
- 圧縮は無効
- 短期キー交換サイズの上限:
- Elliptic curve Diffie-Hellman (ECDHE) [RFC4492]: 最小で 224 ビット
- Finite field Diffie-Hellman (DHE) [
TLS12]: 最小で 2048 ビット
- 暗号スイートは禁止されない
TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 [TLS-ECDHE] と P-256 elliptic curve [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;
});
});
Kestrel 名前付きパイプ エンドポイントをカスタマイズする
Kestrelの名前付きパイプのサポートには、高度なカスタマイズ オプションが含まれています。 名前付きパイプ オプションの CreateNamedPipeServerStream プロパティを使用すると、エンドポイントごとにパイプをカスタマイズできます。
これは、たとえば、Kestrelが異なる 2 つのパイプ エンドポイントを必要とする アプリで便利です。
CreateNamedPipeServerStream オプションを使用すると、パイプ名に応じて、カスタム セキュリティ設定でパイプを作成できます。
using System.IO.Pipes;
using System.Security.AccessControl;
using System.Security.Principal;
var builder = WebApplication.CreateBuilder();
builder.WebHost.ConfigureKestrel(options =>
{
options.ListenNamedPipe("defaultPipe");
options.ListenNamedPipe("securedPipe");
});
builder.WebHost.UseNamedPipes(options =>
{
options.CreateNamedPipeServerStream = (context) =>
{
var pipeName = context.NamedPipeEndPoint.PipeName;
switch (pipeName)
{
case "defaultPipe":
return NamedPipeTransportOptions.CreateDefaultNamedPipeServerStream(context);
case "securedPipe":
var allowSecurity = new PipeSecurity();
allowSecurity.AddAccessRule(new PipeAccessRule("Users", PipeAccessRights.FullControl, AccessControlType.Allow));
return NamedPipeServerStreamAcl.Create(pipeName, PipeDirection.InOut,
NamedPipeServerStream.MaxAllowedServerInstances, PipeTransmissionMode.Byte,
context.PipeOptions, inBufferSize: 0, outBufferSize: 0, allowSecurity);
default:
throw new InvalidOperationException($"Unexpected pipe name: {pipeName}");
}
};
});
var app = builder.Build();
app.MapGet("/", () => "Hello World!");
app.Run();
ASP.NET Core プロジェクトは、5000 - 5300 の間のランダムな HTTP ポートと 7000 - 7300 の間のランダムな HTTPS ポートにバインドするように構成されています。 この既定の構成は、生成される Properties/launchSettings.json ファイルに指定されており、オーバーライドすることができます。 ポートが指定されていない場合、Kestrel は http://localhost:5000 にバインドされます。
以下を使用して URL を指定します。
-
ASPNETCORE_URLS環境変数。 -
--urlsコマンド ライン引数。 -
urlsホスト構成キー。 - UseUrls 拡張メソッド。
これらの方法を使うと、1 つまたは複数の HTTP エンドポイントおよび HTTPS エンドポイント (既定の証明書が使用可能な場合は HTTPS) を指定できます。 セミコロン区切りのリストとして値を構成します (例: "Urls": "http://localhost:8000;http://localhost:8001")。
これらの方法について詳しくは、「サーバーの URL」および「構成のオーバーライド」をご覧ください。
開発証明書が作成されます。
- .NET Core SDK がインストールされるとき。
- 証明書を作成するには dev-certs ツールを使います。
開発用証明書は、証明書を生成したユーザーのみが使用できます。 一部のブラウザーでは、ローカル開発証明書を信頼するには、明示的にアクセス許可を付与する必要があります。
プロジェクト テンプレートでは、アプリを HTTPS で実行するように既定で構成され、HTTPS のリダイレクトと HSTS のサポートが含まれます。
Listen で ListenUnixSocket または KestrelServerOptions メソッドを呼び出して、Kestrel 用に URL プレフィックスおよびポートを構成します。
UseUrls、--urls コマンドライン引数、urls ホスト構成キー、ASPNETCORE_URLS 環境変数も機能しますが、このセクションで後述する制限があります (既定の証明書が、HTTPS エンドポイントの構成に使用できる必要があります)。
KestrelServerOptions 構成:
エンドポイントデフォルトを設定する
ConfigureEndpointDefaults(Action<ListenOptions>) では、指定された各エンドポイントに対して実行するように構成 Action を指定します。
ConfigureEndpointDefaults を複数回呼び出すと、前の Action が最後に指定した Action で置き換えられます。
var builder = WebApplication.CreateBuilder(args);
builder.WebHost.ConfigureKestrel(serverOptions =>
{
serverOptions.ConfigureEndpointDefaults(listenOptions =>
{
// ...
});
});
Note
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 秒以内に要求の処理が完了してシャットダウンします。
- 新しいエンドポイントまたは変更されたエンドポイントが開始されます。
変更されたエンドポイントに接続しているクライアントは、エンドポイントの再起動中に切断または拒否される可能性があります。
HTTPS設定のデフォルトを構成する
ConfigureHttpsDefaults(Action<HttpsConnectionAdapterOptions>) では、各 HTTPS エンドポイントに対して実行するように構成 Action を指定します。
ConfigureHttpsDefaults を複数回呼び出すと、前の Action が最後に指定した Action で置き換えられます。
var builder = WebApplication.CreateBuilder(args);
builder.WebHost.ConfigureKestrel(serverOptions =>
{
serverOptions.ConfigureHttpsDefaults(listenOptions =>
{
// ...
});
});
Note
Listen を呼び出す前にConfigureHttpsDefaults を呼び出すことで作成されるエンドポイントには既定値が適用されません。
ListenOptions.UseHttps
HTTPS を使用するように Kestrel を構成します。
ListenOptions.UseHttps 拡張機能:
-
UseHttps: 既定の証明書で HTTPS を使うように Kestrel を構成します。 既定の証明書が構成されていない場合は、例外がスローされます。 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は、Actionを構成するためのHttpsConnectionAdapterOptionsです。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 構成プロバイダーに関するページを参照してください。 開発用のシークレットは、運用またはテストには使用しないでください。
スキーマに関する注意事項:
- エンドポイント名は大文字と小文字を区別しません。 たとえば、
HTTPSandHttpsは同等です。 -
Urlパラメーターは、エンドポイントごとに必要です。 このパラメーターの形式は、1 つの値に制限されることを除き、最上位レベルのUrls構成パラメーターと同じです。 - これらのエンドポイントは、最上位レベルの
Urls構成での定義に追加されるのではなく、それを置き換えます。 コードでListenを使用して定義されているエンドポイントは、構成セクションで定義されているエンドポイントに累積されます。 -
Certificateセクションは省略可能です。Certificateセクションを指定しないと、Certificates:Defaultで定義した既定値が使用されます。 既定値を使用できない場合は、開発証明書が使用されます。 既定値がなく、開発証明書も存在しない場合、サーバーは例外を発生させ、起動に失敗します。 -
Certificateセクションでは複数の証明書のソースがサポートされています。 - ポートが競合しない限り、構成で任意の数のエンドポイントを定義できます。
証明書のソース
さまざまなソースから証明書を読み込むように証明書ノードを構成することができます。
-
PathとPasswordを使用して .pfx ファイルを読み込みます。 -
Path、KeyPath、およびPasswordを使用して .pem、/、および .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) が 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メソッドのオプションで使用できます。 - 別のセクションで Configure(IConfiguration) を再び呼び出すことにより、複数の構成を読み込むことができます。 前のインスタンスで
Loadを明示的に呼び出していない限り、最後の構成のみが使用されます。 既定の構成セクションを置き換えることができるように、メタパッケージはLoadを呼び出しません。 -
KestrelConfigurationLoaderはListenからの API ファミリーをKestrelServerOptionsオーバーロードとして模倣するため、コードと構成のエンドポイントを同じ場所で設定できます。 これらのオーバーロードでは名前は使用されず、構成からの既定の設定のみが使用されます。
コードで既定値を変更する
ConfigureEndpointDefaults およびConfigureHttpsDefaults を使用して、ListenOptions および HttpsConnectionAdapterOptions の既定の設定を変更できます (前のシナリオで指定した既定の証明書のオーバーライドなど)。 エンドポイントを構成する前に、ConfigureEndpointDefaults および ConfigureHttpsDefaults を呼び出す必要があります。
var builder = WebApplication.CreateBuilder(args);
builder.WebHost.ConfigureKestrel((context, serverOptions) =>
{
serverOptions.ConfigureEndpointDefaults(listenOptions =>
{
// ...
});
serverOptions.ConfigureHttpsDefaults(listenOptions =>
{
// ...
});
});
Server Name Indication を使用してエンドポイントを構成する
Server Name Indication (SNI) を使用すると、同じ IP アドレスとポートで複数のドメインをホストできます。 SNI が機能するためには、サーバーが正しい証明書を提供できるように、クライアントは TLS ハンドシェイクの間にセキュリティで保護されたセッションのホスト名をサーバーに送信します。 クライアントは、TLS ハンドシェイクに続くセキュリティで保護されたセッション中に、提供された証明書をサーバーとの暗号化された通信に使用します。
SNI は次の 2 種類の方法で設定できます。
- コードでエンドポイントを作成し、ServerCertificateSelector コールバックでホスト名を使用して証明書を選択します。
-
構成で、ホスト名と HTTPS オプションの間のマッピングを構成します。 たとえば、
appsettings.jsonファイルの JSON です。
ServerCertificateSelector による SNI
Kestrel は、ServerCertificateSelector コールバックによって SNI をサポートします。 コールバックは接続ごとに 1 回呼び出されるので、アプリはそれを使って、ホスト名を検査し、適切な証明書を選択できます。
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;
};
});
});
});
ServerOptionsSelectionCallback による SNI
Kestrel は、ServerOptionsSelectionCallback コールバックによって追加の動的な TLS 構成をサポートします。 コールバックは接続ごとに 1 回呼び出されるので、アプリはそれを使って、ホスト名を検査し、適切な証明書と 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!);
});
});
});
TlsHandshakeCallbackOptions による SNI
Kestrel は、TlsHandshakeCallbackOptions.OnConnection コールバックによって追加の動的な TLS 構成をサポートします。 コールバックは接続ごとに 1 回呼び出されるので、アプリはそれを使って、ホスト名を検査し、適切な証明書、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 をサポートします。 エンドポイントは、ホスト名と HTTPS オプションの間のマッピングを含む Sni オブジェクトを使用して構成できます。 接続ホスト名はオプションと突き合わされ、これらはその接続に使用されます。
次の構成では、SNI を使用してホスト名に基づいて HTTPS オプションを選択する、MySniEndpoint という名前のエンドポイントを追加します。
{
"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 オプション:
-
Certificateは、証明書ソースを構成します。 -
Protocolsは、許可されている HTTP プロトコルを構成します。 -
SslProtocolsは、許可されている SSL プロトコルを構成します。 -
ClientCertificateModeは、クライアント証明書の要件を構成します。
ホスト名は、ワイルドカードの照合をサポートしています。
- 完全一致。 たとえば、
a.example.orgはa.example.orgと一致します。 - ワイルドカードのプレフィックス。 複数のワイルドカードが一致する場合は、最も長いパターンが選択されます。 たとえば、
*.example.orgはb.example.orgおよびc.example.orgと一致します。 - 完全なワイルドカード。
*は、SNI を使用せずホスト名を送信しないクライアントを含む、他のすべてのものと一致します。
一致した SNI 構成が接続のエンドポイントに適用され、エンドポイントの値がオーバーライドされます。 構成済みの SNI ホスト名と接続が一致しない場合、接続は拒否されます。
SNI の要件
すべての Web サイトは、同じ Kestrel インスタンス上で実行する必要があります。 Kestrel は、リバースプロキシなしでは、複数のインスタンス間で IP アドレスとポートを共有することをサポートしていません。
SSL/TLS プロトコル
SSL プロトコルは、2 つのピア (伝統的にはクライアントとサーバー) 間のトラフィックの暗号化と暗号化解除に使用されるプロトコルです。
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 暗号化の間やプロキシの内側など、低レベルの通信での問題のトラブルシューティングに役立ちます。
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 ソケットにバインドし、オプションのラムダにより 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 の場合は、New-SelfSignedCertificate PowerShell コマンドレットを使用して自己署名証明書を作成できます。 サポート対象外の例については、UpdateIISExpressSSLForChrome.ps1 を参照してください。
macOS、Linux、および Windows の場合は、OpenSSL を使用して証明書を作成できます。
UNIX ソケットにバインドする
Nginxと組み合わせてパフォーマンスを向上させるために、次の例に示すようにListenUnixSocketを使ってUNIXソケットでリッスンします。
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 エンドポイントの構成 (
KestrelServerOptions構成、またはこの記事で前に示した構成ファイルなどを使用) で既定の証明書が指定されていない場合は、これらの方法で HTTPS を使用することはできません。 -
ListenとUseUrls両方の方法を同時に使用すると、ListenエンドポイントがUseUrlsエンドポイントをオーバーライドします。
IIS エンドポイントの構成
IIS を使用するときは、IIS オーバーライド バインドに対する URL バインドを、Listen または UseUrls によって設定します。 詳細については、ASP.NET Core モジュールに関するページを参照してください。
ListenOptions.Protocols
Protocolsプロパティでは、接続エンドポイントまたはサーバーに対して有効にされる HTTP プロトコル (HttpProtocols) が確定されます。
Protocols 列挙型から HttpProtocols プロパティに値を割り当てます。
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 以降
- 再ネゴシエーションは無効
- 圧縮は無効
- 短期キー交換サイズの上限:
- Elliptic curve Diffie-Hellman (ECDHE) [RFC4492]: 最小で 224 ビット
- Finite field Diffie-Hellman (DHE) [
TLS12]: 最小で 2048 ビット
- 暗号スイートは禁止されない
TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 [TLS-ECDHE] と P-256 elliptic curve [FIPS186] の組み合わせは既定ではサポートされています。
次の例では、HTTP/1.1 接続と HTTP/2 接続がポート 8000 上で許可されています。 接続は、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 プレフィックスのみが有効です。
Kestrel を使用して URL バインドを構成する場合、UseUrls は HTTPS をサポートしません。
IPv4 アドレスとポート番号
http://65.55.39.10:80/0.0.0.0は、すべての IPv4 アドレスにバインドする特別なケースです。IPv6 アドレスとポート番号
http://[0:0:0:0:0:ffff:4137:270a]:80/IPv6 の
[::]は IPv4 の0.0.0.0に相当します。ホスト名とポート番号
http://contoso.com:80/ http://*:80/ホスト名、
*、および+は特別ではありません。 有効な IP アドレスまたはlocalhostと認識されないものはすべて、IPv4 および IPv6 のすべての IP にバインドします。 さまざまなホスト名を、同じポート上のさまざまな ASP.NET Core アプリにバインドするには、HTTP.sys かリバース プロキシ サーバーを使用します。 リバース プロキシ サーバーの例としては、IIS、Nginx、Apache などがあります。警告
リバース プロキシ構成でのホストにはホストのフィルター処理が必要です。
localhost名とポート番号、またはループバック IP とポート番号http://localhost:5000/ http://127.0.0.1:5000/ http://[::1]:5000/localhostが指定された場合、Kestrel は IPv4 ループバック インターフェイスと IPv6 ループバック インターフェイスの両方へのバインドを試みます。 要求されたポートがいずれかのループバック インターフェイス上の別のサービスで使用中である場合、Kestrel は開始できません。 他の何らかの理由でいずれかのループバック インターフェイスが使用できない場合 (ほとんどの場合は IPv6 がサポートされていないことが理由)、Kestrel は警告をログに記録します。
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 拡張メソッド。
これらの方法を使うと、1 つまたは複数の HTTP エンドポイントおよび HTTPS エンドポイント (既定の証明書が使用可能な場合は HTTPS) を指定できます。 セミコロン区切りのリストとして値を構成します (例: "Urls": "http://localhost:8000;http://localhost:8001")。
これらの方法について詳しくは、「サーバーの URL」および「構成のオーバーライド」をご覧ください。
開発証明書が作成されます。
- .NET Core SDK がインストールされるとき。
- 証明書を作成するには dev-certs ツールを使います。
開発用証明書は、証明書を生成したユーザーのみが使用できます。 一部のブラウザーでは、ローカル開発証明書を信頼するには、明示的にアクセス許可を付与する必要があります。
プロジェクト テンプレートでは、アプリを HTTPS で実行するように既定で構成され、HTTPS のリダイレクトと HSTS のサポートが含まれます。
Listen で ListenUnixSocket または KestrelServerOptions メソッドを呼び出して、Kestrel 用に URL プレフィックスおよびポートを構成します。
UseUrls、--urls コマンドライン引数、urls ホスト構成キー、ASPNETCORE_URLS 環境変数も機能しますが、このセクションで後述する制限があります (既定の証明書が、HTTPS エンドポイントの構成に使用できる必要があります)。
KestrelServerOptions 構成:
エンドポイントデフォルトを設定する
ConfigureEndpointDefaults(Action<ListenOptions>) では、指定された各エンドポイントに対して実行するように構成 Action を指定します。
ConfigureEndpointDefaults を複数回呼び出すと、前の Action が最後に指定した Action で置き換えられます。
var builder = WebApplication.CreateBuilder(args);
builder.WebHost.ConfigureKestrel(serverOptions =>
{
serverOptions.ConfigureEndpointDefaults(listenOptions =>
{
// ...
});
});
Note
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 秒以内に要求の処理が完了してシャットダウンします。
- 新しいエンドポイントまたは変更されたエンドポイントが開始されます。
変更されたエンドポイントに接続しているクライアントは、エンドポイントの再起動中に切断または拒否される可能性があります。
HTTPS設定のデフォルトを構成する
ConfigureHttpsDefaults(Action<HttpsConnectionAdapterOptions>) では、各 HTTPS エンドポイントに対して実行するように構成 Action を指定します。
ConfigureHttpsDefaults を複数回呼び出すと、前の Action が最後に指定した Action で置き換えられます。
var builder = WebApplication.CreateBuilder(args);
builder.WebHost.ConfigureKestrel(serverOptions =>
{
serverOptions.ConfigureHttpsDefaults(listenOptions =>
{
// ...
});
});
Note
Listen を呼び出す前にConfigureHttpsDefaults を呼び出すことで作成されるエンドポイントには既定値が適用されません。
ListenOptions.UseHttps
HTTPS を使用するように Kestrel を構成します。
ListenOptions.UseHttps 拡張機能:
-
UseHttps: 既定の証明書で HTTPS を使うように Kestrel を構成します。 既定の証明書が構成されていない場合は、例外がスローされます。 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は、Actionを構成するためのHttpsConnectionAdapterOptionsです。ListenOptionsを返します。 -
storeNameは、証明書の読み込み元の証明書ストアです。 -
subjectは、証明書のサブジェクト名です。 -
allowInvalidは、無効な証明書 (自己署名証明書など) を考慮する必要があるかどうかを示します。 -
locationは、証明書を読み込むストアの場所です。 -
serverCertificateは、X.509 証明書です。
運用環境では、HTTPS を明示的に構成する必要があります。 少なくとも、既定の証明書を指定する必要があります。
サポートされている構成を次に説明します。
- 構成なし
- 構成から既定の証明書を置き換える
- コードで既定値を変更する
構成なし
Kestrel は、http://localhost:5000 と https://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 構成プロバイダーに関するページを参照してください。 開発用のシークレットは、運用またはテストには使用しないでください。
スキーマに関する注意事項:
- エンドポイント名は大文字と小文字を区別しません。 たとえば、
HTTPSandHttpsは同等です。 -
Urlパラメーターは、エンドポイントごとに必要です。 このパラメーターの形式は、1 つの値に制限されることを除き、最上位レベルのUrls構成パラメーターと同じです。 - これらのエンドポイントは、最上位レベルの
Urls構成での定義に追加されるのではなく、それを置き換えます。 コードでListenを使用して定義されているエンドポイントは、構成セクションで定義されているエンドポイントに累積されます。 -
Certificateセクションは省略可能です。Certificateセクションを指定しないと、Certificates:Defaultで定義した既定値が使用されます。 既定値を使用できない場合は、開発証明書が使用されます。 既定値がなく、開発証明書も存在しない場合、サーバーは例外を発生させ、起動に失敗します。 -
Certificateセクションでは複数の証明書のソースがサポートされています。 - ポートが競合しない限り、構成で任意の数のエンドポイントを定義できます。
証明書のソース
さまざまなソースから証明書を読み込むように証明書ノードを構成することができます。
-
PathとPasswordを使用して .pfx ファイルを読み込みます。 -
Path、KeyPath、およびPasswordを使用して .pem、/、および .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) が 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メソッドのオプションで使用できます。 - 別のセクションで Configure(IConfiguration) を再び呼び出すことにより、複数の構成を読み込むことができます。 前のインスタンスで
Loadを明示的に呼び出していない限り、最後の構成のみが使用されます。 既定の構成セクションを置き換えることができるように、メタパッケージはLoadを呼び出しません。 -
KestrelConfigurationLoaderはListenからの API ファミリーをKestrelServerOptionsオーバーロードとして模倣するため、コードと構成のエンドポイントを同じ場所で設定できます。 これらのオーバーロードでは名前は使用されず、構成からの既定の設定のみが使用されます。
コードで既定値を変更する
ConfigureEndpointDefaults およびConfigureHttpsDefaults を使用して、ListenOptions および HttpsConnectionAdapterOptions の既定の設定を変更できます (前のシナリオで指定した既定の証明書のオーバーライドなど)。 エンドポイントを構成する前に、ConfigureEndpointDefaults および ConfigureHttpsDefaults を呼び出す必要があります。
var builder = WebApplication.CreateBuilder(args);
builder.WebHost.ConfigureKestrel((context, serverOptions) =>
{
serverOptions.ConfigureEndpointDefaults(listenOptions =>
{
// ...
});
serverOptions.ConfigureHttpsDefaults(listenOptions =>
{
// ...
});
});
Server Name Indication を使用してエンドポイントを構成する
Server Name Indication (SNI) を使用すると、同じ IP アドレスとポートで複数のドメインをホストできます。 SNI が機能するためには、サーバーが正しい証明書を提供できるように、クライアントは TLS ハンドシェイクの間にセキュリティで保護されたセッションのホスト名をサーバーに送信します。 クライアントは、TLS ハンドシェイクに続くセキュリティで保護されたセッション中に、提供された証明書をサーバーとの暗号化された通信に使用します。
SNI は次の 2 種類の方法で設定できます。
- コードでエンドポイントを作成し、ServerCertificateSelector コールバックでホスト名を使用して証明書を選択します。
-
構成で、ホスト名と HTTPS オプションの間のマッピングを構成します。 たとえば、
appsettings.jsonファイルの JSON です。
ServerCertificateSelector による SNI
Kestrel は、ServerCertificateSelector コールバックによって SNI をサポートします。 コールバックは接続ごとに 1 回呼び出されるので、アプリはそれを使って、ホスト名を検査し、適切な証明書を選択できます。
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;
};
});
});
});
ServerOptionsSelectionCallback による SNI
Kestrel は、ServerOptionsSelectionCallback コールバックによって追加の動的な TLS 構成をサポートします。 コールバックは接続ごとに 1 回呼び出されるので、アプリはそれを使って、ホスト名を検査し、適切な証明書と 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!);
});
});
});
TlsHandshakeCallbackOptions による SNI
Kestrel は、TlsHandshakeCallbackOptions.OnConnection コールバックによって追加の動的な TLS 構成をサポートします。 コールバックは接続ごとに 1 回呼び出されるので、アプリはそれを使って、ホスト名を検査し、適切な証明書、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 をサポートします。 エンドポイントは、ホスト名と HTTPS オプションの間のマッピングを含む Sni オブジェクトを使用して構成できます。 接続ホスト名はオプションと突き合わされ、これらはその接続に使用されます。
次の構成では、SNI を使用してホスト名に基づいて HTTPS オプションを選択する、MySniEndpoint という名前のエンドポイントを追加します。
{
"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 オプション:
-
Certificateは、証明書ソースを構成します。 -
Protocolsは、許可されている HTTP プロトコルを構成します。 -
SslProtocolsは、許可されている SSL プロトコルを構成します。 -
ClientCertificateModeは、クライアント証明書の要件を構成します。
ホスト名は、ワイルドカードの照合をサポートしています。
- 完全一致。 たとえば、
a.example.orgはa.example.orgと一致します。 - ワイルドカードのプレフィックス。 複数のワイルドカードが一致する場合は、最も長いパターンが選択されます。 たとえば、
*.example.orgはb.example.orgおよびc.example.orgと一致します。 - 完全なワイルドカード。
*は、SNI を使用せずホスト名を送信しないクライアントを含む、他のすべてのものと一致します。
一致した SNI 構成が接続のエンドポイントに適用され、エンドポイントの値がオーバーライドされます。 構成済みの SNI ホスト名と接続が一致しない場合、接続は拒否されます。
SNI の要件
すべての Web サイトは、同じ Kestrel インスタンス上で実行する必要があります。 Kestrel は、リバースプロキシなしでは、複数のインスタンス間で IP アドレスとポートを共有することをサポートしていません。
SSL/TLS プロトコル
SSL プロトコルは、2 つのピア (伝統的にはクライアントとサーバー) 間のトラフィックの暗号化と暗号化解除に使用されるプロトコルです。
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 暗号化の間やプロキシの内側など、低レベルの通信での問題のトラブルシューティングに役立ちます。
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 ソケットにバインドし、オプションのラムダにより 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 の場合は、New-SelfSignedCertificate PowerShell コマンドレットを使用して自己署名証明書を作成できます。 サポート対象外の例については、UpdateIISExpressSSLForChrome.ps1 を参照してください。
macOS、Linux、および Windows の場合は、OpenSSL を使用して証明書を作成できます。
UNIX ソケットにバインドする
Nginxと組み合わせてパフォーマンスを向上させるために、次の例に示すようにListenUnixSocketを使ってUNIXソケットでリッスンします。
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 エンドポイントの構成 (
KestrelServerOptions構成、またはこの記事で前に示した構成ファイルなどを使用) で既定の証明書が指定されていない場合は、これらの方法で HTTPS を使用することはできません。 -
ListenとUseUrls両方の方法を同時に使用すると、ListenエンドポイントがUseUrlsエンドポイントをオーバーライドします。
IIS エンドポイントの構成
IIS を使用するときは、IIS オーバーライド バインドに対する URL バインドを、Listen または UseUrls によって設定します。 詳細については、ASP.NET Core モジュールに関するページを参照してください。
ListenOptions.Protocols
Protocolsプロパティでは、接続エンドポイントまたはサーバーに対して有効にされる HTTP プロトコル (HttpProtocols) が確定されます。
Protocols 列挙型から HttpProtocols プロパティに値を割り当てます。
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 以降
- 再ネゴシエーションは無効
- 圧縮は無効
- 短期キー交換サイズの上限:
- Elliptic curve Diffie-Hellman (ECDHE) [RFC4492]: 最小で 224 ビット
- Finite field Diffie-Hellman (DHE) [
TLS12]: 最小で 2048 ビット
- 暗号スイートは禁止されない
TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 [TLS-ECDHE] と P-256 elliptic curve [FIPS186] の組み合わせは既定ではサポートされています。
次の例では、HTTP/1.1 接続と HTTP/2 接続がポート 8000 上で許可されています。 接続は、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 プレフィックスのみが有効です。
Kestrel を使用して URL バインドを構成する場合、UseUrls は HTTPS をサポートしません。
IPv4 アドレスとポート番号
http://65.55.39.10:80/0.0.0.0は、すべての IPv4 アドレスにバインドする特別なケースです。IPv6 アドレスとポート番号
http://[0:0:0:0:0:ffff:4137:270a]:80/IPv6 の
[::]は IPv4 の0.0.0.0に相当します。ホスト名とポート番号
http://contoso.com:80/ http://*:80/ホスト名、
*、および+は特別ではありません。 有効な IP アドレスまたはlocalhostと認識されないものはすべて、IPv4 および IPv6 のすべての IP にバインドします。 さまざまなホスト名を、同じポート上のさまざまな ASP.NET Core アプリにバインドするには、HTTP.sys かリバース プロキシ サーバーを使用します。 リバース プロキシ サーバーの例としては、IIS、Nginx、Apache などがあります。警告
リバース プロキシ構成でのホストにはホストのフィルター処理が必要です。
localhost名とポート番号、またはループバック IP とポート番号http://localhost:5000/ http://127.0.0.1:5000/ http://[::1]:5000/localhostが指定された場合、Kestrel は IPv4 ループバック インターフェイスと IPv6 ループバック インターフェイスの両方へのバインドを試みます。 要求されたポートがいずれかのループバック インターフェイス上の別のサービスで使用中である場合、Kestrel は開始できません。 他の何らかの理由でいずれかのループバック インターフェイスが使用できない場合 (ほとんどの場合は IPv6 がサポートされていないことが理由)、Kestrel は警告をログに記録します。
既定では、ASP.NET Core は以下にバインドされます。
http://localhost:5000-
https://localhost:5001(ローカル開発証明書が存在する場合)
以下を使用して URL を指定します。
-
ASPNETCORE_URLS環境変数。 -
--urlsコマンド ライン引数。 -
urlsホスト構成キー。 - UseUrls 拡張メソッド。
これらの方法を使うと、1 つまたは複数の HTTP エンドポイントおよび HTTPS エンドポイント (既定の証明書が使用可能な場合は HTTPS) を指定できます。 セミコロン区切りのリストとして値を構成します (例: "Urls": "http://localhost:8000;http://localhost:8001")。
これらの方法について詳しくは、「サーバーの URL」および「構成のオーバーライド」をご覧ください。
開発証明書が作成されます。
- .NET Core SDK がインストールされるとき。
- 証明書を作成するには dev-certs ツールを使います。
一部のブラウザーでは、ローカル開発証明書を信頼するには、明示的にアクセス許可を付与する必要があります。
プロジェクト テンプレートでは、アプリを HTTPS で実行するように既定で構成され、HTTPS のリダイレクトと HSTS のサポートが含まれます。
Listen で ListenUnixSocket または KestrelServerOptions メソッドを呼び出して、Kestrel 用に URL プレフィックスおよびポートを構成します。
UseUrls、--urls コマンドライン引数、urls ホスト構成キー、ASPNETCORE_URLS 環境変数も機能しますが、このセクションで後述する制限があります (既定の証明書が、HTTPS エンドポイントの構成に使用できる必要があります)。
KestrelServerOptions 構成:
エンドポイントデフォルトを設定する
ConfigureEndpointDefaults(Action<ListenOptions>) では、指定された各エンドポイントに対して実行するように構成 Action を指定します。
ConfigureEndpointDefaults を複数回呼び出すと、前の Action が最後に指定した Action で置き換えられます。
webBuilder.ConfigureKestrel(serverOptions =>
{
serverOptions.ConfigureEndpointDefaults(listenOptions =>
{
// Configure endpoint defaults
});
});
Note
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 秒以内に要求の処理が完了してシャットダウンします。
- 新しいエンドポイントまたは変更されたエンドポイントが開始されます。
変更されたエンドポイントに接続しているクライアントは、エンドポイントの再起動中に切断または拒否される可能性があります。
HTTPS設定のデフォルトを構成する
ConfigureHttpsDefaults(Action<HttpsConnectionAdapterOptions>) では、各 HTTPS エンドポイントに対して実行するように構成 Action を指定します。
ConfigureHttpsDefaults を複数回呼び出すと、前の Action が最後に指定した Action で置き換えられます。
webBuilder.ConfigureKestrel(serverOptions =>
{
serverOptions.ConfigureHttpsDefaults(listenOptions =>
{
// certificate is an X509Certificate2
listenOptions.ServerCertificate = certificate;
});
});
Note
Listen を呼び出す前にConfigureHttpsDefaults を呼び出すことで作成されるエンドポイントには既定値が適用されません。
ListenOptions.UseHttps
HTTPS を使用するように Kestrel を構成します。
ListenOptions.UseHttps 拡張機能:
-
UseHttps: 既定の証明書で HTTPS を使うように Kestrel を構成します。 既定の証明書が構成されていない場合は、例外がスローされます。 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は、Actionを構成するためのHttpsConnectionAdapterOptionsです。ListenOptionsを返します。 -
storeNameは、証明書の読み込み元の証明書ストアです。 -
subjectは、証明書のサブジェクト名です。 -
allowInvalidは、無効な証明書 (自己署名証明書など) を考慮する必要があるかどうかを示します。 -
locationは、証明書を読み込むストアの場所です。 -
serverCertificateは、X.509 証明書です。
運用環境では、HTTPS を明示的に構成する必要があります。 少なくとも、既定の証明書を指定する必要があります。
サポートされている構成を次に説明します。
- 構成なし
- 構成から既定の証明書を置き換える
- コードで既定値を変更する
構成なし
Kestrel は、http://localhost:5000 と https://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 構成プロバイダーに関するページを参照してください。 開発用のシークレットは、運用またはテストには使用しないでください。
スキーマに関する注意事項:
- エンドポイント名は大文字と小文字を区別しません。 たとえば、
HTTPSandHttpsは同等です。 -
Urlパラメーターは、エンドポイントごとに必要です。 このパラメーターの形式は、1 つの値に制限されることを除き、最上位レベルのUrls構成パラメーターと同じです。 - これらのエンドポイントは、最上位レベルの
Urls構成での定義に追加されるのではなく、それを置き換えます。 コードでListenを使用して定義されているエンドポイントは、構成セクションで定義されているエンドポイントに累積されます。 -
Certificateセクションは省略可能です。Certificateセクションを指定しないと、Certificates:Defaultで定義した既定値が使用されます。 既定値を使用できない場合は、開発証明書が使用されます。 既定値がなく、開発証明書も存在しない場合、サーバーは例外を発生させ、起動に失敗します。 -
Certificateセクションでは複数の証明書のソースがサポートされています。 - ポートが競合しない限り、構成で任意の数のエンドポイントを定義できます。
証明書のソース
さまざまなソースから証明書を読み込むように証明書ノードを構成することができます。
-
PathとPasswordを使用して .pfx ファイルを読み込みます。 -
Path、KeyPath、およびPasswordを使用して .pem、/、および .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はListenからの API ファミリーをKestrelServerOptionsオーバーロードとして模倣するため、コードと構成のエンドポイントを同じ場所で設定できます。 これらのオーバーロードでは名前は使用されず、構成からの既定の設定のみが使用されます。
コードで既定値を変更する
ConfigureEndpointDefaults およびConfigureHttpsDefaults を使用して、ListenOptions および HttpsConnectionAdapterOptions の既定の設定を変更できます (前のシナリオで指定した既定の証明書のオーバーライドなど)。 エンドポイントを構成する前に、ConfigureEndpointDefaults および ConfigureHttpsDefaults を呼び出す必要があります。
webBuilder.ConfigureKestrel(serverOptions =>
{
serverOptions.ConfigureEndpointDefaults(listenOptions =>
{
// Configure endpoint defaults
});
serverOptions.ConfigureHttpsDefaults(listenOptions =>
{
listenOptions.SslProtocols = SslProtocols.Tls12;
});
});
Server Name Indication を使用してエンドポイントを構成する
Server Name Indication (SNI) を使用すると、同じ IP アドレスとポートで複数のドメインをホストできます。 SNI が機能するためには、サーバーが正しい証明書を提供できるように、クライアントは TLS ハンドシェイクの間にセキュリティで保護されたセッションのホスト名をサーバーに送信します。 クライアントは、TLS ハンドシェイクに続くセキュリティで保護されたセッション中に、提供された証明書をサーバーとの暗号化された通信に使用します。
SNI は次の 2 種類の方法で設定できます。
- コードでエンドポイントを作成し、ServerCertificateSelector コールバックでホスト名を使用して証明書を選択します。
-
構成で、ホスト名と HTTPS オプションの間のマッピングを構成します。 たとえば、
appsettings.jsonファイルの JSON です。
ServerCertificateSelector による SNI
Kestrel は、ServerCertificateSelector コールバックによって SNI をサポートします。 コールバックは接続ごとに 1 回呼び出されるので、アプリはそれを使って、ホスト名を検査し、適切な証明書を選択できます。 次のコールバック コードは、プロジェクトの 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;
};
});
});
});
ServerOptionsSelectionCallback による SNI
Kestrel は、ServerOptionsSelectionCallback コールバックによって追加の動的な TLS 構成をサポートします。 コールバックは接続ごとに 1 回呼び出されるので、アプリはそれを使って、ホスト名を検査し、適切な証明書と 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 をサポートします。 エンドポイントは、ホスト名と HTTPS オプションの間のマッピングを含む Sni オブジェクトを使用して構成できます。 接続ホスト名はオプションと突き合わされ、これらはその接続に使用されます。
次の構成では、SNI を使用してホスト名に基づいて HTTPS オプションを選択する、MySniEndpoint という名前のエンドポイントを追加します。
{
"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 オプション:
-
Certificateは、証明書ソースを構成します。 -
Protocolsは、許可されている HTTP プロトコルを構成します。 -
SslProtocolsは、許可されている SSL プロトコルを構成します。 -
ClientCertificateModeは、クライアント証明書の要件を構成します。
ホスト名は、ワイルドカードの照合をサポートしています。
- 完全一致。 たとえば、
a.example.orgはa.example.orgと一致します。 - ワイルドカードのプレフィックス。 複数のワイルドカードが一致する場合は、最も長いパターンが選択されます。 たとえば、
*.example.orgはb.example.orgおよびc.example.orgと一致します。 - 完全なワイルドカード。
*は、SNI を使用せずホスト名を送信しないクライアントを含む、他のすべてのものと一致します。
一致した SNI 構成が接続のエンドポイントに適用され、エンドポイントの値がオーバーライドされます。 構成済みの SNI ホスト名と接続が一致しない場合、接続は拒否されます。
SNI の要件
- ターゲット フレームワーク
netcoreapp2.1以降で実行される必要があります。net461以降、コールバックは呼び出されますが、nameは常にnullです。 クライアントが TLS ハンドシェイクでホスト名パラメーターを提供しない場合も、nameはnullです。 - すべての Web サイトは、同じ Kestrel インスタンスで実行されます。 Kestrel は、リバースプロキシなしでは、複数のインスタンス間で IP アドレスとポートを共有することをサポートしていません。
SSL/TLS プロトコル
SSL プロトコルは、2 つのピア (伝統的にはクライアントとサーバー) 間のトラフィックの暗号化と暗号化解除に使用されるプロトコルです。
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 暗号化の間やプロキシの内側など、低レベルの通信での問題のトラブルシューティングに役立ちます。
UseConnectionLogging が UseHttps の前に配置されている場合は、暗号化されたトラフィックがログに記録されます。
UseConnectionLogging が UseHttps の後に配置されている場合は、暗号化解除されたトラフィックがログに記録されます。 これは、接続ミドルウェアに組み込まれています。
webBuilder.ConfigureKestrel(serverOptions =>
{
serverOptions.Listen(IPAddress.Any, 8000, listenOptions =>
{
listenOptions.UseConnectionLogging();
});
});
TCP ソケットにバインドする
Listen メソッドは TCP ソケットにバインドし、オプションのラムダにより 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 の場合は、New-SelfSignedCertificate PowerShell コマンドレットを使用して自己署名証明書を作成できます。 サポート対象外の例については、UpdateIISExpressSSLForChrome.ps1 を参照してください。
macOS、Linux、および Windows の場合は、OpenSSL を使用して証明書を作成できます。
UNIX ソケットにバインドする
Nginxと組み合わせてパフォーマンスを向上させるために、次の例に示すようにListenUnixSocketを使ってUNIXソケットでリッスンします。
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 エンドポイントの構成 (
KestrelServerOptions構成、またはこの記事で前に示した構成ファイルなどを使用) で既定の証明書が指定されていない場合は、これらの方法で HTTPS を使用することはできません。 -
ListenとUseUrls両方の方法を同時に使用すると、ListenエンドポイントがUseUrlsエンドポイントをオーバーライドします。
IIS エンドポイントの構成
IIS を使用するときは、IIS オーバーライド バインドに対する URL バインドを、Listen または UseUrls によって設定します。 詳細については、ASP.NET Core モジュールに関するページを参照してください。
ListenOptions.Protocols
Protocolsプロパティでは、接続エンドポイントまたはサーバーに対して有効にされる HTTP プロトコル (HttpProtocols) が確定されます。
Protocols 列挙型から HttpProtocols プロパティに値を割り当てます。
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 以降
- 再ネゴシエーションは無効
- 圧縮は無効
- 短期キー交換サイズの上限:
- Elliptic curve Diffie-Hellman (ECDHE) [RFC4492]: 最小で 224 ビット
- Finite field Diffie-Hellman (DHE) [
TLS12]: 最小で 2048 ビット
- 暗号スイートは禁止されない
TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 [TLS-ECDHE] と P-256 elliptic curve [FIPS186] の組み合わせは既定ではサポートされています。
次の例では、HTTP/1.1 接続と HTTP/2 接続がポート 8000 上で許可されています。 接続は、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 のラムダを使って構成することもできます。
// 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 を使用して URL バインドを構成する場合、UseUrls は HTTPS をサポートしません。
IPv4 アドレスとポート番号
http://65.55.39.10:80/0.0.0.0は、すべての IPv4 アドレスにバインドする特別なケースです。IPv6 アドレスとポート番号
http://[0:0:0:0:0:ffff:4137:270a]:80/IPv6 の
[::]は IPv4 の0.0.0.0に相当します。ホスト名とポート番号
http://contoso.com:80/ http://*:80/ホスト名、
*、および+は特別ではありません。 有効な IP アドレスまたはlocalhostと認識されないものはすべて、IPv4 および IPv6 のすべての IP にバインドします。 さまざまなホスト名を、同じポート上のさまざまな ASP.NET Core アプリにバインドするには、HTTP.sys かリバース プロキシ サーバーを使用します。 リバース プロキシ サーバーの例としては、IIS、Nginx、Apache などがあります。警告
リバース プロキシ構成でのホストにはホストのフィルター処理が必要です。
localhost名とポート番号、またはループバック IP とポート番号http://localhost:5000/ http://127.0.0.1:5000/ http://[::1]:5000/localhostが指定された場合、Kestrel は IPv4 ループバック インターフェイスと IPv6 ループバック インターフェイスの両方へのバインドを試みます。 要求されたポートがいずれかのループバック インターフェイス上の別のサービスで使用中である場合、Kestrel は開始できません。 他の何らかの理由でいずれかのループバック インターフェイスが使用できない場合 (ほとんどの場合は IPv6 がサポートされていないことが理由)、Kestrel は警告をログに記録します。
ASP.NET Core