Kestrelserveur web dans ASP.NET Core

Par Tom Dykstra, Chris Ross et Stephen Halter

Kestrel est un serveur web multiplateforme pour ASP.NET Core. Kestrel est le serveur recommandé pour ASP.NET Core, et il est configuré par défaut dans ASP.NET Core modèles de projet.

Les fonctionnalités de Kestrel sont les suivantes :

  • Multiplateforme :Kestrel est un serveur web multiplateforme qui s’exécute sur Windows, Linux et macOS.
  • Hautes performances :Kestrel est optimisé pour gérer efficacement un grand nombre de connexions simultanées.
  • Léger : optimisé pour l’exécution dans des environnements à ressources limitées, tels que les conteneurs et les appareils de périphérie.
  • Sécurité renforcée :Kestrel prend en charge HTTPS et est renforcé contre les vulnérabilités du serveur web.
  • Prise en charge du protocole étendu :Kestrel prend en charge les protocoles web courants, notamment :
  • Intégration à ASP.NET Core : intégration transparente avec d’autres composants ASP.NET Core, tels que le pipeline d’intergiciels, l’injection de dépendances et le système de configuration.
  • Charges de travail flexibles : Kestrel prend en charge de nombreuses charges de travail :
    • ASP.NET infrastructures d’application telles que les API minimales, MVC, Razor pages, SignalR, Blazoret gRPC.
    • Création d’un proxy inverse avec YARP.
  • Extensibilité : Personnalisez Kestrel via la configuration, l’intergiciel et les transports personnalisés.
  • Performances diagnostics :Kestrel fournit des fonctionnalités de diagnostics de performances intégrées, telles que la journalisation et les métriques.

Bien démarrer

Les modèles de projet ASP.NET Core utilisent Kestrel par défaut lorsqu’ils ne sont pas hébergés avec IIS. Dans le fichier suivant Program.cs généré par modèle, la méthode WebApplication.CreateBuilder appelle UseKestrel en interne :

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

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

app.Run();

Pour plus d’informations sur la configuration de WebApplication et WebApplicationBuilder, consultez Informations de référence rapides sur les API minimales.

Certificats clients facultatifs

Pour plus d’informations sur les applications qui doivent protéger un sous-ensemble de l’application avec un certificat, consultez Certificats clients facultatifs.

Comportement avec le débogueur attaché

Les délais d’expiration et limites de débit suivants ne sont pas appliqués lorsqu’un débogueur est attaché à un processus Kestrel :

Ressources supplémentaires

Notes

Depuis ASP.NET Core 5.0, le transport libuv de Kestrel est obsolète. Le transport libuv ne reçoit pas de mises à jour pour prendre en charge les nouvelles plateformes de système d’exploitation, telles que Windows ARM64, et sera supprimé dans une version ultérieure. Supprimez tous les appels à la méthode UseLibuv obsolète et utilisez le transport Socket par défaut de Kestrel à la place.

Kestrel est un serveur web multiplateforme pour ASP.NET Core. Kestrel est le serveur web inclus et activé par défaut dans les modèles de projets ASP.NET Core.

Kestrel prend en charge les scénarios suivants :

  • HTTPS
  • HTTP/2 (sauf sur macOS†)
  • Mise à niveau opaque utilisée pour activer les WebSockets
  • Sockets UNIX pour des performances élevées derrière Nginx

†HTTP/2 sera pris en charge sur macOS dans une prochaine version.

Kestrel est pris en charge sur toutes les plateformes et les versions prises en charge par .NET Core.

Bien démarrer

Les modèles de projet ASP.NET Core utilisent Kestrel par défaut lorsqu’ils ne sont pas hébergés avec IIS. Dans le fichier suivant Program.cs généré par modèle, la méthode WebApplication.CreateBuilder appelle UseKestrel en interne :

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

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

app.Run();

Pour plus d’informations sur la configuration de WebApplication et WebApplicationBuilder, consultez Informations de référence rapides sur les API minimales.

Certificats clients facultatifs

Pour plus d’informations sur les applications qui doivent protéger un sous-ensemble de l’application avec un certificat, consultez Certificats clients facultatifs.

Comportement avec le débogueur attaché

Les délais d’expiration et limites de débit suivants ne sont pas appliqués lorsqu’un débogueur est attaché à un processus Kestrel :

Ressources supplémentaires

Notes

Depuis ASP.NET Core 5.0, le transport libuv de Kestrel est obsolète. Le transport libuv ne reçoit pas de mises à jour pour prendre en charge les nouvelles plateformes de système d’exploitation, telles que Windows ARM64, et sera supprimé dans une version ultérieure. Supprimez tous les appels à la méthode UseLibuv obsolète et utilisez le transport Socket par défaut de Kestrel à la place.

Kestrel est un serveur web multiplateforme pour ASP.NET Core. Kestrel est le serveur web inclus et activé par défaut dans les modèles de projets ASP.NET Core.

Kestrel prend en charge les scénarios suivants :

  • HTTPS
  • HTTP/2 (sauf sur macOS†)
  • Mise à niveau opaque utilisée pour activer les WebSockets
  • Sockets UNIX pour des performances élevées derrière Nginx

†HTTP/2 sera pris en charge sur macOS dans une prochaine version.

Kestrel est pris en charge sur toutes les plateformes et les versions prises en charge par .NET Core.

Affichez ou téléchargez l’exemple de code (procédure de téléchargement)

Bien démarrer

Les modèles de projet ASP.NET Core utilisent Kestrel par défaut lorsqu’ils ne sont pas hébergés avec IIS. Dans Program.cs, la méthode ConfigureWebHostDefaults appelle UseKestrel :

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

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

Pour plus d’informations sur la génération de l’hôte, consultez les sections Configurer un hôte et Paramètres du générateur par défaut de l’hôte générique .NET dans ASP.NET Core.

Certificats clients facultatifs

Pour plus d’informations sur les applications qui doivent protéger un sous-ensemble de l’application avec un certificat, consultez Certificats clients facultatifs.

Ressources supplémentaires

Notes

Depuis ASP.NET Core 5.0, le transport libuv de Kestrel est obsolète. Le transport libuv ne reçoit pas de mises à jour pour prendre en charge les nouvelles plateformes de système d’exploitation, telles que Windows ARM64, et sera supprimé dans une version ultérieure. Supprimez tous les appels à la méthode UseLibuv obsolète et utilisez le transport Socket par défaut de Kestrel à la place.

Kestrel est un serveur web multiplateforme pour ASP.NET Core. Kestrel est le serveur web inclus par défaut dans les modèles de projets ASP.NET Core.

Kestrel prend en charge les scénarios suivants :

  • HTTPS
  • Mise à niveau opaque utilisée pour activer les WebSockets
  • Sockets UNIX pour des performances élevées derrière Nginx
  • HTTP/2 (sauf sur macOS†)

†HTTP/2 sera pris en charge sur macOS dans une prochaine version.

Kestrel est pris en charge sur toutes les plateformes et les versions prises en charge par .NET Core.

Affichez ou téléchargez l’exemple de code (procédure de téléchargement)

Assistance HTTP/2

HTTP/2 est disponible pour les applications ASP.NET Core si les conditions de base suivantes sont remplies :

  • Système d'exploitation†
    • Windows Server 2016/Windows 10 ou version ultérieure‡
    • Linux avec OpenSSL 1.0.2 ou version ultérieure (par exemple, Ubuntu 16.04 ou version ultérieure)
  • Version cible de .Net Framework : .NET Core 2.2 ou version ultérieure
  • Connexion ALPN (Application-Layer Protocol Negotiation)
  • TLS 1.2 ou connexion ultérieure

†HTTP/2 sera pris en charge sur macOS dans une prochaine version. ‡Kestrel propose une prise en charge limitée de HTTP/2 sur Windows Server 2012 R2 et Windows 8.1. La prise en charge est limitée car la liste des suites de chiffrement TLS prises en charge sur ces systèmes d’exploitation est limitée. Un certificat généré à l’aide d’Elliptic Curve Digital Signature algorithme (ECDSA) peut être requis pour sécuriser les connexions TLS.

Si une connexion HTTP/2 est établie, HttpRequest.Protocol retourne HTTP/2.

À compter de .NET Core 3.0, HTTP/2 est activé par défaut. Pour plus d’informations sur la configuration, consultez les sections Options Kestrel et ListenOptions.Protocols.

Quand utiliser Kestrel avec un proxy inverse

Kestrel peut être utilisé par lui-même ou avec un serveur proxy inverse. Un serveur proxy inverse reçoit les requêtes HTTP en provenance du réseau et les transfère à Kestrel. Voici quelques exemples de serveur proxy inverse :

Kestrel utilisé comme serveur web edge (accessible sur Internet) :

Kestrel communicates directly with the Internet without a reverse proxy server

Kestrel utilisé dans une configuration de proxy inverse :

Kestrel communicates indirectly with the Internet through a reverse proxy server, such as IIS, Nginx, or Apache

Les deux configurations, avec ou sans serveur proxy inverse, sont des configurations d’hébergement prises en charge.

Kestrel, s’il est utilisé comme serveur de périphérie sans serveur proxy inverse, ne prend pas en charge le partage de la même adresse IP et du même port entre plusieurs processus. Quand Kestrel est configuré pour écouter sur un port, Kestrel gère tout le trafic pour ce port, quel que soit les en-têtes Host des requêtes. Un proxy inverse qui peut partager des ports a la possibilité de transférer des requêtes vers Kestrel sur une adresse IP et un port uniques.

Même si un serveur proxy inverse n’est pas nécessaire, en utiliser un peut être un bon choix.

Un proxy inverse :

  • Peut limiter la surface publique exposée des applications qu’il héberge.
  • Fournit une couche supplémentaire de configuration et de défense.
  • Peut mieux s’intégrer à l’infrastructure existante.
  • Simplifie la configuration de l’équilibrage de charge et d’une communication sécurisée (HTTPS). Seul le serveur proxy inverse nécessite un certificat X.509 : ce serveur peut donc communiquer avec les serveurs d’applications sur le réseau interne avec un protocole HTTP brut.

Avertissement

L’hébergement dans une configuration de proxy inverse nécessite la configuration de l’intergiciel des en-têtes transférés.

Kestrel dans les applications ASP.NET Core

Les modèles de projet ASP.NET Core utilisent Kestrel par défaut. Dans Program.cs, la méthode ConfigureWebHostDefaults appelle UseKestrel :

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

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

Pour plus d’informations sur la génération de l’hôte, consultez les sections Configurer un hôte et Paramètres du générateur par défaut de l’hôte générique .NET dans ASP.NET Core.

Pour fournir une configuration supplémentaire après l’appel de ConfigureWebHostDefaults, utilisez ConfigureKestrel :

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

Kestrel options

Le serveur web Kestrel a des options de configuration de contrainte qui sont particulièrement utiles dans les déploiements exposés à Internet.

Définissez des contraintes sur la propriété Limits de la classe KestrelServerOptions. La propriété Limits conserve une instance de la classe KestrelServerLimits.

Les exemples suivants utilisent l’espace de noms Microsoft.AspNetCore.Server.Kestrel.Core :

using Microsoft.AspNetCore.Server.Kestrel.Core;

Dans les exemples présentés ultérieurement dans cet article, les options Kestrel sont configurées dans le code C#. Les options Kestrel peuvent également être définies à l’aide d’un fournisseur de configuration. Par exemple, le fournisseur de configuration de fichiers peut charger la configuration Kestrel à partir d’un fichier appsettings.json ou appsettings.{Environment}.json :

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

Notes

KestrelServerOptions et la configuration des points de terminaison sont configurables à partir des fournisseurs de configuration. La configuration Kestrel restante doit être configurée en code C#.

Utilisez l’une des approches suivantes :

  • Configurez Kestrel dans Startup.ConfigureServices :

    1. Injectez une instance de IConfiguration dans la classe Startup. L’exemple suivant suppose que la configuration injectée est affectée à la propriété Configuration.

    2. Dans Startup.ConfigureServices, chargez la section de configuration Kestrel dans la configuration de Kestrel :

      using Microsoft.Extensions.Configuration
      
      public class Startup
      {
          public Startup(IConfiguration configuration)
          {
              Configuration = configuration;
          }
      
          public IConfiguration Configuration { get; }
      
          public void ConfigureServices(IServiceCollection services)
          {
              services.Configure<KestrelServerOptions>(
                  Configuration.GetSection("Kestrel"));
          }
      
          public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
          {
              ...
          }
      }
      
  • Configurez Kestrel lors de la génération de l’hôte :

    Dans Program.cs, chargez la section de configuration Kestrel dans la configuration de Kestrel :

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

Les deux approches précédentes fonctionnent avec n’importe quel fournisseur de configuration.

Délai d’expiration toujours actif

KeepAliveTimeout

Obtient ou définit le délai d’expiration toujours actif. La valeur par défaut est de 2 minutes.

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

Nombre maximale de connexions client

MaxConcurrentConnections MaxConcurrentUpgradedConnections

Le nombre maximal de connexions TCP ouvertes simultanées peut être défini pour l’application entière avec le code suivant :

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

Il existe une limite distincte pour les connexions qui ont été mises à niveau à partir de HTTP ou HTTPS vers un autre protocole (par exemple, sur une demande WebSocket). Une fois mise à niveau, une connexion n’est pas prise en compte dans la limite MaxConcurrentConnections.

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

Le nombre maximal de connexions est illimité (null) par défaut.

Taille maximale du corps de la requête

MaxRequestBodySize

La taille maximale par défaut du corps de la requête est de 30 000 000 octets, soit environ 28,6 Mo.

Pour remplacer la limite dans une application ASP.NET Core MVC, nous vous recommandons d’utiliser l’attribut RequestSizeLimitAttribute sur une méthode d’action :

[RequestSizeLimit(100000000)]
public IActionResult MyActionMethod()

Voici un exemple qui montre comment configurer la contrainte pour l’application sur chaque requête :

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

Remplacez le paramètre sur une demande spécifique dans l’intergiciel :

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

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

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

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

Une exception est levée si l’application configure la limite sur une requête une fois que l’application a commencé à la lire. Il existe une propriété IsReadOnly qui indique si la propriété MaxRequestBodySize est en lecture seule ; si tel est le cas, il est trop tard pour configurer la limite.

Quand une application est exécutée hors processus derrière le module ASP.NET Core, la limite de taille du corps de la demande de Kestrel est désactivée, car IIS définit déjà la limite.

Débit données minimal du corps de la requête

MinRequestBodyDataRate MinResponseDataRate

Kestrel vérifie à chaque seconde si les données arrivent au débit spécifié en octets/seconde. Si le débit est inférieur au minimum, la connexion expire. La période de grâce est la durée que Kestrel accorde au client pour augmenter son taux d’envoi jusqu’au minimum ; pendant cette période, le débit n’est pas vérifié. La période de grâce permet d’éviter la suppression des connexions qui, initialement, envoient des données à une vitesse lente en raison de la lenteur du démarrage de TCP.

Le débit minimal par défaut est 240 octets/seconde, avec une période de grâce de 5 secondes.

Un débit minimal s’applique également à la réponse. Le code pour définir les limites de demande et de réponse est identique à l’exception de RequestBody ou Response dans les noms de propriété et d’interface.

Voici un exemple qui montre comment configurer les débits de données minimaux dans Program.cs :

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

Remplacez les limites de débit minimal par requête dans l’intergiciel :

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

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

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

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

Le IHttpMinResponseDataRateFeaturedébit référencé dans l’exemple précédent n’est pas présent dans HttpContext.Features pour les requêtes HTTP/2, car la modification des limites de débit par requête n’est généralement pas prise en charge pour HTTP/2 (le protocole prend en charge le multiplexage de requête). Toutefois, le IHttpMinRequestBodyDataRateFeature est toujours présent HttpContext.Features pour les requêtes HTTP/2, car la limite de débit de lecture peut toujours être désactivée entièrement sur une base par demande en définissant IHttpMinRequestBodyDataRateFeature.MinDataRate sur null même pour une requête HTTP/2. Une tentative de lecture de IHttpMinRequestBodyDataRateFeature.MinDataRate ou une tentative de définition sur une valeur autre que null entraîne une levée de NotSupportedException selon une requête HTTP/2.

Les limites de débit à l’échelle du serveur configurées par le biais de KestrelServerOptions.Limits s’appliquent encore aux connexions HTTP/1.x et HTTP/2.

Délai d’expiration des en-têtes de requête

RequestHeadersTimeout

Obtient ou définit le temps maximal passé par le serveur à recevoir des en-têtes de requête. La valeur par défaut est de 30 secondes.

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

Flux de données maximal par connexion

Http2.MaxStreamsPerConnection limite le nombre de flux de requête simultanée par connexion HTTP/2. Les flux de données excédentaires sont refusés.

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

La valeur par défaut est 100.

Taille de la table d’en-tête

Le décodeur HPACK décompresse les en-têtes HTTP pour les connexions HTTP/2. Http2.HeaderTableSize limite la taille de la table de compression d’en-tête que le décodeur HPACK utilise. La valeur est fournie en octets et doit être supérieure à zéro (0).

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

La valeur par défaut est 4096.

Taille de trame maximale

Http2.MaxFrameSize indique la taille maximale autorisée d’une charge utile de trame de connexion HTTP/2 reçue ou envoyée par le serveur. La valeur est fournie en octets et doit être comprise entre 2^14 (16,384) et 2^24-1 (16,777,215).

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

La valeur par défaut est 2^14 (16,384).

Taille maximale d’en-tête de requête

Http2.MaxRequestHeaderFieldSize indique la taille maximale autorisée en octets des valeurs d’en-tête de requête. Cette limite s’applique au nom et à la valeur dans leurs représentations compressées et non compressées. La valeur doit être supérieure à zéro (0).

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

La valeur par défaut est 8 192.

Taille de fenêtre de connexion initiale

Http2.InitialConnectionWindowSize indique la quantité maximale de données de corps de requête, en octets, que le serveur met en mémoire tampon à un moment donné pour toutes les requêtes (flux) par connexion. Les requêtes sont également limitées par Http2.InitialStreamWindowSize. La valeur doit être supérieure ou égale à 65 535 et inférieure à 2^31 (2 147 483 648).

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

La valeur par défaut est 128 Ko (131 072).

Taille de la fenêtre de flux initiale

Http2.InitialStreamWindowSize indique la quantité maximale de données de corps de requête, en octets, que le serveur met en mémoire tampon à un moment donné par requête (flux). Les requêtes sont également limitées par Http2.InitialConnectionWindowSize. La valeur doit être supérieure ou égale à 65 535 et inférieure à 2^31 (2 147 483 648).

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

La valeur par défaut est 96 Ko (98 304).

Bandes-annonce

Les codes de fin HTTP sont similaires aux en-têtes HTTP, sauf qu’ils sont envoyés après l’envoi du corps de la réponse. Pour IIS et HTTP.sys, seuls les codes de fin de réponse HTTP/2 sont pris en charge.

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

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

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

Dans l’exemple de code précédent :

  • SupportsTrailers garantit que les codes de fin sont pris en charge pour la réponse.
  • DeclareTrailer ajoute le nom de code de fin donné à l’en-tête de réponse Trailer. La déclaration des codes de fin d’une réponse est facultative, mais recommandée. Si DeclareTrailer est appelé, il doit être avant l’envoi des en-têtes de réponse.
  • AppendTrailer ajoute le code de fin.

Réinitialiser

La réinitialisation permet au serveur de réinitialiser une requête HTTP/2 avec un code d’erreur spécifié. Une requête de réinitialisation est considérée comme abandonnée.

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

Reset dans l’exemple de code précédent spécifie le code d’erreur INTERNAL_ERROR. Pour plus d’informations sur les codes d’erreur HTTP/2, consultez la section sur les codes d’erreur de la spécification HTTP/2.

E/S synchrone

AllowSynchronousIO contrôle si une E/S synchrone est autorisée pour la demande et la réponse. La valeur par défaut est false.

Avertissement

Un grand nombre d’opérations d’E/S synchrones de blocage peut entraîner une privation de pool de thread, ce qui fait que l’application ne répond pas. Activez uniquement AllowSynchronousIO lors de l’utilisation d’une bibliothèque qui ne prend pas en charge l’E/S asynchrone.

L’exemple suivant active une E/S synchrone :

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

Pour obtenir des informations sur les autres options et limites de Kestrel, consultez :

Configuration du point de terminaison

Par défaut, ASP.NET Core se lie à :

  • http://localhost:5000
  • https://localhost:5001 (quand un certificat de développement local est présent)

Spécifiez les URL avec :

  • La variable d’environnement ASPNETCORE_URLS.
  • L’argument de ligne de commande --urls.
  • La clé de configuration d’hôte urls.
  • La méthode d’extension UseUrls.

La valeur fournie avec ces approches peut être un ou plusieurs points de terminaison HTTP et HTTPS (HTTPS si un certificat par défaut est disponible). Configurez la valeur sous forme de liste délimitée par des points-virgules (par exemple "Urls": "http://localhost:8000;http://localhost:8001").

Pour plus d’informations sur ces approches, voir URL de serveur et Remplacer la configuration.

Un certificat de développement est créé :

Certains navigateurs nécessitent l’autorisation explicite pour faire confiance au certificat de développement local.

Les modèles de projet configurent les applications pour qu’elles s’exécutent sur HTTPS par défaut et incluent la redirection HTTPS et la prise en charge HSTS.

Appelez les méthodes Listen ou ListenUnixSocket sur KestrelServerOptions pour configurer les préfixes et les ports d’URL pour Kestrel.

UseUrls, l’argument de ligne de commande --urls, la clé de configuration d’hôte urls et la variable d’environnement ASPNETCORE_URLS fonctionnent également, mais ils présentent les limitations indiquées plus loin dans cette section (un certificat par défaut doit être disponible pour la configuration du point de terminaison HTTPS).

ConfigurationKestrelServerOptions :

ConfigureEndpointDefaults(Action<ListenOptions>)

Spécifie une Action de configuration à exécuter pour chaque point de terminaison spécifié. Le fait d’appeler ConfigureEndpointDefaults plusieurs fois remplace les Actions précédentes par la dernière Action spécifiée.

webBuilder.ConfigureKestrel(serverOptions =>
{
    serverOptions.ConfigureEndpointDefaults(listenOptions =>
    {
        // Configure endpoint defaults
    });
});

Note

Les valeurs par défaut ne sont pas appliquées aux points de terminaison créés en appelant Listenavant d’appeler ConfigureEndpointDefaults.

ConfigureHttpsDefaults(Action<HttpsConnectionAdapterOptions>)

Spécifie une Action de configuration à exécuter pour chaque point de terminaison HTTPS. Le fait d’appeler ConfigureHttpsDefaults plusieurs fois remplace les Actions précédentes par la dernière Action spécifiée.

webBuilder.ConfigureKestrel(serverOptions =>
{
    serverOptions.ConfigureHttpsDefaults(listenOptions =>
    {
        // certificate is an X509Certificate2
        listenOptions.ServerCertificate = certificate;
    });
});

Note

Les points de terminaison créés en appelant Listenavant l'appel ConfigureHttpsDefaults n’auront pas les valeurs par défaut appliquées.

Configure(IConfiguration)

Crée un chargeur de configuration pour configurer Kestrel, qui prend en entrée une IConfiguration. La configuration doit être limitée à la section de configuration pour Kestrel.

ListenOptions.UseHttps

Configurez Kestrel pour utiliser HTTPS.

Extensions de ListenOptions.UseHttps :

  • UseHttps : configurez Kestrel pour utiliser HTTPS avec le certificat par défaut. Lève une exception si aucun certificat par défaut n’est configuré.
  • 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)

Paramètres de ListenOptions.UseHttps :

  • filename est le chemin et le nom d’un fichier de certificat, relatif au répertoire qui contient les fichiers de contenu de l’application.
  • password est le mot de passe nécessaire pour accéder aux données du certificat X.509.
  • configureOptions est une Action pour configurer les HttpsConnectionAdapterOptions. Retourne l'ListenOptions.
  • storeName est le magasin de certificats à partir duquel charger le certificat.
  • subject est le nom du sujet du certificat.
  • allowInvalid indique si les certificats non valides doivent être considérés, comme les certificats auto-signés.
  • location est l’emplacement du magasin à partir duquel charger le certificat.
  • serverCertificate est le certificat X.509.

En production, HTTPS doit être explicitement configuré. Au minimum, un certificat par défaut doit être fourni.

Configurations prises en charge décrites dans la suite :

  • Pas de configuration
  • Remplacer le certificat par défaut dans la configuration
  • Changer les valeurs par défaut dans le code

Pas de configuration

Kestrel écoute sur http://localhost:5000 et sur https://localhost:5001 (si un certificat par défaut est disponible).

Remplacer le certificat par défaut dans la configuration

Par défaut, CreateDefaultBuilder appelle Configure(context.Configuration.GetSection("Kestrel")) pour charger la configuration de Kestrel. Un schéma de configuration des paramètres d’application HTTPS par défaut est disponible pour Kestrel. Configurez plusieurs points de terminaison, notamment les URL et les certificats à utiliser, à partir d’un fichier sur disque ou d’un magasin de certificats.

Dans l’exemple appsettings.json suivant :

  • Définissez AllowInvalid sur true pour permettre l’utilisation de certificats non valides (par exemple des certificats auto-signés).
  • Tout point de terminaison HTTPS qui ne spécifie pas de certificat (HttpsDefaultCert dans l’exemple qui suit) revient au certificat défini sous Certificats>Par défaut ou au certificat de développement.
{
  "Kestrel": {
    "Endpoints": {
      "Http": {
        "Url": "http://localhost:5000"
      },
      "HttpsInlineCertFile": {
        "Url": "https://localhost:5001",
        "Certificate": {
          "Path": "<path to .pfx file>",
          "Password": "<certificate password>"
        }
      },
      "HttpsInlineCertStore": {
        "Url": "https://localhost:5002",
        "Certificate": {
          "Subject": "<subject; required>",
          "Store": "<certificate store; required>",
          "Location": "<location; defaults to CurrentUser>",
          "AllowInvalid": "<true or false; defaults to false>"
        }
      },
      "HttpsDefaultCert": {
        "Url": "https://localhost:5003"
      },
      "Https": {
        "Url": "https://*:5004",
        "Certificate": {
          "Path": "<path to .pfx file>",
          "Password": "<certificate password>"
        }
      }
    },
    "Certificates": {
      "Default": {
        "Path": "<path to .pfx file>",
        "Password": "<certificate password>"
      }
    }
  }
}

Une alternative à l’utilisation de Chemin et de Mot de passe pour un nœud de certificat consiste à spécifier le certificat avec des champs du magasin de certificats. Par exemple, le certificat Certificats>Par défaut peut être spécifié en tant que :

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

Notes de schéma :

  • Les noms des points de terminaison ne respectent pas la casse. Par exemple, HTTPS et Https sont valides.
  • Le paramètre Url est obligatoire pour chaque point de terminaison. Le format de ce paramètre est le même que celui du paramètre de configuration Urls du plus haut niveau, sauf qu’il est limité à une seule valeur.
  • Ces points de terminaison remplacent ceux qui sont définis dans le paramètre de configuration Urls du plus haut niveau configuration, au lieu de s’y ajouter. Les points de terminaison définis dans le code via Listen sont cumulatifs avec les points de terminaison définis dans la section de configuration.
  • La section Certificate est facultative. Si la section Certificate n’est pas spécifiée, les valeurs par défaut définies dans les scénarios précédents sont utilisées. Si aucune valeur par défaut n’est disponible, le serveur lève une exception et son démarrage échoue.
  • La section Certificate prend en charge les certificats CheminMot de passe et SujetMagasin.
  • Vous pouvez définir un nombre quelconque de points de terminaison de cette façon, pour autant qu’ils ne provoquent pas de conflits de port.
  • options.Configure(context.Configuration.GetSection("{SECTION}")) retourne un KestrelConfigurationLoader avec une méthode .Endpoint(string name, listenOptions => { }) qui peut être utilisée pour compléter les paramètres d’un point de terminaison configuré :
webBuilder.UseKestrel((context, serverOptions) =>
{
    serverOptions.Configure(context.Configuration.GetSection("Kestrel"))
        .Endpoint("HTTPS", listenOptions =>
        {
            listenOptions.HttpsOptions.SslProtocols = SslProtocols.Tls12;
        });
});

Vous pouvez accéder directement à KestrelServerOptions.ConfigurationLoader pour continuer l’itération sur le chargeur existant, comme celui fourni par CreateDefaultBuilder.

  • La section de configuration pour chaque point de terminaison est disponible sur les options de la méthode Endpoint, ce qui permet de lire les paramètres personnalisés.
  • Plusieurs configurations peuvent être chargées en rappelant options.Configure(context.Configuration.GetSection("{SECTION}")) avec une autre section. Seule la dernière configuration est utilisée, à moins que Load soit explicitement appelé sur les instances précédentes. Le métapackage n’appelle pas Load : sa section de configuration par défaut peut donc être remplacée.
  • KestrelConfigurationLoader reflète la famille d’API Listen de KestrelServerOptions sous forme de surcharges de Endpoint : le code et les points de terminaison de configuration peuvent donc être configurés au même emplacement. Ces surcharges n’utilisent pas de noms et consomment seulement les paramètres par défaut de la configuration.

Changer les valeurs par défaut dans le code

ConfigureEndpointDefaults et ConfigureHttpsDefaults peuvent être utilisés pour modifier les paramètres par défaut pour ListenOptions et HttpsConnectionAdapterOptions, notamment en remplaçant le certificat par défaut spécifié dans le scénario précédent. ConfigureEndpointDefaults et ConfigureHttpsDefaults doivent être appelés avant que des points de terminaison soient configurés.

webBuilder.ConfigureKestrel(serverOptions =>
{
    serverOptions.ConfigureEndpointDefaults(listenOptions =>
    {
        // Configure endpoint defaults
    });

    serverOptions.ConfigureHttpsDefaults(listenOptions =>
    {
        listenOptions.SslProtocols = SslProtocols.Tls12;
    });
});

Prise en charge de Kestrel pour SNI

L’indication du nom de serveur (SNI, Server Name Indication) peut être utilisée pour héberger plusieurs domaines sur la même adresse IP et le même port. Pour que SNI fonctionne, le client envoie le nom d’hôte pour la session sécurisée au serveur pendant la négociation TLS afin que le serveur puisse fournir le certificat correct. Le client utilise le certificat fourni pour la communication chiffrée avec le serveur pendant la session sécurisée qui suit la négociation TLS.

Kestrel prend en charge SNI via le rappel de ServerCertificateSelector. Le rappel est appelé une fois par connexion pour permettre à l’application d’inspecter le nom d’hôte et de sélectionner le certificat approprié.

La prise en charge de SNI nécessite les points suivants :

  • Exécution sur le framework cible netcoreapp2.1 ou version ultérieure. Sur net461 ou version ultérieure, le rappel est invoqué, mais le name est toujours null. name est également null si le client ne fournit pas le paramètre du nom d’hôte dans la négociation TLS.
  • Tous les sites web s’exécutent sur la même instance Kestrel. Kestrel ne prend pas en charge le partage d’une adresse IP et d’un port entre plusieurs instances sans un proxy inverse.
webBuilder.ConfigureKestrel(serverOptions =>
{
    serverOptions.ListenAnyIP(5005, listenOptions =>
    {
        listenOptions.UseHttps(httpsOptions =>
        {
            var localhostCert = CertificateLoader.LoadFromStoreCert(
                "localhost", "My", StoreLocation.CurrentUser,
                allowInvalid: true);
            var exampleCert = CertificateLoader.LoadFromStoreCert(
                "example.com", "My", StoreLocation.CurrentUser,
                allowInvalid: true);
            var subExampleCert = CertificateLoader.LoadFromStoreCert(
                "sub.example.com", "My", StoreLocation.CurrentUser,
                allowInvalid: true);
            var certs = new Dictionary<string, X509Certificate2>(
                StringComparer.OrdinalIgnoreCase);
            certs["localhost"] = localhostCert;
            certs["example.com"] = exampleCert;
            certs["sub.example.com"] = subExampleCert;

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

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

Journalisation des connexions

Appelez UseConnectionLogging pour émettre des journaux de niveau débogage pour les communications au niveau des octets sur une connexion. La journalisation des connexions est utile pour résoudre les problèmes de communication de bas niveau, tels que pendant le chiffrement TLS et derrière les proxys. Si UseConnectionLogging est placé avant UseHttps, le trafic chiffré est journalisé. Si UseConnectionLogging est placé après UseHttps, le trafic déchiffré est journalisé.

webBuilder.ConfigureKestrel(serverOptions =>
{
    serverOptions.Listen(IPAddress.Any, 8000, listenOptions =>
    {
        listenOptions.UseConnectionLogging();
    });
});

Lier à un socket TCP

La méthode Listen se lie à un socket TCP, et une expression lambda options permet la configuration d’un certificat 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>();
        });

L’exemple configure HTTPS pour un point de terminaison avec ListenOptions. Utilisez la même API afin de configurer d’autres paramètres Kestrel pour des points de terminaison spécifiques.

Pour créer des certificats auto-signés sous Windows, vous pouvez utiliser l’applet de commande PowerShell New-SelfSignedCertificate. Pour obtenir un exemple non pris en charge, consultez UpdateIISExpressSSLForChrome.ps1.

OpenSSL permet de créer des certificats sous macOS, Linux et Windows.

Lier à un socket Unix

Écoutez sur un socket Unix avec ListenUnixSocket pour améliorer les performances avec Nginx, comme illustré dans cet exemple :

webBuilder.ConfigureKestrel(serverOptions =>
{
    serverOptions.ListenUnixSocket("/tmp/kestrel-test.sock");
    serverOptions.ListenUnixSocket("/tmp/kestrel-test.sock", 
        listenOptions =>
        {
            listenOptions.UseHttps("testCert.pfx", 
                "testpassword");
        });
})
  • Dans le fichier de configuration Nginx, définissez l’entrée server>location>proxy_pass sur http://unix:/tmp/{KESTREL SOCKET}:/;. {KESTREL SOCKET} est le nom du socket fourni à ListenUnixSocket (par exemple, kestrel-test.sock dans l’exemple précédent).
  • Vérifiez que le socket est accessible en écriture par Nginx (par exemple, chmod go+w /tmp/kestrel-test.sock).

Port 0

Si vous spécifiez le numéro de port 0, Kestrel se lie dynamiquement à un port disponible. L’exemple suivant montre comment déterminer le port auquel Kestrel se lie au moment de l’exécution :

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>");
    });
}

Quand l’application est exécutée, la sortie de la fenêtre de console indique le port dynamique où l’application peut être atteinte :

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

Limitations

Configurez des points de terminaison avec les approches suivantes :

  • UseUrls
  • Arguments de ligne de commande --urls
  • La clé de configuration d’hôte urls
  • ASPNETCORE_URLS variable d’environnement

Ces méthodes sont utiles si vous voulez que votre code fonctionne avec des serveurs autres que Kestrel. Toutefois, soyez conscient des limitations suivantes :

  • HTTPS ne peut pas être utilisé avec ces approches, sauf si un certificat par défaut est fourni dans la configuration du point de terminaison HTTPS (par exemple avec la configuration de KestrelServerOptions ou un fichier de configuration, comme illustré plus haut dans cette rubrique).
  • Quand les deux approches Listen et UseUrls sont utilisées simultanément, les points de terminaison Listen remplacent les points de terminaison UseUrls.

Configuration de point de terminaison IIS

Quand vous utilisez IIS, les liaisons d’URL pour IIS remplacent les liaisons qui sont définies par Listen ou par UseUrls. Pour plus d’informations, consultez la rubrique Module ASP.NET Core.

ListenOptions.Protocols

La propriété Protocols établit les protocoles HTTP (HttpProtocols) activés sur un point de terminaison de connexion ou pour le serveur. Affectez une valeur à la propriété Protocols à partir de l’énumération HttpProtocols.

Valeur enum HttpProtocols Protocole de connexion autorisé
Http1 HTTP/1.1 uniquement. Peut être utilisé avec ou sans TLS.
Http2 HTTP/2 uniquement. Peut être utilisé sans TLS, uniquement si le client prend en charge un mode de connaissance préalable (Prior Knowledge).
Http1AndHttp2 HTTP/1.1 et HTTP/2. HTTP/2 nécessite que le client sélectionne HTTP/2 dans l’établissement d’une liaison TLS ALPN (Application-Layer Protocol Negotiation) ; sinon, la connexion est établie par défaut sur HTTP/1.1.

La valeur ListenOptions.Protocols par défaut pour n’importe quel point de terminaison est HttpProtocols.Http1AndHttp2.

Restrictions TLS pour HTTP/2 :

  • TLS version 1.2 ou ultérieure
  • Renégociation désactivée
  • Compression désactivée
  • Tailles minimales de l’échange de clé éphémère :
    • Diffie-Hellman à courbe elliptique (ECDHE) [RFC4492] : 224 bits minimum
    • Diffie-Hellman à champ fini (DHE) [TLS12] : 2048 bits minimum
  • Suite de chiffrement non interdite.

Prise en charge par défaut de TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 [TLS-ECDHE] avec la courbe elliptique P-256 [FIPS186].

L’exemple suivant autorise les connexions HTTP/1.1 et HTTP/2 sur le port 8000. Les connexions sont sécurisées par TLS avec un certificat fourni :

webBuilder.ConfigureKestrel(serverOptions =>
{
    serverOptions.Listen(IPAddress.Any, 8000, listenOptions =>
    {
        listenOptions.UseHttps("testCert.pfx", "testPassword");
    });
});

Utilisez l’intergiciel de connexion pour filtrer les établissements de liaisons TLS par connexion pour des chiffrements spécifiques, si nécessaire.

L’exemple suivant lève l’exception NotSupportedException pour tout algorithme de chiffrement que l’application ne prend pas en charge. Vous pouvez également définir et comparer ITlsHandshakeFeature.CipherAlgorithm à une liste de suites de chiffrement acceptables.

Aucun chiffrement n’est utilisé avec un algorithme de chiffrement 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();
            });
        }
    }
}

Le filtrage de connexion peut également être configuré via un 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();
        });
    });
});

Sur Linux, CipherSuitesPolicy peut être utilisé pour filtrer les établissements de liaisons TLS par connexion :

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

Définir le protocole à partir de la configuration

Par défaut, CreateDefaultBuilder appelle serverOptions.Configure(context.Configuration.GetSection("Kestrel")) pour charger la configuration de Kestrel.

L’exemple appsettings.json suivant établit HTTP/1.1 comme protocole de connexion par défaut pour tous les points de terminaison :

{
  "Kestrel": {
    "EndpointDefaults": {
      "Protocols": "Http1"
    }
  }
}

L’exemple appsettings.json suivant établit le protocole de connexion HTTP/1.1 pour un point de terminaison spécifique :

{
  "Kestrel": {
    "Endpoints": {
      "HttpsDefaultCert": {
        "Url": "https://localhost:5001",
        "Protocols": "Http1"
      }
    }
  }
}

Les protocoles spécifiés dans le code remplacent les valeurs définies par configuration.

Préfixes d’URL

Quand vous utilisez UseUrls, l’argument de ligne de commande --urls, la clé de configuration d’hôte urls ou la variable d’environnement ASPNETCORE_URLS, les préfixes d’URL peuvent être dans un des formats suivants.

Seuls les préfixes d’URL HTTP sont valides. Kestrel ne prend pas en charge HTTPS lors de la configuration de liaisons d’URL à l’aide de UseUrls.

  • Adresse IPv4 avec numéro de port

    http://65.55.39.10:80/
    

    0.0.0.0 est un cas spécial qui se lie à toutes les adresses IPv4.

  • Adresse IPv6 avec numéro de port

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

    [::] est l’équivalent IPv6 de 0.0.0.0 dans IPv4.

  • Nom d’hôte avec numéro de port

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

    Les noms d’hôte, * et + ne sont pas spéciaux. Tout ce qui n’est pas reconnu comme adresse IP valide ou localhost se lie à toutes les adresses IP IPv4 et IPv6. Pour lier différents noms d’hôte à différentes applications ASP.NET Core sur le même port, utilisez HTTP.sys ou un serveur proxy inverse, comme IIS, Nginx ou Apache.

    Avertissement

    L’hébergement dans une configuration de proxy inverse nécessite la configuration de l’intergiciel des en-têtes transférés.

  • Nom localhost de l’hôte avec numéro de port ou adresse IP de bouclage avec numéro de port

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

    Quand localhost est spécifié, Kestrel tente de se lier aux interfaces de bouclage IPv4 et IPv6. Si le port requis est en cours d’utilisation par un autre service sur l’une des interfaces de bouclage, Kestrel ne démarre pas. Si l’une des interfaces de bouclage n’est pas disponible pour une raison quelconque (généralement du fait de la non-prise en charge d’IPv6), Kestrel journalise un avertissement.

Filtrage d’hôtes

Bien que Kestrel prenne en charge la configuration en fonction de préfixes tels que http://example.com:5000, Kestrel ignore en grande partie le nom d’hôte. L’hôte localhost est un cas spécial utilisé pour la liaison à des adresses de bouclage. Tout hôte autre qu’une adresse IP explicite se lie à toutes les adresses IP publiques. Les en-têtes Host ne sont pas validés.

En guise de solution de contournement, utilisez le middleware de filtrage d’hôtes. L’intergiciel de filtrage d’hôte est fourni par le package Microsoft.AspNetCore.HostFiltering, qui est implicitement fourni pour les applications ASP.NET Core. L’intergiciel (middleware) est ajouté par CreateDefaultBuilder, qui appelle AddHostFiltering :

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

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

Le middleware de filtrage d’hôtes est désactivé par défaut. Pour activer l’intergiciel, définissez une clé AllowedHosts dans appsettings.json/appsettings.{Environment}.json. La valeur est une liste délimitée par des points-virgules des noms d’hôte sans numéros de port :

appsettings.json:

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

Notes

Le middleware des en-têtes transférés a aussi une option AllowedHosts. Le middleware des en-têtes transférés et le middleware de filtrage d’hôtes ont des fonctionnalités similaires pour différents scénarios. La définition d’AllowedHosts avec le middleware des en-têtes transférés est appropriée quand l’en-tête Host n’est pas conservé durant le transfert des requêtes avec un serveur proxy inverse ou un équilibreur de charge. La configuration de AllowedHosts avec l’intergiciel de filtrage d’hôte est appropriée quand Kestrel est utilisé en tant que serveur Edge public ou quand l'en-tête Host est directement transféré.

Pour plus d’informations sur le middleware des en-têtes transférés, consultez Configurer ASP.NET Core pour l’utilisation de serveurs proxy et d’équilibreurs de charge.

Configuration du transport Libuv

Pour les projets qui nécessitent l’utilisation de Libuv (UseLibuv) :

  • Ajoutez une dépendance pour le package Microsoft.AspNetCore.Server.Kestrel.Transport.Libuv au fichier projet de l’application :

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

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

Vidage des requêtes HTTP/1.1

L’ouverture de connexions HTTP prend beaucoup de temps. Elle nécessite beaucoup de ressources pour HTTPS aussi. Par conséquent, Kestrel tente de réutiliser les connexions par protocole HTTP/1.1. Un corps de la demande doit être entièrement consommé pour permettre la réutilisation de la connexion. L’application ne consomme pas toujours le corps de la demande, comme les requêtes POST où le serveur renvoie une redirection ou une réponse 404. Dans le cas de POST-redirect :

  • Le client a peut-être déjà envoyé une partie des données POST.
  • Le serveur écrit la réponse 301.
  • La connexion ne peut pas être utilisée pour une nouvelle demande tant que les données POST du corps de la demande précédente n’ont pas été entièrement lues.
  • Kestrel tente de vider le corps de la demande. Le drainage du corps de la demande signifie lire et ignorer les données sans les traiter.

Le processus de drainage fait un compromis entre l’autorisation de réutiliser la connexion et le temps nécessaire pour vider les données restantes :

  • Le drainage a un délai d’attente de cinq secondes, qui n’est pas configurable.
  • Si toutes les données spécifiées par l’en-tête Content-Length ou Transfer-Encoding n’ont pas été lues avant le délai d’expiration, la connexion est fermée.

Parfois, vous pouvez mettre fin à la demande immédiatement, avant ou après l’écriture de la réponse. Par exemple, les clients peuvent avoir des limites de données restrictives. La limitation des données chargées peut donc être une priorité. Dans ce cas, pour mettre fin à une demande, appelez HttpContext.Abort à partir d’un contrôleur, d’une page Razor ou d’un intergiciel.

Il existe des mises en garde pour appeler Abort :

  • La création de nouvelles connexions peut être lente et coûteuse.
  • Il n’est pas garanti que le client ait lu la réponse avant la fermeture de la connexion.
  • L’appel Abort doit être rare et réservé aux cas d’erreur grave, et non aux erreurs courantes.
    • Appelez Abort uniquement lorsqu’un problème spécifique doit être résolu. Par exemple, appelez Abort si des clients malveillants essaient de publier (POST) des données ou lorsqu’il existe un bogue dans le code client qui provoque des demandes volumineuses ou nombreuses.
    • N’appelez pas Abort pour les erreurs courantes, telles que HTTP 404 (Introuvable).

L’appel de HttpResponse.CompleteAsync avant d’appeler Abort garantit que le serveur a terminé l’écriture de la réponse. Toutefois, le comportement du client n’est pas prévisible et il se peut qu’il ne lise pas la réponse avant l’abandon de la connexion.

Ce processus est différent pour HTTP/2, car le protocole prend en charge l’abandon des flux de requêtes individuels sans fermer la connexion. Le délai d’expiration du drainage de cinq secondes ne s’applique pas. S’il existe des données de corps de la demande non lues après la terminaison d’une réponse, le serveur envoie une trame HTTP/2 RST. Les trames de données de corps de la demande supplémentaires sont ignorées.

Si possible, les clients devraient utiliser l’en-tête de demande Expect: 100-continue et attendre que le serveur réponde avant de commencer à envoyer le corps de la demande. Cela permet au client d’examiner la réponse et d’abandonner avant d’envoyer des données inutiles.

Ressources supplémentaires