Compartilhar via


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étodo UseHttps.

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

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 IPv4 0.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 porta

    http://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 de IConfiguration 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 chama Load, portanto, sua seção de configuração padrão pode ser substituída.
  • O KestrelConfigurationLoader espelha a família de APIs Listen de KestrelServerOptions como sobrecargas de Endpoint, 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:

No Windows, podem ser criados certificados autoassinados usando o New-SelfSignedCertificatecmdlet 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 como http://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:

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:

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 and Https 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 de Urls 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 de Listen são acumulados com os pontos de extremidade definidos na seção de configuração.
  • A seção Certificate é opcional. Se a seção Certificate não for especificada, os padrões definidos em Certificates: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 e Password para carregar arquivos .pfx.
  • Path, KeyPath e Password para carregar arquivos .pem/.crt e .key.
  • Subject e Store 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 é uma Action para configurar as HttpsConnectionAdapterOptions. Retorna o ListenOptions.
  • 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:

O nome do host dá suporte à correspondência de caractere curinga:

  • Correspondência exata. Por exemplo, a.example.org corresponde a a.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 a b.example.org e c.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:

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 Actions 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 Actions 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 é uma Action para configurar as HttpsConnectionAdapterOptions. Retorna o ListenOptions.
  • 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 como true 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 em Certificates: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 and Https 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 de Urls 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 de Listen são acumulados com os pontos de extremidade definidos na seção de configuração.
  • A seção Certificate é opcional. Se a seção Certificate não for especificada, os padrões definidos em Certificates: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 e Password para carregar arquivos .pfx.
  • Path, KeyPath e Password para carregar arquivos .pem/.crt e .key.
  • Subject e Store 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 chama Load, portanto, sua seção de configuração padrão pode ser substituída.
  • O KestrelConfigurationLoader espelha a família de APIs Listen de KestrelServerOptions como sobrecargas de Endpoint, 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:

O nome do host dá suporte à correspondência de caractere curinga:

  • Correspondência exata. Por exemplo, a.example.org corresponde a a.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 a b.example.org e c.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-SelfSignedCertificatecmdlet 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 como http://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 e UseUrls, são usadas ao mesmo tempo, os pontos de extremidade de Listen substituem os pontos de extremidade de UseUrls.

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 IPv4 0.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 um localhost 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 porta

    http://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:

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 Actions 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 Actions 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 é uma Action para configurar as HttpsConnectionAdapterOptions. Retorna o ListenOptions.
  • 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 como true 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 em Certificates: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 and Https 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 de Urls 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 de Listen são acumulados com os pontos de extremidade definidos na seção de configuração.
  • A seção Certificate é opcional. Se a seção Certificate não for especificada, os padrões definidos em Certificates: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 e Password para carregar arquivos .pfx.
  • Path, KeyPath e Password para carregar arquivos .pem/.crt e .key.
  • Subject e Store 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 chama Load, portanto, sua seção de configuração padrão pode ser substituída.
  • O KestrelConfigurationLoader espelha a família de APIs Listen de KestrelServerOptions como sobrecargas de Endpoint, 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:

O nome do host dá suporte à correspondência de caractere curinga:

  • Correspondência exata. Por exemplo, a.example.org corresponde a a.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 a b.example.org e c.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-SelfSignedCertificatecmdlet 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 como http://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 e UseUrls, são usadas ao mesmo tempo, os pontos de extremidade de Listen substituem os pontos de extremidade de UseUrls.

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 IPv4 0.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 um localhost 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 porta

    http://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:

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 Actions 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 Actions 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 é uma Action para configurar as HttpsConnectionAdapterOptions. Retorna o ListenOptions.
  • 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 como true 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 em Certificates: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 and Https 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 de Urls 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 de Listen são acumulados com os pontos de extremidade definidos na seção de configuração.
  • A seção Certificate é opcional. Se a seção Certificate não for especificada, os padrões definidos em Certificates: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 e Password para carregar arquivos .pfx.
  • Path, KeyPath e Password para carregar arquivos .pem/.crt e .key.
  • Subject e Store 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 que Load seja chamado explicitamente nas instâncias anteriores. O metapacote não chama Load, portanto, sua seção de configuração padrão pode ser substituída.
  • O KestrelConfigurationLoader espelha a família de APIs Listen de KestrelServerOptions como sobrecargas de Endpoint, 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:

O nome do host dá suporte à correspondência de caractere curinga:

  • Correspondência exata. Por exemplo, a.example.org corresponde a a.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 a b.example.org e c.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. Em net461 ou posterior, o retorno de chamada é invocado, mas o name é sempre null. O name 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-SelfSignedCertificatecmdlet 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 como http://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 e UseUrls, são usadas ao mesmo tempo, os pontos de extremidade de Listen substituem os pontos de extremidade de UseUrls.

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 IPv4 0.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 um localhost 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 porta

    http://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.