Configuración de puntos de conexión para el servidor web Kestrel de ASP.NET Core
Nota
Esta no es la versión más reciente de este artículo. Para la versión actual, consulta la versión .NET 8 de este artículo.
Advertencia
Esta versión de ASP.NET Core ya no se admite. Para obtener más información, consulta la Directiva de soporte técnico de .NET y .NET Core. Para la versión actual, consulta la versión .NET 8 de este artículo.
Importante
Esta información hace referencia a un producto en versión preliminar, el cual puede sufrir importantes modificaciones antes de que se publique la versión comercial. Microsoft no proporciona ninguna garantía, expresa o implícita, con respecto a la información proporcionada aquí.
Para la versión actual, consulte la versión .NET 8 de este artículo.
Nota:
Esta no es la versión más reciente de este artículo. Para la versión actual, consulta la versión .NET 8 de este artículo.
Advertencia
Esta versión de ASP.NET Core ya no se admite. Para obtener más información, consulta la Directiva de soporte técnico de .NET y .NET Core. Para la versión actual, consulta la versión .NET 8 de este artículo.
Importante
Esta información hace referencia a un producto en versión preliminar, el cual puede sufrir importantes modificaciones antes de que se publique la versión comercial. Microsoft no proporciona ninguna garantía, expresa o implícita, con respecto a la información proporcionada aquí.
Para la versión actual, consulte la versión .NET 8 de este artículo.
Los puntos de conexión de Kestrel proporcionan la infraestructura para escuchar las solicitudes entrantes y enrutarlos al middleware adecuado. La combinación de una dirección y un protocolo define un punto de conexión.
- La dirección especifica la interfaz de red en la que escucha el servidor las solicitudes entrantes, como un puerto TCP.
- El protocolo especifica la comunicación entre el cliente y el servidor, como HTTP/1.1, HTTP/2 o HTTP/3.
- Un punto de conexión se puede proteger mediante el esquema de dirección URL
https
o el métodoUseHttps
.
Los puntos de conexión se pueden configurar mediante direcciones URL, JSON en appsettings.json
y código. En este artículo se describe cómo usar cada opción para configurar puntos de conexión:
Punto de conexión predeterminado
Los nuevos proyectos de ASP.NET Core están configurados para enlazarse a un puerto HTTP aleatorio entre 5000 y 5300 y un puerto HTTPS aleatorio entre 7000 y 7300. Los puertos seleccionados se almacenan en el archivo Properties/launchSettings.json
generado y el desarrollador puede modificarlos. El archivo launchSetting.json
solo se usa en el desarrollo local.
Si no hay ninguna configuración de punto de conexión, Kestrel se enlaza a http://localhost:5000
.
Configuración de puntos de conexión
Los puntos de conexión de Kestrel escuchan las conexiones entrantes. Cuando se crea un punto de conexión, se debe configurar con la dirección que va a escuchar. Normalmente, se trata de una dirección TCP y un número de puerto.
Hay varias opciones para configurar puntos de conexión:
- Configuración de puntos de conexión con direcciones URL
- Especificación solo de puertos
- Configuración de puntos de conexión en appsettings.json
- Configuración de puntos de conexión en el código
Configuración de puntos de conexión con direcciones URL
En las secciones siguientes se explica cómo configurar puntos de conexión mediante:
- La variable de entorno
ASPNETCORE_URLS
. - El argumento de la línea de comandos
--urls
. - La clave de configuración de host
urls
. - El método de extensión UseUrls.
- Propiedad WebApplication.Urls.
Formatos de dirección URL
Las direcciones IP indican las direcciones IP o del host con los puertos y protocolos en que el servidor debe escuchar. El puerto se puede omitir si es el valor predeterminado del protocolo (normalmente 80 y 443). Las direcciones URL puede estar en cualquiera de los siguientes formatos.
Dirección IPv4 con número de puerto
http://65.55.39.10:80/
0.0.0.0
es un caso especial que enlaza a todas las direcciones IPv4.Dirección IPv6 con número de puerto
http://[0:0:0:0:0:ffff:4137:270a]:80/
[::]
es el equivalente en IPv6 de0.0.0.0
en IPv4.Host con caracteres comodín con número de puerto
http://contoso.com:80/ http://*:80/
Todo lo que no se reconozca como una dirección IP válida o
localhost
se trata como un carácter comodín que se enlaza a todas las direcciones IPv4 e IPv6. A algunas personas les gusta usar*
o+
para ser más explícitas. Para enlazar otros nombres de host a otras aplicaciones ASP.NET Core en el mismo puerto, use HTTP.sys o un servidor proxy inverso.Entre los ejemplos de servidor proxy inverso se incluyen IIS, YARP, Nginx y Apache.
El nombre del host
localhost
con el número de puerto o la IP de bucle invertido con el número de puertohttp://localhost:5000/ http://127.0.0.1:5000/ http://[::1]:5000/
Cuando se especifica
localhost
, Kestrel intenta enlazar a las interfaces de bucle invertido de IPv4 e IPv6. Si el puerto solicitado lo está usando otro servicio en cualquier interfaz de bucle invertido, Kestrel no se puede iniciar. Si ninguna de estas interfaces de bucle invertido está disponible por cualquier otra razón (normalmente porque no se admite IPv6), Kestrel registra una advertencia.
Se pueden especificar varios prefijos de dirección URL mediante un delimitador de punto y coma (;
):
http://*:5000;http://localhost:5001;https://hostname:5002
Para más información, consulte Invalidación de la configuración.
Prefijos de direcciones URL HTTPS
Los prefijos de direcciones URL HTTPS solo se pueden usar para definir puntos de conexión si se proporciona un certificado predeterminado en la configuración del punto de conexión HTTPS. Por ejemplo, use la configuración KestrelServerOptions o un archivo de configuración, como se muestra más adelante en este mismo artículo.
Para más información, consulte Configuración de HTTPS.
Especificación solo de puertos
A menudo, las aplicaciones y los contenedores solo reciben un puerto en el que escuchar, como el puerto 80, sin restricciones adicionales como el host o la ruta de acceso. HTTP_PORTS y HTTPS_PORTS son claves de configuración que especifican los puertos de escucha para los servidores HTTP.sys y Kestrel. Estas claves se pueden especificar como variables de entorno definidas con los prefijos DOTNET_
o ASPNETCORE_
, o bien se especifican directamente mediante cualquier otra entrada de configuración, como appsettings.json
. Cada una es una lista de valores de puerto delimitada por punto y coma, tal como se muestra en el ejemplo siguiente:
ASPNETCORE_HTTP_PORTS=80;8080
ASPNETCORE_HTTPS_PORTS=443;8081
El ejemplo anterior es una forma abreviada de la siguiente configuración, que especifica el esquema (HTTP o HTTPS) y cualquier host o IP.
ASPNETCORE_URLS=http://*:80/;http://*:8080/;https://*:443/;https://*:8081/
Las claves de configuración de HTTP_PORTS y HTTPS_PORTS son de menor prioridad, y las direcciones URL o los valores proporcionados directamente en el código las anulan. Los certificados todavía deben configurarse por separado mediante mecanismos específicos del servidor para HTTPS.
Configuración de puntos de conexión en appsettings.json
Kestrel puede cargar puntos de conexión desde una instancia de IConfiguration. De forma predeterminada, la configuración de Kestrel se carga desde la sección Kestrel
y los puntos de conexión se configuran en Kestrel:Endpoints
:
{
"Kestrel": {
"Endpoints": {
"MyHttpEndpoint": {
"Url": "http://localhost:8080"
}
}
}
}
Ejemplo anterior:
- Usa
appsettings.json
como origen de la configuración. Sin embargo, se puede usar cualquier origen deIConfiguration
. - Agrega un punto de conexión denominado
MyHttpEndpoint
en el puerto 8080.
Para obtener más información sobre cómo configurar puntos de conexión con JSON, consulta las secciones posteriores de este artículo en las que se trata la configuración de HTTPS y la configuración de protocolos HTTP en appsettings.json.
Recarga de puntos de conexión desde la configuración
Volver a cargar la configuración del punto de conexión cuando el origen de configuración cambia está habilitado de forma predeterminada. Puede deshabilitarse mediante KestrelServerOptions.Configure(IConfiguration, Boolean).
Si se señala un cambio, se realizarán los pasos siguientes:
- La nueva configuración se compara con la anterior, no se modifica ningún punto de conexión sin cambios de configuración.
- A los puntos de conexión eliminados o modificados se les asignan cinco segundos para completar las solicitudes de procesamiento y cerrarse.
- Los puntos de conexión nuevos o modificados se inician.
Los clientes que se conectan a un punto de conexión modificado pueden desconectarse o rechazarse mientras se reinicia el punto de conexión.
ConfigurationLoader
KestrelServerOptions.Configure devuelve KestrelConfigurationLoader. El método Endpoint(String, Action<EndpointConfiguration>) del cargador que se puede usar para complementar la configuración de un punto de conexión configurado:
var builder = WebApplication.CreateBuilder(args);
builder.WebHost.ConfigureKestrel((context, serverOptions) =>
{
var kestrelSection = context.Configuration.GetSection("Kestrel");
serverOptions.Configure(kestrelSection)
.Endpoint("HTTPS", listenOptions =>
{
// ...
});
});
Se puede acceder directamente a KestrelServerOptions.ConfigurationLoader
para seguir con la iteración en el cargador existente, como el proporcionado por WebApplicationBuilder.WebHost.
- La sección de configuración de cada punto de conexión está disponible en las opciones del método Endpoint para que se pueda leer la configuración personalizada.
- Se puede llamar varias veces a KestrelServerOptions.Configure(IConfiguration), pero solo se usa la última configuración a menos que se llame explícitamente a
Load
en instancias anteriores. El host predeterminado no llama aLoad
, con lo cual su sección de configuración predeterminada se puede reemplazar. KestrelConfigurationLoader
refleja la familiaListen
de API deKestrelServerOptions
como sobrecargas deEndpoint
, por lo que los puntos de conexión de configuración y el código se pueden configurar en el mismo lugar. En estas sobrecargas no se usan nombres y solo consumen valores predeterminados de la configuración.
Configuración de puntos de conexión en el código
KestrelServerOptions proporciona métodos para configurar puntos de conexión en el código:
Cuando las API Listen
y UseUrlsUseUrls
se usan al mismo tiempo, los puntos de conexión de sustituyen a los de Listen
.
Enlazar a un socket TCP
Los métodos Listen, ListenLocalhosty ListenAnyIP se enlazan a un socket TCP:
var builder = WebApplication.CreateBuilder(args);
builder.WebHost.ConfigureKestrel((context, serverOptions) =>
{
serverOptions.Listen(IPAddress.Loopback, 5000);
serverOptions.Listen(IPAddress.Loopback, 5001, listenOptions =>
{
listenOptions.UseHttps("testCert.pfx", "testPassword");
});
});
Ejemplo anterior:
- Configura los puntos de conexión que escuchan en el puerto 5000 y 5001.
- Configura HTTPS para un punto de conexión con el método de extensión UseHttps en ListenOptions. Para más información, consulte Configuración de HTTPS en código.
En Windows, pueden crearse certificados autofirmados con el New-SelfSignedCertificate
cmdlet de PowerShell. Para ver un ejemplo no admitido, consulte UpdateIISExpressSSLForChrome.ps1
.
En macOS, Linux y Windows, pueden crearse certificados con OpenSSL.
Enlazar a un socket de Unix
Escuche en un socket de Unix con ListenUnixSocket para mejorar el rendimiento con Nginx, tal como se muestra en este ejemplo:
var builder = WebApplication.CreateBuilder(args);
builder.WebHost.ConfigureKestrel((context, serverOptions) =>
{
serverOptions.ListenUnixSocket("/tmp/kestrel-test.sock");
});
- En el archivo de configuración de Nginx, establezca la entrada
server
>location
>proxy_pass
enhttp://unix:/tmp/{KESTREL SOCKET}:/;
.{KESTREL SOCKET}
es el nombre del socket proporcionado para ListenUnixSocket (por ejemplo,kestrel-test.sock
en el ejemplo anterior). - Asegúrese de que el socket es grabable por Nginx (por ejemplo,
chmod go+w /tmp/kestrel-test.sock
).
Configuración de los valores predeterminados del punto de conexión
ConfigureEndpointDefaults(Action<ListenOptions>)
especifica una configuración que se ejecuta en cada punto de conexión especificado. La llamada a ConfigureEndpointDefaults
varias veces reemplaza la configuración anterior.
var builder = WebApplication.CreateBuilder(args);
builder.WebHost.ConfigureKestrel(serverOptions =>
{
serverOptions.ConfigureEndpointDefaults(listenOptions =>
{
// ...
});
});
Nota
Los puntos de conexión que se crean mediante una llamada a Listen antes de llamar a ConfigureEndpointDefaults no tendrán aplicados los valores predeterminados.
Enlace de puerto dinámico
Cuando se especifica el número de puerto 0
, Kestrel se enlaza de forma dinámica a un puerto disponible. En el ejemplo siguiente se muestra cómo determinar a qué puerto se enlaza Kestrel en el entorno de ejecución:
app.Run(async (context) =>
{
var serverAddressFeature = context.Features.Get<IServerAddressesFeature>();
if (serverAddressFeature is not null)
{
var listenAddresses = string.Join(", ", serverAddressFeature.Addresses);
// ...
}
});
El enlace dinámico de un puerto no está disponible en algunas situaciones:
- KestrelServerOptions.ListenLocalhost
- Enlace conjunto de HTTP/1.1 o HTTP/2 basado en TCP y HTTP/3 basado en QUIC.
Configuración de HTTPS
Kestrel admite la protección de puntos de conexión con HTTPS. Los datos enviados a través de HTTPS se cifran mediante el protocolo Seguridad de la capa de transporte (TLS) para aumentar la seguridad de los datos transferidos entre el cliente y el servidor.
HTTPS requiere un certificado TLS. El certificado TLS se almacena en el servidor y Kestrel está configurado para usarlo. Una aplicación puede usar el certificado de desarrollo HTTPS de ASP.NET Core en un entorno de desarrollo local. El certificado de desarrollo no está instalado en entornos que no son de desarrollo. En un entorno de producción, se debe configurar explícitamente un certificado TLS. Como mínimo, debe existir un certificado predeterminado.
La forma en que se configuran HTTPS y el certificado TLS depende de cómo se configuran los puntos de conexión:
- Si se usan prefijos de dirección URL o solo puertos específicos para definir puntos de conexión, HTTPS solo se puede usar si se proporciona un certificado predeterminado en la configuración de los puntos de conexión HTTPS. Un certificado predeterminado se puede configurar con una de las siguientes opciones:
- Configuración de HTTPS en appsettings.json
- Configuración de HTTPS en el código
Configuración de HTTPS en appsettings.json
Hay disponible un esquema de configuración de aplicación HTTPS predeterminado para Kestrel. Configure varios puntos de conexión (incluidas las direcciones URL y los certificados que va a usar) desde un archivo en disco o desde un almacén de certificados.
Cualquier punto de conexión HTTPS que no especifique un certificado (HttpsDefaultCert
en el siguiente ejemplo) revierte al certificado definido en Certificates:Default
o al certificado de desarrollo.
El ejemplo siguiente es para appsettings.json
, pero se puede usar cualquier origen de configuración:
{
"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$"
}
}
}
}
Advertencia
En el ejemplo anterior, la contraseña de certificado se almacena en texto sin formato en appsettings.json
. El token $CREDENTIAL_PLACEHOLDER$
se usa como marcador de posición para la contraseña del certificado. Para almacenar contraseñas de certificado de forma segura en entornos de desarrollo, vea Protección de secretos en desarrollo. Para almacenar contraseñas de certificado de forma segura en entornos de producción, vea Proveedor de configuración de Azure Key Vault. Los secretos de desarrollo no se deben usar para producción o prueba.
Notas sobre el esquema
- En los nombres de los puntos de conexión se distingue entre mayúsculas y minúsculas. Por ejemplo,
HTTPS
andHttps
son equivalentes. - El parámetro
Url
es necesario en cada punto de conexión. El formato de este parámetro es el mismo que el del parámetro de configuraciónUrls
de nivel superior, excepto por el hecho de que está limitado a un único valor. Consulte los formatos de dirección URL anteriormente en este artículo. - En vez de agregarse, estos puntos de conexión reemplazan a los que están definidos en la configuración
Urls
de nivel superior. Los puntos de conexión definidos en el código a través deListen
son acumulativos con respecto a los puntos de conexión definidos en la sección de configuración. - La sección
Certificate
es opcional. Si la secciónCertificate
no se especifica, se usan los valores predeterminados definidos enCertificates:Default
. Si no hay valores predeterminados disponibles, se utiliza el certificado de desarrollo. Si no hay valores predeterminados y el certificado de desarrollo no está presente, el servidor produce una excepción y no se inicia. - En la sección
Certificate
se admiten varios orígenes de certificados. - Se puede definir el número de puntos de conexión que se quiera en
Configuration
, siempre que no produzcan conflictos de puerto.
Orígenes de certificados
Los nodos de certificado se pueden configurar para cargar certificados de varios orígenes:
Path
yPassword
para cargar archivos .pfx.Path
,KeyPath
yPassword
para cargar archivos .pem/.crt y .key.Subject
yStore
cargar desde el almacén de certificados.
Por ejemplo, el certificado en Certificates:Default
se puede especificar así:
"Default": {
"Subject": "<subject; required>",
"Store": "<cert store; required>",
"Location": "<location; defaults to CurrentUser>",
"AllowInvalid": "<true or false; defaults to false>"
}
Configuración de certificados de cliente en appsettings.json
ClientCertificateMode se usa para configurar el comportamiento del certificado de cliente.
{
"Kestrel": {
"Endpoints": {
"MyHttpsEndpoint": {
"Url": "https://localhost:5001",
"ClientCertificateMode": "AllowCertificate",
"Certificate": {
"Path": "<path to .pfx file>",
"Password": "$CREDENTIAL_PLACEHOLDER$"
}
}
}
}
}
Advertencia
En el ejemplo anterior, la contraseña de certificado se almacena en texto sin formato en appsettings.json
. El token $CREDENTIAL_PLACEHOLDER$
se usa como marcador de posición para la contraseña del certificado. Para almacenar contraseñas de certificado de forma segura en entornos de desarrollo, vea Protección de secretos en desarrollo. Para almacenar contraseñas de certificado de forma segura en entornos de producción, vea Proveedor de configuración de Azure Key Vault. Los secretos de desarrollo no se deben usar para producción o prueba.
El valor predeterminado es ClientCertificateMode.NoCertificate
, donde Kestrel no solicita ni necesita un certificado del cliente.
Para más información, consulte Configuración de la autenticación de certificados en ASP.NET Core.
Configuración de protocolos SSL/TLS en appsettings.json
Los protocolos SSL son protocolos que se utilizan para cifrar y descifrar el tráfico entre dos elementos del mismo nivel, tradicionalmente un cliente y un servidor.
{
"Kestrel": {
"Endpoints": {
"MyHttpsEndpoint": {
"Url": "https://localhost:5001",
"SslProtocols": ["Tls12", "Tls13"],
"Certificate": {
"Path": "<path to .pfx file>",
"Password": "$CREDENTIAL_PLACEHOLDER$"
}
}
}
}
}
Advertencia
En el ejemplo anterior, la contraseña de certificado se almacena en texto sin formato en appsettings.json
. El token $CREDENTIAL_PLACEHOLDER$
se usa como marcador de posición para la contraseña del certificado. Para almacenar contraseñas de certificado de forma segura en entornos de desarrollo, vea Protección de secretos en desarrollo. Para almacenar contraseñas de certificado de forma segura en entornos de producción, vea Proveedor de configuración de Azure Key Vault. Los secretos de desarrollo no se deben usar para producción o prueba.
El valor predeterminado, SslProtocols.None
, hace que Kestrel use los valores predeterminados del sistema operativo para elegir el mejor protocolo. A menos que tenga una razón específica para seleccionar un protocolo, utilice el valor predeterminado.
Configuración de HTTPS en el código
Al usar la Listen
API, el método de la extensión UseHttps de ListenOptions está disponible para configurar HTTPS.
var builder = WebApplication.CreateBuilder(args);
builder.WebHost.ConfigureKestrel((context, serverOptions) =>
{
serverOptions.Listen(IPAddress.Loopback, 5000);
serverOptions.Listen(IPAddress.Loopback, 5001, listenOptions =>
{
listenOptions.UseHttps("testCert.pfx", "testPassword");
});
});
Parámetros de ListenOptions.UseHttps
:
filename
es la ruta de acceso y el nombre de archivo de un archivo de certificado correspondiente al directorio donde están los archivos de contenido de la aplicación.password
es la contraseña necesaria para obtener acceso a los datos del certificado X.509.configureOptions
es unaAction
para configurarHttpsConnectionAdapterOptions
. DevuelveListenOptions
.storeName
es el almacén de certificados desde el que se carga el certificado.subject
es el nombre del sujeto del certificado.allowInvalid
indica si se deben tener en cuenta los certificados no válidos, como los certificados autofirmados.location
es la ubicación del almacén desde el que se carga el certificado.serverCertificate
es el certificado X.509.
Para obtener una lista completa de sobrecargas de UseHttps
, consulte UseHttps.
Configuración de certificados de cliente en el código
ClientCertificateMode configura los requisitos de certificados de cliente.
var builder = WebApplication.CreateBuilder(args);
builder.WebHost.ConfigureKestrel(serverOptions =>
{
serverOptions.ConfigureHttpsDefaults(listenOptions =>
{
listenOptions.ClientCertificateMode = ClientCertificateMode.AllowCertificate;
});
});
El valor predeterminado es NoCertificate, donde Kestrel no solicita ni necesita ningún certificado del cliente.
Para más información, consulte Configuración de la autenticación de certificados en ASP.NET Core.
Configuración de los valores predeterminados de HTTPS en el código
ConfigureHttpsDefaults(Action<HttpsConnectionAdapterOptions>) especifica una configuración Action
que se va a ejecutar para cada punto de conexión HTTPS. Al llamar a ConfigureHttpsDefaults
varias veces, se reemplazan las Action
instancias anteriores por la última Action
especificada.
var builder = WebApplication.CreateBuilder(args);
builder.WebHost.ConfigureKestrel(serverOptions =>
{
serverOptions.ConfigureHttpsDefaults(listenOptions =>
{
// ...
});
});
Nota
Los puntos de conexión que se crean mediante una llamada a Listen antes de llamar a ConfigureHttpsDefaults no tendrán aplicados los valores predeterminados.
Configuración de protocolos SSL/TLS en el código
Los protocolos SSL se utilizan para cifrar y descifrar el tráfico entre dos elementos del mismo nivel, tradicionalmente un cliente y un servidor.
var builder = WebApplication.CreateBuilder(args);
builder.WebHost.ConfigureKestrel(serverOptions =>
{
serverOptions.ConfigureHttpsDefaults(listenOptions =>
{
listenOptions.SslProtocols = SslProtocols.Tls13;
});
});
Configuración del filtro de conjuntos de cifrado TLS en el código
En Linux, se puede usar CipherSuitesPolicy para filtrar los protocolos de enlace TLS por conexión:
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,
// ...
});
};
});
});
Configuración de Indicación de nombre de servidor
Indicación de nombre de servidor (SNI) se puede usar para hospedar varios dominios en la misma dirección IP y puerto. SNI se puede usar para conservar los recursos mediante el servicio de varios sitios desde un servidor.
Para que SNI funcione, el cliente envía el nombre de host de la sesión segura al servidor durante el protocolo de enlace TLS para que, de este modo, el servidor pueda proporcionar el certificado correcto. El cliente usa el certificado proporcionado para la comunicación cifrada con el servidor durante la sesión segura que sigue al protocolo de enlace TLS.
Todos los sitios web se deben ejecutar en la misma instancia de Kestrel. Kestrel no admite el uso compartido de una dirección IP y un puerto entre varias instancias sin un proxy inverso.
SNI se puede configurar de dos maneras:
- Configure una asignación entre los nombres de host y las opciones de HTTPS en Configuración. Por ejemplo, JSON en el archivo
appsettings.json
. - Cree un punto de conexión en el código y seleccione un certificado mediante el nombre de host con la devolución de llamada ServerCertificateSelector.
Configuración de SNI en appsettings.json
Kestrel admite SNI definida en la configuración. Un punto de conexión se puede configurar con un objeto Sni
que contiene una asignación entre los nombres de host y las opciones de HTTPS. El nombre de host de la conexión coincide con las opciones y se usan para esa conexión.
La configuración siguiente agrega un punto de conexión denominado MySniEndpoint
que usa SNI para seleccionar opciones de HTTPS basadas en el nombre de host:
{
"Kestrel": {
"Endpoints": {
"MySniEndpoint": {
"Url": "https://*",
"SslProtocols": ["Tls11", "Tls12"],
"Sni": {
"a.example.org": {
"Protocols": "Http1AndHttp2",
"SslProtocols": ["Tls11", "Tls12", "Tls13"],
"Certificate": {
"Subject": "<subject; required>",
"Store": "<certificate store; required>",
},
"ClientCertificateMode" : "NoCertificate"
},
"*.example.org": {
"Certificate": {
"Path": "<path to .pfx file>",
"Password": "$CREDENTIAL_PLACEHOLDER$"
}
},
"*": {
// At least one subproperty needs to exist per SNI section or it
// cannot be discovered via IConfiguration
"Protocols": "Http1",
}
}
}
},
"Certificates": {
"Default": {
"Path": "<path to .pfx file>",
"Password": "$CREDENTIAL_PLACEHOLDER$"
}
}
}
}
Advertencia
En el ejemplo anterior, la contraseña de certificado se almacena en texto sin formato en appsettings.json
. El token $CREDENTIAL_PLACEHOLDER$
se usa como marcador de posición para la contraseña del certificado. Para almacenar contraseñas de certificado de forma segura en entornos de desarrollo, vea Protección de secretos en desarrollo. Para almacenar contraseñas de certificado de forma segura en entornos de producción, vea Proveedor de configuración de Azure Key Vault. Los secretos de desarrollo no se deben usar para producción o prueba.
Opciones de HTTPS que puede invalidar SNI:
Certificate
configura el origen del certificado.Protocols
configura los protocolos HTTP permitidos.SslProtocols
configura los protocolos SSL permitidos.ClientCertificateMode
configura los requisitos de certificados de cliente.
El nombre de host admite la coincidencia comodín:
- Coincidencia exacta. Por ejemplo,
a.example.org
coincide cona.example.org
. - Prefijo comodín. Si hay varias coincidencias de caracteres comodín, se elige el patrón más largo. Por ejemplo,
*.example.org
coincide conb.example.org
yc.example.org
. - Comodín completo.
*
coincide con todo lo demás, incluidos los clientes que no usan SNI ni envían un nombre de host.
La configuración de SNI coincidente se aplica al punto de conexión de la conexión, anulando valores del punto de conexión. Si una conexión no coincide con un nombre de host de SNI configurado, se rechaza la conexión.
Configuración de SNI con código
Kestrel admite SNI con varias API de devolución de llamada:
ServerCertificateSelector
ServerOptionsSelectionCallback
TlsHandshakeCallbackOptions
SNI con ServerCertificateSelector
Kestrel admite SNI a través de la devolución de llamada ServerCertificateSelector
. La devolución de llamada se invoca una vez por conexión para permitir que la aplicación inspeccione el nombre de host y seleccione el certificado adecuado:
var builder = WebApplication.CreateBuilder(args);
builder.WebHost.ConfigureKestrel(serverOptions =>
{
serverOptions.ListenAnyIP(5005, listenOptions =>
{
listenOptions.UseHttps(httpsOptions =>
{
var localhostCert = CertificateLoader.LoadFromStoreCert(
"localhost", "My", StoreLocation.CurrentUser,
allowInvalid: true);
var exampleCert = CertificateLoader.LoadFromStoreCert(
"example.com", "My", StoreLocation.CurrentUser,
allowInvalid: true);
var subExampleCert = CertificateLoader.LoadFromStoreCert(
"sub.example.com", "My", StoreLocation.CurrentUser,
allowInvalid: true);
var certs = new Dictionary<string, X509Certificate2>(
StringComparer.OrdinalIgnoreCase)
{
["localhost"] = localhostCert,
["example.com"] = exampleCert,
["sub.example.com"] = subExampleCert
};
httpsOptions.ServerCertificateSelector = (connectionContext, name) =>
{
if (name is not null && certs.TryGetValue(name, out var cert))
{
return cert;
}
return exampleCert;
};
});
});
});
SNI con ServerOptionsSelectionCallback
Kestrel admite una configuración de TLS dinámica adicional a través de la devolución de llamada ServerOptionsSelectionCallback
. La devolución de llamada se invoca una vez por conexión para permitir que la aplicación inspeccione el nombre de host y seleccione el certificado adecuado y la configuración de TLS. Los certificados predeterminados y ConfigureHttpsDefaults
no se usan con esta devolución de llamada.
var builder = WebApplication.CreateBuilder(args);
builder.WebHost.ConfigureKestrel(serverOptions =>
{
serverOptions.ListenAnyIP(5005, listenOptions =>
{
listenOptions.UseHttps(httpsOptions =>
{
var localhostCert = CertificateLoader.LoadFromStoreCert(
"localhost", "My", StoreLocation.CurrentUser,
allowInvalid: true);
var exampleCert = CertificateLoader.LoadFromStoreCert(
"example.com", "My", StoreLocation.CurrentUser,
allowInvalid: true);
listenOptions.UseHttps((stream, clientHelloInfo, state, cancellationToken) =>
{
if (string.Equals(clientHelloInfo.ServerName, "localhost",
StringComparison.OrdinalIgnoreCase))
{
return new ValueTask<SslServerAuthenticationOptions>(
new SslServerAuthenticationOptions
{
ServerCertificate = localhostCert,
// Different TLS requirements for this host
ClientCertificateRequired = true
});
}
return new ValueTask<SslServerAuthenticationOptions>(
new SslServerAuthenticationOptions
{
ServerCertificate = exampleCert
});
}, state: null!);
});
});
});
SNI con TlsHandshakeCallbackOptions
Kestrel admite una configuración de TLS dinámica adicional a través de la devolución de llamada TlsHandshakeCallbackOptions.OnConnection
. La devolución de llamada se invoca una vez por conexión para permitir que la aplicación inspeccione el nombre de host y seleccione el certificado adecuado, la configuración de TLS y otras opciones de servidor. Los certificados predeterminados y ConfigureHttpsDefaults
no se usan con esta devolución de llamada.
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
});
}
});
});
});
});
Configuración de protocolos HTTP
Kestrel admite todas las versiones HTTP que se usan habitualmente. Los puntos de conexión se pueden configurar para admitir diferentes versiones de HTTP mediante la enumeración de HttpProtocols, que especifica las opciones de la versión de HTTP disponibles.
Se requiere TLS para admitir más de una versión de HTTP. El protocolo de enlace Application-Layer Protocol Negotiation (ALPN) de TLS se usa para negociar el protocolo de conexión entre el cliente y el servidor cuando un punto de conexión admite varios protocolos.
Valor de HttpProtocols |
Protocolo de conexión permitido |
---|---|
Http1 |
HTTP/1.1 solo. Puede usarse con o sin TLS. |
Http2 |
HTTP/2 solo. Se pueden utilizar sin TLS solo si el cliente admite un modo de conocimientos previos. |
Http3 |
Solo HTTP/3. Requiere TLS. Es posible que el cliente deba configurarse para usar solo HTTP/3. |
Http1AndHttp2 |
HTTP/1.1 y HTTP/2. HTTP/2 necesita que el cliente seleccione HTTP/2 en el protocolo de enlace Negociación de protocolo de nivel de aplicación (ALPN) de TLS; en caso contrario, el valor predeterminado de la conexión es HTTP/1.1. |
Http1AndHttp2AndHttp3 |
HTTP/1.1, HTTP/2 y HTTP/3. La primera solicitud de cliente normalmente usa HTTP/1.1 o HTTP/2, y el alt-svc encabezado de respuesta solicita al cliente que actualice a HTTP/3. HTTP/2 y HTTP/3 requieren TLS; de lo contrario, la conexión establece como valor predeterminado HTTP/1.1. |
El valor de protocolo predeterminado de un punto de conexión es HttpProtocols.Http1AndHttp2
.
Restricciones de TLS para HTTP/2:
- TLS 1.2 o versiones posteriores
- Renegociación deshabilitada
- Compresión deshabilitada
- Tamaños de intercambio de claves efímeras mínimos:
- Curva elíptica Diffie-Hellman (ECDHE) [RFC4492]: 224 bits como mínimo
- Campo finito Diffie-Hellman (DHE) (DHE) [
TLS12
]: 2048 bits como mínimo
- Conjunto de cifrado no prohibido.
TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
[TLS-ECDHE
] con la curva elíptica P-256 [FIPS186
] se admite de forma predeterminada.
Configuración de protocolos HTTP en appsettings.json
En el siguiente ejemplo de appsettings.json
se establece el protocolo de conexión HTTP/1.1 para un punto de conexión específico:
{
"Kestrel": {
"Endpoints": {
"HttpsDefaultCert": {
"Url": "https://localhost:5001",
"Protocols": "Http1"
}
}
}
}
Se puede configurar un protocolo predeterminado en la sección Kestrel:EndpointDefaults
. En el siguiente ejemplo de appsettings.json
, se establece HTTP/1.1 como el protocolo de conexión predeterminado para todos los puntos de conexión:
{
"Kestrel": {
"EndpointDefaults": {
"Protocols": "Http1"
}
}
}
Los protocolos especificados en el código invalidan los valores establecidos por la configuración.
Configuración de protocolos HTTP
ListenOptions.Protocols se usa para especificar protocolos con la enumeración HttpProtocols.
El siguiente ejemplo configura un punto de conexión para HTTP/1.1, HTTP/2, y HTTP/3 en el puerto 8000. Las conexiones se protegen mediante TLS con un certificado proporcionado:
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;
});
});
Consulte también
Los proyectos de ASP.NET Core están configurados para enlazarse a un puerto HTTP aleatorio entre 5000 y 5300 y un puerto HTTPS aleatorio entre 7000 y 7300. Esta configuración predeterminada se especifica en el archivo Properties/launchSettings.json
generado y se puede invalidar. Si no se especifica ningún puerto, Kestrel se enlaza a http://localhost:5000
.
Especifique direcciones URL mediante los siguientes elementos:
- La variable de entorno
ASPNETCORE_URLS
. - El argumento de la línea de comandos
--urls
. - La clave de configuración de host
urls
. - El método de extensión UseUrls.
El valor que estos métodos suministran puede ser uno o más puntos de conexión HTTP y HTTPS (este último, si hay disponible un certificado predeterminado). Configure el valor como una lista separada por punto y coma (por ejemplo, "Urls": "http://localhost:8000;http://localhost:8001"
).
Para más información sobre estos enfoques, consulte Direcciones URL del servidor e Invalidar la configuración.
Un certificado de desarrollo se crea:
- Al instalar el SDK de .NET.
- Para crear un certificado, se usa la herramienta dev-certs.
El certificado de desarrollo solo está disponible para el usuario que genera el certificado. Algunos exploradores necesitan que se conceda permiso explícito para confiar en el certificado de desarrollo local.
Las plantillas de proyecto configuran aplicaciones para que se ejecuten en HTTPS de forma predeterminada e incluyen redirección de HTTPS y compatibilidad con HSTS.
Llame a los métodos Listen o ListenUnixSocket de KestrelServerOptions para configurar los puertos y los prefijos de dirección URL para Kestrel.
UseUrls
, el argumento de línea de comandos --urls
, la clave de configuración de host urls
y la variable de entorno ASPNETCORE_URLS
también funcionan, pero tienen las limitaciones que se indican más adelante en esta sección (debe haber disponible un certificado predeterminado para la configuración de puntos de conexión HTTPS).
Configuración de KestrelServerOptions
:
ConfigureEndpointDefaults
ConfigureEndpointDefaults(Action<ListenOptions>) especifica una configuración Action
para ejecutar para cada punto de conexión especificado. Al llamar a ConfigureEndpointDefaults
varias veces, se reemplazan las Action
anteriores por la última Action
especificada:
var builder = WebApplication.CreateBuilder(args);
builder.WebHost.ConfigureKestrel(serverOptions =>
{
serverOptions.ConfigureEndpointDefaults(listenOptions =>
{
// ...
});
});
Nota
Los puntos de conexión que se crean mediante una llamada a Listen antes de llamar a ConfigureEndpointDefaults no tendrán aplicados los valores predeterminados.
Configure(IConfiguration)
Habilita Kestrel para cargar puntos de conexión desde IConfiguration. El ámbito de la configuración debe corresponderse con la sección de configuración de Kestrel. La sobrecarga Configure(IConfiguration, bool)
se puede usar para habilitar los puntos de conexión de recarga cuando cambia el origen de configuración.
De forma predeterminada, la configuración de Kestrel se carga desde la sección Kestrel
y se habilita la recarga de los cambios:
{
"Kestrel": {
"Endpoints": {
"Http": {
"Url": "http://localhost:5000"
},
"Https": {
"Url": "https://localhost:5001"
}
}
}
}
Si la configuración de recarga está habilitada y se señala un cambio, se realizarán los pasos siguientes:
- La nueva configuración se compara con la anterior, no se modifica ningún punto de conexión sin cambios de configuración.
- A los puntos de conexión eliminados o modificados se les asignan cinco segundos para completar las solicitudes de procesamiento y cerrarse.
- Los puntos de conexión nuevos o modificados se inician.
Los clientes que se conectan a un punto de conexión modificado pueden desconectarse o rechazarse mientras se reinicia el punto de conexión.
ConfigureHttpsDefaults
ConfigureHttpsDefaults(Action<HttpsConnectionAdapterOptions>) especifica una configuración Action
para ejecutar para cada punto de conexión HTTPS. Al llamar a ConfigureHttpsDefaults
varias veces, se reemplazan las Action
anteriores por la última Action
especificada.
var builder = WebApplication.CreateBuilder(args);
builder.WebHost.ConfigureKestrel(serverOptions =>
{
serverOptions.ConfigureHttpsDefaults(listenOptions =>
{
// ...
});
});
Nota
Los puntos de conexión que se crean mediante una llamada a Listen antes de llamar a ConfigureHttpsDefaults no tendrán aplicados los valores predeterminados.
ListenOptions.UseHttps
Configure Kestrel para que use HTTPS.
Extensiones de ListenOptions.UseHttps
:
UseHttps
: configure Kestrel para que use HTTPS con el certificado predeterminado. Produce una excepción si no hay ningún certificado predeterminado 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
es la ruta de acceso y el nombre de archivo de un archivo de certificado correspondiente al directorio donde están los archivos de contenido de la aplicación.password
es la contraseña necesaria para obtener acceso a los datos del certificado X.509.configureOptions
es unaAction
para configurarHttpsConnectionAdapterOptions
. DevuelveListenOptions
.storeName
es el almacén de certificados desde el que se carga el certificado.subject
es el nombre del sujeto del certificado.allowInvalid
indica si se deben tener en cuenta los certificados no válidos, como los certificados autofirmados.location
es la ubicación del almacén desde el que se carga el certificado.serverCertificate
es el certificado X.509.
En un entorno de producción, HTTPS se debe configurar explícitamente. Como mínimo, debe existir un certificado predeterminado.
Si los certificados se leen desde el disco, en lugar de un almacén de certificados de Windows, el directorio contenedor debe tener los permisos adecuados para evitar el acceso no autorizado.
Estas son las configuraciones compatibles:
- Sin configuración
- Reemplazar el certificado predeterminado de configuración
- Cambiar los valores predeterminados en el código
Sin configuración
Kestrel escucha en http://localhost:5000
.
Reemplazar el certificado predeterminado de configuración
Hay disponible un esquema de configuración de aplicación HTTPS predeterminado para Kestrel. Configure varios puntos de conexión (incluidas las direcciones URL y los certificados que va a usar) desde un archivo en disco o desde un almacén de certificados.
En el ejemplo appsettings.json
siguiente:
- Establezca
AllowInvalid
entrue
para permitir el uso de certificados no válidos (por ejemplo, certificados autofirmados). - Cualquier punto de conexión HTTPS que no especifique un certificado (
HttpsDefaultCert
en el siguiente ejemplo) revierte al certificado definido enCertificates:Default
o al certificado de desarrollo.
{
"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$"
}
}
}
}
Advertencia
En el ejemplo anterior, las contraseñas de certificado se almacenan en texto sin formato en appsettings.json
. El token $CREDENTIAL_PLACEHOLDER$
se usa como marcador de posición para la contraseña de cada certificado. Para almacenar contraseñas de certificado de forma segura en entornos de desarrollo, vea Protección de secretos en desarrollo. Para almacenar contraseñas de certificado de forma segura en entornos de producción, vea Proveedor de configuración de Azure Key Vault. Los secretos de desarrollo no se deben usar para producción o prueba.
Notas sobre el esquema:
- En los nombres de los puntos de conexión se distingue entre mayúsculas y minúsculas. Por ejemplo,
HTTPS
andHttps
son equivalentes. - El parámetro
Url
es necesario en cada punto de conexión. El formato de este parámetro es el mismo que el del parámetro de configuraciónUrls
de nivel superior, excepto por el hecho de que está limitado a un único valor. - En vez de agregarse, estos puntos de conexión reemplazan a los que están definidos en la configuración
Urls
de nivel superior. Los puntos de conexión definidos en el código a través deListen
son acumulativos con respecto a los puntos de conexión definidos en la sección de configuración. - La sección
Certificate
es opcional. Si la secciónCertificate
no se especifica, se usan los valores predeterminados definidos enCertificates:Default
. Si no hay valores predeterminados disponibles, se utiliza el certificado de desarrollo. Si no hay valores predeterminados y el certificado de desarrollo no está presente, el servidor produce una excepción y no se inicia. - En la sección
Certificate
se admiten varios orígenes de certificados. - Se puede definir el número de puntos de conexión que se quiera en la configuración, siempre y cuando no produzcan conflictos de puerto.
Orígenes de certificados
Los nodos de certificado se pueden configurar para cargar certificados de varios orígenes:
Path
yPassword
para cargar archivos .pfx.Path
,KeyPath
yPassword
para cargar archivos .pem/.crt y .key.Subject
yStore
cargar desde el almacén de certificados.
Por ejemplo, el certificado en Certificates:Default
se puede especificar así:
"Default": {
"Subject": "<subject; required>",
"Store": "<cert store; required>",
"Location": "<location; defaults to CurrentUser>",
"AllowInvalid": "<true or false; defaults to false>"
}
ConfigurationLoader
Configure(IConfiguration) devuelve un KestrelConfigurationLoader con un método Endpoint(String, Action<EndpointConfiguration>) que se puede usar para complementar la configuración de un punto de conexión configurado:
var builder = WebApplication.CreateBuilder(args);
builder.WebHost.ConfigureKestrel((context, serverOptions) =>
{
var kestrelSection = context.Configuration.GetSection("Kestrel");
serverOptions.Configure(kestrelSection)
.Endpoint("HTTPS", listenOptions =>
{
// ...
});
});
Se puede acceder directamente a KestrelServerOptions.ConfigurationLoader
para seguir con la iteración en el cargador existente, como el proporcionado por WebApplicationBuilder.WebHost.
- La sección de configuración de cada punto de conexión está disponible en las opciones del método
Endpoint
para que se pueda leer la configuración personalizada. - Se pueden cargar varias configuraciones volviendo a llamar a Configure(IConfiguration) con otra sección. Se usa la última configuración, a menos que se llame explícitamente a
Load
en instancias anteriores. El metapaquete no llama aLoad
, con lo cual su sección de configuración predeterminada se puede reemplazar. KestrelConfigurationLoader
refleja la familiaListen
de API deKestrelServerOptions
como sobrecargas deEndpoint
, por lo que los puntos de conexión de configuración y código se pueden configurar en el mismo lugar. En estas sobrecargas no se usan nombres y solo consumen valores predeterminados de la configuración.
Cambiar los valores predeterminados en el código
ConfigureEndpointDefaults
y ConfigureHttpsDefaults
se pueden usar para cambiar la configuración predeterminada de ListenOptions
y HttpsConnectionAdapterOptions
, incluido sustituir el certificado predeterminado especificado en el escenario anterior. Se debe llamar a ConfigureEndpointDefaults
y a ConfigureHttpsDefaults
antes de que se configure algún punto de conexión.
var builder = WebApplication.CreateBuilder(args);
builder.WebHost.ConfigureKestrel((context, serverOptions) =>
{
serverOptions.ConfigureEndpointDefaults(listenOptions =>
{
// ...
});
serverOptions.ConfigureHttpsDefaults(listenOptions =>
{
// ...
});
});
Configuración de puntos de conexión mediante Indicación de nombre de servidor
Indicación de nombre de servidor (SNI) se puede usar para hospedar varios dominios en la misma dirección IP y puerto. Para que SNI funcione, el cliente envía el nombre de host de la sesión segura al servidor durante el protocolo de enlace TLS para que, de este modo, el servidor pueda proporcionar el certificado correcto. El cliente usa el certificado proporcionado para la comunicación cifrada con el servidor durante la sesión segura que sigue al protocolo de enlace TLS.
SNI se puede configurar de dos maneras:
- Cree un punto de conexión en el código y seleccione un certificado mediante el nombre de host con la devolución de llamada ServerCertificateSelector.
- Configure una asignación entre los nombres de host y las opciones de HTTPS en Configuración. Por ejemplo, JSON en el archivo
appsettings.json
.
SNI con ServerCertificateSelector
Kestrel admite SNI a través de la devolución de llamada ServerCertificateSelector
. La devolución de llamada se invoca una vez por conexión para permitir que la aplicación inspeccione el nombre de host y seleccione el certificado adecuado:
var builder = WebApplication.CreateBuilder(args);
builder.WebHost.ConfigureKestrel(serverOptions =>
{
serverOptions.ListenAnyIP(5005, listenOptions =>
{
listenOptions.UseHttps(httpsOptions =>
{
var localhostCert = CertificateLoader.LoadFromStoreCert(
"localhost", "My", StoreLocation.CurrentUser,
allowInvalid: true);
var exampleCert = CertificateLoader.LoadFromStoreCert(
"example.com", "My", StoreLocation.CurrentUser,
allowInvalid: true);
var subExampleCert = CertificateLoader.LoadFromStoreCert(
"sub.example.com", "My", StoreLocation.CurrentUser,
allowInvalid: true);
var certs = new Dictionary<string, X509Certificate2>(
StringComparer.OrdinalIgnoreCase)
{
["localhost"] = localhostCert,
["example.com"] = exampleCert,
["sub.example.com"] = subExampleCert
};
httpsOptions.ServerCertificateSelector = (connectionContext, name) =>
{
if (name is not null && certs.TryGetValue(name, out var cert))
{
return cert;
}
return exampleCert;
};
});
});
});
SNI con ServerOptionsSelectionCallback
Kestrel admite una configuración de TLS dinámica adicional a través de la devolución de llamada ServerOptionsSelectionCallback
. La devolución de llamada se invoca una vez por conexión para permitir que la aplicación inspeccione el nombre de host y seleccione el certificado adecuado y la configuración de TLS. Los certificados predeterminados y ConfigureHttpsDefaults
no se usan con esta devolución de llamada.
var builder = WebApplication.CreateBuilder(args);
builder.WebHost.ConfigureKestrel(serverOptions =>
{
serverOptions.ListenAnyIP(5005, listenOptions =>
{
listenOptions.UseHttps(httpsOptions =>
{
var localhostCert = CertificateLoader.LoadFromStoreCert(
"localhost", "My", StoreLocation.CurrentUser,
allowInvalid: true);
var exampleCert = CertificateLoader.LoadFromStoreCert(
"example.com", "My", StoreLocation.CurrentUser,
allowInvalid: true);
listenOptions.UseHttps((stream, clientHelloInfo, state, cancellationToken) =>
{
if (string.Equals(clientHelloInfo.ServerName, "localhost",
StringComparison.OrdinalIgnoreCase))
{
return new ValueTask<SslServerAuthenticationOptions>(
new SslServerAuthenticationOptions
{
ServerCertificate = localhostCert,
// Different TLS requirements for this host
ClientCertificateRequired = true
});
}
return new ValueTask<SslServerAuthenticationOptions>(
new SslServerAuthenticationOptions
{
ServerCertificate = exampleCert
});
}, state: null!);
});
});
});
SNI con TlsHandshakeCallbackOptions
Kestrel admite una configuración de TLS dinámica adicional a través de la devolución de llamada TlsHandshakeCallbackOptions.OnConnection
. La devolución de llamada se invoca una vez por conexión para permitir que la aplicación inspeccione el nombre de host y seleccione el certificado adecuado, la configuración de TLS y otras opciones de servidor. Los certificados predeterminados y ConfigureHttpsDefaults
no se usan con esta devolución de llamada.
var builder = WebApplication.CreateBuilder(args);
builder.WebHost.ConfigureKestrel(serverOptions =>
{
serverOptions.ListenAnyIP(5005, listenOptions =>
{
listenOptions.UseHttps(httpsOptions =>
{
var localhostCert = CertificateLoader.LoadFromStoreCert(
"localhost", "My", StoreLocation.CurrentUser,
allowInvalid: true);
var exampleCert = CertificateLoader.LoadFromStoreCert(
"example.com", "My", StoreLocation.CurrentUser,
allowInvalid: true);
listenOptions.UseHttps(new TlsHandshakeCallbackOptions
{
OnConnection = context =>
{
if (string.Equals(context.ClientHelloInfo.ServerName, "localhost",
StringComparison.OrdinalIgnoreCase))
{
// Different TLS requirements for this host
context.AllowDelayedClientCertificateNegotation = true;
return new ValueTask<SslServerAuthenticationOptions>(
new SslServerAuthenticationOptions
{
ServerCertificate = localhostCert
});
}
return new ValueTask<SslServerAuthenticationOptions>(
new SslServerAuthenticationOptions
{
ServerCertificate = exampleCert
});
}
});
});
});
});
SNI en la configuración
Kestrel admite SNI definida en la configuración. Un punto de conexión se puede configurar con un objeto Sni
que contiene una asignación entre los nombres de host y las opciones de HTTPS. El nombre de host de la conexión coincide con las opciones y se usan para esa conexión.
La configuración siguiente agrega un punto de conexión denominado MySniEndpoint
que usa SNI para seleccionar opciones de HTTPS basadas en el nombre de host:
{
"Kestrel": {
"Endpoints": {
"MySniEndpoint": {
"Url": "https://*",
"SslProtocols": ["Tls11", "Tls12"],
"Sni": {
"a.example.org": {
"Protocols": "Http1AndHttp2",
"SslProtocols": ["Tls11", "Tls12", "Tls13"],
"Certificate": {
"Subject": "<subject; required>",
"Store": "<certificate store; required>",
},
"ClientCertificateMode" : "NoCertificate"
},
"*.example.org": {
"Certificate": {
"Path": "<path to .pfx file>",
"Password": "$CREDENTIAL_PLACEHOLDER$"
}
},
"*": {
// At least one subproperty needs to exist per SNI section or it
// cannot be discovered via IConfiguration
"Protocols": "Http1",
}
}
}
},
"Certificates": {
"Default": {
"Path": "<path to .pfx file>",
"Password": "$CREDENTIAL_PLACEHOLDER$"
}
}
}
}
Advertencia
En el ejemplo anterior, las contraseñas de certificado se almacenan en texto sin formato en appsettings.json
. El token $CREDENTIAL_PLACEHOLDER$
se usa como marcador de posición para la contraseña de cada certificado. Para almacenar contraseñas de certificado de forma segura en entornos de desarrollo, vea Protección de secretos en desarrollo. Para almacenar contraseñas de certificado de forma segura en entornos de producción, vea Proveedor de configuración de Azure Key Vault. Los secretos de desarrollo no se deben usar para producción o prueba.
Opciones de HTTPS que puede invalidar SNI:
Certificate
configura el origen del certificado.Protocols
configura los protocolos HTTP permitidos.SslProtocols
configura los protocolos SSL permitidos.ClientCertificateMode
configura los requisitos de certificados de cliente.
El nombre de host admite la coincidencia comodín:
- Coincidencia exacta. Por ejemplo,
a.example.org
coincide cona.example.org
. - Prefijo comodín. Si hay varias coincidencias comodín, se elige el patrón más largo. Por ejemplo,
*.example.org
coincide conb.example.org
yc.example.org
. - Comodín completo.
*
coincide con todo lo demás, incluidos los clientes que no usan SNI ni envían un nombre de host.
La configuración de SNI coincidente se aplica al punto de conexión de la conexión, anulando valores del punto de conexión. Si una conexión no coincide con un nombre de host de SNI configurado, se rechaza la conexión.
Requisitos de SNI
Todos los sitios web se deben ejecutar en la misma instancia de Kestrel. Kestrel no admite el uso compartido de una dirección IP y un puerto entre varias instancias sin un proxy inverso.
Protocolos SSL/TLS
Los protocolos SSL son protocolos que se utilizan para cifrar y descifrar el tráfico entre dos elementos del mismo nivel, tradicionalmente un cliente y un servidor.
var builder = WebApplication.CreateBuilder(args);
builder.WebHost.ConfigureKestrel(serverOptions =>
{
serverOptions.ConfigureHttpsDefaults(listenOptions =>
{
listenOptions.SslProtocols = SslProtocols.Tls13;
});
});
{
"Kestrel": {
"Endpoints": {
"MyHttpsEndpoint": {
"Url": "https://localhost:5001",
"SslProtocols": ["Tls12", "Tls13"],
"Certificate": {
"Path": "<path to .pfx file>",
"Password": "$CREDENTIAL_PLACEHOLDER$"
}
}
}
}
}
Advertencia
En el ejemplo anterior, la contraseña de certificado se almacena en texto sin formato en appsettings.json
. El token $CREDENTIAL_PLACEHOLDER$
se usa como marcador de posición para la contraseña del certificado. Para almacenar contraseñas de certificado de forma segura en entornos de desarrollo, vea Protección de secretos en desarrollo. Para almacenar contraseñas de certificado de forma segura en entornos de producción, vea Proveedor de configuración de Azure Key Vault. Los secretos de desarrollo no se deben usar para producción o prueba.
El valor predeterminado, SslProtocols.None
, hace que Kestrel use los valores predeterminados del sistema operativo para elegir el mejor protocolo. A menos que tenga una razón específica para seleccionar un protocolo, utilice el valor predeterminado.
Certificados de cliente
ClientCertificateMode
configura los requisitos de certificados de cliente.
var builder = WebApplication.CreateBuilder(args);
builder.WebHost.ConfigureKestrel(serverOptions =>
{
serverOptions.ConfigureHttpsDefaults(listenOptions =>
{
listenOptions.ClientCertificateMode = ClientCertificateMode.AllowCertificate;
});
});
{
"Kestrel": {
"Endpoints": {
"MyHttpsEndpoint": {
"Url": "https://localhost:5001",
"ClientCertificateMode": "AllowCertificate",
"Certificate": {
"Path": "<path to .pfx file>",
"Password": "$CREDENTIAL_PLACEHOLDER$"
}
}
}
}
}
Advertencia
En el ejemplo anterior, la contraseña de certificado se almacena en texto sin formato en appsettings.json
. El token $CREDENTIAL_PLACEHOLDER$
se usa como marcador de posición para la contraseña del certificado. Para almacenar contraseñas de certificado de forma segura en entornos de desarrollo, vea Protección de secretos en desarrollo. Para almacenar contraseñas de certificado de forma segura en entornos de producción, vea Proveedor de configuración de Azure Key Vault.
El valor predeterminado es ClientCertificateMode.NoCertificate
, donde Kestrel no solicitará ni necesitará un certificado del cliente.
Para más información, consulte Configuración de la autenticación de certificados en ASP.NET Core.
Registro de conexiones
Llame a UseConnectionLogging para emitir registros de nivel de depuración para la comunicación a nivel de bytes en una conexión. El registro de conexiones es útil para solucionar problemas en la comunicación de bajo nivel, como durante el cifrado TLS y detrás de los servidores proxy. Si UseConnectionLogging
se coloca antes de UseHttps
, se registra el tráfico cifrado. Si UseConnectionLogging
se coloca después de UseHttps
, se registra el tráfico descifrado. Este es el middleware de conexión integrado.
var builder = WebApplication.CreateBuilder(args);
builder.WebHost.ConfigureKestrel((context, serverOptions) =>
{
serverOptions.Listen(IPAddress.Any, 8000, listenOptions =>
{
listenOptions.UseConnectionLogging();
});
});
Enlazar a un socket TCP
El método Listen se enlaza a un socket TCP y una expresión lambda de opciones permite configurar un certificado X.509:
var builder = WebApplication.CreateBuilder(args);
builder.WebHost.ConfigureKestrel((context, serverOptions) =>
{
serverOptions.Listen(IPAddress.Loopback, 5000);
serverOptions.Listen(IPAddress.Loopback, 5001, listenOptions =>
{
listenOptions.UseHttps("testCert.pfx", "testPassword");
});
});
En el ejemplo se configura HTTPS para un punto de conexión con ListenOptions. Use la misma API para configurar otras opciones de Kestrel para puntos de conexión específicos.
En Windows, pueden crearse certificados autofirmados con el New-SelfSignedCertificate
cmdlet de PowerShell. Para ver un ejemplo no admitido, consulte UpdateIISExpressSSLForChrome.ps1
.
En macOS, Linux y Windows, pueden crearse certificados con OpenSSL.
Enlazar a un socket de Unix
Escuche en un socket de Unix con ListenUnixSocket para mejorar el rendimiento con Nginx, tal como se muestra en este ejemplo:
var builder = WebApplication.CreateBuilder(args);
builder.WebHost.ConfigureKestrel((context, serverOptions) =>
{
serverOptions.ListenUnixSocket("/tmp/kestrel-test.sock");
});
- En el archivo de configuración de Nginx, establezca la entrada
server
>location
>proxy_pass
enhttp://unix:/tmp/{KESTREL SOCKET}:/;
.{KESTREL SOCKET}
es el nombre del socket proporcionado para ListenUnixSocket (por ejemplo,kestrel-test.sock
en el ejemplo anterior). - Asegúrese de que el socket es grabable por Nginx (por ejemplo,
chmod go+w /tmp/kestrel-test.sock
).
Puerto 0
Cuando se especifica el número de puerto 0
, Kestrel se enlaza de forma dinámica a un puerto disponible. En el ejemplo siguiente se muestra cómo determinar a qué puerto se enlaza Kestrel en el entorno de ejecución:
app.Run(async (context) =>
{
var serverAddressFeature = context.Features.Get<IServerAddressesFeature>();
if (serverAddressFeature is not null)
{
var listenAddresses = string.Join(", ", serverAddressFeature.Addresses);
// ...
}
});
El enlace dinámico de un puerto no está disponible en algunas situaciones:
ListenLocalhost
- Enlace conjunto de HTTP/1.1 o HTTP/2 basado en TCP y HTTP/3 basado en QUIC.
Limitaciones
Configure puntos de conexión con los siguientes métodos:
- UseUrls
- El argumento de la línea de comandos
--urls
- La clave de configuración de host
urls
- La variable de entorno
ASPNETCORE_URLS
Estos métodos son útiles para que el código funcione con servidores que no sean de Kestrel. Sin embargo, tenga en cuenta las siguientes limitaciones:
- HTTPS no se puede usar con estos enfoques, a menos que se proporcione un certificado predeterminado en la configuración del punto de conexión HTTPS (por ejemplo, mediante la configuración
KestrelServerOptions
o un archivo de configuración, como se ha mostrado antes en este artículo). - Cuando los métodos
Listen
yUseUrls
se usan al mismo tiempo, los puntos de conexión deListen
sustituyen a los deUseUrls
.
Configuración de puntos de conexión IIS
Cuando se usa IIS, los enlaces de direcciones URL de IIS reemplazan a los enlaces que se hayan establecido por medio de Listen
o de UseUrls
. Para más información, vea ASP.NET Core Module (Módulo de ASP.NET Core).
ListenOptions.Protocols
La propiedad Protocols
establece los protocolos HTTP (HttpProtocols
) habilitados en un punto de conexión o para el servidor. Asigne un valor a la propiedad Protocols
desde el valor de enumeración HttpProtocols
.
Valor de enumeración HttpProtocols |
Protocolo de conexión permitido |
---|---|
Http1 |
HTTP/1.1 solo. Puede usarse con o sin TLS. |
Http2 |
HTTP/2 solo. Se pueden utilizar sin TLS solo si el cliente admite un modo de conocimientos previos. |
Http3 |
Solo HTTP/3. Requiere TLS. Es posible que el cliente deba configurarse para usar solo HTTP/3. |
Http1AndHttp2 |
HTTP/1.1 y HTTP/2. HTTP/2 necesita que el cliente seleccione HTTP/2 en el protocolo de enlace Negociación de protocolo de nivel de aplicación (ALPN) de TLS; en caso contrario, el valor predeterminado de la conexión es HTTP/1.1. |
Http1AndHttp2AndHttp3 |
HTTP/1.1, HTTP/2 y HTTP/3. La primera solicitud de cliente normalmente usa HTTP/1.1 o HTTP/2, y el alt-svc encabezado de respuesta solicita al cliente que actualice a HTTP/3. HTTP/2 y HTTP/3 requieren TLS; de lo contrario, la conexión establece como valor predeterminado HTTP/1.1. |
El valor ListenOptions.Protocols
predeterminado de cualquier punto de conexión es HttpProtocols.Http1AndHttp2
.
Restricciones de TLS para HTTP/2:
- TLS 1.2 o versiones posteriores
- Renegociación deshabilitada
- Compresión deshabilitada
- Tamaños de intercambio de claves efímeras mínimos:
- Curva elíptica Diffie-Hellman (ECDHE) [RFC4492]: 224 bits como mínimo
- Campo finito Diffie-Hellman (DHE) (DHE) [
TLS12
]: 2048 bits como mínimo
- Conjunto de cifrado no prohibido.
TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
[TLS-ECDHE
] con la curva elíptica P-256 [FIPS186
] se admite de forma predeterminada.
El siguiente ejemplo permite conexiones HTTP/1.1 y HTTP/2 en el puerto 8000. Las conexiones se protegen mediante TLS con un certificado proporcionado:
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;
});
});
En Linux, se puede usar CipherSuitesPolicy para filtrar los protocolos de enlace TLS por conexión:
var builder = WebApplication.CreateBuilder(args);
builder.WebHost.ConfigureKestrel((context, serverOptions) =>
{
serverOptions.ConfigureHttpsDefaults(listenOptions =>
{
listenOptions.OnAuthenticate = (context, sslOptions) =>
{
sslOptions.CipherSuitesPolicy = new CipherSuitesPolicy(
new[]
{
TlsCipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
TlsCipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
// ...
});
};
});
});
Middleware de conexión
Si es necesario, el middleware de conexión personalizado puede filtrar por cifrados específicos los protocolos de enlace TLS por cada conexión.
En el ejemplo siguiente se produce una excepción NotSupportedException con cualquier algoritmo de cifrado que no admita la aplicación. Como alternativa, defina y compare ITlsHandshakeFeature.CipherAlgorithm con una lista de conjuntos de cifrado aceptables.
No se usa ningún cifrado con un algoritmo de cifrado CipherAlgorithmType.Null.
var builder = WebApplication.CreateBuilder(args);
builder.WebHost.ConfigureKestrel((context, serverOptions) =>
{
serverOptions.Listen(IPAddress.Any, 8000, listenOptions =>
{
listenOptions.UseHttps("testCert.pfx", "testPassword");
listenOptions.Use((context, next) =>
{
var tlsFeature = context.Features.Get<ITlsHandshakeFeature>()!;
if (tlsFeature.CipherAlgorithm == CipherAlgorithmType.Null)
{
throw new NotSupportedException(
$"Prohibited cipher: {tlsFeature.CipherAlgorithm}");
}
return next();
});
});
});
Establecimiento del protocolo HTTP a partir de la configuración
De forma predeterminada, la configuración de Kestrel se carga desde la sección Kestrel
. En el siguiente ejemplo de appsettings.json
, se establece HTTP/1.1 como el protocolo de conexión predeterminado para todos los puntos de conexión:
{
"Kestrel": {
"EndpointDefaults": {
"Protocols": "Http1"
}
}
}
En el siguiente ejemplo de appsettings.json
se establece el protocolo de conexión HTTP/1.1 para un punto de conexión específico:
{
"Kestrel": {
"Endpoints": {
"HttpsDefaultCert": {
"Url": "https://localhost:5001",
"Protocols": "Http1"
}
}
}
}
Los protocolos especificados en el código invalidan los valores establecidos por la configuración.
Prefijos de URL
Al usar UseUrls
, el argumento de línea de comandos --urls
, la clave de configuración de host urls
o una variable de entorno ASPNETCORE_URLS
, los prefijos de dirección URL pueden tener cualquiera de estos formatos.
Solo son válidos los prefijos de dirección URL HTTP. Kestrel no admite HTTPS al configurar enlaces de dirección URL con UseUrls
.
Dirección IPv4 con número de puerto
http://65.55.39.10:80/
0.0.0.0
es un caso especial que enlaza a todas las direcciones IPv4.Dirección IPv6 con número de puerto
http://[0:0:0:0:0:ffff:4137:270a]:80/
[::]
es el equivalente en IPv6 de0.0.0.0
en IPv4.Nombre de host con número de puerto
http://contoso.com:80/ http://*:80/
Los nombres de host,
*
y+
no son especiales. Todo lo que no se identifique como una dirección IP o unlocalhost
válido se enlaza a todas las direcciones IP de IPv6 e IPv4. Para enlazar otros nombres de host a otras aplicaciones ASP.NET Core en el mismo puerto, use HTTP.sys o un servidor proxy inverso. Entre los ejemplos de servidor proxy inverso se incluyen IIS, Nginx o Apache.Advertencia
El hospedaje en una configuración de proxy inverso requiere filtrado de hosts.
Nombre
localhost
del host con el número de puerto o la IP de bucle invertido con el número de puertohttp://localhost:5000/ http://127.0.0.1:5000/ http://[::1]:5000/
Cuando se especifica
localhost
, Kestrel intenta enlazar a las interfaces de bucle invertido de IPv4 e IPv6. Si el puerto solicitado lo está usando otro servicio en cualquier interfaz de bucle invertido, Kestrel no se puede iniciar. Si ninguna de estas interfaces de bucle invertido está disponible por cualquier otra razón (normalmente porque no se admite IPv6), Kestrel registra una advertencia.
Los proyectos de ASP.NET Core están configurados para enlazarse a un puerto HTTP aleatorio entre 5000 y 5300 y un puerto HTTPS aleatorio entre 7000 y 7300. Esta configuración predeterminada se especifica en el archivo Properties/launchSettings.json
generado y se puede invalidar. Si no se especifica ningún puerto, Kestrel se enlaza a:
http://localhost:5000
https://localhost:5001
(cuando hay presente un certificado de desarrollo local)
Especifique direcciones URL mediante los siguientes elementos:
- La variable de entorno
ASPNETCORE_URLS
. - El argumento de la línea de comandos
--urls
. - La clave de configuración de host
urls
. - El método de extensión UseUrls.
El valor que estos métodos suministran puede ser uno o más puntos de conexión HTTP y HTTPS (este último, si hay disponible un certificado predeterminado). Configure el valor como una lista separada por punto y coma (por ejemplo, "Urls": "http://localhost:8000;http://localhost:8001"
).
Para más información sobre estos enfoques, consulte Direcciones URL del servidor e Invalidar la configuración.
Un certificado de desarrollo se crea:
- Al instalar el SDK de .NET.
- Para crear un certificado, se usa la herramienta dev-certs.
El certificado de desarrollo solo está disponible para el usuario que genera el certificado. Algunos exploradores necesitan que se conceda permiso explícito para confiar en el certificado de desarrollo local.
Las plantillas de proyecto configuran aplicaciones para que se ejecuten en HTTPS de forma predeterminada e incluyen redirección de HTTPS y compatibilidad con HSTS.
Llame a los métodos Listen o ListenUnixSocket de KestrelServerOptions para configurar los puertos y los prefijos de dirección URL para Kestrel.
UseUrls
, el argumento de línea de comandos --urls
, la clave de configuración de host urls
y la variable de entorno ASPNETCORE_URLS
también funcionan, pero tienen las limitaciones que se indican más adelante en esta sección (debe haber disponible un certificado predeterminado para la configuración de puntos de conexión HTTPS).
Configuración de KestrelServerOptions
:
ConfigureEndpointDefaults
ConfigureEndpointDefaults(Action<ListenOptions>) especifica una configuración Action
para ejecutar para cada punto de conexión especificado. Al llamar a ConfigureEndpointDefaults
varias veces, se reemplazan las Action
anteriores por la última Action
especificada:
var builder = WebApplication.CreateBuilder(args);
builder.WebHost.ConfigureKestrel(serverOptions =>
{
serverOptions.ConfigureEndpointDefaults(listenOptions =>
{
// ...
});
});
Nota
Los puntos de conexión que se crean mediante una llamada a Listen antes de llamar a ConfigureEndpointDefaults no tendrán aplicados los valores predeterminados.
Configure(IConfiguration)
Habilita Kestrel para cargar puntos de conexión desde IConfiguration. El ámbito de la configuración debe corresponderse con la sección de configuración de Kestrel. La sobrecarga Configure(IConfiguration, bool)
se puede usar para habilitar los puntos de conexión de recarga cuando cambia el origen de configuración.
De forma predeterminada, la configuración de Kestrel se carga desde la sección Kestrel
y se habilita la recarga de los cambios:
{
"Kestrel": {
"Endpoints": {
"Http": {
"Url": "http://localhost:5000"
},
"Https": {
"Url": "https://localhost:5001"
}
}
}
}
Si la configuración de recarga está habilitada y se señala un cambio, se realizarán los pasos siguientes:
- La nueva configuración se compara con la anterior, no se modifica ningún punto de conexión sin cambios de configuración.
- A los puntos de conexión eliminados o modificados se les asignan cinco segundos para completar las solicitudes de procesamiento y cerrarse.
- Los puntos de conexión nuevos o modificados se inician.
Los clientes que se conectan a un punto de conexión modificado pueden desconectarse o rechazarse mientras se reinicia el punto de conexión.
ConfigureHttpsDefaults
ConfigureHttpsDefaults(Action<HttpsConnectionAdapterOptions>) especifica una configuración Action
para ejecutar para cada punto de conexión HTTPS. Al llamar a ConfigureHttpsDefaults
varias veces, se reemplazan las Action
anteriores por la última Action
especificada.
var builder = WebApplication.CreateBuilder(args);
builder.WebHost.ConfigureKestrel(serverOptions =>
{
serverOptions.ConfigureHttpsDefaults(listenOptions =>
{
// ...
});
});
Nota
Los puntos de conexión que se crean mediante una llamada a Listen antes de llamar a ConfigureHttpsDefaults no tendrán aplicados los valores predeterminados.
ListenOptions.UseHttps
Configure Kestrel para que use HTTPS.
Extensiones de ListenOptions.UseHttps
:
UseHttps
: configure Kestrel para que use HTTPS con el certificado predeterminado. Produce una excepción si no hay ningún certificado predeterminado 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
es la ruta de acceso y el nombre de archivo de un archivo de certificado correspondiente al directorio donde están los archivos de contenido de la aplicación.password
es la contraseña necesaria para obtener acceso a los datos del certificado X.509.configureOptions
es unaAction
para configurarHttpsConnectionAdapterOptions
. DevuelveListenOptions
.storeName
es el almacén de certificados desde el que se carga el certificado.subject
es el nombre del sujeto del certificado.allowInvalid
indica si se deben tener en cuenta los certificados no válidos, como los certificados autofirmados.location
es la ubicación del almacén desde el que se carga el certificado.serverCertificate
es el certificado X.509.
En un entorno de producción, HTTPS se debe configurar explícitamente. Como mínimo, debe existir un certificado predeterminado.
Estas son las configuraciones compatibles:
- Sin configuración
- Reemplazar el certificado predeterminado de configuración
- Cambiar los valores predeterminados en el código
Sin configuración
Kestrel escucha en http://localhost:5000
y en https://localhost:5001
(si hay disponible un certificado predeterminado).
Reemplazar el certificado predeterminado de configuración
Hay disponible un esquema de configuración de aplicación HTTPS predeterminado para Kestrel. Configure varios puntos de conexión (incluidas las direcciones URL y los certificados que va a usar) desde un archivo en disco o desde un almacén de certificados.
En el ejemplo appsettings.json
siguiente:
- Establezca
AllowInvalid
entrue
para permitir el uso de certificados no válidos (por ejemplo, certificados autofirmados). - Cualquier punto de conexión HTTPS que no especifique un certificado (
HttpsDefaultCert
en el siguiente ejemplo) revierte al certificado definido enCertificates:Default
o al certificado de desarrollo.
{
"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$"
}
}
}
}
Advertencia
En el ejemplo anterior, las contraseñas de certificado se almacenan en texto sin formato en appsettings.json
. El token $CREDENTIAL_PLACEHOLDER$
se usa como marcador de posición para la contraseña de cada certificado. Para almacenar contraseñas de certificado de forma segura en entornos de desarrollo, vea Protección de secretos en desarrollo. Para almacenar contraseñas de certificado de forma segura en entornos de producción, vea Proveedor de configuración de Azure Key Vault. Los secretos de desarrollo no se deben usar para producción o prueba.
Notas sobre el esquema:
- En los nombres de los puntos de conexión se distingue entre mayúsculas y minúsculas. Por ejemplo,
HTTPS
andHttps
son equivalentes. - El parámetro
Url
es necesario en cada punto de conexión. El formato de este parámetro es el mismo que el del parámetro de configuraciónUrls
de nivel superior, excepto por el hecho de que está limitado a un único valor. - En vez de agregarse, estos puntos de conexión reemplazan a los que están definidos en la configuración
Urls
de nivel superior. Los puntos de conexión definidos en el código a través deListen
son acumulativos con respecto a los puntos de conexión definidos en la sección de configuración. - La sección
Certificate
es opcional. Si la secciónCertificate
no se especifica, se usan los valores predeterminados definidos enCertificates:Default
. Si no hay valores predeterminados disponibles, se utiliza el certificado de desarrollo. Si no hay valores predeterminados y el certificado de desarrollo no está presente, el servidor produce una excepción y no se inicia. - En la sección
Certificate
se admiten varios orígenes de certificados. - Se puede definir el número de puntos de conexión que se quiera en la configuración, siempre y cuando no produzcan conflictos de puerto.
Orígenes de certificados
Los nodos de certificado se pueden configurar para cargar certificados de varios orígenes:
Path
yPassword
para cargar archivos .pfx.Path
,KeyPath
yPassword
para cargar archivos .pem/.crt y .key.Subject
yStore
cargar desde el almacén de certificados.
Por ejemplo, el certificado en Certificates:Default
se puede especificar así:
"Default": {
"Subject": "<subject; required>",
"Store": "<cert store; required>",
"Location": "<location; defaults to CurrentUser>",
"AllowInvalid": "<true or false; defaults to false>"
}
ConfigurationLoader
Configure(IConfiguration) devuelve un KestrelConfigurationLoader con un método Endpoint(String, Action<EndpointConfiguration>) que se puede usar para complementar la configuración de un punto de conexión configurado:
var builder = WebApplication.CreateBuilder(args);
builder.WebHost.ConfigureKestrel((context, serverOptions) =>
{
var kestrelSection = context.Configuration.GetSection("Kestrel");
serverOptions.Configure(kestrelSection)
.Endpoint("HTTPS", listenOptions =>
{
// ...
});
});
Se puede acceder directamente a KestrelServerOptions.ConfigurationLoader
para seguir con la iteración en el cargador existente, como el proporcionado por WebApplicationBuilder.WebHost.
- La sección de configuración de cada punto de conexión está disponible en las opciones del método
Endpoint
para que se pueda leer la configuración personalizada. - Se pueden cargar varias configuraciones volviendo a llamar a Configure(IConfiguration) con otra sección. Se usa la última configuración, a menos que se llame explícitamente a
Load
en instancias anteriores. El metapaquete no llama aLoad
, con lo cual su sección de configuración predeterminada se puede reemplazar. KestrelConfigurationLoader
refleja la familiaListen
de API deKestrelServerOptions
como sobrecargas deEndpoint
, por lo que los puntos de conexión de configuración y código se pueden configurar en el mismo lugar. En estas sobrecargas no se usan nombres y solo consumen valores predeterminados de la configuración.
Cambiar los valores predeterminados en el código
ConfigureEndpointDefaults
y ConfigureHttpsDefaults
se pueden usar para cambiar la configuración predeterminada de ListenOptions
y HttpsConnectionAdapterOptions
, incluido sustituir el certificado predeterminado especificado en el escenario anterior. Se debe llamar a ConfigureEndpointDefaults
y a ConfigureHttpsDefaults
antes de que se configure algún punto de conexión.
var builder = WebApplication.CreateBuilder(args);
builder.WebHost.ConfigureKestrel((context, serverOptions) =>
{
serverOptions.ConfigureEndpointDefaults(listenOptions =>
{
// ...
});
serverOptions.ConfigureHttpsDefaults(listenOptions =>
{
// ...
});
});
Configuración de puntos de conexión mediante Indicación de nombre de servidor
Indicación de nombre de servidor (SNI) se puede usar para hospedar varios dominios en la misma dirección IP y puerto. Para que SNI funcione, el cliente envía el nombre de host de la sesión segura al servidor durante el protocolo de enlace TLS para que, de este modo, el servidor pueda proporcionar el certificado correcto. El cliente usa el certificado proporcionado para la comunicación cifrada con el servidor durante la sesión segura que sigue al protocolo de enlace TLS.
SNI se puede configurar de dos maneras:
- Cree un punto de conexión en el código y seleccione un certificado mediante el nombre de host con la devolución de llamada ServerCertificateSelector.
- Configure una asignación entre los nombres de host y las opciones de HTTPS en Configuración. Por ejemplo, JSON en el archivo
appsettings.json
.
SNI con ServerCertificateSelector
Kestrel admite SNI a través de la devolución de llamada ServerCertificateSelector
. La devolución de llamada se invoca una vez por conexión para permitir que la aplicación inspeccione el nombre de host y seleccione el certificado adecuado:
var builder = WebApplication.CreateBuilder(args);
builder.WebHost.ConfigureKestrel(serverOptions =>
{
serverOptions.ListenAnyIP(5005, listenOptions =>
{
listenOptions.UseHttps(httpsOptions =>
{
var localhostCert = CertificateLoader.LoadFromStoreCert(
"localhost", "My", StoreLocation.CurrentUser,
allowInvalid: true);
var exampleCert = CertificateLoader.LoadFromStoreCert(
"example.com", "My", StoreLocation.CurrentUser,
allowInvalid: true);
var subExampleCert = CertificateLoader.LoadFromStoreCert(
"sub.example.com", "My", StoreLocation.CurrentUser,
allowInvalid: true);
var certs = new Dictionary<string, X509Certificate2>(
StringComparer.OrdinalIgnoreCase)
{
["localhost"] = localhostCert,
["example.com"] = exampleCert,
["sub.example.com"] = subExampleCert
};
httpsOptions.ServerCertificateSelector = (connectionContext, name) =>
{
if (name is not null && certs.TryGetValue(name, out var cert))
{
return cert;
}
return exampleCert;
};
});
});
});
SNI con ServerOptionsSelectionCallback
Kestrel admite una configuración de TLS dinámica adicional a través de la devolución de llamada ServerOptionsSelectionCallback
. La devolución de llamada se invoca una vez por conexión para permitir que la aplicación inspeccione el nombre de host y seleccione el certificado adecuado y la configuración de TLS. Los certificados predeterminados y ConfigureHttpsDefaults
no se usan con esta devolución de llamada.
var builder = WebApplication.CreateBuilder(args);
builder.WebHost.ConfigureKestrel(serverOptions =>
{
serverOptions.ListenAnyIP(5005, listenOptions =>
{
listenOptions.UseHttps(httpsOptions =>
{
var localhostCert = CertificateLoader.LoadFromStoreCert(
"localhost", "My", StoreLocation.CurrentUser,
allowInvalid: true);
var exampleCert = CertificateLoader.LoadFromStoreCert(
"example.com", "My", StoreLocation.CurrentUser,
allowInvalid: true);
listenOptions.UseHttps((stream, clientHelloInfo, state, cancellationToken) =>
{
if (string.Equals(clientHelloInfo.ServerName, "localhost",
StringComparison.OrdinalIgnoreCase))
{
return new ValueTask<SslServerAuthenticationOptions>(
new SslServerAuthenticationOptions
{
ServerCertificate = localhostCert,
// Different TLS requirements for this host
ClientCertificateRequired = true
});
}
return new ValueTask<SslServerAuthenticationOptions>(
new SslServerAuthenticationOptions
{
ServerCertificate = exampleCert
});
}, state: null!);
});
});
});
SNI con TlsHandshakeCallbackOptions
Kestrel admite una configuración de TLS dinámica adicional a través de la devolución de llamada TlsHandshakeCallbackOptions.OnConnection
. La devolución de llamada se invoca una vez por conexión para permitir que la aplicación inspeccione el nombre de host y seleccione el certificado adecuado, la configuración de TLS y otras opciones de servidor. Los certificados predeterminados y ConfigureHttpsDefaults
no se usan con esta devolución de llamada.
var builder = WebApplication.CreateBuilder(args);
builder.WebHost.ConfigureKestrel(serverOptions =>
{
serverOptions.ListenAnyIP(5005, listenOptions =>
{
listenOptions.UseHttps(httpsOptions =>
{
var localhostCert = CertificateLoader.LoadFromStoreCert(
"localhost", "My", StoreLocation.CurrentUser,
allowInvalid: true);
var exampleCert = CertificateLoader.LoadFromStoreCert(
"example.com", "My", StoreLocation.CurrentUser,
allowInvalid: true);
listenOptions.UseHttps(new TlsHandshakeCallbackOptions
{
OnConnection = context =>
{
if (string.Equals(context.ClientHelloInfo.ServerName, "localhost",
StringComparison.OrdinalIgnoreCase))
{
// Different TLS requirements for this host
context.AllowDelayedClientCertificateNegotation = true;
return new ValueTask<SslServerAuthenticationOptions>(
new SslServerAuthenticationOptions
{
ServerCertificate = localhostCert
});
}
return new ValueTask<SslServerAuthenticationOptions>(
new SslServerAuthenticationOptions
{
ServerCertificate = exampleCert
});
}
});
});
});
});
SNI en la configuración
Kestrel admite SNI definida en la configuración. Un punto de conexión se puede configurar con un objeto Sni
que contiene una asignación entre los nombres de host y las opciones de HTTPS. El nombre de host de la conexión coincide con las opciones y se usan para esa conexión.
La configuración siguiente agrega un punto de conexión denominado MySniEndpoint
que usa SNI para seleccionar opciones de HTTPS basadas en el nombre de host:
{
"Kestrel": {
"Endpoints": {
"MySniEndpoint": {
"Url": "https://*",
"SslProtocols": ["Tls11", "Tls12"],
"Sni": {
"a.example.org": {
"Protocols": "Http1AndHttp2",
"SslProtocols": ["Tls11", "Tls12", "Tls13"],
"Certificate": {
"Subject": "<subject; required>",
"Store": "<certificate store; required>",
},
"ClientCertificateMode" : "NoCertificate"
},
"*.example.org": {
"Certificate": {
"Path": "<path to .pfx file>",
"Password": "$CREDENTIAL_PLACEHOLDER$"
}
},
"*": {
// At least one subproperty needs to exist per SNI section or it
// cannot be discovered via IConfiguration
"Protocols": "Http1",
}
}
}
},
"Certificates": {
"Default": {
"Path": "<path to .pfx file>",
"Password": "$CREDENTIAL_PLACEHOLDER$"
}
}
}
}
Advertencia
En el ejemplo anterior, las contraseñas de certificado se almacenan en texto sin formato en appsettings.json
. El token $CREDENTIAL_PLACEHOLDER$
se usa como marcador de posición para la contraseña de cada certificado. Para almacenar contraseñas de certificado de forma segura en entornos de desarrollo, vea Protección de secretos en desarrollo. Para almacenar contraseñas de certificado de forma segura en entornos de producción, vea Proveedor de configuración de Azure Key Vault. Los secretos de desarrollo no se deben usar para producción o prueba.
Opciones de HTTPS que puede invalidar SNI:
Certificate
configura el origen del certificado.Protocols
configura los protocolos HTTP permitidos.SslProtocols
configura los protocolos SSL permitidos.ClientCertificateMode
configura los requisitos de certificados de cliente.
El nombre de host admite la coincidencia comodín:
- Coincidencia exacta. Por ejemplo,
a.example.org
coincide cona.example.org
. - Prefijo comodín. Si hay varias coincidencias comodín, se elige el patrón más largo. Por ejemplo,
*.example.org
coincide conb.example.org
yc.example.org
. - Comodín completo.
*
coincide con todo lo demás, incluidos los clientes que no usan SNI ni envían un nombre de host.
La configuración de SNI coincidente se aplica al punto de conexión de la conexión, anulando valores del punto de conexión. Si una conexión no coincide con un nombre de host de SNI configurado, se rechaza la conexión.
Requisitos de SNI
Todos los sitios web se deben ejecutar en la misma instancia de Kestrel. Kestrel no admite el uso compartido de una dirección IP y un puerto entre varias instancias sin un proxy inverso.
Protocolos SSL/TLS
Los protocolos SSL son protocolos que se utilizan para cifrar y descifrar el tráfico entre dos elementos del mismo nivel, tradicionalmente un cliente y un servidor.
var builder = WebApplication.CreateBuilder(args);
builder.WebHost.ConfigureKestrel(serverOptions =>
{
serverOptions.ConfigureHttpsDefaults(listenOptions =>
{
listenOptions.SslProtocols = SslProtocols.Tls13;
});
});
{
"Kestrel": {
"Endpoints": {
"MyHttpsEndpoint": {
"Url": "https://localhost:5001",
"SslProtocols": ["Tls12", "Tls13"],
"Certificate": {
"Path": "<path to .pfx file>",
"Password": "$CREDENTIAL_PLACEHOLDER$"
}
}
}
}
}
Advertencia
En el ejemplo anterior, la contraseña de certificado se almacena en texto sin formato en appsettings.json
. El token $CREDENTIAL_PLACEHOLDER$
se usa como marcador de posición para la contraseña del certificado. Para almacenar contraseñas de certificado de forma segura en entornos de desarrollo, vea Protección de secretos en desarrollo. Para almacenar contraseñas de certificado de forma segura en entornos de producción, vea Proveedor de configuración de Azure Key Vault. Los secretos de desarrollo no se deben usar para producción o prueba.
El valor predeterminado, SslProtocols.None
, hace que Kestrel use los valores predeterminados del sistema operativo para elegir el mejor protocolo. A menos que tenga una razón específica para seleccionar un protocolo, utilice el valor predeterminado.
Certificados de cliente
ClientCertificateMode
configura los requisitos de certificados de cliente.
var builder = WebApplication.CreateBuilder(args);
builder.WebHost.ConfigureKestrel(serverOptions =>
{
serverOptions.ConfigureHttpsDefaults(listenOptions =>
{
listenOptions.ClientCertificateMode = ClientCertificateMode.AllowCertificate;
});
});
{
"Kestrel": {
"Endpoints": {
"MyHttpsEndpoint": {
"Url": "https://localhost:5001",
"ClientCertificateMode": "AllowCertificate",
"Certificate": {
"Path": "<path to .pfx file>",
"Password": "$CREDENTIAL_PLACEHOLDER$"
}
}
}
}
}
Advertencia
En el ejemplo anterior, la contraseña de certificado se almacena en texto sin formato en appsettings.json
. El token $CREDENTIAL_PLACEHOLDER$
se usa como marcador de posición para la contraseña del certificado. Para almacenar contraseñas de certificado de forma segura en entornos de desarrollo, vea Protección de secretos en desarrollo. Para almacenar contraseñas de certificado de forma segura en entornos de producción, vea Proveedor de configuración de Azure Key Vault.
El valor predeterminado es ClientCertificateMode.NoCertificate
, donde Kestrel no solicitará ni necesitará un certificado del cliente.
Para más información, consulte Configuración de la autenticación de certificados en ASP.NET Core.
Registro de conexiones
Llame a UseConnectionLogging para emitir registros de nivel de depuración para la comunicación a nivel de bytes en una conexión. El registro de conexiones es útil para solucionar problemas en la comunicación de bajo nivel, como durante el cifrado TLS y detrás de los servidores proxy. Si UseConnectionLogging
se coloca antes de UseHttps
, se registra el tráfico cifrado. Si UseConnectionLogging
se coloca después de UseHttps
, se registra el tráfico descifrado. Este es el middleware de conexión integrado.
var builder = WebApplication.CreateBuilder(args);
builder.WebHost.ConfigureKestrel((context, serverOptions) =>
{
serverOptions.Listen(IPAddress.Any, 8000, listenOptions =>
{
listenOptions.UseConnectionLogging();
});
});
Enlazar a un socket TCP
El método Listen se enlaza a un socket TCP y una expresión lambda de opciones permite configurar un certificado X.509:
var builder = WebApplication.CreateBuilder(args);
builder.WebHost.ConfigureKestrel((context, serverOptions) =>
{
serverOptions.Listen(IPAddress.Loopback, 5000);
serverOptions.Listen(IPAddress.Loopback, 5001, listenOptions =>
{
listenOptions.UseHttps("testCert.pfx", "testPassword");
});
});
En el ejemplo se configura HTTPS para un punto de conexión con ListenOptions. Use la misma API para configurar otras opciones de Kestrel para puntos de conexión específicos.
En Windows, pueden crearse certificados autofirmados con el New-SelfSignedCertificate
cmdlet de PowerShell. Para ver un ejemplo no admitido, consulte UpdateIISExpressSSLForChrome.ps1
.
En macOS, Linux y Windows, pueden crearse certificados con OpenSSL.
Enlazar a un socket de Unix
Escuche en un socket de Unix con ListenUnixSocket para mejorar el rendimiento con Nginx, tal como se muestra en este ejemplo:
var builder = WebApplication.CreateBuilder(args);
builder.WebHost.ConfigureKestrel((context, serverOptions) =>
{
serverOptions.ListenUnixSocket("/tmp/kestrel-test.sock");
});
- En el archivo de configuración de Nginx, establezca la entrada
server
>location
>proxy_pass
enhttp://unix:/tmp/{KESTREL SOCKET}:/;
.{KESTREL SOCKET}
es el nombre del socket proporcionado para ListenUnixSocket (por ejemplo,kestrel-test.sock
en el ejemplo anterior). - Asegúrese de que el socket es grabable por Nginx (por ejemplo,
chmod go+w /tmp/kestrel-test.sock
).
Puerto 0
Cuando se especifica el número de puerto 0
, Kestrel se enlaza de forma dinámica a un puerto disponible. En el ejemplo siguiente se muestra cómo determinar a qué puerto se enlaza Kestrel en el entorno de ejecución:
app.Run(async (context) =>
{
var serverAddressFeature = context.Features.Get<IServerAddressesFeature>();
if (serverAddressFeature is not null)
{
var listenAddresses = string.Join(", ", serverAddressFeature.Addresses);
// ...
}
});
Limitaciones
Configure puntos de conexión con los siguientes métodos:
- UseUrls
- El argumento de la línea de comandos
--urls
- La clave de configuración de host
urls
- La variable de entorno
ASPNETCORE_URLS
Estos métodos son útiles para que el código funcione con servidores que no sean de Kestrel. Sin embargo, tenga en cuenta las siguientes limitaciones:
- HTTPS no se puede usar con estos enfoques, a menos que se proporcione un certificado predeterminado en la configuración del punto de conexión HTTPS (por ejemplo, mediante la configuración
KestrelServerOptions
o un archivo de configuración, como se ha mostrado antes en este artículo). - Cuando los métodos
Listen
yUseUrls
se usan al mismo tiempo, los puntos de conexión deListen
sustituyen a los deUseUrls
.
Configuración de puntos de conexión IIS
Cuando se usa IIS, los enlaces de direcciones URL de IIS reemplazan a los enlaces que se hayan establecido por medio de Listen
o de UseUrls
. Para más información, vea ASP.NET Core Module (Módulo de ASP.NET Core).
ListenOptions.Protocols
La propiedad Protocols
establece los protocolos HTTP (HttpProtocols
) habilitados en un punto de conexión o para el servidor. Asigne un valor a la propiedad Protocols
desde el valor de enumeración HttpProtocols
.
Valor de enumeración HttpProtocols |
Protocolo de conexión permitido |
---|---|
Http1 |
HTTP/1.1 solo. Puede usarse con o sin TLS. |
Http2 |
HTTP/2 solo. Se pueden utilizar sin TLS solo si el cliente admite un modo de conocimientos previos. |
Http1AndHttp2 |
HTTP/1.1 y HTTP/2. HTTP/2 necesita que el cliente seleccione HTTP/2 en el protocolo de enlace Negociación de protocolo de nivel de aplicación (ALPN) de TLS; en caso contrario, el valor predeterminado de la conexión es HTTP/1.1. |
El valor ListenOptions.Protocols
predeterminado de cualquier punto de conexión es HttpProtocols.Http1AndHttp2
.
Restricciones de TLS para HTTP/2:
- TLS 1.2 o versiones posteriores
- Renegociación deshabilitada
- Compresión deshabilitada
- Tamaños de intercambio de claves efímeras mínimos:
- Curva elíptica Diffie-Hellman (ECDHE) [RFC4492]: 224 bits como mínimo
- Campo finito Diffie-Hellman (DHE) (DHE) [
TLS12
]: 2048 bits como mínimo
- Conjunto de cifrado no prohibido.
TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
[TLS-ECDHE
] con la curva elíptica P-256 [FIPS186
] se admite de forma predeterminada.
El siguiente ejemplo permite conexiones HTTP/1.1 y HTTP/2 en el puerto 8000. Las conexiones se protegen mediante TLS con un certificado proporcionado:
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;
});
});
En Linux, se puede usar CipherSuitesPolicy para filtrar los protocolos de enlace TLS por conexión:
var builder = WebApplication.CreateBuilder(args);
builder.WebHost.ConfigureKestrel((context, serverOptions) =>
{
serverOptions.ConfigureHttpsDefaults(listenOptions =>
{
listenOptions.OnAuthenticate = (context, sslOptions) =>
{
sslOptions.CipherSuitesPolicy = new CipherSuitesPolicy(
new[]
{
TlsCipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
TlsCipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
// ...
});
};
});
});
Middleware de conexión
Si es necesario, el middleware de conexión personalizado puede filtrar por cifrados específicos los protocolos de enlace TLS por cada conexión.
En el ejemplo siguiente se produce una excepción NotSupportedException con cualquier algoritmo de cifrado que no admita la aplicación. Como alternativa, defina y compare ITlsHandshakeFeature.CipherAlgorithm con una lista de conjuntos de cifrado aceptables.
No se usa ningún cifrado con un algoritmo de cifrado CipherAlgorithmType.Null.
var builder = WebApplication.CreateBuilder(args);
builder.WebHost.ConfigureKestrel((context, serverOptions) =>
{
serverOptions.Listen(IPAddress.Any, 8000, listenOptions =>
{
listenOptions.UseHttps("testCert.pfx", "testPassword");
listenOptions.Use((context, next) =>
{
var tlsFeature = context.Features.Get<ITlsHandshakeFeature>()!;
if (tlsFeature.CipherAlgorithm == CipherAlgorithmType.Null)
{
throw new NotSupportedException(
$"Prohibited cipher: {tlsFeature.CipherAlgorithm}");
}
return next();
});
});
});
Establecimiento del protocolo HTTP a partir de la configuración
De forma predeterminada, la configuración de Kestrel se carga desde la sección Kestrel
. En el siguiente ejemplo de appsettings.json
, se establece HTTP/1.1 como el protocolo de conexión predeterminado para todos los puntos de conexión:
{
"Kestrel": {
"EndpointDefaults": {
"Protocols": "Http1"
}
}
}
En el siguiente ejemplo de appsettings.json
se establece el protocolo de conexión HTTP/1.1 para un punto de conexión específico:
{
"Kestrel": {
"Endpoints": {
"HttpsDefaultCert": {
"Url": "https://localhost:5001",
"Protocols": "Http1"
}
}
}
}
Los protocolos especificados en el código invalidan los valores establecidos por la configuración.
Prefijos de URL
Al usar UseUrls
, el argumento de línea de comandos --urls
, la clave de configuración de host urls
o una variable de entorno ASPNETCORE_URLS
, los prefijos de dirección URL pueden tener cualquiera de estos formatos.
Solo son válidos los prefijos de dirección URL HTTP. Kestrel no admite HTTPS al configurar enlaces de dirección URL con UseUrls
.
Dirección IPv4 con número de puerto
http://65.55.39.10:80/
0.0.0.0
es un caso especial que enlaza a todas las direcciones IPv4.Dirección IPv6 con número de puerto
http://[0:0:0:0:0:ffff:4137:270a]:80/
[::]
es el equivalente en IPv6 de0.0.0.0
en IPv4.Nombre de host con número de puerto
http://contoso.com:80/ http://*:80/
Los nombres de host,
*
y+
no son especiales. Todo lo que no se identifique como una dirección IP o unlocalhost
válido se enlaza a todas las direcciones IP de IPv6 e IPv4. Para enlazar otros nombres de host a otras aplicaciones ASP.NET Core en el mismo puerto, use HTTP.sys o un servidor proxy inverso. Entre los ejemplos de servidor proxy inverso se incluyen IIS, Nginx o Apache.Advertencia
El hospedaje en una configuración de proxy inverso requiere filtrado de hosts.
Nombre
localhost
del host con el número de puerto o la IP de bucle invertido con el número de puertohttp://localhost:5000/ http://127.0.0.1:5000/ http://[::1]:5000/
Cuando se especifica
localhost
, Kestrel intenta enlazar a las interfaces de bucle invertido de IPv4 e IPv6. Si el puerto solicitado lo está usando otro servicio en cualquier interfaz de bucle invertido, Kestrel no se puede iniciar. Si ninguna de estas interfaces de bucle invertido está disponible por cualquier otra razón (normalmente porque no se admite IPv6), Kestrel registra una advertencia.
ASP.NET Core enlaza de forma predeterminada a:
http://localhost:5000
https://localhost:5001
(cuando hay presente un certificado de desarrollo local)
Especifique direcciones URL mediante los siguientes elementos:
- La variable de entorno
ASPNETCORE_URLS
. - El argumento de la línea de comandos
--urls
. - La clave de configuración de host
urls
. - El método de extensión UseUrls.
El valor que estos métodos suministran puede ser uno o más puntos de conexión HTTP y HTTPS (este último, si hay disponible un certificado predeterminado). Configure el valor como una lista separada por punto y coma (por ejemplo, "Urls": "http://localhost:8000;http://localhost:8001"
).
Para más información sobre estos enfoques, consulte Direcciones URL del servidor e Invalidar la configuración.
Un certificado de desarrollo se crea:
- Al instalar el SDK de .NET.
- Para crear un certificado, se usa la herramienta dev-certs.
Algunos exploradores necesitan que se conceda permiso explícito para confiar en el certificado de desarrollo local.
Las plantillas de proyecto configuran aplicaciones para que se ejecuten en HTTPS de forma predeterminada e incluyen redirección de HTTPS y compatibilidad con HSTS.
Llame a los métodos Listen o ListenUnixSocket de KestrelServerOptions para configurar los puertos y los prefijos de dirección URL para Kestrel.
UseUrls
, el argumento de línea de comandos --urls
, la clave de configuración de host urls
y la variable de entorno ASPNETCORE_URLS
también funcionan, pero tienen las limitaciones que se indican más adelante en esta sección (debe haber disponible un certificado predeterminado para la configuración de puntos de conexión HTTPS).
Configuración de KestrelServerOptions
:
ConfigureEndpointDefaults
ConfigureEndpointDefaults(Action<ListenOptions>) especifica una configuración Action
para ejecutar para cada punto de conexión especificado. Al llamar a ConfigureEndpointDefaults
varias veces, se reemplazan las Action
anteriores por la última Action
especificada.
webBuilder.ConfigureKestrel(serverOptions =>
{
serverOptions.ConfigureEndpointDefaults(listenOptions =>
{
// Configure endpoint defaults
});
});
Nota
Los puntos de conexión que se crean mediante una llamada a Listen antes de llamar a ConfigureEndpointDefaults no tendrán aplicados los valores predeterminados.
Configure(IConfiguration)
Habilita Kestrel para cargar puntos de conexión desde IConfiguration. El ámbito de la configuración debe corresponderse con la sección de configuración de Kestrel.
La sobrecarga Configure(IConfiguration, bool)
se puede usar para habilitar los puntos de conexión de recarga cuando cambia el origen de configuración.
IHostBuilder.ConfigureWebHostDefaults
llama a Configure(context.Configuration.GetSection("Kestrel"), reloadOnChange: true)
de forma predeterminada para cargar la configuración de Kestrel y habilitar la recarga.
{
"Kestrel": {
"Endpoints": {
"Http": {
"Url": "http://localhost:5000"
},
"Https": {
"Url": "https://localhost:5001"
}
}
}
}
Si la configuración de recarga está habilitada y se señala un cambio, se realizarán los pasos siguientes:
- La nueva configuración se compara con la anterior, no se modifica ningún punto de conexión sin cambios de configuración.
- A los puntos de conexión eliminados o modificados se les asignan cinco segundos para completar las solicitudes de procesamiento y cerrarse.
- Los puntos de conexión nuevos o modificados se inician.
Los clientes que se conectan a un punto de conexión modificado pueden desconectarse o rechazarse mientras se reinicia el punto de conexión.
ConfigureHttpsDefaults
ConfigureHttpsDefaults(Action<HttpsConnectionAdapterOptions>) especifica una configuración Action
para ejecutar para cada punto de conexión HTTPS. Al llamar a ConfigureHttpsDefaults
varias veces, se reemplazan las Action
anteriores por la última Action
especificada.
webBuilder.ConfigureKestrel(serverOptions =>
{
serverOptions.ConfigureHttpsDefaults(listenOptions =>
{
// certificate is an X509Certificate2
listenOptions.ServerCertificate = certificate;
});
});
Nota
Los puntos de conexión que se crean mediante una llamada a Listen antes de llamar a ConfigureHttpsDefaults no tendrán aplicados los valores predeterminados.
ListenOptions.UseHttps
Configure Kestrel para que use HTTPS.
Extensiones de ListenOptions.UseHttps
:
UseHttps
: configure Kestrel para que use HTTPS con el certificado predeterminado. Produce una excepción si no hay ningún certificado predeterminado 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
es la ruta de acceso y el nombre de archivo de un archivo de certificado correspondiente al directorio donde están los archivos de contenido de la aplicación.password
es la contraseña necesaria para obtener acceso a los datos del certificado X.509.configureOptions
es unaAction
para configurarHttpsConnectionAdapterOptions
. DevuelveListenOptions
.storeName
es el almacén de certificados desde el que se carga el certificado.subject
es el nombre del sujeto del certificado.allowInvalid
indica si se deben tener en cuenta los certificados no válidos, como los certificados autofirmados.location
es la ubicación del almacén desde el que se carga el certificado.serverCertificate
es el certificado X.509.
En un entorno de producción, HTTPS se debe configurar explícitamente. Como mínimo, debe existir un certificado predeterminado.
Estas son las configuraciones compatibles:
- Sin configuración
- Reemplazar el certificado predeterminado de configuración
- Cambiar los valores predeterminados en el código
Sin configuración
Kestrel escucha en http://localhost:5000
y en https://localhost:5001
(si hay disponible un certificado predeterminado).
Reemplazar el certificado predeterminado de configuración
Hay disponible un esquema de configuración de aplicación HTTPS predeterminado para Kestrel. Configure varios puntos de conexión (incluidas las direcciones URL y los certificados que va a usar) desde un archivo en disco o desde un almacén de certificados.
En el ejemplo appsettings.json
siguiente:
- Establezca
AllowInvalid
entrue
para permitir el uso de certificados no válidos (por ejemplo, certificados autofirmados). - Cualquier punto de conexión HTTPS que no especifique un certificado (
HttpsDefaultCert
en el siguiente ejemplo) revierte al certificado definido enCertificates:Default
o al certificado de desarrollo.
{
"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$"
}
}
}
}
Advertencia
En el ejemplo anterior, las contraseñas de certificado se almacenan en texto sin formato en appsettings.json
. El token $CREDENTIAL_PLACEHOLDER$
se usa como marcador de posición para la contraseña de cada certificado. Para almacenar contraseñas de certificado de forma segura en entornos de desarrollo, vea Protección de secretos en desarrollo. Para almacenar contraseñas de certificado de forma segura en entornos de producción, vea Proveedor de configuración de Azure Key Vault. Los secretos de desarrollo no se deben usar para producción o prueba.
Notas sobre el esquema:
- En los nombres de los puntos de conexión se distingue entre mayúsculas y minúsculas. Por ejemplo,
HTTPS
andHttps
son equivalentes. - El parámetro
Url
es necesario en cada punto de conexión. El formato de este parámetro es el mismo que el del parámetro de configuraciónUrls
de nivel superior, excepto por el hecho de que está limitado a un único valor. - En vez de agregarse, estos puntos de conexión reemplazan a los que están definidos en la configuración
Urls
de nivel superior. Los puntos de conexión definidos en el código a través deListen
son acumulativos con respecto a los puntos de conexión definidos en la sección de configuración. - La sección
Certificate
es opcional. Si la secciónCertificate
no se especifica, se usan los valores predeterminados definidos enCertificates:Default
. Si no hay valores predeterminados disponibles, se utiliza el certificado de desarrollo. Si no hay valores predeterminados y el certificado de desarrollo no está presente, el servidor produce una excepción y no se inicia. - En la sección
Certificate
se admiten varios orígenes de certificados. - Se puede definir el número de puntos de conexión que se quiera en la configuración, siempre y cuando no produzcan conflictos de puerto.
Orígenes de certificados
Los nodos de certificado se pueden configurar para cargar certificados de varios orígenes:
Path
yPassword
para cargar archivos .pfx.Path
,KeyPath
yPassword
para cargar archivos .pem/.crt y .key.Subject
yStore
cargar desde el almacén de certificados.
Por ejemplo, el certificado en Certificates:Default
se puede especificar así:
"Default": {
"Subject": "<subject; required>",
"Store": "<cert store; required>",
"Location": "<location; defaults to CurrentUser>",
"AllowInvalid": "<true or false; defaults to false>"
}
ConfigurationLoader
options.Configure(context.Configuration.GetSection("{SECTION}"))
devuelve un KestrelConfigurationLoader con un método .Endpoint(string name, listenOptions => { })
que se puede usar para complementar la configuración de un punto de conexión configurado:
webBuilder.UseKestrel((context, serverOptions) =>
{
serverOptions.Configure(context.Configuration.GetSection("Kestrel"))
.Endpoint("HTTPS", listenOptions =>
{
listenOptions.HttpsOptions.SslProtocols = SslProtocols.Tls12;
});
});
Se puede acceder directamente a KestrelServerOptions.ConfigurationLoader
para seguir con la iteración en el cargador existente, como el proporcionado por CreateDefaultBuilder.
- La sección de configuración de cada punto de conexión está disponible en las opciones del método
Endpoint
para que se pueda leer la configuración personalizada. - Se pueden cargar varias configuraciones volviendo a llamar a
options.Configure(context.Configuration.GetSection("{SECTION}"))
con otra sección. Se usa la última configuración, a menos que se llame explícitamente aLoad
en instancias anteriores. El metapaquete no llama aLoad
, con lo cual su sección de configuración predeterminada se puede reemplazar. KestrelConfigurationLoader
refleja la familiaListen
de API deKestrelServerOptions
como sobrecargas deEndpoint
, por lo que los puntos de conexión de configuración y código se pueden configurar en el mismo lugar. En estas sobrecargas no se usan nombres y solo consumen valores predeterminados de la configuración.
Cambiar los valores predeterminados en el código
ConfigureEndpointDefaults
y ConfigureHttpsDefaults
se pueden usar para cambiar la configuración predeterminada de ListenOptions
y HttpsConnectionAdapterOptions
, incluido sustituir el certificado predeterminado especificado en el escenario anterior. Se debe llamar a ConfigureEndpointDefaults
y a ConfigureHttpsDefaults
antes de que se configure algún punto de conexión.
webBuilder.ConfigureKestrel(serverOptions =>
{
serverOptions.ConfigureEndpointDefaults(listenOptions =>
{
// Configure endpoint defaults
});
serverOptions.ConfigureHttpsDefaults(listenOptions =>
{
listenOptions.SslProtocols = SslProtocols.Tls12;
});
});
Configuración de puntos de conexión mediante Indicación de nombre de servidor
Indicación de nombre de servidor (SNI) se puede usar para hospedar varios dominios en la misma dirección IP y puerto. Para que SNI funcione, el cliente envía el nombre de host de la sesión segura al servidor durante el protocolo de enlace TLS para que, de este modo, el servidor pueda proporcionar el certificado correcto. El cliente usa el certificado proporcionado para la comunicación cifrada con el servidor durante la sesión segura que sigue al protocolo de enlace TLS.
SNI se puede configurar de dos maneras:
- Cree un punto de conexión en el código y seleccione un certificado mediante el nombre de host con la devolución de llamada ServerCertificateSelector.
- Configure una asignación entre los nombres de host y las opciones de HTTPS en Configuración. Por ejemplo, JSON en el archivo
appsettings.json
.
SNI con ServerCertificateSelector
Kestrel admite SNI a través de la devolución de llamada ServerCertificateSelector
. La devolución de llamada se invoca una vez por conexión para permitir que la aplicación inspeccione el nombre de host y seleccione el certificado adecuado. El siguiente código de devolución de llamada se puede usar en la llamada al método ConfigureWebHostDefaults
del archivo Program.cs
de un proyecto:
// using System.Security.Cryptography.X509Certificates;
// using Microsoft.AspNetCore.Server.Kestrel.Https;
webBuilder.ConfigureKestrel(serverOptions =>
{
serverOptions.ListenAnyIP(5005, listenOptions =>
{
listenOptions.UseHttps(httpsOptions =>
{
var localhostCert = CertificateLoader.LoadFromStoreCert(
"localhost", "My", StoreLocation.CurrentUser,
allowInvalid: true);
var exampleCert = CertificateLoader.LoadFromStoreCert(
"example.com", "My", StoreLocation.CurrentUser,
allowInvalid: true);
var subExampleCert = CertificateLoader.LoadFromStoreCert(
"sub.example.com", "My", StoreLocation.CurrentUser,
allowInvalid: true);
var certs = new Dictionary<string, X509Certificate2>(StringComparer.OrdinalIgnoreCase)
{
{ "localhost", localhostCert },
{ "example.com", exampleCert },
{ "sub.example.com", subExampleCert },
};
httpsOptions.ServerCertificateSelector = (connectionContext, name) =>
{
if (name != null && certs.TryGetValue(name, out var cert))
{
return cert;
}
return exampleCert;
};
});
});
});
SNI con ServerOptionsSelectionCallback
Kestrel admite una configuración de TLS dinámica adicional a través de la devolución de llamada ServerOptionsSelectionCallback
. La devolución de llamada se invoca una vez por conexión para permitir que la aplicación inspeccione el nombre de host y seleccione el certificado adecuado y la configuración de TLS. Los certificados predeterminados y ConfigureHttpsDefaults
no se usan con esta devolución de llamada.
// using System.Security.Cryptography.X509Certificates;
// using Microsoft.AspNetCore.Server.Kestrel.Https;
webBuilder.ConfigureKestrel(serverOptions =>
{
serverOptions.ListenAnyIP(5005, listenOptions =>
{
listenOptions.UseHttps(httpsOptions =>
{
var localhostCert = CertificateLoader.LoadFromStoreCert(
"localhost", "My", StoreLocation.CurrentUser,
allowInvalid: true);
var exampleCert = CertificateLoader.LoadFromStoreCert(
"example.com", "My", StoreLocation.CurrentUser,
allowInvalid: true);
listenOptions.UseHttps((stream, clientHelloInfo, state, cancellationToken) =>
{
if (string.Equals(clientHelloInfo.ServerName, "localhost", StringComparison.OrdinalIgnoreCase))
{
return new ValueTask<SslServerAuthenticationOptions>(new SslServerAuthenticationOptions
{
ServerCertificate = localhostCert,
// Different TLS requirements for this host
ClientCertificateRequired = true,
});
}
return new ValueTask<SslServerAuthenticationOptions>(new SslServerAuthenticationOptions
{
ServerCertificate = exampleCert,
});
}, state: null);
});
});
});
SNI en la configuración
Kestrel admite SNI definida en la configuración. Un punto de conexión se puede configurar con un objeto Sni
que contiene una asignación entre los nombres de host y las opciones de HTTPS. El nombre de host de la conexión coincide con las opciones y se usan para esa conexión.
La configuración siguiente agrega un punto de conexión denominado MySniEndpoint
que usa SNI para seleccionar opciones de HTTPS basadas en el nombre de host:
{
"Kestrel": {
"Endpoints": {
"MySniEndpoint": {
"Url": "https://*",
"SslProtocols": ["Tls11", "Tls12"],
"Sni": {
"a.example.org": {
"Protocols": "Http1AndHttp2",
"SslProtocols": ["Tls11", "Tls12", "Tls13"],
"Certificate": {
"Subject": "<subject; required>",
"Store": "<certificate store; required>",
},
"ClientCertificateMode" : "NoCertificate"
},
"*.example.org": {
"Certificate": {
"Path": "<path to .pfx file>",
"Password": "$CREDENTIAL_PLACEHOLDER$"
}
},
"*": {
// At least one subproperty needs to exist per SNI section or it
// cannot be discovered via IConfiguration
"Protocols": "Http1",
}
}
}
},
"Certificates": {
"Default": {
"Path": "<path to .pfx file>",
"Password": "$CREDENTIAL_PLACEHOLDER$"
}
}
}
}
Advertencia
En el ejemplo anterior, las contraseñas de certificado se almacenan en texto sin formato en appsettings.json
. El token $CREDENTIAL_PLACEHOLDER$
se usa como marcador de posición para la contraseña de cada certificado. Para almacenar contraseñas de certificado de forma segura en entornos de desarrollo, vea Protección de secretos en desarrollo. Para almacenar contraseñas de certificado de forma segura en entornos de producción, vea Proveedor de configuración de Azure Key Vault. Los secretos de desarrollo no se deben usar para producción o prueba.
Opciones de HTTPS que puede invalidar SNI:
Certificate
configura el origen del certificado.Protocols
configura los protocolos HTTP permitidos.SslProtocols
configura los protocolos SSL permitidos.ClientCertificateMode
configura los requisitos de certificados de cliente.
El nombre de host admite la coincidencia comodín:
- Coincidencia exacta. Por ejemplo,
a.example.org
coincide cona.example.org
. - Prefijo comodín. Si hay varias coincidencias comodín, se elige el patrón más largo. Por ejemplo,
*.example.org
coincide conb.example.org
yc.example.org
. - Comodín completo.
*
coincide con todo lo demás, incluidos los clientes que no usan SNI ni envían un nombre de host.
La configuración de SNI coincidente se aplica al punto de conexión de la conexión, anulando valores del punto de conexión. Si una conexión no coincide con un nombre de host de SNI configurado, se rechaza la conexión.
Requisitos de SNI
- Ejecutarse en el marco de destino
netcoreapp2.1
o posterior. Ennet461
o posterior, se invoca la devolución de llamada, peroname
siempre esnull
.name
también seránull
si el cliente no proporciona el parámetro de nombre de host en el protocolo de enlace TLS. - Todos los sitios web deben ejecutarse en la misma instancia de Kestrel. Kestrel no admite el uso compartido de una dirección IP y un puerto entre varias instancias sin un proxy inverso.
Protocolos SSL/TLS
Los protocolos SSL son protocolos que se utilizan para cifrar y descifrar el tráfico entre dos elementos del mismo nivel, tradicionalmente un cliente y un servidor.
webBuilder.ConfigureKestrel(serverOptions =>
{
serverOptions.ConfigureHttpsDefaults(listenOptions =>
{
listenOptions.SslProtocols = SslProtocols.Tls13;
});
});
{
"Kestrel": {
"Endpoints": {
"MyHttpsEndpoint": {
"Url": "https://localhost:5001",
"SslProtocols": ["Tls12", "Tls13"],
"Certificate": {
"Path": "<path to .pfx file>",
"Password": "$CREDENTIAL_PLACEHOLDER$"
}
}
}
}
}
Advertencia
En el ejemplo anterior, la contraseña de certificado se almacena en texto sin formato en appsettings.json
. El token $CREDENTIAL_PLACEHOLDER$
se usa como marcador de posición para la contraseña del certificado. Para almacenar contraseñas de certificado de forma segura en entornos de desarrollo, vea Protección de secretos en desarrollo. Para almacenar contraseñas de certificado de forma segura en entornos de producción, vea Proveedor de configuración de Azure Key Vault. Los secretos de desarrollo no se deben usar para producción o prueba.
El valor predeterminado, SslProtocols.None
, hace que Kestrel use los valores predeterminados del sistema operativo para elegir el mejor protocolo. A menos que tenga una razón específica para seleccionar un protocolo, utilice el valor predeterminado.
Certificados de cliente
ClientCertificateMode
configura los requisitos de certificados de cliente.
webBuilder.ConfigureKestrel(serverOptions =>
{
serverOptions.ConfigureHttpsDefaults(listenOptions =>
{
listenOptions.ClientCertificateMode = ClientCertificateMode.AllowCertificate;
});
});
{
"Kestrel": {
"Endpoints": {
"MyHttpsEndpoint": {
"Url": "https://localhost:5001",
"ClientCertificateMode": "AllowCertificate",
"Certificate": {
"Path": "<path to .pfx file>",
"Password": "$CREDENTIAL_PLACEHOLDER$"
}
}
}
}
}
Advertencia
En el ejemplo anterior, la contraseña de certificado se almacena en texto sin formato en appsettings.json
. El token $CREDENTIAL_PLACEHOLDER$
se usa como marcador de posición para la contraseña del certificado. Para almacenar contraseñas de certificado de forma segura en entornos de desarrollo, vea Protección de secretos en desarrollo. Para almacenar contraseñas de certificado de forma segura en entornos de producción, vea Proveedor de configuración de Azure Key Vault. Los secretos de desarrollo no se deben usar para producción o prueba.
El valor predeterminado es ClientCertificateMode.NoCertificate
, donde Kestrel no solicitará ni necesitará un certificado del cliente.
Para más información, consulte Configuración de la autenticación de certificados en ASP.NET Core.
Registro de conexiones
Llame a UseConnectionLogging para emitir registros de nivel de depuración para la comunicación a nivel de bytes en una conexión. El registro de conexiones es útil para solucionar problemas en la comunicación de bajo nivel, como durante el cifrado TLS y detrás de los servidores proxy. Si UseConnectionLogging
se coloca antes de UseHttps
, se registra el tráfico cifrado. Si UseConnectionLogging
se coloca después de UseHttps
, se registra el tráfico descifrado. Este es el middleware de conexión integrado.
webBuilder.ConfigureKestrel(serverOptions =>
{
serverOptions.Listen(IPAddress.Any, 8000, listenOptions =>
{
listenOptions.UseConnectionLogging();
});
});
Enlazar a un socket TCP
El método Listen se enlaza a un socket TCP y una expresión lambda de opciones permite configurar un 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>();
});
En el ejemplo se configura HTTPS para un punto de conexión con ListenOptions. Use la misma API para configurar otras opciones de Kestrel para puntos de conexión específicos.
En Windows, pueden crearse certificados autofirmados con el New-SelfSignedCertificate
cmdlet de PowerShell. Para ver un ejemplo no admitido, consulte UpdateIISExpressSSLForChrome.ps1
.
En macOS, Linux y Windows, pueden crearse certificados con OpenSSL.
Enlazar a un socket de Unix
Escuche en un socket de Unix con ListenUnixSocket para mejorar el rendimiento con Nginx, tal como se muestra en este ejemplo:
webBuilder.ConfigureKestrel(serverOptions =>
{
serverOptions.ListenUnixSocket("/tmp/kestrel-test.sock");
serverOptions.ListenUnixSocket("/tmp/kestrel-test.sock",
listenOptions =>
{
listenOptions.UseHttps("testCert.pfx",
"testpassword");
});
})
- En el archivo de configuración de Nginx, establezca la entrada
server
>location
>proxy_pass
enhttp://unix:/tmp/{KESTREL SOCKET}:/;
.{KESTREL SOCKET}
es el nombre del socket proporcionado para ListenUnixSocket (por ejemplo,kestrel-test.sock
en el ejemplo anterior). - Asegúrese de que el socket es grabable por Nginx (por ejemplo,
chmod go+w /tmp/kestrel-test.sock
).
Puerto 0
Cuando se especifica el número de puerto 0
, Kestrel se enlaza de forma dinámica a un puerto disponible. En el ejemplo siguiente se muestra cómo determinar a qué puerto se enlaza Kestrel en el entorno de ejecución:
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>");
});
}
Cuando la aplicación se ejecuta, la salida de la ventana de consola indica el puerto dinámico en el que se puede tener acceso a la aplicación:
Listening on the following addresses: http://127.0.0.1:48508
Limitaciones
Configure puntos de conexión con los siguientes métodos:
- UseUrls
- El argumento de la línea de comandos
--urls
- La clave de configuración de host
urls
- La variable de entorno
ASPNETCORE_URLS
Estos métodos son útiles para que el código funcione con servidores que no sean de Kestrel. Sin embargo, tenga en cuenta las siguientes limitaciones:
- HTTPS no se puede usar con estos enfoques, a menos que se proporcione un certificado predeterminado en la configuración del punto de conexión HTTPS (por ejemplo, mediante la configuración
KestrelServerOptions
o un archivo de configuración, como se ha mostrado antes en este artículo). - Cuando los métodos
Listen
yUseUrls
se usan al mismo tiempo, los puntos de conexión deListen
sustituyen a los deUseUrls
.
Configuración de puntos de conexión IIS
Cuando se usa IIS, los enlaces de direcciones URL de IIS reemplazan a los enlaces que se hayan establecido por medio de Listen
o de UseUrls
. Para más información, vea ASP.NET Core Module (Módulo de ASP.NET Core).
ListenOptions.Protocols
La propiedad Protocols
establece los protocolos HTTP (HttpProtocols
) habilitados en un punto de conexión o para el servidor. Asigne un valor a la propiedad Protocols
desde el valor de enumeración HttpProtocols
.
Valor de enumeración HttpProtocols |
Protocolo de conexión permitido |
---|---|
Http1 |
HTTP/1.1 solo. Puede usarse con o sin TLS. |
Http2 |
HTTP/2 solo. Se pueden utilizar sin TLS solo si el cliente admite un modo de conocimientos previos. |
Http1AndHttp2 |
HTTP/1.1 y HTTP/2. HTTP/2 necesita que el cliente seleccione HTTP/2 en el protocolo de enlace Negociación de protocolo de nivel de aplicación (ALPN) de TLS; en caso contrario, el valor predeterminado de la conexión es HTTP/1.1. |
El valor ListenOptions.Protocols
predeterminado de cualquier punto de conexión es HttpProtocols.Http1AndHttp2
.
Restricciones de TLS para HTTP/2:
- TLS 1.2 o versiones posteriores
- Renegociación deshabilitada
- Compresión deshabilitada
- Tamaños de intercambio de claves efímeras mínimos:
- Curva elíptica Diffie-Hellman (ECDHE) [RFC4492]: 224 bits como mínimo
- Campo finito Diffie-Hellman (DHE) (DHE) [
TLS12
]: 2048 bits como mínimo
- Conjunto de cifrado no prohibido.
TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
[TLS-ECDHE
] con la curva elíptica P-256 [FIPS186
] se admite de forma predeterminada.
El siguiente ejemplo permite conexiones HTTP/1.1 y HTTP/2 en el puerto 8000. Las conexiones se protegen mediante TLS con un certificado proporcionado:
webBuilder.ConfigureKestrel(serverOptions =>
{
serverOptions.Listen(IPAddress.Any, 8000, listenOptions =>
{
listenOptions.UseHttps("testCert.pfx", "testPassword");
});
});
En Linux, se puede usar CipherSuitesPolicy para filtrar los protocolos de enlace TLS por conexión:
// using System.Net.Security;
// using Microsoft.AspNetCore.Hosting;
// using Microsoft.AspNetCore.Server.Kestrel.Core;
// using Microsoft.Extensions.DependencyInjection;
// using Microsoft.Extensions.Hosting;
webBuilder.ConfigureKestrel(serverOptions =>
{
serverOptions.ConfigureHttpsDefaults(listenOptions =>
{
listenOptions.OnAuthenticate = (context, sslOptions) =>
{
sslOptions.CipherSuitesPolicy = new CipherSuitesPolicy(
new[]
{
TlsCipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
TlsCipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
// ...
});
};
});
});
Middleware de conexión
Si es necesario, el middleware de conexión personalizado puede filtrar por cifrados específicos los protocolos de enlace TLS por cada conexión.
En el ejemplo siguiente se produce una excepción NotSupportedException con cualquier algoritmo de cifrado que no admita la aplicación. Como alternativa, defina y compare ITlsHandshakeFeature.CipherAlgorithm con una lista de conjuntos de cifrado aceptables.
No se usa ningún cifrado con un algoritmo de cifrado 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();
});
}
}
}
El filtrado de conexiones también puede configurarse mediante una función 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();
});
});
});
Establecimiento del protocolo HTTP a partir de la configuración
CreateDefaultBuilder
llama a serverOptions.Configure(context.Configuration.GetSection("Kestrel"))
de forma predeterminada para cargar la configuración de Kestrel.
En el siguiente ejemplo de appsettings.json
, se establece HTTP/1.1 como el protocolo de conexión predeterminado para todos los puntos de conexión:
{
"Kestrel": {
"EndpointDefaults": {
"Protocols": "Http1"
}
}
}
En el siguiente ejemplo de appsettings.json
se establece el protocolo de conexión HTTP/1.1 para un punto de conexión específico:
{
"Kestrel": {
"Endpoints": {
"HttpsDefaultCert": {
"Url": "https://localhost:5001",
"Protocols": "Http1"
}
}
}
}
Los protocolos especificados en el código invalidan los valores establecidos por la configuración.
Prefijos de URL
Al usar UseUrls
, el argumento de línea de comandos --urls
, la clave de configuración de host urls
o una variable de entorno ASPNETCORE_URLS
, los prefijos de dirección URL pueden tener cualquiera de estos formatos.
Solo son válidos los prefijos de dirección URL HTTP. Kestrel no admite HTTPS al configurar enlaces de dirección URL con UseUrls
.
Dirección IPv4 con número de puerto
http://65.55.39.10:80/
0.0.0.0
es un caso especial que enlaza a todas las direcciones IPv4.Dirección IPv6 con número de puerto
http://[0:0:0:0:0:ffff:4137:270a]:80/
[::]
es el equivalente en IPv6 de0.0.0.0
en IPv4.Nombre de host con número de puerto
http://contoso.com:80/ http://*:80/
Los nombres de host,
*
y+
no son especiales. Todo lo que no se identifique como una dirección IP o unlocalhost
válido se enlaza a todas las direcciones IP de IPv6 e IPv4. Para enlazar otros nombres de host a otras aplicaciones ASP.NET Core en el mismo puerto, use HTTP.sys o un servidor proxy inverso. Entre los ejemplos de servidor proxy inverso se incluyen IIS, Nginx o Apache.Advertencia
El hospedaje en una configuración de proxy inverso requiere filtrado de hosts.
Nombre
localhost
del host con el número de puerto o la IP de bucle invertido con el número de puertohttp://localhost:5000/ http://127.0.0.1:5000/ http://[::1]:5000/
Cuando se especifica
localhost
, Kestrel intenta enlazar a las interfaces de bucle invertido de IPv4 e IPv6. Si el puerto solicitado lo está usando otro servicio en cualquier interfaz de bucle invertido, Kestrel no se puede iniciar. Si ninguna de estas interfaces de bucle invertido está disponible por cualquier otra razón (normalmente porque no se admite IPv6), Kestrel registra una advertencia.