ASP.NET Core の Kestrel Web サーバー

作成者: Tom DykstraChris RossStephen Halter

Kestrel は、Kestrelです。 Kestrel は ASP.NET Core に推奨されるサーバーであり、ASP.NET Core プロジェクト テンプレートに既定で構成されています。

Kestrel の機能には次のものが含まれます。

  • クロスプラットフォーム:Kestrel は、Windows、Linux、macOS で実行されるクロスプラットフォーム Web サーバーです。
  • 高パフォーマンス:Kestrel は、多数の同時接続を効率的に処理するように最適化されています。
  • 軽量: コンテナーやエッジ デバイスなど、リソースに制約のある環境での実行に最適化されています。
  • セキュリティ強化:Kestrel は HTTPS をサポートし、Web サーバーの脆弱性に対して強化されています。
  • 幅広いプロトコルのサポート:Kestrel では、次を含む一般的な Web プロトコルがサポートされています。
  • ASP.NET Core との統合: ミドルウェア パイプライン、依存関係の挿入、構成システムなど、他の ASP.NET Core コンポーネントとのシームレスな統合。
  • 柔軟なワークロード: Kestrel では、多くのワークロードがサポートされます。
    • 最小 API、MVC、Razor Pages、SignalRBlazor、gRPC などの ASP.NET アプリ フレームワーク。
    • YARP を使用したリバース プロキシの構築。
  • 機能拡張: 構成、ミドルウェア、およびカスタム トランスポートを使用して Kestrel をカスタマイズします。
  • パフォーマンス診断:Kestrel によってログやメトリックなど、組み込みのパフォーマンス診断機能が提供されます。

はじめに

ASP.NET Core プロジェクト テンプレートは、IIS でホストされていない場合、既定で Kestrel を使用します。 次のテンプレートによって生成された Program.cs では、WebApplication.CreateBuilder メソッドによって内部的に UseKestrel が呼び出されます。

var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();

app.MapGet("/", () => "Hello World!");

app.Run();

WebApplicationWebApplicationBuilder の構成の詳細については、「Minimal API クイック リファレンス」を参照してください。

オプションのクライアント証明書

証明書を使用してアプリのサブセットを保護する必要があるアプリの詳細については、「オプションのクライアント証明書」を参照してください。

デバッガーがアタッチされているときの動作

デバッガーが Kestrel プロセスにアタッチされているときは、次のタイムアウトとレート制限は適用されません。

その他のリソース

Note

ASP.NET Core 5.0 から、Kestrel の libuv トランスポートは廃止されています。 libuv トランスポートには、Windows ARM64 などの新しい OS プラットフォームをサポートする更新プログラムが提供されず、今後のリリースでは削除される予定です。 古い UseLibuv メソッドの呼び出しをすべて削除し、代わりに Kestrel の既定の Socket トランスポートを使用してください。

Kestrel は、Kestrelです。 Kestrel は、ASP.NET Core のプロジェクト テンプレートに既定で含まれ、有効になっている Web サーバーです。

Kestrel では次のシナリオがサポートされます。

  • HTTPS
  • HTTP/2 (macOS の場合を除く†)
  • Websocket を有効にするために使用される非透過的なアップグレード
  • Nginx の背後にある高パフォーマンスの UNIX ソケット

†将来のリリースでは HTTP/2 が macOS 上でサポートされるようになります。

Kestrel は、.NET Core がサポートするすべてのプラットフォームおよびバージョンでサポートされます。

はじめに

ASP.NET Core プロジェクト テンプレートは、IIS でホストされていない場合、既定で Kestrel を使用します。 次のテンプレートによって生成された Program.cs では、WebApplication.CreateBuilder メソッドによって内部的に UseKestrel が呼び出されます。

var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();

app.MapGet("/", () => "Hello World!");

app.Run();

WebApplicationWebApplicationBuilder の構成の詳細については、「Minimal API クイック リファレンス」を参照してください。

オプションのクライアント証明書

証明書を使用してアプリのサブセットを保護する必要があるアプリの詳細については、「オプションのクライアント証明書」を参照してください。

デバッガーがアタッチされているときの動作

デバッガーが Kestrel プロセスにアタッチされているときは、次のタイムアウトとレート制限は適用されません。

その他のリソース

Note

ASP.NET Core 5.0 から、Kestrel の libuv トランスポートは廃止されています。 libuv トランスポートには、Windows ARM64 などの新しい OS プラットフォームをサポートする更新プログラムが提供されず、今後のリリースでは削除される予定です。 古い UseLibuv メソッドの呼び出しをすべて削除し、代わりに Kestrel の既定の Socket トランスポートを使用してください。

Kestrel は、Kestrelです。 Kestrel は、ASP.NET Core のプロジェクト テンプレートに既定で含まれ、有効になっている Web サーバーです。

Kestrel では次のシナリオがサポートされます。

  • HTTPS
  • HTTP/2 (macOS の場合を除く†)
  • Websocket を有効にするために使用される非透過的なアップグレード
  • Nginx の背後にある高パフォーマンスの UNIX ソケット

†将来のリリースでは HTTP/2 が macOS 上でサポートされるようになります。

Kestrel は、.NET Core がサポートするすべてのプラットフォームおよびバージョンでサポートされます。

サンプル コードを表示またはダウンロードします (ダウンロード方法)。

はじめに

ASP.NET Core プロジェクト テンプレートは、IIS でホストされていない場合、既定で Kestrel を使用します。 Program.csConfigureWebHostDefaults メソッドは、UseKestrel を呼び出します。

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

public static IHostBuilder CreateHostBuilder(string[] args) =>
    Host.CreateDefaultBuilder(args)
        .ConfigureWebHostDefaults(webBuilder =>
        {
            webBuilder.UseStartup<Startup>();
        });

ホストのビルドに関する詳細については、「ASP.NET Core の .NET 汎用ホスト」の「ホストを設定する」セクションと「既定の builder 設定」セクションを参照してください。

オプションのクライアント証明書

証明書を使用してアプリのサブセットを保護する必要があるアプリの詳細については、「オプションのクライアント証明書」を参照してください。

その他のリソース

Note

ASP.NET Core 5.0 から、Kestrel の libuv トランスポートは廃止されています。 libuv トランスポートには、Windows ARM64 などの新しい OS プラットフォームをサポートする更新プログラムが提供されず、今後のリリースでは削除される予定です。 古い UseLibuv メソッドの呼び出しをすべて削除し、代わりに Kestrel の既定の Socket トランスポートを使用してください。

Kestrel は、Kestrelです。 Kestrel は、ASP.NET Core のプロジェクト テンプレートに既定で含まれる Web サーバーです。

Kestrel では次のシナリオがサポートされます。

  • HTTPS
  • Websocket を有効にするために使用される非透過的なアップグレード
  • Nginx の背後にある高パフォーマンスの UNIX ソケット
  • HTTP/2 (macOS の場合を除く†)

†将来のリリースでは HTTP/2 が macOS 上でサポートされるようになります。

Kestrel は、.NET Core がサポートするすべてのプラットフォームおよびバージョンでサポートされます。

サンプル コードを表示またはダウンロードします (ダウンロード方法)。

HTTP/2 のサポート

Http/2 は、次の基本要件が満たされている場合に、ASP.NET Core アプリで使用できます。

†将来のリリースでは HTTP/2 が macOS 上でサポートされるようになります。 ‡Kestrel では、Windows Server 2012 R2 および Windows 8.1 上での HTTP/2 のサポートは制限されています。 サポートが制限されている理由は、これらのオペレーティング システムで使用できる TLS 暗号のスイートのリストが制限されているためです。 TLS 接続をセキュリティで保護するためには、楕円曲線デジタル署名アルゴリズム (ECDSA) を使用して生成した証明書が必要になる場合があります。

HTTP/2 接続が確立されると、HttpRequest.ProtocolHTTP/2 を報告します。

.NET Core 3.0 以降では、HTTP/2 は既定で有効になっています。 構成の詳細については、Kestrel オプションに関するセクションと「ListenOptions.Protocols」セクションを参照してください。

Kestrel とリバース プロキシを使用するタイミング

Kestrel は単独で使用することも、"リバース プロキシ サーバー" と併用することもできます。 リバース プロキシ サーバーはネットワークから HTTP 要求を受け取り、これを Kestrel に転送します。 リバース プロキシ サーバーの例を次に示します。

エッジ (インターネットに接続する) Web サーバーとして使用される Kestrel:

Kestrel communicates directly with the Internet without a reverse proxy server

リバース プロキシ構成で使用される Kestrel:

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

いずれの構成でも、リバース プロキシ サーバーの有無に関わらず、ホスティング構成がサポートされています。

リバース プロキシ サーバーのないエッジ サーバーとして使用される Kestrel は、複数のプロセス間で同じ IP とポートを共有することをサポートしていません。 あるポートをリッスンするように Kestrel を構成する場合は、要求の Host ヘッダーに関係なく、Kestrel によってそのポートに対するすべてのトラフィックが処理されます。 ポートを共有できるリバース プロキシは、一意の IP とポート上の Kestrel に要求を転送することができます。

リバース プロキシ サーバーが必要ない場合であっても、リバース プロキシ サーバーを使用すると次のような利点があります。

リバース プロキシ:

  • ホストするアプリの公開されるパブリック サーフェス領域を制限することができます。
  • 構成および防御の層を追加します。
  • 既存のインフラストラクチャとより適切に統合できる場合があります。
  • 負荷分散とセキュリティで保護された通信 (HTTPS) の構成を簡略化します。 リバース プロキシ サーバーのみで X.509 証明書が必要です。このサーバーでは、プレーンな HTTP を使用して内部ネットワーク上のアプリのサーバーと通信することができます。

警告

リバース プロキシ構成でホスティングを行うには、転送ヘッダー ミドルウェア構成が必要です。

ASP.NET Core アプリでの Kestrel

ASP.NET Core プロジェクト テンプレートは既定では Kestrel を使用します。 Program.csConfigureWebHostDefaults メソッドは、UseKestrel を呼び出します。

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

public static IHostBuilder CreateHostBuilder(string[] args) =>
    Host.CreateDefaultBuilder(args)
        .ConfigureWebHostDefaults(webBuilder =>
        {
            webBuilder.UseStartup<Startup>();
        });

ホストのビルドに関する詳細については、「ASP.NET Core の .NET 汎用ホスト」の「ホストを設定する」セクションと「既定の builder 設定」セクションを参照してください。

ConfigureWebHostDefaults を呼び出した後に追加の構成を指定するには、ConfigureKestrel を使用します。

public static IHostBuilder CreateHostBuilder(string[] args) =>
    Host.CreateDefaultBuilder(args)
        .ConfigureWebHostDefaults(webBuilder =>
        {
            webBuilder.ConfigureKestrel(serverOptions =>
            {
                // Set properties and call methods on options
            })
            .UseStartup<Startup>();
        });

Kestrel オプション

Kestrel Web サーバーには、インターネットに接続する展開で特に有効な制約構成オプションがいくつかあります。

KestrelServerOptions クラスの Limits プロパティで制約を設定します。 Limits プロパティは、KestrelServerLimits クラスのインスタンスを保持します。

Microsoft.AspNetCore.Server.Kestrel.Core 名前空間を使用する例を次に示します。

using Microsoft.AspNetCore.Server.Kestrel.Core;

この記事の後半で示す例では、Kestrel オプションが C# コードで構成されています。 Kestrel オプションは、Kestrelを使用して設定することもできます。 たとえば、ファイル構成プロバイダーを使用すると、appsettings.json ファイルまたは appsettings.{Environment}.json ファイルから、Kestrel 構成を読み込むことができます。

{
  "Kestrel": {
    "Limits": {
      "MaxConcurrentConnections": 100,
      "MaxConcurrentUpgradedConnections": 100
    },
    "DisableStringReuse": true
  }
}

Note

KestrelServerOptions およびKestrelServerOptionsは、構成プロバイダーから構成できます。 残りの Kestrel 構成は、C# コードで構成する必要があります。

次の方法のいずれかを使用します。

  • Startup.ConfigureServices で Kestrel を構成します。

    1. IConfiguration のインスタンスを Startup クラスに挿入します。 以下の例では、挿入された構成が Configuration プロパティに割り当てられることを前提としています。

    2. Startup.ConfigureServices で、構成の Kestrel セクションを Kestrel の構成に読み込みます。

      using Microsoft.Extensions.Configuration
      
      public class Startup
      {
          public Startup(IConfiguration configuration)
          {
              Configuration = configuration;
          }
      
          public IConfiguration Configuration { get; }
      
          public void ConfigureServices(IServiceCollection services)
          {
              services.Configure<KestrelServerOptions>(
                  Configuration.GetSection("Kestrel"));
          }
      
          public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
          {
              ...
          }
      }
      
  • ホストのビルド時に Kestrel を構成します。

    Program.cs で、構成の Kestrel セクションを Kestrel の構成に読み込みます。

    // using Microsoft.Extensions.DependencyInjection;
    
    public static IHostBuilder CreateHostBuilder(string[] args) =>
        Host.CreateDefaultBuilder(args)
            .ConfigureServices((context, services) =>
            {
                services.Configure<KestrelServerOptions>(
                    context.Configuration.GetSection("Kestrel"));
            })
            .ConfigureWebHostDefaults(webBuilder =>
            {
                webBuilder.UseStartup<Startup>();
            });
    

上記の方法はいずれも、任意の構成プロバイダーで使用できます。

Keep-Alive タイムアウト

KeepAliveTimeout

Keep-Alive タイムアウトを取得するか、設定します。 既定値は 2 分です。

webBuilder.ConfigureKestrel(serverOptions =>
{
    serverOptions.Limits.MaxConcurrentConnections = 100;
    serverOptions.Limits.MaxConcurrentUpgradedConnections = 100;
    serverOptions.Limits.MaxRequestBodySize = 10 * 1024;
    serverOptions.Limits.MinRequestBodyDataRate =
        new MinDataRate(bytesPerSecond: 100, 
            gracePeriod: TimeSpan.FromSeconds(10));
    serverOptions.Limits.MinResponseDataRate =
        new MinDataRate(bytesPerSecond: 100, 
            gracePeriod: TimeSpan.FromSeconds(10));
    serverOptions.Listen(IPAddress.Loopback, 5000);
    serverOptions.Listen(IPAddress.Loopback, 5001, 
        listenOptions =>
        {
            listenOptions.UseHttps("testCert.pfx", 
                "testPassword");
        });
    serverOptions.Limits.KeepAliveTimeout = 
        TimeSpan.FromMinutes(2);
    serverOptions.Limits.RequestHeadersTimeout = 
        TimeSpan.FromMinutes(1);
})

クライアントの最大接続数

MaxConcurrentConnections MaxConcurrentUpgradedConnections

次のコードを使用することで、アプリ全体に対して同時に開かれる TCP 接続の最大数を設定できます。

webBuilder.ConfigureKestrel(serverOptions =>
{
    serverOptions.Limits.MaxConcurrentConnections = 100;
    serverOptions.Limits.MaxConcurrentUpgradedConnections = 100;
    serverOptions.Limits.MaxRequestBodySize = 10 * 1024;
    serverOptions.Limits.MinRequestBodyDataRate =
        new MinDataRate(bytesPerSecond: 100, 
            gracePeriod: TimeSpan.FromSeconds(10));
    serverOptions.Limits.MinResponseDataRate =
        new MinDataRate(bytesPerSecond: 100, 
            gracePeriod: TimeSpan.FromSeconds(10));
    serverOptions.Listen(IPAddress.Loopback, 5000);
    serverOptions.Listen(IPAddress.Loopback, 5001, 
        listenOptions =>
        {
            listenOptions.UseHttps("testCert.pfx", 
                "testPassword");
        });
    serverOptions.Limits.KeepAliveTimeout = 
        TimeSpan.FromMinutes(2);
    serverOptions.Limits.RequestHeadersTimeout = 
        TimeSpan.FromMinutes(1);
})

HTTP または HTTPS から別のプロトコルにアップグレードされた接続については別個の制限があります (WebSockets 要求に関する制限など)。 接続がアップグレードされた後、それは MaxConcurrentConnections 制限に対してカウントされません。

webBuilder.ConfigureKestrel(serverOptions =>
{
    serverOptions.Limits.MaxConcurrentConnections = 100;
    serverOptions.Limits.MaxConcurrentUpgradedConnections = 100;
    serverOptions.Limits.MaxRequestBodySize = 10 * 1024;
    serverOptions.Limits.MinRequestBodyDataRate =
        new MinDataRate(bytesPerSecond: 100, 
            gracePeriod: TimeSpan.FromSeconds(10));
    serverOptions.Limits.MinResponseDataRate =
        new MinDataRate(bytesPerSecond: 100, 
            gracePeriod: TimeSpan.FromSeconds(10));
    serverOptions.Listen(IPAddress.Loopback, 5000);
    serverOptions.Listen(IPAddress.Loopback, 5001, 
        listenOptions =>
        {
            listenOptions.UseHttps("testCert.pfx", 
                "testPassword");
        });
    serverOptions.Limits.KeepAliveTimeout = 
        TimeSpan.FromMinutes(2);
    serverOptions.Limits.RequestHeadersTimeout = 
        TimeSpan.FromMinutes(1);
})

接続の最大数は既定では無制限 (null) です。

要求本文の最大サイズ

MaxRequestBodySize

既定の要求本文の最大サイズは、30,000,000 バイトです。これは約 28.6 MB になります。

ASP.NET Core MVC アプリでの制限をオーバーライドする方法としては、アクション メソッドに対して RequestSizeLimitAttribute 属性を使用することをお勧めします。

[RequestSizeLimit(100000000)]
public IActionResult MyActionMethod()

次の例では、すべての要求についての制約をアプリに対して構成する方法を示します。

webBuilder.ConfigureKestrel(serverOptions =>
{
    serverOptions.Limits.MaxConcurrentConnections = 100;
    serverOptions.Limits.MaxConcurrentUpgradedConnections = 100;
    serverOptions.Limits.MaxRequestBodySize = 10 * 1024;
    serverOptions.Limits.MinRequestBodyDataRate =
        new MinDataRate(bytesPerSecond: 100, 
            gracePeriod: TimeSpan.FromSeconds(10));
    serverOptions.Limits.MinResponseDataRate =
        new MinDataRate(bytesPerSecond: 100, 
            gracePeriod: TimeSpan.FromSeconds(10));
    serverOptions.Listen(IPAddress.Loopback, 5000);
    serverOptions.Listen(IPAddress.Loopback, 5001, 
        listenOptions =>
        {
            listenOptions.UseHttps("testCert.pfx", 
                "testPassword");
        });
    serverOptions.Limits.KeepAliveTimeout = 
        TimeSpan.FromMinutes(2);
    serverOptions.Limits.RequestHeadersTimeout = 
        TimeSpan.FromMinutes(1);
})

ミドルウェア内の特定の要求で設定をオーバーライドします。

app.Run(async (context) =>
{
    context.Features.Get<IHttpMaxRequestBodySizeFeature>()
        .MaxRequestBodySize = 10 * 1024;

    var minRequestRateFeature = 
        context.Features.Get<IHttpMinRequestBodyDataRateFeature>();
    var minResponseRateFeature = 
        context.Features.Get<IHttpMinResponseDataRateFeature>();

    if (minRequestRateFeature != null)
    {
        minRequestRateFeature.MinDataRate = new MinDataRate(
            bytesPerSecond: 100, gracePeriod: TimeSpan.FromSeconds(10));
    }

    if (minResponseRateFeature != null)
    {
        minResponseRateFeature.MinDataRate = new MinDataRate(
            bytesPerSecond: 100, gracePeriod: TimeSpan.FromSeconds(10));
    }

アプリが要求の読み取りを開始した後で、要求に対する制限をアプリで構成すると、例外がスローされます。 MaxRequestBodySize プロパティが読み取り専用状態にある (制限を構成するには遅すぎる) かどうかを示す IsReadOnly プロパティがあります。

ASP.NET Core Module の背後でアプリがアウト プロセスで実行されるとき、Kestrel の要求本文サイズ上限が無効になります。IIS により既に上限が設定されているためです。

要求本文の最小レート

MinRequestBodyDataRate MinResponseDataRate

Kestrel はデータが指定のレート (バイト数/秒) で到着しているかどうかを毎秒チェックします。 レートが最小値を下回った場合は接続がタイムアウトになります。猶予期間とは、クライアントによって送信速度を最低ラインまで引き上げられるのを、Kestrel が待機する時間のことです。この期間中、レートはチェックされません。 猶予期間により、TCP のスロースタートのため最初にデータを低速で送信する接続がドロップされるのを回避できます。

既定の最小レートは 240 バイト/秒であり、5 秒の猶予時間が設定されています。

最小レートは応答にも適用されます。 要求制限と応答制限を設定するコードは、プロパティ名およびインターフェイス名に RequestBody または Response が使用されることを除けば同じです。

次の例では、Program.cs で最小データ レートを構成する方法を示します。

webBuilder.ConfigureKestrel(serverOptions =>
{
    serverOptions.Limits.MaxConcurrentConnections = 100;
    serverOptions.Limits.MaxConcurrentUpgradedConnections = 100;
    serverOptions.Limits.MaxRequestBodySize = 10 * 1024;
    serverOptions.Limits.MinRequestBodyDataRate =
        new MinDataRate(bytesPerSecond: 100, 
            gracePeriod: TimeSpan.FromSeconds(10));
    serverOptions.Limits.MinResponseDataRate =
        new MinDataRate(bytesPerSecond: 100, 
            gracePeriod: TimeSpan.FromSeconds(10));
    serverOptions.Listen(IPAddress.Loopback, 5000);
    serverOptions.Listen(IPAddress.Loopback, 5001, 
        listenOptions =>
        {
            listenOptions.UseHttps("testCert.pfx", 
                "testPassword");
        });
    serverOptions.Limits.KeepAliveTimeout = 
        TimeSpan.FromMinutes(2);
    serverOptions.Limits.RequestHeadersTimeout = 
        TimeSpan.FromMinutes(1);
})

ミドルウェアでは要求ごとに最小レート制限をオーバーライドします。

app.Run(async (context) =>
{
    context.Features.Get<IHttpMaxRequestBodySizeFeature>()
        .MaxRequestBodySize = 10 * 1024;

    var minRequestRateFeature = 
        context.Features.Get<IHttpMinRequestBodyDataRateFeature>();
    var minResponseRateFeature = 
        context.Features.Get<IHttpMinResponseDataRateFeature>();

    if (minRequestRateFeature != null)
    {
        minRequestRateFeature.MinDataRate = new MinDataRate(
            bytesPerSecond: 100, gracePeriod: TimeSpan.FromSeconds(10));
    }

    if (minResponseRateFeature != null)
    {
        minResponseRateFeature.MinDataRate = new MinDataRate(
            bytesPerSecond: 100, gracePeriod: TimeSpan.FromSeconds(10));
    }

前のサンプルで参照した IHttpMinResponseDataRateFeature は、HTTP/2 要求の HttpContext.Features には存在しません。これは、プロトコルで要求の多重化に対応するために、要求ごとのレート制限の変更が、HTTP/2 で一般的にサポートされていないからです。 ただし、IHttpMinRequestBodyDataRateFeature は引き続き現在の HTTP/2 要求の HttpContext.Features です。これは、HTTP/2 要求に対してであっても、IHttpMinRequestBodyDataRateFeature.MinDataRatenull に設定すれば、読み取りのレート制限を要求ごとに "すべて無効" にできるためです。 IHttpMinRequestBodyDataRateFeature.MinDataRate を読み取ろうとしたり、null 以外の値に設定しようとしたりすると、HTTP/2 要求を指定した NotSupportedException がスローされます。

KestrelServerOptions.Limits で構成したサーバー全体のレート制限は、引き続き HTTP/1.x と HTTP/2 の両方の接続に適用されます。

要求ヘッダー タイムアウト

RequestHeadersTimeout

サーバーで要求ヘッダーの受信にかかる時間の最大値を取得または設定します。 既定値は 30 秒です。

webBuilder.ConfigureKestrel(serverOptions =>
{
    serverOptions.Limits.MaxConcurrentConnections = 100;
    serverOptions.Limits.MaxConcurrentUpgradedConnections = 100;
    serverOptions.Limits.MaxRequestBodySize = 10 * 1024;
    serverOptions.Limits.MinRequestBodyDataRate =
        new MinDataRate(bytesPerSecond: 100, 
            gracePeriod: TimeSpan.FromSeconds(10));
    serverOptions.Limits.MinResponseDataRate =
        new MinDataRate(bytesPerSecond: 100, 
            gracePeriod: TimeSpan.FromSeconds(10));
    serverOptions.Listen(IPAddress.Loopback, 5000);
    serverOptions.Listen(IPAddress.Loopback, 5001, 
        listenOptions =>
        {
            listenOptions.UseHttps("testCert.pfx", 
                "testPassword");
        });
    serverOptions.Limits.KeepAliveTimeout = 
        TimeSpan.FromMinutes(2);
    serverOptions.Limits.RequestHeadersTimeout = 
        TimeSpan.FromMinutes(1);
})

接続ごとの最大ストリーム

HTTP/2 接続ごとの同時要求ストリームの数は、Http2.MaxStreamsPerConnection によって制限されます。 余分なストリームは拒否されます。

webBuilder.ConfigureKestrel(serverOptions =>
{
    serverOptions.Limits.Http2.MaxStreamsPerConnection = 100;
});

既定値は 100 です。

ヘッダー テーブルのサイズ

HTTP/2 接続では、HTTP ヘッダーは HPACK デコーダーによって圧縮解除されます。 HPACK デコーダーが使用するヘッダー圧縮テーブルのサイズは Http2.HeaderTableSize によって制限されます。 値はオクテット単位で指定し、ゼロ (0) より大きくなければなりません。

webBuilder.ConfigureKestrel(serverOptions =>
{
    serverOptions.Limits.Http2.HeaderTableSize = 4096;
});

既定値は 4096 です。

最大フレーム サイズ

Http2.MaxFrameSize は、サーバーによって受信または送信された HTTP/2 接続フレーム ペイロードの最大許容サイズを示しています。 値はオクテット単位で指定し、2^14 (16,384) から 2^24-1 (16,777,215) までの範囲とする必要があります。

webBuilder.ConfigureKestrel(serverOptions =>
{
    serverOptions.Limits.Http2.MaxFrameSize = 16384;
});

既定値は 2^14 (16,384) です。

最大要求ヘッダー サイズ

Http2.MaxRequestHeaderFieldSize は、要求ヘッダー値の最大許容サイズをオクテット単位で示しています。 この制限は、名前と値の圧縮表示と非圧縮表示の両方に適用されます。 ゼロ (0) より大きい値である必要があります。

webBuilder.ConfigureKestrel(serverOptions =>
{
    serverOptions.Limits.Http2.MaxRequestHeaderFieldSize = 8192;
});

既定値は 8,192 です。

初期接続ウィンドウ サイズ

Http2.InitialConnectionWindowSize は、サーバーが接続ごとの要求 (ストリーム) 全体で一度にバッファする最大要求本文データをバイト単位で示しています。 要求は Http2.InitialStreamWindowSize による制限も受けます。 この値は 65,535 より大きく、2^31 (2,147,483,648) 未満である必要があります。

webBuilder.ConfigureKestrel(serverOptions =>
{
    serverOptions.Limits.Http2.InitialConnectionWindowSize = 131072;
});

既定値は 128 KB (131,072) です。

初期ストリーム ウィンドウ サイズ

Http2.InitialStreamWindowSize は、サーバーが要求 (ストリーム) ごとに一度にバッファする最大要求本文データをバイト単位で示しています。 要求は Http2.InitialConnectionWindowSize による制限も受けます。 この値は 65,535 より大きく、2^31 (2,147,483,648) 未満である必要があります。

webBuilder.ConfigureKestrel(serverOptions =>
{
    serverOptions.Limits.Http2.InitialStreamWindowSize = 98304;
});

既定値は 96 KB (98,304) です。

予告編

HTTP トレーラーは HTTP ヘッダーに似ていますが、応答本文の送信後に送信される点が異なります。 IIS と HTTP.sys の場合は、HTTP/2 応答トレーラーのみがサポートされています。

if (httpContext.Response.SupportsTrailers())
{
    httpContext.Response.DeclareTrailer("trailername");	

    // Write body
    httpContext.Response.WriteAsync("Hello world");

    httpContext.Response.AppendTrailer("trailername", "TrailerValue");
}

上記のコード例では次のようになっています。

  • SupportsTrailers によって、応答におけるトレーラーが確実にサポートされます。
  • DeclareTrailer によって、指定したトレーラー名が Trailer 応答ヘッダーに追加されます。 応答のトレーラーを宣言することは省略可能ですが、推奨されています。 DeclareTrailer を呼び出す場合、それは、応答ヘッダーを送信する前に行う必要があります。
  • AppendTrailer によって、トレーラーが追加されます。

Reset

リセットを使用すると、指定されたエラー コードを使用してサーバーに HTTP/2 要求をリセットさせることができます。 リセット要求は中止されたと見なされます。

var resetFeature = httpContext.Features.Get<IHttpResetFeature>();
resetFeature.Reset(errorCode: 2);

上記のコード例の Reset により、INTERNAL_ERROR エラー コードが指定されています。 HTTP/2 エラー コードの詳細については、HTTP/2 仕様の「エラーコード」セクションを参照してください。

同期 I/O

AllowSynchronousIO を使うと、要求と応答に対して同期 I/O を許可するかどうかを制御できます。 既定値は false です。

警告

ブロッキング同期 I/O 操作の回数が多いと、スレッド プールの不足を招き、アプリが応答しなくなる可能性があります。 非同期 I/O をサポートしていないライブラリを使用する場合にのみ AllowSynchronousIO を有効にしてください。

同期 I/O を有効にする例を次に示します。

webBuilder.ConfigureKestrel(serverOptions =>
{
    serverOptions.AllowSynchronousIO = true;
})

Kestrel のその他のオプションと制限については、以下をご覧ください。

エンドポイントの構成

既定では、ASP.NET Core は以下にバインドされます。

  • http://localhost:5000
  • https://localhost:5001 (ローカル開発証明書が存在する場合)

以下を使用して URL を指定します。

  • ASPNETCORE_URLS 環境変数。
  • --urls コマンド ライン引数。
  • urls ホスト構成キー。
  • UseUrls 拡張メソッド。

これらの方法を使うと、1 つまたは複数の HTTP エンドポイントおよび HTTPS エンドポイント (既定の証明書が使用可能な場合は HTTPS) を指定できます。 セミコロン区切りのリストとして値を構成します (例: "Urls": "http://localhost:8000;http://localhost:8001")。

これらの方法について詳しくは、「サーバーの URL」および「構成のオーバーライド」をご覧ください。

開発証明書が作成されます。

一部のブラウザーでは、ローカル開発証明書を信頼するには、明示的にアクセス許可を付与する必要があります。

プロジェクト テンプレートでは、アプリを HTTPS で実行するように既定で構成され、HTTPS のリダイレクトと HSTS のサポートが含まれます。

KestrelServerOptionsListen または ListenUnixSocket メソッドを呼び出して、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

ConfigureEndpointDefaults を呼び出すListenListen を呼び出すことで作成されるエンドポイントには既定値が適用されません。

ConfigureHttpsDefaults(Action<HttpsConnectionAdapterOptions>)

各 HTTPS エンドポイントに対して実行するように、構成の Action を指定します。 ConfigureHttpsDefaults を複数回呼び出すと、前の Action が最後に指定した Action で置き換えられます。

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

Note

ConfigureHttpsDefaults を呼び出すListenListen を呼び出すことで作成されるエンドポイントには既定値が適用されません。

Configure(IConfiguration)

入力として IConfiguration を受け取る Kestrel を設定するための構成ローダーを作成します。 構成のスコープは、Kestrel の構成セクションにする必要があります。

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 は、HttpsConnectionAdapterOptions を構成するための Action です。 ListenOptions を返します。
  • storeName は、証明書の読み込み元の証明書ストアです。
  • subject は、証明書のサブジェクト名です。
  • allowInvalid は、無効な証明書 (自己署名証明書など) を考慮する必要があるかどうかを示します。
  • location は、証明書を読み込むストアの場所です。
  • serverCertificate は、X.509 証明書です。

運用環境では、HTTPS を明示的に構成する必要があります。 少なくとも、既定の証明書を指定する必要があります。

サポートされている構成を次に説明します。

  • 構成なし
  • 構成から既定の証明書を置き換える
  • コードで既定値を変更する

構成なし

Kestrel は、http://localhost:5000https://localhost:5001 (既定の証明書が使用可能な場合) でリッスンします。

構成から既定の証明書を置き換える

CreateDefaultBuilder は既定で Configure(context.Configuration.GetSection("Kestrel")) を呼び出して Kestrel の構成を読み込みます。 Kestrel は、既定の HTTPS アプリ設定構成スキーマを使用できます。 ディスク上のファイルまたは証明書ストアから、URL や使用する証明書など、複数のエンドポイントを構成します。

次の appsettings.json の例では以下のようになります。

  • AllowInvalidtrue に設定し、の無効な証明書 (自己署名証明書など) の使用を許可します。
  • 証明書 (後の例では HttpsDefaultCert) が指定されていないすべての HTTPS エンドポイントは、[証明書]>[既定] または開発証明書で定義されている証明書にフォールバックします。
{
  "Kestrel": {
    "Endpoints": {
      "Http": {
        "Url": "http://localhost:5000"
      },
      "HttpsInlineCertFile": {
        "Url": "https://localhost:5001",
        "Certificate": {
          "Path": "<path to .pfx file>",
          "Password": "<certificate password>"
        }
      },
      "HttpsInlineCertStore": {
        "Url": "https://localhost:5002",
        "Certificate": {
          "Subject": "<subject; required>",
          "Store": "<certificate store; required>",
          "Location": "<location; defaults to CurrentUser>",
          "AllowInvalid": "<true or false; defaults to false>"
        }
      },
      "HttpsDefaultCert": {
        "Url": "https://localhost:5003"
      },
      "Https": {
        "Url": "https://*:5004",
        "Certificate": {
          "Path": "<path to .pfx file>",
          "Password": "<certificate password>"
        }
      }
    },
    "Certificates": {
      "Default": {
        "Path": "<path to .pfx file>",
        "Password": "<certificate password>"
      }
    }
  }
}

証明書ノードの PathPassword を使用する代わりの方法は、証明書ストアのフィールドを使って証明書を指定することです。 たとえば、[証明書]>[既定] の証明書は次のように指定できます。

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

スキーマに関する注意事項:

  • エンドポイント名は大文字と小文字が区別されます。 たとえば、HTTPSHttps は有効です。
  • Url パラメーターは、エンドポイントごとに必要です。 このパラメーターの形式は、1 つの値に制限されることを除き、最上位レベルの Urls 構成パラメーターと同じです。
  • これらのエンドポイントは、最上位レベルの Urls 構成での定義に追加されるのではなく、それを置き換えます。 コードで Listen を使用して定義されているエンドポイントは、構成セクションで定義されているエンドポイントに累積されます。
  • Certificate セクションは省略可能です。 Certificate セクションを指定しないと、前述のシナリオで定義した既定値が使用されます。 既定値を使用できない場合、サーバーにより例外がスローされ、開始できません。
  • Certificate セクションは、Certificate-Password 証明書と Subject-Store 証明書の両方をサポートします。
  • ポートが競合しない限り、この方法で任意の数のエンドポイントを定義できます。
  • options.Configure(context.Configuration.GetSection("{SECTION}")).Endpoint(string name, listenOptions => { }) メソッドで返す KestrelConfigurationLoader を使用して、構成されているエンドポイントの設定を補足できます。
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 オーバーロードとしてミラーリングするので、コードと構成のエンドポイントを同じ場所で構成できます。 これらのオーバーロードでは名前は使用されず、構成からの既定の設定のみが使用されます。

コードで既定値を変更する

ConfigureEndpointDefaults およびConfigureHttpsDefaults を使用して、ListenOptions および HttpsConnectionAdapterOptions の既定の設定を変更できます (前のシナリオで指定した既定の証明書のオーバーライドなど)。 エンドポイントを構成する前に、ConfigureEndpointDefaults および ConfigureHttpsDefaults を呼び出す必要があります。

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

    serverOptions.ConfigureHttpsDefaults(listenOptions =>
    {
        listenOptions.SslProtocols = SslProtocols.Tls12;
    });
});

Kestrel による SNI のサポート

Server Name Indication (SNI) を使用すると、同じ IP アドレスとポートで複数のドメインをホストできます。 SNI が機能するためには、サーバーが正しい証明書を提供できるように、クライアントは TLS ハンドシェイクの間にセキュリティで保護されたセッションのホスト名をサーバーに送信します。 クライアントは、TLS ハンドシェイクに続くセキュリティで保護されたセッション中に、提供された証明書をサーバーとの暗号化された通信に使用します。

Kestrel は、ServerCertificateSelector コールバックによって SNI をサポートします。 コールバックは接続ごとに 1 回呼び出されるので、アプリはそれを使って、ホスト名を検査し、適切な証明書を選択できます。

SNI のサポートには、次が必要です。

  • ターゲット フレームワーク netcoreapp2.1 以降で実行される必要があります。 net461 以降、コールバックは呼び出されますが、name は常に null です。 クライアントが TLS ハンドシェイクでホスト名パラメーターを提供しない場合も、namenull です。
  • すべての Web サイトは、同じ Kestrel インスタンスで実行されます。 Kestrel では、リバース プロキシは使用しない、複数のインスタンスでの IP アドレスとポートの共有はサポートしていません。
webBuilder.ConfigureKestrel(serverOptions =>
{
    serverOptions.ListenAnyIP(5005, listenOptions =>
    {
        listenOptions.UseHttps(httpsOptions =>
        {
            var localhostCert = CertificateLoader.LoadFromStoreCert(
                "localhost", "My", StoreLocation.CurrentUser,
                allowInvalid: true);
            var exampleCert = CertificateLoader.LoadFromStoreCert(
                "example.com", "My", StoreLocation.CurrentUser,
                allowInvalid: true);
            var subExampleCert = CertificateLoader.LoadFromStoreCert(
                "sub.example.com", "My", StoreLocation.CurrentUser,
                allowInvalid: true);
            var certs = new Dictionary<string, X509Certificate2>(
                StringComparer.OrdinalIgnoreCase);
            certs["localhost"] = localhostCert;
            certs["example.com"] = exampleCert;
            certs["sub.example.com"] = subExampleCert;

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

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

接続のログ記録

接続でのバイト レベルの通信に対してデバッグ レベルのログを出力するには、UseConnectionLogging を呼び出します。 接続のログ記録は、TLS 暗号化の間やプロキシの内側など、低レベルの通信での問題のトラブルシューティングに役立ちます。 UseConnectionLoggingUseHttps の前に配置されている場合は、暗号化されたトラフィックがログに記録されます。 UseConnectionLoggingUseHttps の後に配置されている場合は、暗号化解除されたトラフィックがログに記録されます。

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 を使用することはできません。
  • ListenUseUrls 両方の方法を同時に使用すると、Listen エンドポイントが UseUrls エンドポイントをオーバーライドします。

IIS エンドポイントの構成

IIS を使用するときは、IIS オーバーライド バインドに対する URL バインドを、Listen または UseUrls によって設定します。 詳しくは、「ASP.NET Core モジュールの概要」をご覧ください。

ListenOptions.Protocols

Protocolsプロパティでは、接続エンドポイントまたはサーバーに対して有効にされる HTTP プロトコル (HttpProtocols) が確定されます。 HttpProtocols 列挙型から Protocols プロパティに値を割り当てます。

HttpProtocols 列挙値 許可される接続プロトコル
Http1 HTTP/1.1 のみ。 TLS の有無にかかわらず使用できます。
Http2 HTTP/2 のみ。 予備知識モードがクライアントでサポートされている場合に限り、TLS なしで使用できます。
Http1AndHttp2 HTTP/1.1 および HTTP/2。 HTTP/2 では、クライアントが TLS アプリケーション レイヤー プロトコル ネゴシエーション (ALPN) ハンドシェイクで HTTP/2 を選択する必要があります。それ以外の場合、接続は既定で HTTP/1.1 となります。

任意のエンドポイントに対する ListenOptions.Protocols の既定値は HttpProtocols.Http1AndHttp2 です。

HTTP/2 に対する TLS 制限事項:

  • TLS バージョン 1.2 以降
  • 再ネゴシエーションは無効
  • 圧縮は無効
  • 短期キー交換サイズの上限:
    • 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");
    });
});

必要に応じて、接続ミドルウェアを使用し、特定の暗号のために接続ごとに 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();
        });
    });
});

Linux では、CipherSuitesPolicy を使って、接続ごとに TLS ハンドシェイクをフィルター処理できます。

// using System.Net.Security;
// using Microsoft.AspNetCore.Hosting;
// using Microsoft.AspNetCore.Server.Kestrel.Core;
// using Microsoft.Extensions.DependencyInjection;
// using Microsoft.Extensions.Hosting;

webBuilder.ConfigureKestrel(serverOptions =>
{
    serverOptions.ConfigureHttpsDefaults(listenOptions =>
    {
        listenOptions.OnAuthenticate = (context, sslOptions) =>
        {
            sslOptions.CipherSuitesPolicy = new CipherSuitesPolicy(
                new[]
                {
                    TlsCipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
                    TlsCipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
                    // ...
                });
        };
    });
});

構成からのプロトコルを設定する

CreateDefaultBuilder は既定で serverOptions.Configure(context.Configuration.GetSection("Kestrel")) を呼び出して Kestrel の構成を読み込みます。

次の appsettings.json の例では、すべてのエンドポイントにおける既定の接続プロトコルとして HTTP/1.1 を確立しています。

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

次の appsettings.json の例では、特定のエンドポイントにおける HTTP/1.1 接続プロトコルを確立しています。

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

構成で設定された値は、コード内で指定されたプロトコルによってオーバーライドされます。

URL プレフィックス

UseUrls--urls コマンドライン引数、urls ホスト構成キー、または ASPNETCORE_URLS 環境変数を使用する場合、URL プレフィックスは次のいずれかの形式となります。

HTTP URL プレフィックスのみが有効です。 UseUrls を使用して URL バインドを構成する場合、Kestrel は HTTPS をサポートしません。

  • IPv4 アドレスとポート番号

    http://65.55.39.10:80/
    

    0.0.0.0 は、すべての IPv4 アドレスにバインドする特別なケースです。

  • IPv6 アドレスとポート番号

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

    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 は警告をログに記録します。

ホスト フィルタリング

Kestrel は http://example.com:5000 などのプレフィックスに基づく構成をサポートしますが、Kestrel はほとんどのホスト名を無視します。 ホスト localhost は、ループバック アドレスへのバインドに使用される特殊なケースです。 明示的な IP アドレス以外のすべてのホストは、すべてのパブリック IP アドレスにバインドします。 Host ヘッダーは検証されません。

これを解決するには、Host Filtering Middleware を使用します。 Host Filtering Middleware は、ASP.NET Core アプリに暗黙的に含まれる、Microsoft.AspNetCore.HostFiltering パッケージによって提供されています。 ミドルウェアは CreateDefaultBuilder によって追加され、そこでは AddHostFiltering が呼び出されます。

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

    public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
        WebHost.CreateDefaultBuilder(args)
            .UseStartup<Startup>();
}

Host Filtering Middleware は既定では無効です。 このミドルウェアを有効にするには、appsettings.json/appsettings.{Environment}.jsonAllowedHosts キーを定義します。 この値は、ポート番号を含まないホスト名のセミコロン区切りリストです。

appsettings.json:

{
  "AllowedHosts": "example.com;localhost"
}

Note

Forwarded Headers Middleware にも AllowedHosts オプションがあります。 Forwarded Headers Middleware および Host Filtering Middleware には、異なるシナリオ用に類似した機能があります。 リバース プロキシ サーバーまたはロード バランサーを使用して要求を転送するとき、Host ヘッダーが保存されていない場合、Forwarded Headers Middleware に AllowedHosts を設定するのが適切です。 Kestrel が一般向けエッジ サーバーとして使用されていたり、Host ヘッダーが直接転送されたりしている場合、Host Filtering Middleware に AllowedHosts を設定するのが適切です。

Forwarded Headers Middleware の詳細については、「プロキシ サーバーとロード バランサーを使用するために ASP.NET Core を構成する」を参照してください。

Libuv トランスポート構成

Libuv (UseLibuv) を使用する必要のあるプロジェクトの場合

  • アプリのプロジェクト ファイルに Microsoft.AspNetCore.Server.Kestrel.Transport.Libuv パッケージの依存関係を追加します。

    <PackageReference Include="Microsoft.AspNetCore.Server.Kestrel.Transport.Libuv"
                      Version="{VERSION}" />
    
  • IWebHostBuilderUseLibuv を呼び出す

    public class Program
    {
        public static void Main(string[] args)
        {
            CreateHostBuilder(args).Build().Run();
        }
    
        public static IHostBuilder CreateHostBuilder(string[] args) =>
            Host.CreateDefaultBuilder(args)
                .ConfigureWebHostDefaults(webBuilder =>
                {
                    webBuilder.UseLibuv();
                    webBuilder.UseStartup<Startup>();
                });
    }
    

HTTP/1.1 要求のドレイン

HTTP 接続を開くには時間がかかります。 HTTPS の場合も、リソースが大量に消費されます。 そのため、Kestrel は、HTTP/1.1 プロトコルごとに接続を再利用しようとします。 接続を再利用できるようにするには、要求本文を完全に使用する必要があります。 アプリは、サーバーがリダイレクトまたは 404 応答を返す POST 要求のように、常に要求本文を使用するわけではありません。 POST-リダイレクトの場合:

  • クライアントが POST データの一部を既に送信している可能性があります。
  • サーバーは 301 応答を書き込みます。
  • 以前の要求本文の POST データが完全に読み取られるまで、新しい要求に対して接続を使用することはできません。
  • Kestrel は、要求本文のドレインを試行します。 要求本文のドレインは、データを処理せずに読み取りおよび破棄を行うことを意味します。

ドレイン プロセスでは、接続が再利用できるようになる代わりに、残りのデータをドレインするのに時間がかかります。

  • ドレインのタイムアウトは 5 秒であり、この設定は構成できません。
  • Content-Length または Transfer-Encoding ヘッダーで指定されたすべてのデータがタイムアウト前に読み取られていない場合、接続は閉じられます。

場合によっては、応答の書き込みの前後に要求をすぐに終了する必要があります。 たとえば、クライアントのデータ キャップが制限されているため、アップロードするデータの制限が優先される場合があります。 このような場合、要求を終了するには、コントローラー、Razor ページ、またはミドルウェアから HttpContext.Abort を呼び出します。

Abort を呼び出す際には、次の点に注意する必要があります。

  • 新しい接続の作成には、時間とコストがかかることがあります。
  • 接続が閉じる前にクライアントが応答を読み取ることは保証されません。
  • Abort の呼び出しは最小限に抑え、一般的なエラーではなく重大なエラーが発生した場合のために予約する必要があります。
    • Abort は特定の問題を解決する必要がある場合にのみ、呼び出してください。 たとえば、悪意のあるクライアントがデータを POST しようとしている場合や、クライアント コードに大量または多数の要求を引き起こすバグがある場合に Abort を呼び出します。
    • HTTP 404 (Not Found) などの一般的なエラー状況では、Abort を呼び出さないでください。

Abort を呼び出す前に HttpResponse.CompleteAsync を呼び出すと、サーバーが応答の書き込みを完了したことが保証されます。 ただし、クライアントの動作は予測できないため、接続が中止される前に応答が読み取られない場合があります。

プロトコルでは、接続を閉じずに個々の要求ストリームを中止することがサポートされているため、HTTP/2 では、このプロセスが異なります。 5 秒のドレイン タイムアウトは適用されません。 応答の完了後に未読の要求本文データがある場合、サーバーは HTTP/2 RST フレームを送信します。 追加の要求本文データ フレームは無視されます。

可能なかぎり、クライアントが Expect: 100-continue の要求ヘッダーを利用し、要求本文の送信を開始する前にサーバーの応答を待機することをお勧めします。 これにより、クライアントは、不要なデータを送信する前に、応答を調べて中止することができます。

その他の技術情報