Kestrelimplementacja serwera sieci Web w ASP.NET Core

Przez Tom Dykstra, Chris Ross i Stephen Halter

Kestrelto międzyplatformowy serwer internetowy dla ASP.NET Core. Kestrelto serwer internetowy, który jest domyślnie dołączony i włączony w szablonach projektów ASP.NET Core.

Kestrel program obsługuje następujące scenariusze:

  • HTTPS
  • HTTP/2 (z wyjątkiem systemu macOS†)
  • Nieprzezroczyste uaktualnienie używane do włączania obiektów WebSocket
  • Gniazda systemu Unix w celu zapewnienia wysokiej wydajności za serwerem Nginx

†HTTP/2 będzie obsługiwana w systemie macOS w przyszłej wersji.

Kestrel program jest obsługiwany na wszystkich platformach i wersjach obsługiwanych przez platformę .NET Core.

Rozpoczęcie pracy

ASP.NET Core szablony projektów są używane Kestrel domyślnie, gdy nie są hostowane z usługami IIS. W przypadku następującego wygenerowanego szablonu Program.csWebApplication.CreateBuilder metoda wywołuje UseKestrel wewnętrznie:

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

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

app.Run();

Aby uzyskać więcej informacji na temat konfigurowania WebApplication interfejsów API i WebApplicationBuilder, zobacz Omówienie minimalnych interfejsów API.

Opcjonalne certyfikaty klienta

Aby uzyskać informacje na temat aplikacji, które muszą chronić podzbiór aplikacji przy użyciu certyfikatu, zobacz Opcjonalne certyfikaty klienta.

Dodatkowe zasoby

Uwaga

Od ASP.NET Core 5.0 Kestreltransport libuv jest przestarzały. Transport libuv nie otrzymuje aktualizacji do obsługi nowych platform systemu operacyjnego, takich jak Windows ARM64, i zostanie usunięty w przyszłej wersji. Usuń wszystkie wywołania do przestarzałej UseLibuv metody i zamiast tego użyj Kestreldomyślnego transportu gniazda.

Kestrelto międzyplatformowy serwer internetowy dla ASP.NET Core. Kestrelto serwer internetowy, który jest domyślnie dołączony i włączony w szablonach projektów ASP.NET Core.

Kestrel program obsługuje następujące scenariusze:

  • HTTPS
  • HTTP/2 (z wyjątkiem systemu macOS†)
  • Nieprzezroczyste uaktualnienie używane do włączania obiektów WebSocket
  • Gniazda systemu Unix w celu zapewnienia wysokiej wydajności za serwerem Nginx

†HTTP/2 będzie obsługiwana w systemie macOS w przyszłej wersji.

Kestrel program jest obsługiwany na wszystkich platformach i wersjach obsługiwanych przez platformę .NET Core.

Wyświetl lub pobierz przykładowy kod (jak pobrać)

Rozpoczęcie pracy

ASP.NET Core szablony projektów są używane Kestrel domyślnie, gdy nie są hostowane z usługami IIS. W Program.cspliku metoda wywołuje metodę ConfigureWebHostDefaultsUseKestrel:

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

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

Aby uzyskać więcej informacji na temat tworzenia hosta, zobacz sekcje Konfigurowanie hosta i Domyślne ustawienia konstruktorahosta ogólnego platformy .NET w ASP.NET Core.

Opcjonalne certyfikaty klienta

Aby uzyskać informacje na temat aplikacji, które muszą chronić podzbiór aplikacji przy użyciu certyfikatu, zobacz Opcjonalne certyfikaty klienta.

Dodatkowe zasoby

Uwaga

Od ASP.NET Core 5.0 Kestreltransport libuv jest przestarzały. Transport libuv nie otrzymuje aktualizacji do obsługi nowych platform systemu operacyjnego, takich jak Windows ARM64, i zostanie usunięty w przyszłej wersji. Usuń wszystkie wywołania do przestarzałej UseLibuv metody i zamiast tego użyj Kestreldomyślnego transportu gniazda.

Kestrelto międzyplatformowy serwer internetowy dla ASP.NET Core. Kestrelto serwer internetowy, który jest domyślnie dołączony do szablonów projektów ASP.NET Core.

Kestrel program obsługuje następujące scenariusze:

  • HTTPS
  • Nieprzezroczyste uaktualnienie używane do włączania obiektów WebSocket
  • Gniazda systemu Unix w celu zapewnienia wysokiej wydajności za serwerem Nginx
  • HTTP/2 (z wyjątkiem systemu macOS†)

†HTTP/2 będzie obsługiwana w systemie macOS w przyszłej wersji.

Kestrel program jest obsługiwany na wszystkich platformach i wersjach obsługiwanych przez platformę .NET Core.

Wyświetl lub pobierz przykładowy kod (jak pobrać)

Obsługa protokołu HTTP/2

Protokół HTTP/2 jest dostępny dla aplikacji ASP.NET Core, jeśli spełnione są następujące podstawowe wymagania:

  • System operacyjny†
    • Windows Server 2016/Windows 10 lub nowszym}
    • Linux z systemem OpenSSL 1.0.2 lub nowszym (na przykład Ubuntu 16.04 lub nowszym)
  • Platforma docelowa: .NET Core 2.2 lub nowsza
  • Połączenie negocjowania protokołu warstwy aplikacji (ALPN)
  • Połączenie TLS 1.2 lub nowsze

†HTTP/2 będzie obsługiwana w systemie macOS w przyszłej wersji. ***Kestrel ma ograniczoną obsługę protokołu HTTP/2 w Windows Server 2012 R2 i Windows 8.1. Obsługa jest ograniczona, ponieważ lista obsługiwanych zestawów szyfrowania TLS dostępnych w tych systemach operacyjnych jest ograniczona. Do zabezpieczenia połączeń TLS może być wymagany certyfikat wygenerowany przy użyciu algorytmu podpisu cyfrowego krzywej eliptycznej (ECDSA).

Jeśli zostanie nawiązane połączenie HTTP/2, HttpRequest.Protocol raportuje HTTP/2polecenie .

Począwszy od platformy .NET Core 3.0, protokół HTTP/2 jest domyślnie włączony. Aby uzyskać więcej informacji na temat konfiguracji, zobacz Kestrel sekcje opcje i ListenOptions.Protocols .

Kiedy używać z Kestrel zwrotnym serwerem proxy

Kestrel może być używany przez siebie lub z zwrotnym serwerem proxy. Zwrotny serwer proxy odbiera żądania HTTP z sieci i przekazuje je do adresu Kestrel. Przykłady zwrotnego serwera proxy obejmują:

Kestrel używany jako serwer sieci Web brzegowy (dostępny z Internetu):

Kestrel communicates directly with the Internet without a reverse proxy server

Kestrel używane w konfiguracji zwrotnego serwera proxy:

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

Konfiguracja z odwrotnym serwerem proxy lub bez tego serwera jest obsługiwaną konfiguracją hostingu.

Kestrel używany jako serwer brzegowy bez odwrotnego serwera proxy nie obsługuje udostępniania tego samego adresu IP i portu między wieloma procesami. Gdy Kestrel skonfigurowano nasłuchiwanie na porcie, Kestrel obsługuje cały ruch dla tego portu niezależnie od nagłówków żądań Host . Zwrotny serwer proxy, który może współużytkować porty, ma możliwość przekazywania żądań do Kestrel unikatowego adresu IP i portu.

Nawet jeśli zwrotny serwer proxy nie jest wymagany, użycie odwrotnego serwera proxy może być dobrym wyborem.

Zwrotny serwer proxy:

  • Może ograniczyć uwidoczniony obszar powierzchni publicznej aplikacji hostowanych przez nią.
  • Zapewnia dodatkową warstwę konfiguracji i obrony.
  • Może lepiej zintegrować się z istniejącą infrastrukturą.
  • Uprość równoważenie obciążenia i konfigurację bezpiecznej komunikacji (HTTPS). Tylko zwrotny serwer proxy wymaga certyfikatu X.509, a serwer może komunikować się z serwerami aplikacji w sieci wewnętrznej przy użyciu zwykłego protokołu HTTP.

Ostrzeżenie

Hostowanie w konfiguracji zwrotnego serwera proxy wymaga konfiguracji oprogramowania pośredniczącego nagłówków przekazywanych.

Kestrelw aplikacjach ASP.NET Core

ASP.NET Core szablony projektów są domyślnie używaneKestrel. W Program.cspliku metoda wywołuje metodę ConfigureWebHostDefaultsUseKestrel:

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

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

Aby uzyskać więcej informacji na temat tworzenia hosta, zobacz sekcje Konfigurowanie hosta i domyślne ustawienia konstruktorahosta ogólnego platformy .NET w ASP.NET Core.

Aby zapewnić dodatkową konfigurację po wywołaniu metody ConfigureWebHostDefaults, użyj polecenia 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 Opcje

Serwer Kestrel internetowy ma opcje konfiguracji ograniczeń, które są szczególnie przydatne we wdrożeniach dostępnych z Internetu.

Ustaw ograniczenia dla Limits właściwości KestrelServerOptions klasy. Właściwość Limits zawiera wystąpienie KestrelServerLimits klasy.

W poniższych przykładach użyto Microsoft.AspNetCore.Server.Kestrel.Core przestrzeni nazw:

using Microsoft.AspNetCore.Server.Kestrel.Core;

W przykładach przedstawionych w dalszej części tego artykułu Kestrel opcje są konfigurowane w kodzie języka C#. Kestrel opcje można również ustawić przy użyciu dostawcy konfiguracji. Na przykład dostawca konfiguracji plików może załadować Kestrel konfigurację z pliku appsettings.json lub appsettings.{Environment}.json :

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

Uwaga

KestrelServerOptionskonfiguracja punktu końcowego można konfigurować od dostawców konfiguracji. Pozostałą Kestrel konfigurację należy skonfigurować w kodzie języka C#.

Użyj jednej z następujących metod:

  • Skonfiguruj Kestrel w programie Startup.ConfigureServices:

    1. Wstrzykiwanie wystąpienia klasy IConfigurationStartup . W poniższym przykładzie przyjęto założenie, że wstrzyknięta konfiguracja jest przypisana do Configuration właściwości.

    2. W Startup.ConfigureServicespliku załaduj sekcję Kestrel konfiguracji do Kestrelkonfiguracji programu :

      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)
          {
              ...
          }
      }
      
  • Skonfiguruj Kestrel podczas kompilowania hosta:

    W Program.cspliku załaduj sekcję Kestrel konfiguracji do Kestrelkonfiguracji programu :

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

Oba powyższe podejścia współpracują z dowolnym dostawcą konfiguracji.

Limit czasu utrzymania aktywności

KeepAliveTimeout

Pobiera lub ustawia limit czasu utrzymania aktywności. Wartość domyślna to 2 minuty.

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

Maksymalna liczba połączeń klientów

MaxConcurrentConnections MaxConcurrentUpgradedConnections

Maksymalną liczbę współbieżnych otwartych połączeń TCP można ustawić dla całej aplikacji przy użyciu następującego kodu:

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

Istnieje oddzielny limit połączeń, które zostały uaktualnione z protokołu HTTP lub HTTPS do innego protokołu (na przykład w żądaniu protokołu WebSockets). Po uaktualnieniu połączenia nie jest ono liczone względem limitu 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);
})

Maksymalna liczba połączeń jest domyślnie nieograniczona (null).

Maksymalny rozmiar treści żądania

MaxRequestBodySize

Domyślny maksymalny rozmiar treści żądania to 30 000 000 bajtów, czyli około 28,6 MB.

Zalecaną metodą zastąpienia limitu w aplikacji ASP.NET Core MVC jest użycie atrybutu RequestSizeLimitAttribute metody akcji:

[RequestSizeLimit(100000000)]
public IActionResult MyActionMethod()

Oto przykład pokazujący, jak skonfigurować ograniczenie dla aplikacji na każdym żądaniu:

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

Zastąpij ustawienie dla określonego żądania w programie pośredniczącym:

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

Wyjątek jest zgłaszany, jeśli aplikacja konfiguruje limit żądania po rozpoczęciu odczytywania żądania przez aplikację. IsReadOnly Istnieje właściwość wskazująca, czy MaxRequestBodySize właściwość jest w stanie tylko do odczytu, co oznacza, że jest za późno, aby skonfigurować limit.

Gdy aplikacja kończy się procesem za modułem ASP.NET Core, limit rozmiaru treści żądania jest wyłączony, Kestrelponieważ usługi IIS już ustawiają limit.

Minimalna szybkość danych treści żądania

MinRequestBodyDataRate MinResponseDataRate

Kestrel sprawdza co sekundę, jeśli dane docierają do określonej stawki w bajtach/sekundach. Jeśli szybkość spadnie poniżej minimum, przekroczono limit czasu połączenia. Okres prolongaty to czas, który Kestrel daje klientowi zwiększenie szybkości wysyłania do minimum; stawka nie jest sprawdzana w tym czasie. Okres prolongaty pomaga uniknąć porzucania połączeń, które początkowo wysyłają dane w powolnym tempie z powodu powolnego uruchamiania PROTOKOŁU TCP.

Domyślna minimalna stawka to 240 bajtów/sekund z 5-sekundowym okresem prolongaty.

Minimalna stawka dotyczy również odpowiedzi. Kod ustawiania limitu żądań i limit odpowiedzi jest taki sam, z wyjątkiem właściwości RequestBody lub Response nazw interfejsów.

Oto przykład pokazujący sposób konfigurowania minimalnych szybkości danych w programie 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);
})

Zastąpij minimalne limity szybkości na żądanie w programie pośredniczącym:

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

Przywoływany IHttpMinResponseDataRateFeature w poprzednim przykładzie nie jest obecny w HttpContext.Features przypadku żądań HTTP/2, ponieważ modyfikowanie limitów szybkości na żądanie zwykle nie jest obsługiwane dla protokołu HTTP/2 ze względu na obsługę żądania multipleksowania. IHttpMinRequestBodyDataRateFeature Jednak wartość jest nadal obecna HttpContext.Features dla żądań HTTP/2, ponieważ limit szybkości odczytu nadal można całkowicie wyłączyć dla poszczególnych żądań, ustawiając wartość IHttpMinRequestBodyDataRateFeature.MinDataRate nawet null dla żądania HTTP/2. Próba odczytania IHttpMinRequestBodyDataRateFeature.MinDataRate lub próby ustawienia jej na wartość inną niż null spowoduje NotSupportedException zgłoszenie żądania HTTP/2.

Limity szybkości dla całego serwera skonfigurowane za pośrednictwem KestrelServerOptions.Limits nadal mają zastosowanie zarówno do połączeń HTTP/1.x, jak i HTTP/2.

Limit czasu nagłówków żądań

RequestHeadersTimeout

Pobiera lub ustawia maksymalny czas poświęcany przez serwer na odbieranie nagłówków żądań. Wartość domyślna to 30 sekund.

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

Maksymalna liczba strumieni na połączenie

Http2.MaxStreamsPerConnection ogranicza liczbę współbieżnych strumieni żądań na połączenie HTTP/2. Nadmiar strumieni jest odrzucany.

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

Wartość domyślna to 100.

Rozmiar tabeli nagłówka

Dekoder HPACK dekompresuje nagłówki HTTP dla połączeń HTTP/2. Http2.HeaderTableSize ogranicza rozmiar tabeli kompresji nagłówka używanej przez dekoder HPACK. Wartość jest podana w oktetach i musi być większa niż zero (0).

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

Wartość domyślna to 4096.

Maksymalny rozmiar ramki

Http2.MaxFrameSize wskazuje maksymalny dozwolony rozmiar ładunku ramki połączenia HTTP/2 odebranego lub wysłanego przez serwer. Wartość jest podana w oktetach i musi zawierać się między 2^14 (16 384) i 2^24-1 (16 777 215).

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

Wartość domyślna to 2^14 (16 384).

Maksymalny rozmiar nagłówka żądania

Http2.MaxRequestHeaderFieldSize wskazuje maksymalny dozwolony rozmiar w oktetach wartości nagłówka żądania. Ten limit dotyczy zarówno nazwy, jak i wartości w skompresowanych i nieskompresowanych reprezentacjach. Wartość musi być większa niż zero (0).

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

Wartość domyślna to 8192.

Początkowy rozmiar okna połączenia

Http2.InitialConnectionWindowSize wskazuje maksymalne dane treści żądania w bajtach buforów serwera jednocześnie zagregowane we wszystkich żądaniach (strumieniach) na połączenie. Żądania są również ograniczone przez usługę Http2.InitialStreamWindowSize. Wartość musi być większa lub równa 65 535 i mniejsza niż 2^31 (2 147 483 648).

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

Wartość domyślna to 128 KB (131 072).

Rozmiar okna początkowego strumienia

Http2.InitialStreamWindowSize wskazuje maksymalne dane treści żądania w bajtach buforów serwera jednocześnie na żądanie (strumień). Żądania są również ograniczone przez usługę Http2.InitialConnectionWindowSize. Wartość musi być większa lub równa 65 535 i mniejsza niż 2^31 (2 147 483 648).

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

Wartość domyślna to 96 KB (98 304).

Przyczepy

Przyczepy HTTP są podobne do nagłówków HTTP, z wyjątkiem wysyłanych po wysłaniu treści odpowiedzi. W przypadku usług IIS i HTTP.sys obsługiwane są tylko przyczepy odpowiedzi HTTP/2.

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

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

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

W poprzednim przykładowym kodzie:

  • SupportsTrailers zapewnia, że przyczepy są obsługiwane w odpowiedzi.
  • DeclareTrailer Dodaje daną nazwę przyczepy do nagłówka Trailer odpowiedzi. Deklarowanie zwiastunów odpowiedzi jest opcjonalne, ale zalecane. Jeśli DeclareTrailer jest wywoływana, musi być przed wysłaniem nagłówków odpowiedzi.
  • AppendTrailer dołącza przyczepę.

Reset

Resetowanie umożliwia serwerowi zresetowanie żądania HTTP/2 z określonym kodem błędu. Żądanie resetowania jest uznawane za przerwane.

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

Reset w poprzednim przykładzie kodu określa kod błędu INTERNAL_ERROR . Aby uzyskać więcej informacji na temat kodów błędów HTTP/2, odwiedź sekcję kod błędu specyfikacji HTTP/2.

Synchroniczne operacje we/wy

AllowSynchronousIO określa, czy synchroniczne operacje we/wy są dozwolone dla żądania i odpowiedzi. Wartość domyślna to false.

Ostrzeżenie

Duża liczba blokowania synchronicznych operacji we/wy może prowadzić do głodu puli wątków, co sprawia, że aplikacja nie odpowiada. Włączaj AllowSynchronousIO tylko w przypadku korzystania z biblioteki, która nie obsługuje asynchronicznych operacji we/wy.

W poniższym przykładzie włączono synchroniczne operacje we/wy:

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

Aby uzyskać informacje o innych Kestrel opcjach i limitach, zobacz:

Konfiguracja punktu końcowego

Domyślnie ASP.NET Core wiąże się z:

  • http://localhost:5000
  • https://localhost:5001 (gdy jest obecny lokalny certyfikat programowania)

Określ adresy URL przy użyciu:

  • ASPNETCORE_URLS zmienna środowiskowa.
  • --urls argument wiersza polecenia.
  • urls klucz konfiguracji hosta.
  • UseUrls metoda rozszerzenia.

Wartość podana przy użyciu tych metod może być co najmniej jednym punktem końcowym HTTP i HTTPS (HTTPS, jeśli jest dostępny domyślny certyfikat). Skonfiguruj wartość jako listę rozdzieloną średnikami (na przykład "Urls": "http://localhost:8000;http://localhost:8001").

Aby uzyskać więcej informacji na temat tych podejść, zobacz Adresy URL serwera i Konfiguracja przesłonięcia.

Zostanie utworzony certyfikat dewelopera:

Niektóre przeglądarki wymagają udzielenia jawnego uprawnienia do zaufania lokalnemu certyfikatowi programistycznemu.

Project szablony konfigurują aplikacje do uruchamiania na protokole HTTPS domyślnie i obejmują obsługę przekierowania HTTPS i hsTS.

Wywołaj metodę Listen lub ListenUnixSocket metod w KestrelServerOptions celu skonfigurowania prefiksów adresów URL i portów dla programu Kestrel.

UseUrls--urls, argument wiersza polecenia, urls klucz konfiguracji hosta i ASPNETCORE_URLS zmienna środowiskowa również działają, ale mają ograniczenia odnotowane w dalszej części tej sekcji (certyfikat domyślny musi być dostępny dla konfiguracji punktu końcowego HTTPS).

KestrelServerOptions Konfiguracji:

ConfigureEndpointDefaults(ActionListenOptions<>)

Określa konfigurację Action do uruchomienia dla każdego określonego punktu końcowego. Wywołanie ConfigureEndpointDefaults wiele razy zastępuje poprzednią Actionwartość z ostatnią Action określoną wartością.

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

Uwaga

Punkty końcowe utworzone przez wywołanie przed wywołaniem ConfigureEndpointDefaultsListen nie będą miały zastosowanych wartości domyślnych.

ConfigureHttpsDefaults(ActionHttpsConnectionAdapterOptions<>)

Określa konfigurację Action do uruchomienia dla każdego punktu końcowego HTTPS. Wywołanie ConfigureHttpsDefaults wiele razy zastępuje poprzednią Actionwartość z ostatnią Action określoną wartością.

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

Uwaga

Punkty końcowe utworzone przez wywołanie przed wywołaniem ConfigureHttpsDefaultsListen nie będą miały zastosowanych wartości domyślnych.

Configure(IConfiguration)

Tworzy moduł ładujący konfiguracji do konfigurowania Kestrel , który przyjmuje wartość IConfiguration jako dane wejściowe. Konfiguracja musi być ograniczona do sekcji konfiguracji dla Kestrelelementu .

ListenOptions.UseHttps

Skonfiguruj Kestrel do korzystania z protokołu HTTPS.

ListenOptions.UseHttps Rozszerzenia:

  • UseHttps: Skonfiguruj Kestrel do używania protokołu HTTPS z certyfikatem domyślnym. Zgłasza wyjątek, jeśli nie skonfigurowano certyfikatu domyślnego.
  • 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 Parametry:

  • filename to ścieżka i nazwa pliku certyfikatu względem katalogu zawierającego pliki zawartości aplikacji.
  • password to hasło wymagane do uzyskania dostępu do danych certyfikatu X.509.
  • configureOptions jest elementem Action do skonfigurowania elementu HttpsConnectionAdapterOptions. Zwraca wartość ListenOptions.
  • storeName to magazyn certyfikatów, z którego ma być ładowany certyfikat.
  • subject jest nazwą podmiotu certyfikatu.
  • allowInvalid wskazuje, czy należy wziąć pod uwagę nieprawidłowe certyfikaty, takie jak certyfikaty z podpisem własnym.
  • location to lokalizacja magazynu do załadowania certyfikatu.
  • serverCertificate jest certyfikatem X.509.

W środowisku produkcyjnym protokół HTTPS musi być jawnie skonfigurowany. Należy podać co najmniej domyślny certyfikat.

Opisane poniżej konfiguracje obsługiwane:

  • Brak konfiguracji
  • Zamień domyślny certyfikat z konfiguracji
  • Zmienianie wartości domyślnych w kodzie

Brak konfiguracji

Kestrel nasłuchuje i http://localhost:5000https://localhost:5001 (jeśli jest dostępny domyślny certyfikat).

Zamień domyślny certyfikat z konfiguracji

CreateDefaultBuilder wywołania Configure(context.Configuration.GetSection("Kestrel")) domyślnie do załadowania Kestrel konfiguracji. Domyślny schemat konfiguracji ustawień aplikacji HTTPS jest dostępny dla Kestrelprogramu . Skonfiguruj wiele punktów końcowych, w tym adresy URL i certyfikaty do użycia, z pliku na dysku lub z magazynu certyfikatów.

W poniższym appsettings.json przykładzie:

  • Ustaw wartość AllowInvalid , aby zezwolić true na używanie nieprawidłowych certyfikatów (na przykład certyfikatów z podpisem własnym).
  • Każdy punkt końcowy HTTPS, który nie określa certyfikatu (HttpsDefaultCert w poniższym przykładzie) powraca do certyfikatu zdefiniowanego w obszarze CertificatesDefault> lub certyfikatu programistycznego.
{
  "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>"
      }
    }
  }
}

Alternatywą dla dowolnego węzła certyfikatu jest użycie ścieżki i hasła do określenia certyfikatu przy użyciu pól magazynu certyfikatów. Na przykład certyfikat CertificatesDefault> można określić jako:

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

Uwagi dotyczące schematu:

  • Nazwy punktów końcowych są bez uwzględniania wielkości liter. Na przykład HTTPS i Https są prawidłowe.
  • Parametr Url jest wymagany dla każdego punktu końcowego. Format tego parametru jest taki sam jak parametr konfiguracji najwyższego poziomu Urls , z wyjątkiem tego, że jest ograniczony do pojedynczej wartości.
  • Te punkty końcowe zastępują te zdefiniowane w konfiguracji najwyższego poziomu Urls zamiast dodawać do nich. Punkty końcowe zdefiniowane w kodzie za pośrednictwem Listen są skumulowane z punktami końcowymi zdefiniowanymi w sekcji konfiguracji.
  • Sekcja jest opcjonalna Certificate . Certificate Jeśli sekcja nie zostanie określona, zostaną użyte wartości domyślne zdefiniowane we wcześniejszych scenariuszach. Jeśli nie są dostępne żadne wartości domyślne, serwer zgłasza wyjątek i nie można uruchomić.
  • Sekcja Certificate obsługuje certyfikaty Path-Password i Subject-Store.
  • W ten sposób można zdefiniować dowolną liczbę punktów końcowych, o ile nie powodują konfliktów portów.
  • options.Configure(context.Configuration.GetSection("{SECTION}"))KestrelConfigurationLoader Metoda zwraca element .Endpoint(string name, listenOptions => { }) z metodą , która może służyć do uzupełniania skonfigurowanych ustawień punktu końcowego:
webBuilder.UseKestrel((context, serverOptions) =>
{
    serverOptions.Configure(context.Configuration.GetSection("Kestrel"))
        .Endpoint("HTTPS", listenOptions =>
        {
            listenOptions.HttpsOptions.SslProtocols = SslProtocols.Tls12;
        });
});

KestrelServerOptions.ConfigurationLoader Można uzyskać bezpośredni dostęp, aby kontynuować iterowanie dla istniejącego modułu ładującego, na przykład podanego przez CreateDefaultBuilderusługę .

  • Sekcja konfiguracji dla każdego punktu końcowego jest dostępna w opcjach w metodzie Endpoint , aby ustawienia niestandardowe mogły być odczytywane.
  • Wiele konfiguracji może zostać załadowanych przez wywołanie options.Configure(context.Configuration.GetSection("{SECTION}")) metody ponownie z inną sekcją. Używana jest tylko ostatnia konfiguracja, chyba że Load jest jawnie wywoływana w poprzednich wystąpieniach. Metapakiet nie wywołuje Load metody , aby można było zastąpić domyślną sekcję konfiguracji.
  • KestrelConfigurationLoader Dubluje rodzinę Listen interfejsów API z KestrelServerOptions jako Endpoint przeciążeń, więc punkty końcowe kodu i konfiguracji mogą być skonfigurowane w tym samym miejscu. Te przeciążenia nie używają nazw i używają tylko ustawień domyślnych z konfiguracji.

Zmienianie wartości domyślnych w kodzie

ConfigureEndpointDefaults Można ich ConfigureHttpsDefaults używać do zmieniania ustawień domyślnych dla ListenOptions elementów i HttpsConnectionAdapterOptions, w tym zastępowania certyfikatu domyślnego określonego w poprzednim scenariuszu. ConfigureEndpointDefaults i ConfigureHttpsDefaults powinny być wywoływane przed skonfigurowaniem jakichkolwiek punktów końcowych.

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

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

Kestrel obsługa interfejsu SNI

Wskazanie nazwy serwera (SNI) może służyć do hostowania wielu domen na tym samym adresie IP i porcie. Aby funkcja SNI działała, klient wysyła nazwę hosta dla bezpiecznej sesji do serwera podczas uzgadniania protokołu TLS, aby serwer mógł dostarczyć prawidłowy certyfikat. Klient używa dostarczonego certyfikatu do zaszyfrowanej komunikacji z serwerem podczas bezpiecznej sesji, która następuje po uzgadnianiu protokołu TLS.

Kestrel obsługuje SNI za pośrednictwem wywołania zwrotnego ServerCertificateSelector . Wywołanie zwrotne jest wywoływane raz na połączenie, aby umożliwić aplikacji sprawdzenie nazwy hosta i wybranie odpowiedniego certyfikatu.

Obsługa SNI wymaga:

  • Uruchamianie na platformie netcoreapp2.1 docelowej lub nowszej. W systemie net461 lub nowszym wywołanie zwrotne jest wywoływane, ale name zawsze nullma wartość . Parametr name jest również null wtedy, gdy klient nie podaje parametru nazwy hosta w uzgadnianiu protokołu TLS.
  • Wszystkie witryny internetowe działają w tym samym Kestrel wystąpieniu. Kestrel Nie obsługuje udostępniania adresu IP i portu w wielu wystąpieniach bez zwrotnego serwera proxy.
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;
            };
        });
    });
});

Rejestrowanie połączeń

Wywołanie UseConnectionLogging w celu emitowania dzienników poziomu debugowania dla komunikacji na poziomie bajtów w połączeniu. Rejestrowanie połączeń jest pomocne w rozwiązywaniu problemów z komunikacją niskiego poziomu, na przykład podczas szyfrowania TLS i za serwerami proxy. Jeśli UseConnectionLogging zostanie umieszczony przed UseHttps, zaszyfrowany ruch jest rejestrowany. Jeśli UseConnectionLogging zostanie umieszczony po UseHttps, odszyfrowany ruch jest rejestrowany.

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

Wiązanie z gniazdem TCP

Metoda Listen wiąże się z gniazdem TCP, a opcja lambda zezwala na konfigurację certyfikatu 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>();
        });

W przykładzie skonfigurowaliśmy protokół HTTPS dla punktu końcowego za pomocą polecenia ListenOptions. Użyj tego samego interfejsu API, aby skonfigurować inne Kestrel ustawienia dla określonych punktów końcowych.

W Windows można utworzyć certyfikaty z podpisem własnym przy użyciu New-SelfSignedCertificate polecenia cmdlet programu PowerShell. W przypadku nieobsługiwanego przykładu zobacz UpdateIISExpressSSLForChrome.ps1.

W systemach macOS, Linux i Windows można tworzyć certyfikaty przy użyciu biblioteki OpenSSL.

Wiązanie z gniazdem systemu Unix

Nasłuchiwanie na gniazdach systemu Unix za pomocą polecenia ListenUnixSocket w celu zwiększenia wydajności za pomocą serwera Nginx, jak pokazano w tym przykładzie:

webBuilder.ConfigureKestrel(serverOptions =>
{
    serverOptions.ListenUnixSocket("/tmp/kestrel-test.sock");
    serverOptions.ListenUnixSocket("/tmp/kestrel-test.sock", 
        listenOptions =>
        {
            listenOptions.UseHttps("testCert.pfx", 
                "testpassword");
        });
})
  • W pliku konfiguracji Nginx ustaw server>proxy_pass>locationwpis na .http://unix:/tmp/{KESTREL SOCKET}:/; {KESTREL SOCKET} to nazwa gniazda udostępnionego ListenUnixSocket (na przykład kestrel-test.sock w poprzednim przykładzie).
  • Upewnij się, że gniazdo jest zapisywalne przez serwer Nginx (na przykład chmod go+w /tmp/kestrel-test.sock).

Port 0

Po określeniu Kestrel numeru 0 portu dynamicznie wiąże się z dostępnym portem. W poniższym przykładzie pokazano, jak określić, który port Kestrel faktycznie jest powiązany ze środowiskiem uruchomieniowym:

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

Po uruchomieniu aplikacji dane wyjściowe okna konsoli wskazują port dynamiczny, do którego można uzyskać dostęp do aplikacji:

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

Ograniczenia

Skonfiguruj punkty końcowe przy użyciu następujących metod:

  • UseUrls
  • --urls argument wiersza polecenia
  • urls klucz konfiguracji hosta
  • ASPNETCORE_URLS zmienna środowiskowa

Te metody są przydatne do pracy kodu z serwerami innymi niż Kestrel. Należy jednak pamiętać o następujących ograniczeniach:

  • Nie można używać protokołu HTTPS z tymi metodami, chyba że w konfiguracji punktu końcowego HTTPS zostanie podany domyślny certyfikat (na przykład przy użyciu KestrelServerOptions konfiguracji lub pliku konfiguracji, jak pokazano wcześniej w tym temacie).
  • Gdy oba Listen metody i UseUrls są używane jednocześnie, Listen punkty końcowe zastępują UseUrls punkty końcowe.

Konfiguracja punktu końcowego usług IIS

W przypadku korzystania z usług IIS powiązania adresów URL dla powiązań zastępowania usług IIS są ustawiane przez elementy Listen lub UseUrls. Aby uzyskać więcej informacji, zobacz temat modułu ASP.NET Core.

ListenOptions.Protocols

Właściwość Protocols ustanawia protokoły HTTP (HttpProtocols) włączone w punkcie końcowym połączenia lub dla serwera. Przypisz wartość do Protocols właściwości z wyliczenia HttpProtocols .

HttpProtocols wartość wyliczenia Dozwolony protokół połączenia
Http1 Tylko HTTP/1.1. Może być używany z protokołem TLS lub bez tego protokołu.
Http2 Tylko HTTP/2. Może być używany bez protokołu TLS tylko wtedy, gdy klient obsługuje tryb wcześniejszej wiedzy.
Http1AndHttp2 HTTP/1.1 i HTTP/2. Protokół HTTP/2 wymaga od klienta wybrania protokołu HTTP/2 w uzgadnianiu protokołu SSL Application-Layer Protocol (ALPN ); w przeciwnym razie połączenie jest domyślnie ustawione na HTTP/1.1.

Wartość domyślna ListenOptions.Protocols dla dowolnego punktu końcowego to HttpProtocols.Http1AndHttp2.

Ograniczenia protokołu TLS dla protokołu HTTP/2:

  • Protokół TLS w wersji 1.2 lub nowszej
  • Ponowne negocjowanie wyłączone
  • Kompresja wyłączona
  • Minimalne rozmiary wymiany kluczy efemerycznych:
    • Krzywa eliptyczna Diffie-Hellman (ECDHE) [RFC4492]: minimum 224 bitów
    • Pole skończone Diffie-Hellman (DHE) [TLS12]: minimum 2048 bitów
  • Zestaw szyfrowania nie jest zabroniony.

TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 [TLS-ECDHE] z krzywą eliptyczną P-256 [FIPS186] jest domyślnie obsługiwana.

Poniższy przykład zezwala na połączenia HTTP/1.1 i HTTP/2 na porcie 8000. Połączenia są zabezpieczone przez protokół TLS przy użyciu dostarczonego certyfikatu:

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

Użyj oprogramowania pośredniczącego połączenia, aby filtrować uzgadnianie protokołu TLS na podstawie poszczególnych połączeń pod kątem określonych szyfrów, jeśli jest to wymagane.

W poniższym przykładzie jest zgłaszany NotSupportedException żaden algorytm szyfrowania, którego aplikacja nie obsługuje. Alternatywnie zdefiniuj i porównaj ITlsHandshakeFeature.CipherAlgorithm z listą dopuszczalnych zestawów szyfrowania.

Żadne szyfrowanie nie jest używane z algorytmem szyfrowania 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();
            });
        }
    }
}

Filtrowanie połączeń można również skonfigurować za pomocą IConnectionBuilder wyrażenia lambda:

// using System;
// using System.Net;
// using System.Security.Authentication;
// using Microsoft.AspNetCore.Connections;
// using Microsoft.AspNetCore.Connections.Features;

webBuilder.ConfigureKestrel(serverOptions =>
{
    serverOptions.Listen(IPAddress.Any, 8000, listenOptions =>
    {
        listenOptions.UseHttps("testCert.pfx", "testPassword");
        listenOptions.Use((context, next) =>
        {
            var tlsFeature = context.Features.Get<ITlsHandshakeFeature>();

            if (tlsFeature.CipherAlgorithm == CipherAlgorithmType.Null)
            {
                throw new NotSupportedException(
                    $"Prohibited cipher: {tlsFeature.CipherAlgorithm}");
            }

            return next();
        });
    });
});

W systemie Linux CipherSuitesPolicy można używać do filtrowania uzgadniania protokołu TLS na podstawie poszczególnych połączeń:

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

Ustawianie protokołu z konfiguracji

CreateDefaultBuilder domyślnie wywołuje serverOptions.Configure(context.Configuration.GetSection("Kestrel")) funkcję ładowania Kestrel konfiguracji.

appsettings.json Poniższy przykład ustanawia protokół HTTP/1.1 jako domyślny protokół połączenia dla wszystkich punktów końcowych:

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

appsettings.json Poniższy przykład ustanawia protokół połączenia HTTP/1.1 dla określonego punktu końcowego:

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

Protokoły określone w kodzie zastępują wartości ustawione przez konfigurację.

Prefiksy adresów URL

W przypadku używania UseUrls--urls argumentu wiersza polecenia, urls klucza konfiguracji hosta lub ASPNETCORE_URLS zmiennej środowiskowej prefiksy adresów URL mogą mieć dowolny z następujących formatów.

Tylko prefiksy adresów URL HTTP są prawidłowe. Kestrel Nie obsługuje protokołu HTTPS podczas konfigurowania powiązań adresów URL przy użyciu polecenia UseUrls.

  • Adres IPv4 z numerem portu

    http://65.55.39.10:80/
    

    0.0.0.0 to specjalny przypadek, który wiąże się ze wszystkimi adresami IPv4.

  • Adres IPv6 z numerem portu

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

    [::] to odpowiednik protokołu IPv6 protokołu IPv4 0.0.0.0.

  • Nazwa hosta z numerem portu

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

    Nazwy hostów , *i +nie są specjalne. Wszystkie nie rozpoznane jako prawidłowy adres IP lub localhost powiązane ze wszystkimi adresami IP IPv4 i IPv6. Aby powiązać różne nazwy hostów z różnymi aplikacjami ASP.NET Core na tym samym porcie, użyj HTTP.sys lub zwrotnego serwera proxy, takiego jak IIS, Nginx lub Apache.

    Ostrzeżenie

    Hosting w konfiguracji zwrotnego serwera proxy wymaga konfiguracji oprogramowania pośredniczącego nagłówków przekazywanych.

  • Nazwa hosta localhost z numerem portu lub adresem IP sprzężenia zwrotnego z numerem portu

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

    Po localhost określeniu Kestrel parametru program próbuje powiązać zarówno interfejsy Sprzężenia zwrotnego IPv4, jak i IPv6. Jeśli żądany port jest używany przez inną usługę w interfejsie sprzężenia zwrotnego, Kestrel nie można uruchomić. Jeśli którykolwiek z interfejsów sprzężenia zwrotnego jest niedostępny z jakiegokolwiek innego powodu (najczęściej dlatego, że protokół IPv6 nie jest obsługiwany), Kestrel rejestruje ostrzeżenie.

Filtrowanie hostów

Chociaż Kestrel obsługuje konfigurację na podstawie prefiksów, takich jak http://example.com:5000, Kestrel w dużej mierze ignoruje nazwę hosta. Host localhost to specjalny przypadek używany do tworzenia powiązań z adresami sprzężenia zwrotnego. Każdy host inny niż jawny adres IP wiąże się ze wszystkimi publicznymi adresami IP. Host nagłówki nie są weryfikowane.

Aby obejść ten problem, użyj oprogramowania pośredniczącego filtrowania hostów. Oprogramowanie pośredniczące filtrowania hostów jest dostarczane przez pakiet Microsoft.AspNetCore.HostFiltering, który jest niejawnie udostępniany dla aplikacji ASP.NET Core. Oprogramowanie pośredniczące jest dodawane przez CreateDefaultBuilderelement , który wywołuje metodę 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>();
}

Oprogramowanie pośredniczące filtrowania hostów jest domyślnie wyłączone. Aby włączyć oprogramowanie pośredniczące, zdefiniuj AllowedHosts klucz w pliku/appsettings.jsonappsettings.{Environment}.json . Wartość jest rozdzieloną średnikami listą nazw hostów bez numerów portów:

appsettings.json:

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

Uwaga

Oprogramowanie pośredniczące nagłówków przekazywanych również ma AllowedHosts opcję. Oprogramowanie pośredniczące nagłówków przekazywanych i oprogramowanie pośredniczące filtrowania hostów mają podobne funkcje w różnych scenariuszach. Ustawienie AllowedHosts z oprogramowaniem pośredniczącym nagłówków przekazywanych jest odpowiednie, gdy Host nagłówek nie jest zachowywany podczas przekazywania żądań za pomocą zwrotnego serwera proxy lub modułu równoważenia obciążenia. Ustawienie AllowedHosts z oprogramowaniem pośredniczącym filtrowania hostów jest odpowiednie, gdy Kestrel jest używane jako publiczny serwer brzegowy lub gdy Host nagłówek jest bezpośrednio przekazywany.

Aby uzyskać więcej informacji na temat oprogramowania pośredniczącego nagłówków przekazywanych, zobacz Konfigurowanie ASP.NET Core do pracy z serwerami proxy i modułami równoważenia obciążenia.

Konfiguracja transportu Libuv

W przypadku projektów, które wymagają użycia biblioteki Libuv (UseLibuv):

  • Dodaj zależność pakietu Microsoft.AspNetCore.Server.Kestrel.Transport.Libuv do pliku projektu aplikacji:

    <PackageReference Include="Microsoft.AspNetCore.Server.Kestrel.Transport.Libuv"
                      Version="{VERSION}" />
    
  • Wywołaj metodę UseLibuv na stronie IWebHostBuilder:

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

Opróżnianie żądań HTTP/1.1

Otwieranie połączeń HTTP jest czasochłonne. W przypadku protokołu HTTPS jest on również intensywnie obciążany zasobami. Kestrel W związku z tym próbuje ponownie użyć połączeń na protokół HTTP/1.1. Treść żądania musi być w pełni wykorzystana, aby umożliwić ponowne użycie połączenia. Aplikacja nie zawsze używa treści żądania, na POST przykład żądań, w których serwer zwraca odpowiedź przekierowania lub 404. W przypadku POST-redirect:

  • Klient mógł już wysłać część POST danych.
  • Serwer zapisuje odpowiedź 301.
  • Nie można użyć połączenia dla nowego żądania, dopóki POST dane z poprzedniej treści żądania nie zostaną w pełni odczytane.
  • Kestrel próbuje opróżnić treść żądania. Opróżnianie treści żądania oznacza odczytywanie i odrzucanie danych bez ich przetwarzania.

Proces opróżniania sprawia, że kompromis między zezwoleniem na ponowne użycie połączenia a czasem potrzebnym na opróżnienie pozostałych danych:

  • Opróżnianie ma limit czasu 5 sekund, co nie jest konfigurowalne.
  • Jeśli wszystkie dane określone przez Content-Length nagłówek lub Transfer-Encoding nie zostały odczytane przed upływem limitu czasu, połączenie zostanie zamknięte.

Czasami możesz chcieć przerwać żądanie natychmiast, przed lub po zapisaniu odpowiedzi. Na przykład klienci mogą mieć restrykcyjne limity danych, dlatego ograniczenie przekazanych danych może być priorytetem. W takich przypadkach, aby zakończyć żądanie, wywołaj metodę HttpContext.Abort z kontrolera, Razor strony lub oprogramowania pośredniczącego.

Istnieją zastrzeżenia dotyczące wywoływania elementu Abort:

  • Tworzenie nowych połączeń może być powolne i kosztowne.
  • Nie ma gwarancji, że klient odczytał odpowiedź przed zamknięciem połączenia.
  • Wywołanie Abort powinno być rzadkie i zarezerwowane w przypadku poważnych przypadków błędów, a nie typowych błędów.
    • Wywołaj polecenie Abort tylko wtedy, gdy należy rozwiązać konkretny problem. Na przykład wywołaj metodę Abort , jeśli złośliwi klienci próbują wykonać POST dane lub gdy kod klienta zawiera usterkę, która powoduje duże lub liczne żądania.
    • Nie należy wywoływać Abort typowych sytuacji błędów, takich jak HTTP 404 (nie znaleziono).

Wywołanie metody HttpResponse.CompleteAsync przed wywołaniem Abort gwarantuje, że serwer zakończył pisanie odpowiedzi. Jednak zachowanie klienta nie jest przewidywalne i może nie odczytać odpowiedzi przed przerwaniem połączenia.

Ten proces jest inny w przypadku protokołu HTTP/2, ponieważ protokół obsługuje przerywanie poszczególnych strumieni żądań bez zamykania połączenia. Pięciosekundowy limit czasu opróżniania nie ma zastosowania. Jeśli po zakończeniu odpowiedzi znajdują się jakiekolwiek nieprzeczytane dane treści żądania, serwer wysyła ramkę HTTP/2 RST. Dodatkowe ramki danych treści żądania są ignorowane.

Jeśli to możliwe, lepiej jest, aby klienci korzystali z nagłówka Oczekiwano: 100-kontynuuj żądania i poczekaj, aż serwer odpowie przed rozpoczęciem wysyłania treści żądania. Daje to klientowi możliwość zbadania odpowiedzi i przerwania przed wysłaniem niepotrzebnych danych.

Dodatkowe zasoby