ASP.NET Core での HTTP.sys Web サーバーの実装

作成者: Tom DykstraChris Ross

HTTP.sys は、Windows 上でのみ動作する ASP.NET Core 用 Web サーバーです。 HTTP.sys は Kestrel サーバーの代替製品であり、Kestrel では提供されていない機能がいくつか用意されています。

重要

HTTP.sys は ASP.NET Core モジュールと互換性がなく、IIS や IIS Express で使用することはできません。

HTTP.sys は、次の機能をサポートします。

  • Windows 認証
  • ポート共有
  • SNI を使用する HTTPS
  • HTTP/2 over TLS (Windows 10 以降)
  • 直接ファイル伝送
  • 応答キャッシュ
  • WebSocket (Windows 8 以降)

サポートされている Windows バージョン:

  • Windows 7 以降
  • Windows Server 2008 R2 以降

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

HTTP.sys を使用するタイミング

HTTP.sys は、次のような展開に適しています。

  • IIS を使用せず、インターネットに直接サーバーを公開する必要がある。

    HTTP.sys communicates directly with the Internet

  • 内部の展開から Kestrel では使用できない機能が要求されている。 詳細については、Kestrel と HTTP.sys の比較に関するページを参照してください。

    HTTP.sys communicates directly with the internal network

HTTP.sys は、さまざまな種類の攻撃を防ぎ、フル機能の Web サーバーとして堅牢性、セキュリティ、スケーラビリティを提供する、成熟したテクノロジです。 IIS 自体が、HTTP.sys 上で HTTP リスナーとして実行されています。

HTTP/2 のサポート

HTTP/2 は、次の基本要件が満たされている場合に、ASP.NET Core アプリに対して有効になります。

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

HTTP/2 は既定で有効になっています。 Http/2 接続が確立されない場合、接続は http/1.1 にフォールバックします。 Windows の今後のリリースで、HTTP.sys で HTTP/2 を無効にする機能を含む HTTP/2 構成フラグが使用可能になる予定です。

HTTP/3 のサポート

HTTP/3 は、次の基本要件が満たされている場合に、ASP.NET Core アプリに対して有効になります。

以前のバージョンの Windows 11 ビルドでは、Windows Insider ビルドの使用が必要になる場合があります。

HTTP/3 は、alt-svc ヘッダーを介して HTTP/1.1 または HTTP/2 からのアップグレードとして検出されます。 これは、最初の要求では HTTP/3 に切り替える前に、通常 HTTP/1.1 または HTTP/2 が使用されることを意味します。 Http.Sys によって alt-svc ヘッダーは自動的に追加されないため、アプリケーションで追加する必要があります。 次のコードは、alt-svc 応答ヘッダーを追加するミドルウェアの例を示しています。

app.Use((context, next) =>
{
    context.Response.Headers.AltSvc = "h3=\":443\"";
    return next(context);
});

上記のコードを要求パイプラインの早い段階に配置します。

Http.Sys では、HTTP/3 が使用可能であることをクライアントに通知するために、応答ヘッダーではなく AltSvc HTTP/2 プロトコル メッセージの送信もサポートされています。 EnableAltSvc レジストリ キーに関するページを参照してください。 これには、IP アドレスではなくホスト名を使用する netsh sslcert バインドが必要です。

Kerberos を使用したカーネル モード認証

HTTP.sys では、Kerberos 認証プロトコルを使用したカーネル モード認証に処理が委任されます。 Kerberos および HTTP.sys ではユーザー モード認証がサポートされていません。 Active Directory から取得され、クライアントによって、ユーザーを認証するサーバーに転送される Kerberos トークン/チケットを暗号化解除するには、コンピューター アカウントを使用する必要があります。 アプリのユーザーではなく、ホストのサービス プリンシパル名 (SPN) を登録します。

カーネル モード応答バッファリングのサポート

一部のシナリオでは、待機時間の長い少量の書き込みが大量に発生すると、HTTP.sys のパフォーマンスに大きな影響を与える場合があります。 この影響は、HTTP.sysPipe バッファーが実装されていないことが原因です。 これらのシナリオでパフォーマンスを向上させるため、HTTP.sys では応答バッファリングがサポートされています。 HttpSysOptions.EnableKernelResponseBufferingtrue に設定して、バッファリングを有効にします。

応答バッファリングは、同期 I/O を実行するアプリで、または非同期 I/O で未処理の書き込みを一度に 1 つしか実行しないアプリで有効にする必要があります。 これらのシナリオでは、応答バッファリングにより、待機時間の長い接続に対してスループットが大幅に向上する場合があります。

非同期 I/O を使用し、未処理の書き込みを一度に複数実行する場合があるアプリでは、このフラグを使用しないでください このフラグを有効にすると、HTTP.Sys により CPU とメモリの使用率が高くなる場合があります。

HTTP.sys の使用方法

HTTP.sys を使用するように ASP.NET Core アプリを構成する

ホストを構築するときに UseHttpSys 拡張メソッドを呼び出し、必要な HttpSysOptions を指定します。 次の例では、既定値にオプションを設定しています。

using Microsoft.AspNetCore.Hosting.Server;
using Microsoft.AspNetCore.Hosting.Server.Features;
using Microsoft.AspNetCore.Http.Features;
using Microsoft.AspNetCore.Server.HttpSys;

var builder = WebApplication.CreateBuilder(args);

builder.WebHost.UseHttpSys(options =>
{
    options.AllowSynchronousIO = false;
    options.Authentication.Schemes = AuthenticationSchemes.None;
    options.Authentication.AllowAnonymous = true;
    options.MaxConnections = null;
    options.MaxRequestBodySize = 30_000_000;
    options.UrlPrefixes.Add("http://localhost:5005");
});

builder.Services.AddRazorPages();

var app = builder.Build();

HTTP.sys の追加の構成は、レジストリ設定を通じて処理されます。

HTTP.sys オプションの詳細については、「HttpSysOptions」を参照してください。

MaxRequestBodySize

要求本文の最大許容サイズ (バイト単位) です。 null に設定する場合、要求本文の最大サイズは制限されません。 この制限は、アップグレード済みの接続 (常に無制限) には影響しません。

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

[RequestSizeLimit(100000000)]
public IActionResult MyActionMethod()

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

要求ごとにアプリで MaxRequestBodySize をオーバーライドする必要がある場合は、IHttpMaxRequestBodySizeFeature を使います。

app.Use((context, next) =>
{
    context.Features.GetRequiredFeature<IHttpMaxRequestBodySizeFeature>()
                                             .MaxRequestBodySize = 10 * 1024;

    var server = context.RequestServices
        .GetRequiredService<IServer>();
    var serverAddressesFeature = server.Features
                                 .GetRequiredFeature<IServerAddressesFeature>();

    var addresses = string.Join(", ", serverAddressesFeature.Addresses);

    var loggerFactory = context.RequestServices
        .GetRequiredService<ILoggerFactory>();
    var logger = loggerFactory.CreateLogger("Sample");

    logger.LogInformation("Addresses: {addresses}", addresses);

    return next(context);
});

Visual Studio を使用する場合は、アプリが IIS または IIS Express を実行するように構成されていないことを確認します。

Visual Studio では、既定の起動プロファイルは IIS Express 用です。 プロジェクトをコンソール アプリとして実行するには、次のスクリーンショットに示すように、選択したプロファイルを手動で変更します。

Select console app profile

Windows Server を構成する

  1. アプリに対して開くポートを決めたら、Windows ファイアウォールNew-NetFirewallRule PowerShell コマンドレットを使用して、トラフィックが HTTP.sys に到達できるようにファイアウォールのポートを開きます。 次のコマンドとアプリの構成では、ポート 443 を使用します。

  2. Azure VM に展開する場合は、ネットワーク セキュリティ グループ内でポートを開きます。 次のコマンドとアプリの構成では、ポート 443 を使用します。

  3. 必要に応じて、X.509 証明書を取得してインストールします。

    Windows の場合は、New-SelfSignedCertificate PowerShell コマンドレットを使用して自己署名証明書を作成します。 サポート対象外の例については、UpdateIISExpressSSLForChrome.ps1 を参照してください。

    自己署名証明書か CA 署名証明書のいずれかをサーバーの Local Machine>Personal ストアにインストールします。

  4. アプリがフレームワークに依存する展開である場合は、.NET Core、.NET Framework、またはその両方 (アプリが .NET Framework をターゲットとする .NET Core アプリである場合) をインストールします。

    • .NET Core: アプリで .NET Core が必要な場合は、.NET Core のダウンロードから .NET Core Runtime インストーラーを取得して実行します。 サーバーに SDK 全体をインストールしないでください。
    • .NET Framework:アプリで .NET Framework が必要な場合は、.NET Framework のインストール ガイドを参照してください。 必要な .NET Framework をインストールします。 最新の .NET Framework のインストーラーは .NET Core のダウンロード ページから入手できます。

    アプリが自己完結型の展開の場合、アプリの展開内にランタイムが含まれています。 サーバーにフレームワークをインストールする必要はありません。

  5. アプリに URL とポートを構成します。

    既定では、ASP.NET Core は http://localhost:5000 にバインドされます。 URL プレフィックスとポートを構成するには、次のオプションがあります。

    次のコード例は、サーバーのローカル IP アドレス 10.0.0.4 を使ってポート 443 上で UrlPrefixes を使う方法を示しています。

    var builder = WebApplication.CreateBuilder(args);
    
    builder.WebHost.UseHttpSys(options =>
    {
        options.UrlPrefixes.Add("https://10.0.0.4:443");
    });
    
    builder.Services.AddRazorPages();
    
    var app = builder.Build();
    

    UrlPrefixes の利点は、プレフィックスの形式が正しくなかった場合、すぐにエラー メッセージが生成されることです。

    UrlPrefixes の設定は UseUrls/urls/ASPNETCORE_URLS の設定をオーバーライドします。 したがって、UseUrlsurls、および ASPNETCORE_URLS 環境変数の利点は、Kestrel と HTTP.sys を簡単に切り替えられることです。

    HTTP.sys は、URL プレフィックスで次の 2 種類のワイルドカードを認識します:

    • *弱いバインディング であり、フォールバック バインディングとも呼ばれます。 URL プレフィックスが http://*:5000 で、他の何かがポート 5000 にバインドされている場合、このバインディングは使用されません。
    • +強力なバインディングです。 URL プレフィックスが http://+:5000 の場合、このバインディングは他のポート 5000 バインドの前に使用されます。

    詳細については、「UrlPrefix 文字列」を参照してください。

    警告

    最上位のワイルドカードのバインド ( http://*:80/http://+:80 ) は使用しては いけません 。 最上位のワイルドカードのバインドを使用すると、アプリにセキュリティの脆弱性が生じます。 これは、強力と脆弱の両方のワイルドカードに適用されます。 ワイルドカードではなく、明示的なホスト名か IP アドレスを使用してください。 親ドメイン全体を制御する場合、サブドメインのワイルドカードのバインド (たとえば、*.mysub.com) がセキュリティ リスクになることはありません (脆弱である *.com とは対照的)。 詳細については、RFC 9110: セクション 7.2: 「Host and :authority (ホストと :authority)」を参照してください。

    多くの場合、アプリとコンテナーには、リッスンするためのポート (ポート 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 用のサーバー固有のメカニズムを介して個別に構成する必要があります。

    これらの構成キーは、最上位のワイルドカード バインドと同等です。 これらは開発およびコンテナーのシナリオには便利ですが、他のサービスもホストする可能性があるコンピューター上で実行する場合は、ワイルドカードを避けてください。

  6. サーバーで URL プレフィックスを事前登録します。

    HTTP.sys を構成するための組み込みツールは、netsh.exe です。 netsh.exe を使用して、URL プレフィックスを予約し、X.509 証明書を割り当てることができます。 ツールを使用するには管理者特権が必要です。

    netsh.exe ツールを使用して、アプリ用に URL を登録します。

    netsh http add urlacl url=<URL> user=<USER>
    
    • <URL>:完全修飾 URL (Uniform Resource Locator)。 ワイルドカードのバインドは使用しないでください。 有効なホスト名かローカル IP アドレスを使用してください。 "URL の末尾にはスラッシュが必要です。 "
    • <USER>:ユーザーまたはユーザー グループの名前を指定します。

    次の例では、サーバーのローカル IP アドレスは 10.0.0.4 です。

    netsh http add urlacl url=https://10.0.0.4:443/ user=Users
    

    URL が登録されると、ツールから URL reservation successfully added という応答があります。

    登録済みの URL を削除するには、delete urlacl コマンドを使用します。

    netsh http delete urlacl url=<URL>
    
  7. サーバーで X.509 証明書を登録します。

    netsh.exe ツールを使用して、アプリ用の証明書を登録します。

    netsh http add sslcert ipport=<IP>:<PORT> certhash=<THUMBPRINT> appid="{<GUID>}"
    
    • <IP>:バインド用のローカル IP アドレスを指定します。 ワイルドカードのバインドは使用しないでください。 有効な IP アドレスを使用してください。
    • <PORT>:バインド用のポートを指定します。
    • <THUMBPRINT>:X.509 証明書の拇印です。
    • <GUID>:情報提供を目的として開発者によって生成された、アプリを表す GUID です。

    参照用に、この GUID をパッケージ タグとしてアプリに格納します。

    • Visual Studio での操作: [][]
      • ソリューション エクスプローラー内でアプリを右クリックし、 [プロパティ] をクリックして、アプリのプロジェクト プロパティを開きます。
      • [パッケージ] タブを選択します。
      • 作成した GUID を [タグ] フィールドに入力します。
    • Visual Studio を使用しない場合:
      • アプリのプロジェクト ファイルを開きます。

      • 作成した GUID を指定した <PackageTags> プロパティを、新規または既存の <PropertyGroup> に追加します。

        <PropertyGroup>
          <PackageTags>9412ee86-c21b-4eb8-bd89-f650fbf44931</PackageTags>
        </PropertyGroup>
        

    次に例を示します。

    • サーバーのローカル IP アドレスは 10.0.0.4 です。
    • オンラインのランダム GUID ジェネレーターによって、appid の値が提供されます。
    netsh http add sslcert 
        ipport=10.0.0.4:443 
        certhash=b66ee04419d4ee37464ab8785ff02449980eae10 
        appid="{9412ee86-c21b-4eb8-bd89-f650fbf44931}"
    

    証明書が登録されると、ツールから SSL Certificate successfully added という応答があります。

    証明書の登録を削除するには、delete sslcert コマンドを使用します。

    netsh http delete sslcert ipport=<IP>:<PORT>
    

    以下は、netsh.exe のリファレンス ドキュメントです。

  8. アプリを実行します。

    1024 より大きいポート番号で (HTTPS ではなく) HTTP を使用して localhost にバインドする場合、アプリの実行に管理者権限は必要ありません。 その他の構成の場合 (たとえば、ローカル IP アドレスを使用する場合やポート 443 にバインドする場合)、管理者権限でアプリを実行します。

    サーバーのパブリック IP アドレスでアプリが応答します。 この例では、サーバーは自身のパブリック IP アドレス 104.214.79.47 でインターネットからアクセスされます。

    この例では開発証明書が使用されています。 証明書が信頼できないというブラウザーの警告がバイパスされた後に、ページが安全に読み込まれます。

    Browser window showing the app's Index page loaded

プロキシ サーバーとロード バランサーのシナリオ

インターネットや企業ネットワークからの要求とやりとりする HTTP.sys でホストされるアプリの場合、プロキシ サーバーやロード バランサーの背後でホストするとき、追加の構成が必要になることがあります。 詳細については、「プロキシ サーバーとロード バランサーを使用するために ASP.NET Core を構成する」を参照してください。

IHttpSysRequestTimingFeature を使用して詳細なタイミング情報を取得する

IHttpSysRequestTimingFeature では、要求の詳細なタイミング情報が提供されます。

  • タイムスタンプは、QueryPerformanceCounter を使用して取得されます。
  • タイムスタンプの頻度は、QueryPerformanceFrequency を使用して取得できます。
  • タイミングのインデックスを HttpSysRequestTimingType にキャストして、タイミングが何を表しているのかを把握できます。
  • 現在の要求でタイミングを利用できない場合、値は 0 になることがあります。
using Microsoft.AspNetCore.Http.Features;
using Microsoft.AspNetCore.Server.HttpSys;

var builder = WebApplication.CreateBuilder(args);

builder.WebHost.UseHttpSys();

var app = builder.Build();

app.Use((context, next) =>
{
    var feature = context.Features.GetRequiredFeature<IHttpSysRequestTimingFeature>();
    
    var loggerFactory = context.RequestServices.GetRequiredService<ILoggerFactory>();
    var logger = loggerFactory.CreateLogger("Sample");

    var timestamps = feature.Timestamps;

    for (var i = 0; i < timestamps.Length; i++)
    {
        var timestamp = timestamps[i];
        var timingType = (HttpSysRequestTimingType)i;

        logger.LogInformation("Timestamp {timingType}: {timestamp}",
                                          timingType, timestamp);
    }

    return next(context);
});

app.MapGet("/", () => Results.Ok());

app.Run();

IHttpSysRequestTimingFeature.TryGetTimestamp では、指定されたタイミングの種類のタイムスタンプを取得します。

using Microsoft.AspNetCore.Http.Features;
using Microsoft.AspNetCore.Server.HttpSys;
var builder = WebApplication.CreateBuilder(args);

builder.WebHost.UseHttpSys();

var app = builder.Build();

app.Use((context, next) =>
{
    var feature = context.Features.GetRequiredFeature<IHttpSysRequestTimingFeature>();

    var loggerFactory = context.RequestServices.GetRequiredService<ILoggerFactory>();
    var logger = loggerFactory.CreateLogger("Sample");

    var timingType = HttpSysRequestTimingType.RequestRoutingEnd;

    if (feature.TryGetTimestamp(timingType, out var timestamp))
    {
        logger.LogInformation("Timestamp {timingType}: {timestamp}",
                                          timingType, timestamp);
    }
    else
    {
        logger.LogInformation("Timestamp {timingType}: not available for the "
                                           + "current request",    timingType);
    }

    return next(context);
});

app.MapGet("/", () => Results.Ok());

app.Run();

IHttpSysRequestTimingFeature.TryGetElapsedTime は、指定された 2 つのタイミング間の経過時間を示します。

using Microsoft.AspNetCore.Http.Features;
using Microsoft.AspNetCore.Server.HttpSys;

var builder = WebApplication.CreateBuilder(args);

builder.WebHost.UseHttpSys();

var app = builder.Build();

app.Use((context, next) =>
{
    var feature = context.Features.GetRequiredFeature<IHttpSysRequestTimingFeature>();

    var loggerFactory = context.RequestServices.GetRequiredService<ILoggerFactory>();
    var logger = loggerFactory.CreateLogger("Sample");

    var startingTimingType = HttpSysRequestTimingType.RequestRoutingStart;
    var endingTimingType = HttpSysRequestTimingType.RequestRoutingEnd;

    if (feature.TryGetElapsedTime(startingTimingType, endingTimingType, out var elapsed))
    {
        logger.LogInformation(
            "Elapsed time {startingTimingType} to {endingTimingType}: {elapsed}",
            startingTimingType,
            endingTimingType,
            elapsed);
    }
    else
    {
        logger.LogInformation(
            "Elapsed time {startingTimingType} to {endingTimingType}:"
            + " not available for the current request.",
            startingTimingType,
            endingTimingType);
    }

    return next(context);
});

app.MapGet("/", () => Results.Ok());

app.Run();

gRPC をサポートする高度な HTTP/2 機能

HTTP.sys 内の追加の HTTP/2 機能によって、gRPC がサポートされています。これには、応答トレーラーやリセット フレームの送信に関するサポートが含まれます。

HTTP.sys で gRPC を実行するための要件:

  • Windows 11 ビルド 22000 またはそれ以降、Windows Server 2022 ビルド 20348 またはそれ以降が必要です。
  • TLS 1.2 またはそれ以降の接続。

予告編

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 仕様の「エラーコード」セクションを参照してください。

トレース

HTTP.sys からトレースを取得する方法については、「HTTP.sys 管理のシナリオ」を参照してください。

その他のリソース

HTTP.sys は、Windows 上でのみ動作する ASP.NET Core 用 Web サーバーです。 HTTP.sys は Kestrel サーバーの代替製品であり、Kestrel では提供されていない機能がいくつか用意されています。

重要

HTTP.sys は ASP.NET Core モジュールと互換性がなく、IIS や IIS Express で使用することはできません。

HTTP.sys は、次の機能をサポートします。

  • Windows 認証
  • ポート共有
  • SNI を使用する HTTPS
  • HTTP/2 over TLS (Windows 10 以降)
  • 直接ファイル伝送
  • 応答キャッシュ
  • WebSocket (Windows 8 以降)

サポートされている Windows バージョン:

  • Windows 7 以降
  • Windows Server 2008 R2 以降

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

HTTP.sys を使用するタイミング

HTTP.sys は、次のような展開に適しています。

  • IIS を使用せず、インターネットに直接サーバーを公開する必要がある。

    HTTP.sys communicates directly with the Internet

  • 内部の展開から Kestrel では使用できない機能が要求されている。 詳細については、Kestrel と HTTP.sys の比較に関するページを参照してください。

    HTTP.sys communicates directly with the internal network

HTTP.sys は、さまざまな種類の攻撃を防ぎ、フル機能の Web サーバーとして堅牢性、セキュリティ、スケーラビリティを提供する、成熟したテクノロジです。 IIS 自体が、HTTP.sys 上で HTTP リスナーとして実行されています。

HTTP/2 のサポート

HTTP/2 は、次の基本要件が満たされている場合に、ASP.NET Core アプリに対して有効になります。

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

HTTP/2 は既定で有効になっています。 Http/2 接続が確立されない場合、接続は http/1.1 にフォールバックします。 Windows の今後のリリースで、HTTP.sys で HTTP/2 を無効にする機能を含む HTTP/2 構成フラグが使用可能になる予定です。

HTTP/3 のサポート

HTTP/3 は、次の基本要件が満たされている場合に、ASP.NET Core アプリに対して有効になります。

以前のバージョンの Windows 11 ビルドでは、Windows Insider ビルドの使用が必要になる場合があります。

HTTP/3 は、alt-svc ヘッダーを介して HTTP/1.1 または HTTP/2 からのアップグレードとして検出されます。 これは、最初の要求では HTTP/3 に切り替える前に、通常 HTTP/1.1 または HTTP/2 が使用されることを意味します。 Http.Sys によって alt-svc ヘッダーは自動的に追加されないため、アプリケーションで追加する必要があります。 次のコードは、alt-svc 応答ヘッダーを追加するミドルウェアの例を示しています。

app.Use((context, next) =>
{
    context.Response.Headers.AltSvc = "h3=\":443\"";
    return next(context);
});

上記のコードを要求パイプラインの早い段階に配置します。

Http.Sys では、HTTP/3 が使用可能であることをクライアントに通知するために、応答ヘッダーではなく AltSvc HTTP/2 プロトコル メッセージの送信もサポートされています。 EnableAltSvc レジストリ キーに関するページを参照してください。 これには、IP アドレスではなくホスト名を使用する netsh sslcert バインドが必要です。

Kerberos を使用したカーネル モード認証

HTTP.sys では、Kerberos 認証プロトコルを使用したカーネル モード認証に処理が委任されます。 Kerberos および HTTP.sys ではユーザー モード認証がサポートされていません。 Active Directory から取得され、クライアントによって、ユーザーを認証するサーバーに転送される Kerberos トークン/チケットを暗号化解除するには、コンピューター アカウントを使用する必要があります。 アプリのユーザーではなく、ホストのサービス プリンシパル名 (SPN) を登録します。

HTTP.sys の使用方法

HTTP.sys を使用するように ASP.NET Core アプリを構成する

ホストを構築するときに UseHttpSys 拡張メソッドを呼び出し、必要な HttpSysOptions を指定します。 次の例では、既定値にオプションを設定しています。

public static IHostBuilder CreateHostBuilder(string[] args) =>
    Host.CreateDefaultBuilder(args)
        .ConfigureWebHostDefaults(webBuilder =>
        {
            webBuilder.UseHttpSys(options =>
            {
                options.AllowSynchronousIO = false;
                options.Authentication.Schemes = AuthenticationSchemes.None;
                options.Authentication.AllowAnonymous = true;
                options.MaxConnections = null;
                options.MaxRequestBodySize = 30000000;
                options.UrlPrefixes.Add("http://localhost:5005");
            });
            webBuilder.UseStartup<Startup>();
        });

HTTP.sys の追加の構成は、レジストリ設定を通じて処理されます。

HTTP.sys オプションの詳細については、「HttpSysOptions」を参照してください。

MaxRequestBodySize

要求本文の最大許容サイズ (バイト単位) です。 null に設定する場合、要求本文の最大サイズは制限されません。 この制限は、アップグレード済みの接続 (常に無制限) には影響しません。

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

[RequestSizeLimit(100000000)]
public IActionResult MyActionMethod()

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

要求ごとにアプリで MaxRequestBodySize をオーバーライドする必要がある場合は、IHttpMaxRequestBodySizeFeature を使います。

public void Configure(IApplicationBuilder app, IWebHostEnvironment env, 
    ILogger<Startup> logger, IServer server)
{
    app.Use(async (context, next) =>
    {
        context.Features.Get<IHttpMaxRequestBodySizeFeature>()
            .MaxRequestBodySize = 10 * 1024;

        var serverAddressesFeature = 
            app.ServerFeatures.Get<IServerAddressesFeature>();
        var addresses = string.Join(", ", serverAddressesFeature?.Addresses);

        logger.LogInformation("Addresses: {Addresses}", addresses);

        await next.Invoke();
    });

    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }
    else
    {
        app.UseExceptionHandler("/Error");
    }

    app.UseStaticFiles();
    app.UseRouting();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapRazorPages();
    });
}

Visual Studio を使用する場合は、アプリが IIS または IIS Express を実行するように構成されていないことを確認します。

Visual Studio では、既定の起動プロファイルは IIS Express 用です。 プロジェクトをコンソール アプリとして実行するには、次のスクリーンショットに示すように、選択したプロファイルを手動で変更します。

Select console app profile

Windows Server を構成する

  1. アプリに対して開くポートを決めたら、Windows ファイアウォールNew-NetFirewallRule PowerShell コマンドレットを使用して、トラフィックが HTTP.sys に到達できるようにファイアウォールのポートを開きます。 次のコマンドとアプリの構成では、ポート 443 を使用します。

  2. Azure VM に展開する場合は、ネットワーク セキュリティ グループ内でポートを開きます。 次のコマンドとアプリの構成では、ポート 443 を使用します。

  3. 必要に応じて、X.509 証明書を取得してインストールします。

    Windows の場合は、New-SelfSignedCertificate PowerShell コマンドレットを使用して自己署名証明書を作成します。 サポート対象外の例については、UpdateIISExpressSSLForChrome.ps1 を参照してください。

    自己署名証明書か CA 署名証明書のいずれかをサーバーの Local Machine>Personal ストアにインストールします。

  4. アプリがフレームワークに依存する展開である場合は、.NET Core、.NET Framework、またはその両方 (アプリが .NET Framework をターゲットとする .NET Core アプリである場合) をインストールします。

    • .NET Core: アプリで .NET Core が必要な場合は、.NET Core のダウンロードから .NET Core Runtime インストーラーを取得して実行します。 サーバーに SDK 全体をインストールしないでください。
    • .NET Framework:アプリで .NET Framework が必要な場合は、.NET Framework のインストール ガイドを参照してください。 必要な .NET Framework をインストールします。 最新の .NET Framework のインストーラーは .NET Core のダウンロード ページから入手できます。

    アプリが自己完結型の展開の場合、アプリの展開内にランタイムが含まれています。 サーバーにフレームワークをインストールする必要はありません。

  5. アプリに URL とポートを構成します。

    既定では、ASP.NET Core は http://localhost:5000 にバインドされます。 URL プレフィックスとポートを構成するには、次のオプションがあります。

    次のコード例は、サーバーのローカル IP アドレス 10.0.0.4 を使ってポート 443 上で UrlPrefixes を使う方法を示しています。

    public static IHostBuilder CreateHostBuilder(string[] args) =>
        Host.CreateDefaultBuilder(args)
            .ConfigureWebHostDefaults(webBuilder =>
            {
                webBuilder.UseHttpSys(options =>
                {
                    options.UrlPrefixes.Add("https://10.0.0.4:443");
                });
                webBuilder.UseStartup<Startup>();
            });
    

    UrlPrefixes の利点は、プレフィックスの形式が正しくなかった場合、すぐにエラー メッセージが生成されることです。

    UrlPrefixes の設定は UseUrls/urls/ASPNETCORE_URLS の設定をオーバーライドします。 したがって、UseUrlsurls、および ASPNETCORE_URLS 環境変数の利点は、Kestrel と HTTP.sys を簡単に切り替えられることです。

    HTTP.sys では、HTTP サーバー API の UrlPrefix 文字列形式が使用されます。

    警告

    最上位のワイルドカードのバインド ( http://*:80/http://+:80 ) は使用しては いけません 。 最上位のワイルドカードのバインドを使用すると、アプリにセキュリティの脆弱性が生じます。 これは、強力と脆弱の両方のワイルドカードに適用されます。 ワイルドカードではなく、明示的なホスト名か IP アドレスを使用してください。 親ドメイン全体を制御する場合、サブドメインのワイルドカードのバインド (たとえば、*.mysub.com) がセキュリティ リスクになることはありません (脆弱である *.com とは対照的)。 詳細については、RFC 9110: セクション 7.2: 「Host and :authority (ホストと :authority)」を参照してください。

  6. サーバーで URL プレフィックスを事前登録します。

    HTTP.sys を構成するための組み込みツールは、netsh.exe です。 netsh.exe を使用して、URL プレフィックスを予約し、X.509 証明書を割り当てることができます。 ツールを使用するには管理者特権が必要です。

    netsh.exe ツールを使用して、アプリ用に URL を登録します。

    netsh http add urlacl url=<URL> user=<USER>
    
    • <URL>:完全修飾 URL (Uniform Resource Locator)。 ワイルドカードのバインドは使用しないでください。 有効なホスト名かローカル IP アドレスを使用してください。 "URL の末尾にはスラッシュが必要です。 "
    • <USER>:ユーザーまたはユーザー グループの名前を指定します。

    次の例では、サーバーのローカル IP アドレスは 10.0.0.4 です。

    netsh http add urlacl url=https://10.0.0.4:443/ user=Users
    

    URL が登録されると、ツールから URL reservation successfully added という応答があります。

    登録済みの URL を削除するには、delete urlacl コマンドを使用します。

    netsh http delete urlacl url=<URL>
    
  7. サーバーで X.509 証明書を登録します。

    netsh.exe ツールを使用して、アプリ用の証明書を登録します。

    netsh http add sslcert ipport=<IP>:<PORT> certhash=<THUMBPRINT> appid="{<GUID>}"
    
    • <IP>:バインド用のローカル IP アドレスを指定します。 ワイルドカードのバインドは使用しないでください。 有効な IP アドレスを使用してください。
    • <PORT>:バインド用のポートを指定します。
    • <THUMBPRINT>:X.509 証明書の拇印です。
    • <GUID>:情報提供を目的として開発者によって生成された、アプリを表す GUID です。

    参照用に、この GUID をパッケージ タグとしてアプリに格納します。

    • Visual Studio での操作: [][]
      • ソリューション エクスプローラー内でアプリを右クリックし、 [プロパティ] をクリックして、アプリのプロジェクト プロパティを開きます。
      • [パッケージ] タブを選択します。
      • 作成した GUID を [タグ] フィールドに入力します。
    • Visual Studio を使用しない場合:
      • アプリのプロジェクト ファイルを開きます。

      • 作成した GUID を指定した <PackageTags> プロパティを、新規または既存の <PropertyGroup> に追加します。

        <PropertyGroup>
          <PackageTags>9412ee86-c21b-4eb8-bd89-f650fbf44931</PackageTags>
        </PropertyGroup>
        

    次に例を示します。

    • サーバーのローカル IP アドレスは 10.0.0.4 です。
    • オンラインのランダム GUID ジェネレーターによって、appid の値が提供されます。
    netsh http add sslcert 
        ipport=10.0.0.4:443 
        certhash=b66ee04419d4ee37464ab8785ff02449980eae10 
        appid="{9412ee86-c21b-4eb8-bd89-f650fbf44931}"
    

    証明書が登録されると、ツールから SSL Certificate successfully added という応答があります。

    証明書の登録を削除するには、delete sslcert コマンドを使用します。

    netsh http delete sslcert ipport=<IP>:<PORT>
    

    以下は、netsh.exe のリファレンス ドキュメントです。

  8. アプリを実行します。

    1024 より大きいポート番号で (HTTPS ではなく) HTTP を使用して localhost にバインドする場合、アプリの実行に管理者権限は必要ありません。 その他の構成の場合 (たとえば、ローカル IP アドレスを使用する場合やポート 443 にバインドする場合)、管理者権限でアプリを実行します。

    サーバーのパブリック IP アドレスでアプリが応答します。 この例では、サーバーは自身のパブリック IP アドレス 104.214.79.47 でインターネットからアクセスされます。

    この例では開発証明書が使用されています。 証明書が信頼できないというブラウザーの警告がバイパスされた後に、ページが安全に読み込まれます。

    Browser window showing the app's Index page loaded

プロキシ サーバーとロード バランサーのシナリオ

インターネットや企業ネットワークからの要求とやりとりする HTTP.sys でホストされるアプリの場合、プロキシ サーバーやロード バランサーの背後でホストするとき、追加の構成が必要になることがあります。 詳細については、「プロキシ サーバーとロード バランサーを使用するために ASP.NET Core を構成する」を参照してください。

gRPC をサポートする高度な HTTP/2 機能

HTTP.sys 内の追加の HTTP/2 機能によって、gRPC がサポートされています。これには、応答トレーラーやリセット フレームの送信に関するサポートが含まれます。

HTTP.sys で gRPC を実行するための要件:

  • Windows 11 ビルド 22000 またはそれ以降、Windows Server 2022 ビルド 20348 またはそれ以降が必要です。
  • TLS 1.2 またはそれ以降の接続。

予告編

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 仕様の「エラーコード」セクションを参照してください。

その他の技術情報

HTTP.sys は、Windows 上でのみ動作する ASP.NET Core 用 Web サーバーです。 HTTP.sys は Kestrel サーバーの代替製品であり、Kestrel では提供されていない機能がいくつか用意されています。

重要

HTTP.sys は ASP.NET Core モジュールと互換性がなく、IIS や IIS Express で使用することはできません。

HTTP.sys は、次の機能をサポートします。

  • Windows 認証
  • ポート共有
  • SNI を使用する HTTPS
  • HTTP/2 over TLS (Windows 10 以降)
  • 直接ファイル伝送
  • 応答キャッシュ
  • WebSocket (Windows 8 以降)

サポートされている Windows バージョン:

  • Windows 7 以降
  • Windows Server 2008 R2 以降

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

HTTP.sys を使用するタイミング

HTTP.sys は、次のような展開に適しています。

  • IIS を使用せず、インターネットに直接サーバーを公開する必要がある。

    HTTP.sys communicates directly with the Internet

  • 内部の展開から Kestrel では使用できない機能が要求されている。 詳細については、Kestrel と HTTP.sys の比較に関するページを参照してください。

    HTTP.sys communicates directly with the internal network

HTTP.sys は、さまざまな種類の攻撃を防ぎ、フル機能の Web サーバーとして堅牢性、セキュリティ、スケーラビリティを提供する、成熟したテクノロジです。 IIS 自体が、HTTP.sys 上で HTTP リスナーとして実行されています。

HTTP/2 のサポート

Http/2 は、次の基本要件が満たされている場合に、ASP.NET Core アプリに対して有効になります。

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

HTTP/2 は既定で有効になっています。 Http/2 接続が確立されない場合、接続は http/1.1 にフォールバックします。 Windows の今後のリリースで、HTTP.sys で HTTP/2 を無効にする機能を含む HTTP/2 構成フラグが使用可能になる予定です。

Kerberos を使用したカーネル モード認証

HTTP.sys では、Kerberos 認証プロトコルを使用したカーネル モード認証に処理が委任されます。 Kerberos および HTTP.sys ではユーザー モード認証がサポートされていません。 Active Directory から取得され、クライアントによって、ユーザーを認証するサーバーに転送される Kerberos トークン/チケットを暗号化解除するには、コンピューター アカウントを使用する必要があります。 アプリのユーザーではなく、ホストのサービス プリンシパル名 (SPN) を登録します。

HTTP.sys の使用方法

HTTP.sys を使用するように ASP.NET Core アプリを構成する

ホストを構築するときに UseHttpSys 拡張メソッドを呼び出し、必要な HttpSysOptions を指定します。 次の例では、既定値にオプションを設定しています。

public static IHostBuilder CreateHostBuilder(string[] args) =>
    Host.CreateDefaultBuilder(args)
        .ConfigureWebHostDefaults(webBuilder =>
        {
            webBuilder.UseHttpSys(options =>
            {
                options.AllowSynchronousIO = false;
                options.Authentication.Schemes = AuthenticationSchemes.None;
                options.Authentication.AllowAnonymous = true;
                options.MaxConnections = null;
                options.MaxRequestBodySize = 30000000;
                options.UrlPrefixes.Add("http://localhost:5005");
            });
            webBuilder.UseStartup<Startup>();
        });

HTTP.sys の追加の構成は、レジストリ設定を通じて処理されます。

HTTP.sys オプション

プロパティ 説明 Default
AllowSynchronousIO HttpContext.Request.Body および HttpContext.Response.Body に対して、入力/出力の同期を許可するかどうかを制御します。 false
Authentication.AllowAnonymous 匿名要求を許可します。 true
Authentication.Schemes 許可される認証方式を指定します。 リスナーを破棄する前ならいつでも変更できます。 値は AuthenticationSchemes 列挙型 (BasicKerberosNegotiateNone、および NTLM) によって指定します。 None
EnableResponseCaching 対象となるヘッダーを持つ応答に対して、カーネル モードのキャッシュを試行します。 Set-CookieVary、または Pragma ヘッダーを含む応答は対象外です。 応答は、public である Cache-Control ヘッダーと shared-max-age または max-age の値のいずれかを含むか、または Expires ヘッダーを含む必要があります。 true
Http503Verbosity 調整の条件によって要求を拒否する場合の HTTP.sys の動作。 Http503VerbosityLevel.
Basic
MaxAccepts 同時受け入れの最大数です。 5 × Environment.
ProcessorCount
MaxConnections 受け入れるコンカレント接続の最大数です。 無限にするには、-1 を使用します。 コンピューター全体のレジストリ設定を使用するには、null を使用します。 null
(コンピューター全体の
設定)
MaxRequestBodySize MaxRequestBodySize」セクションを参照してください。 30000000 バイト
(~28.6 MB)
RequestQueueLimit キューに置くことができる要求の最大数。 1000
RequestQueueMode これは、サーバーで要求キューの作成と構成を行う必要があるかどうか、または既存のキューにアタッチする必要があるかを示します。
既存のキューにアタッチする場合、既存の構成オプションのほとんどは適用されません。
RequestQueueMode.Create
RequestQueueName HTTP.sys 要求キューの名前。 null (匿名キュー)
ThrowWriteExceptions 応答本文の書き込みがクライアントの接続の切断によって失敗した場合、例外をスローするか、または正常に完了するかどうかを指定します。 false
(正常に完了する)
Timeouts HTTP.sys TimeoutManager 構成を公開します。これはレジストリでも構成できます。 各設定に関する既定値などの詳細については、API のリンクを参照してください。
UrlPrefixes HTTP.sys に登録する UrlPrefixCollection を指定します。 最も便利なのは UrlPrefixCollection.Add です。これを使用して、コレクションにプレフィックスを追加できます。 これらは、リスナーを破棄する前ならいつでも変更できます。

MaxRequestBodySize

要求本文の最大許容サイズ (バイト単位) です。 null に設定する場合、要求本文の最大サイズは制限されません。 この制限は、アップグレード済みの接続 (常に無制限) には影響しません。

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

[RequestSizeLimit(100000000)]
public IActionResult MyActionMethod()

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

要求ごとにアプリで MaxRequestBodySize をオーバーライドする必要がある場合は、IHttpMaxRequestBodySizeFeature を使います。

public void Configure(IApplicationBuilder app, IWebHostEnvironment env, 
    ILogger<Startup> logger, IServer server)
{
    app.Use(async (context, next) =>
    {
        context.Features.Get<IHttpMaxRequestBodySizeFeature>()
            .MaxRequestBodySize = 10 * 1024;

        var serverAddressesFeature = 
            app.ServerFeatures.Get<IServerAddressesFeature>();
        var addresses = string.Join(", ", serverAddressesFeature?.Addresses);

        logger.LogInformation("Addresses: {Addresses}", addresses);

        await next.Invoke();
    });

    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }
    else
    {
        app.UseExceptionHandler("/Error");
    }

    app.UseStaticFiles();
    app.UseRouting();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapRazorPages();
    });
}

Visual Studio を使用する場合は、アプリが IIS または IIS Express を実行するように構成されていないことを確認します。

Visual Studio では、既定の起動プロファイルは IIS Express 用です。 プロジェクトをコンソール アプリとして実行するには、次のスクリーン ショットに示すように、選択したプロファイルを手動で変更します。

Select console app profile

Windows Server を構成する

  1. アプリに対して開くポートを決めたら、Windows ファイアウォールNew-NetFirewallRule PowerShell コマンドレットを使用して、トラフィックが HTTP.sys に到達できるようにファイアウォールのポートを開きます。 次のコマンドとアプリの構成では、ポート 443 を使用します。

  2. Azure VM に展開する場合は、ネットワーク セキュリティ グループ内でポートを開きます。 次のコマンドとアプリの構成では、ポート 443 を使用します。

  3. 必要に応じて、X.509 証明書を取得してインストールします。

    Windows の場合は、New-SelfSignedCertificate PowerShell コマンドレットを使用して自己署名証明書を作成します。 サポート対象外の例については、UpdateIISExpressSSLForChrome.ps1 を参照してください。

    自己署名証明書か CA 署名証明書のいずれかをサーバーの Local Machine>Personal ストアにインストールします。

  4. アプリがフレームワークに依存する展開である場合は、.NET Core、.NET Framework、またはその両方 (アプリが .NET Framework をターゲットとする .NET Core アプリである場合) をインストールします。

    • .NET Core: アプリで .NET Core が必要な場合は、.NET Core のダウンロードから .NET Core Runtime インストーラーを取得して実行します。 サーバーに SDK 全体をインストールしないでください。
    • .NET Framework:アプリで .NET Framework が必要な場合は、.NET Framework のインストール ガイドを参照してください。 必要な .NET Framework をインストールします。 最新の .NET Framework のインストーラーは .NET Core のダウンロード ページから入手できます。

    アプリが自己完結型の展開の場合、アプリの展開内にランタイムが含まれています。 サーバーにフレームワークをインストールする必要はありません。

  5. アプリに URL とポートを構成します。

    既定では、ASP.NET Core は http://localhost:5000 にバインドされます。 URL プレフィックスとポートを構成するには、次のオプションがあります。

    次のコード例は、サーバーのローカル IP アドレス 10.0.0.4 を使ってポート 443 上で UrlPrefixes を使う方法を示しています。

    public static IHostBuilder CreateHostBuilder(string[] args) =>
        Host.CreateDefaultBuilder(args)
            .ConfigureWebHostDefaults(webBuilder =>
            {
                webBuilder.UseHttpSys(options =>
                {
                    options.UrlPrefixes.Add("https://10.0.0.4:443");
                });
                webBuilder.UseStartup<Startup>();
            });
    

    UrlPrefixes の利点は、プレフィックスの形式が正しくなかった場合、すぐにエラー メッセージが生成されることです。

    UrlPrefixes の設定は UseUrls/urls/ASPNETCORE_URLS の設定をオーバーライドします。 したがって、UseUrlsurls、および ASPNETCORE_URLS 環境変数の利点は、Kestrel と HTTP.sys を簡単に切り替えられることです。

    HTTP.sys では、HTTP サーバー API の UrlPrefix 文字列形式が使用されます。

    警告

    最上位のワイルドカードのバインド ( http://*:80/http://+:80 ) は使用しては いけません 。 最上位のワイルドカードのバインドを使用すると、アプリにセキュリティの脆弱性が生じます。 これは、強力と脆弱の両方のワイルドカードに適用されます。 ワイルドカードではなく、明示的なホスト名か IP アドレスを使用してください。 親ドメイン全体を制御する場合、サブドメインのワイルドカードのバインド (たとえば、*.mysub.com) がセキュリティ リスクになることはありません (脆弱である *.com とは対照的)。 詳細については、RFC 9110: セクション 7.2: 「Host and :authority (ホストと :authority)」を参照してください。

  6. サーバーで URL プレフィックスを事前登録します。

    HTTP.sys を構成するための組み込みツールは、netsh.exe です。 netsh.exe を使用して、URL プレフィックスを予約し、X.509 証明書を割り当てることができます。 ツールを使用するには管理者特権が必要です。

    netsh.exe ツールを使用して、アプリ用に URL を登録します。

    netsh http add urlacl url=<URL> user=<USER>
    
    • <URL>:完全修飾 URL (Uniform Resource Locator)。 ワイルドカードのバインドは使用しないでください。 有効なホスト名かローカル IP アドレスを使用してください。 "URL の末尾にはスラッシュが必要です。 "
    • <USER>:ユーザーまたはユーザー グループの名前を指定します。

    次の例では、サーバーのローカル IP アドレスは 10.0.0.4 です。

    netsh http add urlacl url=https://10.0.0.4:443/ user=Users
    

    URL が登録されると、ツールから URL reservation successfully added という応答があります。

    登録済みの URL を削除するには、delete urlacl コマンドを使用します。

    netsh http delete urlacl url=<URL>
    
  7. サーバーで X.509 証明書を登録します。

    netsh.exe ツールを使用して、アプリ用の証明書を登録します。

    netsh http add sslcert ipport=<IP>:<PORT> certhash=<THUMBPRINT> appid="{<GUID>}"
    
    • <IP>:バインド用のローカル IP アドレスを指定します。 ワイルドカードのバインドは使用しないでください。 有効な IP アドレスを使用してください。
    • <PORT>:バインド用のポートを指定します。
    • <THUMBPRINT>:X.509 証明書の拇印です。
    • <GUID>:情報提供を目的として開発者によって生成された、アプリを表す GUID です。

    参照用に、この GUID をパッケージ タグとしてアプリに格納します。

    • Visual Studio での操作: [][]
      • ソリューション エクスプローラー内でアプリを右クリックし、 [プロパティ] をクリックして、アプリのプロジェクト プロパティを開きます。
      • [パッケージ] タブを選択します。
      • 作成した GUID を [タグ] フィールドに入力します。
    • Visual Studio を使用しない場合:
      • アプリのプロジェクト ファイルを開きます。

      • 作成した GUID を指定した <PackageTags> プロパティを、新規または既存の <PropertyGroup> に追加します。

        <PropertyGroup>
          <PackageTags>9412ee86-c21b-4eb8-bd89-f650fbf44931</PackageTags>
        </PropertyGroup>
        

    次に例を示します。

    • サーバーのローカル IP アドレスは 10.0.0.4 です。
    • オンラインのランダム GUID ジェネレーターによって、appid の値が提供されます。
    netsh http add sslcert 
        ipport=10.0.0.4:443 
        certhash=b66ee04419d4ee37464ab8785ff02449980eae10 
        appid="{9412ee86-c21b-4eb8-bd89-f650fbf44931}"
    

    証明書が登録されると、ツールから SSL Certificate successfully added という応答があります。

    証明書の登録を削除するには、delete sslcert コマンドを使用します。

    netsh http delete sslcert ipport=<IP>:<PORT>
    

    以下は、netsh.exe のリファレンス ドキュメントです。

  8. アプリを実行します。

    1024 より大きいポート番号で (HTTPS ではなく) HTTP を使用して localhost にバインドする場合、アプリの実行に管理者権限は必要ありません。 その他の構成の場合 (たとえば、ローカル IP アドレスを使用する場合やポート 443 にバインドする場合)、管理者権限でアプリを実行します。

    サーバーのパブリック IP アドレスでアプリが応答します。 この例では、サーバーは自身のパブリック IP アドレス 104.214.79.47 でインターネットからアクセスされます。

    この例では開発証明書が使用されています。 証明書が信頼できないというブラウザーの警告がバイパスされた後に、ページが安全に読み込まれます。

    Browser window showing the app's Index page loaded

プロキシ サーバーとロード バランサーのシナリオ

インターネットや企業ネットワークからの要求とやりとりする HTTP.sys でホストされるアプリの場合、プロキシ サーバーやロード バランサーの背後でホストするとき、追加の構成が必要になることがあります。 詳細については、「プロキシ サーバーとロード バランサーを使用するために ASP.NET Core を構成する」を参照してください。

gRPC をサポートする高度な HTTP/2 機能

HTTP.sys 内の追加の HTTP/2 機能によって、gRPC がサポートされています。これには、応答トレーラーやリセット フレームの送信に関するサポートが含まれます。

HTTP.sys で gRPC を実行するための要件:

  • Windows 10、OS Build 19041.508 以降
  • TLS 1.2 以降の接続

予告編

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 仕様の「エラーコード」セクションを参照してください。

その他の技術情報