KestrelServidor Web no 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.

Por Tom Dykstra, Chris Ross e Stephen Halter

O Kestrel é um servidor Web multiplataforma para ASP.NET Core. Kestrel é o servidor recomendado para ASP.NET Core e é configurado por padrão em ASP.NET Core modelos de projeto.

Os recursos de Kestrel incluem:

  • Multiplataforma:Kestrel é um servidor Web multiplataforma executado no Windows, Linux e macOS.
  • Alto desempenho:Kestrel é otimizado para lidar com um grande número de conexões simultâneas com eficiência.
  • Leve: otimizado para execução em ambientes restritos a recursos, como contêineres e dispositivos de borda.
  • Segurança protegida:Kestrel dá suporte a HTTPS e é protegido contra vulnerabilidades do servidor Web.
  • Suporte amplo a protocolos:Kestrel dá suporte a protocolos Web comuns, incluindo:
  • Integração com o ASP.NET Core: integração perfeita com outros componentes ASP.NET Core, como o pipeline de middleware, injeção de dependência e sistema de configuração.
  • Cargas de trabalho flexíveis: Kestrel dá suporte a muitas cargas de trabalho:
    • Estruturas de aplicativo do ASP.NET, como APIs mínimas, MVC, páginas do Razor, SignalR, Blazor e gRPC.
    • Criando um proxy reverso com YARP.
  • Extensibilidade: Personalize Kestrel por meio de configuração, middleware e transportes personalizados.
  • Diagnóstico de desempenho:Kestrel fornece recursos internos de diagnóstico de desempenho, como registro em log e métricas.

Introdução

Os modelos de projeto do ASP.NET Core usam Kestrel por padrão quando não são hospedados com o IIS. No seguinte modelo gerado Program.cs, o método WebApplication.CreateBuilder chama UseKestrel internamente:

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

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

app.Run();

Para obter mais informações sobre como configurar WebApplication e WebApplicationBuilder, consulte Referência rápida de APIs mínimas.

Certificados do cliente opcionais

Para obter informações sobre aplicativos que precisam proteger um subconjunto do aplicativo com um certificado, consulte Certificados de cliente opcionais.

Comportamento com depurador anexado

Os seguintes tempos limite e limites de taxa não são impostos quando um depurador é anexado a um processo Kestrel:

Recursos adicionais

Observação

A partir do ASP.NET Core 5.0, o transporte libuv de Kestrel ficou obsoleto. O transporte libuv não recebe atualizações para dar suporte a novas plataformas do sistema operacional, como o Windows ARM64, e será removido em uma versão futura. Remova todas as chamadas para o método obsoleto UseLibuv e use, ao invés dele, o transporte de soquete padrão de Kestrel.

O Kestrel é um servidor Web multiplataforma para ASP.NET Core. O Kestrel é o servidor Web que está incluído por padrão em modelos de projeto do ASP.NET Core.

Kestrel oferece suporte aos seguintes cenários:

  • HTTPS
  • HTTP/2 (exceto em macOS†)
  • Atualização do Opaque usado para habilitar o WebSockets
  • Soquetes do UNIX para alto desempenho protegidos pelo Nginx

†O HTTP/2 será compatível com macOS em uma versão futura.

Há suporte para o Kestrel em todas as plataformas e versões compatíveis com o .NET Core.

Introdução

Os modelos de projeto do ASP.NET Core usam Kestrel por padrão quando não são hospedados com o IIS. No seguinte modelo gerado Program.cs, o método WebApplication.CreateBuilder chama UseKestrel internamente:

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

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

app.Run();

Para obter mais informações sobre como configurar WebApplication e WebApplicationBuilder, consulte Referência rápida de APIs mínimas.

Certificados do cliente opcionais

Para obter informações sobre aplicativos que precisam proteger um subconjunto do aplicativo com um certificado, consulte Certificados de cliente opcionais.

Comportamento com depurador anexado

Os seguintes tempos limite e limites de taxa não são impostos quando um depurador é anexado a um processo Kestrel:

Recursos adicionais

Observação

A partir do ASP.NET Core 5.0, o transporte libuv de Kestrel ficou obsoleto. O transporte libuv não recebe atualizações para dar suporte a novas plataformas do sistema operacional, como o Windows ARM64, e será removido em uma versão futura. Remova todas as chamadas para o método obsoleto UseLibuv e use, ao invés dele, o transporte de soquete padrão de Kestrel.

O Kestrel é um servidor Web multiplataforma para ASP.NET Core. O Kestrel é o servidor Web que está incluído por padrão em modelos de projeto do ASP.NET Core.

Kestrel oferece suporte aos seguintes cenários:

  • HTTPS
  • HTTP/2 (exceto em macOS†)
  • Atualização do Opaque usado para habilitar o WebSockets
  • Soquetes do UNIX para alto desempenho protegidos pelo Nginx

†O HTTP/2 será compatível com macOS em uma versão futura.

Há suporte para o Kestrel em todas as plataformas e versões compatíveis com o .NET Core.

Exibir ou baixar código de exemplo (como baixar)

Introdução

Os modelos de projeto do ASP.NET Core usam Kestrel por padrão quando não são hospedados com o IIS. Em Program.cs, o método ConfigureWebHostDefaults faz a chamada de UseKestrel:

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

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

Para obter mais informações sobre como criar o host, consulte as seções Configurar um host e configurações de construtor padrão do Host Genérico do .NET no ASP.NET Core.

Certificados do cliente opcionais

Para obter informações sobre aplicativos que precisam proteger um subconjunto do aplicativo com um certificado, consulte Certificados de cliente opcionais.

Recursos adicionais

Observação

A partir do ASP.NET Core 5.0, o transporte libuv de Kestrel ficou obsoleto. O transporte libuv não recebe atualizações para dar suporte a novas plataformas do sistema operacional, como o Windows ARM64, e será removido em uma versão futura. Remova todas as chamadas para o método obsoleto UseLibuv e use, ao invés dele, o transporte de soquete padrão de Kestrel.

O Kestrel é um servidor Web multiplataforma para ASP.NET Core. O Kestrel é o servidor Web que está incluído por padrão em modelos de projeto do ASP.NET Core.

Kestrel oferece suporte aos seguintes cenários:

  • HTTPS
  • Atualização do Opaque usado para habilitar o WebSockets
  • Soquetes do UNIX para alto desempenho protegidos pelo Nginx
  • HTTP/2 (exceto em macOS†)

†O HTTP/2 será compatível com macOS em uma versão futura.

Há suporte para o Kestrel em todas as plataformas e versões compatíveis com o .NET Core.

Exibir ou baixar código de exemplo (como baixar)

Suporte do HTTP/2

O HTTP/2 estará disponível para aplicativos ASP.NET Core se os seguintes requisitos básicos forem atendidos:

  • Sistema operacional†
    • Windows Server 2016/Windows 10 ou posterior‡
    • Linux com OpenSSL 1.0.2 ou posterior (por exemplo, Ubuntu 16.04 ou posterior)
  • Estrutura de destino: .NET Core 2.2 ou posterior
  • Conexão ALPN (Negociação de protocolo de camada de aplicativo)
  • Conexão TLS 1.2 ou posterior

O HTTP/2 será compatível com macOS em uma versão futura. ‡Kestrel tem suporte limitado para HTTP/2 no Windows Server 2012 R2 e Windows 8.1. O suporte é limitado porque a lista de conjuntos de codificação TLS disponível nesses sistemas operacionais é limitada. Um certificado gerado usando um ECDSA (Algoritmo de Assinatura Digital Curva Elíptica) pode ser necessário para proteger conexões TLS.

Se uma conexão HTTP/2 for estabelecida, HttpRequest.Protocol relatará HTTP/2.

A partir do .NET Core 3.0, o HTTP/2 está habilitado por padrão. Para obter mais informações sobre a configuração, consulte as seções Kestrelopções e ListenOptions.Protocols.

Quando usar o Kestrel com um proxy reverso

Kestrel pode ser usado por si só ou com um servidor proxy reverso. Um servidor proxy reverso recebe solicitações HTTP da rede e as encaminha para o Kestrel. Os exemplos de servidores proxy reversos incluem:

Kestrel usado como um servidor Web de borda (voltado para a Internet):

Kestrel se comunica diretamente com a Internet, sem um servidor proxy reverso

Kestrel usado em uma configuração de proxy reverso:

Kestrel se comunica indiretamente com a Internet através de um servidor proxy reverso, tal como o IIS, o Nginx ou o Apache

Qualquer configuração – com ou sem servidor proxy reverso, é uma configuração de hospedagem compatível.

O Kestrel usado como um servidor de borda sem servidor proxy reverso não dá suporte ao compartilhamento do mesmo IP e da mesma porta entre vários processos. Quando o Kestrel é configurado para escutar uma porta, o Kestrel manipula todo o tráfego dessa porta, independentemente dos cabeçalhos de Host das solicitações. Um proxy reverso que pode compartilhar portas tem a capacidade de encaminhar solicitações aoKestrel em um IP e em uma porta exclusivos.

Mesmo se um servidor proxy reverso não for necessário, o uso de um servidor proxy reverso poderá ser uma boa opção.

Um proxy reverso:

  • Pode limitar a área da superfície pública exposta dos aplicativos que ele hospeda.
  • Fornece uma camada adicional de configuração e de segurança cibernética de defesa aprofundada.
  • Pode ser integrado melhor à infraestrutura existente.
  • Simplifica o balanceamento de carga e a configuração de comunicação segura (HTTPS). Somente o servidor proxy reverso exige um certificado X.509, e esse servidor pode se comunicar com os servidores de aplicativos da rede interna usando HTTP simples.

Aviso

A hospedagem em uma configuração de proxy reverso requer a configuração de middleware de cabeçalhos encaminhados.

Kestrel nos aplicativos do ASP.NET Core

Os modelos de projeto do ASP.NET Core usam o Kestrel por padrão. Em Program.cs, o método ConfigureWebHostDefaults faz a chamada de UseKestrel:

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

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

Para obter mais informações sobre como criar o host, consulte as seções Configurar um host e configurações de construtor padrão do Host Genérico do .NET no ASP.NET Core.

Para fornecer configuração adicional após chamar ConfigureWebHostDefaults, use ConfigureKestrel:

public static IHostBuilder CreateHostBuilder(string[] args) =>
    Host.CreateDefaultBuilder(args)
        .ConfigureWebHostDefaults(webBuilder =>
        {
            webBuilder.ConfigureKestrel(serverOptions =>
            {
                // Set properties and call methods on options
            })
            .UseStartup<Startup>();
        });

Kestrel options

O servidor Web do Kestrel tem opções de configuração de restrição especialmente úteis em implantações para a Internet.

Defina restrições sobre a propriedade Limits da classe KestrelServerOptions. A propriedade Limits contém uma instância da classe KestrelServerLimits.

Os exemplos a seguir usam o namespace Microsoft.AspNetCore.Server.Kestrel.Core:

using Microsoft.AspNetCore.Server.Kestrel.Core;

Em exemplos mostrados posteriormente neste artigo, as opções Kestrel são configuradas no código C#. As opções Kestrel também podem ser definidas usando um provedor de configuração. Por exemplo, o Provedor de Configuração de Arquivos pode carregar a configuração Kestrel de um arquivo appsettings.json ou appsettings.{Environment}.json:

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

Observação

KestrelServerOptions e a configuração do ponto de extremidade são configuráveis de provedores de configuração. A configuração Kestrel restante deve ser configurada no código C#.

Use uma das abordagens a seguir:

  • Configurar Kestrel em Startup.ConfigureServices:

    1. Injete uma instância de IConfiguration na classe Startup. O exemplo a seguir pressupõe que a configuração injetada seja atribuída à propriedade Configuration.

    2. No Startup.ConfigureServices, carregue a seção de configuração Kestrel na configuração do Kestrel:

      using Microsoft.Extensions.Configuration
      
      public class Startup
      {
          public Startup(IConfiguration configuration)
          {
              Configuration = configuration;
          }
      
          public IConfiguration Configuration { get; }
      
          public void ConfigureServices(IServiceCollection services)
          {
              services.Configure<KestrelServerOptions>(
                  Configuration.GetSection("Kestrel"));
          }
      
          public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
          {
              ...
          }
      }
      
  • Configure Kestrel ao compilar o host:

    No Program.cs, carregue a seção de configuração Kestrel na configuração do Kestrel:

    // using Microsoft.Extensions.DependencyInjection;
    
    public static IHostBuilder CreateHostBuilder(string[] args) =>
        Host.CreateDefaultBuilder(args)
            .ConfigureServices((context, services) =>
            {
                services.Configure<KestrelServerOptions>(
                    context.Configuration.GetSection("Kestrel"));
            })
            .ConfigureWebHostDefaults(webBuilder =>
            {
                webBuilder.UseStartup<Startup>();
            });
    

Ambas as abordagens anteriores funcionam com qualquer provedor de configuração.

Tempo limite de keep-alive

KeepAliveTimeout

Obtém ou define o tempo limite de keep-alive. O padrão é de dois minutos.

webBuilder.ConfigureKestrel(serverOptions =>
{
    serverOptions.Limits.MaxConcurrentConnections = 100;
    serverOptions.Limits.MaxConcurrentUpgradedConnections = 100;
    serverOptions.Limits.MaxRequestBodySize = 10 * 1024;
    serverOptions.Limits.MinRequestBodyDataRate =
        new MinDataRate(bytesPerSecond: 100, 
            gracePeriod: TimeSpan.FromSeconds(10));
    serverOptions.Limits.MinResponseDataRate =
        new MinDataRate(bytesPerSecond: 100, 
            gracePeriod: TimeSpan.FromSeconds(10));
    serverOptions.Listen(IPAddress.Loopback, 5000);
    serverOptions.Listen(IPAddress.Loopback, 5001, 
        listenOptions =>
        {
            listenOptions.UseHttps("testCert.pfx", 
                "testPassword");
        });
    serverOptions.Limits.KeepAliveTimeout = 
        TimeSpan.FromMinutes(2);
    serverOptions.Limits.RequestHeadersTimeout = 
        TimeSpan.FromMinutes(1);
})

Número máximo de conexões de cliente

MaxConcurrentConnections MaxConcurrentUpgradedConnections

O número máximo de conexões TCP abertas simultâneas pode ser definido para o aplicativo inteiro com o código a seguir:

webBuilder.ConfigureKestrel(serverOptions =>
{
    serverOptions.Limits.MaxConcurrentConnections = 100;
    serverOptions.Limits.MaxConcurrentUpgradedConnections = 100;
    serverOptions.Limits.MaxRequestBodySize = 10 * 1024;
    serverOptions.Limits.MinRequestBodyDataRate =
        new MinDataRate(bytesPerSecond: 100, 
            gracePeriod: TimeSpan.FromSeconds(10));
    serverOptions.Limits.MinResponseDataRate =
        new MinDataRate(bytesPerSecond: 100, 
            gracePeriod: TimeSpan.FromSeconds(10));
    serverOptions.Listen(IPAddress.Loopback, 5000);
    serverOptions.Listen(IPAddress.Loopback, 5001, 
        listenOptions =>
        {
            listenOptions.UseHttps("testCert.pfx", 
                "testPassword");
        });
    serverOptions.Limits.KeepAliveTimeout = 
        TimeSpan.FromMinutes(2);
    serverOptions.Limits.RequestHeadersTimeout = 
        TimeSpan.FromMinutes(1);
})

Há um limite separado para conexões que foram atualizadas do HTTP ou HTTPS para outro protocolo (por exemplo, em uma solicitação do WebSockets). Depois que uma conexão é atualizada, ela não é contada em relação ao limite de MaxConcurrentConnections.

webBuilder.ConfigureKestrel(serverOptions =>
{
    serverOptions.Limits.MaxConcurrentConnections = 100;
    serverOptions.Limits.MaxConcurrentUpgradedConnections = 100;
    serverOptions.Limits.MaxRequestBodySize = 10 * 1024;
    serverOptions.Limits.MinRequestBodyDataRate =
        new MinDataRate(bytesPerSecond: 100, 
            gracePeriod: TimeSpan.FromSeconds(10));
    serverOptions.Limits.MinResponseDataRate =
        new MinDataRate(bytesPerSecond: 100, 
            gracePeriod: TimeSpan.FromSeconds(10));
    serverOptions.Listen(IPAddress.Loopback, 5000);
    serverOptions.Listen(IPAddress.Loopback, 5001, 
        listenOptions =>
        {
            listenOptions.UseHttps("testCert.pfx", 
                "testPassword");
        });
    serverOptions.Limits.KeepAliveTimeout = 
        TimeSpan.FromMinutes(2);
    serverOptions.Limits.RequestHeadersTimeout = 
        TimeSpan.FromMinutes(1);
})

O número máximo de conexões é ilimitado (nulo) por padrão.

Tamanho máximo do corpo da solicitação

MaxRequestBodySize

O tamanho máximo do corpo da solicitação padrão é de 30.000.000 bytes, que equivale aproximadamente a 28,6 MB.

A abordagem recomendada para substituir o limite em um aplicativo ASP.NET Core MVC é usar o atributo RequestSizeLimitAttribute em um método de ação:

[RequestSizeLimit(100000000)]
public IActionResult MyActionMethod()

Aqui está um exemplo que mostra como configurar a restrição para o aplicativo em cada solicitação:

webBuilder.ConfigureKestrel(serverOptions =>
{
    serverOptions.Limits.MaxConcurrentConnections = 100;
    serverOptions.Limits.MaxConcurrentUpgradedConnections = 100;
    serverOptions.Limits.MaxRequestBodySize = 10 * 1024;
    serverOptions.Limits.MinRequestBodyDataRate =
        new MinDataRate(bytesPerSecond: 100, 
            gracePeriod: TimeSpan.FromSeconds(10));
    serverOptions.Limits.MinResponseDataRate =
        new MinDataRate(bytesPerSecond: 100, 
            gracePeriod: TimeSpan.FromSeconds(10));
    serverOptions.Listen(IPAddress.Loopback, 5000);
    serverOptions.Listen(IPAddress.Loopback, 5001, 
        listenOptions =>
        {
            listenOptions.UseHttps("testCert.pfx", 
                "testPassword");
        });
    serverOptions.Limits.KeepAliveTimeout = 
        TimeSpan.FromMinutes(2);
    serverOptions.Limits.RequestHeadersTimeout = 
        TimeSpan.FromMinutes(1);
})

Substitua a configuração em uma solicitação específica no middleware:

app.Run(async (context) =>
{
    context.Features.Get<IHttpMaxRequestBodySizeFeature>()
        .MaxRequestBodySize = 10 * 1024;

    var minRequestRateFeature = 
        context.Features.Get<IHttpMinRequestBodyDataRateFeature>();
    var minResponseRateFeature = 
        context.Features.Get<IHttpMinResponseDataRateFeature>();

    if (minRequestRateFeature != null)
    {
        minRequestRateFeature.MinDataRate = new MinDataRate(
            bytesPerSecond: 100, gracePeriod: TimeSpan.FromSeconds(10));
    }

    if (minResponseRateFeature != null)
    {
        minResponseRateFeature.MinDataRate = new MinDataRate(
            bytesPerSecond: 100, gracePeriod: TimeSpan.FromSeconds(10));
    }

Uma exceção será gerada se o aplicativo configurar o limite em uma solicitação depois que o aplicativo começar a ler a solicitação. Há uma propriedade IsReadOnly que indica se a propriedade MaxRequestBodySize está no estado somente leitura, o que significa que é tarde demais para configurar o limite.

Quando um aplicativo é executado fora do processo por trás do Módulo do ASP.NET Core, o limite de tamanho do corpo da solicitação do Kestrel fica desabilitado, pois o IIS já define o limite.

Taxa de dados mínima do corpo da solicitação

MinRequestBodyDataRate MinResponseDataRate

O Kestrel verifica a cada segundo se os dados estão sendo recebidos na taxa especificada em bytes/segundo. Se a taxa cair abaixo do mínimo, a conexão atingirá o tempo limite. O período de cortesia é a quantidade de tempo que Kestrel dá ao cliente para aumentar sua taxa de envio até o mínimo; a taxa não é verificada durante esse período. O período de cortesia ajuda a evitar a remoção de conexões que inicialmente enviam dados em uma taxa baixa devido ao início lento do TCP.

A taxa mínima de padrão é de 240 bytes/segundo com um período de cortesia de 5 segundos.

Uma taxa mínima também se aplica à resposta. O código para definir o limite de solicitação e o limite de resposta é o mesmo, exceto por ter RequestBody ou Response nos nomes da propriedade e da interface.

Este é um exemplo que mostra como configurar as taxas mínima de dados em Program.cs:

webBuilder.ConfigureKestrel(serverOptions =>
{
    serverOptions.Limits.MaxConcurrentConnections = 100;
    serverOptions.Limits.MaxConcurrentUpgradedConnections = 100;
    serverOptions.Limits.MaxRequestBodySize = 10 * 1024;
    serverOptions.Limits.MinRequestBodyDataRate =
        new MinDataRate(bytesPerSecond: 100, 
            gracePeriod: TimeSpan.FromSeconds(10));
    serverOptions.Limits.MinResponseDataRate =
        new MinDataRate(bytesPerSecond: 100, 
            gracePeriod: TimeSpan.FromSeconds(10));
    serverOptions.Listen(IPAddress.Loopback, 5000);
    serverOptions.Listen(IPAddress.Loopback, 5001, 
        listenOptions =>
        {
            listenOptions.UseHttps("testCert.pfx", 
                "testPassword");
        });
    serverOptions.Limits.KeepAliveTimeout = 
        TimeSpan.FromMinutes(2);
    serverOptions.Limits.RequestHeadersTimeout = 
        TimeSpan.FromMinutes(1);
})

Substitua os limites de taxa mínima por solicitação no middleware:

app.Run(async (context) =>
{
    context.Features.Get<IHttpMaxRequestBodySizeFeature>()
        .MaxRequestBodySize = 10 * 1024;

    var minRequestRateFeature = 
        context.Features.Get<IHttpMinRequestBodyDataRateFeature>();
    var minResponseRateFeature = 
        context.Features.Get<IHttpMinResponseDataRateFeature>();

    if (minRequestRateFeature != null)
    {
        minRequestRateFeature.MinDataRate = new MinDataRate(
            bytesPerSecond: 100, gracePeriod: TimeSpan.FromSeconds(10));
    }

    if (minResponseRateFeature != null)
    {
        minResponseRateFeature.MinDataRate = new MinDataRate(
            bytesPerSecond: 100, gracePeriod: TimeSpan.FromSeconds(10));
    }

O IHttpMinResponseDataRateFeature referenciado no exemplo anterior não está presente no HttpContext.Features para solicitações HTTP/2, porque a modificação dos limites de taxa em cada solicitação não é geralmente compatível com HTTP/2 devido ao suporte de multiplexação de solicitação do protocolo. No entanto, o IHttpMinRequestBodyDataRateFeature ainda está presente em HttpContext.Features para solicitações HTTP/2, pois o limite de taxa de leitura ainda pode ser desabilitado totalmente em cada solicitação, definindo IHttpMinRequestBodyDataRateFeature.MinDataRate para null mesmo em uma solicitação HTTP/2. Tentar ler IHttpMinRequestBodyDataRateFeature.MinDataRate ou tentar defini-lo como um valor diferente de null resultará na geração de um NotSupportedException devido a uma solicitação HTTP/2.

Os limites de taxa de todo o servidor configurados por meio de KestrelServerOptions.Limits ainda se aplicam a conexões HTTP/1.x e HTTP/2.

Tempo limite dos cabeçalhos de solicitação

RequestHeadersTimeout

Obtém ou define a quantidade máxima de tempo que o servidor gasta recebendo cabeçalhos de solicitação. O padrão é 30 segundos.

webBuilder.ConfigureKestrel(serverOptions =>
{
    serverOptions.Limits.MaxConcurrentConnections = 100;
    serverOptions.Limits.MaxConcurrentUpgradedConnections = 100;
    serverOptions.Limits.MaxRequestBodySize = 10 * 1024;
    serverOptions.Limits.MinRequestBodyDataRate =
        new MinDataRate(bytesPerSecond: 100, 
            gracePeriod: TimeSpan.FromSeconds(10));
    serverOptions.Limits.MinResponseDataRate =
        new MinDataRate(bytesPerSecond: 100, 
            gracePeriod: TimeSpan.FromSeconds(10));
    serverOptions.Listen(IPAddress.Loopback, 5000);
    serverOptions.Listen(IPAddress.Loopback, 5001, 
        listenOptions =>
        {
            listenOptions.UseHttps("testCert.pfx", 
                "testPassword");
        });
    serverOptions.Limits.KeepAliveTimeout = 
        TimeSpan.FromMinutes(2);
    serverOptions.Limits.RequestHeadersTimeout = 
        TimeSpan.FromMinutes(1);
})

Fluxos máximos por conexão

O Http2.MaxStreamsPerConnection limita o número de fluxos de solicitações simultâneas por conexão HTTP/2. Os fluxos em excesso são recusados.

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

O valor padrão é 100.

Tamanho da tabela de cabeçalho

O decodificador HPACK descompacta os cabeçalhos HTTP para conexões HTTP/2. O Http2.HeaderTableSize limita o tamanho da tabela de compactação de cabeçalho usada pelo decodificador HPACK. O valor é fornecido em octetos e deve ser maior do que zero (0).

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

O valor padrão é 4096.

Tamanho máximo do quadro

Http2.MaxFrameSize indica o tamanho máximo permitido de uma carga do quadro da conexão HTTP/2 recebido ou enviado pelo servidor. O valor é fornecido em octetos e deve estar entre 2^14 (16.384) e 2^24-1 (16.777.215).

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

O valor padrão é 2^14 (16.384).

Tamanho máximo do cabeçalho de solicitação

Http2.MaxRequestHeaderFieldSize indica o tamanho máximo permitido em octetos de valores de cabeçalho de solicitação. Esse limite se aplica tanto ao nome quanto ao valor em suas representações compactadas e descompactadas. O valor deve ser maior que zero (0).

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

O valor padrão é 8.192.

Tamanho inicial da janela de conexão

Http2.InitialConnectionWindowSize indica os dados máximos do corpo da solicitação em bytes, que o servidor armazena em buffer ao mesmo tempo, agregados em todas as solicitações (fluxos) por conexão. As solicitações também são limitadas por Http2.InitialStreamWindowSize. O valor deve ser maior ou igual a 65.535 e menor que 2^31 (2.147.483.648).

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

O valor padrão é 128 KB (131.072).

Tamanho inicial da janela de fluxo

Http2.InitialStreamWindowSize indica o máximo de dados do corpo da solicitação, em bytes, que o servidor armazena em buffer ao mesmo tempo, por solicitação (fluxo). As solicitações também são limitadas por Http2.InitialConnectionWindowSize. O valor deve ser maior ou igual a 65.535 e menor que 2^31 (2.147.483.648).

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

O valor padrão é 96 KB (98.304).

Trailers

Os trailers HTTP são semelhantes aos cabeçalhos HTTP, exceto por serem enviados após o corpo da resposta ser enviado. Para IIS e HTTP.sys, há suporte apenas para trailers de resposta HTTP/2.

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

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

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

No código de exemplo anterior:

  • SupportsTrailers garante que os trailers sejam compatíveis com a resposta.
  • DeclareTrailer adiciona o nome do trailer fornecido ao cabeçalho de resposta Trailer. Declarar os trailers de uma resposta é opcional, mas recomendado. Se DeclareTrailer for chamado, deverá ser antes que os cabeçalhos de resposta sejam enviados.
  • O AppendTrailer acrescenta o trailer.

Redefinir

A opção Redefinir permite que o servidor redefina uma solicitação HTTP/2 com um código de erro especificado. Uma solicitação de redefinição é considerada anulada.

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

Reset no exemplo de código anterior especifica o código de erro INTERNAL_ERROR. Para obter mais informações sobre códigos de erro HTTP/2, visite a seção de código de erro de especificação HTTP/2.

E/S Síncrona

AllowSynchronousIO controla se a E/S síncrona é permitida para a solicitação e resposta. O valor padrão é false.

Aviso

Um grande número de operações de E/S síncronas de bloqueio pode levar à privação de pool de thread, o que faz com que o aplicativo não responda. Habilite AllowSynchronousIO somente ao usar uma biblioteca em que não há suporte para E/S assíncrona.

O exemplo a seguir ativa a E/S síncrona:

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

Para obter informações sobre outras opções e limites do Kestrel, confira:

Configuração de ponto de extremidade

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(Action<ListenOptions>)

Especifica uma Action de configuração 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.

ConfigureHttpsDefaults(Action<HttpsConnectionAdapterOptions>)

Especifica uma Action de configuração 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.

Configure(IConfiguration)

Cria um carregador de configuração para configurar o Kestrel que usa uma IConfiguration como entrada. A configuração precisa estar no escopo da seção de configuração do Kestrel.

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

CreateDefaultBuilder chama Configure(context.Configuration.GetSection("Kestrel")) por padrão para carregar a configuração do Kestrel. 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 Certificados>Padrão 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": "<certificate password>"
        }
      },
      "HttpsInlineCertStore": {
        "Url": "https://localhost:5002",
        "Certificate": {
          "Subject": "<subject; required>",
          "Store": "<certificate store; required>",
          "Location": "<location; defaults to CurrentUser>",
          "AllowInvalid": "<true or false; defaults to false>"
        }
      },
      "HttpsDefaultCert": {
        "Url": "https://localhost:5003"
      },
      "Https": {
        "Url": "https://*:5004",
        "Certificate": {
          "Path": "<path to .pfx file>",
          "Password": "<certificate password>"
        }
      }
    },
    "Certificates": {
      "Default": {
        "Path": "<path to .pfx file>",
        "Password": "<certificate password>"
      }
    }
  }
}

Uma alternativa ao uso de Caminho e Senha para qualquer nó de certificado é especificar o certificado usando campos de repositório de certificados. Por exemplo, o certificado Certificados>Padrão pode ser especificado como:

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

Observações do esquema:

  • Os nomes de pontos de extremidade diferenciam maiúsculas de minúsculas. Por exemplo, HTTPS e Https são válidos.
  • 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 nos cenários anteriores serão usados. Se não houver nenhum padrão disponível, o servidor gerará uma exceção e não poderá ser iniciado.
  • A seção Certificate é compatível com os certificados de CaminhoSenha e AssuntoRepositório.
  • Qualquer número de pontos de extremidade pode ser definido dessa forma, contanto que eles não causem conflitos de porta.
  • 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;
    });
});

KestrelSuporte para SNI

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.

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 suporte para SNI requer:

  • 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.
webBuilder.ConfigureKestrel(serverOptions =>
{
    serverOptions.ListenAnyIP(5005, listenOptions =>
    {
        listenOptions.UseHttps(httpsOptions =>
        {
            var localhostCert = CertificateLoader.LoadFromStoreCert(
                "localhost", "My", StoreLocation.CurrentUser,
                allowInvalid: true);
            var exampleCert = CertificateLoader.LoadFromStoreCert(
                "example.com", "My", StoreLocation.CurrentUser,
                allowInvalid: true);
            var subExampleCert = CertificateLoader.LoadFromStoreCert(
                "sub.example.com", "My", StoreLocation.CurrentUser,
                allowInvalid: true);
            var certs = new Dictionary<string, X509Certificate2>(
                StringComparer.OrdinalIgnoreCase);
            certs["localhost"] = localhostCert;
            certs["example.com"] = exampleCert;
            certs["sub.example.com"] = subExampleCert;

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

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

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.

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 realmente 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 tópico).
  • 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, confira o tópico Módulo do 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");
    });
});

O middleware de conexão personalizado pode filtrar handshakes TLS por conexão individual 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();
        });
    });
});

No Linux, CipherSuitesPolicy pode ser usado para filtrar handshakes TLS por conexão individual:

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

Definir o protocolo 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, como o IIS, o Nginx ou o Apache.

    Aviso

    A hospedagem em uma configuração de proxy reverso requer a configuração de middleware de cabeçalhos encaminhados.

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

Filtragem de host

Embora o Kestrel permita a configuração com base em prefixos como http://example.com:5000, o Kestrel geralmente ignora o nome do host. O host localhost é um caso especial usado para a associação a endereços de loopback. Todo host que não for um endereço IP explícito será associado a todos os endereços IP públicos. Cabeçalhos Host não são validados.

Como uma solução alternativa, use o Middleware de Filtragem de Host. O Middleware de Filtragem de Host é fornecido pelo pacote Microsoft.AspNetCore.HostFiltering, que é fornecido implicitamente para aplicativos ASP.NET Core. O middleware é adicionado pelo CreateDefaultBuilder, que chama AddHostFiltering:

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

    public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
        WebHost.CreateDefaultBuilder(args)
            .UseStartup<Startup>();
}

Middleware de Filtragem de Host está desabilitado por padrão. Para habilitar o middleware, defina uma chave AllowedHosts no appsettings.json/appsettings.{Environment}.json. O valor dessa chave é uma lista separada por ponto e vírgula de nomes de host sem números de porta:

appsettings.json:

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

Observação

Middleware de Cabeçalhos Encaminhados também tem uma opção AllowedHosts. Middleware de Cabeçalhos Encaminhados e Middleware de filtragem de Host têm funcionalidades semelhantes para cenários diferentes. A definição de AllowedHosts com Middleware de Cabeçalhos Encaminhados é apropriada quando o cabeçalho Host não é preservado ao encaminhar solicitações com um servidor proxy reverso ou um balanceador de carga. A definição de AllowedHosts com Middleware de Filtragem de Host é apropriada quando o Kestrel é usado como um servidor de borda voltado ao público ou quando o cabeçalho Host é encaminhado diretamente.

Para obter mais informações sobre Middleware de Cabeçalhos Encaminhados, veja Configurar o ASP.NET Core para funcionar com servidores proxy e balanceadores de carga.

Configuração de transporte libuv

Em projetos que exigem o uso do Libuv (UseLibuv):

  • Adicione uma dependência para o pacote Microsoft.AspNetCore.Server.Kestrel.Transport.Libuv ao arquivo de projeto do aplicativo:

    <PackageReference Include="Microsoft.AspNetCore.Server.Kestrel.Transport.Libuv"
                      Version="{VERSION}" />
    
  • Chame UseLibuv no IWebHostBuilder:

    public class Program
    {
        public static void Main(string[] args)
        {
            CreateHostBuilder(args).Build().Run();
        }
    
        public static IHostBuilder CreateHostBuilder(string[] args) =>
            Host.CreateDefaultBuilder(args)
                .ConfigureWebHostDefaults(webBuilder =>
                {
                    webBuilder.UseLibuv();
                    webBuilder.UseStartup<Startup>();
                });
    }
    

Esvaziamento de solicitações HTTP/1.1

Abrir conexões HTTP é algo demorado. Para HTTPS, o uso de recursos também é intensivo. Portanto, o Kestrel tenta reutilizar conexões de acordo com o protocolo HTTP/1.1. O corpo da solicitação deve ser consumido inteiramente para permitir o reúso da conexão. O aplicativo nem sempre consome o corpo da solicitação, como solicitações POST em que o servidor retorna um redirecionamento ou uma resposta 404. No caso de POST-redirect:

  • O cliente pode já ter enviado parte dos dados de POST.
  • O servidor grava a resposta 301.
  • A conexão não pode ser usada para uma nova solicitação até que os dados de POST do corpo da solicitação anterior sejam totalmente lidos.
  • Kestrel tenta esvaziar o corpo da solicitação. Esvaziar o corpo da solicitação significa ler e descartar os dados sem processá-los.

O processo de esvaziamento faz uma compensação entre permitir que a conexão seja reutilizado e o tempo necessário para esvaziar todos os dados restantes:

  • O esvaziamento tem um tempo limite de cinco segundos, o que não é configurável.
  • Se todos os dados especificados pelo Content-Length cabeçalho ou Transfer-Encoding não tiverem sido lidos antes do tempo limite, a conexão será fechada.

Às vezes, talvez você queira encerrar a solicitação imediatamente, antes ou depois de gravar a resposta. Por exemplo, os clientes podem ter limites de dados restritivos, portanto, limitar dados carregados pode ser uma prioridade. Em alguns casos, para encerrar uma solicitação, chame HttpContext.Abort de um controlador, Página do Razor ou middleware.

Há ressalvas para chamar Abort:

  • A criação de novas conexões pode ser lenta e cara.
  • Não há garantia de que o cliente tenha lido a resposta antes do fechamento da conexão.
  • A chamada Abort deve ser rara e reservada para casos de erro graves, não erros comuns.
    • Chame apenas Abort quando um problema específico precisar ser resolvido. Por exemplo, chame Abort se clientes mal-intencionados estiverem tentando dados POST ou quando houver um bug no código do cliente que cause muitas solicitações ou solicitações grandes.
    • Não chame Abort para situações de erro comuns, como HTTP 404 (Não Encontrado).

Chamar HttpResponse.CompleteAsync antes de chamar Abort garante que o servidor tenha concluído a gravação da resposta. No entanto, o comportamento do cliente não é previsível e eles podem não ler a resposta antes que a conexão seja anulada.

Esse processo é diferente para HTTP/2 porque o protocolo dá suporte à anulação de fluxos de solicitação individuais sem fechar a conexão. O tempo limite de esvaziamento de cinco segundos não se aplica. Se houver dados do corpo da solicitação não lidos após a conclusão de uma resposta, o servidor enviará um quadro HTTP/2 RST. Os quadros de dados do corpo da solicitação adicionais são ignorados.

Se possível, é melhor que os clientes usem o cabeçalho de solicitação Expect: 100-continue e aguardem até que o servidor responda antes de começar a enviar o corpo da solicitação. Isso dá ao cliente a oportunidade de examinar a resposta e anular antes de enviar dados desnecessários.

Recursos adicionais