Kestrel-Webserver in ASP.NET Core

Von Tom Dykstra, Chris Ross und Stephen Halter

Kestrel ist ein plattformübergreifender Kestrel. Kestrel ist der empfohlene Server für ASP.NET Core und ist standardmäßig in ASP.NET Core-Projektvorlagen konfiguriert.

Kestrel bietet folgende Features:

  • Plattformübergreifend:Kestrel ist ein plattformübergreifender Webserver, der unter Windows, Linux und macOS ausgeführt wird.
  • Hohe Leistung:Kestrel ist für die effiziente Verarbeitung einer großen Anzahl gleichzeitiger Verbindungen optimiert.
  • Einfach: Der Server ist für die Ausführung in ressourcenbeschränkten Umgebungen wie Containern und Edgegeräten optimiert.
  • Verstärkte Sicherheit:Kestrel unterstützt HTTPS und ist gegen Webserver-Sicherheitsrisiken gehärtet.
  • Umfassende Protokollunterstützung:Kestrel unterstützt gängige Webprotokolle, einschließlich:
  • Integration mit ASP.NET Core: Nahtlose Integration in andere ASP.NET Core-Komponenten, z. B. Middlewarepipeline, Dependency Injection und Konfigurationssystem.
  • Flexible Workloads: Kestrel unterstützt viele Workloads:
    • ASP.NET-App-Frameworks wie Minimal-APIs, MVC, Razor Pages, SignalR, Blazor und gRPC
    • Erstellen eines Reverseproxys mit YARP
  • Erweiterbarkeit: Passen Sie Kestrel durch Konfiguration, Middleware und benutzerdefinierte Transporte an.
  • Leistungsdiagnose:Kestrel bietet integrierte Leistungsdiagnosefeatures, z. B. Protokollierung und Metriken.

Erste Schritte

ASP.NET Core-Projektvorlagen verwenden standardmäßig Kestrel, wenn sie nicht mit IIS gehostet werden. In der folgenden vorlagengenerierten Datei Program.csruft die WebApplication.CreateBuilder-Methode UseKestrel intern auf:

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

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

app.Run();

Weitere Informationen zum Konfigurieren von WebApplication und WebApplicationBuilder finden Sie unter Minimal-APIs – Kurzreferenz.

Optionale Clientzertifikate

Informationen zu Apps, die eine Teilmenge der App mit einem Zertifikat schützen müssen, finden Sie unter Optionale Clientzertifikate.

Verhalten mit angefügtem Debugger

Die folgenden Timeouts und Ratenbegrenzungen werden nicht erzwungen, wenn ein Debugger an einen Kestrel-Prozess angefügt ist.

Zusätzliche Ressourcen

Hinweis

Ab ASP.NET Core 5.0 ist der Libuv-Transport von Kestrel veraltet. Der Libuv-Transport empfängt keine Updates zur Unterstützung neuer Betriebssystemplattformen wie Windows ARM64 und wird in einem zukünftigen Release entfernt. Entfernen Sie alle Aufrufe der veralteten UseLibuv-Methode, und verwenden Sie stattdessen den standardmäßigen Sockettransport von Kestrel.

Kestrel ist ein plattformübergreifender Kestrel. Kestrel ist der Webserver, der standardmäßig in ASP.NET Core-Projektvorlagen enthalten und aktiviert ist.

Kestrel unterstützt die folgenden Szenarios:

  • HTTPS
  • HTTP/2 (außer unter macOS†)
  • Nicht transparente Upgrades, die zum Aktivieren von WebSockets verwendet werden
  • Unix-Sockets für eine hohe Leistung im Hintergrund von Nginx

†HTTP/2 wird in einem zukünftigen Release unter macOS unterstützt.

Kestrel wird auf allen Plattformen und für alle Versionen unterstützt, die .NET Core unterstützt.

Erste Schritte

ASP.NET Core-Projektvorlagen verwenden standardmäßig Kestrel, wenn sie nicht mit IIS gehostet werden. In der folgenden vorlagengenerierten Datei Program.csruft die WebApplication.CreateBuilder-Methode UseKestrel intern auf:

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

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

app.Run();

Weitere Informationen zum Konfigurieren von WebApplication und WebApplicationBuilder finden Sie unter Minimal-APIs – Kurzreferenz.

Optionale Clientzertifikate

Informationen zu Apps, die eine Teilmenge der App mit einem Zertifikat schützen müssen, finden Sie unter Optionale Clientzertifikate.

Verhalten mit angefügtem Debugger

Die folgenden Timeouts und Ratenbegrenzungen werden nicht erzwungen, wenn ein Debugger an einen Kestrel-Prozess angefügt ist.

Zusätzliche Ressourcen

Hinweis

Ab ASP.NET Core 5.0 ist der Libuv-Transport von Kestrel veraltet. Der Libuv-Transport empfängt keine Updates zur Unterstützung neuer Betriebssystemplattformen wie Windows ARM64 und wird in einem zukünftigen Release entfernt. Entfernen Sie alle Aufrufe der veralteten UseLibuv-Methode, und verwenden Sie stattdessen den standardmäßigen Sockettransport von Kestrel.

Kestrel ist ein plattformübergreifender Kestrel. Kestrel ist der Webserver, der standardmäßig in ASP.NET Core-Projektvorlagen enthalten und aktiviert ist.

Kestrel unterstützt die folgenden Szenarios:

  • HTTPS
  • HTTP/2 (außer unter macOS†)
  • Nicht transparente Upgrades, die zum Aktivieren von WebSockets verwendet werden
  • Unix-Sockets für eine hohe Leistung im Hintergrund von Nginx

†HTTP/2 wird in einem zukünftigen Release unter macOS unterstützt.

Kestrel wird auf allen Plattformen und für alle Versionen unterstützt, die .NET Core unterstützt.

Anzeigen oder Herunterladen von Beispielcode (Vorgehensweise zum Herunterladen)

Erste Schritte

ASP.NET Core-Projektvorlagen verwenden standardmäßig Kestrel, wenn sie nicht mit IIS gehostet werden. In Program.cs ruft die ConfigureWebHostDefaults-Methode UseKestrel auf:

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

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

Weitere Informationen zum Erstellen des Hosts finden Sie im Artikel Generischer .NET-Host in ASP.NET Core in den Abschnitten Einrichten eines Hosts und Standardeinstellungen für den Generator.

Optionale Clientzertifikate

Informationen zu Apps, die eine Teilmenge der App mit einem Zertifikat schützen müssen, finden Sie unter Optionale Clientzertifikate.

Zusätzliche Ressourcen

Hinweis

Ab ASP.NET Core 5.0 ist der Libuv-Transport von Kestrel veraltet. Der Libuv-Transport empfängt keine Updates zur Unterstützung neuer Betriebssystemplattformen wie Windows ARM64 und wird in einem zukünftigen Release entfernt. Entfernen Sie alle Aufrufe der veralteten UseLibuv-Methode, und verwenden Sie stattdessen den standardmäßigen Sockettransport von Kestrel.

Kestrel ist ein plattformübergreifender Kestrel. Kestrel ist der Webserver, der standardmäßig in ASP.NET Core-Projektvorlagen enthalten ist.

Kestrel unterstützt die folgenden Szenarios:

  • HTTPS
  • Nicht transparente Upgrades, die zum Aktivieren von WebSockets verwendet werden
  • Unix-Sockets für eine hohe Leistung im Hintergrund von Nginx
  • HTTP/2 (außer unter macOS†)

†HTTP/2 wird in einem zukünftigen Release unter macOS unterstützt.

Kestrel wird auf allen Plattformen und für alle Versionen unterstützt, die .NET Core unterstützt.

Anzeigen oder Herunterladen von Beispielcode (Vorgehensweise zum Herunterladen)

HTTP/2-Unterstützung

HTTP/2 ist für ASP.NET Core-Apps verfügbar, wenn die folgenden Basisanforderungen erfüllt sind:

  • Betriebssystem†
    • Windows Server 2016/Windows 10 oder höher‡
    • Linux mit OpenSSL 1.0.2 oder höher (z.B. Ubuntu 16.04 oder höher)
  • Zielframework: .NET Core 2.2 oder höher
  • ALPN-Verbindung (Application-Layer Protocol Negotiation)
  • TLS 1.2-Verbindung oder höher

†HTTP/2 wird in einem zukünftigen Release unter macOS unterstützt. ‡Kestrel bietet eingeschränkte Unterstützung für HTTP/2 unter Windows Server 2012 R2 und Windows 8.1. Die Unterstützung ist eingeschränkt, weil die Liste der unterstützten TLS-Verschlüsselungssammlungen unter diesen Betriebssystemen begrenzt ist. Zum Sichern von TLS-Verbindungen ist möglicherweise ein durch einen Elliptic Curve Digital Signature Algorithm (ECDSA) generiertes Zertifikat erforderlich.

Wenn eine HTTP/2-Verbindung hergestellt wurde, meldet HttpRequest.ProtocolHTTP/2.

Ab .NET Core 3.0 ist HTTP/2 standardmäßig aktiviert. Weitere Informationen zur Konfiguration finden Sie in den Abschnitten Kestrel-Optionen und ListenOptions.Protocols.

Verwenden von Kestrel mit einem Reverseproxy

Kestrel kann eigenständig oder mit einem Reverseproxyserver verwendet werden. Ein Reverseproxyserver empfängt HTTP-Anforderungen aus dem Netzwerk und leitet diese an Kestrel weiter. Beispiele für einen Reverseproxyserver:

Kestrel bei Verwendung als Webserver mit direkter Internetverbindung:

Kestrel communicates directly with the Internet without a reverse proxy server

Kestrel bei Verwendung in einer Reverseproxykonfiguration:

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

Jede der beiden Konfigurationen – mit oder ohne einen Reverseproxyserver – stellt eine unterstützte Hostingkonfiguration dar.

Bei Verwendung als Edgeserver ohne Reverseproxyserver unterstützt Kestrel die gemeinsame Nutzung der gleichen IP-Adresse und des gleichen Ports durch mehrere Prozesse nicht. Wenn Kestrel für das Lauschen an einem Port konfiguriert ist, verarbeitet Kestrel den gesamten Datenverkehr für diesen Port unabhängig von den Host-Headern der Anforderungen. Ein Reverseproxy, der Ports freigeben kann, kann Anforderungen an Kestrel über eine eindeutige IP und einen eindeutigen Port weiterleiten.

Auch wenn kein Reverseproxyserver erforderlich ist, kann die Verwendung eines solchen empfehlenswert sein.

Für einen Reverseproxy gilt Folgendes:

  • Er kann die verfügbar gemachten öffentlichen Oberflächen der von ihm gehosteten Apps einschränken.
  • Er stellt eine zusätzliche Ebene für Konfiguration und Schutz bereit.
  • Er lässt sich besser in die vorhandene Infrastruktur integrieren.
  • Er vereinfacht die Konfiguration von Lastenausgleich und sicherer Kommunikation (HTTPS). Nur der Reverseproxyserver erfordert ein X.509-Zertifikat, und dieser Server kann mit den Servern der App im internen Netzwerk über einfaches HTTP kommunizieren.

Warnung

Für das Hosten in einer Reverseproxykonfiguration ist eine Middlewarekonfiguration für weitergeleitete Header erforderlich.

Kestrel in ASP.NET Core-Apps

ASP.NET Core-Projektvorlagen verwenden Kestrel standardmäßig. In Program.cs ruft die ConfigureWebHostDefaults-Methode UseKestrel auf:

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

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

Weitere Informationen zum Erstellen des Hosts finden Sie im Artikel Generischer .NET-Host in ASP.NET Core in den Abschnitten Einrichten eines Hosts und Standardeinstellungen für den Generator.

Um zusätzliche Konfiguration nach dem Aufruf von ConfigureWebHostDefaults bereitzustellen, verwenden Sie 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-Optionen

Der Kestrel-Webserver verfügt über einschränkende Konfigurationsoptionen, die besonders nützlich bei Bereitstellungen mit Internetzugriff sind.

Legen Sie Einschränkungen für die Limits-Eigenschaft der KestrelServerOptions-Klasse fest. Die Limits-Eigenschaft enthält eine Instanz der KestrelServerLimits-Klasse.

In den folgenden Beispielen wird der Microsoft.AspNetCore.Server.Kestrel.Core-Namespace verwendet:

using Microsoft.AspNetCore.Server.Kestrel.Core;

In den Beispielen, die weiter unten in diesem Artikel aufgeführt sind, werden Kestrel-Optionen in C#-Code konfiguriert. Kestrel-Optionen können ebenso mithilfe eines Kestrel festgelegt werden. Beispielsweise kann der Dateikonfigurationsanbieter die Kestrel-Konfiguration aus einer appsettings.json- oder appsettings.{Environment}.json-Datei laden:

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

Hinweis

KestrelServerOptions und die KestrelServerOptions können über Konfigurationsanbieter konfiguriert werden. Die verbleibende Kestrel-Konfiguration muss in C#-Code konfiguriert werden.

Verwenden Sie einen der folgenden Ansätze:

  • Konfigurieren Sie Kestrel in Startup.ConfigureServices:

    1. Fügen Sie eine Instanz von IConfiguration in die Startup-Klasse ein. Im folgenden Beispiel wird davon ausgegangen, dass die eingefügte Konfiguration der Configuration-Eigenschaft zugewiesen wird.

    2. Laden Sie in Startup.ConfigureServices den Abschnitt Kestrel der Konfiguration in die Konfiguration von Kestrel:

      using Microsoft.Extensions.Configuration
      
      public class Startup
      {
          public Startup(IConfiguration configuration)
          {
              Configuration = configuration;
          }
      
          public IConfiguration Configuration { get; }
      
          public void ConfigureServices(IServiceCollection services)
          {
              services.Configure<KestrelServerOptions>(
                  Configuration.GetSection("Kestrel"));
          }
      
          public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
          {
              ...
          }
      }
      
  • Konfigurieren Sie Kestrel beim Erstellen des Hosts:

    Laden Sie in Program.cs den Abschnitt Kestrel der Konfiguration in die Konfiguration von Kestrel:

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

Beide vorangehenden Ansätze funktionieren mit jedem Konfigurationsanbieter.

Keep-Alive-Timeout

KeepAliveTimeout

Ruft das Keep-Alive-Timeout ab oder legt es fest. Standardwert: 2 Minuten.

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

Maximale Anzahl der Clientverbindungen

MaxConcurrentConnections MaxConcurrentUpgradedConnections

Die maximale Anzahl von gleichzeitig geöffneten TCP-Verbindungen kann mithilfe von folgendem Code für die gesamte App festgelegt werden:

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

Es gibt einen separaten Grenzwert für Verbindungen, die von HTTP oder HTTPS auf ein anderes Protokoll aktualisiert wurden (z.B. auf eine WebSockets-Anforderung). Nachdem eine Verbindung aktualisiert wurde, zählt diese nicht mehr für den MaxConcurrentConnections-Grenzwert.

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

Die maximale Anzahl von Verbindungen ist standardmäßig nicht begrenzt (NULL).

Maximale Größe des Anforderungstexts

MaxRequestBodySize

Die maximale Größe des Anforderungstexts beträgt standardmäßig 30.000.000 Byte, also ungefähr 28,6 MB.

Die empfohlene Methode zur Außerkraftsetzung des Grenzwerts in einer ASP.NET Core-MVC-App besteht im Verwenden des RequestSizeLimitAttribute-Attributs in einer Aktionsmethode:

[RequestSizeLimit(100000000)]
public IActionResult MyActionMethod()

Im folgenden Beispiel wird veranschaulicht, wie die Einschränkungen auf jeder Anforderung für die App konfiguriert werden:

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

Außer Kraft setzen der Einstellung für eine bestimmte Anforderung in Middleware:

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

Eine Ausnahme wird ausgelöst, wenn die App den Grenzwert einer Anforderung konfiguriert, nachdem die App bereits mit dem Lesen der Anforderung begonnen hat. Es gibt eine IsReadOnly-Eigenschaft, die angibt, wenn sich die MaxRequestBodySize-Eigenschaft im schreibgeschützten Zustand befindet, also wenn der Grenzwert nicht mehr konfiguriert werden kann.

Wenn eine App prozessextern hinter dem ASP.NET Core-Modul ausgeführt wird, ist das Größenlimit von Kestrel für Anforderungstext deaktiviert, weil IIS dieses Limit bereits festlegt.

Minimale Datenrate des Anforderungstexts

MinRequestBodyDataRate MinResponseDataRate

Kestrel überprüft sekündlich, ob Daten mit der angegebenen Rate in Bytes/Sekunde eingehen. Wenn die Rate den mindestens erforderlichen Wert unterschreitet, wird für die Verbindung wegen Timeout getrennt. Bei der Toleranzperiode handelt es sich um die Zeitspanne, die Kestrel dem Client gewährt, um die Senderate auf den mindestens erforderlichen Wert zu erhöhen. Die Rate wird währenddessen nicht überprüft. Diese Toleranzperiode beugt dem Trennen von Verbindungen vor, die Daten aufgrund eines langsamen TCP-Starts anfänglich mit einer niedrigen Rate senden.

Die mindestens erforderliche Rate beträgt standardmäßig 240 Bytes/Sekunde mit einer Toleranzperiode von 5 Sekunden.

Für die Antwort gilt ebenfalls eine mindestens erforderliche Rate. Der Code zum Festlegen des Grenzwerts für Anforderung und Antwort ist abgesehen von RequestBody oder Response in den Namen von Eigenschaften und Schnittstelle identisch.

In diesem Beispiel wird veranschaulicht, wie Sie die mindestens erforderlichen Datenraten in Program.cs konfigurieren:

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

Außer Kraft setzen des minimalen Ratenlimits pro Anforderung in Middleware:

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

Das IHttpMinResponseDataRateFeature aus dem vorherigen Beispiel ist in HttpContext.Features für HTTP/2-Anforderungen nicht vorhanden, weil die Änderung von Ratenlimits für jede Anforderung aufgrund der Unterstützung für Anforderungsmultiplexing von HTTP/2 von diesem Protokoll unterstützt wird. IHttpMinRequestBodyDataRateFeature ist jedoch in HttpContext.Features für HTTP/2-Anforderungen noch vorhanden, weil das Leseratenlimit weiterhin für jede Anforderung IHttpMinRequestBodyDataRateFeature werden kann, indem IHttpMinRequestBodyDataRateFeature.MinDataRate auch für eine HTTP/2-Anforderung auf null festgelegt wird. Der Versuch, IHttpMinRequestBodyDataRateFeature.MinDataRate zu lesen oder auf einen anderen Wert als null festzulegen, führt dazu, dass bei einer HTTP/2-Anforderung eine NotSupportedException ausgelöst wird.

Serverweite Ratenlimits, die über KestrelServerOptions.Limits konfiguriert sind, gelten auch für HTTP/1.x- und HTTP/2-Verbindungen.

Timeout für Anforderungsheader

RequestHeadersTimeout

Ruft die maximale Zeitspanne ab, während der der Server Anforderungsheader empfängt, oder legt diese fest. Der Standardwert beträgt 30 Sekunden.

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

Maximale Datenströme pro Verbindung

Http2.MaxStreamsPerConnection schränkt die Anzahl gleichzeitiger Anforderungsdatenströme pro HTTP/2-Verbindung ein. Überschüssige Datenströme werden zurückgewiesen.

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

Der Standardwert ist 100.

Größe der Headertabelle

Der HPACK-Decoder dekomprimiert HTTP-Header für HTTP/2-Verbindungen. Http2.HeaderTableSize schränkt die Größe der Headerkomprimierungstabelle ein, die der HPACK-Decoder verwendet. Der Wert wird in Oktetten bereitgestellt und muss größer als null (0) sein.

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

Der Standardwert ist 4096.

Maximale Framegröße

Http2.MaxFrameSize gibt die maximal zulässige Größe einer vom Server empfangenen oder gesendeten HTTP/2-Verbindungsrahmen-Nutzlast an. Der Wert wird in Oktetten bereitgestellt und muss zwischen 2^14 (16.384) und 2^24-1 (16.777.215) liegen.

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

Der Standardwert ist 2^14 (16.384).

Maximale Größe des Anforderungsheaders

Http2.MaxRequestHeaderFieldSize gibt die maximal zulässige Größe in Oktetten der Anforderungsheaderwerte an. Dieser Grenzwert gilt sowohl für den Namen als auch den Wert in der komprimierten und nicht komprimierten Darstellung. Der Wert muss größer als 0 (null) sein.

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

Der Standardwert ist 8.192.

Anfangsfenstergröße der Verbindung

Http2.InitialConnectionWindowSize gibt die maximalen Anforderungstextdaten in Byte an, die der Server auf einmal für alle Anforderungen (Streams) pro Verbindung aggregiert. Anforderungen werden auch durch Http2.InitialStreamWindowSize beschränkt. Der Wert muss größer als oder gleich 65.535 und kleiner als 2^31 (2.147.483.648) sein.

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

Der Standardwert ist 128 KB (131.072).

Anfangsfenstergröße des Streams

Http2.InitialStreamWindowSize gibt die maximalen Anforderungstextdaten in Byte an, die der Server auf einmal pro Anforderung (Stream) puffert. Anforderungen werden auch durch Http2.InitialConnectionWindowSize beschränkt. Der Wert muss größer als oder gleich 65.535 und kleiner als 2^31 (2.147.483.648) sein.

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

Der Standardwert ist 96 KB (98.304).

Trailer

HTTP-Nachspanne ähneln den HTTP-Headers, jedoch werden sie erst gesendet, nachdem der Antworttext gesendet wurde. Für IIS und HTTP.sys werden nur HTTP/2-Antwortnachspanne unterstützt.

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

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

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

Im vorherigen Beispielcode:

  • stellt SupportsTrailers sicher, dass Nachspanne für die Antwort unterstützt werden.
  • fügt DeclareTrailer dem Antwortheader Trailer den angegebenen Namen für den Nachspann hinzu. Das Deklarieren des Nachspanns einer Antwort ist optional, wird jedoch empfohlen. Wenn DeclareTrailer aufgerufen wird, muss der Nachspann deklariert werden, bevor Antwortheader gesendet werden.
  • fügt AppendTrailer den Nachspann an.

Reset

Durch die Option „Zurücksetzen“ kann der Server eine HTTP/2-Anforderung mit einem angegebenen Fehlercode zurücksetzen. Eine Anforderung zum Zurücksetzen wird als abgebrochen betrachtet.

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

Reset gibt im vorangehenden Codebeispiel den Fehlercode INTERNAL_ERROR an. Weitere Informationen zu HTTP/2-Fehlercodes finden Sie im Abschnitt HTTP/2-Spezifikationsfehlercode.

Synchrone E/A-Vorgänge

AllowSynchronousIO steuert, ob für Anforderung und Antwort synchrone E/A-Vorgänge zulässig sind. Der Standardwert ist false.

Warnung

Sehr viele blockierende synchrone E/A-Vorgänge können zu einem Ressourcenmangel im Threadpool führen, wodurch die App nicht mehr reagiert. Aktivieren Sie AllowSynchronousIO nur bei Verwendung einer Bibliothek, die asynchrone E/A-Vorgänge nicht unterstützt.

Das folgende Beispiel aktiviert synchrone E/A-Vorgänge:

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

Weitere Informationen zu anderen Kestrel-Optionen und -Einschränkungen finden Sie unter:

Endpunktkonfiguration

Standardmäßig wird ASP.NET Core an Folgendes gebunden:

  • http://localhost:5000
  • https://localhost:5001 (wenn ein lokales Entwicklungszertifikat vorhanden ist)

Verwenden Sie Folgendes zum Angeben der URLs:

  • Die Umgebungsvariable ASPNETCORE_URLS
  • Das Befehlszeilenargument --urls
  • Den Hostkonfigurationsschlüssel urls
  • Die Erweiterungsmethode UseUrls

Der Wert, der mit diesen Ansätzen angegeben wird, kann mindestens ein HTTP- oder HTTPS-Endpunkt sein (HTTPS wenn ein Standardzertifikat verfügbar ist). Konfigurieren Sie den Wert als eine durch Semikolons getrennte Liste (z.B. "Urls": "http://localhost:8000;http://localhost:8001").

Weitere Informationen zu diesen Ansätzen finden Sie unter Server-URLs und Außerkraftsetzen der Konfiguration.

Ein Entwicklungszertifikat wird erstellt:

Einige Browser erfordern, dass Sie die explizite Berechtigung erteilen, dem lokalen Entwicklungszertifikat zu vertrauen.

Projektvorlagen konfigurieren Apps, damit sie standardmäßig auf HTTPS ausgeführt werden und die HTTPS-Umleitung und HSTS-Unterstützung enthalten.

Rufen Sie die Listen- oder ListenUnixSocket-Methode unter KestrelServerOptions auf, um URL-Präfixe und Ports für Kestrel zu konfigurieren.

UseUrls, das Befehlszeilenargument --urls, der Hostkonfigurationsschlüssel urls und die Umgebungsvariable ASPNETCORE_URLS funktionieren ebenfalls, verfügen jedoch über Einschränkungen, die im Verlauf dieses Abschnitts erläutert werden (Ein Standardzertifikat muss für die HTTPS-Endpunktkonfiguration verfügbar sein).

KestrelServerOptions-Konfiguration:

ConfigureEndpointDefaults(Action<ListenOptions>)

Gibt die Konfiguration von Action zum Ausführen von jedem angegebenen Endpunkt an. Mehrmalige Aufrufe von ConfigureEndpointDefaults ersetzen vorherige Instanzen von Action mit der zuletzt angegebenen Action.

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

Hinweis

Auf Endpunkte, die durch Aufrufen von ListenListen dem Aufrufen von ConfigureEndpointDefaults erstellt werden, werden die Standardwerte nicht angewendet.

ConfigureHttpsDefaults(Action<HttpsConnectionAdapterOptions>)

Gibt die Konfiguration von Action zum Ausführen von jedem HTTPS-Endpunkt an. Mehrmalige Aufrufe von ConfigureHttpsDefaults ersetzen vorherige Instanzen von Action mit der zuletzt angegebenen Action.

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

Hinweis

Auf Endpunkte, die durch Aufrufen von Listenvor dem Aufrufen von ConfigureHttpsDefaults erstellt werden, werden die Standardwerte nicht angewendet.

Configure(IConfiguration)

Erstellt ein Konfigurationsladeprogramm für das Einrichten von Kestrel, das IConfiguration als Eingabe erfordert. Die Konfiguration muss auf den Konfigurationsabschnitt für Kestrel festgelegt werden.

ListenOptions.UseHttps

Konfiguriert Kestrel zur Verwendung von HTTPS.

ListenOptions.UseHttps-Erweiterungen:

  • UseHttps: Hiermit wird Kestrel zur Verwendung von HTTPS mit dem Standardzertifikat konfiguriert. Löst eine Ausnahme aus, wenn kein Standardzertifikat konfiguriert ist.
  • 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-Parameter:

  • filename entspricht dem Pfad und Dateinamen einer Zertifikatdatei relativ zu dem Verzeichnis, das die Inhaltsdateien der App enthält.
  • password ist das für den Zugriff auf die X.509-Zertifikatsdaten erforderliche Kennwort.
  • configureOptions ist eine Action zum Konfigurieren von HttpsConnectionAdapterOptions. Gibt ListenOptions zurück.
  • storeName ist der Zertifikatspeicher, aus dem das Zertifikat geladen wird.
  • subject ist der Name des Antragstellers für das Zertifikat.
  • allowInvalid gibt an, ob ungültige Zertifikate berücksichtigt werden sollten, z.B. selbstsignierte Zertifikate.
  • location ist der Speicherort, aus dem das Zertifikat geladen wird.
  • serverCertificate ist das X.509-Zertifikat.

In der Produktion muss HTTPS explizit konfiguriert sein. Zumindest muss ein Standardzertifikat angegeben werden.

Die im Folgenden beschriebenen unterstützten Konfigurationen:

  • Keine Konfiguration
  • Ersetzen des Standardzertifikats aus der Konfiguration
  • Ändern des Standards im Code

Keine Konfiguration

Kestrel überwacht http://localhost:5000 und https://localhost:5001 (wenn ein Standardzertifikat verfügbar ist).

Ersetzen des Standardzertifikats aus der Konfiguration

CreateDefaultBuilder ruft Configure(context.Configuration.GetSection("Kestrel")) standardmäßig zum Laden der Kestrel-Konfiguration auf. Ein Standardkonfigurationsschema für HTTPS-App-Einstellungen ist für Kestrel verfügbar. Konfigurieren Sie mehrere Endpunkte, einschließlich der zu verwendenden URLs und Zertifikate aus einer Datei auf dem Datenträger oder einem Zertifikatspeicher.

Im folgenden Beispiel für appsettings.json gilt:

  • Legen Sie AllowInvalid auf true fest, um die Verwendung von ungültigen Zertifikaten zu erlauben (z.B. selbstsignierte Zertifikate).
  • Jeder HTTPS-Endpunkt, der kein Zertifikat angibt (im folgenden Beispiel der Endpunkt HttpsDefaultCert), greift auf das unter Zertifikate>Standard festgelegte Zertifikat oder das Entwicklungszertifikat zurück.
{
  "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>"
      }
    }
  }
}

Alternativ zur Verwendung von Pfad und Kennwort für alle Zertifikatknoten können Sie das Zertifikat mithilfe von Zertifikatspeicherfeldern angeben. Das Zertifikat unter Zertifikate>Standard kann beispielweise wie folgt angegeben werden:

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

Schema-Hinweise:

  • Bei den Namen der Endpunkte wird die Groß-/Kleinschreibung nicht beachtet. Zum Beispiel sind HTTPS und Https gültig.
  • Der Parameter Url ist für jeden Endpunkt erforderlich. Das Format für diesen Parameter ist identisch mit dem allgemeinen Konfigurationsparameter Urls, mit der Ausnahme, dass er auf einen einzelnen Wert begrenzt ist.
  • Diese Endpunkte ersetzen die in der allgemeinen Urls-Konfiguration festgelegten Endpunkte, anstatt zu ihnen hinzuzufügen. Endpunkte, die über Listen in Code definiert werden, werden den im Konfigurationsabschnitt definierten Endpunkten hinzugefügt.
  • Der Certificate-Abschnitt ist optional. Wenn der Certificate-Abschnitt nicht angegeben ist, werden die in früheren Szenarios definierten Standardwerte verwendet. Wenn keine Standardwerte verfügbar sind, löst der Server eine Ausnahme aus und startet nicht.
  • Der Certificate-Abschnitt unterstützt Zertifikate vom Typ CertificatePassword und SubjectStore.
  • Auf diese Weise kann eine beliebige Anzahl von Endpunkten definiert werden, solange Sie keine Portkonflikte verursachen.
  • options.Configure(context.Configuration.GetSection("{SECTION}")) gibt KestrelConfigurationLoader mit der Methode .Endpoint(string name, listenOptions => { }) zurück, die dazu verwendet werden kann, die Einstellungen eines Endpunkts zu ergänzen:
webBuilder.UseKestrel((context, serverOptions) =>
{
    serverOptions.Configure(context.Configuration.GetSection("Kestrel"))
        .Endpoint("HTTPS", listenOptions =>
        {
            listenOptions.HttpsOptions.SslProtocols = SslProtocols.Tls12;
        });
});

Auf KestrelServerOptions.ConfigurationLoader kann direkt zugegriffen werden, um die Iteration auf dem vorhandenen Ladeprogramm fortzusetzen, etwa auf dem von CreateDefaultBuilder bereitgestellten Ladeprogramm.

  • Der Konfigurationsabschnitt ist für jeden Endpunkt in den Optionen der Methode Endpoint verfügbar, sodass benutzerdefinierte Einstellungen gelesen werden können.
  • Mehrere Konfigurationen können durch erneutes Aufrufen von options.Configure(context.Configuration.GetSection("{SECTION}")) mit einem anderen Abschnitt geladen werden. Sofern Load nicht in einer vorherigen Instanz explizit aufgerufen wird, wird nur die letzte Konfiguration verwendet. Das Metapaket ruft Load nicht auf, sodass der Abschnitt mit der Standardkonfiguration ersetzt werden kann.
  • KestrelConfigurationLoader spiegelt die API-Familie Listen von KestrelServerOptions als Endpoint-Überladungen, weshalb Code und Konfigurationsendpunkte am selben Ort konfiguriert werden können. Diese Überladungen verwenden keine Namen und nutzen nur Standardeinstellungen aus der Konfiguration.

Ändern des Standards im Code

ConfigureEndpointDefaults und ConfigureHttpsDefaults können zum Ändern der Standardeinstellungen für ListenOptions und HttpsConnectionAdapterOptions verwendet werden, einschließlich der Standardzertifikate, die im vorherigen Szenario festgelegt wurden. ConfigureEndpointDefaults und ConfigureHttpsDefaults sollten aufgerufen werden, bevor Endpunkte konfiguriert werden.

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

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

Kestrel-Unterstützung für SNI

Die Servernamensanzeige (SNI) kann zum Hosten mehrerer Domänen auf der gleichen IP-Adresse und dem gleichen Port verwendet werden. Damit die Servernamensanzeige funktioniert, sendet der Client während des TLS-Handshakes den Hostnamen für die sichere Sitzung an den Server, sodass der Server das richtige Zertifikat bereitstellen kann. Der Client verwendet das beigestellte Zertifikat für die verschlüsselte Kommunikation mit dem Server während der sicheren Sitzung nach dem TLS-Handshake.

Kestrel unterstützt die Servernamensanzeige über den ServerCertificateSelector-Rückruf. Der Rückruf wird für jede Verbindung einmal aufgerufen, um der App zu ermöglichen, den Hostnamen zu überprüfen und das entsprechende Zertifikat auszuwählen.

Für die Unterstützung der Servernamensanzeige benötigen Sie Folgendes:

  • Wird auf dem Zielframework netcoreapp2.1 oder höher ausgeführt. In net461 oder höher, wird der Rückruf aufgerufen, name ist aber immer null. name ist auch null, wenn der Client den Hostnamenparameter nicht im TLS-Handshake angibt.
  • Alle Websites werden in derselben Kestrel-Instanz ausgeführt. Kestrel unterstützt ohne Reverseproxy keine gemeinsame IP-Adresse und keinen gemeinsamen Port für mehrere Instanzen.
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;
            };
        });
    });
});

Verbindungsprotokollierung

Rufen Sie UseConnectionLogging auf, um Protokolle auf Debugebene für die Kommunikation auf Byteebene für eine Verbindung auszugeben. Die Verbindungsprotokollierung ist beim Beheben von Problemen bei der Low-Level-Kommunikation hilfreich, wie z. B. bei der TLS-Verschlüsselung und bei Proxys. Wenn UseConnectionLogging vor UseHttps platziert wird, wird der verschlüsselte Datenverkehr protokolliert. Wenn UseConnectionLogging nach UseHttps platziert wird, wird der entschlüsselte Datenverkehr protokolliert.

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

Binden an einen TCP-Socket

Die Listen-Methode wird an ein TCP-Socket gebunden, und ein Lambdaausdruck einer Option lässt die Konfiguration des X.509-Zertifikats zu:

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

Im Beispiel wird HTTPS für einen Endpunkt mit ListenOptions konfiguriert. Verwenden Sie die gleiche API zum Konfigurieren anderer Kestrel-Einstellungen für bestimmte Endpunkte.

Unter Windows können selbstsignierte Zertifikate mit dem PowerShell-Cmdlet New-SelfSignedCertificate erstellt werden. Ein nicht unterstütztes Beispiel finden Sie unter UpdateIISExpressSSLForChrome.ps1.

Unter macOS, Linux und Windows können Zertifikate mithilfe von OpenSSL erstellt werden.

Binden an einen Unix-Socket

Wie in diesem Beispiel dargestellt, lauschen Sie an einem Unix-Socket mit ListenUnixSocket, um eine verbesserte Leistung mit Nginx zu erzielen:

webBuilder.ConfigureKestrel(serverOptions =>
{
    serverOptions.ListenUnixSocket("/tmp/kestrel-test.sock");
    serverOptions.ListenUnixSocket("/tmp/kestrel-test.sock", 
        listenOptions =>
        {
            listenOptions.UseHttps("testCert.pfx", 
                "testpassword");
        });
})
  • Legen Sie den Eintrag server>location>proxy_pass in der Nginx-Konfigurationsdatei auf http://unix:/tmp/{KESTREL SOCKET}:/; fest. {KESTREL SOCKET} ist der Name des für ListenUnixSocket bereitgestellten Socket (zum Beispiel kestrel-test.sock im vorherigen Beispiel).
  • Stellen Sie sicher, dass der Socket von Nginx beschreibbar ist (z. B. chmod go+w /tmp/kestrel-test.sock).

Port 0

Wenn die Portnummer 0 angegeben wird, wird Kestrel dynamisch an einen verfügbaren Port gebunden. Im folgenden Beispiel wird veranschaulicht, wie bestimmt werden kann, für welchen Port Kestrel zur Laufzeit eine Bindung erstellt hat:

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

Wenn die App ausgeführt wird, gibt das Ausgabefenster der Konsole den dynamischen Port an, über den die App erreicht werden kann:

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

Einschränkungen

Konfigurieren Sie Endpunkte mithilfe der folgenden Ansätze:

  • UseUrls
  • Befehlszeilenargument --urls
  • Hostkonfigurationsschlüssel urls
  • Umgebungsvariable ASPNETCORE_URLS

Diese Methoden sind nützlich, wenn Ihr Code mit anderen Servern als Kestrel funktionieren soll. Beachten Sie jedoch die folgenden Einschränkungen:

  • HTTPS kann nicht mit diesen Ansätzen verwendet werden, außer ein Standardzertifikat wird in der HTTPS-Endpunktkonfiguration angegeben (z.B. wenn Sie wie zuvor in diesem Artikel gezeigt die KestrelServerOptions-Konfiguration oder eine Konfigurationsdatei verwenden).
  • Wenn die Ansätze Listen und UseUrls gleichzeitig verwendet werden, überschreiben die Listen-Endpunkte die UseUrls-Endpunkte.

IIS-Endpunktkonfiguration

Bei der Verwendung von IIS werden die URL-Bindungen für IIS-Überschreibungsbindungen durch Listen oder UseUrls festgelegt. Weitere Informationen finden Sie im Artikel ASP.NET Core-Modul.

ListenOptions.Protocols

Die Protocols-Eigenschaft richtet die HTTP-Protokolle (HttpProtocols) ein, die für einen Verbindungsendpunkt oder für den Server aktiviert werden. Weisen Sie der Protocols-Eigenschaft einen Wert aus der HttpProtocols-Enumeration zu.

HttpProtocols-Enumerationswert Zulässiges Verbindungsprotokoll
Http1 Nur HTTP/1.1. Kann mit oder ohne TLS verwendet werden.
Http2 Nur HTTP/2. Kann nur ohne TLS verwendet werden, wenn der Client einen Vorabkenntnis-Modus unterstützt.
Http1AndHttp2 HTTP/1.1 und HTTP/2. Für HTTP/2 muss der Client HTTP/2 im TLS ALPN-Handshake (Application-Layer Protocol Negotiation) auswählen, andernfalls wird standardmäßig eine HTTP/1.1 verwendet.

Der Standardwert von ListenOptions.Protocols ist für alle Endpunkte HttpProtocols.Http1AndHttp2.

TLS-Einschränkungen für HTTP/2:

  • TLS Version 1.2 oder höher
  • Erneute Aushandlung deaktiviert
  • Komprimierung deaktiviert
  • Minimale Größen für Austausch von flüchtigen Schlüsseln:
    • ECDHE (Elliptic Curve Diffie-Hellman) [RFC4492]: mindestens 224 Bit
    • DHE (Finite Field Diffie-Hellman) [TLS12]: mindestens 2048 Bit
  • Verschlüsselungssammlung nicht verboten

TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 [TLS-ECDHE] mit der elliptischen P-256-Kurve [FIPS186] wird standardmäßig unterstützt.

Das folgende Beispiel erlaubt HTTP/1.1- und HTTP/2-Verbindungen an Port 8000. Die Verbindungen werden durch TLS mit einem bereitgestellten Zertifikat geschützt:

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

Verwenden Sie Verbindungsmiddleware, um TLS-Handshakes auf Verbindungsbasis für bestimmte Verschlüsselungen zu filtern, falls erforderlich.

Im folgenden Beispiel wird NotSupportedException für jeden Verschlüsselungsalgorithmus ausgelöst, der von der App nicht unterstützt wird. Alternativ können Sie ITlsHandshakeFeature.CipherAlgorithm definieren und mit einer Liste zulässiger Verschlüsselungssammlungen vergleichen.

Es wird keine Verschlüsselung mit einem CipherAlgorithmType.Null-Verschlüsselungsalgorithmus verwendet.

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

Die Verbindungsfilterung kann auch über einen IConnectionBuilder-Lambdaausdruck konfiguriert werden:

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

Unter Linux kann CipherSuitesPolicy zum Filtern von TLS-Handshakes auf Verbindungsbasis verwendet werden:

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

Festlegen des Protokolls aus der Konfiguration

CreateDefaultBuilder ruft serverOptions.Configure(context.Configuration.GetSection("Kestrel")) standardmäßig zum Laden der Kestrel-Konfiguration auf.

Das folgende appsettings.json -Beispiel richtet HTTP/1.1 als Standardverbindungsprotokoll für alle Endpunkte ein:

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

Das folgende appsettings.json -Beispiel richtet HTTP/1.1 als Verbindungsprotokoll für einen bestimmten Endpunkt ein:

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

Protokolle, die in Code angegeben werden, setzen Werte außer Kraft, der durch die Konfiguration festgelegt werden.

URL-Präfixe

Bei der Verwendung von UseUrls, dem Befehlszeilenargument --urls, dem Hostkonfigurationsschlüssel urls oder der Umgebungsvariable ASPNETCORE_URLS können die URL-Präfixe in den folgenden Formaten vorliegen.

Nur HTTP-URL-Präfixe sind gültig. Kestrel unterstützt HTTPS nicht beim Konfigurieren von URL-Bindungen mit UseUrls.

  • IPv4-Adresse mit Portnummer

    http://65.55.39.10:80/
    

    Bei 0.0.0.0 handelt es sich um einen Sonderfall, für den eine Bindung an alle IPv4-Adressen erfolgt.

  • IPv6-Adresse mit Portnummer

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

    [::] stellt das Äquivalent von IPv6 zu 0.0.0.0 für IPv4 dar.

  • Hostname mit Portnummer

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

    Hostnamen, * und + sind nicht spezifisch. Alle Elemente, die nicht als gültige IP-Adresse oder localhost erkannt werden, werden an alle IPv4- und IPv6-IP-Adressen gebunden. Verwenden Sie HTTP.sys oder einen Reverseproxyserver zum Binden verschiedener Hostnamen an verschiedene ASP.NET Core-Apps auf demselben Port, z.B. IIS, Nginx oder Apache.

    Warnung

    Für das Hosten in einer Reverseproxykonfiguration ist eine Middlewarekonfiguration für weitergeleitete Header erforderlich.

  • localhost-Hostname mit Portnummer oder Loopback-IP mit Portnummer

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

    Wenn localhost angegeben ist, versucht Kestrel, eine Bindung zu IPv4- und IPv6-Loopback-Schnittstellen zu erstellen. Wenn der erforderliche Port von einem anderen Dienst auf einer der Loopback-Schnittstellen verwendet wird, tritt beim Starten von Kestrel ein Fehler auf. Wenn eine der Loopback-Schnittstellen aus anderen Gründen nicht verfügbar ist (meistens durch die fehlende Unterstützung von IPv6), protokolliert Kestrel eine Warnung.

Host-Filterung

Obwohl Kestrel die Konfiguration basierend auf Präfixe wie http://example.com:5000 unterstützt, ignoriert Kestrel den Hostnamen weitgehend. Der Host localhost ist ein Sonderfall, der für die Bindung an Loopback-Adressen verwendet wird. Jeder Host, der keine explizite IP-Adresse ist, wird an alle öffentlichen IP-Adressen gebunden. Host-Header werden nicht überprüft.

Verwenden Sie Middleware zum Filtern von Hosts, um dieses Problem zu umgehen. Die Middleware zum Filtern von Hosts wird durch das Microsoft.AspNetCore.HostFiltering-Paket bereitgestellt, das implizit für ASP.NET Core-Apps zur Verfügung steht. Die Middleware wird von CreateDefaultBuilder hinzugefügt, wodurch AddHostFiltering aufgerufen wird:

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

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

Die Middleware zum Filtern von Hosts ist standardmäßig deaktiviert. Wenn Sie die Middleware aktivieren möchten, definieren Sie einen AllowedHosts-Schlüssel in appsettings.json/appsettings.{Environment}.json. Der Wert ist eine durch Semikolons getrennte Liste von Hostnamen ohne Portnummern:

appsettings.json:

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

Hinweis

Middleware für weitergeleitete Header hat auch eine AllowedHosts-Option. Middleware für weitergeleitete Header und Middleware zum Filtern von Hosts besitzen ähnliche Funktionen für unterschiedliche Szenarios. Legen Sie AllowedHosts mit Middleware für weitergeleitete Header fest, wenn der Host-Header beim Weiterleiten von Anforderungen mit einem Reverseproxyserver oder einem Lastenausgleichsmodul nicht beibehalten wird. Legen Sie AllowedHosts mit Middleware zum Filtern von Hosts fest, wenn Kestrel als öffentlicher Edgeserver verwendet oder der Host-Header direkt weitergeleitet wird.

Weitere Informationen zu Middleware für weitergeleitete Header finden Sie unter Konfigurieren von ASP.NET Core zur Verwendung mit Proxyservern und Lastenausgleich.

Libuv-Transportkonfiguration

Für Projekte, die den Einsatz von Libuv (UseLibuv) erfordern:

  • Fügen Sie der Projektdatei der App eine Abhängigkeit für das Microsoft.AspNetCore.Server.Kestrel.Transport.Libuv-Paket hinzu:

    <PackageReference Include="Microsoft.AspNetCore.Server.Kestrel.Transport.Libuv"
                      Version="{VERSION}" />
    
  • UseLibuv auf IWebHostBuilder aufrufen:

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

Leeren von HTTP/1.1-Anforderungen

Das Öffnen von HTTP-Verbindungen ist zeitaufwendig. Bei HTTPS ist es zudem ressourcenintensiv. Daher versucht Kestrel, Verbindungen gemäß dem HTTP/1.1-Protokoll wiederzuverwenden. Ein Anforderungstext muss vollständig genutzt worden sein, damit die Verbindung wiederverwendet werden kann. Die App nutzt nicht immer den Anforderungstext, z. B. bei einer POST-Anforderung, bei der der Server eine Umleitung oder 404-Antwort zurückgibt. Im Fall der POST-Umleitung:

  • Der Client hat möglicherweise bereits einen Teil der POST-Daten gesendet.
  • Der Server schreibt die 301-Antwort.
  • Die Verbindung kann erst dann für eine neue Anforderung verwendet werden, wenn die POST-Daten im vorherigen Anforderungstext vollständig gelesen wurden.
  • Kestrel versucht, den Anforderungstext zu leeren. Leeren des Anforderungstexts bedeutet, die Daten zu lesen und zu verwerfen, ohne sie zu verarbeiten.

Beim Ausgleichsprozess wird ein Kompromiss zwischen der Möglichkeit der Wiederverwendung der Verbindung und der Dauer gefunden, die zum Entfernen der verbleibenden Daten benötigt wird:

  • Für das Leeren gilt ein Zeitlimit von fünf Sekunden, das nicht konfigurierbar ist.
  • Wenn vor dem Zeitlimit nicht alle durch den Header Content-Length oder Transfer-Encoding angegebenen Daten gelesen wurden, wird die Verbindung geschlossen.

Mitunter möchten Sie die Anforderung sofort beenden, entweder bevor oder nachdem die Antwort geschrieben wurde. Beispielsweise können für Clients restriktive Datenobergrenzen gelten, sodass das Begrenzen hochgeladener Daten Priorität haben kann. Um in solchen Fällen eine Anforderung zu beenden, rufen Sie HttpContext.abort in einem Controller, eine Razor Page oder Middleware auf.

Gegen den Aufruf von Abort gibt es Vorbehalte:

  • Das Erstellen neuer Verbindungen kann langsam und aufwendig sein.
  • Es gibt keine Garantie, dass der Client die Antwort gelesen hat, bevor die Verbindung geschlossen wird.
  • Das Aufrufen von Abort sollte selten erfolgen und schweren Fehlerfällen und nicht gewöhnlichen Fehlern vorbehalten sein.
    • Rufen Sie Abort nur dann auf, wenn ein konkretes Problem gelöst werden muss. Rufen Sie beispielsweise Abort auf, wenn böswillige Clients versuchen, Daten per POST abzurufen, oder wenn es einen Fehler im Clientcode gibt, der umfangreiche oder zahlreiche Anforderungen verursacht.
    • Rufen Sie Abort nicht für gewöhnliche Fehlersituationen auf, wie z. B. HTTP 404 (Nicht gefunden).

Durch den Aufruf von HttpResponse.CompleteAsync vor dem Aufruf von Abort wird sichergestellt, dass der Server das Schreiben der Antwort abgeschlossen hat. Das Clientverhalten ist jedoch nicht vorhersagbar, und es kann sein, dass die Antwort nicht gelesen wird, bevor die Verbindung abgebrochen wird.

Dieser Prozess bei HTTP/2 ist anders, da das Protokoll den Abbruch einzelner Anforderungsströme ohne Schließen der Verbindung unterstützt. Das fünfsekündige Zeitlimit für das Leeren gilt nicht. Wenn nach dem Fertigstellen einer Antwort ungelesene Anforderungstextdaten vorhanden sind, sendet der Server einen HTTP/2-RST-Datenrahmen. Zusätzliche Datenrahmen im Anforderungstext werden ignoriert.

Wenn möglich, ist es für Clients besser, den Anforderungsheader Expect: 100-continue zu verwenden und auf die Antwort des Servers zu warten, bevor mit dem Senden des Anforderungstexts begonnen wird. Das gibt dem Client die Gelegenheit, die Antwort zu prüfen und abzubrechen, bevor nicht benötigte Daten gesendet werden.

Zusätzliche Ressourcen