ASP.NET Core 中的 Kestrel Web 服务器实现Kestrel web server implementation in ASP.NET Core

作者:Tom DykstraChris RossStephen HalterBy Tom Dykstra, Chris Ross, and Stephen Halter

Kestrel 是一个跨平台的适用于 ASP.NET Core 的 Web 服务器Kestrel is a cross-platform web server for ASP.NET Core. Kestrel 是 Web 服务器,默认包括在 ASP.NET Core 项目模板中。Kestrel is the web server that's included by default in ASP.NET Core project templates.

Kestrel 支持以下方案:Kestrel supports the following scenarios:

  • HTTPSHTTPS
  • 用于启用 WebSocket 的不透明升级Opaque upgrade used to enable WebSockets
  • 用于获得 Nginx 高性能的 Unix 套接字Unix sockets for high performance behind Nginx
  • HTTP/2(除 macOS† 以外)HTTP/2 (except on macOS†)

macOS 的未来版本将支持 †HTTP/2。†HTTP/2 will be supported on macOS in a future release.

  • HTTPSHTTPS
  • 用于启用 WebSocket 的不透明升级Opaque upgrade used to enable WebSockets
  • 用于获得 Nginx 高性能的 Unix 套接字Unix sockets for high performance behind Nginx

.NET Core 支持的所有平台和版本均支持 Kestrel。Kestrel is supported on all platforms and versions that .NET Core supports.

查看或下载示例代码如何下载View or download sample code (how to download)

HTTP/2 支持HTTP/2 support

如果满足以下基本要求,将为 ASP.NET Core 应用提供 HTTP/2HTTP/2 is available for ASP.NET Core apps if the following base requirements are met:

  • 操作系统†Operating system†
    • Windows Server 2016/Windows 10 或更高版本‡Windows Server 2016/Windows 10 or later‡
    • 具有 OpenSSL 1.0.2 或更高版本的 Linux(例如,Ubuntu 16.04 或更高版本)Linux with OpenSSL 1.0.2 or later (for example, Ubuntu 16.04 or later)
  • 目标框架:.NET Core 2.2 或更高版本Target framework: .NET Core 2.2 or later
  • 应用程序层协议协商 (ALPN) 连接Application-Layer Protocol Negotiation (ALPN) connection
  • TLS 1.2 或更高版本的连接TLS 1.2 or later connection

macOS 的未来版本将支持 †HTTP/2。†HTTP/2 will be supported on macOS in a future release. ‡Kestrel 在 Windows Server 2012 R2 和 Windows 8.1 上对 HTTP/2 的支持有限。‡Kestrel has limited support for HTTP/2 on Windows Server 2012 R2 and Windows 8.1. 支持受限是因为可在这些操作系统上使用的受支持 TLS 密码套件列表有限。Support is limited because the list of supported TLS cipher suites available on these operating systems is limited. 可能需要使用椭圆曲线数字签名算法 (ECDSA) 生成的证书来保护 TLS 连接。A certificate generated using an Elliptic Curve Digital Signature Algorithm (ECDSA) may be required to secure TLS connections.

如果已建立 HTTP/2 连接,HttpRequest.Protocol 会报告 HTTP/2If an HTTP/2 connection is established, HttpRequest.Protocol reports HTTP/2.

默认情况下,禁用 HTTP/2。HTTP/2 is disabled by default. 有关配置的详细信息,请参阅 Kestrel 选项ListenOptions.Protocols 部分。For more information on configuration, see the Kestrel options and ListenOptions.Protocols sections.

何时结合使用 Kestrel 和反向代理When to use Kestrel with a reverse proxy

可以单独使用 Kestrel,也可以将其与反向代理服务器 (如 Internet Information Services (IIS)NginxApache)结合使用。Kestrel can be used by itself or with a reverse proxy server, such as Internet Information Services (IIS), Nginx, or Apache. 反向代理服务器接收来自网络的 HTTP 请求,并将这些请求转发到 Kestrel。A reverse proxy server receives HTTP requests from the network and forwards them to Kestrel.

Kestrel 用作边缘(面向 Internet)Web 服务器:Kestrel used as an edge (Internet-facing) web server:

Kestrel 直接与 Internet 通信,不使用反向代理服务器

Kestrel 用于反向代理配置:Kestrel used in a reverse proxy configuration:

Kestrel 通过反向代理服务器(如 IIS、Nginx 或 Apache)间接与 Internet 进行通信

无论配置是否使用反向代理服务器——,都是从 Internet 接收请求的 ASP.NET Core 2.1 或更高版本应用的支持托管配置。Either configuration—with or without a reverse proxy server—is a supported hosting configuration for ASP.NET Core 2.1 or later apps that receive requests from the Internet.

在没有反向代理服务器的情况下用作边缘服务器的 Kestrel 不支持在多个进程间共享相同的 IP 和端口。Kestrel used as an edge server without a reverse proxy server doesn't support sharing the same IP and port among multiple processes. 如果将 Kestrel 配置为侦听某个端口,Kestrel 会处理该端口的所有流量(无视请求的 Host 标头)。When Kestrel is configured to listen on a port, Kestrel handles all of the traffic for that port regardless of requests' Host headers. 可以共享端口的反向代理能在唯一的 IP 和端口上将请求转发至 Kestrel。A reverse proxy that can share ports has the ability to forward requests to Kestrel on a unique IP and port.

即使不需要反向代理服务器,使用反向代理服务器可能也是个不错的选择。Even if a reverse proxy server isn't required, using a reverse proxy server might be a good choice.

反向代理:A reverse proxy:

  • 可以限制所承载的应用中的公开的公共外围应用。Can limit the exposed public surface area of the apps that it hosts.
  • 提供额外的配置和防护层。Provide an additional layer of configuration and defense.
  • 可以更好地与现有基础结构集成。Might integrate better with existing infrastructure.
  • 简化了负载均和和安全通信 (HTTPS) 配置。Simplify load balancing and secure communication (HTTPS) configuration. 仅反向代理服务器需要 X.509 证书,并且该服务器可使用普通 HTTP 在内部网络上与应用服务器通信。Only the reverse proxy server requires an X.509 certificate, and that server can communicate with your app servers on the internal network using plain HTTP.

警告

采用反向代理配置进行托管需要主机筛选Hosting in a reverse proxy configuration requires host filtering.

如何在 ASP.NET Core 应用中使用 KestrelHow to use Kestrel in ASP.NET Core apps

Microsoft.AspNetCore.App 元包中包括 Microsoft.AspNetCore.Server.Kestrel 包(ASP.NET Core 2.1 或更高版本)。The Microsoft.AspNetCore.Server.Kestrel package is included in the Microsoft.AspNetCore.App metapackage (ASP.NET Core 2.1 or later).

默认情况下,ASP.NET Core 项目模板使用 Kestrel。ASP.NET Core project templates use Kestrel by default. 在 Program.cs 中,模板代码调用 CreateDefaultBuilder,后者在后台调用 UseKestrelIn Program.cs, the template code calls CreateDefaultBuilder, which calls UseKestrel behind the scenes.

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

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

若要在调用 CreateDefaultBuilder 后提供其他配置,请使用 ConfigureKestrelTo provide additional configuration after calling CreateDefaultBuilder, use ConfigureKestrel:

public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
    WebHost.CreateDefaultBuilder(args)
        .UseStartup<Startup>()
        .ConfigureKestrel((context, options) =>
        {
            // Set properties and call methods on options
        });

如果应用未调用 CreateDefaultBuilder 来设置主机,请在调用 ConfigureKestrel 之前 先调用 UseKestrelIf the app doesn't call CreateDefaultBuilder to set up the host, call UseKestrel before calling ConfigureKestrel:

public static void Main(string[] args)
{
    var host = new WebHostBuilder()
        .UseContentRoot(Directory.GetCurrentDirectory())
        .UseKestrel()
        .UseIISIntegration()
        .UseStartup<Startup>()
        .ConfigureKestrel((context, options) =>
        {
            // Set properties and call methods on options
        })
        .Build();

    host.Run();
}

若要在调用 CreateDefaultBuilder 后提供其他配置,请调用 UseKestrelTo provide additional configuration after calling CreateDefaultBuilder, call UseKestrel:

public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
    WebHost.CreateDefaultBuilder(args)
        .UseStartup<Startup>()
        .UseKestrel(options =>
        {
            // Set properties and call methods on options
        });

Kestrel 选项Kestrel options

Kestrel Web 服务器具有约束配置选项,这些选项在面向 Internet 的部署中尤其有用。The Kestrel web server has constraint configuration options that are especially useful in Internet-facing deployments.

KestrelServerOptions 类的 Limits 属性设置约束。Set constraints on the Limits property of the KestrelServerOptions class. Limits 属性包含 KestrelServerLimits 类的实例。The Limits property holds an instance of the KestrelServerLimits class.

下面的示例使用 Microsoft.AspNetCore.Server.Kestrel.Core 命名空间。The following examples use the Microsoft.AspNetCore.Server.Kestrel.Core namespace:

using Microsoft.AspNetCore.Server.Kestrel.Core;

保持活动状态超时Keep-alive timeout

KeepAliveTimeout

获取或设置保持活动状态超时Gets or sets the keep-alive timeout. 默认值为 2 分钟。Defaults to 2 minutes.

.ConfigureKestrel((context, options) =>
{
    options.Limits.MaxConcurrentConnections = 100;
    options.Limits.MaxConcurrentUpgradedConnections = 100;
    options.Limits.MaxRequestBodySize = 10 * 1024;
    options.Limits.MinRequestBodyDataRate =
        new MinDataRate(bytesPerSecond: 100, gracePeriod: TimeSpan.FromSeconds(10));
    options.Limits.MinResponseDataRate =
        new MinDataRate(bytesPerSecond: 100, gracePeriod: TimeSpan.FromSeconds(10));
    options.Listen(IPAddress.Loopback, 5000);
    options.Listen(IPAddress.Loopback, 5001, listenOptions =>
    {
        listenOptions.UseHttps("testCert.pfx", "testPassword");
    });
    options.Limits.KeepAliveTimeout = TimeSpan.FromMinutes(2);
    options.Limits.RequestHeadersTimeout = TimeSpan.FromMinutes(1);
});
public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
    WebHost.CreateDefaultBuilder(args)
        .UseStartup<Startup>()
        .UseKestrel(options =>
        {
            options.Limits.KeepAliveTimeout = TimeSpan.FromMinutes(2);
        });

客户端最大连接数Maximum client connections

MaxConcurrentConnections
MaxConcurrentUpgradedConnections

可使用以下代码为整个应用设置并发打开的最大 TCP 连接数:The maximum number of concurrent open TCP connections can be set for the entire app with the following code:

.ConfigureKestrel((context, options) =>
{
    options.Limits.MaxConcurrentConnections = 100;
    options.Limits.MaxConcurrentUpgradedConnections = 100;
    options.Limits.MaxRequestBodySize = 10 * 1024;
    options.Limits.MinRequestBodyDataRate =
        new MinDataRate(bytesPerSecond: 100, gracePeriod: TimeSpan.FromSeconds(10));
    options.Limits.MinResponseDataRate =
        new MinDataRate(bytesPerSecond: 100, gracePeriod: TimeSpan.FromSeconds(10));
    options.Listen(IPAddress.Loopback, 5000);
    options.Listen(IPAddress.Loopback, 5001, listenOptions =>
    {
        listenOptions.UseHttps("testCert.pfx", "testPassword");
    });
    options.Limits.KeepAliveTimeout = TimeSpan.FromMinutes(2);
    options.Limits.RequestHeadersTimeout = TimeSpan.FromMinutes(1);
});
public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
    WebHost.CreateDefaultBuilder(args)
        .UseStartup<Startup>()
        .UseKestrel(options =>
        {
            options.Limits.MaxConcurrentConnections = 100;
        });

对于已从 HTTP 或 HTTPS 升级到另一个协议(例如,Websocket 请求)的连接,有一个单独的限制。There's a separate limit for connections that have been upgraded from HTTP or HTTPS to another protocol (for example, on a WebSockets request). 连接升级后,不会计入 MaxConcurrentConnections 限制。After a connection is upgraded, it isn't counted against the MaxConcurrentConnections limit.

.ConfigureKestrel((context, options) =>
{
    options.Limits.MaxConcurrentConnections = 100;
    options.Limits.MaxConcurrentUpgradedConnections = 100;
    options.Limits.MaxRequestBodySize = 10 * 1024;
    options.Limits.MinRequestBodyDataRate =
        new MinDataRate(bytesPerSecond: 100, gracePeriod: TimeSpan.FromSeconds(10));
    options.Limits.MinResponseDataRate =
        new MinDataRate(bytesPerSecond: 100, gracePeriod: TimeSpan.FromSeconds(10));
    options.Listen(IPAddress.Loopback, 5000);
    options.Listen(IPAddress.Loopback, 5001, listenOptions =>
    {
        listenOptions.UseHttps("testCert.pfx", "testPassword");
    });
    options.Limits.KeepAliveTimeout = TimeSpan.FromMinutes(2);
    options.Limits.RequestHeadersTimeout = TimeSpan.FromMinutes(1);
});
public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
    WebHost.CreateDefaultBuilder(args)
        .UseStartup<Startup>()
        .UseKestrel(options =>
        {
            options.Limits.MaxConcurrentUpgradedConnections = 100;
        });

默认情况下,最大连接数不受限制 (NULL)。The maximum number of connections is unlimited (null) by default.

请求正文最大大小Maximum request body size

MaxRequestBodySize

默认的请求正文最大大小为 30,000,000 字节,大约 28.6 MB。The default maximum request body size is 30,000,000 bytes, which is approximately 28.6 MB.

在 ASP.NET Core MVC 应用中替代限制的推荐方法是在操作方法上使用 RequestSizeLimitAttribute 属性:The recommended approach to override the limit in an ASP.NET Core MVC app is to use the RequestSizeLimitAttribute attribute on an action method:

[RequestSizeLimit(100000000)]
public IActionResult MyActionMethod()

以下示例演示如何为每个请求上的应用配置约束:Here's an example that shows how to configure the constraint for the app on every request:

.ConfigureKestrel((context, options) =>
{
    options.Limits.MaxConcurrentConnections = 100;
    options.Limits.MaxConcurrentUpgradedConnections = 100;
    options.Limits.MaxRequestBodySize = 10 * 1024;
    options.Limits.MinRequestBodyDataRate =
        new MinDataRate(bytesPerSecond: 100, gracePeriod: TimeSpan.FromSeconds(10));
    options.Limits.MinResponseDataRate =
        new MinDataRate(bytesPerSecond: 100, gracePeriod: TimeSpan.FromSeconds(10));
    options.Listen(IPAddress.Loopback, 5000);
    options.Listen(IPAddress.Loopback, 5001, listenOptions =>
    {
        listenOptions.UseHttps("testCert.pfx", "testPassword");
    });
    options.Limits.KeepAliveTimeout = TimeSpan.FromMinutes(2);
    options.Limits.RequestHeadersTimeout = TimeSpan.FromMinutes(1);
});
public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
    WebHost.CreateDefaultBuilder(args)
        .UseStartup<Startup>()
        .UseKestrel(options =>
        {
            options.Limits.MaxRequestBodySize = 10 * 1024;
        });

可在中间件中替代特定请求的设置:You can override the setting on a specific request in 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));
    }

如果在应用开始读取请求后尝试配置请求限制,则会引发异常。An exception is thrown if you attempt to configure the limit on a request after the app has started to read the request. IsReadOnly 属性指示 MaxRequestBodySize 属性处于只读状态,意味已经无法再配置限制。There's an IsReadOnly property that indicates if the MaxRequestBodySize property is in read-only state, meaning it's too late to configure the limit.

当应用在 ASP.NET Core 模块后于进程外运行时,由于 IIS 已设置限制,因此禁用了 Kestrel 的请求正文大小限制。When an app is run out-of-process behind the ASP.NET Core Module, Kestrel's request body size limit is disabled because IIS already sets the limit.

请求正文最小数据速率Minimum request body data rate

MinRequestBodyDataRate
MinResponseDataRate

Kestrel 每秒检查一次数据是否以指定的速率(字节/秒)传入。Kestrel checks every second if data is arriving at the specified rate in bytes/second. 如果速率低于最小值,则连接超时。宽限期是 Kestrel 提供给客户端用于将其发送速率提升到最小值的时间量;在此期间不会检查速率。If the rate drops below the minimum, the connection is timed out. The grace period is the amount of time that Kestrel gives the client to increase its send rate up to the minimum; the rate isn't checked during that time. 宽限期有助于避免最初由于 TCP 慢启动而以较慢速率发送数据的连接中断。The grace period helps avoid dropping connections that are initially sending data at a slow rate due to TCP slow-start.

默认的最小速率为 240 字节/秒,包含 5 秒的宽限期。The default minimum rate is 240 bytes/second with a 5 second grace period.

最小速率也适用于响应。A minimum rate also applies to the response. 除了属性和接口名称中具有 RequestBodyResponse 以外,用于设置请求限制和响应限制的代码相同。The code to set the request limit and the response limit is the same except for having RequestBody or Response in the property and interface names.

以下示例演示如何在 Program.cs 中配置最小数据速率 :Here's an example that shows how to configure the minimum data rates in Program.cs:

.ConfigureKestrel((context, options) =>
{
    options.Limits.MaxConcurrentConnections = 100;
    options.Limits.MaxConcurrentUpgradedConnections = 100;
    options.Limits.MaxRequestBodySize = 10 * 1024;
    options.Limits.MinRequestBodyDataRate =
        new MinDataRate(bytesPerSecond: 100, gracePeriod: TimeSpan.FromSeconds(10));
    options.Limits.MinResponseDataRate =
        new MinDataRate(bytesPerSecond: 100, gracePeriod: TimeSpan.FromSeconds(10));
    options.Listen(IPAddress.Loopback, 5000);
    options.Listen(IPAddress.Loopback, 5001, listenOptions =>
    {
        listenOptions.UseHttps("testCert.pfx", "testPassword");
    });
    options.Limits.KeepAliveTimeout = TimeSpan.FromMinutes(2);
    options.Limits.RequestHeadersTimeout = TimeSpan.FromMinutes(1);
});
public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
    WebHost.CreateDefaultBuilder(args)
        .UseStartup<Startup>()
        .UseKestrel(options =>
        {
            options.Limits.MinRequestBodyDataRate =
                new MinDataRate(bytesPerSecond: 100, gracePeriod: TimeSpan.FromSeconds(10));
            options.Limits.MinResponseDataRate =
                new MinDataRate(bytesPerSecond: 100, gracePeriod: TimeSpan.FromSeconds(10));
        });

可以在中间件中替代每个请求的最低速率限制:You can override the minimum rate limits per request in 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));
    }

由于协议支持请求多路复用,HTTP/2 不支持基于每个请求修改速率限制,因此 HTTP/2 请求的 HttpContext.Features 中不存在前面示例中引用的速率特性。Neither rate feature referenced in the prior sample are present in HttpContext.Features for HTTP/2 requests because modifying rate limits on a per-request basis isn't supported for HTTP/2 due to the protocol's support for request multiplexing. 通过 KestrelServerOptions.Limits 配置的服务器范围的速率限制仍适用于 HTTP/1.x 和 HTTP/2 连接。Server-wide rate limits configured via KestrelServerOptions.Limits still apply to both HTTP/1.x and HTTP/2 connections.

请求标头超时Request headers timeout

RequestHeadersTimeout

获取或设置服务器接收请求标头所花费的最大时间量。Gets or sets the maximum amount of time the server spends receiving request headers. 默认值为 30 秒。Defaults to 30 seconds.

.ConfigureKestrel((context, options) =>
{
    options.Limits.MaxConcurrentConnections = 100;
    options.Limits.MaxConcurrentUpgradedConnections = 100;
    options.Limits.MaxRequestBodySize = 10 * 1024;
    options.Limits.MinRequestBodyDataRate =
        new MinDataRate(bytesPerSecond: 100, gracePeriod: TimeSpan.FromSeconds(10));
    options.Limits.MinResponseDataRate =
        new MinDataRate(bytesPerSecond: 100, gracePeriod: TimeSpan.FromSeconds(10));
    options.Listen(IPAddress.Loopback, 5000);
    options.Listen(IPAddress.Loopback, 5001, listenOptions =>
    {
        listenOptions.UseHttps("testCert.pfx", "testPassword");
    });
    options.Limits.KeepAliveTimeout = TimeSpan.FromMinutes(2);
    options.Limits.RequestHeadersTimeout = TimeSpan.FromMinutes(1);
});
public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
    WebHost.CreateDefaultBuilder(args)
        .UseStartup<Startup>()
        .UseKestrel(options =>
        {
            options.Limits.RequestHeadersTimeout = TimeSpan.FromMinutes(1);
        });

每个连接的最大流Maximum streams per connection

Http2.MaxStreamsPerConnection 限制每个 HTTP/2 连接的并发请求流的数量。Http2.MaxStreamsPerConnection limits the number of concurrent request streams per HTTP/2 connection. 拒绝过多的流。Excess streams are refused.

public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
    WebHost.CreateDefaultBuilder(args)
        .UseStartup<Startup>()
        .ConfigureKestrel((context, options) =>
        {
            options.Limits.Http2.MaxStreamsPerConnection = 100;
        });

默认值为 100。The default value is 100.

标题表大小Header table size

HPACK 解码器解压缩 HTTP/2 连接的 HTTP 标头。The HPACK decoder decompresses HTTP headers for HTTP/2 connections. Http2.HeaderTableSize 限制 HPACK 解码器使用的标头压缩表的大小。Http2.HeaderTableSize limits the size of the header compression table that the HPACK decoder uses. 该值以八位字节提供,且必须大于零 (0)。The value is provided in octets and must be greater than zero (0).

public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
    WebHost.CreateDefaultBuilder(args)
        .UseStartup<Startup>()
        .ConfigureKestrel((context, options) =>
        {
            options.Limits.Http2.HeaderTableSize = 4096;
        });

默认值为 4096。The default value is 4096.

最大帧大小Maximum frame size

Http2.MaxFrameSize 指示要接收的 HTTP/2 连接帧有效负载的最大大小。Http2.MaxFrameSize indicates the maximum size of the HTTP/2 connection frame payload to receive. 该值以八位字节提供,必须介于 2^14 (16,384) 和 2^24-1 (16,777,215) 之间。The value is provided in octets and must be between 2^14 (16,384) and 2^24-1 (16,777,215).

public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
    WebHost.CreateDefaultBuilder(args)
        .UseStartup<Startup>()
        .ConfigureKestrel((context, options) =>
        {
            options.Limits.Http2.MaxFrameSize = 16384;
        });

默认值为 2^14 (16,384)。The default value is 2^14 (16,384).

最大请求标头大小Maximum request header size

Http2.MaxRequestHeaderFieldSize 表示请求标头值的允许的最大大小(用八进制表示)。Http2.MaxRequestHeaderFieldSize indicates the maximum allowed size in octets of request header values. 此限制同时适用于压缩和未压缩表示形式中的名称和值。This limit applies to both name and value together in their compressed and uncompressed representations. 该值必须大于零 (0)。The value must be greater than zero (0).

public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
    WebHost.CreateDefaultBuilder(args)
        .UseStartup<Startup>()
        .ConfigureKestrel((context, options) =>
        {
            options.Limits.Http2.MaxRequestHeaderFieldSize = 8192;
        });

默认值为 8,192。The default value is 8,192.

初始连接窗口大小Initial connection window size

Http2.InitialConnectionWindowSize 表示服务器一次性缓存的最大请求主体数据大小(每次连接时在所有请求(流)中汇总,以字节为单位)。Http2.InitialConnectionWindowSize indicates the maximum request body data in bytes the server buffers at one time aggregated across all requests (streams) per connection. 请求也受 Http2.InitialStreamWindowSize 限制。Requests are also limited by Http2.InitialStreamWindowSize. 该值必须大于或等于 65,535,并小于 2^31 (2,147,483,648)。The value must be greater than or equal to 65,535 and less than 2^31 (2,147,483,648).

public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
    WebHost.CreateDefaultBuilder(args)
        .UseStartup<Startup>()
        .ConfigureKestrel((context, options) =>
        {
            options.Limits.Http2.InitialConnectionWindowSize = 131072;
        });

默认值为 128 KB (131,072)。The default value is 128 KB (131,072).

初始流窗口大小Initial stream window size

Http2.InitialStreamWindowSize 表示服务器针对每个请求(流)的一次性缓存的最大请求主体数据大小(以字节为单位)。Http2.InitialStreamWindowSize indicates the maximum request body data in bytes the server buffers at one time per request (stream). 请求也受 Http2.InitialStreamWindowSize 限制。Requests are also limited by Http2.InitialStreamWindowSize. 该值必须大于或等于 65,535,并小于 2^31 (2,147,483,648)。The value must be greater than or equal to 65,535 and less than 2^31 (2,147,483,648).

public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
    WebHost.CreateDefaultBuilder(args)
        .UseStartup<Startup>()
        .ConfigureKestrel((context, options) =>
        {
            options.Limits.Http2.InitialStreamWindowSize = 98304;
        });

默认值为 96 KB (98,304)。The default value is 96 KB (98,304).

有关其他 Kestrel 选项和限制的信息,请参阅:For information about other Kestrel options and limits, see:

终结点配置Endpoint configuration

默认情况下,ASP.NET Core 绑定到:By default, ASP.NET Core binds to:

  • http://localhost:5000
  • https://localhost:5001(存在本地开发证书时)https://localhost:5001 (when a local development certificate is present)

使用以下内容指定 URL:Specify URLs using the:

  • ASPNETCORE_URLS 环境变量。ASPNETCORE_URLS environment variable.
  • --urls 命令行参数。--urls command-line argument.
  • urls 主机配置键。urls host configuration key.
  • UseUrls 扩展方法。UseUrls extension method.

采用这些方法提供的值可以是一个或多个 HTTP 和 HTTPS 终结点(如果默认证书可用,则为 HTTPS)。The value provided using these approaches can be one or more HTTP and HTTPS endpoints (HTTPS if a default cert is available). 将值配置为以分号分隔的列表(例如 "Urls": "http://localhost:8000; http://localhost:8001")。Configure the value as a semicolon-separated list (for example, "Urls": "http://localhost:8000;http://localhost:8001").

有关这些方法的详细信息,请参阅服务器 URL重写配置For more information on these approaches, see Server URLs and Override configuration.

关于开发证书的创建:A development certificate is created:

部分浏览器需要获取信任本地开发证书的显示权限。Some browsers require that you grant explicit permission to the browser to trust the local development certificate.

ASP.NET Core 2.1 及更高版本的项目模板将应用配置为默认情况下在 HTTPS 上运行,并包括 HTTPS 重定向和 HSTS 支持ASP.NET Core 2.1 and later project templates configure apps to run on HTTPS by default and include HTTPS redirection and HSTS support.

调用 KestrelServerOptions 上的 ListenListenUnixSocket 方法以配置 URL 前缀和 Kestrel 的端口。Call Listen or ListenUnixSocket methods on KestrelServerOptions to configure URL prefixes and ports for Kestrel.

UseUrls--urls 命令行参数、urls 主机配置键以及 ASPNETCORE_URLS 环境变量也有用,但具有本节后面注明的限制(必须要有可用于 HTTPS 终结点配置的默认证书)。UseUrls, the --urls command-line argument, urls host configuration key, and the ASPNETCORE_URLS environment variable also work but have the limitations noted later in this section (a default certificate must be available for HTTPS endpoint configuration).

ASP.NET Core 2.1 或更高版本 KestrelServerOptions 配置:ASP.NET Core 2.1 or later KestrelServerOptions configuration:

ConfigureEndpointDefaults(Action<ListenOptions>)ConfigureEndpointDefaults(Action<ListenOptions>)

指定一个为每个指定的终结点运行的配置 ActionSpecifies a configuration Action to run for each specified endpoint. 多次调用 ConfigureEndpointDefaults,用最新指定的 Action 替换之前的 ActionCalling ConfigureEndpointDefaults multiple times replaces prior Actions with the last Action specified.

Host.CreateDefaultBuilder(args)
    .ConfigureWebHostDefaults(webBuilder =>
    {
        webBuilder.ConfigureKestrel(serverOptions =>
        {
            serverOptions.ConfigureEndpointDefaults(configureOptions =>
            {
                configureOptions.NoDelay = true;
            });
        });
        webBuilder.UseStartup<Startup>();
    });
public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
    WebHost.CreateDefaultBuilder(args)
        .UseStartup<Startup>()
        .ConfigureKestrel((context, options) =>
        {
            options.ConfigureEndpointDefaults(configureOptions =>
            {
                configureOptions.NoDelay = true;
            });
        });

ConfigureHttpsDefaults(Action<HttpsConnectionAdapterOptions>)ConfigureHttpsDefaults(Action<HttpsConnectionAdapterOptions>)

指定一个为每个 HTTPS 终结点运行的配置 ActionSpecifies a configuration Action to run for each HTTPS endpoint. 多次调用 ConfigureHttpsDefaults,用最新指定的 Action 替换之前的 ActionCalling ConfigureHttpsDefaults multiple times replaces prior Actions with the last Action specified.

Host.CreateDefaultBuilder(args)
    .ConfigureWebHostDefaults(webBuilder =>
    {
        webBuilder.ConfigureKestrel(serverOptions =>
        {
            serverOptions.ConfigureHttpsDefaults(options =>
            {
                // certificate is an X509Certificate2
                options.ServerCertificate = certificate;
            });
        });
        webBuilder.UseStartup<Startup>();
    });
public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
    WebHost.CreateDefaultBuilder(args)
        .UseStartup<Startup>()
        .ConfigureKestrel((context, options) =>
        {
            options.ConfigureHttpsDefaults(httpsOptions =>
            {
                // certificate is an X509Certificate2
                httpsOptions.ServerCertificate = certificate;
            });
        });

Configure(IConfiguration)Configure(IConfiguration)

创建配置加载程序,用于设置将 IConfiguration 作为输入的 Kestrel。Creates a configuration loader for setting up Kestrel that takes an IConfiguration as input. 配置必须针对 Kestrel 的配置节。The configuration must be scoped to the configuration section for Kestrel.

ListenOptions.UseHttpsListenOptions.UseHttps

将 Kestrel 配置为使用 HTTPS。Configure Kestrel to use HTTPS.

ListenOptions.UseHttps 扩展:ListenOptions.UseHttps extensions:

  • UseHttps – 将 Kestrel 配置为使用 HTTPS,采用默认证书。UseHttps – Configure Kestrel to use HTTPS with the default certificate. 如果没有配置默认证书,则会引发异常。Throws an exception if no default certificate is configured.
  • 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)

ListenOptions.UseHttps 参数:ListenOptions.UseHttps parameters:

  • filename 是证书文件的路径和文件名,关联包含应用内容文件的目录。filename is the path and file name of a certificate file, relative to the directory that contains the app's content files.
  • password 是访问 X.509 证书数据所需的密码。password is the password required to access the X.509 certificate data.
  • configureOptions 是配置 HttpsConnectionAdapterOptionsActionconfigureOptions is an Action to configure the HttpsConnectionAdapterOptions. 返回 ListenOptionsReturns the ListenOptions.
  • storeName 是从中加载证书的证书存储。storeName is the certificate store from which to load the certificate.
  • subject 是证书的主题名称。subject is the subject name for the certificate.
  • allowInvalid 指示是否存在需要留意的无效证书,例如自签名证书。allowInvalid indicates if invalid certificates should be considered, such as self-signed certificates.
  • location 是从中加载证书的存储位置。location is the store location to load the certificate from.
  • serverCertificate 是 X.509 证书。serverCertificate is the X.509 certificate.

在生产中,必须显式配置 HTTPS。In production, HTTPS must be explicitly configured. 至少必须提供默认证书。At a minimum, a default certificate must be provided.

下面要描述的支持的配置:Supported configurations described next:

  • 无配置No configuration
  • 从配置中替换默认证书Replace the default certificate from configuration
  • 更改代码中的默认值Change the defaults in code

无配置No configuration

Kestrel 在 http://localhost:5000https://localhost:5001 上进行侦听(如果默认证书可用)。Kestrel listens on http://localhost:5000 and https://localhost:5001 (if a default cert is available).

从配置中替换默认证书Replace the default certificate from configuration

CreateDefaultBuilder 在默认情况下调用 serverOptions.Configure(context.Configuration.GetSection("Kestrel")) 来加载 Kestrel 配置。CreateDefaultBuilder calls serverOptions.Configure(context.Configuration.GetSection("Kestrel")) by default to load Kestrel configuration. Kestrel 可以使用默认 HTTPS 应用设置配置架构。A default HTTPS app settings configuration schema is available for Kestrel. 从磁盘上的文件或从证书存储中配置多个终结点,包括要使用的 URL 和证书。Configure multiple endpoints, including the URLs and the certificates to use, either from a file on disk or from a certificate store.

在以下 appsettings.json 示例中 :In the following appsettings.json example:

  • 将 AllowInvalid 设置为 true,从而允许使用无效证书(例如自签名证书) 。Set AllowInvalid to true to permit the use of invalid certificates (for example, self-signed certificates).
  • 任何未指定证书的 HTTPS 终结点(下例中的 HttpsDefaultCert)会回退至在 Certificates > Default 下定义的证书或开发证书 。Any HTTPS endpoint that doesn't specify a certificate (HttpsDefaultCert in the example that follows) falls back to the cert defined under Certificates > Default or the development certificate.
{
"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>"
      }
    }
  }
}

此外还可以使用任何证书节点的 Path 和 Password,采用证书存储字段指定证书 。An alternative to using Path and Password for any certificate node is to specify the certificate using certificate store fields. 例如,可将 Certificates > Default 证书指定为 :For example, the Certificates > Default certificate can be specified as:

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

架构的注意事项:Schema notes:

  • 终结点的名称不区分大小写。Endpoints names are case-insensitive. 例如,HTTPSHttps 都是有效的。For example, HTTPS and Https are valid.

  • 每个终结点都要具备 Url 参数。The Url parameter is required for each endpoint. 此参数的格式和顶层 Urls 配置参数一样,只不过它只能有单个值。The format for this parameter is the same as the top-level Urls configuration parameter except that it's limited to a single value.

  • 这些终结点不会添加进顶层 Urls 配置中定义的终结点,而是替换它们。These endpoints replace those defined in the top-level Urls configuration rather than adding to them. 通过 Listen 在代码中定义的终结点与在配置节中定义的终结点相累积。Endpoints defined in code via Listen are cumulative with the endpoints defined in the configuration section.

  • Certificate 部分是可选的。The Certificate section is optional. 如果为指定 Certificate 部分,则使用在之前的方案中定义的默认值。If the Certificate section isn't specified, the defaults defined in earlier scenarios are used. 如果没有可用的默认值,服务器会引发异常且无法启动。If no defaults are available, the server throws an exception and fails to start.

  • Certificate 支持 Path–Password 和 Subject–Store 证书 。The Certificate section supports both PathPassword and SubjectStore certificates.

  • 只要不会导致端口冲突,就能以这种方式定义任何数量的终结点。Any number of endpoints may be defined in this way so long as they don't cause port conflicts.

  • options.Configure(context.Configuration.GetSection("Kestrel")) 通过 .Endpoint(string name, options => { }) 方法返回 KestrelConfigurationLoader,可以用于补充已配置的终结点设置:options.Configure(context.Configuration.GetSection("Kestrel")) returns a KestrelConfigurationLoader with an .Endpoint(string name, options => { }) method that can be used to supplement a configured endpoint's settings:

    options.Configure(context.Configuration.GetSection("Kestrel"))
        .Endpoint("HTTPS", opt =>
        {
            opt.HttpsOptions.SslProtocols = SslProtocols.Tls12;
        });
    

    也可以直接访问 KestrelServerOptions.ConfigurationLoader 来保持现有加载程序上的迭代,例如由 CreateDefaultBuilder 提供的加载程序。You can also directly access KestrelServerOptions.ConfigurationLoader to keep iterating on the existing loader, such as the one provided by CreateDefaultBuilder.

  • 每个终结点的配置节都可用于 Endpoint 方法中的选项,以便读取自定义设置。The configuration section for each endpoint is a available on the options in the Endpoint method so that custom settings may be read.

  • 通过另一节再次调用 options.Configure(context.Configuration.GetSection("Kestrel")) 可能加载多个配置。Multiple configurations may be loaded by calling options.Configure(context.Configuration.GetSection("Kestrel")) again with another section. 只使用最新配置,除非之前的实例上显式调用了 LoadOnly the last configuration is used, unless Load is explicitly called on prior instances. 元包不会调用 Load,所以可能会替换它的默认配置节。The metapackage doesn't call Load so that its default configuration section may be replaced.

  • KestrelConfigurationLoaderKestrelServerOptions 将 API 的 Listen 簇反射为 Endpoint 重载,因此可在同样的位置配置代码和配置终结点。KestrelConfigurationLoader mirrors the Listen family of APIs from KestrelServerOptions as Endpoint overloads, so code and config endpoints may be configured in the same place. 这些重载不使用名称,且只使用配置中的默认设置。These overloads don't use names and only consume default settings from configuration.

更改代码中的默认值Change the defaults in code

可以使用 ConfigureEndpointDefaultsConfigureHttpsDefaults 更改 ListenOptionsHttpsConnectionAdapterOptions 的默认设置,包括重写之前的方案指定的默认证书。ConfigureEndpointDefaults and ConfigureHttpsDefaults can be used to change default settings for ListenOptions and HttpsConnectionAdapterOptions, including overriding the default certificate specified in the prior scenario. 需要在配置任何终结点之前调用 ConfigureEndpointDefaultsConfigureHttpsDefaultsConfigureEndpointDefaults and ConfigureHttpsDefaults should be called before any endpoints are configured.

options.ConfigureEndpointDefaults(opt =>
{
    opt.NoDelay = true;
});

options.ConfigureHttpsDefaults(httpsOptions =>
{
    httpsOptions.SslProtocols = SslProtocols.Tls12;
});

SNI 的 Kestrel 支持Kestrel support for SNI

服务器名称指示 (SNI) 可用于承载相同 IP 地址和端口上的多个域。Server Name Indication (SNI) can be used to host multiple domains on the same IP address and port. 为了运行 SNI,客户端在 TLS 握手过程中将进行安全会话的主机名发送至服务器,从而让服务器可以提供正确的证书。For SNI to function, the client sends the host name for the secure session to the server during the TLS handshake so that the server can provide the correct certificate. 在 TLS 握手后的安全会话期间,客户端将服务器提供的证书用于与服务器进行加密通信。The client uses the furnished certificate for encrypted communication with the server during the secure session that follows the TLS handshake.

Kestrel 通过 ServerCertificateSelector 回调支持 SNI。Kestrel supports SNI via the ServerCertificateSelector callback. 每次连接调用一次回调,从而允许应用检查主机名并选择合适的证书。The callback is invoked once per connection to allow the app to inspect the host name and select the appropriate certificate.

SNI 支持要求:SNI support requires:

  • 在目标框架 netcoreapp2.1 上运行。Running on target framework netcoreapp2.1. netcoreapp2.0net461 上,回调也会调用,但是 name 始终为 nullOn netcoreapp2.0 and net461, the callback is invoked but the name is always null. 如果客户端未在 TLS 握手过程中提供主机名参数,则 name 也为 nullThe name is also null if the client doesn't provide the host name parameter in the TLS handshake.
  • 所有网站在相同的 Kestrel 实例上运行。All websites run on the same Kestrel instance. Kestrel 在无反向代理时不支持跨多个实例共享一个 IP 地址和端口。Kestrel doesn't support sharing an IP address and port across multiple instances without a reverse proxy.
public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
    WebHost.CreateDefaultBuilder(args)
        .UseStartup<Startup>()
        .ConfigureKestrel((context, options) =>
        {
            options.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;
                    };
                });
            });
        });
public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
    WebHost.CreateDefaultBuilder(args)
        .UseStartup<Startup>()
        .UseKestrel((context, options) =>
        {
            options.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;
                    };
                });
            });
        })
        .Build();

绑定到 TCP 套接字Bind to a TCP socket

Listen 方法绑定至 TCP 套接字,且 options lambda 允许 X.509 证书配置:The Listen method binds to a TCP socket, and an options lambda permits X.509 certificate configuration:

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

public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
    WebHost.CreateDefaultBuilder(args)
        .UseStartup<Startup>()
        .ConfigureKestrel((context, options) =>
        {
            options.Listen(IPAddress.Loopback, 5000);
            options.Listen(IPAddress.Loopback, 5001, listenOptions =>
            {
                listenOptions.UseHttps("testCert.pfx", "testPassword");
            });
        });
public static void Main(string[] args)
{
    CreateWebHostBuilder(args).Build().Run();
}

public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
    WebHost.CreateDefaultBuilder(args)
        .UseStartup<Startup>()
        .UseKestrel(options =>
        {
            options.Listen(IPAddress.Loopback, 5000);
            options.Listen(IPAddress.Loopback, 5001, listenOptions =>
            {
                listenOptions.UseHttps("testCert.pfx", "testPassword");
            });
        });
public static void Main(string[] args)
{
    CreateWebHostBuilder(args).Build().Run();
}

public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
    WebHost.CreateDefaultBuilder(args)
        .UseStartup<Startup>()
        .UseKestrel(options =>
        {
            options.Listen(IPAddress.Loopback, 5000);
            options.Listen(IPAddress.Loopback, 5001, listenOptions =>
            {
                listenOptions.UseHttps("testCert.pfx", "testPassword");
            });
        });

示例使用 ListenOptions 为终结点配置 HTTPS。The example configures HTTPS for an endpoint with ListenOptions. 可使用相同 API 为特定终结点配置其他 Kestrel 设置。Use the same API to configure other Kestrel settings for specific endpoints.

在 Windows 上,可以使用 New-SelfSignedCertificate PowerShell cmdlet 创建自签名证书。On Windows, self-signed certificates can be created using the New-SelfSignedCertificate PowerShell cmdlet. 有关不支持的示例,请参阅 UpdateIISExpressSSLForChrome.ps1For an unsupported example, see UpdateIISExpressSSLForChrome.ps1.

在 macOS、Linux 和 Windows 上,可以使用 OpenSSL 创建证书。On macOS, Linux, and Windows, certificates can be created using OpenSSL.

绑定到 Unix 套接字Bind to a Unix socket

可通过 ListenUnixSocket 侦听 Unix 套接字以提高 Nginx 的性能,如以下示例所示:Listen on a Unix socket with ListenUnixSocket for improved performance with Nginx, as shown in this example:

.ConfigureKestrel((context, options) =>
{
    options.ListenUnixSocket("/tmp/kestrel-test.sock");
    options.ListenUnixSocket("/tmp/kestrel-test.sock", listenOptions =>
    {
        listenOptions.UseHttps("testCert.pfx", "testpassword");
    });
});
public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
    WebHost.CreateDefaultBuilder(args)
        .UseStartup<Startup>()
        .UseKestrel(options =>
        {
            options.ListenUnixSocket("/tmp/kestrel-test.sock");
            options.ListenUnixSocket("/tmp/kestrel-test.sock", listenOptions =>
            {
                listenOptions.UseHttps("testCert.pfx", "testpassword");
            });
        });

端口 0Port 0

如果指定端口号 0,Kestrel 将动态绑定到可用端口。When the port number 0 is specified, Kestrel dynamically binds to an available port. 以下示例演示如何确定 Kestrel 在运行时实际绑定到的端口:The following example shows how to determine which port Kestrel actually bound at 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>");
    });
}

在应用运行时,控制台窗口输出指示可用于访问应用的动态端口:When the app is run, the console window output indicates the dynamic port where the app can be reached:

Listening on the following addresses: http://127.0.0.1:48508

限制Limitations

使用以下方法配置终结点:Configure endpoints with the following approaches:

  • UseUrls
  • --urls 命令行参数--urls command-line argument
  • urls 主机配置键urls host configuration key
  • ASPNETCORE_URLS 环境变量ASPNETCORE_URLS environment variable

若要将代码用于 Kestrel 以外的服务器,这些方法非常有用。These methods are useful for making code work with servers other than Kestrel. 不过,请注意以下限制:However, be aware of the following limitations:

  • HTTPS 无法与这些方法结合使用,除非在 HTTPS 终结点配置中提供了默认证书(例如,使用 KestrelServerOptions 配置或配置文件,如本主题前面的部分所示)。HTTPS can't be used with these approaches unless a default certificate is provided in the HTTPS endpoint configuration (for example, using KestrelServerOptions configuration or a configuration file as shown earlier in this topic).
  • 如果同时使用 ListenUseUrls 方法,Listen 终结点将覆盖 UseUrls 终结点。When both the Listen and UseUrls approaches are used simultaneously, the Listen endpoints override the UseUrls endpoints.

IIS 终结点配置IIS endpoint configuration

使用 IIS 时,由 ListenUseUrls 设置用于 IIS 覆盖绑定的 URL 绑定。When using IIS, the URL bindings for IIS override bindings are set by either Listen or UseUrls. 有关详细信息,请参阅 ASP.NET Core 模块主题。For more information, see the ASP.NET Core Module topic.

ListenOptions.ProtocolsListenOptions.Protocols

Protocols 属性建立在连接终结点上或为服务器启用的 HTTP 协议(HttpProtocols)。The Protocols property establishes the HTTP protocols (HttpProtocols) enabled on a connection endpoint or for the server. HttpProtocols 枚举向 Protocols 属性赋值。Assign a value to the Protocols property from the HttpProtocols enum.

HttpProtocols 枚举值HttpProtocols enum value 允许的连接协议Connection protocol permitted
Http1 仅 HTTP/1.1。HTTP/1.1 only. 可以在具有 TLS 或没有 TLS 的情况下使用。Can be used with or without TLS.
Http2 仅 HTTP/2。HTTP/2 only. 主要在具有 TLS 的情况下使用。Primarily used with TLS. 仅当客户端支持先验知识模式时,才可以在没有 TLS 的情况下使用。May be used without TLS only if the client supports a Prior Knowledge mode.
Http1AndHttp2 HTTP/1.1 和 HTTP/2。HTTP/1.1 and HTTP/2. 需要 TLS 和应用程序层协议协商 (ALPN) 连接来协商 HTTP/2;否则,连接默认为 HTTP/1.1。Requires a TLS and Application-Layer Protocol Negotiation (ALPN) connection to negotiate HTTP/2; otherwise, the connection defaults to HTTP/1.1.

默认协议是 HTTP/1.1。The default protocol is HTTP/1.1.

HTTP/2 的 TLS 限制:TLS restrictions for HTTP/2:

  • TLS 版本 1.2 或更高版本TLS version 1.2 or later
  • 重新协商已禁用Renegotiation disabled
  • 压缩已禁用Compression disabled
  • 最小的临时密钥交换大小:Minimum ephemeral key exchange sizes:
    • 椭圆曲线 Diffie-Hellman (ECDHE) [RFC4492] –最小 224 位Elliptic curve Diffie-Hellman (ECDHE) [RFC4492] – 224 bits minimum
    • 有限字段 Diffie-Hellman (DHE) [TLS12] – 最小 2048 位Finite field Diffie-Hellman (DHE) [TLS12] – 2048 bits minimum
  • 密码套件未列入阻止列表Cipher suite not blacklisted

默认情况下,支持具有 P-256 椭圆曲线 [FIPS186] 的 TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 [TLS-ECDHE]。TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 [TLS-ECDHE] with the P-256 elliptic curve [FIPS186] is supported by default.

以下示例允许端口 8000 上的 HTTP/1.1 和 HTTP/2 连接。The following example permits HTTP/1.1 and HTTP/2 connections on port 8000. TLS 使用提供的证书来保护连接:Connections are secured by TLS with a supplied certificate:

public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
    WebHost.CreateDefaultBuilder(args)
        .UseStartup<Startup>()
        .ConfigureKestrel((context, options) =>
        {
            options.Listen(IPAddress.Any, 8000, listenOptions =>
            {
                listenOptions.Protocols = HttpProtocols.Http1AndHttp2;
                listenOptions.UseHttps("testCert.pfx", "testPassword");
            });
        });

(可选)创建 IConnectionAdapter 实现,以针对特定密码的每个连接筛选 TLS 握手:Optionally create an IConnectionAdapter implementation to filter TLS handshakes on a per-connection basis for specific ciphers:

public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
    WebHost.CreateDefaultBuilder(args)
        .UseStartup<Startup>()
        .ConfigureKestrel((context, options) =>
        {
            options.Listen(IPAddress.Any, 8000, listenOptions =>
            {
                listenOptions.Protocols = HttpProtocols.Http1AndHttp2;
                listenOptions.UseHttps("testCert.pfx", "testPassword");
                listenOptions.ConnectionAdapters.Add(new TlsFilterAdapter());
            });
        });
private class TlsFilterAdapter : IConnectionAdapter
{
    public bool IsHttps => false;

    public Task<IAdaptedConnection> OnConnectionAsync(ConnectionAdapterContext context)
    {
        var tlsFeature = context.Features.Get<ITlsHandshakeFeature>();

        // Throw NotSupportedException for any cipher algorithm that you don't 
        // wish to support. Alternatively, define and compare 
        // ITlsHandshakeFeature.CipherAlgorithm to a list of acceptable cipher 
        // suites.
        //
        // A ITlsHandshakeFeature.CipherAlgorithm of CipherAlgorithmType.Null 
        // indicates that no cipher algorithm supported by Kestrel matches the 
        // requested algorithm(s).
        if (tlsFeature.CipherAlgorithm == CipherAlgorithmType.Null)
        {
            throw new NotSupportedException("Prohibited cipher: " + tlsFeature.CipherAlgorithm);
        }

        return Task.FromResult<IAdaptedConnection>(new AdaptedConnection(context.ConnectionStream));
    }

    private class AdaptedConnection : IAdaptedConnection
    {
        public AdaptedConnection(Stream adaptedStream)
        {
            ConnectionStream = adaptedStream;
        }

        public Stream ConnectionStream { get; }

        public void Dispose()
        {
        }
    }
}

从配置中设置协议Set the protocol from configuration

CreateDefaultBuilder 在默认情况下调用 serverOptions.Configure(context.Configuration.GetSection("Kestrel")) 来加载 Kestrel 配置。CreateDefaultBuilder calls serverOptions.Configure(context.Configuration.GetSection("Kestrel")) by default to load Kestrel configuration.

在以下 appsettings.json 示例中,为 Kestrel 的所有终结点建立默认的连接协议(HTTP/1.1 和 HTTP/2):In the following appsettings.json example, a default connection protocol (HTTP/1.1 and HTTP/2) is established for all of Kestrel's endpoints:

{
  "Kestrel": {
    "EndPointDefaults": {
      "Protocols": "Http1AndHttp2"
    }
  }
}

以下配置文件示例为特定终结点建立了连接协议:The following configuration file example establishes a connection protocol for a specific endpoint:

{
  "Kestrel": {
    "EndPoints": {
      "HttpsDefaultCert": {
        "Url": "https://localhost:5001",
        "Protocols": "Http1AndHttp2"
      }
    }
  }
}

代码中指定的协议覆盖了由配置设置的值。Protocols specified in code override values set by configuration.

传输配置Transport configuration

对于 ASP.NET Core 2.1 版,Kestrel 默认传输不再基于 Libuv,而是基于托管的套接字。With the release of ASP.NET Core 2.1, Kestrel's default transport is no longer based on Libuv but instead based on managed sockets. 这是 ASP.NET Core 2.0 应用升级到 2.1 时的一个重大更改,它调用 UseLibuv 并依赖于以下包中的一个:This is a breaking change for ASP.NET Core 2.0 apps upgrading to 2.1 that call UseLibuv and depend on either of the following packages:

对于使用 Microsoft.AspNetCore.App 元包且需要使用 Libuv 的 ASP.NET Core 2.1 或更高版本的项目:For ASP.NET Core 2.1 or later projects that use the Microsoft.AspNetCore.App metapackage and require the use of Libuv:

  • 将用于 Microsoft.AspNetCore.Server.Kestrel.Transport.Libuv 包的依赖项添加到应用的项目文件:Add a dependency for the Microsoft.AspNetCore.Server.Kestrel.Transport.Libuv package to the app's project file:

    <PackageReference Include="Microsoft.AspNetCore.Server.Kestrel.Transport.Libuv" 
                      Version="<LATEST_VERSION>" />
    
  • 调用 UseLibuvCall UseLibuv:

    public class Program
    {
        public static void Main(string[] args)
        {
            CreateWebHostBuilder(args).Build().Run();
        }
    
        public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
            WebHost.CreateDefaultBuilder(args)
                .UseLibuv()
                .UseStartup<Startup>();
    }
    

URL 前缀URL prefixes

如果使用 UseUrls--urls 命令行参数、urls 主机配置键或 ASPNETCORE_URLS 环境变量,URL 前缀可采用以下任意格式。When using UseUrls, --urls command-line argument, urls host configuration key, or ASPNETCORE_URLS environment variable, the URL prefixes can be in any of the following formats.

仅 HTTP URL 前缀是有效的。Only HTTP URL prefixes are valid. 使用 UseUrls 配置 URL 绑定时,Kestrel 不支持 HTTPS。Kestrel doesn't support HTTPS when configuring URL bindings using UseUrls.

  • 包含端口号的 IPv4 地址IPv4 address with port number

    http://65.55.39.10:80/
    

    0.0.0.0 是一种绑定到所有 IPv4 地址的特殊情况。0.0.0.0 is a special case that binds to all IPv4 addresses.

  • 包含端口号的 IPv6 地址IPv6 address with port number

    http://[0:0:0:0:0:ffff:4137:270a]:80/
    

    [::] 是 IPv4 0.0.0.0 的 IPv6 等效项。[::] is the IPv6 equivalent of IPv4 0.0.0.0.

  • 包含端口号的主机名Host name with port number

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

    主机名、*+ 并不特殊。Host names, *, and +, aren't special. 没有识别为有效 IP 地址或 localhost 的任何内容都将绑定到所有 IPv4 和 IPv6 IP。Anything not recognized as a valid IP address or localhost binds to all IPv4 and IPv6 IPs. 若要将不同主机名绑定到相同端口上的不同 ASP.NET Core 应用,请使用 HTTP.sys 或 IIS、Nginx 或 Apache 等反向代理服务器。To bind different host names to different ASP.NET Core apps on the same port, use HTTP.sys or a reverse proxy server, such as IIS, Nginx, or Apache.

    警告

    采用反向代理配置进行托管需要主机筛选Hosting in a reverse proxy configuration requires host filtering.

  • 包含端口号的主机 localhost 名称或包含端口号的环回 IPHost localhost name with port number or loopback IP with port number

    http://localhost:5000/
    http://127.0.0.1:5000/
    http://[::1]:5000/
    

    指定 localhost 后,Kestrel 将尝试绑定到 IPv4 和 IPv6 环回接口。When localhost is specified, Kestrel attempts to bind to both IPv4 and IPv6 loopback interfaces. 如果其他服务正在任一环回接口上使用请求的端口,则 Kestrel 将无法启动。If the requested port is in use by another service on either loopback interface, Kestrel fails to start. 如果任一环回接口出于任何其他原因(通常是因为 IPv6 不受支持)而不可用,则 Kestrel 将记录一个警告。If either loopback interface is unavailable for any other reason (most commonly because IPv6 isn't supported), Kestrel logs a warning.

主机筛选Host filtering

尽管 Kestrel 支持基于前缀的配置(例如 http://example.com:5000),但 Kestrel 在很大程度上会忽略主机名。While Kestrel supports configuration based on prefixes such as http://example.com:5000, Kestrel largely ignores the host name. 主机 localhost 是一个特殊情况,用于绑定至环回地址。Host localhost is a special case used for binding to loopback addresses. 除了显式 IP 地址以外的所有主机都绑定至所有公共 IP 地址。Any host other than an explicit IP address binds to all public IP addresses. 不验证 Host 标头。Host headers aren't validated.

解决方法是,使用主机筛选中间件。As a workaround, use Host Filtering Middleware. 主机筛选中间件由 Microsoft.AspNetCore.HostFiltering 包提供,此包包含在 Microsoft.AspNetCore.App 元包中(ASP.NET Core 2.1 或更高版本)。Host Filtering Middleware is provided by the Microsoft.AspNetCore.HostFiltering package, which is included in the Microsoft.AspNetCore.App metapackage (ASP.NET Core 2.1 or later). 由调用 AddHostFilteringCreateDefaultBuilder 添加中间件:The middleware is added by CreateDefaultBuilder, which calls 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>();
}

默认情况下,主机筛选中间件处于禁用状态。Host Filtering Middleware is disabled by default. 要启用该中间件,请在 appsettings.json/appsettings.<EnvironmentName>.json 中定义一个 AllowedHosts 键 。To enable the middleware, define an AllowedHosts key in appsettings.json/appsettings.<EnvironmentName>.json. 此值是以分号分隔的不带端口号的主机名列表:The value is a semicolon-delimited list of host names without port numbers:

appsettings.json :appsettings.json:

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

备注

转接头中间件 同样包含 AllowedHosts 选项。Forwarded Headers Middleware also has an AllowedHosts option. 转接头中间件和主机筛选中间件具有适合不同方案的相似功能。Forwarded Headers Middleware and Host Filtering Middleware have similar functionality for different scenarios. 如果未保留 Host 标头,并且使用反向代理服务器或负载均衡器转接请求,则使用转接头中间件设置 AllowedHosts 比较合适。Setting AllowedHosts with Forwarded Headers Middleware is appropriate when the Host header isn't preserved while forwarding requests with a reverse proxy server or load balancer. 将 Kestrel 用作面向公众的边缘服务器或直接转接 Host 标头时,使用主机筛选中间件设置 AllowedHosts 比较合适。Setting AllowedHosts with Host Filtering Middleware is appropriate when Kestrel is used as a public-facing edge server or when the Host header is directly forwarded.

有关转接头中间件的详细信息,请参阅 配置 ASP.NET Core 以使用代理服务器和负载均衡器For more information on Forwarded Headers Middleware, see 配置 ASP.NET Core 以使用代理服务器和负载均衡器.

其他资源Additional resources