Servers - Kestrel - Endpoints
In this article
-
The address specifies the network interface that the server listens on for incoming requests, such as a TCP port.
-
The protocol specifies the communication between the client and server, such as HTTP/1.1, HTTP/2, or HTTP/3.
-
An endpoint can be secured using the
https
URL scheme orUseHttps
method. -
Configure endpoints
-
Configure
HTTPS
-
Configure HTTP protocols
Default endpoint
Configure endpoints
-
Configure endpoints with URLs
-
Specify ports only
-
Configure endpoints in
appsettings.json
-
Configure endpoints in code
Configure endpoints with URLs
-
ASPNETCORE_URLS
environment variable. -
--urls
command-line argument. -
urls
host configuration key. -
UseUrls
extension method. -
WebApplication.Urls property.
URL formats
- IPv4 address with port number http://65.55.39.10:80/
0.0.0.0 is a special case that binds to all IPv4 addresses.
- IPv6 address with port number http://[0:0:0:0:0:ffff:4137:270a]:80/
[::] is the IPv6 equivalent of IPv4 0.0.0.0
.
- Wildcard host with port number http://contoso.com:80/ http://*:80/
Anything not recognized as a valid IP address or localhost
is treated as a wildcard that binds to all IPv4 and IPv6 addresses. Some people like to use * or + to be more explicit. To bind different host names to different ASP.NET Core apps on the same port, use HTTP.sys or a reverse proxy server.
Reverse proxy server examples include IIS, YARP, Nginx, and Apache.
- Host name
localhost
with port number or loopback IP with port number http://localhost:5000/ http://127.0.0.1:5000/ http://[::1]:5000/
When localhost
is specified, Kestrel
attempts to bind to both IPv4 and IPv6 loopback interfaces. If the requested port is in use by another service on either loopback interface, Kestrel
fails to start. If either loopback interface is unavailable for any other reason (most commonly because IPv6 isn't supported), Kestrel
logs a warning.
HTTPS
URL prefixes
Specify ports only
appsettings.json
Configure endpoints in {
"Kestrel": {
"Endpoints": {
"MyHttpEndpoint": {
"Url": "http://localhost:8080"
}
}
}
}
-
Uses
appsettings.json
as the configuration source. However, anyIConfiguration
source can be used. -
Adds an endpoint named
MyHttpEndpoint
on port 8080.
Reloading endpoints from configuration
-
The new configuration is compared to the old one, and any endpoint without configuration changes isn't modified.
-
Removed or modified endpoints are given 5 seconds to complete processing requests and shut down.
-
New or modified endpoints are started.
ConfigurationLoader
var builder = WebApplication.CreateBuilder(args);
builder.WebHost.ConfigureKestrel((context, serverOptions) =>
{
var kestrelSection = context.Configuration.GetSection("Kestrel");
serverOptions.Configure(kestrelSection)
.Endpoint("HTTPS", listenOptions =>
{
// ...
});
});
-
The configuration section for each endpoint is available on the options in the
Endpoint
method so that custom settings may be read. -
KestrelServerOptions.Configure(IConfiguration)
can be called multiple times, but only the last configuration is used unlessLoad
is explicitly called on prior instances. The default host doesn't callLoad
so that its default configuration section may be replaced. -
KestrelConfigurationLoader
mirrors theListen
family of APIs fromKestrelServerOptions
asEndpoint
overloads, so code and config endpoints can be configured in the same place. These overloads don't use names and only consume default settings from configuration.
Configure endpoints in code
-
Listen
-
ListenLocalhost
-
ListenAnyIP
-
ListenUnixSocket
-
ListenNamedPipe
Bind to a TCP socket
var builder = WebApplication.CreateBuilder(args);
builder.WebHost.ConfigureKestrel((context, serverOptions) =>
{
serverOptions.Listen(IPAddress.Loopback, 5000);
serverOptions.Listen(IPAddress.Loopback, 5001, listenOptions =>
{
listenOptions.UseHttps("testCert.pfx", "testPassword");
});
});
-
Configures endpoints that listen on port 5000 and 5001.
-
Configures
HTTPS
for an endpoint with theUseHttps
extension method onListenOptions
. For more information, see ConfigureHTTPS
in code.
Bind to a Unix socket
var builder = WebApplication.CreateBuilder(args);
builder.WebHost.ConfigureKestrel((context, serverOptions) =>
{
serverOptions.ListenUnixSocket("/tmp/kestrel-test.sock");
});
-
In the Nginx configuration file, set the
server > location > proxy_pass
entry to http://unix:/tmp/{KESTREL SOCKET}:/;. {KESTREL SOCKET} is the name of the socket provided to ListenUnixSocket (for example,kestrel-test.sock
in the preceding example). -
Ensure that the socket is writeable by Nginx (for example,
chmod go+w /tmp/kestrel-test.sock
).
Configure endpoint defaults
var builder = WebApplication.CreateBuilder(args);
builder.WebHost.ConfigureKestrel(serverOptions =>
{
serverOptions.ConfigureEndpointDefaults(listenOptions =>
{
// ...
});
});
Note Endpoints created by calling
Listen
before callingConfigureEndpointDefaults
won't have the defaults applied.
Dynamic port binding
app.Run(async (context) =>
{
var serverAddressFeature = context.Features.Get<IServerAddressesFeature>();
if (serverAddressFeature is not null)
{
var listenAddresses = string.Join(", ", serverAddressFeature.Addresses);
// ...
}
});
-
KestrelServerOptions.ListenLocalhost
-
Binding TCP-based HTTP/1.1 or HTTP/2, and QUIC-based HTTP/3 together.
HTTPS
Configure -
If URL prefixes or specify ports only are used to define endpoints,
HTTPS
can be used only if a default certificate is provided inHTTPS
endpoint configuration. A default certificate can be configured with one of the following options: -
Configure
HTTPS
inappsettings.json
-
Configure
HTTPS
in code
HTTPS
in appsettings.json
Configure {
"Kestrel": {
"Endpoints": {
"Http": {
"Url": "http://localhost:5000"
},
"HttpsInlineCertFile": {
"Url": "https://localhost:5001",
"Certificate": {
"Path": "<path to .pfx file>",
"Password": "$CREDENTIAL_PLACEHOLDER$"
}
},
"HttpsInlineCertAndKeyFile": {
"Url": "https://localhost:5002",
"Certificate": {
"Path": "<path to .pem/.crt file>",
"KeyPath": "<path to .key file>",
"Password": "$CREDENTIAL_PLACEHOLDER$"
}
},
"HttpsInlineCertStore": {
"Url": "https://localhost:5003",
"Certificate": {
"Subject": "<subject; required>",
"Store": "<certificate store; required>",
"Location": "<location; defaults to CurrentUser>",
"AllowInvalid": "<true or false; defaults to false>"
}
},
"HttpsDefaultCert": {
"Url": "https://localhost:5004"
}
},
"Certificates": {
"Default": {
"Path": "<path to .pfx file>",
"Password": "$CREDENTIAL_PLACEHOLDER$"
}
}
}
}
Warning In the preceding example, the certificate password is stored in plain-text in
appsettings.json
. The $CREDENTIAL_PLACEHOLDER$ token is used as a placeholder for the certificate's password. To store certificate passwords securely in development environments, see Protect secrets in development. To store certificate passwords securely in production environments, see Azure Key Vault configuration provider. Development secrets shouldn't be used for production or test.
Schema notes
-
Endpoint
names are case-insensitive. For example,HTTPS
andHttps
are equivalent. -
The
Url
parameter is required for each endpoint. The format for this parameter is the same as the top-levelUrls
configuration parameter except that it's limited to a single value. See URL formats earlier in this article. -
These endpoints replace the ones defined in the top-level
Urls
configuration rather than adding to them. Endpoints defined in code viaListen
are cumulative with the endpoints defined in the configuration section. -
The
Certificate
section is optional. If theCertificate
section isn't specified, the defaults defined inCertificates:Default
are used. If no defaults are available, the development certificate is used. If there are no defaults and the development certificate isn't present, the server throws an exception and fails to start. -
The
Certificate
section supports multiple certificate sources. -
Any number of endpoints may be defined in
Configuration
, as long as they don't cause port conflicts.
Certificate
sources
-
Path
andPassword
to load .pfx files. -
Path
,KeyPath
andPassword
to load .pem/.crt and .key files. -
Subject
andStore
to load from the certificate store.
"Default": {
"Subject": "<subject; required>",
"Store": "<cert store; required>",
"Location": "<location; defaults to CurrentUser>",
"AllowInvalid": "<true or false; defaults to false>"
}
appsettings.json
Configure client certificates in {
"Kestrel": {
"Endpoints": {
"MyHttpsEndpoint": {
"Url": "https://localhost:5001",
"ClientCertificateMode": "AllowCertificate",
"Certificate": {
"Path": "<path to .pfx file>",
"Password": "$CREDENTIAL_PLACEHOLDER$"
}
}
}
}
}
Warning In the preceding example, the certificate password is stored in plain-text in
appsettings.json
. The$CREDENTIAL_PLACEHOLDER$
token is used as a placeholder for the certificate's password. To store certificate passwords securely in development environments, see Protect secrets in development. To store certificate passwords securely in production environments, see Azure Key Vault configuration provider. Development secrets shouldn't be used for production or test.
appsettings.json
Configure SSL/TLS protocols in {
"Kestrel": {
"Endpoints": {
"MyHttpsEndpoint": {
"Url": "https://localhost:5001",
"SslProtocols": ["Tls12", "Tls13"],
"Certificate": {
"Path": "<path to .pfx file>",
"Password": "$CREDENTIAL_PLACEHOLDER$"
}
}
}
}
}
Warning In the preceding example, the certificate password is stored in plain-text in
appsettings.json
. The$CREDENTIAL_PLACEHOLDER$
token is used as a placeholder for the certificate's password. To store certificate passwords securely in development environments, see Protect secrets in development. To store certificate passwords securely in production environments, see Azure Key Vault configuration provider. Development secrets shouldn't be used for production or test.
HTTPS
in code
Configure var builder = WebApplication.CreateBuilder(args);
builder.WebHost.ConfigureKestrel((context, serverOptions) =>
{
serverOptions.Listen(IPAddress.Loopback, 5000);
serverOptions.Listen(IPAddress.Loopback, 5001, listenOptions =>
{
listenOptions.UseHttps("testCert.pfx", "testPassword");
});
});
-
filename
is the path and file name of a certificate file, relative to the directory that contains the app's content files. -
password is the password required to access the X.509 certificate data.
-
configureOptions
is anAction
to configure theHttpsConnectionAdapterOptions
. Returns theListenOptions
. -
storeName
is the certificate store from which to load the certificate. -
subject
is thesubject
name for the certificate. -
allowInvalid
indicates if invalid certificates should be considered, such as self-signed certificates. -
location
is the storelocation
to load the certificate from. -
serverCertificate
is the X.509 certificate.
Configure client certificates in code
var builder = WebApplication.CreateBuilder(args);
builder.WebHost.ConfigureKestrel(serverOptions =>
{
serverOptions.ConfigureHttpsDefaults(listenOptions =>
{
listenOptions.ClientCertificateMode = ClientCertificateMode.AllowCertificate;
});
});
HTTPS
defaults in code
Configure var builder = WebApplication.CreateBuilder(args);
builder.WebHost.ConfigureKestrel(serverOptions =>
{
serverOptions.ConfigureHttpsDefaults(listenOptions =>
{
// ...
});
});
Note Endpoints created by calling
Listen
before callingConfigureHttpsDefaults
won't have the defaults applied.
Configure SSL/TLS protocols in code
var builder = WebApplication.CreateBuilder(args);
builder.WebHost.ConfigureKestrel(serverOptions =>
{
serverOptions.ConfigureHttpsDefaults(listenOptions =>
{
listenOptions.SslProtocols = SslProtocols.Tls13;
});
});
Configure TLS cipher suites filter in code
var builder = WebApplication.CreateBuilder(args);
builder.WebHost.ConfigureKestrel((context, serverOptions) =>
{
serverOptions.ConfigureHttpsDefaults(listenOptions =>
{
listenOptions.OnAuthenticate = (context, sslOptions) =>
{
sslOptions.CipherSuitesPolicy = new CipherSuitesPolicy(
new[]
{
TlsCipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
TlsCipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
// ...
});
};
});
});
Configure Server Name Indication
-
Configure a mapping between host names and
HTTPS
options inConfiguration
. For example, JSON in theappsettings.json
file. -
Create an endpoint in code and select a certificate using the host name with the
ServerCertificateSelector
callback.
appsettings.json
Configure SNI in {
"Kestrel": {
"Endpoints": {
"MySniEndpoint": {
"Url": "https://*",
"SslProtocols": ["Tls11", "Tls12"],
"Sni": {
"a.example.org": {
"Protocols": "Http1AndHttp2",
"SslProtocols": ["Tls11", "Tls12", "Tls13"],
"Certificate": {
"Subject": "<subject; required>",
"Store": "<certificate store; required>",
},
"ClientCertificateMode" : "NoCertificate"
},
"*.example.org": {
"Certificate": {
"Path": "<path to .pfx file>",
"Password": "$CREDENTIAL_PLACEHOLDER$"
}
},
"*": {
// At least one subproperty needs to exist per SNI section or it
// cannot be discovered via IConfiguration
"Protocols": "Http1",
}
}
}
},
"Certificates": {
"Default": {
"Path": "<path to .pfx file>",
"Password": "$CREDENTIAL_PLACEHOLDER$"
}
}
}
}
Warning In the preceding example, the certificate password is stored in plain-text in
appsettings.json
. The$CREDENTIAL_PLACEHOLDER$
token is used as a placeholder for the certificate's password. To store certificate passwords securely in development environments, see Protect secrets in development. To store certificate passwords securely in production environments, see Azure Key Vault configuration provider. Development secrets shouldn't be used for production or test.
-
Certificate
configures the certificate source. -
Protocols
configures the allowed HTTP protocols. -
SslProtocols
configures the allowed SSL protocols. -
ClientCertificateMode
configures the client certificate requirements. -
Exact match. For example,
a.example.org
matchesa.example.org
. -
Wildcard prefix. If there are multiple wildcard matches, then the longest pattern is chosen. For example,
*.example.org
matchesb.example.org
andc.example.org
. -
Full wildcard. * matches everything else, including clients that aren't using SNI and don't send a host name.
Configure SNI with code
-
ServerCertificateSelector
-
ServerOptionsSelectionCallback
-
TlsHandshakeCallbackOptions
ServerCertificateSelector
SNI with var builder = WebApplication.CreateBuilder(args);
builder.WebHost.ConfigureKestrel(serverOptions =>
{
serverOptions.ListenAnyIP(5005, listenOptions =>
{
listenOptions.UseHttps(httpsOptions =>
{
var localhostCert = CertificateLoader.LoadFromStoreCert(
"localhost", "My", StoreLocation.CurrentUser,
allowInvalid: true);
var exampleCert = CertificateLoader.LoadFromStoreCert(
"example.com", "My", StoreLocation.CurrentUser,
allowInvalid: true);
var subExampleCert = CertificateLoader.LoadFromStoreCert(
"sub.example.com", "My", StoreLocation.CurrentUser,
allowInvalid: true);
var certs = new Dictionary<string, X509Certificate2>(
StringComparer.OrdinalIgnoreCase)
{
["localhost"] = localhostCert,
["example.com"] = exampleCert,
["sub.example.com"] = subExampleCert
};
httpsOptions.ServerCertificateSelector = (connectionContext, name) =>
{
if (name is not null && certs.TryGetValue(name, out var cert))
{
return cert;
}
return exampleCert;
};
});
});
});
ServerOptionsSelectionCallback
SNI with var builder = WebApplication.CreateBuilder(args);
builder.WebHost.ConfigureKestrel(serverOptions =>
{
serverOptions.ListenAnyIP(5005, listenOptions =>
{
listenOptions.UseHttps(httpsOptions =>
{
var localhostCert = CertificateLoader.LoadFromStoreCert(
"localhost", "My", StoreLocation.CurrentUser,
allowInvalid: true);
var exampleCert = CertificateLoader.LoadFromStoreCert(
"example.com", "My", StoreLocation.CurrentUser,
allowInvalid: true);
listenOptions.UseHttps((stream, clientHelloInfo, state, cancellationToken) =>
{
if (string.Equals(clientHelloInfo.ServerName, "localhost",
StringComparison.OrdinalIgnoreCase))
{
return new ValueTask<SslServerAuthenticationOptions>(
new SslServerAuthenticationOptions
{
ServerCertificate = localhostCert,
// Different TLS requirements for this host
ClientCertificateRequired = true
});
}
return new ValueTask<SslServerAuthenticationOptions>(
new SslServerAuthenticationOptions
{
ServerCertificate = exampleCert
});
}, state: null!);
});
});
});
TlsHandshakeCallbackOptions
SNI with var builder = WebApplication.CreateBuilder(args);
builder.WebHost.ConfigureKestrel(serverOptions =>
{
serverOptions.ListenAnyIP(5005, listenOptions =>
{
listenOptions.UseHttps(httpsOptions =>
{
var localhostCert = CertificateLoader.LoadFromStoreCert(
"localhost", "My", StoreLocation.CurrentUser,
allowInvalid: true);
var exampleCert = CertificateLoader.LoadFromStoreCert(
"example.com", "My", StoreLocation.CurrentUser,
allowInvalid: true);
listenOptions.UseHttps(new TlsHandshakeCallbackOptions
{
OnConnection = context =>
{
if (string.Equals(context.ClientHelloInfo.ServerName, "localhost",
StringComparison.OrdinalIgnoreCase))
{
// Different TLS requirements for this host
context.AllowDelayedClientCertificateNegotation = true;
return new ValueTask<SslServerAuthenticationOptions>(
new SslServerAuthenticationOptions
{
ServerCertificate = localhostCert
});
}
return new ValueTask<SslServerAuthenticationOptions>(
new SslServerAuthenticationOptions
{
ServerCertificate = exampleCert
});
}
});
});
});
});
Configure HTTP protocols
HttpProtocols value |
Connection protocol permitted |
---|---|
Http1 |
HTTP/1.1 only. Can be used with or without TLS. |
Http2 |
HTTP/2 only. May be used without TLS only if the client supports a Prior Knowledge mode. |
Http3 |
HTTP/3 only. Requires TLS. The client may need to be configured to use HTTP/3 only. |
Http1AndHttp2 |
HTTP/1.1 and HTTP/2. HTTP/2 requires the client to select HTTP/2 in the TLS Application-Layer Protocol Negotiation (ALPN) handshake; otherwise, the connection defaults to HTTP/1.1. |
Http1AndHttp2AndHttp3 |
HTTP/1.1, HTTP/2 and HTTP/3. The first client request normally uses HTTP/1.1 or HTTP/2, and the alt-svc response header prompts the client to upgrade to HTTP/3. HTTP/2 and HTTP/3 requires TLS; otherwise, the connection defaults to HTTP/1.1. |
-
TLS version 1.2 or later
-
Renegotiation disabled
-
Compression disabled
-
Minimum ephemeral key exchange sizes:
-
Elliptic curve Diffie-Hellman (ECDHE) [RFC4492]: 224 bits minimum
-
Finite field Diffie-Hellman (DHE) [TLS12]: 2048 bits minimum
-
-
Cipher suite not prohibited.
appsettings.json
Configure HTTP protocols in {
"Kestrel": {
"Endpoints": {
"HttpsDefaultCert": {
"Url": "https://localhost:5001",
"Protocols": "Http1"
}
}
}
}
{
"Kestrel": {
"EndpointDefaults": {
"Protocols": "Http1"
}
}
}
Configure HTTP protocols in code
var builder = WebApplication.CreateBuilder(args);
builder.WebHost.ConfigureKestrel((context, serverOptions) =>
{
serverOptions.Listen(IPAddress.Any, 8000, listenOptions =>
{
listenOptions.UseHttps("testCert.pfx", "testPassword");
listenOptions.Protocols = HttpProtocols.Http1AndHttp2AndHttp3;
});
});
See also
-
Kestrel
web server in ASP.NET Core -
Configure options for the ASP.NET Core
Kestrel
web server
Ref: Configure endpoints for the ASP.NET Core Kestrel
web server