Condividi tramite


Kestrel server Web in ASP.NET Core

Nota

Questa non è la versione più recente di questo articolo. Per la versione corrente, vedere la versione .NET 8 di questo articolo.

Avviso

Questa versione di ASP.NET Core non è più supportata. Per altre informazioni, vedere Criteri di supporto di .NET e .NET Core. Per la versione corrente, vedere la versione .NET 8 di questo articolo.

Importante

Queste informazioni si riferiscono a un prodotto non definitive che può essere modificato in modo sostanziale prima che venga rilasciato commercialmente. Microsoft non riconosce alcuna garanzia, espressa o implicita, in merito alle informazioni qui fornite.

Per la versione corrente, vedere la versione .NET 8 di questo articolo.

Di Tom Dykstra, Chris Ross e Stephen Halter

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

KestrelLe funzionalità di includono:

  • Multipiattaforma:Kestrel è un server Web multipiattaforma che viene eseguito in Windows, Linux e macOS.
  • Prestazioni elevate:Kestrel è ottimizzato per gestire un numero elevato di connessioni simultanee in modo efficiente.
  • Lightweight: ottimizzato per l'esecuzione in ambienti con vincoli di risorse, ad esempio contenitori e dispositivi perimetrali.
  • Protezione avanzata:Kestrel supporta HTTPS e viene avanzata contro le vulnerabilità del server Web.
  • Supporto di protocolli wide:Kestrel supporta protocolli Web comuni, tra cui:
  • Integrazione con ASP.NET Core: integrazione facile con altri componenti ASP.NET Core, ad esempio la pipeline middleware, l'inserimento delle dipendenze e il sistema di configurazione.
  • Carichi di lavoro flessibili: Kestrel supporta molti carichi di lavoro:
    • ASP.NET framework dell'app, ad esempio API minime, MVC, Razor pagine, SignalR, Blazore gRPC.
    • Creazione di un proxy inverso con YARP.
  • Estendibilità: personalizzare Kestrel tramite configurazioni, middleware e trasporti personalizzati.
  • Diagnostica delle prestazioni:Kestrel offre funzionalità di diagnostica delle prestazioni predefinite, ad esempio la registrazione e le metriche.

Operazioni preliminari

ASP.NET modelli di progetto core usati Kestrel per impostazione predefinita quando non sono ospitati con IIS. Nel modello generato dal Program.csmodello 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 di e WebApplicationBuilder, vedere Informazioni di riferimento rapido sulle API minime.

Certificati client facoltativi

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

Comportamento con debugger collegato

I timeout e i limiti di frequenza seguenti non vengono applicati quando un debugger è collegato a un Kestrel processo:

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 tutte 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.

Operazioni preliminari

ASP.NET modelli di progetto core usati Kestrel per impostazione predefinita quando non sono ospitati con IIS. Nel modello generato dal Program.csmodello 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 di e WebApplicationBuilder, vedere Informazioni di riferimento rapido sulle API minime.

Certificati client facoltativi

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

Comportamento con debugger collegato

I timeout e i limiti di frequenza seguenti non vengono applicati quando un debugger è collegato a un Kestrel processo:

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 tutte 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)

Operazioni preliminari

ASP.NET modelli di progetto core usati Kestrel per impostazione predefinita quando non sono ospitati con IIS. In Program.csil 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 impostazioni del generatore predefinito di 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 tutte 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 versione successiva*
    • 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 restituisce 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 le richieste HTTP dalla rete e le inoltra a Kestrel. Alcuni esempi di 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 del proxy inverso:

Kestrel comunica indirettamente con Internet tramite 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 stessa 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 in grado di condividere le porte ha la possibilità di inoltrare le richieste a Kestrel su 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.
  • Fornire un ulteriore livello di configurazione e difesa della sicurezza informatica avanzata.
  • 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 del proxy inverso richiede la configurazione del middleware delle intestazioni inoltrate.

Kestrel nelle app ASP.NET Core

ASP.NET modelli di progetto core usati Kestrel per impostazione predefinita. In Program.csil 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 impostazioni del generatore predefinito di 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>();
        });

Opzioni Kestrel

Il Kestrel server Web dispone di 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 vengono configurate nel codice C#. Kestrel le opzioni possono essere impostate anche 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 configurazione inserita sia assegnata alla Configuration proprietà .

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

      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 durante la compilazione Kestrel dell'host:

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

    // 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 per 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 out-of-process dietro il modulo core ASP.NET, 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 velocità specificata in byte al secondo. Se la frequenza scende al di sotto del valore minimo, si verifica il timeout della connessione. Il periodo di tolleranza è l'intervallo di tempo che Kestrel consente al client di aumentare la velocità di invio fino al minimo. La tariffa non viene controllata 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.

Di seguito è riportato 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 le dimensioni massime consentite 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, tranne che vengono 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");
}

Nell'esempio precedente di codice:

  • SupportsTrailers assicura che i trailer siano supportati per la risposta.
  • DeclareTrailer aggiunge il nome del trailer specificato all'intestazione della Trailer 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.

Reimposta

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, vedere la sezione relativa al 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 bloccanti può causare la fame del pool di thread, che rende l'app non risponde. Abilitare AllowSynchronousIO solo quando si usa una libreria che non supporta l'I/O asincrona.

L'esempio seguente abilita l'I/O sincrono:

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

Per informazioni su altre Kestrel opzioni e limiti, vedere:

Configurazione 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 la concessione esplicita dell'autorizzazione 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 reindirizzamento HTTPS e il supporto HSTS.

Chiamare Listen o ListenUnixSocket metodi su KestrelServerOptions per configurare i prefissi URL e le porte 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 Listen prima della chiamata ConfigureEndpointDefaults 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 Listen prima della chiamata ConfigureHttpsDefaults non avranno le impostazioni predefinite applicate.

Configure(IConfiguration)

Crea un caricatore di configurazione per la configurazione Kestrel che accetta come IConfiguration input. La configurazione deve avere come ambito la sezione di configurazione per Kestrel.

ListenOptions.UseHttps

Configurare Kestrel per l'uso di HTTPS.

Estensioni ListenOptions.UseHttps:

  • UseHttps: configurare Kestrel per l'uso di 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 è in ascolto su http://localhost:5000 e https://localhost:5001 (se è disponibile un certificato predefinito).

Sostituire il certificato predefinito della configurazione

CreateDefaultBuilder chiama Configure(context.Configuration.GetSection("Kestrel")) per impostazione predefinita la configurazione di caricamento Kestrel . Uno schema di configurazione predefinito delle impostazioni dell'app HTTPS è 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, il certificato specificato mediante Certificates>Default può essere specificato 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 sia i certificati Path-Password che 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 nel 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 netcoreapp2.1 di destinazione 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 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 proxy. Se UseConnectionLogging viene posizionato prima UseHttpsdi , viene registrato il traffico crittografato. Se UseConnectionLogging viene inserito dopo UseHttps, il traffico decrittografato viene registrato.

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 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

Limiti

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 rendere il codice funzionante 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 dello 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 NotSupportedException un'eccezione per qualsiasi algoritmo di crittografia non supportato dall'app. In alternativa, definire e confrontare ITlsHandshakeFeature.CipherAlgorithm con un elenco di suite di crittografia accettabili.

Nessuna crittografia viene usata 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 la configurazione di caricamento Kestrel .

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 del proxy inverso richiede la configurazione del 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 entrambe le interfacce di loopback IPv4 e IPv6. Se la porta richiesta è in uso da un altro servizio in una delle due interfacce di loopback, Kestrel l'avvio non riesce. Se una delle due interfacce di loopback non è disponibile per qualsiasi altro motivo (in genere perché IPv6 non è supportato), Kestrel registra un avviso.

Filtro host

Sebbene Kestrel supporti la configurazione basata su prefissi, ad http://example.com:5000esempio , 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>();
                });
    }
    

Svuotamento delle richieste HTTP/1.1

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

  • È possibile che il client abbia già 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 elaborarli.

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.

In alcuni casi può essere necessario terminare la richiesta immediatamente, prima o dopo la scrittura della risposta. Ad esempio, i client possono avere limiti di dati restrittivi, 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 avvertenze 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 a casi di errore gravi, non errori comuni.
    • Chiamare Abort solo quando è necessario risolvere un problema specifico. Ad esempio, chiamare Abort se i client malintenzionati tentano di dati POST o quando si verifica un bug nel codice client che causa richieste di grandi dimensioni o numerose.
    • Non chiamare Abort per situazioni di errore comuni, ad esempio HTTP 404 (Non trovato).

La chiamata a HttpResponse.CompleteAsync prima della chiamata 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 timeout di 5 secondi di svuotamento non si applica. Se sono presenti dati sul 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 della richiesta Expect: 100-continue e attendere che il server risponda prima di iniziare a inviare il corpo della richiesta. Ciò consente al client di esaminare la risposta e interrompere prima di inviare dati non necessario.

Risorse aggiuntive