Implementazione del server Web Kestrel in ASP.NET Core

Di Tom Dykstra, Chris Ross e Stephen Halter

Kestrelè un server Web multipiattaforma per ASP.NET Core. Kestrelè il server Web incluso e abilitato per impostazione predefinita nei modelli di progetto ASP.NET Core.

Kestrel supporta gli scenari seguenti:

  • HTTPS
  • HTTP/2 (ad eccezione di macOS†)
  • Aggiornamento opaco usato per abilitare WebSocket
  • Socket Unix ad alte prestazioni dietro Nginx

†HTTP/2 sarà supportato in macOS in una versione futura.

Kestrel è supportato in tutte le piattaforme e versioni supportate da .NET Core.

Introduzione

ASP.NET Core modelli di progetto usati Kestrel per impostazione predefinita quando non è ospitato con IIS. Nel modello generato Program.csdal modello seguente il WebApplication.CreateBuilder metodo chiama UseKestrel internamente:

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

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

app.Run();

Per altre informazioni sulla configurazione WebApplication e WebApplicationBuilder, vedere Panoramica delle API minime.

Certificati client facoltativi

Per informazioni sulle app che devono proteggere un subset dell'app con un certificato, vedere Certificati client facoltativi.

Risorse aggiuntive

Nota

A partire da ASP.NET Core 5,0, Kestrelil trasporto libuv è obsoleto. Il trasporto libuv non riceve aggiornamenti per supportare nuove piattaforme del sistema operativo, ad esempio Windows ARM64, e verrà rimosso in una versione futura. Rimuovere le chiamate al metodo obsoleto UseLibuv e usare Kestrelinvece il trasporto Socket predefinito.

Kestrelè un server Web multipiattaforma per ASP.NET Core. Kestrelè il server Web incluso e abilitato per impostazione predefinita nei modelli di progetto ASP.NET Core.

Kestrel supporta gli scenari seguenti:

  • HTTPS
  • HTTP/2 (ad eccezione di macOS†)
  • Aggiornamento opaco usato per abilitare WebSocket
  • Socket Unix ad alte prestazioni dietro Nginx

†HTTP/2 sarà supportato in macOS in una versione futura.

Kestrel è supportato in tutte le piattaforme e versioni supportate da .NET Core.

Visualizzare o scaricare il codice di esempio (procedura per il download)

Introduzione

ASP.NET Core modelli di progetto usati Kestrel per impostazione predefinita quando non è ospitato con IIS. In Program.cs, il ConfigureWebHostDefaults metodo chiama UseKestrel:

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

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

Per altre informazioni sulla compilazione dell'host, vedere le sezioni Configurare un host e le impostazioni del generatore predefinitodell'host generico .NET in ASP.NET Core.

Certificati client facoltativi

Per informazioni sulle app che devono proteggere un subset dell'app con un certificato, vedere Certificati client facoltativi.

Risorse aggiuntive

Nota

A partire da ASP.NET Core 5,0, Kestrelil trasporto libuv è obsoleto. Il trasporto libuv non riceve aggiornamenti per supportare nuove piattaforme del sistema operativo, ad esempio Windows ARM64, e verrà rimosso in una versione futura. Rimuovere le chiamate al metodo obsoleto UseLibuv e usare Kestrelinvece il trasporto Socket predefinito.

Kestrelè un server Web multipiattaforma per ASP.NET Core. Kestrelè il server Web incluso per impostazione predefinita nei modelli di progetto ASP.NET Core.

Kestrel supporta gli scenari seguenti:

  • HTTPS
  • Aggiornamento opaco usato per abilitare WebSocket
  • Socket Unix ad alte prestazioni dietro Nginx
  • HTTP/2 (ad eccezione di macOS†)

†HTTP/2 sarà supportato in macOS in una versione futura.

Kestrel è supportato in tutte le piattaforme e versioni supportate da .NET Core.

Visualizzare o scaricare il codice di esempio (procedura per il download)

Supporto HTTP/2

HTTP/2 è disponibile per le app ASP.NET Core se vengono soddisfatti i requisiti di base seguenti:

  • Sistema operativo†
    • Windows Server 2016/Windows 10 o versioni successive=
    • Linux con OpenSSL 1.0.2 o versioni successive (ad esempio, Ubuntu 16.04 o versioni successive)
  • Framework di destinazione: .NET Core 2.2 o versioni successive
  • Connessione ALPN (Application-Layer Protocol Negotiation)
  • Connessione TLS 1.2 o successiva

†HTTP/2 sarà supportato in macOS in una versione futura. ^Kestrel ha un supporto limitato per HTTP/2 in Windows Server 2012 R2 e Windows 8.1. Il supporto è limitato perché l'elenco di suite di crittografia TLS supportate disponibili in questi sistemi operativi è limitato. Un certificato generato con un algoritmo ECDSA potrebbe essere necessario per proteggere le connessioni TLS.

Se viene stabilita una connessione HTTP/2, HttpRequest.Protocol segnala HTTP/2.

A partire da .NET Core 3.0, HTTP/2 è abilitato per impostazione predefinita. Per altre informazioni sulla configurazione, vedere le Kestrel sezioni opzioni e ListenOptions.Protocols .

Quando usare Kestrel con un proxy inverso

Kestrel può essere usato da solo o con un server proxy inverso. Un server proxy inverso riceve richieste HTTP dalla rete e le inoltra a Kestrel. Esempi di un server proxy inverso includono:

Kestrel usato come server Web perimetrale (con connessione Internet):

Kestrel comunica direttamente con Internet senza un server proxy inverso

Kestrel usato in una configurazione proxy inversa:

Kestrel comunica indirettamente con Internet attraverso un server proxy inverso, ad esempio IIS, Nginx o Apache

La configurazione, con o senza un server proxy inverso, è una configurazione di hosting supportata.

Kestrel usato come server perimetrale senza un server proxy inverso non supporta la condivisione dello stesso INDIRIZZO IP e della porta tra più processi. Quando Kestrel è configurato per l'ascolto su una porta, Kestrel gestisce tutto il traffico per tale porta indipendentemente dalle intestazioni delle Host richieste. Un proxy inverso che può condividere porte ha la possibilità di inoltrare le richieste a Kestrel in un indirizzo IP e una porta univoci.

Anche se la presenza di un server proxy inverso non è necessaria, può risultare utile per i motivi seguenti.

Un proxy inverso:

  • Può limitare l'area della superficie di attacco pubblica esposta delle app ospitate.
  • Offre un livello aggiuntivo di configurazione e protezione.
  • Potrebbe offrire un'integrazione migliore con l'infrastruttura esistente.
  • Semplifica il bilanciamento del carico e la configurazione di comunicazioni protette (HTTPS). Solo il server proxy inverso richiede un certificato X.509 e tale server può comunicare con i server dell'app nella rete interna usando HTTP normale.

Avviso

L'hosting in una configurazione proxy inverso richiede la configurazione middleware delle intestazioni inoltrate.

Kestrelnelle app di ASP.NET Core

ASP.NET Core modelli di progetto usati Kestrel per impostazione predefinita. In Program.cs, il ConfigureWebHostDefaults metodo chiama UseKestrel:

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

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

Per altre informazioni sulla compilazione dell'host, vedere le sezioni Configurare un host e le impostazioni del generatore predefinitodell'host generico .NET in ASP.NET Core.

Per fornire una configurazione aggiuntiva dopo la chiamata di ConfigureWebHostDefaults, usare 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 Opzioni

Il Kestrel server Web include opzioni di configurazione dei vincoli particolarmente utili nelle distribuzioni con connessione Internet.

Impostare i vincoli per la proprietà Limits della classe KestrelServerOptions. La proprietà Limits contiene un'istanza della classe KestrelServerLimits.

Negli esempi seguenti viene usato lo spazio dei nomi Microsoft.AspNetCore.Server.Kestrel.Core:

using Microsoft.AspNetCore.Server.Kestrel.Core;

Negli esempi illustrati più avanti in questo articolo, Kestrel le opzioni sono configurate nel codice C#. Kestrel è anche possibile impostare opzioni usando un provider di configurazione. Ad esempio, il provider di configurazione file può caricare Kestrel la configurazione da un appsettings.json file o appsettings.{Environment}.json :

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

Nota

KestrelServerOptions e la configurazione degli endpoint sono configurabili dai provider di configurazione. La configurazione rimanente Kestrel deve essere configurata nel codice C#.

Usare uno degli approcci seguenti:

  • Configurare Kestrel in Startup.ConfigureServices:

    1. Inserire un'istanza di IConfiguration nella Startup classe. Nell'esempio seguente si presuppone che la Configuration configurazione inserita venga assegnata alla proprietà.

    2. In Startup.ConfigureServicescaricare la Kestrel sezione della configurazione nella Kestrelconfigurazione:

      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)
          {
              ...
          }
      }
      
  • Configurare Kestrel quando si compila l'host:

    In Program.cscaricare la Kestrel sezione della configurazione nella Kestrelconfigurazione:

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

Entrambi gli approcci precedenti funzionano con qualsiasi provider di configurazione.

Timeout keep-alive

KeepAliveTimeout

Ottiene o imposta il timeout keep-alive. Il valore predefinito è 2 minuti.

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

Numero massimo di connessioni client

MaxConcurrentConnections MaxConcurrentUpgradedConnections

È possibile impostare il numero massimo di connessioni TCP aperte simultaneamente per l'intera app con il codice seguente:

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

È previsto un limite separato per le connessioni che sono state aggiornate da HTTP o HTTPS a un altro protocollo (ad esempio su una richiesta WebSocket). Dopo l'aggiornamento di una connessione, questa non viene conteggiata per il limite 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);
})

Per impostazione predefinita, il numero massimo di connessioni è illimitato (null).

Dimensione massima del corpo della richiesta

MaxRequestBodySize

La dimensione massima predefinita del corpo della richiesta è pari a 30.000.000 di byte, equivalenti a circa 28,6 MB.

Il metodo consigliato per ignorare il limite in un'app ASP.NET Core MVC è l'uso dell'attributo RequestSizeLimitAttribute in un metodo di azione:

[RequestSizeLimit(100000000)]
public IActionResult MyActionMethod()

L'esempio seguente illustra come configurare il vincolo per l'app in ogni richiesta:

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

Eseguire l'override dell'impostazione in una richiesta specifica nel 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));
    }

Viene generata un'eccezione se l'app configura il limite in una richiesta dopo che l'app ha iniziato a leggere la richiesta. Una proprietà IsReadOnly indica se la proprietà MaxRequestBodySize è in stato di sola lettura e pertanto è troppo tardi per configurare il limite.

Quando un'app viene eseguita fuori processo dietro il modulo ASP.NET Core, Kestrelil limite di dimensioni del corpo della richiesta è disabilitato perché IIS imposta già il limite.

Velocità minima dei dati del corpo della richiesta

MinRequestBodyDataRate MinResponseDataRate

Kestrel controlla ogni secondo se i dati arrivano alla frequenza specificata in byte/secondo. Se la frequenza scende al di sotto del minimo, la connessione viene timeout. Il periodo di tolleranza è la quantità di tempo che Kestrel dà al client di aumentare il tasso di invio fino al minimo. Il tasso non viene controllato durante tale periodo. Il periodo di prova consente di evitare l'interruzione di connessioni che inizialmente inviano i dati a velocità ridotta a causa dell'avvio lento del protocollo TCP.

La velocità minima predefinita è di 240 byte al secondo, con un periodo di tolleranza di 5 secondi.

Anche per la risposta è prevista una velocità minima. Il codice per impostare il limite della richiesta e della risposta è identico e varia solo per RequestBody o Response nei nomi di proprietà e di interfaccia.

Ecco un esempio che illustra come configurare le tariffe minime dei dati in 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);
})

Eseguire l'override dei limiti minimi di frequenza per richiesta nel 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));
    }

La funzionalità IHttpMinResponseDataRateFeature a cui si fa riferimento nell'esempio precedente non è presente in HttpContext.Features per le richieste HTTP/2, perché la modifica dei limiti di velocità per ogni richiesta in genere non è supportata per HTTP/2 a causa del supporto del protocollo per il multiplexing delle richieste. La funzionalità IHttpMinRequestBodyDataRateFeature è tuttavia ancora presente in HttpContext.Features per le richieste HTTP/2, perché il limite di velocità di lettura può comunque essere disabilitato interamente per ogni singola richiesta impostando IHttpMinRequestBodyDataRateFeature.MinDataRate su null anche per una richiesta HTTP/2. Il tentativo di leggere IHttpMinRequestBodyDataRateFeature.MinDataRate o il tentativo di impostazione di un valore diverso da null causerà la generazione di una NotSupportedException per una richiesta HTTP/2.

I limiti di velocità a livello di server configurati tramite KestrelServerOptions.Limits vengono tuttavia applicati alle connessioni HTTP/1.x e HTTP/2.

Timeout delle intestazioni delle richieste

RequestHeadersTimeout

Ottiene o imposta la quantità massima di tempo che il server dedica alla ricezione delle intestazioni delle richieste. Il valore predefinito è 30 secondi.

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

Numero massimo di flussi per connessione

Http2.MaxStreamsPerConnection limita il numero di flussi di richieste simultanee per ogni connessione HTTP/2. I flussi in eccesso vengono rifiutati.

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

Il valore predefinito è 100.

Dimensioni della tabella delle intestazioni

Il decodificatore HPACK decomprime le intestazioni HTTP per le connessioni HTTP/2. Http2.HeaderTableSize limita le dimensioni della tabella di compressione delle intestazioni usata dal decodificatore HPACK. Il valore viene specificato in ottetti e deve essere maggiore di zero (0).

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

Il valore predefinito è 4096.

Dimensione massima del frame

Http2.MaxFrameSize indica la dimensione massima consentita di un payload del frame di connessione HTTP/2 ricevuto o inviato dal server. Il valore viene specificato in ottetti e deve essere compreso tra 2^14 (16.384) e 2^24-1 (16.777.215).

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

Il valore predefinito è 2^14 (16.384).

Dimensioni massime dell'intestazione della richiesta

Http2.MaxRequestHeaderFieldSize indica le dimensioni massime consentite in ottetti di valori di intestazione di richiesta. Questo limite si applica sia al nome che al valore nelle rappresentazioni compresse e non compresse. Il valore deve essere maggiore di zero (0).

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

Il valore predefinito è 8.192.

Dimensioni della finestra di connessione iniziali

Http2.InitialConnectionWindowSize indica il numero massimo di byte di dati del corpo della richiesta che il server memorizza nel buffer in una volta, aggregati in tutte le richieste (flussi), per ogni connessione. Le richieste sono anche limitate da Http2.InitialStreamWindowSize. Il valore deve essere maggiore di o uguale a 65.535 e minore di 2^31 (2.147.483.648).

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

Il valore predefinito è 128 KB (131.072).

Dimensioni della finestra di flusso iniziali

Http2.InitialStreamWindowSize indica il numero massimo di byte di dati del corpo della richiesta che il server memorizza nel buffer in una volta per ogni richiesta (flusso). Le richieste sono anche limitate da Http2.InitialConnectionWindowSize. Il valore deve essere maggiore di o uguale a 65.535 e minore di 2^31 (2.147.483.648).

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

Il valore predefinito è 96 KB (98.304).

Trailer

I trailer HTTP sono simili alle intestazioni HTTP, ad eccezione di quelli inviati dopo l'invio del corpo della risposta. Per IIS e HTTP.sys, sono supportati solo i trailer di risposta HTTP/2.

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

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

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

Nel codice di esempio precedente:

  • SupportsTrailers assicura che i trailer siano supportati per la risposta.
  • DeclareTrailer aggiunge il nome del trailer specificato all'intestazione Trailer di risposta. La dichiarazione dei trailer di una risposta è facoltativa, ma consigliata. Se DeclareTrailer viene chiamato, deve essere prima dell'invio delle intestazioni di risposta.
  • AppendTrailer aggiunge il trailer.

Reset

La reimpostazione consente al server di reimpostare una richiesta HTTP/2 con un codice di errore specificato. Una richiesta di reimpostazione viene considerata interrotta.

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

Reset nell'esempio di codice precedente specifica il INTERNAL_ERROR codice di errore. Per altre informazioni sui codici di errore HTTP/2, visitare la sezione codice di errore della specifica HTTP/2.

I/O sincrono

AllowSynchronousIO controlla se l'I/O sincrono è consentito per la richiesta e la risposta. Il valore predefinito è false.

Avviso

Un numero elevato di operazioni di I/O sincrone può causare la starvazione del pool di thread, che rende l'app non rispondente. Abilita AllowSynchronousIO solo quando si usa una libreria che non supporta l'I/O asincrona.

Nell'esempio seguente viene abilitato l'I/O sincrona:

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

Per informazioni su altre Kestrel opzioni e limiti, vedere:

Configurazione dell'endpoint

Per impostazione predefinita, ASP.NET Core è associato a:

  • http://localhost:5000
  • https://localhost:5001 (quando è presente un certificato di sviluppo locale)

Specificare gli URL usando gli elementi seguenti:

  • La variabile di ambiente ASPNETCORE_URLS.
  • L'argomento della riga di comando --urls.
  • La chiave di configurazione dell'host urls.
  • Il metodo di estensione UseUrls.

Il valore specificato usando i metodi seguenti può essere uno o più endpoint HTTP e HTTPS (HTTPS se è disponibile un certificato predefinito). Configurare il valore come un elenco delimitato da punto e virgola (ad esempio, "Urls": "http://localhost:8000;http://localhost:8001").

Per altre informazioni su questi approcci, vedere URL del server e Override della configurazione.

Viene creato un certificato di sviluppo nei casi seguenti:

Alcuni browser richiedono l'autorizzazione esplicita per considerare attendibile il certificato di sviluppo locale.

I modelli di progetto configurano le app da eseguire su HTTPS per impostazione predefinita e includono il supporto di reindirizzamento HTTPS e HSTS.

Chiamare Listen o ListenUnixSocket metodi su KestrelServerOptions per configurare i prefissi e le porte URL per Kestrel.

Anche UseUrls, l'argomento della riga di comando --urls, la chiave di configurazione dell'host urls e la variabile di ambiente ASPNETCORE_URLS funzionano, ma con le limitazioni indicate più avanti nella sezione (deve essere disponibile un certificato predefinito per la configurazione dell'endopoint HTTPS).

KestrelServerOptions configurazione:

ConfigureEndpointDefaults(Action<ListenOptions>)

Specifica un elemento di configurazione Action da eseguire per ogni endpoint specificato. Se si chiama ConfigureEndpointDefaults più volte, gli elementi Action precedenti vengono sostituiti con l'ultimo elemento Action specificato.

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

Nota

Gli endpoint creati chiamando prima di chiamare ConfigureEndpointDefaultsListen non avranno le impostazioni predefinite applicate.

ConfigureHttpsDefaults(Action<HttpsConnectionAdapterOptions>)

Specifica un elemento di configurazione Action da eseguire per ogni endpoint HTTPS. Se si chiama ConfigureHttpsDefaults più volte, gli elementi Action precedenti vengono sostituiti con l'ultimo elemento Action specificato.

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

Nota

Gli endpoint creati chiamando prima di chiamare ConfigureHttpsDefaultsListen non avranno le impostazioni predefinite applicate.

Configure(IConfiguration)

Crea un caricatore di configurazione per la configurazione Kestrel che accetta un IConfiguration input. La configurazione deve essere con ambito nella sezione di configurazione per Kestrel.

ListenOptions.UseHttps

Configurare Kestrel per usare HTTPS.

Estensioni ListenOptions.UseHttps:

  • UseHttps: configurare Kestrel per usare HTTPS con il certificato predefinito. Genera un'eccezione se non è stato configurato alcun certificato predefinito.
  • 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)

Parametri ListenOptions.UseHttps:

  • filename è il percorso e il nome file di un file di certificato, relativo alla directory che contiene i file di contenuto dell'app.
  • password è la password richiesta per accedere ai dati del certificato X.509.
  • configureOptions è un elemento Action per configurare HttpsConnectionAdapterOptions. Restituisce ListenOptions.
  • storeName è l'archivio certificati da cui caricare il certificato.
  • subject è il nome dell'oggetto del certificato.
  • allowInvalid indica se devono essere considerati i certificati non validi, come ad esempio i certificati autofirmati.
  • location è il percorso dell'archivio da cui caricare il certificato.
  • serverCertificate è il certificato X.509.

Nell'ambiente di produzione, HTTPS deve essere configurato in modo esplicito. Come minimo, è necessario specificare un certificato predefinito.

Configurazioni supportate descritte in seguito:

  • Nessuna configurazione
  • Sostituire il certificato predefinito della configurazione
  • Modificare le impostazioni predefinite nel codice

Nessuna configurazione

Kestrel listens on http://localhost:5000 e https://localhost:5001 (se è disponibile un certificato predefinito).

Sostituire il certificato predefinito della configurazione

CreateDefaultBuilder chiamate Configure(context.Configuration.GetSection("Kestrel")) per impostazione predefinita per caricare Kestrel la configurazione. Lo schema di configurazione delle impostazioni dell'app HTTPS predefinito è disponibile per Kestrel. Configurare più endpoint, inclusi gli URL e i certificati da usare, da un file su disco o da un archivio certificati.

Nell'esempio seguente appsettings.json :

  • Impostare AllowInvalid su true per consentire l'uso di certificati non validi, come ad esempio i certificati autofirmati.
  • Tutti gli endpoint HTTPS che non specificano un certificato (HttpsDefaultCert nell'esempio che segue) usano il certificato definito in Certificates>Default o il certificato di sviluppo.
{
  "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>"
      }
    }
  }
}

Un'alternativa all'uso di Path e Password per qualsiasi nodo del certificato consiste nello specificare il certificato usando i campi dell'archivio certificati. Ad esempio, è possibile specificare il certificatopredefinitocertificati> come:

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

Note di schema:

  • I nomi degli endpoint non applicano la distinzione tra maiuscole e minuscole. Ad esempio, sono validi sia HTTPS che Https.
  • Il parametro Url è obbligatorio per ogni endpoint. Il formato per questo parametro è uguale a quello del parametro di configurazione di primo livello Urls, con la differenza che si limita a un singolo valore.
  • Questi endpoint sostituiscono quelli definiti nella configurazione di primo livello Urls, non vi si aggiungono. Gli endpoint definiti nel codice tramite Listen si aggiungono agli endpoint definiti nella sezione di configurazione.
  • La sezione Certificate è facoltativa. Se la sezione Certificate non è specificata, vengono usati i valori predefiniti definiti negli scenari precedenti. Se non è disponibile alcun valore predefinito, il server genera un'eccezione e non viene avviato.
  • La Certificate sezione supporta entrambi i certificatiPath-Password e Subject-Store.
  • In questo modo è possibile definire un numero qualsiasi di endpoint, purché non provochino conflitti di porte.
  • options.Configure(context.Configuration.GetSection("{SECTION}")) restituisce un oggetto KestrelConfigurationLoader con un metodo .Endpoint(string name, listenOptions => { }) che può essere usato per integrare le impostazioni dell'endpoint configurato:
webBuilder.UseKestrel((context, serverOptions) =>
{
    serverOptions.Configure(context.Configuration.GetSection("Kestrel"))
        .Endpoint("HTTPS", listenOptions =>
        {
            listenOptions.HttpsOptions.SslProtocols = SslProtocols.Tls12;
        });
});

KestrelServerOptions.ConfigurationLoader è possibile accedere direttamente per continuare l'iterazione sul caricatore esistente, ad esempio quello fornito da CreateDefaultBuilder.

  • La sezione di configurazione per ogni endpoint è disponibile nelle opzioni del Endpoint metodo in modo che le impostazioni personalizzate possano essere lette.
  • È possibile caricare più configurazioni chiamando ancora options.Configure(context.Configuration.GetSection("{SECTION}")) con un'altra sezione. Viene usata solo l'ultima configurazione, a meno che Load sia stato chiamato esplicitamente in istanze precedenti. Il metapacchetto non chiama Load in modo che la sezione di configurazione predefinita venga sostituita.
  • KestrelConfigurationLoader riflette la famiglia di API Listen da KestrelServerOptions all'overload di Endpoint, in modo che gli endpoint di codice e di configurazione possano essere configurati nella stessa posizione. Questi overload non usano nomi e usano solo le impostazioni predefinite della configurazione.

Modificare le impostazioni predefinite nel codice

ConfigureEndpointDefaults e ConfigureHttpsDefaults possono essere usati per modificare le impostazioni predefinite per ListenOptions e HttpsConnectionAdapterOptions, inclusa l'esecuzione dell'override del certificato predefinito specificato nello scenario precedente. ConfigureEndpointDefaults e ConfigureHttpsDefaults devono essere chiamati prima che venga configurato qualsiasi endpoint.

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

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

Kestrel supporto per SNI

L'Indicazione nome server (SNI) può essere usata per ospitare più domini sulla stessa porta e indirizzo IP. Perché SNI funzioni è necessario che il client invii al server il nome host per la sessione protetta durante l'handshake TLS in modo che il server possa specificare il certificato corretto. Il client usa il certificato specificato per la comunicazione crittografata con il server durante la sessione protetta che segue l'handshake TLS.

Kestrel supporta SNI tramite il ServerCertificateSelector callback. Il callback viene richiamato una volta per ogni connessione per consentire all'app di controllare il nome host e selezionare il certificato appropriato.

Il supporto SNI richiede:

  • Esecuzione nel framework di destinazione netcoreapp2.1 o versione successiva. In net461 o versioni successive, il callback viene richiamato, ma è name sempre null. L'elemento name è null anche se il client non specifica il parametro del nome host nell'handshake TLS.
  • Tutti i siti Web vengono eseguiti nella stessa Kestrel istanza. Kestrel non supporta la condivisione di un indirizzo IP e di una porta tra più istanze senza un proxy inverso.
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;
            };
        });
    });
});

Registrazione delle connessioni

Chiamata UseConnectionLogging per generare log a livello di debug per la comunicazione a livello di byte in una connessione. La registrazione delle connessioni è utile per la risoluzione dei problemi di comunicazione di basso livello, ad esempio durante la crittografia TLS e dietro i proxy. Se UseConnectionLogging viene inserito prima UseHttpsdi , viene registrato il traffico crittografato. Se UseConnectionLogging viene inserito dopo UseHttps, viene registrato il traffico decrittografato.

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

Associazione a un socket TCP

Il metodo Listen esegue l'associazione a un socket TCP e un'espressione lambda per le opzioni consente di configurare un certificato 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>();
        });

L'esempio configura HTTPS per un endpoint con ListenOptions. Usare la stessa API per configurare altre Kestrel impostazioni per endpoint specifici.

In Windows è possibile creare certificati autofirmato usando il New-SelfSignedCertificate cmdlet di PowerShell. Per un esempio non supportato, vedere UpdateIISExpressSSLForChrome.ps1.

In macOS, Linux e Windows, i certificati possono essere creati con OpenSSL.

Associazione a un socket Unix

Impostare l'ascolto su un socket Unix con ListenUnixSocket per migliorare le prestazioni con Nginx, come visualizzato nell'esempio seguente:

webBuilder.ConfigureKestrel(serverOptions =>
{
    serverOptions.ListenUnixSocket("/tmp/kestrel-test.sock");
    serverOptions.ListenUnixSocket("/tmp/kestrel-test.sock", 
        listenOptions =>
        {
            listenOptions.UseHttps("testCert.pfx", 
                "testpassword");
        });
})
  • Nel file di configurazione di Nginx impostare la server>proxy_pass>locationvoce su .http://unix:/tmp/{KESTREL SOCKET}:/; {KESTREL SOCKET} è il nome del socket fornito a ListenUnixSocket , kestrel-test.sock ad esempio nell'esempio precedente.
  • Assicurarsi che il socket sia scrivibile da Nginx (ad esempio, chmod go+w /tmp/kestrel-test.sock).

Porta 0

Quando viene specificato il numero 0 di porta, Kestrel associa dinamicamente a una porta disponibile. L'esempio seguente illustra come determinare la porta Kestrel effettivamente associata in fase di esecuzione:

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

Quando si esegue l'app, l'output della finestra della console indica la porta dinamica in cui l'app può essere raggiunta:

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

Limitazioni

Configurare gli endpoint con i metodi seguenti:

  • UseUrls
  • L'argomento della riga di comando --urls
  • La chiave di configurazione dell'host urls
  • La variabile di ambiente ASPNETCORE_URLS

Questi metodi sono utili per fare in modo che il codice funzioni con server diversi da Kestrel. Tenere presenti, tuttavia, le limitazioni seguenti:

  • HTTPS non può essere usato con questi approcci, a meno che non venga specificato un certificato predefinito nella configurazione dell'endpoint HTTPS (ad esempio, usando la configurazione KestrelServerOptions o un file di configurazione come illustrato in precedenza in questo argomento).
  • Quando sia l'approccio Listen che l'approccio UseUrls vengono usati contemporaneamente, gli endpoint Listen eseguono l'override degli endpoint UseUrls.

Configurazione dell'endpoint IIS

Quando si usa IIS, le associazioni di URL per le associazioni di override di IIS vengono impostate mediante Listen o UseUrls. Per altre informazioni, vedere l'articolo Introduzione al modulo ASP.NET Core.

ListenOptions.Protocols

La proprietà Protocols stabilisce i protocolli HTTP (HttpProtocols) abilitati in un endpoint di connessione o per il server. Assegnare un valore alla proprietà Protocols dall'enumerazione HttpProtocols.

Valore di enumerazione HttpProtocols Protocollo di connessione consentito
Http1 Solo HTTP/1.1. Può essere usato con o senza TLS.
Http2 Solo HTTP/2. Può essere usato senza TLS solo se il client supporta una modalità di conoscenza pregressa.
Http1AndHttp2 HTTP/1.1 e HTTP/2. HTTP/2 richiede al client di selezionare HTTP/2 nell'handshake TLS Application-Layer Protocol Negotiation (ALPN ); in caso contrario, per impostazione predefinita la connessione è HTTP/1.1.

Il valore predefinito ListenOptions.Protocols per qualsiasi endpoint è HttpProtocols.Http1AndHttp2.

Restrizioni relative a TLS per HTTP/2:

  • TLS versione 1.2 o successiva
  • Rinegoziazione disabilitata
  • Compressione disabilitata
  • Dimensioni minime per lo scambio di chiavi temporanee:
    • Curva ellittica Diffie-Hellman (ECDHE) [RFC4492]: minimo 224 bit
    • Campo finito Diffie-Hellman (DHE) [TLS12]: minimo di 2048 bit
  • Suite di crittografia non vietata.

TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 [TLS-ECDHE] con la curva ellittica P-256 [FIPS186] è supportata per impostazione predefinita.

Nell'esempio seguente sono consentite connessioni HTTP/1.1 e HTTP/2 sulla porta 8000. Le connessioni sono protette da TLS con un certificato incluso:

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

Usare il middleware di connessione per filtrare gli handshake TLS in base alla connessione per crittografie specifiche, se necessario.

L'esempio seguente genera un'eccezione NotSupportedException per qualsiasi algoritmo di crittografia non supportato dall'app. In alternativa, definire e confrontare ITlsHandshakeFeature.CipherAlgorithm con un elenco di pacchetti di crittografia accettabili.

Non viene usata alcuna crittografia con un algoritmo di crittografia 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();
            });
        }
    }
}

Il filtro delle connessioni può essere configurato anche tramite un'espressione IConnectionBuilder 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();
        });
    });
});

In Linux CipherSuitesPolicy è possibile usare per filtrare gli handshake TLS in base alla connessione:

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

Impostare il protocollo dalla configurazione

CreateDefaultBuilder chiama serverOptions.Configure(context.Configuration.GetSection("Kestrel")) per impostazione predefinita per caricare Kestrel la configurazione.

L'esempio seguente appsettings.json stabilisce HTTP/1.1 come protocollo di connessione predefinito per tutti gli endpoint:

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

L'esempio seguente appsettings.json stabilisce il protocollo di connessione HTTP/1.1 per un endpoint specifico:

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

I protocolli specificati nei valori di override del codice sono impostati dalla configurazione.

Prefissi URL

Se si usa UseUrls, l'argomento della riga di comando --urls, la chiave di configurazione dell'host urls o la variabile di ambiente ASPNETCORE_URLS, i prefissi URL possono avere uno dei formati seguenti.

Sono validi solo i prefissi URL HTTP. Kestrel non supporta HTTPS durante la configurazione delle associazioni URL tramite UseUrls.

  • Indirizzo IPv4 con numero di porta

    http://65.55.39.10:80/
    

    0.0.0.0 è un caso speciale che esegue l'associazione a tutti gli indirizzi IPv4.

  • Indirizzo IPv6 con numero di porta

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

    [::] è l'equivalente IPv6 di 0.0.0.0 per IPv4.

  • Nome host con numero di porta

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

    I nomi host, * e + non sono casi particolari. Tutto ciò che non è riconosciuto come un indirizzo IP o un elemento localhost valido esegue l'associazione a tutti gli IP IPv4 e IPv6. Per associare nomi host diversi ad app ASP.NET Core diverse sulla stessa porta, usare HTTP.sys o un server proxy inverso come IIS, Nginx o Apache.

    Avviso

    L'hosting in una configurazione proxy inverso richiede la configurazione middleware delle intestazioni inoltrate.

  • Nome host localhost con numero di porta o IP di loopback con numero di porta

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

    Quando localhost viene specificato, Kestrel tenta di eseguire l'associazione a interfacce di loopback IPv4 e IPv6. Se la porta richiesta è in uso da un altro servizio in un'interfaccia di loopback, Kestrel non viene avviata. Se un'interfaccia di loopback non è disponibile per qualsiasi altro motivo (più comunemente perché IPv6 non è supportata), Kestrel registra un avviso.

Filtro host

Sebbene Kestrel supporti la configurazione in base ai prefissi, ad esempio http://example.com:5000, Kestrel ignora in gran parte il nome host. L'host localhost è un caso speciale usato per l'associazione agli indirizzi di loopback. Qualsiasi host che non sia un indirizzo IP esplicito esegue l'associazione a tutti gli indirizzi IP pubblici. Le intestazioni Host non vengono convalidate.

Come soluzione alternativa, usare il middleware di filtro host. Il middleware di filtro host viene fornito dal pacchetto Microsoft.AspNetCore.HostFiltering, fornito in modo implicito per le app ASP.NET Core. Il middleware viene aggiunto da CreateDefaultBuilder, che chiama 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>();
}

Per impostazione predefinita, il middleware di filtro host è disabilitato per impostazione predefinita. Per abilitare il middleware, definire una AllowedHosts chiave in/appsettings.jsonappsettings.{Environment}.json . Il valore è un elenco con valori delimitati da punto e virgola di nomi host senza numeri di porta:

appsettings.json:

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

Nota

Il middleware delle intestazioni inoltrate include anche un'opzione AllowedHosts. Il middleware di intestazioni inoltrate e il middleware di filtro host hanno funzionalità simili per diversi scenari. L'impostazione di AllowedHosts con il middleware delle intestazioni inoltrate è appropriato se l'intestazione Host non viene mantenuta durante l'inoltro delle richieste con un server proxy inverso o il bilanciamento del carico. L'impostazione AllowedHosts con il middleware di filtro host è appropriata quando Kestrel viene usata come server perimetrale pubblico o quando l'intestazione Host viene inoltrata direttamente.

Per altre informazioni sul middleware di intestazioni inoltrate, vedere Configurare ASP.NET Core per l'uso di server proxy e servizi di bilanciamento del carico.

Configurazione del trasporto Libuv

Per i progetti che richiedono l'uso di Libuv (UseLibuv):

  • Aggiungere una dipendenza per il Microsoft.AspNetCore.Server.Kestrel.Transport.Libuv pacchetto al file di progetto dell'app:

    <PackageReference Include="Microsoft.AspNetCore.Server.Kestrel.Transport.Libuv"
                      Version="{VERSION}" />
    
  • Chiamare UseLibuv su 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>();
                });
    }
    

Scaricamento delle richieste HTTP/1.1

L'apertura delle connessioni HTTP richiede molto tempo. Per HTTPS, è anche intensivo di risorse. Di conseguenza, Kestrel tenta di riutilizzare le connessioni per il protocollo HTTP/1.1. Un corpo della richiesta deve essere completamente utilizzato per consentire il riutilizzo della connessione. L'app non utilizza sempre il corpo della richiesta, ad esempio richieste POST in cui il server restituisce un reindirizzamento o una risposta 404. POSTNel caso di reindirizzamento:

  • Il client potrebbe già aver inviato parte dei POST dati.
  • Il server scrive la risposta 301.
  • La connessione non può essere usata per una nuova richiesta finché i POST dati del corpo della richiesta precedente non sono stati letti completamente.
  • Kestrel tenta di svuotare il corpo della richiesta. Svuotare il corpo della richiesta significa leggere ed eliminare i dati senza elaborarlo.

Il processo di svuotamento rende un compromesso tra consentire il riutilizzo della connessione e il tempo necessario per svuotare i dati rimanenti:

  • Lo svuotamento ha un timeout di cinque secondi, che non è configurabile.
  • Se tutti i dati specificati dall'intestazione Content-Length o Transfer-Encoding non sono stati letti prima del timeout, la connessione viene chiusa.

A volte è possibile terminare immediatamente la richiesta, prima o dopo aver scritto la risposta. Ad esempio, i client possono avere limiti restrittivi per i dati, pertanto la limitazione dei dati caricati potrebbe essere una priorità. In questi casi per terminare una richiesta, chiamare HttpContext.Abort da un controller, Razor una pagina o un middleware.

Ci sono avvisi per chiamare Abort:

  • La creazione di nuove connessioni può essere lenta e costosa.
  • Non è garantito che il client abbia letto la risposta prima della chiusura della connessione.
  • La chiamata Abort deve essere rara e riservata ai casi di errore gravi, non errori comuni.
    • Chiamare Abort solo quando deve essere risolto un problema specifico. Ad esempio, chiamare Abort se i client dannosi tentano POST di dati o quando si verifica un bug nel codice client che causa richieste di grandi dimensioni o numerose richieste.
    • Non chiamare Abort per situazioni di errore comuni, ad esempio HTTP 404 (Non trovato).

La chiamata a HttpResponse.CompleteAsync prima di chiamare Abort garantisce che il server abbia completato la scrittura della risposta. Tuttavia, il comportamento del client non è prevedibile e potrebbe non leggere la risposta prima che la connessione venga interrotta.

Questo processo è diverso per HTTP/2 perché il protocollo supporta l'interruzione dei singoli flussi di richiesta senza chiudere la connessione. Il cinque secondo timeout di scarico non si applica. Se sono presenti dati del corpo della richiesta non letti dopo aver completato una risposta, il server invia un frame HTTP/2 RST. I frame di dati del corpo della richiesta aggiuntivi vengono ignorati.

Se possibile, è preferibile che i client usino l'intestazione Di richiesta prevista: 100-continue request e attendere che il server risponda prima di iniziare a inviare il corpo della richiesta. Ciò consente al client di esaminare la risposta e di interrompere prima di inviare dati non autorizzati.

Risorse aggiuntive