Compartir vía


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

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

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 de 0.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 puerto

    http://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 de IConfiguration.
  • 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 a Load, con lo cual su sección de configuración predeterminada se puede reemplazar.
  • KestrelConfigurationLoader refleja la familia Listen de API de KestrelServerOptions como sobrecargas de Endpoint, 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:

En Windows, pueden crearse certificados autofirmados con el New-SelfSignedCertificatecmdlet 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 en http://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:

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:

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 and Https 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ón Urls 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 de Listen 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ón Certificate no se especifica, se usan los valores predeterminados definidos en Certificates: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 y Password para cargar archivos .pfx.
  • Path, KeyPath y Password para cargar archivos .pem/.crt y .key.
  • Subject y Store 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 una Action para configurar HttpsConnectionAdapterOptions. Devuelve ListenOptions.
  • 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:

El nombre de host admite la coincidencia comodín:

  • Coincidencia exacta. Por ejemplo, a.example.org coincide con a.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 con b.example.org y c.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:

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 una Action para configurar HttpsConnectionAdapterOptions. Devuelve ListenOptions.
  • 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 en true 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 en Certificates: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 and Https 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ón Urls 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 de Listen 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ón Certificate no se especifica, se usan los valores predeterminados definidos en Certificates: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 y Password para cargar archivos .pfx.
  • Path, KeyPath y Password para cargar archivos .pem/.crt y .key.
  • Subject y Store 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 a Load, con lo cual su sección de configuración predeterminada se puede reemplazar.
  • KestrelConfigurationLoader refleja la familia Listen de API de KestrelServerOptions como sobrecargas de Endpoint, 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:

El nombre de host admite la coincidencia comodín:

  • Coincidencia exacta. Por ejemplo, a.example.org coincide con a.example.org.
  • Prefijo comodín. Si hay varias coincidencias comodín, se elige el patrón más largo. Por ejemplo, *.example.org coincide con b.example.org y c.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-SelfSignedCertificatecmdlet 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 en http://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 y UseUrls se usan al mismo tiempo, los puntos de conexión de Listen sustituyen a los de UseUrls.

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 de 0.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 un localhost 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 puerto

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

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 una Action para configurar HttpsConnectionAdapterOptions. Devuelve ListenOptions.
  • 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 en true 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 en Certificates: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 and Https 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ón Urls 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 de Listen 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ón Certificate no se especifica, se usan los valores predeterminados definidos en Certificates: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 y Password para cargar archivos .pfx.
  • Path, KeyPath y Password para cargar archivos .pem/.crt y .key.
  • Subject y Store 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 a Load, con lo cual su sección de configuración predeterminada se puede reemplazar.
  • KestrelConfigurationLoader refleja la familia Listen de API de KestrelServerOptions como sobrecargas de Endpoint, 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:

El nombre de host admite la coincidencia comodín:

  • Coincidencia exacta. Por ejemplo, a.example.org coincide con a.example.org.
  • Prefijo comodín. Si hay varias coincidencias comodín, se elige el patrón más largo. Por ejemplo, *.example.org coincide con b.example.org y c.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-SelfSignedCertificatecmdlet 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 en http://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 y UseUrls se usan al mismo tiempo, los puntos de conexión de Listen sustituyen a los de UseUrls.

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 de 0.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 un localhost 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 puerto

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

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 una Action para configurar HttpsConnectionAdapterOptions. Devuelve ListenOptions.
  • 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 en true 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 en Certificates: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 and Https 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ón Urls 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 de Listen 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ón Certificate no se especifica, se usan los valores predeterminados definidos en Certificates: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 y Password para cargar archivos .pfx.
  • Path, KeyPath y Password para cargar archivos .pem/.crt y .key.
  • Subject y Store 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 a Load en instancias anteriores. El metapaquete no llama a Load, con lo cual su sección de configuración predeterminada se puede reemplazar.
  • KestrelConfigurationLoader refleja la familia Listen de API de KestrelServerOptions como sobrecargas de Endpoint, 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:

El nombre de host admite la coincidencia comodín:

  • Coincidencia exacta. Por ejemplo, a.example.org coincide con a.example.org.
  • Prefijo comodín. Si hay varias coincidencias comodín, se elige el patrón más largo. Por ejemplo, *.example.org coincide con b.example.org y c.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. En net461 o posterior, se invoca la devolución de llamada, pero name siempre es null. 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-SelfSignedCertificatecmdlet 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 en http://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 y UseUrls se usan al mismo tiempo, los puntos de conexión de Listen sustituyen a los de UseUrls.

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 de 0.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 un localhost 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 puerto

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