Configurare gli endpoint per il server Web ASP.NET Core Kestrel

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.

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.

Kestrel gli endpoint forniscono l'infrastruttura per l'ascolto delle richieste in ingresso e il routing al middleware appropriato. La combinazione di un indirizzo e di un protocollo definisce un endpoint.

  • L'indirizzo specifica l'interfaccia di rete su cui il server è in ascolto per le richieste in ingresso, ad esempio una porta TCP.
  • Il protocollo specifica la comunicazione tra il client e il server, ad esempio HTTP/1.1, HTTP/2 o HTTP/3.
  • Un endpoint può essere protetto usando lo schema o UseHttps il https metodo URL.

Gli endpoint possono essere configurati usando URL, JSON in appsettings.jsone codice. Questo articolo illustra come usare ogni opzione per configurare un endpoint:

Endpoint predefinito

I nuovi progetti core ASP.NET sono configurati per l'associazione a una porta HTTP casuale tra 5000-5300 e una porta HTTPS casuale compresa tra 7000 e 7300. Le porte selezionate vengono archiviate nel file generato Properties/launchSettings.json e possono essere modificate dallo sviluppatore. Il launchSetting.json file viene usato solo nello sviluppo locale.

Se non è disponibile alcuna configurazione dell'endpoint, Kestrel viene associato a http://localhost:5000.

Configurare gli endpoint

Kestrel gli endpoint sono in ascolto delle connessioni in ingresso. Quando viene creato un endpoint, deve essere configurato con l'indirizzo a cui sarà in ascolto. In genere, si tratta di un indirizzo TCP e di un numero di porta.

Sono disponibili diverse opzioni per la configurazione degli endpoint:

Configurare gli endpoint con URL

Le sezioni seguenti illustrano come configurare gli endpoint usando :

  • 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.
  • Proprietà WebApplication.Urls.

Formati URL

Gli URL indicano gli indirizzi IP o host con porte e protocolli su cui il server deve rimanere in ascolto. La porta può essere omessa se è l'impostazione predefinita per il protocollo (in genere 80 e 443). Gli URL possono essere in uno dei formati seguenti.

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

  • Host con caratteri jolly con numero di porta

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

    Qualsiasi elemento non riconosciuto come indirizzo IP valido o localhost viene considerato come un carattere jolly che si associa a tutti gli indirizzi IPv4 e IPv6. Alcune persone amano usare * o + per essere più esplicite. Per associare nomi host diversi a app ASP.NET Core nella stessa porta, usare HTTP.sys o un server proxy inverso.

    Gli esempi di server proxy inverso includono IIS, YARP, Nginx e Apache.

  • Nome localhost host 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.

È possibile specificare più prefissi URL usando un delimitatore punto e virgola (;):

http://*:5000;http://localhost:5001;https://hostname:5002

Per altre informazioni, vedere Eseguire l'override della configurazione.

Prefissi URL HTTPS

I prefissi URL HTTPS possono essere usati per definire gli endpoint solo se viene fornito un certificato predefinito nella configurazione dell'endpoint HTTPS. Ad esempio, usare KestrelServerOptions la configurazione o un file di configurazione, come illustrato più avanti in questo articolo.

Per altre informazioni, vedere Configurare HTTPS.

Specificare solo le porte

Le app e i contenitori vengono spesso assegnati solo a una porta in ascolto, ad esempio la porta 80, senza vincoli aggiuntivi come host o percorso. HTTP_PORTS e HTTPS_PORTS sono chiavi di configurazione che specificano le porte di ascolto per i Kestrel server e HTTP.sys. Queste chiavi possono essere specificate come variabili di ambiente definite con i DOTNET_ prefissi o ASPNETCORE_ specificate direttamente tramite qualsiasi altro input di configurazione, ad esempio appsettings.json. Ogni è un elenco delimitato da punto e virgola di valori di porta, come illustrato nell'esempio seguente:

ASPNETCORE_HTTP_PORTS=80;8080
ASPNETCORE_HTTPS_PORTS=443;8081

L'esempio precedente è abbreviato per la configurazione seguente, che specifica lo schema (HTTP o HTTPS) e qualsiasi host o IP.

ASPNETCORE_URLS=http://*:80/;http://*:8080/;https://*:443/;https://*:8081/

Le chiavi di configurazione HTTP_PORTS e HTTPS_PORTS sono priorità più bassa e vengono sostituite da URL o valori forniti direttamente nel codice. I certificati devono comunque essere configurati separatamente tramite meccanismi specifici del server per HTTPS.

Configurare gli endpoint in appsettings.json

Kestrel può caricare gli endpoint da un'istanza IConfiguration di . Per impostazione predefinita, Kestrel la Kestrel configurazione viene caricata dalla sezione e gli endpoint sono configurati in Kestrel:Endpoints:

{
  "Kestrel": {
    "Endpoints": {
      "MyHttpEndpoint": {
        "Url": "http://localhost:8080"
      }
    }
  }
}

L'esempio precedente:

  • appsettings.json Usa come origine di configurazione. È tuttavia possibile usare qualsiasi IConfiguration origine.
  • Aggiunge un endpoint denominato MyHttpEndpoint sulla porta 8080.

Per altre informazioni sulla configurazione degli endpoint con JSON, vedere le sezioni successive di questo articolo che illustrano la configurazione di HTTPS e la configurazione di protocolli HTTP in appsettings.json.

Ricaricare gli endpoint dalla configurazione

Ricaricare la configurazione dell'endpoint quando l'origine di configurazione cambia è abilitata per impostazione predefinita. Può essere disabilitata usando KestrelServerOptions.Configure(IConfiguration, Boolean).

Se viene segnalata una modifica, vengono eseguiti i passaggi seguenti:

  • La nuova configurazione viene confrontata con quella precedente e qualsiasi endpoint senza modifiche alla configurazione non viene modificato.
  • Agli endpoint rimossi o modificati vengono assegnati 5 secondi per completare le richieste di elaborazione e arrestare.
  • Vengono avviati endpoint nuovi o modificati.

I client che si connettono a un endpoint modificato possono essere disconnessi o rifiutati durante il riavvio dell'endpoint.

ConfigurationLoader

KestrelServerOptions.Configure restituisce KestrelConfigurationLoader. Metodo del Endpoint(String, Action<EndpointConfiguration>) caricatore che può essere usato per integrare le impostazioni di un endpoint configurato:

var builder = WebApplication.CreateBuilder(args);

builder.WebHost.ConfigureKestrel((context, serverOptions) =>
{
    var kestrelSection = context.Configuration.GetSection("Kestrel");

    serverOptions.Configure(kestrelSection)
        .Endpoint("HTTPS", listenOptions =>
        {
            // ...
        });
});

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

  • La sezione di configurazione per ogni endpoint è disponibile nelle opzioni nel Endpoint metodo in modo che le impostazioni personalizzate possano essere lette.
  • KestrelServerOptions.Configure(IConfiguration) può essere chiamato più volte, ma viene usata solo l'ultima configurazione, a meno che non Load venga chiamata esplicitamente nelle istanze precedenti. L'host predefinito non chiama Load in modo che la relativa sezione di configurazione predefinita possa essere sostituita.
  • KestrelConfigurationLoader rispecchia la Listen famiglia di API da KestrelServerOptions come Endpoint overload, in modo che gli endpoint di codice e configurazione possano essere configurati nella stessa posizione. Questi overload non usano nomi e usano solo le impostazioni predefinite della configurazione.

Configurare gli endpoint nel codice

KestrelServerOptions fornisce metodi per la configurazione degli endpoint nel codice:

Quando entrambe le Listen API UseUrls e vengono usate contemporaneamente, gli endpoint eseguono l'override Listen degli UseUrls endpoint.

Associazione a un socket TCP

I Listenmetodi , ListenLocalhoste vengono ListenAnyIP associati a un socket TCP:

var builder = WebApplication.CreateBuilder(args);

builder.WebHost.ConfigureKestrel((context, serverOptions) =>
{
    serverOptions.Listen(IPAddress.Loopback, 5000);
    serverOptions.Listen(IPAddress.Loopback, 5001, listenOptions =>
    {
        listenOptions.UseHttps("testCert.pfx", "testPassword");
    });
});

L'esempio precedente:

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:

var builder = WebApplication.CreateBuilder(args);

builder.WebHost.ConfigureKestrel((context, serverOptions) =>
{
    serverOptions.ListenUnixSocket("/tmp/kestrel-test.sock");
});
  • 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).

Configurare le impostazioni predefinite dell'endpoint

ConfigureEndpointDefaults(Action<ListenOptions>) specifica la configurazione eseguita per ogni endpoint specificato. La chiamata ConfigureEndpointDefaults più volte sostituisce la configurazione precedente.

var builder = WebApplication.CreateBuilder(args);

builder.WebHost.ConfigureKestrel(serverOptions =>
{
    serverOptions.ConfigureEndpointDefaults(listenOptions =>
    {
        // ...
    });
});

Nota

Gli endpoint creati chiamando Listen prima della chiamata ConfigureEndpointDefaults non avranno le impostazioni predefinite applicate.

Associazione di porte dinamiche

Quando si specifica il numero 0 di porta, Kestrel associa dinamicamente a una porta disponibile. Nell'esempio seguente viene illustrato come determinare la porta Kestrel associata in fase di esecuzione:

app.Run(async (context) =>
{
    var serverAddressFeature = context.Features.Get<IServerAddressesFeature>();

    if (serverAddressFeature is not null)
    {
        var listenAddresses = string.Join(", ", serverAddressFeature.Addresses);

        // ...
    }
});

L'associazione dinamica di una porta non è disponibile in alcune situazioni:

Configurare l'HTTPS

Kestrel supporta la protezione degli endpoint con HTTPS. I dati inviati tramite HTTPS vengono crittografati usando Transport Layer Security (TLS) per aumentare la sicurezza dei dati trasferiti tra il client e il server.

HTTPS richiede un certificato TLS. Il certificato TLS viene archiviato nel server ed Kestrel è configurato per usarlo. Un'app può usare il certificato di sviluppo HTTPS core ASP.NET in un ambiente di sviluppo locale. Il certificato di sviluppo non è installato in ambienti non di sviluppo. Nell'ambiente di produzione, un certificato TLS deve essere configurato in modo esplicito. Come minimo, è necessario specificare un certificato predefinito.

Il modo in cui è configurato HTTPS e il certificato TLS dipende dalla modalità di configurazione degli endpoint:

Configurare HTTPS in appsettings.json

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.

Qualsiasi endpoint HTTPS che non specifica un certificato (HttpsDefaultCert nell'esempio seguente) esegue il fallback al certificato definito in Certificates:Default o al certificato di sviluppo.

L'esempio seguente è relativo a appsettings.json, ma è possibile usare qualsiasi origine di configurazione:

{
  "Kestrel": {
    "Endpoints": {
      "Http": {
        "Url": "http://localhost:5000"
      },
      "HttpsInlineCertFile": {
        "Url": "https://localhost:5001",
        "Certificate": {
          "Path": "<path to .pfx file>",
          "Password": "$CREDENTIAL_PLACEHOLDER$"
        }
      },
      "HttpsInlineCertAndKeyFile": {
        "Url": "https://localhost:5002",
        "Certificate": {
          "Path": "<path to .pem/.crt file>",
          "KeyPath": "<path to .key file>",
          "Password": "$CREDENTIAL_PLACEHOLDER$"
        }
      },
      "HttpsInlineCertStore": {
        "Url": "https://localhost:5003",
        "Certificate": {
          "Subject": "<subject; required>",
          "Store": "<certificate store; required>",
          "Location": "<location; defaults to CurrentUser>",
          "AllowInvalid": "<true or false; defaults to false>"
        }
      },
      "HttpsDefaultCert": {
        "Url": "https://localhost:5004"
      }
    },
    "Certificates": {
      "Default": {
        "Path": "<path to .pfx file>",
        "Password": "$CREDENTIAL_PLACEHOLDER$"
      }
    }
  }
}

Avviso

Nell'esempio precedente la password del certificato viene archiviata in testo normale in appsettings.json. Il $CREDENTIAL_PLACEHOLDER$ token viene usato come segnaposto per la password del certificato. Per archiviare le password dei certificati in modo sicuro negli ambienti di sviluppo, vedere Proteggere i segreti in fase di sviluppo. Per archiviare le password dei certificati in modo sicuro negli ambienti di produzione, vedere Provider di configurazione di Azure Key Vault. I segreti di sviluppo non devono essere usati per la produzione o il test.

Note sullo schema

  • I nomi degli endpoint non fanno distinzione tra maiuscole e minuscole. Ad esempio, la sintassi di HTTPS and Https sono equivalenti.
  • 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. Vedere i formati di URL in precedenza in questo articolo.
  • Questi endpoint sostituiscono quelli definiti nella configurazione di primo livello Urls anziché aggiungerli. Gli endpoint definiti nel codice tramite Listen si aggiungono agli endpoint definiti nella sezione di configurazione.
  • La sezione Certificate è facoltativa. Se la Certificate sezione non è specificata, vengono usate le impostazioni predefinite definite in Certificates:Default . Se non sono disponibili impostazioni predefinite, viene usato il certificato di sviluppo. Se non sono presenti impostazioni predefinite e il certificato di sviluppo non è presente, il server genera un'eccezione e non viene avviato.
  • La Certificate sezione supporta più origini di certificati.
  • Qualsiasi numero di endpoint può essere definito in Configuration, purché non causi conflitti di porta.

Origini certificato

I nodi certificato possono essere configurati per caricare i certificati da diverse origini:

  • Pathe per caricare i file con estensione Password pfx.
  • Pathe KeyPath per caricare i file con estensione pem.crt/ e .key. Password
  • Subject e Store da caricare dall'archivio certificati.

Ad esempio, il Certificates:Default certificato può essere specificato come:

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

Configurare i certificati client in appsettings.json

ClientCertificateMode viene usato per configurare il comportamento del certificato client.

{
  "Kestrel": {
    "Endpoints": {
      "MyHttpsEndpoint": {
        "Url": "https://localhost:5001",
        "ClientCertificateMode": "AllowCertificate",
        "Certificate": {
          "Path": "<path to .pfx file>",
          "Password": "$CREDENTIAL_PLACEHOLDER$"
        }
      }
    }
  }
}

Avviso

Nell'esempio precedente la password del certificato viene archiviata in testo normale in appsettings.json. Il $CREDENTIAL_PLACEHOLDER$ token viene usato come segnaposto per la password del certificato. Per archiviare le password dei certificati in modo sicuro negli ambienti di sviluppo, vedere Proteggere i segreti in fase di sviluppo. Per archiviare le password dei certificati in modo sicuro negli ambienti di produzione, vedere Provider di configurazione di Azure Key Vault. I segreti di sviluppo non devono essere usati per la produzione o il test.

Il valore predefinito è ClientCertificateMode.NoCertificate, dove Kestrel non richiede o richiede un certificato dal client.

Per altre informazioni, vedere Configurare l'autenticazione del certificato in ASP.NET Core.

Configurare i protocolli SSL/TLS in appsettings.json

I protocolli SSL sono protocolli usati per crittografare e decrittografare il traffico tra due peer, tradizionalmente un client e un server.

{
  "Kestrel": {
    "Endpoints": {
      "MyHttpsEndpoint": {
        "Url": "https://localhost:5001",
        "SslProtocols": ["Tls12", "Tls13"],
        "Certificate": {
          "Path": "<path to .pfx file>",
          "Password": "$CREDENTIAL_PLACEHOLDER$"
        }
      }
    }
  }
}

Avviso

Nell'esempio precedente la password del certificato viene archiviata in testo normale in appsettings.json. Il $CREDENTIAL_PLACEHOLDER$ token viene usato come segnaposto per la password del certificato. Per archiviare le password dei certificati in modo sicuro negli ambienti di sviluppo, vedere Proteggere i segreti in fase di sviluppo. Per archiviare le password dei certificati in modo sicuro negli ambienti di produzione, vedere Provider di configurazione di Azure Key Vault. I segreti di sviluppo non devono essere usati per la produzione o il test.

Il valore predefinito, SslProtocols.None, determina Kestrel l'uso delle impostazioni predefinite del sistema operativo per scegliere il protocollo migliore. A meno che non si disponga di un motivo specifico per selezionare un protocollo, usare l'impostazione predefinita.

Configurare HTTPS nel codice

Quando si usa l'API Listen , il UseHttps metodo di estensione in ListenOptions è disponibile per configurare HTTPS.

var builder = WebApplication.CreateBuilder(args);

builder.WebHost.ConfigureKestrel((context, serverOptions) =>
{
    serverOptions.Listen(IPAddress.Loopback, 5000);
    serverOptions.Listen(IPAddress.Loopback, 5001, listenOptions =>
    {
        listenOptions.UseHttps("testCert.pfx", "testPassword");
    });
});

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.

Per un elenco completo degli UseHttps overload, vedere UseHttps.

Configurare i certificati client nel codice

ClientCertificateMode configura i requisiti del certificato client.

var builder = WebApplication.CreateBuilder(args);

builder.WebHost.ConfigureKestrel(serverOptions =>
{
    serverOptions.ConfigureHttpsDefaults(listenOptions =>
    {
        listenOptions.ClientCertificateMode = ClientCertificateMode.AllowCertificate;
    });
});

Il valore predefinito è NoCertificate, dove Kestrel non richiede o richiede un certificato dal client.

Per altre informazioni, vedere Configurare l'autenticazione del certificato in ASP.NET Core.

Configurare le impostazioni predefinite HTTPS nel codice

ConfigureHttpsDefaults(Action<HttpsConnectionAdapterOptions>) specifica una configurazione Action da eseguire per ogni endpoint HTTPS. La chiamata ConfigureHttpsDefaults più volte sostituisce le istanze precedenti Action con l'ultimo Action specificato.

var builder = WebApplication.CreateBuilder(args);

builder.WebHost.ConfigureKestrel(serverOptions =>
{
    serverOptions.ConfigureHttpsDefaults(listenOptions =>
    {
        // ...
    });
});

Nota

Gli endpoint creati chiamando Listen prima della chiamata ConfigureHttpsDefaults non avranno le impostazioni predefinite applicate.

Configurare i protocolli SSL/TLS nel codice

I protocolli SSL sono protocolli usati per crittografare e decrittografare il traffico tra due peer, tradizionalmente un client e un server.

var builder = WebApplication.CreateBuilder(args);

builder.WebHost.ConfigureKestrel(serverOptions =>
{
    serverOptions.ConfigureHttpsDefaults(listenOptions =>
    {
        listenOptions.SslProtocols = SslProtocols.Tls13;
    });
});

Configurare il filtro dei pacchetti di crittografia TLS nel codice

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

var builder = WebApplication.CreateBuilder(args);

builder.WebHost.ConfigureKestrel((context, 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,
                    // ...
                });
        };
    });
});

Configurare l'indicazione del nome del server

L'Indicazione nome server (SNI) può essere usata per ospitare più domini sulla stessa porta e indirizzo IP. SNI può essere usato per risparmiare risorse servendo più siti da un server.

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.

Tutti i siti Web devono essere eseguiti nella stessa Kestrel istanza. Kestrel non supporta la condivisione di un indirizzo IP e una porta tra più istanze senza un proxy inverso.

SNI può essere configurato in due modi:

  • Configurare un mapping tra i nomi host e le opzioni HTTPS in Configurazione. Ad esempio, JSON nel appsettings.json file.
  • Creare un endpoint nel codice e selezionare un certificato usando il nome host con il ServerCertificateSelector callback.

Configurare SNI in appsettings.json

Kestrel supporta SNI definito nella configurazione. Un endpoint può essere configurato con un Sni oggetto che contiene un mapping tra i nomi host e le opzioni HTTPS. Il nome host della connessione viene confrontato con le opzioni e vengono usate per tale connessione.

La configurazione seguente aggiunge un endpoint denominato MySniEndpoint che usa SNI per selezionare le opzioni HTTPS in base al nome host:

{
  "Kestrel": {
    "Endpoints": {
      "MySniEndpoint": {
        "Url": "https://*",
        "SslProtocols": ["Tls11", "Tls12"],
        "Sni": {
          "a.example.org": {
            "Protocols": "Http1AndHttp2",
            "SslProtocols": ["Tls11", "Tls12", "Tls13"],
            "Certificate": {
              "Subject": "<subject; required>",
              "Store": "<certificate store; required>",
            },
            "ClientCertificateMode" : "NoCertificate"
          },
          "*.example.org": {
            "Certificate": {
              "Path": "<path to .pfx file>",
              "Password": "$CREDENTIAL_PLACEHOLDER$"
            }
          },
          "*": {
            // At least one subproperty needs to exist per SNI section or it
            // cannot be discovered via IConfiguration
            "Protocols": "Http1",
          }
        }
      }
    },
    "Certificates": {
      "Default": {
        "Path": "<path to .pfx file>",
        "Password": "$CREDENTIAL_PLACEHOLDER$"
      }
    }
  }
}

Avviso

Nell'esempio precedente la password del certificato viene archiviata in testo normale in appsettings.json. Il $CREDENTIAL_PLACEHOLDER$ token viene usato come segnaposto per la password del certificato. Per archiviare le password dei certificati in modo sicuro negli ambienti di sviluppo, vedere Proteggere i segreti in fase di sviluppo. Per archiviare le password dei certificati in modo sicuro negli ambienti di produzione, vedere Provider di configurazione di Azure Key Vault. I segreti di sviluppo non devono essere usati per la produzione o il test.

Opzioni HTTPS che possono essere sostituite da SNI:

  • Certificateconfigura l'origine del certificato.
  • Protocolsconfigura i protocolli HTTP consentiti.
  • SslProtocolsconfigura i protocolli SSL consentiti.
  • ClientCertificateModeconfigura i requisiti del certificato client.

Il nome host supporta la corrispondenza con caratteri jolly:

  • Corrispondenza esatta. Ad esempio, a.example.org corrisponde a a.example.org.
  • Prefisso con caratteri jolly. Se sono presenti più corrispondenze con caratteri jolly, viene scelto il criterio più lungo. Ad esempio, *.example.org corrisponde b.example.org a e c.example.org.
  • Carattere jolly completo. * corrisponde a tutto il resto, inclusi i client che non usano SNI e non inviano un nome host.

La configurazione SNI corrispondente viene applicata all'endpoint per la connessione, sostituendo i valori nell'endpoint. Se una connessione non corrisponde a un nome host SNI configurato, la connessione viene rifiutata.

Configurare SNI con codice

Kestrel supporta SNI con diverse API di callback:

  • ServerCertificateSelector
  • ServerOptionsSelectionCallback
  • TlsHandshakeCallbackOptions

SNI con ServerCertificateSelector

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:

var builder = WebApplication.CreateBuilder(args);

builder.WebHost.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)
            {
                ["localhost"] = localhostCert,
                ["example.com"] = exampleCert,
                ["sub.example.com"] = subExampleCert
            };

            httpsOptions.ServerCertificateSelector = (connectionContext, name) =>
            {
                if (name is not null && certs.TryGetValue(name, out var cert))
                {
                    return cert;
                }

                return exampleCert;
            };
        });
    });
});

SNI con ServerOptionsSelectionCallback

Kestrel supporta una configurazione TLS dinamica aggiuntiva tramite il ServerOptionsSelectionCallback callback. Il callback viene richiamato una volta per ogni connessione per consentire all'app di controllare il nome host e selezionare il certificato e la configurazione TLS appropriati. I certificati predefiniti e ConfigureHttpsDefaults non vengono usati con questo callback.

var builder = WebApplication.CreateBuilder(args);

builder.WebHost.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);

            listenOptions.UseHttps((stream, clientHelloInfo, state, cancellationToken) =>
            {
                if (string.Equals(clientHelloInfo.ServerName, "localhost",
                    StringComparison.OrdinalIgnoreCase))
                {
                    return new ValueTask<SslServerAuthenticationOptions>(
                        new SslServerAuthenticationOptions
                        {
                            ServerCertificate = localhostCert,
                            // Different TLS requirements for this host
                            ClientCertificateRequired = true
                        });
                }

                return new ValueTask<SslServerAuthenticationOptions>(
                    new SslServerAuthenticationOptions
                    {
                        ServerCertificate = exampleCert
                    });
            }, state: null!);
        });
    });
});

SNI con TlsHandshakeCallbackOptions

Kestrel supporta una configurazione TLS dinamica aggiuntiva tramite il TlsHandshakeCallbackOptions.OnConnection callback. Il callback viene richiamato una volta per ogni connessione per consentire all'app di controllare il nome host e selezionare il certificato appropriato, la configurazione TLS e altre opzioni del server. I certificati predefiniti e ConfigureHttpsDefaults non vengono usati con questo callback.

var builder = WebApplication.CreateBuilder(args);

builder.WebHost.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);

            listenOptions.UseHttps(new TlsHandshakeCallbackOptions
            {
                OnConnection = context =>
                {
                    if (string.Equals(context.ClientHelloInfo.ServerName, "localhost",
                        StringComparison.OrdinalIgnoreCase))
                    {
                        // Different TLS requirements for this host
                        context.AllowDelayedClientCertificateNegotation = true;

                        return new ValueTask<SslServerAuthenticationOptions>(
                            new SslServerAuthenticationOptions
                            {
                                ServerCertificate = localhostCert
                            });
                    }

                    return new ValueTask<SslServerAuthenticationOptions>(
                        new SslServerAuthenticationOptions
                        {
                            ServerCertificate = exampleCert
                        });
                }
            });
        });
    });
});

Configurare i protocolli HTTP

Kestrel supporta tutte le versioni HTTP di uso comune. Gli endpoint possono essere configurati per supportare versioni HTTP diverse usando l'enumerazione HttpProtocols , che specifica le opzioni di versione HTTP disponibili.

TLS è necessario per supportare più versioni HTTP. L'handshake TLS Application-Layer Protocol Negotiate (ALPN) viene usato per negoziare il protocollo di connessione tra il client e il server quando un endpoint supporta più protocolli.

Valore 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.
Http3 Solo HTTP/3. Richiede TLS. Potrebbe essere necessario configurare il client solo per l'uso di HTTP/3.
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.
Http1AndHttp2AndHttp3 HTTP/1.1, HTTP/2 e HTTP/3. La prima richiesta client usa normalmente HTTP/1.1 o HTTP/2 e l'intestazione della risposta richiede al client di eseguire l'aggiornamento alt-svc a HTTP/3. HTTP/2 e HTTP/3 richiede TLS; in caso contrario, per impostazione predefinita la connessione è HTTP/1.1.

Il valore del protocollo predefinito per un 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.

Configurare i protocolli HTTP in appsettings.json

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

Nella sezione è possibile configurare Kestrel:EndpointDefaults un protocollo predefinito. L'esempio seguente appsettings.json stabilisce HTTP/1.1 come protocollo di connessione predefinito per tutti gli endpoint:

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

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

Configurare i protocolli HTTP nel codice

ListenOptions.Protocols viene utilizzato per specificare i protocolli con l'enumerazione HttpProtocols .

L'esempio seguente configura un endpoint per le connessioni HTTP/1.1, HTTP/2 e HTTP/3 sulla porta 8000. Le connessioni sono protette da TLS con un certificato incluso:

var builder = WebApplication.CreateBuilder(args);

builder.WebHost.ConfigureKestrel((context, serverOptions) =>
{
    serverOptions.Listen(IPAddress.Any, 8000, listenOptions =>
    {
        listenOptions.UseHttps("testCert.pfx", "testPassword");
        listenOptions.Protocols = HttpProtocols.Http1AndHttp2AndHttp3;
    });
});

Vedi anche

ASP.NET progetti Core sono configurati per l'associazione a una porta HTTP casuale compresa tra 5000-5300 e una porta HTTPS casuale compresa tra 7000 e 7300. Questa configurazione predefinita viene specificata nel file generato Properties/launchSettings.json e può essere sottoposta a override. Se non vengono specificate porte, Kestrel esegue l'associazione a http://localhost:5000.

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:

Il certificato di sviluppo è disponibile solo per l'utente che genera il certificato. 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

ConfigureEndpointDefaults(Action<ListenOptions>) specifica una configurazione Action da eseguire per ogni endpoint specificato. La chiamata ConfigureEndpointDefaults più volte sostituisce i valori precedenti Actioncon l'ultimo Action specificato:

var builder = WebApplication.CreateBuilder(args);

builder.WebHost.ConfigureKestrel(serverOptions =>
{
    serverOptions.ConfigureEndpointDefaults(listenOptions =>
    {
        // ...
    });
});

Nota

Gli endpoint creati chiamando Listen prima della chiamata ConfigureEndpointDefaults non avranno le impostazioni predefinite applicate.

Configure(IConfiguration)

Consente di Kestrel caricare gli endpoint da un oggetto IConfiguration. La configurazione deve avere come ambito la sezione di configurazione per Kestrel. L'overload Configure(IConfiguration, bool) può essere usato per abilitare il ricaricamento degli endpoint quando cambia l'origine della configurazione.

Per impostazione predefinita, Kestrel la Kestrel configurazione viene caricata dalla sezione e la ricarica delle modifiche è abilitata:

{
  "Kestrel": {
    "Endpoints": {
      "Http": {
        "Url": "http://localhost:5000"
      },
      "Https": {
        "Url": "https://localhost:5001"
      }
    }
  }
}

Se la configurazione di ricaricamento è abilitata e viene segnalata una modifica, vengono eseguiti i passaggi seguenti:

  • La nuova configurazione viene confrontata con quella precedente, qualsiasi endpoint senza modifiche alla configurazione non viene modificato.
  • Agli endpoint rimossi o modificati vengono assegnati 5 secondi per completare le richieste di elaborazione e arrestare.
  • Vengono avviati endpoint nuovi o modificati.

I client che si connettono a un endpoint modificato possono essere disconnessi o rifiutati durante il riavvio dell'endpoint.

ConfigureHttpsDefaults

ConfigureHttpsDefaults(Action<HttpsConnectionAdapterOptions>) specifica una 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.

var builder = WebApplication.CreateBuilder(args);

builder.WebHost.ConfigureKestrel(serverOptions =>
{
    serverOptions.ConfigureHttpsDefaults(listenOptions =>
    {
        // ...
    });
});

Nota

Gli endpoint creati chiamando Listen prima della chiamata ConfigureHttpsDefaults non avranno le impostazioni predefinite applicate.

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.

Se i certificati vengono letti dal disco, anziché da un archivio certificati di Windows, la directory contenitore deve disporre delle autorizzazioni appropriate per impedire l'accesso non autorizzato.

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.

Sostituire il certificato predefinito della configurazione

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, ad esempio certificati autofirmato.
  • Qualsiasi endpoint HTTPS che non specifica un certificato (HttpsDefaultCert nell'esempio seguente) esegue il fallback al certificato definito in Certificates:Default o al certificato di sviluppo.
{
  "Kestrel": {
    "Endpoints": {
      "Http": {
        "Url": "http://localhost:5000"
      },
      "HttpsInlineCertFile": {
        "Url": "https://localhost:5001",
        "Certificate": {
          "Path": "<path to .pfx file>",
          "Password": "$CREDENTIAL_PLACEHOLDER$"
        }
      },
      "HttpsInlineCertAndKeyFile": {
        "Url": "https://localhost:5002",
        "Certificate": {
          "Path": "<path to .pem/.crt file>",
          "KeyPath": "<path to .key file>",
          "Password": "$CREDENTIAL_PLACEHOLDER$"
        }
      },
      "HttpsInlineCertStore": {
        "Url": "https://localhost:5003",
        "Certificate": {
          "Subject": "<subject; required>",
          "Store": "<certificate store; required>",
          "Location": "<location; defaults to CurrentUser>",
          "AllowInvalid": "<true or false; defaults to false>"
        }
      },
      "HttpsDefaultCert": {
        "Url": "https://localhost:5004"
      }
    },
    "Certificates": {
      "Default": {
        "Path": "<path to .pfx file>",
        "Password": "$CREDENTIAL_PLACEHOLDER$"
      }
    }
  }
}

Avviso

Nell'esempio precedente le password dei certificati vengono archiviate in testo normale in appsettings.json. Il $CREDENTIAL_PLACEHOLDER$ token viene usato come segnaposto per la password di ogni certificato. Per archiviare le password dei certificati in modo sicuro negli ambienti di sviluppo, vedere Proteggere i segreti in fase di sviluppo. Per archiviare le password dei certificati in modo sicuro negli ambienti di produzione, vedere Provider di configurazione di Azure Key Vault. I segreti di sviluppo non devono essere usati per la produzione o il test.

Note di schema:

  • I nomi degli endpoint non fanno distinzione tra maiuscole e minuscole. Ad esempio, la sintassi di HTTPS and Https sono equivalenti.
  • 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 Certificate sezione non è specificata, vengono usate le impostazioni predefinite definite in Certificates:Default . Se non sono disponibili impostazioni predefinite, viene usato il certificato di sviluppo. Se non sono presenti impostazioni predefinite e il certificato di sviluppo non è presente, il server genera un'eccezione e non viene avviato.
  • La Certificate sezione supporta più origini di certificati.
  • Qualsiasi numero di endpoint può essere definito in Configuration purché non causi conflitti di porta.

Origini certificato

I nodi certificato possono essere configurati per caricare i certificati da diverse origini:

  • Pathe per caricare i file con estensione Password pfx.
  • Pathe KeyPath per caricare i file con estensione pem.crt/ e .key. Password
  • Subject e Store da caricare dall'archivio certificati.

Ad esempio, il Certificates:Default certificato può essere specificato come:

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

ConfigurationLoader

Configure(IConfiguration) restituisce un oggetto KestrelConfigurationLoader con un metodo Endpoint(String, Action<EndpointConfiguration>) che può essere usato per integrare le impostazioni dell'endpoint configurato:

var builder = WebApplication.CreateBuilder(args);

builder.WebHost.ConfigureKestrel((context, serverOptions) =>
{
    var kestrelSection = context.Configuration.GetSection("Kestrel");

    serverOptions.Configure(kestrelSection)
        .Endpoint("HTTPS", listenOptions =>
        {
            // ...
        });
});

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

  • 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 Configure(IConfiguration) 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.

var builder = WebApplication.CreateBuilder(args);

builder.WebHost.ConfigureKestrel((context, serverOptions) =>
{
    serverOptions.ConfigureEndpointDefaults(listenOptions =>
    {
        // ...
    });

    serverOptions.ConfigureHttpsDefaults(listenOptions =>
    {
        // ...
    });
});

Configurare gli endpoint usando l'indicazione del nome del server

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.

SNI può essere configurato in due modi:

  • Creare un endpoint nel codice e selezionare un certificato usando il nome host con il ServerCertificateSelector callback.
  • Configurare un mapping tra i nomi host e le opzioni HTTPS in Configurazione. Ad esempio, JSON nel appsettings.json file.

SNI con ServerCertificateSelector

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:

var builder = WebApplication.CreateBuilder(args);

builder.WebHost.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)
            {
                ["localhost"] = localhostCert,
                ["example.com"] = exampleCert,
                ["sub.example.com"] = subExampleCert
            };

            httpsOptions.ServerCertificateSelector = (connectionContext, name) =>
            {
                if (name is not null && certs.TryGetValue(name, out var cert))
                {
                    return cert;
                }

                return exampleCert;
            };
        });
    });
});

SNI con ServerOptionsSelectionCallback

Kestrel supporta una configurazione TLS dinamica aggiuntiva tramite il ServerOptionsSelectionCallback callback. Il callback viene richiamato una volta per ogni connessione per consentire all'app di controllare il nome host e selezionare il certificato e la configurazione TLS appropriati. I certificati predefiniti e ConfigureHttpsDefaults non vengono usati con questo callback.

var builder = WebApplication.CreateBuilder(args);

builder.WebHost.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);

            listenOptions.UseHttps((stream, clientHelloInfo, state, cancellationToken) =>
            {
                if (string.Equals(clientHelloInfo.ServerName, "localhost",
                    StringComparison.OrdinalIgnoreCase))
                {
                    return new ValueTask<SslServerAuthenticationOptions>(
                        new SslServerAuthenticationOptions
                        {
                            ServerCertificate = localhostCert,
                            // Different TLS requirements for this host
                            ClientCertificateRequired = true
                        });
                }

                return new ValueTask<SslServerAuthenticationOptions>(
                    new SslServerAuthenticationOptions
                    {
                        ServerCertificate = exampleCert
                    });
            }, state: null!);
        });
    });
});

SNI con TlsHandshakeCallbackOptions

Kestrel supporta una configurazione TLS dinamica aggiuntiva tramite il TlsHandshakeCallbackOptions.OnConnection callback. Il callback viene richiamato una volta per ogni connessione per consentire all'app di controllare il nome host e selezionare il certificato appropriato, la configurazione TLS e altre opzioni del server. I certificati predefiniti e ConfigureHttpsDefaults non vengono usati con questo callback.

var builder = WebApplication.CreateBuilder(args);

builder.WebHost.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);

            listenOptions.UseHttps(new TlsHandshakeCallbackOptions
            {
                OnConnection = context =>
                {
                    if (string.Equals(context.ClientHelloInfo.ServerName, "localhost",
                        StringComparison.OrdinalIgnoreCase))
                    {
                        // Different TLS requirements for this host
                        context.AllowDelayedClientCertificateNegotation = true;

                        return new ValueTask<SslServerAuthenticationOptions>(
                            new SslServerAuthenticationOptions
                            {
                                ServerCertificate = localhostCert
                            });
                    }

                    return new ValueTask<SslServerAuthenticationOptions>(
                        new SslServerAuthenticationOptions
                        {
                            ServerCertificate = exampleCert
                        });
                }
            });
        });
    });
});

SNI nella configurazione

Kestrel supporta SNI definito nella configurazione. Un endpoint può essere configurato con un Sni oggetto che contiene un mapping tra i nomi host e le opzioni HTTPS. Il nome host della connessione viene confrontato con le opzioni e vengono usate per tale connessione.

La configurazione seguente aggiunge un endpoint denominato MySniEndpoint che usa SNI per selezionare le opzioni HTTPS in base al nome host:

{
  "Kestrel": {
    "Endpoints": {
      "MySniEndpoint": {
        "Url": "https://*",
        "SslProtocols": ["Tls11", "Tls12"],
        "Sni": {
          "a.example.org": {
            "Protocols": "Http1AndHttp2",
            "SslProtocols": ["Tls11", "Tls12", "Tls13"],
            "Certificate": {
              "Subject": "<subject; required>",
              "Store": "<certificate store; required>",
            },
            "ClientCertificateMode" : "NoCertificate"
          },
          "*.example.org": {
            "Certificate": {
              "Path": "<path to .pfx file>",
              "Password": "$CREDENTIAL_PLACEHOLDER$"
            }
          },
          "*": {
            // At least one subproperty needs to exist per SNI section or it
            // cannot be discovered via IConfiguration
            "Protocols": "Http1",
          }
        }
      }
    },
    "Certificates": {
      "Default": {
        "Path": "<path to .pfx file>",
        "Password": "$CREDENTIAL_PLACEHOLDER$"
      }
    }
  }
}

Avviso

Nell'esempio precedente le password dei certificati vengono archiviate in testo normale in appsettings.json. Il $CREDENTIAL_PLACEHOLDER$ token viene usato come segnaposto per la password di ogni certificato. Per archiviare le password dei certificati in modo sicuro negli ambienti di sviluppo, vedere Proteggere i segreti in fase di sviluppo. Per archiviare le password dei certificati in modo sicuro negli ambienti di produzione, vedere Provider di configurazione di Azure Key Vault. I segreti di sviluppo non devono essere usati per la produzione o il test.

Opzioni HTTPS che possono essere sostituite da SNI:

  • Certificateconfigura l'origine del certificato.
  • Protocolsconfigura i protocolli HTTP consentiti.
  • SslProtocolsconfigura i protocolli SSL consentiti.
  • ClientCertificateModeconfigura i requisiti del certificato client.

Il nome host supporta la corrispondenza con caratteri jolly:

  • Corrispondenza esatta. Ad esempio, a.example.org corrisponde a a.example.org.
  • Prefisso con caratteri jolly. Se sono presenti più corrispondenze con caratteri jolly, viene scelto il criterio più lungo. Ad esempio, *.example.org corrisponde b.example.org a e c.example.org.
  • Carattere jolly completo. * corrisponde a tutto il resto, inclusi i client che non usano SNI e non inviano un nome host.

La configurazione SNI corrispondente viene applicata all'endpoint per la connessione, sostituendo i valori nell'endpoint. Se una connessione non corrisponde a un nome host SNI configurato, la connessione viene rifiutata.

Requisiti SNI

Tutti i siti Web devono essere eseguiti nella stessa Kestrel istanza. Kestrel non supporta la condivisione di un indirizzo IP e una porta tra più istanze senza un proxy inverso.

Protocolli SSL/TLS

I protocolli SSL sono protocolli usati per crittografare e decrittografare il traffico tra due peer, tradizionalmente un client e un server.

var builder = WebApplication.CreateBuilder(args);

builder.WebHost.ConfigureKestrel(serverOptions =>
{
    serverOptions.ConfigureHttpsDefaults(listenOptions =>
    {
        listenOptions.SslProtocols = SslProtocols.Tls13;
    });
});
{
  "Kestrel": {
    "Endpoints": {
      "MyHttpsEndpoint": {
        "Url": "https://localhost:5001",
        "SslProtocols": ["Tls12", "Tls13"],
        "Certificate": {
          "Path": "<path to .pfx file>",
          "Password": "$CREDENTIAL_PLACEHOLDER$"
        }
      }
    }
  }
}

Avviso

Nell'esempio precedente la password del certificato viene archiviata in testo normale in appsettings.json. Il $CREDENTIAL_PLACEHOLDER$ token viene usato come segnaposto per la password del certificato. Per archiviare le password dei certificati in modo sicuro negli ambienti di sviluppo, vedere Proteggere i segreti in fase di sviluppo. Per archiviare le password dei certificati in modo sicuro negli ambienti di produzione, vedere Provider di configurazione di Azure Key Vault. I segreti di sviluppo non devono essere usati per la produzione o il test.

Il valore predefinito, SslProtocols.None, determina Kestrel l'uso delle impostazioni predefinite del sistema operativo per scegliere il protocollo migliore. A meno che non si disponga di un motivo specifico per selezionare un protocollo, usare l'impostazione predefinita.

Certificati client

ClientCertificateModeconfigura i requisiti del certificato client.

var builder = WebApplication.CreateBuilder(args);

builder.WebHost.ConfigureKestrel(serverOptions =>
{
    serverOptions.ConfigureHttpsDefaults(listenOptions =>
    {
        listenOptions.ClientCertificateMode = ClientCertificateMode.AllowCertificate;
    });
});
{
  "Kestrel": {
    "Endpoints": {
      "MyHttpsEndpoint": {
        "Url": "https://localhost:5001",
        "ClientCertificateMode": "AllowCertificate",
        "Certificate": {
          "Path": "<path to .pfx file>",
          "Password": "$CREDENTIAL_PLACEHOLDER$"
        }
      }
    }
  }
}

Avviso

Nell'esempio precedente la password del certificato viene archiviata in testo normale in appsettings.json. Il $CREDENTIAL_PLACEHOLDER$ token viene usato come segnaposto per la password del certificato. Per archiviare le password dei certificati in modo sicuro negli ambienti di sviluppo, vedere Proteggere i segreti in fase di sviluppo. Per archiviare le password dei certificati in modo sicuro negli ambienti di produzione, vedere Provider di configurazione di Azure Key Vault.

Il valore predefinito è ClientCertificateMode.NoCertificate dove Kestrel non richiederà o richiederà un certificato dal client.

Per altre informazioni, vedere Configurare l'autenticazione del certificato in ASP.NET Core.

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. Questo è il middleware di connessione predefinito.

var builder = WebApplication.CreateBuilder(args);

builder.WebHost.ConfigureKestrel((context, 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:

var builder = WebApplication.CreateBuilder(args);

builder.WebHost.ConfigureKestrel((context, serverOptions) =>
{
    serverOptions.Listen(IPAddress.Loopback, 5000);
    serverOptions.Listen(IPAddress.Loopback, 5001, listenOptions =>
    {
        listenOptions.UseHttps("testCert.pfx", "testPassword");
    });
});

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:

var builder = WebApplication.CreateBuilder(args);

builder.WebHost.ConfigureKestrel((context, serverOptions) =>
{
    serverOptions.ListenUnixSocket("/tmp/kestrel-test.sock");
});
  • 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. Nell'esempio seguente viene illustrato come determinare la porta Kestrel associata in fase di esecuzione:

app.Run(async (context) =>
{
    var serverAddressFeature = context.Features.Get<IServerAddressesFeature>();

    if (serverAddressFeature is not null)
    {
        var listenAddresses = string.Join(", ", serverAddressFeature.Addresses);

        // ...
    }
});

L'associazione dinamica di una porta non è disponibile in alcune situazioni:

  • ListenLocalhost
  • Associazione http/1.1 o HTTP/2 basata su TCP e HTTP/3 basato su QUIC insieme.

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 fornito un certificato predefinito nella configurazione dell'endpoint HTTPS, ad esempio usando KestrelServerOptions la configurazione o un file di configurazione, come illustrato in precedenza in questo articolo.
  • 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'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.
Http3 Solo HTTP/3. Richiede TLS. Potrebbe essere necessario configurare il client solo per l'uso di HTTP/3.
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.
Http1AndHttp2AndHttp3 HTTP/1.1, HTTP/2 e HTTP/3. La prima richiesta client usa normalmente HTTP/1.1 o HTTP/2 e l'intestazione della risposta richiede al client di eseguire l'aggiornamento alt-svc a HTTP/3. HTTP/2 e HTTP/3 richiede TLS; 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:

var builder = WebApplication.CreateBuilder(args);

builder.WebHost.ConfigureKestrel((context, serverOptions) =>
{
    serverOptions.Listen(IPAddress.Any, 8000, listenOptions =>
    {
        listenOptions.UseHttps("testCert.pfx", "testPassword");
        listenOptions.Protocols = HttpProtocols.Http1AndHttp2AndHttp3;
    });
});

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

var builder = WebApplication.CreateBuilder(args);

builder.WebHost.ConfigureKestrel((context, 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,
                    // ...
                });
        };
    });
});

Middleware di connessione

Il middleware di connessione personalizzato può 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 un elenco di suite di crittografia accettabili.

Nessuna crittografia viene usata con un CipherAlgorithmType.Null algoritmo di crittografia.

var builder = WebApplication.CreateBuilder(args);

builder.WebHost.ConfigureKestrel((context, 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();
        });
    });
});

Impostare il protocollo HTTP dalla configurazione

Per impostazione predefinita, Kestrel la configurazione viene caricata dalla Kestrel sezione . 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 a app ASP.NET Core nella stessa porta, usare HTTP.sys o un server proxy inverso. Gli esempi di server proxy inverso includono IIS, Nginx o Apache.

    Avviso

    Una configurazione che prevede un proxy inverso richiede il filtro host.

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

ASP.NET progetti Core sono configurati per l'associazione a una porta HTTP casuale compresa tra 5000-5300 e una porta HTTPS casuale compresa tra 7000 e 7300. Questa configurazione predefinita viene specificata nel file generato Properties/launchSettings.json e può essere sottoposta a override. Se non vengono specificate porte, Kestrel esegue l'associazione 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:

Il certificato di sviluppo è disponibile solo per l'utente che genera il certificato. 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

ConfigureEndpointDefaults(Action<ListenOptions>) specifica una configurazione Action da eseguire per ogni endpoint specificato. La chiamata ConfigureEndpointDefaults più volte sostituisce i valori precedenti Actioncon l'ultimo Action specificato:

var builder = WebApplication.CreateBuilder(args);

builder.WebHost.ConfigureKestrel(serverOptions =>
{
    serverOptions.ConfigureEndpointDefaults(listenOptions =>
    {
        // ...
    });
});

Nota

Gli endpoint creati chiamando Listen prima della chiamata ConfigureEndpointDefaults non avranno le impostazioni predefinite applicate.

Configure(IConfiguration)

Consente di Kestrel caricare gli endpoint da un oggetto IConfiguration. La configurazione deve avere come ambito la sezione di configurazione per Kestrel. L'overload Configure(IConfiguration, bool) può essere usato per abilitare il ricaricamento degli endpoint quando cambia l'origine della configurazione.

Per impostazione predefinita, Kestrel la Kestrel configurazione viene caricata dalla sezione e la ricarica delle modifiche è abilitata:

{
  "Kestrel": {
    "Endpoints": {
      "Http": {
        "Url": "http://localhost:5000"
      },
      "Https": {
        "Url": "https://localhost:5001"
      }
    }
  }
}

Se la configurazione di ricaricamento è abilitata e viene segnalata una modifica, vengono eseguiti i passaggi seguenti:

  • La nuova configurazione viene confrontata con quella precedente, qualsiasi endpoint senza modifiche alla configurazione non viene modificato.
  • Agli endpoint rimossi o modificati vengono assegnati 5 secondi per completare le richieste di elaborazione e arrestare.
  • Vengono avviati endpoint nuovi o modificati.

I client che si connettono a un endpoint modificato possono essere disconnessi o rifiutati durante il riavvio dell'endpoint.

ConfigureHttpsDefaults

ConfigureHttpsDefaults(Action<HttpsConnectionAdapterOptions>) specifica una 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.

var builder = WebApplication.CreateBuilder(args);

builder.WebHost.ConfigureKestrel(serverOptions =>
{
    serverOptions.ConfigureHttpsDefaults(listenOptions =>
    {
        // ...
    });
});

Nota

Gli endpoint creati chiamando Listen prima della chiamata ConfigureHttpsDefaults non avranno le impostazioni predefinite applicate.

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

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, ad esempio certificati autofirmato.
  • Qualsiasi endpoint HTTPS che non specifica un certificato (HttpsDefaultCert nell'esempio seguente) esegue il fallback al certificato definito in Certificates:Default o al certificato di sviluppo.
{
  "Kestrel": {
    "Endpoints": {
      "Http": {
        "Url": "http://localhost:5000"
      },
      "HttpsInlineCertFile": {
        "Url": "https://localhost:5001",
        "Certificate": {
          "Path": "<path to .pfx file>",
          "Password": "$CREDENTIAL_PLACEHOLDER$"
        }
      },
      "HttpsInlineCertAndKeyFile": {
        "Url": "https://localhost:5002",
        "Certificate": {
          "Path": "<path to .pem/.crt file>",
          "KeyPath": "<path to .key file>",
          "Password": "$CREDENTIAL_PLACEHOLDER$"
        }
      },
      "HttpsInlineCertStore": {
        "Url": "https://localhost:5003",
        "Certificate": {
          "Subject": "<subject; required>",
          "Store": "<certificate store; required>",
          "Location": "<location; defaults to CurrentUser>",
          "AllowInvalid": "<true or false; defaults to false>"
        }
      },
      "HttpsDefaultCert": {
        "Url": "https://localhost:5004"
      }
    },
    "Certificates": {
      "Default": {
        "Path": "<path to .pfx file>",
        "Password": "$CREDENTIAL_PLACEHOLDER$"
      }
    }
  }
}

Avviso

Nell'esempio precedente le password dei certificati vengono archiviate in testo normale in appsettings.json. Il $CREDENTIAL_PLACEHOLDER$ token viene usato come segnaposto per la password di ogni certificato. Per archiviare le password dei certificati in modo sicuro negli ambienti di sviluppo, vedere Proteggere i segreti in fase di sviluppo. Per archiviare le password dei certificati in modo sicuro negli ambienti di produzione, vedere Provider di configurazione di Azure Key Vault. I segreti di sviluppo non devono essere usati per la produzione o il test.

Note di schema:

  • I nomi degli endpoint non fanno distinzione tra maiuscole e minuscole. Ad esempio, la sintassi di HTTPS and Https sono equivalenti.
  • 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 Certificate sezione non è specificata, vengono usate le impostazioni predefinite definite in Certificates:Default . Se non sono disponibili impostazioni predefinite, viene usato il certificato di sviluppo. Se non sono presenti impostazioni predefinite e il certificato di sviluppo non è presente, il server genera un'eccezione e non viene avviato.
  • La Certificate sezione supporta più origini di certificati.
  • Qualsiasi numero di endpoint può essere definito in Configuration purché non causi conflitti di porta.

Origini certificato

I nodi certificato possono essere configurati per caricare i certificati da diverse origini:

  • Pathe per caricare i file con estensione Password pfx.
  • Pathe KeyPath per caricare i file con estensione pem.crt/ e .key. Password
  • Subject e Store da caricare dall'archivio certificati.

Ad esempio, il Certificates:Default certificato può essere specificato come:

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

ConfigurationLoader

Configure(IConfiguration) restituisce un oggetto KestrelConfigurationLoader con un metodo Endpoint(String, Action<EndpointConfiguration>) che può essere usato per integrare le impostazioni dell'endpoint configurato:

var builder = WebApplication.CreateBuilder(args);

builder.WebHost.ConfigureKestrel((context, serverOptions) =>
{
    var kestrelSection = context.Configuration.GetSection("Kestrel");

    serverOptions.Configure(kestrelSection)
        .Endpoint("HTTPS", listenOptions =>
        {
            // ...
        });
});

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

  • 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 Configure(IConfiguration) 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.

var builder = WebApplication.CreateBuilder(args);

builder.WebHost.ConfigureKestrel((context, serverOptions) =>
{
    serverOptions.ConfigureEndpointDefaults(listenOptions =>
    {
        // ...
    });

    serverOptions.ConfigureHttpsDefaults(listenOptions =>
    {
        // ...
    });
});

Configurare gli endpoint usando l'indicazione del nome del server

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.

SNI può essere configurato in due modi:

  • Creare un endpoint nel codice e selezionare un certificato usando il nome host con il ServerCertificateSelector callback.
  • Configurare un mapping tra i nomi host e le opzioni HTTPS in Configurazione. Ad esempio, JSON nel appsettings.json file.

SNI con ServerCertificateSelector

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:

var builder = WebApplication.CreateBuilder(args);

builder.WebHost.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)
            {
                ["localhost"] = localhostCert,
                ["example.com"] = exampleCert,
                ["sub.example.com"] = subExampleCert
            };

            httpsOptions.ServerCertificateSelector = (connectionContext, name) =>
            {
                if (name is not null && certs.TryGetValue(name, out var cert))
                {
                    return cert;
                }

                return exampleCert;
            };
        });
    });
});

SNI con ServerOptionsSelectionCallback

Kestrel supporta una configurazione TLS dinamica aggiuntiva tramite il ServerOptionsSelectionCallback callback. Il callback viene richiamato una volta per ogni connessione per consentire all'app di controllare il nome host e selezionare il certificato e la configurazione TLS appropriati. I certificati predefiniti e ConfigureHttpsDefaults non vengono usati con questo callback.

var builder = WebApplication.CreateBuilder(args);

builder.WebHost.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);

            listenOptions.UseHttps((stream, clientHelloInfo, state, cancellationToken) =>
            {
                if (string.Equals(clientHelloInfo.ServerName, "localhost",
                    StringComparison.OrdinalIgnoreCase))
                {
                    return new ValueTask<SslServerAuthenticationOptions>(
                        new SslServerAuthenticationOptions
                        {
                            ServerCertificate = localhostCert,
                            // Different TLS requirements for this host
                            ClientCertificateRequired = true
                        });
                }

                return new ValueTask<SslServerAuthenticationOptions>(
                    new SslServerAuthenticationOptions
                    {
                        ServerCertificate = exampleCert
                    });
            }, state: null!);
        });
    });
});

SNI con TlsHandshakeCallbackOptions

Kestrel supporta una configurazione TLS dinamica aggiuntiva tramite il TlsHandshakeCallbackOptions.OnConnection callback. Il callback viene richiamato una volta per ogni connessione per consentire all'app di controllare il nome host e selezionare il certificato appropriato, la configurazione TLS e altre opzioni del server. I certificati predefiniti e ConfigureHttpsDefaults non vengono usati con questo callback.

var builder = WebApplication.CreateBuilder(args);

builder.WebHost.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);

            listenOptions.UseHttps(new TlsHandshakeCallbackOptions
            {
                OnConnection = context =>
                {
                    if (string.Equals(context.ClientHelloInfo.ServerName, "localhost",
                        StringComparison.OrdinalIgnoreCase))
                    {
                        // Different TLS requirements for this host
                        context.AllowDelayedClientCertificateNegotation = true;

                        return new ValueTask<SslServerAuthenticationOptions>(
                            new SslServerAuthenticationOptions
                            {
                                ServerCertificate = localhostCert
                            });
                    }

                    return new ValueTask<SslServerAuthenticationOptions>(
                        new SslServerAuthenticationOptions
                        {
                            ServerCertificate = exampleCert
                        });
                }
            });
        });
    });
});

SNI nella configurazione

Kestrel supporta SNI definito nella configurazione. Un endpoint può essere configurato con un Sni oggetto che contiene un mapping tra i nomi host e le opzioni HTTPS. Il nome host della connessione viene confrontato con le opzioni e vengono usate per tale connessione.

La configurazione seguente aggiunge un endpoint denominato MySniEndpoint che usa SNI per selezionare le opzioni HTTPS in base al nome host:

{
  "Kestrel": {
    "Endpoints": {
      "MySniEndpoint": {
        "Url": "https://*",
        "SslProtocols": ["Tls11", "Tls12"],
        "Sni": {
          "a.example.org": {
            "Protocols": "Http1AndHttp2",
            "SslProtocols": ["Tls11", "Tls12", "Tls13"],
            "Certificate": {
              "Subject": "<subject; required>",
              "Store": "<certificate store; required>",
            },
            "ClientCertificateMode" : "NoCertificate"
          },
          "*.example.org": {
            "Certificate": {
              "Path": "<path to .pfx file>",
              "Password": "$CREDENTIAL_PLACEHOLDER$"
            }
          },
          "*": {
            // At least one subproperty needs to exist per SNI section or it
            // cannot be discovered via IConfiguration
            "Protocols": "Http1",
          }
        }
      }
    },
    "Certificates": {
      "Default": {
        "Path": "<path to .pfx file>",
        "Password": "$CREDENTIAL_PLACEHOLDER$"
      }
    }
  }
}

Avviso

Nell'esempio precedente le password dei certificati vengono archiviate in testo normale in appsettings.json. Il $CREDENTIAL_PLACEHOLDER$ token viene usato come segnaposto per la password di ogni certificato. Per archiviare le password dei certificati in modo sicuro negli ambienti di sviluppo, vedere Proteggere i segreti in fase di sviluppo. Per archiviare le password dei certificati in modo sicuro negli ambienti di produzione, vedere Provider di configurazione di Azure Key Vault. I segreti di sviluppo non devono essere usati per la produzione o il test.

Opzioni HTTPS che possono essere sostituite da SNI:

  • Certificateconfigura l'origine del certificato.
  • Protocolsconfigura i protocolli HTTP consentiti.
  • SslProtocolsconfigura i protocolli SSL consentiti.
  • ClientCertificateModeconfigura i requisiti del certificato client.

Il nome host supporta la corrispondenza con caratteri jolly:

  • Corrispondenza esatta. Ad esempio, a.example.org corrisponde a a.example.org.
  • Prefisso con caratteri jolly. Se sono presenti più corrispondenze con caratteri jolly, viene scelto il criterio più lungo. Ad esempio, *.example.org corrisponde b.example.org a e c.example.org.
  • Carattere jolly completo. * corrisponde a tutto il resto, inclusi i client che non usano SNI e non inviano un nome host.

La configurazione SNI corrispondente viene applicata all'endpoint per la connessione, sostituendo i valori nell'endpoint. Se una connessione non corrisponde a un nome host SNI configurato, la connessione viene rifiutata.

Requisiti SNI

Tutti i siti Web devono essere eseguiti nella stessa Kestrel istanza. Kestrel non supporta la condivisione di un indirizzo IP e una porta tra più istanze senza un proxy inverso.

Protocolli SSL/TLS

I protocolli SSL sono protocolli usati per crittografare e decrittografare il traffico tra due peer, tradizionalmente un client e un server.

var builder = WebApplication.CreateBuilder(args);

builder.WebHost.ConfigureKestrel(serverOptions =>
{
    serverOptions.ConfigureHttpsDefaults(listenOptions =>
    {
        listenOptions.SslProtocols = SslProtocols.Tls13;
    });
});
{
  "Kestrel": {
    "Endpoints": {
      "MyHttpsEndpoint": {
        "Url": "https://localhost:5001",
        "SslProtocols": ["Tls12", "Tls13"],
        "Certificate": {
          "Path": "<path to .pfx file>",
          "Password": "$CREDENTIAL_PLACEHOLDER$"
        }
      }
    }
  }
}

Avviso

Nell'esempio precedente la password del certificato viene archiviata in testo normale in appsettings.json. Il $CREDENTIAL_PLACEHOLDER$ token viene usato come segnaposto per la password del certificato. Per archiviare le password dei certificati in modo sicuro negli ambienti di sviluppo, vedere Proteggere i segreti in fase di sviluppo. Per archiviare le password dei certificati in modo sicuro negli ambienti di produzione, vedere Provider di configurazione di Azure Key Vault. I segreti di sviluppo non devono essere usati per la produzione o il test.

Il valore predefinito, SslProtocols.None, determina Kestrel l'uso delle impostazioni predefinite del sistema operativo per scegliere il protocollo migliore. A meno che non si disponga di un motivo specifico per selezionare un protocollo, usare l'impostazione predefinita.

Certificati client

ClientCertificateModeconfigura i requisiti del certificato client.

var builder = WebApplication.CreateBuilder(args);

builder.WebHost.ConfigureKestrel(serverOptions =>
{
    serverOptions.ConfigureHttpsDefaults(listenOptions =>
    {
        listenOptions.ClientCertificateMode = ClientCertificateMode.AllowCertificate;
    });
});
{
  "Kestrel": {
    "Endpoints": {
      "MyHttpsEndpoint": {
        "Url": "https://localhost:5001",
        "ClientCertificateMode": "AllowCertificate",
        "Certificate": {
          "Path": "<path to .pfx file>",
          "Password": "$CREDENTIAL_PLACEHOLDER$"
        }
      }
    }
  }
}

Avviso

Nell'esempio precedente la password del certificato viene archiviata in testo normale in appsettings.json. Il $CREDENTIAL_PLACEHOLDER$ token viene usato come segnaposto per la password del certificato. Per archiviare le password dei certificati in modo sicuro negli ambienti di sviluppo, vedere Proteggere i segreti in fase di sviluppo. Per archiviare le password dei certificati in modo sicuro negli ambienti di produzione, vedere Provider di configurazione di Azure Key Vault.

Il valore predefinito è ClientCertificateMode.NoCertificate dove Kestrel non richiederà o richiederà un certificato dal client.

Per altre informazioni, vedere Configurare l'autenticazione del certificato in ASP.NET Core.

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. Questo è il middleware di connessione predefinito.

var builder = WebApplication.CreateBuilder(args);

builder.WebHost.ConfigureKestrel((context, 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:

var builder = WebApplication.CreateBuilder(args);

builder.WebHost.ConfigureKestrel((context, serverOptions) =>
{
    serverOptions.Listen(IPAddress.Loopback, 5000);
    serverOptions.Listen(IPAddress.Loopback, 5001, listenOptions =>
    {
        listenOptions.UseHttps("testCert.pfx", "testPassword");
    });
});

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:

var builder = WebApplication.CreateBuilder(args);

builder.WebHost.ConfigureKestrel((context, serverOptions) =>
{
    serverOptions.ListenUnixSocket("/tmp/kestrel-test.sock");
});
  • 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. Nell'esempio seguente viene illustrato come determinare la porta Kestrel associata in fase di esecuzione:

app.Run(async (context) =>
{
    var serverAddressFeature = context.Features.Get<IServerAddressesFeature>();

    if (serverAddressFeature is not null)
    {
        var listenAddresses = string.Join(", ", serverAddressFeature.Addresses);

        // ...
    }
});

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 fornito un certificato predefinito nella configurazione dell'endpoint HTTPS, ad esempio usando KestrelServerOptions la configurazione o un file di configurazione, come illustrato in precedenza in questo articolo.
  • 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'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:

var builder = WebApplication.CreateBuilder(args);

builder.WebHost.ConfigureKestrel((context, serverOptions) =>
{
    serverOptions.Listen(IPAddress.Any, 8000, listenOptions =>
    {
        listenOptions.UseHttps("testCert.pfx", "testPassword");
        listenOptions.Protocols = HttpProtocols.Http1AndHttp2AndHttp3;
    });
});

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

var builder = WebApplication.CreateBuilder(args);

builder.WebHost.ConfigureKestrel((context, 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,
                    // ...
                });
        };
    });
});

Middleware di connessione

Il middleware di connessione personalizzato può 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 un elenco di suite di crittografia accettabili.

Nessuna crittografia viene usata con un CipherAlgorithmType.Null algoritmo di crittografia.

var builder = WebApplication.CreateBuilder(args);

builder.WebHost.ConfigureKestrel((context, 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();
        });
    });
});

Impostare il protocollo HTTP dalla configurazione

Per impostazione predefinita, Kestrel la configurazione viene caricata dalla Kestrel sezione . 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 a app ASP.NET Core nella stessa porta, usare HTTP.sys o un server proxy inverso. Gli esempi di server proxy inverso includono IIS, Nginx o Apache.

    Avviso

    Una configurazione che prevede un proxy inverso richiede il filtro host.

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

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

ConfigureEndpointDefaults(Action<ListenOptions>) specifica una 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.

Configure(IConfiguration)

Consente di Kestrel caricare gli endpoint da un oggetto IConfiguration. La configurazione deve avere come ambito la sezione di configurazione per Kestrel.

L'overload Configure(IConfiguration, bool) può essere usato per abilitare il ricaricamento degli endpoint quando cambia l'origine della configurazione.

IHostBuilder.ConfigureWebHostDefaults chiama Configure(context.Configuration.GetSection("Kestrel"), reloadOnChange: true) per impostazione predefinita la configurazione di caricamento Kestrel e abilita il ricaricamento.

{
  "Kestrel": {
    "Endpoints": {
      "Http": {
        "Url": "http://localhost:5000"
      },
      "Https": {
        "Url": "https://localhost:5001"
      }
    }
  }
}

Se la configurazione di ricaricamento è abilitata e viene segnalata una modifica, vengono eseguiti i passaggi seguenti:

  • La nuova configurazione viene confrontata con quella precedente, qualsiasi endpoint senza modifiche alla configurazione non viene modificato.
  • Agli endpoint rimossi o modificati vengono assegnati 5 secondi per completare le richieste di elaborazione e arrestare.
  • Vengono avviati endpoint nuovi o modificati.

I client che si connettono a un endpoint modificato possono essere disconnessi o rifiutati durante il riavvio dell'endpoint.

ConfigureHttpsDefaults

ConfigureHttpsDefaults(Action<HttpsConnectionAdapterOptions>) specifica una 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.

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

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, ad esempio certificati autofirmato.
  • Qualsiasi endpoint HTTPS che non specifica un certificato (HttpsDefaultCert nell'esempio seguente) esegue il fallback al certificato definito in Certificates:Default o al certificato di sviluppo.
{
  "Kestrel": {
    "Endpoints": {
      "Http": {
        "Url": "http://localhost:5000"
      },
      "HttpsInlineCertFile": {
        "Url": "https://localhost:5001",
        "Certificate": {
          "Path": "<path to .pfx file>",
          "Password": "$CREDENTIAL_PLACEHOLDER$"
        }
      },
      "HttpsInlineCertAndKeyFile": {
        "Url": "https://localhost:5002",
        "Certificate": {
          "Path": "<path to .pem/.crt file>",
          "KeyPath": "<path to .key file>",
          "Password": "$CREDENTIAL_PLACEHOLDER$"
        }
      },
      "HttpsInlineCertStore": {
        "Url": "https://localhost:5003",
        "Certificate": {
          "Subject": "<subject; required>",
          "Store": "<certificate store; required>",
          "Location": "<location; defaults to CurrentUser>",
          "AllowInvalid": "<true or false; defaults to false>"
        }
      },
      "HttpsDefaultCert": {
        "Url": "https://localhost:5004"
      }
    },
    "Certificates": {
      "Default": {
        "Path": "<path to .pfx file>",
        "Password": "$CREDENTIAL_PLACEHOLDER$"
      }
    }
  }
}

Avviso

Nell'esempio precedente le password dei certificati vengono archiviate in testo normale in appsettings.json. Il $CREDENTIAL_PLACEHOLDER$ token viene usato come segnaposto per la password di ogni certificato. Per archiviare le password dei certificati in modo sicuro negli ambienti di sviluppo, vedere Proteggere i segreti in fase di sviluppo. Per archiviare le password dei certificati in modo sicuro negli ambienti di produzione, vedere Provider di configurazione di Azure Key Vault. I segreti di sviluppo non devono essere usati per la produzione o il test.

Note di schema:

  • I nomi degli endpoint non fanno distinzione tra maiuscole e minuscole. Ad esempio, la sintassi di HTTPS and Https sono equivalenti.
  • 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 Certificate sezione non è specificata, vengono usate le impostazioni predefinite definite in Certificates:Default . Se non sono disponibili impostazioni predefinite, viene usato il certificato di sviluppo. Se non sono presenti impostazioni predefinite e il certificato di sviluppo non è presente, il server genera un'eccezione e non viene avviato.
  • La Certificate sezione supporta più origini di certificati.
  • Qualsiasi numero di endpoint può essere definito in Configuration purché non causi conflitti di porta.

Origini certificato

I nodi certificato possono essere configurati per caricare i certificati da diverse origini:

  • Pathe per caricare i file con estensione Password pfx.
  • Pathe KeyPath per caricare i file con estensione pem.crt/ e .key. Password
  • Subject e Store da caricare dall'archivio certificati.

Ad esempio, il Certificates:Default certificato può essere specificato come:

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

ConfigurationLoader

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

Configurare gli endpoint usando l'indicazione del nome del server

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.

SNI può essere configurato in due modi:

  • Creare un endpoint nel codice e selezionare un certificato usando il nome host con il ServerCertificateSelector callback.
  • Configurare un mapping tra i nomi host e le opzioni HTTPS in Configurazione. Ad esempio, JSON nel appsettings.json file.

SNI con ServerCertificateSelector

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 codice di callback seguente può essere usato nella ConfigureWebHostDefaults chiamata al metodo del file di Program.cs un progetto:

// using System.Security.Cryptography.X509Certificates;
// using Microsoft.AspNetCore.Server.Kestrel.Https;

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)
            {
                { "localhost", localhostCert },
                { "example.com", exampleCert },
                { "sub.example.com", subExampleCert },
            };            

            httpsOptions.ServerCertificateSelector = (connectionContext, name) =>
            {
                if (name != null && certs.TryGetValue(name, out var cert))
                {
                    return cert;
                }

                return exampleCert;
            };
        });
    });
});

SNI con ServerOptionsSelectionCallback

Kestrel supporta una configurazione TLS dinamica aggiuntiva tramite il ServerOptionsSelectionCallback callback. Il callback viene richiamato una volta per ogni connessione per consentire all'app di controllare il nome host e selezionare il certificato e la configurazione TLS appropriati. I certificati predefiniti e ConfigureHttpsDefaults non vengono usati con questo callback.

// using System.Security.Cryptography.X509Certificates;
// using Microsoft.AspNetCore.Server.Kestrel.Https;

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

            listenOptions.UseHttps((stream, clientHelloInfo, state, cancellationToken) =>
            {
                if (string.Equals(clientHelloInfo.ServerName, "localhost", StringComparison.OrdinalIgnoreCase))
                {
                    return new ValueTask<SslServerAuthenticationOptions>(new SslServerAuthenticationOptions
                    {
                        ServerCertificate = localhostCert,
                        // Different TLS requirements for this host
                        ClientCertificateRequired = true,
                    });
                }

                return new ValueTask<SslServerAuthenticationOptions>(new SslServerAuthenticationOptions
                {
                    ServerCertificate = exampleCert,
                });
            }, state: null);
        });
    });
});

SNI nella configurazione

Kestrel supporta SNI definito nella configurazione. Un endpoint può essere configurato con un Sni oggetto che contiene un mapping tra i nomi host e le opzioni HTTPS. Il nome host della connessione viene confrontato con le opzioni e vengono usate per tale connessione.

La configurazione seguente aggiunge un endpoint denominato MySniEndpoint che usa SNI per selezionare le opzioni HTTPS in base al nome host:

{
  "Kestrel": {
    "Endpoints": {
      "MySniEndpoint": {
        "Url": "https://*",
        "SslProtocols": ["Tls11", "Tls12"],
        "Sni": {
          "a.example.org": {
            "Protocols": "Http1AndHttp2",
            "SslProtocols": ["Tls11", "Tls12", "Tls13"],
            "Certificate": {
              "Subject": "<subject; required>",
              "Store": "<certificate store; required>",
            },
            "ClientCertificateMode" : "NoCertificate"
          },
          "*.example.org": {
            "Certificate": {
              "Path": "<path to .pfx file>",
              "Password": "$CREDENTIAL_PLACEHOLDER$"
            }
          },
          "*": {
            // At least one subproperty needs to exist per SNI section or it
            // cannot be discovered via IConfiguration
            "Protocols": "Http1",
          }
        }
      }
    },
    "Certificates": {
      "Default": {
        "Path": "<path to .pfx file>",
        "Password": "$CREDENTIAL_PLACEHOLDER$"
      }
    }
  }
}

Avviso

Nell'esempio precedente le password dei certificati vengono archiviate in testo normale in appsettings.json. Il $CREDENTIAL_PLACEHOLDER$ token viene usato come segnaposto per la password di ogni certificato. Per archiviare le password dei certificati in modo sicuro negli ambienti di sviluppo, vedere Proteggere i segreti in fase di sviluppo. Per archiviare le password dei certificati in modo sicuro negli ambienti di produzione, vedere Provider di configurazione di Azure Key Vault. I segreti di sviluppo non devono essere usati per la produzione o il test.

Opzioni HTTPS che possono essere sostituite da SNI:

  • Certificateconfigura l'origine del certificato.
  • Protocolsconfigura i protocolli HTTP consentiti.
  • SslProtocolsconfigura i protocolli SSL consentiti.
  • ClientCertificateModeconfigura i requisiti del certificato client.

Il nome host supporta la corrispondenza con caratteri jolly:

  • Corrispondenza esatta. Ad esempio, a.example.org corrisponde a a.example.org.
  • Prefisso con caratteri jolly. Se sono presenti più corrispondenze con caratteri jolly, viene scelto il criterio più lungo. Ad esempio, *.example.org corrisponde b.example.org a e c.example.org.
  • Carattere jolly completo. * corrisponde a tutto il resto, inclusi i client che non usano SNI e non inviano un nome host.

La configurazione SNI corrispondente viene applicata all'endpoint per la connessione, sostituendo i valori nell'endpoint. Se una connessione non corrisponde a un nome host SNI configurato, la connessione viene rifiutata.

Requisiti SNI

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

Protocolli SSL/TLS

I protocolli SSL sono protocolli usati per crittografare e decrittografare il traffico tra due peer, tradizionalmente un client e un server.

webBuilder.ConfigureKestrel(serverOptions =>
{
    serverOptions.ConfigureHttpsDefaults(listenOptions =>
    {
        listenOptions.SslProtocols = SslProtocols.Tls13;
    });
});
{
  "Kestrel": {
    "Endpoints": {
      "MyHttpsEndpoint": {
        "Url": "https://localhost:5001",
        "SslProtocols": ["Tls12", "Tls13"],
        "Certificate": {
          "Path": "<path to .pfx file>",
          "Password": "$CREDENTIAL_PLACEHOLDER$"
        }
      }
    }
  }
}

Avviso

Nell'esempio precedente la password del certificato viene archiviata in testo normale in appsettings.json. Il $CREDENTIAL_PLACEHOLDER$ token viene usato come segnaposto per la password del certificato. Per archiviare le password dei certificati in modo sicuro negli ambienti di sviluppo, vedere Proteggere i segreti in fase di sviluppo. Per archiviare le password dei certificati in modo sicuro negli ambienti di produzione, vedere Provider di configurazione di Azure Key Vault. I segreti di sviluppo non devono essere usati per la produzione o il test.

Il valore predefinito, SslProtocols.None, determina Kestrel l'uso delle impostazioni predefinite del sistema operativo per scegliere il protocollo migliore. A meno che non si disponga di un motivo specifico per selezionare un protocollo, usare l'impostazione predefinita.

Certificati client

ClientCertificateModeconfigura i requisiti del certificato client.

webBuilder.ConfigureKestrel(serverOptions =>
{
    serverOptions.ConfigureHttpsDefaults(listenOptions =>
    {
        listenOptions.ClientCertificateMode = ClientCertificateMode.AllowCertificate;
    });
});
{
  "Kestrel": {
    "Endpoints": {
      "MyHttpsEndpoint": {
        "Url": "https://localhost:5001",
        "ClientCertificateMode": "AllowCertificate",
        "Certificate": {
          "Path": "<path to .pfx file>",
          "Password": "$CREDENTIAL_PLACEHOLDER$"
        }
      }
    }
  }
}

Avviso

Nell'esempio precedente la password del certificato viene archiviata in testo normale in appsettings.json. Il $CREDENTIAL_PLACEHOLDER$ token viene usato come segnaposto per la password del certificato. Per archiviare le password dei certificati in modo sicuro negli ambienti di sviluppo, vedere Proteggere i segreti in fase di sviluppo. Per archiviare le password dei certificati in modo sicuro negli ambienti di produzione, vedere Provider di configurazione di Azure Key Vault. I segreti di sviluppo non devono essere usati per la produzione o il test.

Il valore predefinito è ClientCertificateMode.NoCertificate dove Kestrel non richiederà o richiederà un certificato dal client.

Per altre informazioni, vedere Configurare l'autenticazione del certificato in ASP.NET Core.

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. Questo è il middleware di connessione predefinito.

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. Nell'esempio seguente viene illustrato come determinare la porta Kestrel 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 fornito un certificato predefinito nella configurazione dell'endpoint HTTPS, ad esempio usando KestrelServerOptions la configurazione o un file di configurazione, come illustrato in precedenza in questo articolo.
  • 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'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");
    });
});

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

Middleware di connessione

Il middleware di connessione personalizzato può 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();
        });
    });
});

Impostare il protocollo HTTP 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 a app ASP.NET Core nella stessa porta, usare HTTP.sys o un server proxy inverso. Gli esempi di server proxy inverso includono IIS, Nginx o Apache.

    Avviso

    Una configurazione che prevede un proxy inverso richiede il filtro host.

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