Configurar pontos de extremidade para o servidor Web Kestrel do ASP.NET Core
Observação
Esta não é a versão mais recente deste artigo. Para informações sobre a versão vigente, confira a Versão do .NET 8 deste artigo.
Aviso
Esta versão do ASP.NET Core não tem mais suporte. Para obter mais informações, confira .NET e a Política de Suporte do .NET Core. Para informações sobre a versão vigente, confira a Versão do .NET 8 deste artigo.
Importante
Essas informações relacionam-se ao produto de pré-lançamento, que poderá ser substancialmente modificado antes do lançamento comercial. A Microsoft não oferece nenhuma garantia, explícita ou implícita, quanto às informações fornecidas aqui.
Para informações sobre a versão vigente, confira a Versão do .NET 8 deste artigo.
Observação
Esta não é a versão mais recente deste artigo. Para informações sobre a versão vigente, confira a Versão do .NET 8 deste artigo.
Aviso
Esta versão do ASP.NET Core não tem mais suporte. Para obter mais informações, confira .NET e a Política de Suporte do .NET Core. Para informações sobre a versão vigente, confira a Versão do .NET 8 deste artigo.
Importante
Essas informações relacionam-se ao produto de pré-lançamento, que poderá ser substancialmente modificado antes do lançamento comercial. A Microsoft não oferece nenhuma garantia, explícita ou implícita, quanto às informações fornecidas aqui.
Para informações sobre a versão vigente, confira a Versão do .NET 8 deste artigo.
Os pontos de extremidade do Kestrel fornecem a infraestrutura para ouvir solicitações de entrada e roteá-las para o middleware apropriado. A combinação de um endereço e um protocolo define um ponto de extremidade.
- O endereço especifica o adaptador de rede que o servidor escuta para solicitações de entrada, como uma porta TCP.
- O protocolo especifica a comunicação entre o cliente e o servidor, como HTTP/1.1, HTTP/2 ou HTTP/3.
- Um ponto de extremidade pode ser protegido usando o esquema de URL
https
ou o métodoUseHttps
.
Os pontos de extremidade podem ser configurados usando URLs, JSON em appsettings.json
e código. Esse artigo discute como usar cada opção para configurar um ponto de extremidade:
Ponto de extremidade padrão
Os novos projetos do ASP.NET Core são configurados para se associar a uma porta HTTP aleatória entre 5000-5300 e uma porta HTTPS aleatória entre 7000 e 7300. As portas selecionadas são armazenadas no arquivo Properties/launchSettings.json
gerado e podem ser modificadas pelo desenvolvedor. O arquivo launchSetting.json
é usado apenas no desenvolvimento local.
Se não houver nenhuma configuração de ponto de extremidade, o Kestrel será associado a http://localhost:5000
.
Configurar pontos de extremidade
Os pontos de extremidade do Kestrel escutam conexões de entrada. Quando um ponto de extremidade é criado, ele deve ser configurado com o endereço que ele ouvirá. Normalmente, esse é um endereço TCP e o número da porta.
Há várias opções para configurar pontos de extremidade:
- Configurar pontos de extremidade com URLs
- Especificar portas apenas
- Configurar pontos de extremidade em appsettings.json
- Configurar pontos de extremidade no código
Configurar pontos de extremidade com URLs
As seções a seguir explicam como configurar pontos de extremidade usando:
- A variável de ambiente
ASPNETCORE_URLS
. - O argumento de linha de comando
--urls
. - A chave de configuração do host
urls
. - O método de extensão UseUrls.
- Propriedade WebApplication.Urls.
Formatos de URL
Os URLs indicam os endereços IP ou de host com portas e protocolos que o servidor deve escutar. A porta poderá ser omitida se for o padrão para o protocolo (normalmente 80 e 443). Os URLs podem ser em qualquer dos seguintes formatos.
Endereço IPv4 com o número da porta
http://65.55.39.10:80/
0.0.0.0
é um caso especial que associa a todos os endereços IPv4.Endereço IPv6 com número da porta
http://[0:0:0:0:0:ffff:4137:270a]:80/
[::]
é o equivalente do IPv6 ao IPv40.0.0.0
.Host curinga com o número da porta
http://contoso.com:80/ http://*:80/
Tudo o que não é reconhecido como um endereço IP ou
localhost
válido é tratado como um curinga que associa a todos os endereços IPv4 e IPv6. Algumas pessoas gostam de usar*
ou+
para serem mais explícitas. Para associar nomes de host diferentes a diferentes aplicativos ASP.NET Core na mesma porta, use o HTTP.sys ou um servidor proxy reverso.Exemplos de servidor proxy reverso incluem IIS, YARP, Nginx e Apache.
Nome do host do
localhost
com o número da porta ou o IP de loopback com o número da portahttp://localhost:5000/ http://127.0.0.1:5000/ http://[::1]:5000/
Quando o
localhost
for especificado, o Kestrel tentará se associar às interfaces de loopback IPv4 e IPv6. Se a porta solicitada está sendo usada por outro serviço em uma das interfaces de loopback, o Kestrel falha ao ser iniciado. Se uma das interfaces de loopback não estiver disponível por qualquer outro motivo (geralmente porque não há suporte para o IPv6), o Kestrel registra um aviso em log.
Vários prefixos de URL podem ser especificados usando um delimitador de ponto e vírgula (;
):
http://*:5000;http://localhost:5001;https://hostname:5002
Para obter mais informações, consulte Substituir configuração.
Prefixos de URL HTTPS
Os prefixos de URL HTTPS podem ser usados para definir pontos de extremidade somente se um certificado padrão for fornecido na configuração do ponto de extremidade HTTPS. Por exemplo, use a configuração KestrelServerOptions ou um arquivo de configuração, conforme mostrado posteriormente neste artigo.
Para saber mais, consulte Configurar HTTPS.
Especificar portas apenas
Aplicativos e contêineres geralmente recebem apenas uma porta para escutar, por exemplo, a porta 80, sem restrições adicionais, como host ou caminho. HTTP_PORTS e HTTPS_PORTS são chaves de configuração que especificam as portas de escuta para os servidores HTTP.sys e Kestrel. Essas chaves podem ser especificadas como variáveis de ambiente definidas com os prefixos DOTNET_
ou ASPNETCORE_
, ou especificadas diretamente por meio de outra entrada de configuração, como appsettings.json
. Cada uma delas é uma lista delimitada por ponto e vírgula de valores de porta, conforme mostrado no exemplo abaixo:
ASPNETCORE_HTTP_PORTS=80;8080
ASPNETCORE_HTTPS_PORTS=443;8081
O exemplo anterior é uma abreviação da configuração a seguir, que especifica o esquema (HTTP ou HTTPS) e qualquer host ou IP.
ASPNETCORE_URLS=http://*:80/;http://*:8080/;https://*:443/;https://*:8081/
As chaves de configuração HTTP_PORTS e HTTPS_PORTS são de menor prioridade e são substituídas por URLs ou valores fornecidos diretamente no código. Os certificados ainda precisam ser configurados separadamente por meio de mecânica específica do servidor para HTTPS.
Configurar pontos de extremidade em appsettings.json
O Kestrel pode carregar pontos de extremidade de uma instância de IConfiguration. Por padrão, a configuração do Kestrel é carregada da seção Kestrel
e os pontos de extremidade são configurados em Kestrel:Endpoints
:
{
"Kestrel": {
"Endpoints": {
"MyHttpEndpoint": {
"Url": "http://localhost:8080"
}
}
}
}
No exemplo anterior:
- Usa
appsettings.json
como a fonte de configuração. No entanto, qualquer fonte deIConfiguration
pode ser usada. - Adiciona um ponto de extremidade chamado
MyHttpEndpoint
na porta 8080.
Para obter mais informações sobre como configurar pontos de extremidade com JSON, consulte seções posteriores neste artigo que discutem a configuração de HTTPS e configuração de protocolos HTTP em appsettings.json.
Recarregar pontos de extremidade da configuração
Recarregar a configuração do ponto de extremidade quando a fonte da configuração for alterada é habilitada por padrão. Ele pode ser desabilitado usando KestrelServerOptions.Configure(IConfiguration, Boolean).
Se uma alteração for sinalizada, as seguintes etapas serão executadas:
- A nova configuração é comparada com a antiga e os pontos de extremidade sem alterações de configuração não são modificados.
- Os pontos de extremidade removidos ou modificados têm cinco segundos para concluir as solicitações de processamento e desligar.
- Pontos de extremidade novos ou modificados são iniciados.
Os clientes que se conectam a um ponto de extremidade modificado podem ser desconectados ou recusados enquanto o ponto de extremidade é reiniciado.
ConfigurationLoader
KestrelServerOptions.Configure retorna um KestrelConfigurationLoader. O método Endpoint(String, Action<EndpointConfiguration>) do carregador que pode ser usado para complementar as definições de um ponto de extremidade configurado:
var builder = WebApplication.CreateBuilder(args);
builder.WebHost.ConfigureKestrel((context, serverOptions) =>
{
var kestrelSection = context.Configuration.GetSection("Kestrel");
serverOptions.Configure(kestrelSection)
.Endpoint("HTTPS", listenOptions =>
{
// ...
});
});
KestrelServerOptions.ConfigurationLoader
pode ser acessado diretamente para continuar a iterar no carregador existente, por exemplo, o fornecido por WebApplicationBuilder.WebHost.
- A seção de configuração de cada ponto de extremidade está disponível nas opções do método Endpoint para que as configurações personalizadas possam ser lidas.
- O KestrelServerOptions.Configure(IConfiguration) pode ser chamado várias vezes, mas somente a última configuração será usada, a menos que
Load
seja chamado explicitamente nas instâncias anteriores. O host padrão não chamaLoad
, portanto, sua seção de configuração padrão pode ser substituída. - O
KestrelConfigurationLoader
espelha a família de APIsListen
deKestrelServerOptions
como sobrecargas deEndpoint
, portanto, os pontos de extremidade de código e de configuração podem ser configurados no mesmo local. Essas sobrecargas não usam nomes e consomem somente as definições padrão da configuração.
Configurar pontos de extremidade no código
O KestrelServerOptions fornece métodos para configurar pontos de extremidade no código:
Quando ambas as APIs Listen
e UseUrls, são usadas ao mesmo tempo, os pontos de extremidade de Listen
substituem os pontos de extremidade de UseUrls
.
Associar a um soquete TCP
Os métodos Listen, ListenLocalhost e ListenAnyIP associam-se a um soquete 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");
});
});
No exemplo anterior:
- Configura pontos de extremidade que escutam nas portas 5000 e 5001.
- Configura o HTTPS de um ponto de extremidade com o método de extensão UseHttps em ListenOptions. Para saber mais, consulte Configurar HTTPS no código.
No Windows, podem ser criados certificados autoassinados usando o New-SelfSignedCertificate
cmdlet do PowerShell. Para obter um exemplo sem suporte, confira UpdateIISExpressSSLForChrome.ps1
.
Nas plataformas macOS, Linux e Windows, é possível criar certificados usando o OpenSSL.
Associar a um soquete do UNIX
Escute em um soquete do UNIX com ListenUnixSocket para um melhor desempenho com o Nginx, conforme mostrado neste exemplo:
var builder = WebApplication.CreateBuilder(args);
builder.WebHost.ConfigureKestrel((context, serverOptions) =>
{
serverOptions.ListenUnixSocket("/tmp/kestrel-test.sock");
});
- No arquivo de configuração Nginx, defina a entrada
server
>location
>proxy_pass
comohttp://unix:/tmp/{KESTREL SOCKET}:/;
.{KESTREL SOCKET}
é o nome do soquete fornecido a ListenUnixSocket (por exemplo,kestrel-test.sock
no exemplo anterior). - Verifique se o Nginx pode gravar no soquete (por exemplo,
chmod go+w /tmp/kestrel-test.sock
).
Configurar padrões de ponto de extremidade
O ConfigureEndpointDefaults(Action<ListenOptions>)
especifica uma configuração que é executada para cada ponto de extremidade especificado. Chamar ConfigureEndpointDefaults
várias vezes substitui a configuração anterior.
var builder = WebApplication.CreateBuilder(args);
builder.WebHost.ConfigureKestrel(serverOptions =>
{
serverOptions.ConfigureEndpointDefaults(listenOptions =>
{
// ...
});
});
Observação
Os pontos de extremidade criados ao chamar Listen antes de chamar ConfigureEndpointDefaults não terão os padrões aplicados.
Associação de porta dinâmica
Quando o número da porta 0
for especificado, o Kestrel se associará dinamicamente a uma porta disponível. O exemplo a seguir mostra como determinar a qual porta o Kestrel se associou no runtime:
app.Run(async (context) =>
{
var serverAddressFeature = context.Features.Get<IServerAddressesFeature>();
if (serverAddressFeature is not null)
{
var listenAddresses = string.Join(", ", serverAddressFeature.Addresses);
// ...
}
});
A associação dinâmica de uma porta não está disponível em algumas situações:
- KestrelServerOptions.ListenLocalhost
- Associação de HTTP/1.1 ou HTTP/2 baseado em TCP e HTTP/3 baseado em QUIC.
Configurar HTTPS
O Kestrel dá suporte à proteção de pontos de extremidade com HTTPS. Os dados enviados por HTTPS são criptografados usando o TLS (Transport Layer Security) para aumentar a segurança dos dados transferidos entre o cliente e o servidor.
O HTTPS requer um certificado TLS. O certificado TLS é armazenado no servidor e o Kestrel está configurado para usá-lo. Um aplicativo pode usar o certificado de desenvolvimento HTTPS do ASP.NET Core em um ambiente de desenvolvimento local. O certificado de desenvolvimento não é instalado em ambientes que não sejam de desenvolvimento. Em produção, um certificado TLS precisa ser configurado explicitamente. No mínimo, um certificado padrão precisa ser fornecido.
A forma como o HTTPS e o certificado TLS são configurados depende de como os pontos de extremidade são configurados:
- Se os prefixos de URL ou especificar apenas portas são usados para definir pontos de extremidade, o HTTPS pode ser usado somente se um certificado padrão for fornecido na configuração do ponto de extremidade HTTPS. Um certificado padrão pode ser configurado com uma das seguintes opções:
- Configurar HTTPS em appsettings.json
- Configurar o HTTPS no código
Configurar HTTPS em appsettings.json
Há um esquema de definições de configurações de aplicativo HTTPS padrão disponível para o Kestrel. Configure vários pontos de extremidade, incluindo URLs e os certificados a serem usados, por meio de um arquivo no disco ou de um repositório de certificados.
Qualquer ponto de extremidade HTTPS que não especificar um certificado (HttpsDefaultCert
no exemplo a seguir) será revertido para o certificado definido em Certificates:Default
ou para o certificado de desenvolvimento.
O exemplo a seguir é para appsettings.json
, mas qualquer fonte de configuração pode ser usada:
{
"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$"
}
}
}
}
Aviso
No exemplo anterior, a senha do certificado é armazenada em texto sem formatação em appsettings.json
. O token $CREDENTIAL_PLACEHOLDER$
é usado como um espaço reservado para a senha do certificado. Para armazenar senhas de certificado com segurança em ambientes de desenvolvimento, confira Proteger segredos em desenvolvimento. Para armazenar senhas de certificado com segurança em ambientes de produção, confira o provedor de configuração do Azure Key Vault. Os segredos de desenvolvimento não devem ser usados em produção ou teste.
Observações do esquema
- Os nomes do ponto de extremidade diferenciam maiúsculas de minúsculas. Por exemplo:
HTTPS
andHttps
são equivalentes. - O parâmetro
Url
é necessário para cada ponto de extremidade. O formato desse parâmetro é o mesmo que o do parâmetro de configuração deUrls
de nível superior, exceto que ele é limitado a um único valor. Consulte formatos de URL anteriormente nesse artigo. - Esses pontos de extremidade substituem aqueles definidos na configuração de
Urls
de nível superior em vez de serem adicionados a eles. Os pontos de extremidade definidos no código por meio deListen
são acumulados com os pontos de extremidade definidos na seção de configuração. - A seção
Certificate
é opcional. Se a seçãoCertificate
não for especificada, os padrões definidos emCertificates:Default
serão usados. Se nenhum padrão estiver disponível, o certificado de desenvolvimento será usado. Se não houver padrões e o certificado de desenvolvimento não estiver presente, o servidor gerará uma exceção e falhará ao iniciar. - A seção
Certificate
dá suporte a várias fontes de certificado. - Qualquer número de pontos de extremidade pode ser definido na
Configuration
, contanto que eles não causem conflitos de porta.
Fontes de certificado
Os nós de certificado podem ser configurados para carregar certificados de várias fontes:
Path
ePassword
para carregar arquivos .pfx.Path
,KeyPath
ePassword
para carregar arquivos .pem/.crt e .key.Subject
eStore
para carregar do repositório de certificados.
Por exemplo, o certificado Certificates:Default
pode ser especificado como:
"Default": {
"Subject": "<subject; required>",
"Store": "<cert store; required>",
"Location": "<location; defaults to CurrentUser>",
"AllowInvalid": "<true or false; defaults to false>"
}
Configurar certificados de cliente em appsettings.json
O ClientCertificateMode é usado para configurar o comportamento do certificado do cliente.
{
"Kestrel": {
"Endpoints": {
"MyHttpsEndpoint": {
"Url": "https://localhost:5001",
"ClientCertificateMode": "AllowCertificate",
"Certificate": {
"Path": "<path to .pfx file>",
"Password": "$CREDENTIAL_PLACEHOLDER$"
}
}
}
}
}
Aviso
No exemplo anterior, a senha do certificado é armazenada em texto sem formatação em appsettings.json
. O token $CREDENTIAL_PLACEHOLDER$
é usado como um espaço reservado para a senha do certificado. Para armazenar senhas de certificado com segurança em ambientes de desenvolvimento, confira Proteger segredos em desenvolvimento. Para armazenar senhas de certificado com segurança em ambientes de produção, confira o provedor de configuração do Azure Key Vault. Os segredos de desenvolvimento não devem ser usados em produção ou teste.
O valor padrão é ClientCertificateMode.NoCertificate
, em que o Kestrel não solicitará ou exigirá um certificado do cliente.
Para obter mais informações, consulte Configurar a autenticação de certificado no ASP.NET Core.
Configurar os protocolos SSL/TLS em appsettings.json
Protocolos SSL são protocolos usados para criptografar e descriptografar o tráfego entre dois pares, tradicionalmente um cliente e um servidor.
{
"Kestrel": {
"Endpoints": {
"MyHttpsEndpoint": {
"Url": "https://localhost:5001",
"SslProtocols": ["Tls12", "Tls13"],
"Certificate": {
"Path": "<path to .pfx file>",
"Password": "$CREDENTIAL_PLACEHOLDER$"
}
}
}
}
}
Aviso
No exemplo anterior, a senha do certificado é armazenada em texto sem formatação em appsettings.json
. O token $CREDENTIAL_PLACEHOLDER$
é usado como um espaço reservado para a senha do certificado. Para armazenar senhas de certificado com segurança em ambientes de desenvolvimento, confira Proteger segredos em desenvolvimento. Para armazenar senhas de certificado com segurança em ambientes de produção, confira o provedor de configuração do Azure Key Vault. Os segredos de desenvolvimento não devem ser usados em produção ou teste.
O valor padrão, SslProtocols.None
, faz com que o Kestrel use os padrões do sistema operacional para escolher o melhor protocolo. A menos que você tenha um motivo específico para selecionar um protocolo, use o padrão.
Configurar o HTTPS no código
Ao usar a API Listen
, o método de extensão UseHttps em ListenOptions está disponível para configurar 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");
});
});
Parâmetros de ListenOptions.UseHttps
:
filename
é o caminho e o nome do arquivo de um arquivo de certificado, relativo ao diretório que contém os arquivos de conteúdo do aplicativo.password
é a senha necessária para acessar os dados do certificado X.509 .configureOptions
é umaAction
para configurar asHttpsConnectionAdapterOptions
. Retorna oListenOptions
.storeName
é o repositório de certificados do qual o certificado deve ser carregado.subject
é o nome da entidade do certificado.allowInvalid
indica se certificados inválidos devem ser considerados, como os certificados autoassinados.location
é o local do repositório do qual o certificado deve ser carregado.serverCertificate
é o certificado X.509.
Para obter uma lista completa de sobrecarga de UseHttps
, consulte UseHttps.
Configurar certificados de cliente no código
O ClientCertificateMode configura os requisitos de certificado do cliente.
var builder = WebApplication.CreateBuilder(args);
builder.WebHost.ConfigureKestrel(serverOptions =>
{
serverOptions.ConfigureHttpsDefaults(listenOptions =>
{
listenOptions.ClientCertificateMode = ClientCertificateMode.AllowCertificate;
});
});
O valor padrão é NoCertificate, em que o Kestrel não solicitará ou exigirá um certificado do cliente.
Para obter mais informações, consulte Configurar a autenticação de certificado no ASP.NET Core.
Configurar padrões HTTPS no código
O ConfigureHttpsDefaults(Action<HttpsConnectionAdapterOptions>) especifica uma configuração de Action
a ser executado para cada ponto de extremidade HTTPS. Chamar ConfigureHttpsDefaults
várias vezes substitui as instâncias de Action
anteriores pela última Action
especificada.
var builder = WebApplication.CreateBuilder(args);
builder.WebHost.ConfigureKestrel(serverOptions =>
{
serverOptions.ConfigureHttpsDefaults(listenOptions =>
{
// ...
});
});
Observação
Os pontos de extremidade criados ao chamar Listen antes de chamar ConfigureHttpsDefaults não terão os padrões aplicados.
Configurar os protocolos SSL/TLS no código
Os protocolos SSL são usados para criptografar e descriptografar o tráfego entre dois pares, tradicionalmente um cliente e um servidor.
var builder = WebApplication.CreateBuilder(args);
builder.WebHost.ConfigureKestrel(serverOptions =>
{
serverOptions.ConfigureHttpsDefaults(listenOptions =>
{
listenOptions.SslProtocols = SslProtocols.Tls13;
});
});
Configurar o filtro de conjuntos de criptografia do TLS no código
No Linux, CipherSuitesPolicy pode ser usado para filtrar handshakes TLS por conexão individual:
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,
// ...
});
};
});
});
Configurar Indicação de Nome de Servidor
A SNI (Indicação de Nome de Servidor) pode ser usada para hospedar vários domínios no mesmo endereço IP e na mesma porta. A SNI pode ser usada para conservar recursos atendendo vários sites de um servidor.
Para que a SNI funcione, o cliente envia o nome do host da sessão segura para o servidor durante o handshake TLS para que o servidor possa fornecer o certificado correto. O cliente usa o certificado fornecido para a comunicação criptografada com o servidor durante a sessão segura que segue o handshake TLS.
Todos os sites precisam ser executados na mesma instância do Kestrel. O Kestrel não é compatível com o compartilhamento de endereço IP e porta entre várias instâncias sem um proxy reverso.
A SNI pode ser configurada de duas maneiras:
- Configure um mapeamento entre nomes de host e opções HTTPS na Configuração. Por exemplo, JSON no arquivo
appsettings.json
. - Crie um ponto de extremidade no código e selecione um certificado usando o nome do host com o retorno de chamada ServerCertificateSelector.
Configurar a SNI em appsettings.json
O Kestrel dá suporte à SNI definida na configuração. Um ponto de extremidade pode ser configurado com um objeto Sni
que contém um mapeamento entre nomes de host e opções HTTPS. O nome do host da conexão é correspondido com as opções e eles são usados nessa conexão.
A configuração a seguir adiciona um ponto de extremidade chamado MySniEndpoint
que usa SNI para selecionar opções HTTPS com base no nome do 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$"
}
}
}
}
Aviso
No exemplo anterior, a senha do certificado é armazenada em texto sem formatação em appsettings.json
. O token $CREDENTIAL_PLACEHOLDER$
é usado como um espaço reservado para a senha do certificado. Para armazenar senhas de certificado com segurança em ambientes de desenvolvimento, confira Proteger segredos em desenvolvimento. Para armazenar senhas de certificado com segurança em ambientes de produção, confira o provedor de configuração do Azure Key Vault. Os segredos de desenvolvimento não devem ser usados em produção ou teste.
Opções HTTPS que podem ser substituídas pela SNI:
Certificate
configura a origem do certificado.Protocols
configura os protocolos HTTP permitidos.SslProtocols
configura os protocolos SSL permitidos.ClientCertificateMode
configura os requisitos de certificado do cliente.
O nome do host dá suporte à correspondência de caractere curinga:
- Correspondência exata. Por exemplo,
a.example.org
corresponde aa.example.org
. - Prefixo de caractere curinga. Se houver várias correspondências de caractere curinga, o padrão mais longo será escolhido. Por exemplo,
*.example.org
corresponde ab.example.org
ec.example.org
. - Caractere curinga completo.
*
corresponde a todo o resto, incluindo clientes que não estão usando SNI nem enviam um nome de host.
A configuração de SNI correspondente é aplicada ao ponto de extremidade da conexão, substituindo valores no ponto de extremidade. Se uma conexão não corresponder a um nome de host da SNI configurada, a conexão será recusada.
Configurar a SNI com código
O Kestrel dá suporte à SNI com várias APIs de retorno de chamada:
ServerCertificateSelector
ServerOptionsSelectionCallback
TlsHandshakeCallbackOptions
SNI com ServerCertificateSelector
O Kestrel dá suporte à SNI por meio do retorno de chamada do ServerCertificateSelector
. O retorno de chamada é invocado uma vez por conexão para permitir que o aplicativo inspecione o nome do host e selecione o certificado apropriado:
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 com ServerOptionsSelectionCallback
Kestrel dá suporte à configuração de TLS dinâmica adicional por meio do retorno de chamada ServerOptionsSelectionCallback
. O retorno de chamada é invocado uma vez por conexão para permitir que o aplicativo inspecione o nome do host e selecione o certificado e a configuração de TLS apropriados. Certificados padrão e ConfigureHttpsDefaults
não são usados com esse retorno de chamada.
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 com TlsHandshakeCallbackOptions
Kestrel dá suporte à configuração de TLS dinâmica adicional por meio do retorno de chamada TlsHandshakeCallbackOptions.OnConnection
. O retorno de chamada é invocado uma vez por conexão para permitir que o aplicativo inspecione o nome do host e selecione o certificado, a configuração de TLS e outras opções de servidor apropriadas. Certificados padrão e ConfigureHttpsDefaults
não são usados com esse retorno de chamada.
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
});
}
});
});
});
});
Configurar protocolos HTTP
O Kestrel dá suporte a todas as versões HTTP geralmente usadas. Os pontos de extremidade podem ser configurados para dar suporte a diferentes versões HTTP usando a enumeração HttpProtocols, que especifica as opções de versão HTTP disponíveis.
O TLS é necessário para dar suporte a mais de uma versão HTTP. O handshake APLN (Negociação de Protocolo de Camada de Aplicativo) TLS é usado para negociar o protocolo de conexão entre o cliente e o servidor quando um ponto de extremidade dá suporte a vários protocolos.
HttpProtocols valor |
Protocolo de conexão permitido |
---|---|
Http1 |
HTTP/1.1 apenas. Pode ser usado com ou sem TLS. |
Http2 |
HTTP/2 apenas. Poderá ser usado sem TLS apenas se o cliente for compatível com um Modo de conhecimento prévio. |
Http3 |
HTTP/3 apenas. Requer TLS. O cliente pode precisar ser configurado apenas para usar apenas HTTP/3. |
Http1AndHttp2 |
HTTP/1.1 e HTTP/2. HTTP/2 requer que o cliente selecione HTTP/2 no handshake da ALPN (Application-Layer Protocol Negotiation) do TLS; caso contrário, a conexão assume o padrão de HTTP/1.1. |
Http1AndHttp2AndHttp3 |
HTTP/1.1, HTTP/2 e HTTP/3. A primeira solicitação de cliente normalmente usa HTTP/1.1 ou HTTP/2, e o cabeçalho de resposta alt-svc solicita que o cliente atualize para HTTP/3. HTTP/2 e HTTP/3 exigem TLS; caso contrário, a conexão assume o padrão de HTTP/1.1. |
O valor do protocolo padrão para um ponto de extremidade é HttpProtocols.Http1AndHttp2
.
Restrições TLS para HTTP/2:
- Versão TLS 1.2 ou posterior
- Renegociação desabilitada
- Compactação desabilitada
- Tamanhos mínimos de troca de chaves efêmera:
- ECDHE (Diffie-Hellman de curva elíptica) [RFC4492]: mínimo de 224 bits
- DHE (Diffie-Hellman de campo finito) [
TLS12
]: mínimo de 2048 bits
- Pacote de criptografia não proibido.
Há suporte para TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
[TLS-ECDHE
] com a curva elíptica P-256 [FIPS186
] por padrão.
Configurar protocolos HTTP em appsettings.json
O exemplo appsettings.json
a seguir estabelece o protocolo de conexão HTTP/1.1 para um ponto de extremidade específico:
{
"Kestrel": {
"Endpoints": {
"HttpsDefaultCert": {
"Url": "https://localhost:5001",
"Protocols": "Http1"
}
}
}
}
Um protocolo padrão pode ser configurado na seção Kestrel:EndpointDefaults
. O exemplo appsettings.json
a seguir estabelece HTTP/1.1 como o protocolo de conexão padrão para todos os pontos de extremidade:
{
"Kestrel": {
"EndpointDefaults": {
"Protocols": "Http1"
}
}
}
Os protocolos especificados no código substituem os valores definidos pela configuração.
Configurar protocolos HTTP no código
O ListenOptions.Protocols é usado para especificar protocolos com a enumeração HttpProtocols.
O exemplo a seguir configura um ponto de extremidade para conexões HTTP/1.1, HTTP/2 e HTTP/3 na porta 8000. As conexões são protegidas pela TLS com um certificado fornecido:
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;
});
});
Confira também
Os projetos do ASP.NET Core são configurados para se associar a uma porta HTTP aleatória entre 5000-5300 e uma porta HTTPS aleatória entre 7000 e 7300. Essa configuração padrão é especificada no arquivo Properties/launchSettings.json
gerado e pode ser substituída. Se nenhuma porta for especificada, o Kestrel se associará a http://localhost:5000
.
Especificar URLs usando:
- A variável de ambiente
ASPNETCORE_URLS
. - O argumento de linha de comando
--urls
. - A chave de configuração do host
urls
. - O método de extensão UseUrls.
O valor fornecido usando essas abordagens pode ser um ou mais pontos de extremidade HTTP e HTTPS (HTTPS se houver um certificado padrão). Configure o valor como uma lista separada por ponto e vírgula (por exemplo, "Urls": "http://localhost:8000;http://localhost:8001"
).
Veja mais informações sobre essas abordagens em URLs de servidor e Substituir configuração.
Um certificado de desenvolvimento é criado:
- Quando o SDK do .NET é instalado.
- A ferramenta dev-certs é usada para criar um certificado.
O certificado de desenvolvimento está disponível apenas para o usuário que gera o certificado. Alguns navegadores exigem a concessão de permissão explícita para confiar no certificado de desenvolvimento local.
Os modelos de projeto configuram os aplicativos para serem executados em HTTPS, por padrão, e incluem o Redirecionamento de HTTPS e o suporte a HSTS.
Chame os métodos Listen ou ListenUnixSocket em KestrelServerOptions para configurar prefixos de URL e portas para o Kestrel.
UseUrls
, o argumento de linha de comando --urls
, a chave de configuração de host urls
e a variável de ambiente ASPNETCORE_URLS
também funcionam mas têm limitações que serão indicadas mais adiante nesta seção (um certificado padrão precisa estar disponível para a configuração do ponto de extremidade HTTPS).
Configuração de KestrelServerOptions
:
ConfigureEndpointDefaults
ConfigureEndpointDefaults(Action<ListenOptions>) especifica uma configuração Action
a ser executada para cada ponto de extremidade especificado. Chamar ConfigureEndpointDefaults
várias vezes substitui as Action
s pela última Action
especificada:
var builder = WebApplication.CreateBuilder(args);
builder.WebHost.ConfigureKestrel(serverOptions =>
{
serverOptions.ConfigureEndpointDefaults(listenOptions =>
{
// ...
});
});
Observação
Os pontos de extremidade criados ao chamar Listen antes de chamar ConfigureEndpointDefaults não terão os padrões aplicados.
Configure(IConfiguration)
Permite que o Kestrel pontos de extremidade de um IConfiguration. A configuração precisa estar no escopo da seção de configuração do Kestrel. A sobrecarga de Configure(IConfiguration, bool)
pode ser usada para habilitar o recarregamento de pontos de extremidade quando a origem da configuração for alterada.
Por padrão, a configuração do Kestrel é carregada da seção Kestrel
e as alterações de recarregamento são habilitadas:
{
"Kestrel": {
"Endpoints": {
"Http": {
"Url": "http://localhost:5000"
},
"Https": {
"Url": "https://localhost:5001"
}
}
}
}
Se a configuração de recarregamento estiver habilitada e uma alteração for sinalizada, as seguintes etapas serão executadas:
- A nova configuração é comparada com a antiga e os pontos de extremidade sem alterações de configuração não são modificados.
- Os pontos de extremidade removidos ou modificados têm cinco segundos para concluir as solicitações de processamento e desligar.
- Pontos de extremidade novos ou modificados são iniciados.
Os clientes que se conectam a um ponto de extremidade modificado podem ser desconectados ou recusados enquanto o ponto de extremidade é reiniciado.
ConfigureHttpsDefaults
ConfigureHttpsDefaults(Action<HttpsConnectionAdapterOptions>) especifica uma configuração Action
a ser executada para cada ponto de extremidade HTTPS. Chamar ConfigureHttpsDefaults
várias vezes substitui as Action
s pela última Action
especificada.
var builder = WebApplication.CreateBuilder(args);
builder.WebHost.ConfigureKestrel(serverOptions =>
{
serverOptions.ConfigureHttpsDefaults(listenOptions =>
{
// ...
});
});
Observação
Os pontos de extremidade criados ao chamar Listen antes de chamar ConfigureHttpsDefaults não terão os padrões aplicados.
ListenOptions.UseHttps
Configure Kestrel para usar HTTPS.
Extensões ListenOptions.UseHttps
:
UseHttps
: configure o Kestrel para usar HTTPS com o certificado padrão. Gera uma exceção quando não há nenhum certificado padrão configurado.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)
Parâmetros de ListenOptions.UseHttps
:
filename
é o caminho e o nome do arquivo de um arquivo de certificado, relativo ao diretório que contém os arquivos de conteúdo do aplicativo.password
é a senha necessária para acessar os dados do certificado X.509 .configureOptions
é umaAction
para configurar asHttpsConnectionAdapterOptions
. Retorna oListenOptions
.storeName
é o repositório de certificados do qual o certificado deve ser carregado.subject
é o nome da entidade do certificado.allowInvalid
indica se certificados inválidos devem ser considerados, como os certificados autoassinados.location
é o local do repositório do qual o certificado deve ser carregado.serverCertificate
é o certificado X.509.
Em produção, HTTPS precisa ser configurado explicitamente. No mínimo, um certificado padrão precisa ser fornecido.
Se os certificados estiverem sendo lidos do disco, em vez de um Repositório de Certificados do Windows, o diretório deverá ter permissões apropriadas para impedir o acesso não autorizado.
Configurações com suporte descritas a seguir:
- Nenhuma configuração
- Substituir o certificado padrão da configuração
- Alterar os padrões no código
Nenhuma configuração
Kestrel escuta em http://localhost:5000
.
Substituir o certificado padrão da configuração
Há um esquema de definições de configurações de aplicativo HTTPS padrão disponível para o Kestrel. Configure vários pontos de extremidade, incluindo URLs e os certificados a serem usados, por meio de um arquivo no disco ou de um repositório de certificados.
No exemplo appsettings.json
a seguir:
- Defina
AllowInvalid
comotrue
para permitir o uso de certificados inválidos (por exemplo, os certificados autoassinados). - Todo ponto de extremidade HTTPS que não especificar um certificado (
HttpsDefaultCert
no exemplo a seguir) será revertido para o certificado definido emCertificates:Default
ou para o certificado de desenvolvimento.
{
"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$"
}
}
}
}
Aviso
No exemplo anterior, as senhas de certificado são armazenadas em texto sem formatação em appsettings.json
. O token $CREDENTIAL_PLACEHOLDER$
é usado como um espaço reservado para a senha de cada certificado. Para armazenar senhas de certificado com segurança em ambientes de desenvolvimento, confira Proteger segredos em desenvolvimento. Para armazenar senhas de certificado com segurança em ambientes de produção, confira o provedor de configuração do Azure Key Vault. Os segredos de desenvolvimento não devem ser usados em produção ou teste.
Observações do esquema:
- Os nomes de pontos de extremidade não diferenciam maiúsculas de minúsculas. Por exemplo:
HTTPS
andHttps
são equivalentes. - O parâmetro
Url
é necessário para cada ponto de extremidade. O formato desse parâmetro é o mesmo que o do parâmetro de configuração deUrls
de nível superior, exceto que ele é limitado a um único valor. - Esses pontos de extremidade substituem aqueles definidos na configuração de
Urls
de nível superior em vez de serem adicionados a eles. Os pontos de extremidade definidos no código por meio deListen
são acumulados com os pontos de extremidade definidos na seção de configuração. - A seção
Certificate
é opcional. Se a seçãoCertificate
não for especificada, os padrões definidos emCertificates:Default
serão usados. Se nenhum padrão estiver disponível, o certificado de desenvolvimento será usado. Se não houver padrões e o certificado de desenvolvimento não estiver presente, o servidor gerará uma exceção e falhará ao iniciar. - A seção
Certificate
dá suporte a várias fontes de certificado. - Qualquer número de pontos de extremidade pode ser definido na Configuração, contanto que não causem conflitos de porta.
Fontes de certificado
Os nós de certificado podem ser configurados para carregar certificados de várias fontes:
Path
ePassword
para carregar arquivos .pfx.Path
,KeyPath
ePassword
para carregar arquivos .pem/.crt e .key.Subject
eStore
para carregar do repositório de certificados.
Por exemplo, o certificado Certificates:Default
pode ser especificado como:
"Default": {
"Subject": "<subject; required>",
"Store": "<cert store; required>",
"Location": "<location; defaults to CurrentUser>",
"AllowInvalid": "<true or false; defaults to false>"
}
ConfigurationLoader
Configure(IConfiguration) retorna um KestrelConfigurationLoader com um método Endpoint(String, Action<EndpointConfiguration>) que pode ser usado para complementar as definições de um ponto de extremidade configurado:
var builder = WebApplication.CreateBuilder(args);
builder.WebHost.ConfigureKestrel((context, serverOptions) =>
{
var kestrelSection = context.Configuration.GetSection("Kestrel");
serverOptions.Configure(kestrelSection)
.Endpoint("HTTPS", listenOptions =>
{
// ...
});
});
KestrelServerOptions.ConfigurationLoader
pode ser acessado diretamente para continuar a iterar no carregador existente, por exemplo, o fornecido por WebApplicationBuilder.WebHost.
- A seção de configuração de cada ponto de extremidade está disponível nas opções no método
Endpoint
para que as configurações personalizadas possam ser lidas. - Várias configurações podem ser carregadas chamando Configure(IConfiguration) novamente com outra seção. Somente a última configuração será usada, a menos que
Load
seja chamado explicitamente nas instâncias anteriores. O metapacote não chamaLoad
, portanto, sua seção de configuração padrão pode ser substituída. - O
KestrelConfigurationLoader
espelha a família de APIsListen
deKestrelServerOptions
como sobrecargas deEndpoint
, portanto, os pontos de extremidade de código e de configuração podem ser configurados no mesmo local. Essas sobrecargas não usam nomes e consomem somente as definições padrão da configuração.
Alterar os padrões no código
ConfigureEndpointDefaults
e ConfigureHttpsDefaults
podem ser usados para alterar as configurações padrão de ListenOptions
e HttpsConnectionAdapterOptions
, incluindo a substituição do certificado padrão especificado no cenário anterior. ConfigureEndpointDefaults
e ConfigureHttpsDefaults
devem ser chamados antes que qualquer ponto de extremidade seja configurado.
var builder = WebApplication.CreateBuilder(args);
builder.WebHost.ConfigureKestrel((context, serverOptions) =>
{
serverOptions.ConfigureEndpointDefaults(listenOptions =>
{
// ...
});
serverOptions.ConfigureHttpsDefaults(listenOptions =>
{
// ...
});
});
Configurar pontos de extremidade usando a Indicação de Nome de Servidor
A SNI (Indicação de Nome de Servidor) pode ser usada para hospedar vários domínios no mesmo endereço IP e na mesma porta. Para que a SNI funcione, o cliente envia o nome do host da sessão segura para o servidor durante o handshake TLS para que o servidor possa fornecer o certificado correto. O cliente usa o certificado fornecido para a comunicação criptografada com o servidor durante a sessão segura que segue o handshake TLS.
A SNI pode ser configurada de duas maneiras:
- Crie um ponto de extremidade no código e selecione um certificado usando o nome do host com o retorno de chamada ServerCertificateSelector.
- Configure um mapeamento entre nomes de host e opções HTTPS na Configuração. Por exemplo, JSON no arquivo
appsettings.json
.
SNI com ServerCertificateSelector
O Kestrel dá suporte à SNI por meio do retorno de chamada do ServerCertificateSelector
. O retorno de chamada é invocado uma vez por conexão para permitir que o aplicativo inspecione o nome do host e selecione o certificado apropriado:
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 com ServerOptionsSelectionCallback
Kestrel dá suporte à configuração de TLS dinâmica adicional por meio do retorno de chamada ServerOptionsSelectionCallback
. O retorno de chamada é invocado uma vez por conexão para permitir que o aplicativo inspecione o nome do host e selecione o certificado e a configuração de TLS apropriados. Certificados padrão e ConfigureHttpsDefaults
não são usados com esse retorno de chamada.
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 com TlsHandshakeCallbackOptions
Kestrel dá suporte à configuração de TLS dinâmica adicional por meio do retorno de chamada TlsHandshakeCallbackOptions.OnConnection
. O retorno de chamada é invocado uma vez por conexão para permitir que o aplicativo inspecione o nome do host e selecione o certificado, a configuração de TLS e outras opções de servidor apropriadas. Certificados padrão e ConfigureHttpsDefaults
não são usados com esse retorno de chamada.
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 na configuração
O Kestrel dá suporte à SNI definida na configuração. Um ponto de extremidade pode ser configurado com um objeto Sni
que contém um mapeamento entre nomes de host e opções HTTPS. O nome do host de conexão é correspondido com as opções e eles são usados nessa conexão.
A configuração a seguir adiciona um ponto de extremidade chamado MySniEndpoint
que usa SNI para selecionar opções HTTPS com base no nome do 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$"
}
}
}
}
Aviso
No exemplo anterior, as senhas de certificado são armazenadas em texto sem formatação em appsettings.json
. O token $CREDENTIAL_PLACEHOLDER$
é usado como um espaço reservado para a senha de cada certificado. Para armazenar senhas de certificado com segurança em ambientes de desenvolvimento, confira Proteger segredos em desenvolvimento. Para armazenar senhas de certificado com segurança em ambientes de produção, confira o provedor de configuração do Azure Key Vault. Os segredos de desenvolvimento não devem ser usados em produção ou teste.
Opções HTTPS que podem ser substituídas pela SNI:
Certificate
configura a origem do certificado.Protocols
configura os protocolos HTTP permitidos.SslProtocols
configura os protocolos SSL permitidos.ClientCertificateMode
configura os requisitos de certificado do cliente.
O nome do host dá suporte à correspondência de caractere curinga:
- Correspondência exata. Por exemplo,
a.example.org
corresponde aa.example.org
. - Prefixo de caractere curinga. Se houver várias correspondências de caractere curinga, o padrão mais longo será escolhido. Por exemplo,
*.example.org
corresponde ab.example.org
ec.example.org
. - Caractere curinga completo.
*
corresponde a todo o resto, incluindo clientes que não estão usando SNI nem enviam um nome de host.
A configuração de SNI correspondente é aplicada ao ponto de extremidade da conexão, substituindo valores no ponto de extremidade. Se uma conexão não corresponder a um nome de host SNI configurado, a conexão será recusada.
Requisitos de SNI
Todos os sites precisam ser executados na mesma instância do Kestrel. O Kestrel não é compatível com o compartilhamento de endereço IP e porta entre várias instâncias sem um proxy reverso.
Protocolos SSL/TLS
Protocolos SSL são protocolos usados para criptografar e descriptografar o tráfego entre dois pares, tradicionalmente um cliente e um servidor.
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$"
}
}
}
}
}
Aviso
No exemplo anterior, a senha do certificado é armazenada em texto sem formatação em appsettings.json
. O token $CREDENTIAL_PLACEHOLDER$
é usado como um espaço reservado para a senha do certificado. Para armazenar senhas de certificado com segurança em ambientes de desenvolvimento, confira Proteger segredos em desenvolvimento. Para armazenar senhas de certificado com segurança em ambientes de produção, confira o provedor de configuração do Azure Key Vault. Os segredos de desenvolvimento não devem ser usados em produção ou teste.
O valor padrão, SslProtocols.None
, faz com que o Kestrel use os padrões do sistema operacional para escolher o melhor protocolo. A menos que você tenha um motivo específico para selecionar um protocolo, use o padrão.
Certificados do cliente
ClientCertificateMode
configura os requisitos de certificado do cliente.
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$"
}
}
}
}
}
Aviso
No exemplo anterior, a senha do certificado é armazenada em texto sem formatação em appsettings.json
. O token $CREDENTIAL_PLACEHOLDER$
é usado como um espaço reservado para a senha do certificado. Para armazenar senhas de certificado com segurança em ambientes de desenvolvimento, confira Proteger segredos em desenvolvimento. Para armazenar senhas de certificado com segurança em ambientes de produção, confira o provedor de configuração do Azure Key Vault.
O valor padrão é ClientCertificateMode.NoCertificate
, em que o Kestrel não solicitará ou exigirá um certificado do cliente.
Para obter mais informações, consulte Configurar a autenticação de certificado no ASP.NET Core.
Registro em log de conexão
Chame UseConnectionLogging para emitir logs de nível de Depuração para comunicação em nível de byte em uma conexão. O registro em log de conexão é útil para solucionar problemas na comunicação de baixo nível, como durante a criptografia TLS e por trás de proxies. Se UseConnectionLogging
for colocado antes de UseHttps
, o tráfego criptografado será registrado. Se UseConnectionLogging
for colocado depois de UseHttps
, o tráfego descriptografado será registrado. Este é o Middleware de Conexão interno.
var builder = WebApplication.CreateBuilder(args);
builder.WebHost.ConfigureKestrel((context, serverOptions) =>
{
serverOptions.Listen(IPAddress.Any, 8000, listenOptions =>
{
listenOptions.UseConnectionLogging();
});
});
Associar a um soquete TCP
O método Listen é associado a um soquete TCP, e um lambda de opções permite a configuração do certificado 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");
});
});
O exemplo configura o HTTPS de um ponto de extremidade com ListenOptions. Use a mesma API para definir outras configurações do Kestrel para pontos de extremidade específicos.
No Windows, podem ser criados certificados autoassinados usando o New-SelfSignedCertificate
cmdlet do PowerShell. Para obter um exemplo sem suporte, confira UpdateIISExpressSSLForChrome.ps1
.
Nas plataformas macOS, Linux e Windows, é possível criar certificados usando o OpenSSL.
Associar a um soquete do UNIX
Escute em um soquete do UNIX com ListenUnixSocket para um melhor desempenho com o Nginx, conforme mostrado neste exemplo:
var builder = WebApplication.CreateBuilder(args);
builder.WebHost.ConfigureKestrel((context, serverOptions) =>
{
serverOptions.ListenUnixSocket("/tmp/kestrel-test.sock");
});
- No arquivo de configuração Nginx, defina a entrada
server
>location
>proxy_pass
comohttp://unix:/tmp/{KESTREL SOCKET}:/;
.{KESTREL SOCKET}
é o nome do soquete fornecido a ListenUnixSocket (por exemplo,kestrel-test.sock
no exemplo anterior). - Verifique se o Nginx pode gravar no soquete (por exemplo,
chmod go+w /tmp/kestrel-test.sock
).
Porta 0
Quando o número da porta 0
for especificado, o Kestrel se associará dinamicamente a uma porta disponível. O exemplo a seguir mostra como determinar a qual porta o Kestrel se associou no runtime:
app.Run(async (context) =>
{
var serverAddressFeature = context.Features.Get<IServerAddressesFeature>();
if (serverAddressFeature is not null)
{
var listenAddresses = string.Join(", ", serverAddressFeature.Addresses);
// ...
}
});
A associação dinâmica de uma porta não está disponível em algumas situações:
ListenLocalhost
- Associação de HTTP/1.1 ou HTTP/2 baseado em TCP e HTTP/3 baseado em QUIC.
Limitações
Configure pontos de extremidade com as seguintes abordagens:
- UseUrls
- O argumento de linha de comando
--urls
- A chave de configuração do host
urls
- A variável de ambiente
ASPNETCORE_URLS
Esses métodos são úteis para fazer com que o código funcione com servidores que não sejam o Kestrel. No entanto, esteja ciente das seguintes limitações:
- O protocolo HTTPS não pode ser usado com essas abordagens, a menos que um certificado padrão seja fornecido na configuração do ponto de extremidade HTTPS (por exemplo, usando a configuração
KestrelServerOptions
ou um arquivo de configuração, como já foi mostrado neste artigo). - Quando ambas as abordagens,
Listen
eUseUrls
, são usadas ao mesmo tempo, os pontos de extremidade deListen
substituem os pontos de extremidade deUseUrls
.
Configuração de ponto de extremidade do IIS
Ao usar o IIS, as associações de URL para IIS substituem as associações definidas por Listen
ou UseUrls
. Para obter mais informações, consulte Módulo ASP.NET Core.
ListenOptions.Protocols
A propriedade Protocols
estabelece os protocolos HTTP (HttpProtocols
) habilitados em um ponto de extremidade de conexão ou para o servidor. Atribua um valor à propriedade Protocols
com base na enumeração HttpProtocols
.
Valor de enumeração HttpProtocols |
Protocolo de conexão permitido |
---|---|
Http1 |
HTTP/1.1 apenas. Pode ser usado com ou sem TLS. |
Http2 |
HTTP/2 apenas. Poderá ser usado sem TLS apenas se o cliente for compatível com um Modo de conhecimento prévio. |
Http3 |
HTTP/3 apenas. Requer TLS. O cliente pode precisar ser configurado apenas para usar apenas HTTP/3. |
Http1AndHttp2 |
HTTP/1.1 e HTTP/2. HTTP/2 requer que o cliente selecione HTTP/2 no handshake da ALPN (Application-Layer Protocol Negotiation) do TLS; caso contrário, a conexão assume o padrão de HTTP/1.1. |
Http1AndHttp2AndHttp3 |
HTTP/1.1, HTTP/2 e HTTP/3. A primeira solicitação de cliente normalmente usa HTTP/1.1 ou HTTP/2, e o cabeçalho de resposta alt-svc solicita que o cliente atualize para HTTP/3. HTTP/2 e HTTP/3 exigem TLS; caso contrário, a conexão assume o padrão de HTTP/1.1. |
O valor padrão de ListenOptions.Protocols
para qualquer ponto de extremidade é HttpProtocols.Http1AndHttp2
.
Restrições TLS para HTTP/2:
- Versão TLS 1.2 ou posterior
- Renegociação desabilitada
- Compactação desabilitada
- Tamanhos mínimos de troca de chaves efêmera:
- ECDHE (Diffie-Hellman de curva elíptica) [RFC4492]: mínimo de 224 bits
- DHE (Diffie-Hellman de campo finito) [
TLS12
]: mínimo de 2048 bits
- Pacote de criptografia não proibido.
Há suporte a TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
[TLS-ECDHE
] com a curva elíptica P-256 [FIPS186
] tem suporte por padrão.
O exemplo a seguir permite conexões HTTP/1.1 e HTTP/2 na porta 8000. As conexões são protegidas pela TLS com um certificado fornecido:
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;
});
});
No Linux, CipherSuitesPolicy pode ser usado para filtrar handshakes TLS por conexão:
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 de Conexão
O middleware de conexão personalizado pode filtrar handshakes TLS por conexão em busca de criptografias específicas, se necessário.
O exemplo a seguir gera NotSupportedException para todo algoritmo de criptografia ao qual o aplicativo não dá suporte. Como alternativa, defina e compare ITlsHandshakeFeature.CipherAlgorithm com uma lista de conjuntos de criptografia aceitáveis.
Nenhuma criptografia é usada com um algoritmo de criptografia CipherAlgorithmType.Null.
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();
});
});
});
Definir o protocolo HTTP com base na configuração
Por padrão, a configuração do Kestrel é carregada da seção Kestrel
. O exemplo appsettings.json
a seguir estabelece HTTP/1.1 como o protocolo de conexão padrão para todos os pontos de extremidade:
{
"Kestrel": {
"EndpointDefaults": {
"Protocols": "Http1"
}
}
}
O exemplo appsettings.json
a seguir estabelece o protocolo de conexão HTTP/1.1 para um ponto de extremidade específico:
{
"Kestrel": {
"Endpoints": {
"HttpsDefaultCert": {
"Url": "https://localhost:5001",
"Protocols": "Http1"
}
}
}
}
Os protocolos especificados no código substituem os valores definidos pela configuração.
Prefixos de URL
Ao usar UseUrls
, o argumento de linha de comando --urls
, a chave de configuração de host urls
ou a variável de ambiente ASPNETCORE_URLS
, os prefixos de URL podem estar em um dos formatos a seguir.
Somente os prefixos de URL HTTP são válidos. O Kestrel não é compatível com HTTPS ao configurar associações de URL que usam UseUrls
.
Endereço IPv4 com o número da porta
http://65.55.39.10:80/
0.0.0.0
é um caso especial que associa a todos os endereços IPv4.Endereço IPv6 com número da porta
http://[0:0:0:0:0:ffff:4137:270a]:80/
[::]
é o equivalente do IPv6 ao IPv40.0.0.0
.Nome do host com o número da porta
http://contoso.com:80/ http://*:80/
Os nomes de host
*
e+
não são especiais. Tudo o que não é reconhecido como um endereço IP ou umlocalhost
válido é associado a todos os IPs IPv6 e IPv4. Para associar nomes de host diferentes a diferentes aplicativos ASP.NET Core na mesma porta, use o HTTP.sys ou um servidor proxy reverso. Exemplos de servidor proxy reverso incluem IIS, Nginx ou Apache.Aviso
A hospedagem em uma configuração de proxy reverso exige a filtragem de host.
Nome do
localhost
do host com o número da porta ou o IP de loopback com o número da portahttp://localhost:5000/ http://127.0.0.1:5000/ http://[::1]:5000/
Quando o
localhost
for especificado, o Kestrel tentará se associar às interfaces de loopback IPv4 e IPv6. Se a porta solicitada está sendo usada por outro serviço em uma das interfaces de loopback, o Kestrel falha ao ser iniciado. Se uma das interfaces de loopback não estiver disponível por qualquer outro motivo (geralmente porque não há suporte para o IPv6), o Kestrel registra um aviso em log.
Os projetos do ASP.NET Core são configurados para se associar a uma porta HTTP aleatória entre 5000-5300 e uma porta HTTPS aleatória entre 7000 e 7300. Essa configuração padrão é especificada no arquivo Properties/launchSettings.json
gerado e pode ser substituída. Se nenhuma porta for especificada, o Kestrel se associará a:
http://localhost:5000
https://localhost:5001
(quando um certificado de desenvolvimento local está presente)
Especificar URLs usando:
- A variável de ambiente
ASPNETCORE_URLS
. - O argumento de linha de comando
--urls
. - A chave de configuração do host
urls
. - O método de extensão UseUrls.
O valor fornecido usando essas abordagens pode ser um ou mais pontos de extremidade HTTP e HTTPS (HTTPS se houver um certificado padrão). Configure o valor como uma lista separada por ponto e vírgula (por exemplo, "Urls": "http://localhost:8000;http://localhost:8001"
).
Veja mais informações sobre essas abordagens em URLs de servidor e Substituir configuração.
Um certificado de desenvolvimento é criado:
- Quando o SDK do .NET é instalado.
- A ferramenta dev-certs é usada para criar um certificado.
O certificado de desenvolvimento está disponível apenas para o usuário que gera o certificado. Alguns navegadores exigem a concessão de permissão explícita para confiar no certificado de desenvolvimento local.
Os modelos de projeto configuram os aplicativos para serem executados em HTTPS, por padrão, e incluem o Redirecionamento de HTTPS e o suporte a HSTS.
Chame os métodos Listen ou ListenUnixSocket em KestrelServerOptions para configurar prefixos de URL e portas para o Kestrel.
UseUrls
, o argumento de linha de comando --urls
, a chave de configuração de host urls
e a variável de ambiente ASPNETCORE_URLS
também funcionam mas têm limitações que serão indicadas mais adiante nesta seção (um certificado padrão precisa estar disponível para a configuração do ponto de extremidade HTTPS).
Configuração de KestrelServerOptions
:
ConfigureEndpointDefaults
ConfigureEndpointDefaults(Action<ListenOptions>) especifica uma configuração Action
a ser executada para cada ponto de extremidade especificado. Chamar ConfigureEndpointDefaults
várias vezes substitui as Action
s pela última Action
especificada:
var builder = WebApplication.CreateBuilder(args);
builder.WebHost.ConfigureKestrel(serverOptions =>
{
serverOptions.ConfigureEndpointDefaults(listenOptions =>
{
// ...
});
});
Observação
Os pontos de extremidade criados ao chamar Listen antes de chamar ConfigureEndpointDefaults não terão os padrões aplicados.
Configure(IConfiguration)
Permite que o Kestrel pontos de extremidade de um IConfiguration. A configuração precisa estar no escopo da seção de configuração do Kestrel. A sobrecarga de Configure(IConfiguration, bool)
pode ser usada para habilitar o recarregamento de pontos de extremidade quando a origem da configuração for alterada.
Por padrão, a configuração do Kestrel é carregada da seção Kestrel
e as alterações de recarregamento são habilitadas:
{
"Kestrel": {
"Endpoints": {
"Http": {
"Url": "http://localhost:5000"
},
"Https": {
"Url": "https://localhost:5001"
}
}
}
}
Se a configuração de recarregamento estiver habilitada e uma alteração for sinalizada, as seguintes etapas serão executadas:
- A nova configuração é comparada com a antiga e os pontos de extremidade sem alterações de configuração não são modificados.
- Os pontos de extremidade removidos ou modificados têm cinco segundos para concluir as solicitações de processamento e desligar.
- Pontos de extremidade novos ou modificados são iniciados.
Os clientes que se conectam a um ponto de extremidade modificado podem ser desconectados ou recusados enquanto o ponto de extremidade é reiniciado.
ConfigureHttpsDefaults
ConfigureHttpsDefaults(Action<HttpsConnectionAdapterOptions>) especifica uma configuração Action
a ser executada para cada ponto de extremidade HTTPS. Chamar ConfigureHttpsDefaults
várias vezes substitui as Action
s pela última Action
especificada.
var builder = WebApplication.CreateBuilder(args);
builder.WebHost.ConfigureKestrel(serverOptions =>
{
serverOptions.ConfigureHttpsDefaults(listenOptions =>
{
// ...
});
});
Observação
Os pontos de extremidade criados ao chamar Listen antes de chamar ConfigureHttpsDefaults não terão os padrões aplicados.
ListenOptions.UseHttps
Configure Kestrel para usar HTTPS.
Extensões ListenOptions.UseHttps
:
UseHttps
: configure o Kestrel para usar HTTPS com o certificado padrão. Gera uma exceção quando não há nenhum certificado padrão configurado.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)
Parâmetros de ListenOptions.UseHttps
:
filename
é o caminho e o nome do arquivo de um arquivo de certificado, relativo ao diretório que contém os arquivos de conteúdo do aplicativo.password
é a senha necessária para acessar os dados do certificado X.509 .configureOptions
é umaAction
para configurar asHttpsConnectionAdapterOptions
. Retorna oListenOptions
.storeName
é o repositório de certificados do qual o certificado deve ser carregado.subject
é o nome da entidade do certificado.allowInvalid
indica se certificados inválidos devem ser considerados, como os certificados autoassinados.location
é o local do repositório do qual o certificado deve ser carregado.serverCertificate
é o certificado X.509.
Em produção, HTTPS precisa ser configurado explicitamente. No mínimo, um certificado padrão precisa ser fornecido.
Configurações com suporte descritas a seguir:
- Nenhuma configuração
- Substituir o certificado padrão da configuração
- Alterar os padrões no código
Nenhuma configuração
O Kestrel escuta em http://localhost:5000
e em https://localhost:5001
(se houver um certificado padrão disponível).
Substituir o certificado padrão da configuração
Há um esquema de definições de configurações de aplicativo HTTPS padrão disponível para o Kestrel. Configure vários pontos de extremidade, incluindo URLs e os certificados a serem usados, por meio de um arquivo no disco ou de um repositório de certificados.
No exemplo appsettings.json
a seguir:
- Defina
AllowInvalid
comotrue
para permitir o uso de certificados inválidos (por exemplo, os certificados autoassinados). - Todo ponto de extremidade HTTPS que não especificar um certificado (
HttpsDefaultCert
no exemplo a seguir) será revertido para o certificado definido emCertificates:Default
ou para o certificado de desenvolvimento.
{
"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$"
}
}
}
}
Aviso
No exemplo anterior, as senhas de certificado são armazenadas em texto sem formatação em appsettings.json
. O token $CREDENTIAL_PLACEHOLDER$
é usado como um espaço reservado para a senha de cada certificado. Para armazenar senhas de certificado com segurança em ambientes de desenvolvimento, confira Proteger segredos em desenvolvimento. Para armazenar senhas de certificado com segurança em ambientes de produção, confira o provedor de configuração do Azure Key Vault. Os segredos de desenvolvimento não devem ser usados em produção ou teste.
Observações do esquema:
- Os nomes de pontos de extremidade não diferenciam maiúsculas de minúsculas. Por exemplo:
HTTPS
andHttps
são equivalentes. - O parâmetro
Url
é necessário para cada ponto de extremidade. O formato desse parâmetro é o mesmo que o do parâmetro de configuração deUrls
de nível superior, exceto que ele é limitado a um único valor. - Esses pontos de extremidade substituem aqueles definidos na configuração de
Urls
de nível superior em vez de serem adicionados a eles. Os pontos de extremidade definidos no código por meio deListen
são acumulados com os pontos de extremidade definidos na seção de configuração. - A seção
Certificate
é opcional. Se a seçãoCertificate
não for especificada, os padrões definidos emCertificates:Default
serão usados. Se nenhum padrão estiver disponível, o certificado de desenvolvimento será usado. Se não houver padrões e o certificado de desenvolvimento não estiver presente, o servidor gerará uma exceção e falhará ao iniciar. - A seção
Certificate
dá suporte a várias fontes de certificado. - Qualquer número de pontos de extremidade pode ser definido na Configuração, contanto que não causem conflitos de porta.
Fontes de certificado
Os nós de certificado podem ser configurados para carregar certificados de várias fontes:
Path
ePassword
para carregar arquivos .pfx.Path
,KeyPath
ePassword
para carregar arquivos .pem/.crt e .key.Subject
eStore
para carregar do repositório de certificados.
Por exemplo, o certificado Certificates:Default
pode ser especificado como:
"Default": {
"Subject": "<subject; required>",
"Store": "<cert store; required>",
"Location": "<location; defaults to CurrentUser>",
"AllowInvalid": "<true or false; defaults to false>"
}
ConfigurationLoader
Configure(IConfiguration) retorna um KestrelConfigurationLoader com um método Endpoint(String, Action<EndpointConfiguration>) que pode ser usado para complementar as definições de um ponto de extremidade configurado:
var builder = WebApplication.CreateBuilder(args);
builder.WebHost.ConfigureKestrel((context, serverOptions) =>
{
var kestrelSection = context.Configuration.GetSection("Kestrel");
serverOptions.Configure(kestrelSection)
.Endpoint("HTTPS", listenOptions =>
{
// ...
});
});
KestrelServerOptions.ConfigurationLoader
pode ser acessado diretamente para continuar a iterar no carregador existente, por exemplo, o fornecido por WebApplicationBuilder.WebHost.
- A seção de configuração de cada ponto de extremidade está disponível nas opções no método
Endpoint
para que as configurações personalizadas possam ser lidas. - Várias configurações podem ser carregadas chamando Configure(IConfiguration) novamente com outra seção. Somente a última configuração será usada, a menos que
Load
seja chamado explicitamente nas instâncias anteriores. O metapacote não chamaLoad
, portanto, sua seção de configuração padrão pode ser substituída. - O
KestrelConfigurationLoader
espelha a família de APIsListen
deKestrelServerOptions
como sobrecargas deEndpoint
, portanto, os pontos de extremidade de código e de configuração podem ser configurados no mesmo local. Essas sobrecargas não usam nomes e consomem somente as definições padrão da configuração.
Alterar os padrões no código
ConfigureEndpointDefaults
e ConfigureHttpsDefaults
podem ser usados para alterar as configurações padrão de ListenOptions
e HttpsConnectionAdapterOptions
, incluindo a substituição do certificado padrão especificado no cenário anterior. ConfigureEndpointDefaults
e ConfigureHttpsDefaults
devem ser chamados antes que qualquer ponto de extremidade seja configurado.
var builder = WebApplication.CreateBuilder(args);
builder.WebHost.ConfigureKestrel((context, serverOptions) =>
{
serverOptions.ConfigureEndpointDefaults(listenOptions =>
{
// ...
});
serverOptions.ConfigureHttpsDefaults(listenOptions =>
{
// ...
});
});
Configurar pontos de extremidade usando a Indicação de Nome de Servidor
A SNI (Indicação de Nome de Servidor) pode ser usada para hospedar vários domínios no mesmo endereço IP e na mesma porta. Para que a SNI funcione, o cliente envia o nome do host da sessão segura para o servidor durante o handshake TLS para que o servidor possa fornecer o certificado correto. O cliente usa o certificado fornecido para a comunicação criptografada com o servidor durante a sessão segura que segue o handshake TLS.
A SNI pode ser configurada de duas maneiras:
- Crie um ponto de extremidade no código e selecione um certificado usando o nome do host com o retorno de chamada ServerCertificateSelector.
- Configure um mapeamento entre nomes de host e opções HTTPS na Configuração. Por exemplo, JSON no arquivo
appsettings.json
.
SNI com ServerCertificateSelector
O Kestrel dá suporte à SNI por meio do retorno de chamada do ServerCertificateSelector
. O retorno de chamada é invocado uma vez por conexão para permitir que o aplicativo inspecione o nome do host e selecione o certificado apropriado:
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 com ServerOptionsSelectionCallback
Kestrel dá suporte à configuração de TLS dinâmica adicional por meio do retorno de chamada ServerOptionsSelectionCallback
. O retorno de chamada é invocado uma vez por conexão para permitir que o aplicativo inspecione o nome do host e selecione o certificado e a configuração de TLS apropriados. Certificados padrão e ConfigureHttpsDefaults
não são usados com esse retorno de chamada.
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 com TlsHandshakeCallbackOptions
Kestrel dá suporte à configuração de TLS dinâmica adicional por meio do retorno de chamada TlsHandshakeCallbackOptions.OnConnection
. O retorno de chamada é invocado uma vez por conexão para permitir que o aplicativo inspecione o nome do host e selecione o certificado, a configuração de TLS e outras opções de servidor apropriadas. Certificados padrão e ConfigureHttpsDefaults
não são usados com esse retorno de chamada.
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 na configuração
O Kestrel dá suporte à SNI definida na configuração. Um ponto de extremidade pode ser configurado com um objeto Sni
que contém um mapeamento entre nomes de host e opções HTTPS. O nome do host de conexão é correspondido com as opções e eles são usados nessa conexão.
A configuração a seguir adiciona um ponto de extremidade chamado MySniEndpoint
que usa SNI para selecionar opções HTTPS com base no nome do 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$"
}
}
}
}
Aviso
No exemplo anterior, as senhas de certificado são armazenadas em texto sem formatação em appsettings.json
. O token $CREDENTIAL_PLACEHOLDER$
é usado como um espaço reservado para a senha de cada certificado. Para armazenar senhas de certificado com segurança em ambientes de desenvolvimento, confira Proteger segredos em desenvolvimento. Para armazenar senhas de certificado com segurança em ambientes de produção, confira o provedor de configuração do Azure Key Vault. Os segredos de desenvolvimento não devem ser usados em produção ou teste.
Opções HTTPS que podem ser substituídas pela SNI:
Certificate
configura a origem do certificado.Protocols
configura os protocolos HTTP permitidos.SslProtocols
configura os protocolos SSL permitidos.ClientCertificateMode
configura os requisitos de certificado do cliente.
O nome do host dá suporte à correspondência de caractere curinga:
- Correspondência exata. Por exemplo,
a.example.org
corresponde aa.example.org
. - Prefixo de caractere curinga. Se houver várias correspondências de caractere curinga, o padrão mais longo será escolhido. Por exemplo,
*.example.org
corresponde ab.example.org
ec.example.org
. - Caractere curinga completo.
*
corresponde a todo o resto, incluindo clientes que não estão usando SNI nem enviam um nome de host.
A configuração de SNI correspondente é aplicada ao ponto de extremidade da conexão, substituindo valores no ponto de extremidade. Se uma conexão não corresponder a um nome de host SNI configurado, a conexão será recusada.
Requisitos de SNI
Todos os sites precisam ser executados na mesma instância do Kestrel. O Kestrel não é compatível com o compartilhamento de endereço IP e porta entre várias instâncias sem um proxy reverso.
Protocolos SSL/TLS
Protocolos SSL são protocolos usados para criptografar e descriptografar o tráfego entre dois pares, tradicionalmente um cliente e um servidor.
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$"
}
}
}
}
}
Aviso
No exemplo anterior, a senha do certificado é armazenada em texto sem formatação em appsettings.json
. O token $CREDENTIAL_PLACEHOLDER$
é usado como um espaço reservado para a senha do certificado. Para armazenar senhas de certificado com segurança em ambientes de desenvolvimento, confira Proteger segredos em desenvolvimento. Para armazenar senhas de certificado com segurança em ambientes de produção, confira o provedor de configuração do Azure Key Vault. Os segredos de desenvolvimento não devem ser usados em produção ou teste.
O valor padrão, SslProtocols.None
, faz com que o Kestrel use os padrões do sistema operacional para escolher o melhor protocolo. A menos que você tenha um motivo específico para selecionar um protocolo, use o padrão.
Certificados do cliente
ClientCertificateMode
configura os requisitos de certificado do cliente.
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$"
}
}
}
}
}
Aviso
No exemplo anterior, a senha do certificado é armazenada em texto sem formatação em appsettings.json
. O token $CREDENTIAL_PLACEHOLDER$
é usado como um espaço reservado para a senha do certificado. Para armazenar senhas de certificado com segurança em ambientes de desenvolvimento, confira Proteger segredos em desenvolvimento. Para armazenar senhas de certificado com segurança em ambientes de produção, confira o provedor de configuração do Azure Key Vault.
O valor padrão é ClientCertificateMode.NoCertificate
, em que o Kestrel não solicitará ou exigirá um certificado do cliente.
Para obter mais informações, consulte Configurar a autenticação de certificado no ASP.NET Core.
Registro em log de conexão
Chame UseConnectionLogging para emitir logs de nível de Depuração para comunicação em nível de byte em uma conexão. O registro em log de conexão é útil para solucionar problemas na comunicação de baixo nível, como durante a criptografia TLS e por trás de proxies. Se UseConnectionLogging
for colocado antes de UseHttps
, o tráfego criptografado será registrado. Se UseConnectionLogging
for colocado depois de UseHttps
, o tráfego descriptografado será registrado. Este é o Middleware de Conexão interno.
var builder = WebApplication.CreateBuilder(args);
builder.WebHost.ConfigureKestrel((context, serverOptions) =>
{
serverOptions.Listen(IPAddress.Any, 8000, listenOptions =>
{
listenOptions.UseConnectionLogging();
});
});
Associar a um soquete TCP
O método Listen é associado a um soquete TCP, e um lambda de opções permite a configuração do certificado 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");
});
});
O exemplo configura o HTTPS de um ponto de extremidade com ListenOptions. Use a mesma API para definir outras configurações do Kestrel para pontos de extremidade específicos.
No Windows, podem ser criados certificados autoassinados usando o New-SelfSignedCertificate
cmdlet do PowerShell. Para obter um exemplo sem suporte, confira UpdateIISExpressSSLForChrome.ps1
.
Nas plataformas macOS, Linux e Windows, é possível criar certificados usando o OpenSSL.
Associar a um soquete do UNIX
Escute em um soquete do UNIX com ListenUnixSocket para um melhor desempenho com o Nginx, conforme mostrado neste exemplo:
var builder = WebApplication.CreateBuilder(args);
builder.WebHost.ConfigureKestrel((context, serverOptions) =>
{
serverOptions.ListenUnixSocket("/tmp/kestrel-test.sock");
});
- No arquivo de configuração Nginx, defina a entrada
server
>location
>proxy_pass
comohttp://unix:/tmp/{KESTREL SOCKET}:/;
.{KESTREL SOCKET}
é o nome do soquete fornecido a ListenUnixSocket (por exemplo,kestrel-test.sock
no exemplo anterior). - Verifique se o Nginx pode gravar no soquete (por exemplo,
chmod go+w /tmp/kestrel-test.sock
).
Porta 0
Quando o número da porta 0
for especificado, o Kestrel se associará dinamicamente a uma porta disponível. O exemplo a seguir mostra como determinar a qual porta o Kestrel se associou no runtime:
app.Run(async (context) =>
{
var serverAddressFeature = context.Features.Get<IServerAddressesFeature>();
if (serverAddressFeature is not null)
{
var listenAddresses = string.Join(", ", serverAddressFeature.Addresses);
// ...
}
});
Limitações
Configure pontos de extremidade com as seguintes abordagens:
- UseUrls
- O argumento de linha de comando
--urls
- A chave de configuração do host
urls
- A variável de ambiente
ASPNETCORE_URLS
Esses métodos são úteis para fazer com que o código funcione com servidores que não sejam o Kestrel. No entanto, esteja ciente das seguintes limitações:
- O protocolo HTTPS não pode ser usado com essas abordagens, a menos que um certificado padrão seja fornecido na configuração do ponto de extremidade HTTPS (por exemplo, usando a configuração
KestrelServerOptions
ou um arquivo de configuração, como já foi mostrado neste artigo). - Quando ambas as abordagens,
Listen
eUseUrls
, são usadas ao mesmo tempo, os pontos de extremidade deListen
substituem os pontos de extremidade deUseUrls
.
Configuração de ponto de extremidade do IIS
Ao usar o IIS, as associações de URL para IIS substituem as associações definidas por Listen
ou UseUrls
. Para obter mais informações, consulte Módulo ASP.NET Core.
ListenOptions.Protocols
A propriedade Protocols
estabelece os protocolos HTTP (HttpProtocols
) habilitados em um ponto de extremidade de conexão ou para o servidor. Atribua um valor à propriedade Protocols
com base na enumeração HttpProtocols
.
Valor de enumeração HttpProtocols |
Protocolo de conexão permitido |
---|---|
Http1 |
HTTP/1.1 apenas. Pode ser usado com ou sem TLS. |
Http2 |
HTTP/2 apenas. Poderá ser usado sem TLS apenas se o cliente for compatível com um Modo de conhecimento prévio. |
Http1AndHttp2 |
HTTP/1.1 e HTTP/2. HTTP/2 requer que o cliente selecione HTTP/2 no handshake da ALPN (Application-Layer Protocol Negotiation) do TLS; caso contrário, a conexão assume o padrão de HTTP/1.1. |
O valor padrão de ListenOptions.Protocols
para qualquer ponto de extremidade é HttpProtocols.Http1AndHttp2
.
Restrições TLS para HTTP/2:
- Versão TLS 1.2 ou posterior
- Renegociação desabilitada
- Compactação desabilitada
- Tamanhos mínimos de troca de chaves efêmera:
- ECDHE (Diffie-Hellman de curva elíptica) [RFC4492]: mínimo de 224 bits
- DHE (Diffie-Hellman de campo finito) [
TLS12
]: mínimo de 2048 bits
- Pacote de criptografia não proibido.
Há suporte a TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
[TLS-ECDHE
] com a curva elíptica P-256 [FIPS186
] tem suporte por padrão.
O exemplo a seguir permite conexões HTTP/1.1 e HTTP/2 na porta 8000. As conexões são protegidas pela TLS com um certificado fornecido:
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;
});
});
No Linux, CipherSuitesPolicy pode ser usado para filtrar handshakes TLS por conexão:
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 de Conexão
O middleware de conexão personalizado pode filtrar handshakes TLS por conexão em busca de criptografias específicas, se necessário.
O exemplo a seguir gera NotSupportedException para todo algoritmo de criptografia ao qual o aplicativo não dá suporte. Como alternativa, defina e compare ITlsHandshakeFeature.CipherAlgorithm com uma lista de conjuntos de criptografia aceitáveis.
Nenhuma criptografia é usada com um algoritmo de criptografia CipherAlgorithmType.Null.
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();
});
});
});
Definir o protocolo HTTP com base na configuração
Por padrão, a configuração do Kestrel é carregada da seção Kestrel
. O exemplo appsettings.json
a seguir estabelece HTTP/1.1 como o protocolo de conexão padrão para todos os pontos de extremidade:
{
"Kestrel": {
"EndpointDefaults": {
"Protocols": "Http1"
}
}
}
O exemplo appsettings.json
a seguir estabelece o protocolo de conexão HTTP/1.1 para um ponto de extremidade específico:
{
"Kestrel": {
"Endpoints": {
"HttpsDefaultCert": {
"Url": "https://localhost:5001",
"Protocols": "Http1"
}
}
}
}
Os protocolos especificados no código substituem os valores definidos pela configuração.
Prefixos de URL
Ao usar UseUrls
, o argumento de linha de comando --urls
, a chave de configuração de host urls
ou a variável de ambiente ASPNETCORE_URLS
, os prefixos de URL podem estar em um dos formatos a seguir.
Somente os prefixos de URL HTTP são válidos. O Kestrel não é compatível com HTTPS ao configurar associações de URL que usam UseUrls
.
Endereço IPv4 com o número da porta
http://65.55.39.10:80/
0.0.0.0
é um caso especial que associa a todos os endereços IPv4.Endereço IPv6 com número da porta
http://[0:0:0:0:0:ffff:4137:270a]:80/
[::]
é o equivalente do IPv6 ao IPv40.0.0.0
.Nome do host com o número da porta
http://contoso.com:80/ http://*:80/
Os nomes de host
*
e+
não são especiais. Tudo o que não é reconhecido como um endereço IP ou umlocalhost
válido é associado a todos os IPs IPv6 e IPv4. Para associar nomes de host diferentes a diferentes aplicativos ASP.NET Core na mesma porta, use o HTTP.sys ou um servidor proxy reverso. Exemplos de servidor proxy reverso incluem IIS, Nginx ou Apache.Aviso
A hospedagem em uma configuração de proxy reverso exige a filtragem de host.
Nome do
localhost
do host com o número da porta ou o IP de loopback com o número da portahttp://localhost:5000/ http://127.0.0.1:5000/ http://[::1]:5000/
Quando o
localhost
for especificado, o Kestrel tentará se associar às interfaces de loopback IPv4 e IPv6. Se a porta solicitada está sendo usada por outro serviço em uma das interfaces de loopback, o Kestrel falha ao ser iniciado. Se uma das interfaces de loopback não estiver disponível por qualquer outro motivo (geralmente porque não há suporte para o IPv6), o Kestrel registra um aviso em log.
Por padrão, o ASP.NET Core associa a:
http://localhost:5000
https://localhost:5001
(quando um certificado de desenvolvimento local está presente)
Especificar URLs usando:
- A variável de ambiente
ASPNETCORE_URLS
. - O argumento de linha de comando
--urls
. - A chave de configuração do host
urls
. - O método de extensão UseUrls.
O valor fornecido usando essas abordagens pode ser um ou mais pontos de extremidade HTTP e HTTPS (HTTPS se houver um certificado padrão). Configure o valor como uma lista separada por ponto e vírgula (por exemplo, "Urls": "http://localhost:8000;http://localhost:8001"
).
Veja mais informações sobre essas abordagens em URLs de servidor e Substituir configuração.
Um certificado de desenvolvimento é criado:
- Quando o SDK do .NET é instalado.
- A ferramenta dev-certs é usada para criar um certificado.
Alguns navegadores exigem a concessão de permissão explícita para confiar no certificado de desenvolvimento local.
Os modelos de projeto configuram os aplicativos para serem executados em HTTPS, por padrão, e incluem o Redirecionamento de HTTPS e o suporte a HSTS.
Chame os métodos Listen ou ListenUnixSocket em KestrelServerOptions para configurar prefixos de URL e portas para o Kestrel.
UseUrls
, o argumento de linha de comando --urls
, a chave de configuração de host urls
e a variável de ambiente ASPNETCORE_URLS
também funcionam mas têm limitações que serão indicadas mais adiante nesta seção (um certificado padrão precisa estar disponível para a configuração do ponto de extremidade HTTPS).
Configuração de KestrelServerOptions
:
ConfigureEndpointDefaults
ConfigureEndpointDefaults(Action<ListenOptions>) especifica uma configuração Action
a ser executada para cada ponto de extremidade especificado. Chamar ConfigureEndpointDefaults
várias vezes substitui as Action
s pela última Action
especificada.
webBuilder.ConfigureKestrel(serverOptions =>
{
serverOptions.ConfigureEndpointDefaults(listenOptions =>
{
// Configure endpoint defaults
});
});
Observação
Os pontos de extremidade criados ao chamar Listen antes de chamar ConfigureEndpointDefaults não terão os padrões aplicados.
Configure(IConfiguration)
Permite que o Kestrel pontos de extremidade de um IConfiguration. A configuração precisa estar no escopo da seção de configuração do Kestrel.
A sobrecarga de Configure(IConfiguration, bool)
pode ser usada para habilitar o recarregamento de pontos de extremidade quando a origem da configuração for alterada.
IHostBuilder.ConfigureWebHostDefaults
chama Configure(context.Configuration.GetSection("Kestrel"), reloadOnChange: true)
por padrão para carregar o a configuração do Kestrel e habilitar o recarregamento.
{
"Kestrel": {
"Endpoints": {
"Http": {
"Url": "http://localhost:5000"
},
"Https": {
"Url": "https://localhost:5001"
}
}
}
}
Se a configuração de recarregamento estiver habilitada e uma alteração for sinalizada, as seguintes etapas serão executadas:
- A nova configuração é comparada com a antiga e os pontos de extremidade sem alterações de configuração não são modificados.
- Os pontos de extremidade removidos ou modificados têm cinco segundos para concluir as solicitações de processamento e desligar.
- Pontos de extremidade novos ou modificados são iniciados.
Os clientes que se conectam a um ponto de extremidade modificado podem ser desconectados ou recusados enquanto o ponto de extremidade é reiniciado.
ConfigureHttpsDefaults
ConfigureHttpsDefaults(Action<HttpsConnectionAdapterOptions>) especifica uma configuração Action
a ser executada para cada ponto de extremidade HTTPS. Chamar ConfigureHttpsDefaults
várias vezes substitui as Action
s pela última Action
especificada.
webBuilder.ConfigureKestrel(serverOptions =>
{
serverOptions.ConfigureHttpsDefaults(listenOptions =>
{
// certificate is an X509Certificate2
listenOptions.ServerCertificate = certificate;
});
});
Observação
Os pontos de extremidade criados ao chamar Listen antes de chamar ConfigureHttpsDefaults não terão os padrões aplicados.
ListenOptions.UseHttps
Configure Kestrel para usar HTTPS.
Extensões ListenOptions.UseHttps
:
UseHttps
: configure o Kestrel para usar HTTPS com o certificado padrão. Gera uma exceção quando não há nenhum certificado padrão configurado.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)
Parâmetros de ListenOptions.UseHttps
:
filename
é o caminho e o nome do arquivo de um arquivo de certificado, relativo ao diretório que contém os arquivos de conteúdo do aplicativo.password
é a senha necessária para acessar os dados do certificado X.509 .configureOptions
é umaAction
para configurar asHttpsConnectionAdapterOptions
. Retorna oListenOptions
.storeName
é o repositório de certificados do qual o certificado deve ser carregado.subject
é o nome da entidade do certificado.allowInvalid
indica se certificados inválidos devem ser considerados, como os certificados autoassinados.location
é o local do repositório do qual o certificado deve ser carregado.serverCertificate
é o certificado X.509.
Em produção, HTTPS precisa ser configurado explicitamente. No mínimo, um certificado padrão precisa ser fornecido.
Configurações com suporte descritas a seguir:
- Nenhuma configuração
- Substituir o certificado padrão da configuração
- Alterar os padrões no código
Nenhuma configuração
O Kestrel escuta em http://localhost:5000
e em https://localhost:5001
(se houver um certificado padrão disponível).
Substituir o certificado padrão da configuração
Há um esquema de definições de configurações de aplicativo HTTPS padrão disponível para o Kestrel. Configure vários pontos de extremidade, incluindo URLs e os certificados a serem usados, por meio de um arquivo no disco ou de um repositório de certificados.
No exemplo appsettings.json
a seguir:
- Defina
AllowInvalid
comotrue
para permitir o uso de certificados inválidos (por exemplo, os certificados autoassinados). - Todo ponto de extremidade HTTPS que não especificar um certificado (
HttpsDefaultCert
no exemplo a seguir) será revertido para o certificado definido emCertificates:Default
ou para o certificado de desenvolvimento.
{
"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$"
}
}
}
}
Aviso
No exemplo anterior, as senhas de certificado são armazenadas em texto sem formatação em appsettings.json
. O token $CREDENTIAL_PLACEHOLDER$
é usado como um espaço reservado para a senha de cada certificado. Para armazenar senhas de certificado com segurança em ambientes de desenvolvimento, confira Proteger segredos em desenvolvimento. Para armazenar senhas de certificado com segurança em ambientes de produção, confira o provedor de configuração do Azure Key Vault. Os segredos de desenvolvimento não devem ser usados em produção ou teste.
Observações do esquema:
- Os nomes de pontos de extremidade não diferenciam maiúsculas de minúsculas. Por exemplo:
HTTPS
andHttps
são equivalentes. - O parâmetro
Url
é necessário para cada ponto de extremidade. O formato desse parâmetro é o mesmo que o do parâmetro de configuração deUrls
de nível superior, exceto que ele é limitado a um único valor. - Esses pontos de extremidade substituem aqueles definidos na configuração de
Urls
de nível superior em vez de serem adicionados a eles. Os pontos de extremidade definidos no código por meio deListen
são acumulados com os pontos de extremidade definidos na seção de configuração. - A seção
Certificate
é opcional. Se a seçãoCertificate
não for especificada, os padrões definidos emCertificates:Default
serão usados. Se nenhum padrão estiver disponível, o certificado de desenvolvimento será usado. Se não houver padrões e o certificado de desenvolvimento não estiver presente, o servidor gerará uma exceção e falhará ao iniciar. - A seção
Certificate
dá suporte a várias fontes de certificado. - Qualquer número de pontos de extremidade pode ser definido na Configuração, contanto que não causem conflitos de porta.
Fontes de certificado
Os nós de certificado podem ser configurados para carregar certificados de várias fontes:
Path
ePassword
para carregar arquivos .pfx.Path
,KeyPath
ePassword
para carregar arquivos .pem/.crt e .key.Subject
eStore
para carregar do repositório de certificados.
Por exemplo, o certificado Certificates:Default
pode ser especificado como:
"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}"))
retorna um KestrelConfigurationLoader com um método .Endpoint(string name, listenOptions => { })
que pode ser usado para complementar as definições de um ponto de extremidade configurado:
webBuilder.UseKestrel((context, serverOptions) =>
{
serverOptions.Configure(context.Configuration.GetSection("Kestrel"))
.Endpoint("HTTPS", listenOptions =>
{
listenOptions.HttpsOptions.SslProtocols = SslProtocols.Tls12;
});
});
KestrelServerOptions.ConfigurationLoader
pode ser acessado diretamente para continuar a iterar no carregador existente, por exemplo, o fornecido por CreateDefaultBuilder.
- A seção de configuração de cada ponto de extremidade está disponível nas opções no método
Endpoint
para que as configurações personalizadas possam ser lidas. - Várias configurações podem ser carregadas chamando
options.Configure(context.Configuration.GetSection("{SECTION}"))
novamente com outra seção. Somente a última configuração será usada, a menos queLoad
seja chamado explicitamente nas instâncias anteriores. O metapacote não chamaLoad
, portanto, sua seção de configuração padrão pode ser substituída. - O
KestrelConfigurationLoader
espelha a família de APIsListen
deKestrelServerOptions
como sobrecargas deEndpoint
, portanto, os pontos de extremidade de código e de configuração podem ser configurados no mesmo local. Essas sobrecargas não usam nomes e consomem somente as definições padrão da configuração.
Alterar os padrões no código
ConfigureEndpointDefaults
e ConfigureHttpsDefaults
podem ser usados para alterar as configurações padrão de ListenOptions
e HttpsConnectionAdapterOptions
, incluindo a substituição do certificado padrão especificado no cenário anterior. ConfigureEndpointDefaults
e ConfigureHttpsDefaults
devem ser chamados antes que qualquer ponto de extremidade seja configurado.
webBuilder.ConfigureKestrel(serverOptions =>
{
serverOptions.ConfigureEndpointDefaults(listenOptions =>
{
// Configure endpoint defaults
});
serverOptions.ConfigureHttpsDefaults(listenOptions =>
{
listenOptions.SslProtocols = SslProtocols.Tls12;
});
});
Configurar pontos de extremidade usando a Indicação de Nome de Servidor
A SNI (Indicação de Nome de Servidor) pode ser usada para hospedar vários domínios no mesmo endereço IP e na mesma porta. Para que a SNI funcione, o cliente envia o nome do host da sessão segura para o servidor durante o handshake TLS para que o servidor possa fornecer o certificado correto. O cliente usa o certificado fornecido para a comunicação criptografada com o servidor durante a sessão segura que segue o handshake TLS.
A SNI pode ser configurada de duas maneiras:
- Crie um ponto de extremidade no código e selecione um certificado usando o nome do host com o retorno de chamada ServerCertificateSelector.
- Configure um mapeamento entre nomes de host e opções HTTPS na Configuração. Por exemplo, JSON no arquivo
appsettings.json
.
SNI com ServerCertificateSelector
O Kestrel dá suporte à SNI por meio do retorno de chamada do ServerCertificateSelector
. O retorno de chamada é invocado uma vez por conexão para permitir que o aplicativo inspecione o nome do host e selecione o certificado apropriado. O código de retorno de chamada a seguir pode ser usado na chamada de método ConfigureWebHostDefaults
do arquivo Program.cs
de um projeto:
// 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 com ServerOptionsSelectionCallback
Kestrel dá suporte à configuração de TLS dinâmica adicional por meio do retorno de chamada ServerOptionsSelectionCallback
. O retorno de chamada é invocado uma vez por conexão para permitir que o aplicativo inspecione o nome do host e selecione o certificado e a configuração de TLS apropriados. Certificados padrão e ConfigureHttpsDefaults
não são usados com esse retorno de chamada.
// 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 na configuração
O Kestrel dá suporte à SNI definida na configuração. Um ponto de extremidade pode ser configurado com um objeto Sni
que contém um mapeamento entre nomes de host e opções HTTPS. O nome do host de conexão é correspondido com as opções e eles são usados nessa conexão.
A configuração a seguir adiciona um ponto de extremidade chamado MySniEndpoint
que usa SNI para selecionar opções HTTPS com base no nome do 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$"
}
}
}
}
Aviso
No exemplo anterior, as senhas de certificado são armazenadas em texto sem formatação em appsettings.json
. O token $CREDENTIAL_PLACEHOLDER$
é usado como um espaço reservado para a senha de cada certificado. Para armazenar senhas de certificado com segurança em ambientes de desenvolvimento, confira Proteger segredos em desenvolvimento. Para armazenar senhas de certificado com segurança em ambientes de produção, confira o provedor de configuração do Azure Key Vault. Os segredos de desenvolvimento não devem ser usados em produção ou teste.
Opções HTTPS que podem ser substituídas pela SNI:
Certificate
configura a origem do certificado.Protocols
configura os protocolos HTTP permitidos.SslProtocols
configura os protocolos SSL permitidos.ClientCertificateMode
configura os requisitos de certificado do cliente.
O nome do host dá suporte à correspondência de caractere curinga:
- Correspondência exata. Por exemplo,
a.example.org
corresponde aa.example.org
. - Prefixo de caractere curinga. Se houver várias correspondências de caractere curinga, o padrão mais longo será escolhido. Por exemplo,
*.example.org
corresponde ab.example.org
ec.example.org
. - Caractere curinga completo.
*
corresponde a todo o resto, incluindo clientes que não estão usando SNI nem enviam um nome de host.
A configuração de SNI correspondente é aplicada ao ponto de extremidade da conexão, substituindo valores no ponto de extremidade. Se uma conexão não corresponder a um nome de host SNI configurado, a conexão será recusada.
Requisitos de SNI
- Execução na estrutura de destino
netcoreapp2.1
ou posterior. Emnet461
ou posterior, o retorno de chamada é invocado, mas oname
é semprenull
. Oname
também seránull
se o cliente não fornecer o parâmetro de nome do host no handshake TLS. - Todos os sites são executados na mesma instância do Kestrel. O Kestrel não é compatível com o compartilhamento de endereço IP e porta entre várias instâncias sem um proxy reverso.
Protocolos SSL/TLS
Protocolos SSL são protocolos usados para criptografar e descriptografar o tráfego entre dois pares, tradicionalmente um cliente e um servidor.
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$"
}
}
}
}
}
Aviso
No exemplo anterior, a senha do certificado é armazenada em texto sem formatação em appsettings.json
. O token $CREDENTIAL_PLACEHOLDER$
é usado como um espaço reservado para a senha do certificado. Para armazenar senhas de certificado com segurança em ambientes de desenvolvimento, confira Proteger segredos em desenvolvimento. Para armazenar senhas de certificado com segurança em ambientes de produção, confira o provedor de configuração do Azure Key Vault. Os segredos de desenvolvimento não devem ser usados em produção ou teste.
O valor padrão, SslProtocols.None
, faz com que o Kestrel use os padrões do sistema operacional para escolher o melhor protocolo. A menos que você tenha um motivo específico para selecionar um protocolo, use o padrão.
Certificados do cliente
ClientCertificateMode
configura os requisitos de certificado do cliente.
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$"
}
}
}
}
}
Aviso
No exemplo anterior, a senha do certificado é armazenada em texto sem formatação em appsettings.json
. O token $CREDENTIAL_PLACEHOLDER$
é usado como um espaço reservado para a senha do certificado. Para armazenar senhas de certificado com segurança em ambientes de desenvolvimento, confira Proteger segredos em desenvolvimento. Para armazenar senhas de certificado com segurança em ambientes de produção, confira o provedor de configuração do Azure Key Vault. Os segredos de desenvolvimento não devem ser usados em produção ou teste.
O valor padrão é ClientCertificateMode.NoCertificate
, em que o Kestrel não solicitará ou exigirá um certificado do cliente.
Para obter mais informações, consulte Configurar a autenticação de certificado no ASP.NET Core.
Registro em log de conexão
Chame UseConnectionLogging para emitir logs de nível de Depuração para comunicação em nível de byte em uma conexão. O registro em log de conexão é útil para solucionar problemas na comunicação de baixo nível, como durante a criptografia TLS e por trás de proxies. Se UseConnectionLogging
for colocado antes de UseHttps
, o tráfego criptografado será registrado. Se UseConnectionLogging
for colocado depois de UseHttps
, o tráfego descriptografado será registrado. Este é o Middleware de Conexão interno.
webBuilder.ConfigureKestrel(serverOptions =>
{
serverOptions.Listen(IPAddress.Any, 8000, listenOptions =>
{
listenOptions.UseConnectionLogging();
});
});
Associar a um soquete TCP
O método Listen é associado a um soquete TCP, e um lambda de opções permite a configuração do certificado 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>();
});
O exemplo configura o HTTPS de um ponto de extremidade com ListenOptions. Use a mesma API para definir outras configurações do Kestrel para pontos de extremidade específicos.
No Windows, podem ser criados certificados autoassinados usando o New-SelfSignedCertificate
cmdlet do PowerShell. Para obter um exemplo sem suporte, confira UpdateIISExpressSSLForChrome.ps1
.
Nas plataformas macOS, Linux e Windows, é possível criar certificados usando o OpenSSL.
Associar a um soquete do UNIX
Escute em um soquete do UNIX com ListenUnixSocket para um melhor desempenho com o Nginx, conforme mostrado neste exemplo:
webBuilder.ConfigureKestrel(serverOptions =>
{
serverOptions.ListenUnixSocket("/tmp/kestrel-test.sock");
serverOptions.ListenUnixSocket("/tmp/kestrel-test.sock",
listenOptions =>
{
listenOptions.UseHttps("testCert.pfx",
"testpassword");
});
})
- No arquivo de configuração Nginx, defina a entrada
server
>location
>proxy_pass
comohttp://unix:/tmp/{KESTREL SOCKET}:/;
.{KESTREL SOCKET}
é o nome do soquete fornecido a ListenUnixSocket (por exemplo,kestrel-test.sock
no exemplo anterior). - Verifique se o Nginx pode gravar no soquete (por exemplo,
chmod go+w /tmp/kestrel-test.sock
).
Porta 0
Quando o número da porta 0
for especificado, o Kestrel se associará dinamicamente a uma porta disponível. O exemplo a seguir mostra como determinar a qual porta o Kestrel se associou no runtime:
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 o aplicativo é executado, a saída da janela do console indica a porta dinâmica na qual o aplicativo pode ser acessado:
Listening on the following addresses: http://127.0.0.1:48508
Limitações
Configure pontos de extremidade com as seguintes abordagens:
- UseUrls
- O argumento de linha de comando
--urls
- A chave de configuração do host
urls
- A variável de ambiente
ASPNETCORE_URLS
Esses métodos são úteis para fazer com que o código funcione com servidores que não sejam o Kestrel. No entanto, esteja ciente das seguintes limitações:
- O protocolo HTTPS não pode ser usado com essas abordagens, a menos que um certificado padrão seja fornecido na configuração do ponto de extremidade HTTPS (por exemplo, usando a configuração
KestrelServerOptions
ou um arquivo de configuração, como já foi mostrado neste artigo). - Quando ambas as abordagens,
Listen
eUseUrls
, são usadas ao mesmo tempo, os pontos de extremidade deListen
substituem os pontos de extremidade deUseUrls
.
Configuração de ponto de extremidade do IIS
Ao usar o IIS, as associações de URL para IIS substituem as associações definidas por Listen
ou UseUrls
. Para obter mais informações, consulte Módulo ASP.NET Core.
ListenOptions.Protocols
A propriedade Protocols
estabelece os protocolos HTTP (HttpProtocols
) habilitados em um ponto de extremidade de conexão ou para o servidor. Atribua um valor à propriedade Protocols
com base na enumeração HttpProtocols
.
Valor de enumeração HttpProtocols |
Protocolo de conexão permitido |
---|---|
Http1 |
HTTP/1.1 apenas. Pode ser usado com ou sem TLS. |
Http2 |
HTTP/2 apenas. Poderá ser usado sem TLS apenas se o cliente for compatível com um Modo de conhecimento prévio. |
Http1AndHttp2 |
HTTP/1.1 e HTTP/2. HTTP/2 requer que o cliente selecione HTTP/2 no handshake da ALPN (Application-Layer Protocol Negotiation) do TLS; caso contrário, a conexão assume o padrão de HTTP/1.1. |
O valor padrão de ListenOptions.Protocols
para qualquer ponto de extremidade é HttpProtocols.Http1AndHttp2
.
Restrições TLS para HTTP/2:
- Versão TLS 1.2 ou posterior
- Renegociação desabilitada
- Compactação desabilitada
- Tamanhos mínimos de troca de chaves efêmera:
- ECDHE (Diffie-Hellman de curva elíptica) [RFC4492]: mínimo de 224 bits
- DHE (Diffie-Hellman de campo finito) [
TLS12
]: mínimo de 2048 bits
- Pacote de criptografia não proibido.
Há suporte a TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
[TLS-ECDHE
] com a curva elíptica P-256 [FIPS186
] tem suporte por padrão.
O exemplo a seguir permite conexões HTTP/1.1 e HTTP/2 na porta 8000. As conexões são protegidas pela TLS com um certificado fornecido:
webBuilder.ConfigureKestrel(serverOptions =>
{
serverOptions.Listen(IPAddress.Any, 8000, listenOptions =>
{
listenOptions.UseHttps("testCert.pfx", "testPassword");
});
});
No Linux, CipherSuitesPolicy pode ser usado para filtrar handshakes TLS por conexão:
// 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 de Conexão
O middleware de conexão personalizado pode filtrar handshakes TLS por conexão em busca de criptografias específicas, se necessário.
O exemplo a seguir gera NotSupportedException para todo algoritmo de criptografia ao qual o aplicativo não dá suporte. Como alternativa, defina e compare ITlsHandshakeFeature.CipherAlgorithm a uma lista de conjuntos de criptografia aceitáveis.
Nenhuma criptografia é usada com um algoritmo de criptografia 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();
});
}
}
}
A filtragem de conexão também pode ser configurada por meio de um lambda IConnectionBuilder:
// 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();
});
});
});
Definir o protocolo HTTP com base na configuração
CreateDefaultBuilder
chama serverOptions.Configure(context.Configuration.GetSection("Kestrel"))
por padrão para carregar a configuração do Kestrel.
O exemplo appsettings.json
a seguir estabelece HTTP/1.1 como o protocolo de conexão padrão para todos os pontos de extremidade:
{
"Kestrel": {
"EndpointDefaults": {
"Protocols": "Http1"
}
}
}
O exemplo appsettings.json
a seguir estabelece o protocolo de conexão HTTP/1.1 para um ponto de extremidade específico:
{
"Kestrel": {
"Endpoints": {
"HttpsDefaultCert": {
"Url": "https://localhost:5001",
"Protocols": "Http1"
}
}
}
}
Os protocolos especificados no código substituem os valores definidos pela configuração.
Prefixos de URL
Ao usar UseUrls
, o argumento de linha de comando --urls
, a chave de configuração de host urls
ou a variável de ambiente ASPNETCORE_URLS
, os prefixos de URL podem estar em um dos formatos a seguir.
Somente os prefixos de URL HTTP são válidos. O Kestrel não é compatível com HTTPS ao configurar associações de URL que usam UseUrls
.
Endereço IPv4 com o número da porta
http://65.55.39.10:80/
0.0.0.0
é um caso especial que associa a todos os endereços IPv4.Endereço IPv6 com número da porta
http://[0:0:0:0:0:ffff:4137:270a]:80/
[::]
é o equivalente do IPv6 ao IPv40.0.0.0
.Nome do host com o número da porta
http://contoso.com:80/ http://*:80/
Os nomes de host
*
e+
não são especiais. Tudo o que não é reconhecido como um endereço IP ou umlocalhost
válido é associado a todos os IPs IPv6 e IPv4. Para associar nomes de host diferentes a diferentes aplicativos ASP.NET Core na mesma porta, use o HTTP.sys ou um servidor proxy reverso. Exemplos de servidor proxy reverso incluem IIS, Nginx ou Apache.Aviso
A hospedagem em uma configuração de proxy reverso exige a filtragem de host.
Nome do
localhost
do host com o número da porta ou o IP de loopback com o número da portahttp://localhost:5000/ http://127.0.0.1:5000/ http://[::1]:5000/
Quando o
localhost
for especificado, o Kestrel tentará se associar às interfaces de loopback IPv4 e IPv6. Se a porta solicitada está sendo usada por outro serviço em uma das interfaces de loopback, o Kestrel falha ao ser iniciado. Se uma das interfaces de loopback não estiver disponível por qualquer outro motivo (geralmente porque não há suporte para o IPv6), o Kestrel registra um aviso em log.