Partager via


Héberger ASP.NET Core sur Linux avec Nginx

De Sourabh Shirhatti

Remarque

Ceci n’est pas la dernière version de cet article. Pour la version actuelle, consultez la version .NET 9 de cet article.

Avertissement

Cette version d’ASP.NET Core n’est plus prise en charge. Pour plus d’informations, consultez la stratégie de support .NET et .NET Core. Pour la version actuelle, consultez la version .NET 9 de cet article.

Important

Ces informations portent sur la préversion du produit, qui est susceptible d’être en grande partie modifié avant sa commercialisation. Microsoft n’offre aucune garantie, expresse ou implicite, concernant les informations fournies ici.

Pour la version actuelle, consultez la version .NET 9 de cet article.

Ce guide explique la configuration d’un environnement ASP.NET Core prêt pour la production pour Ubuntu, Red Hat Enterprise (RHEL) et SUSE Linux Enterprise Server.

Pour plus d’informations sur les autres distributions Linux prises en charge par ASP.NET Core, consultez Prérequis pour .NET Core sur Linux.

Ce guide montre comment effectuer les opérations suivantes :

  • Placer une application ASP.NET Core existante derrière un serveur proxy inverse.
  • Configurer le serveur proxy inverse pour transférer les requêtes au serveur web Kestrel.
  • S’assurer que l’application web s’exécute au démarrage en tant que démon.
  • Configurer un outil de gestion des processus pour aider à redémarrer l’application web.

Prérequis

  • Accédez à Ubuntu 20.04 avec un compte d’utilisateur standard disposant de privilèges sudo.
  • Dernière version stable du runtime .NET installée sur le serveur.
  • Une application ASP.NET Core existante.

Puis, à n’importe quel moment après la mise à niveau de l’infrastructure partagée, redémarrez les applications ASP.NET Core hébergées par le serveur.

Publier et copier sur l’application

Configurez l’application pour un déploiement dépendant du framework.

Si l’application est exécutée localement dans l’environnement de développement et n’est pas configurée par le serveur pour établir des connexions HTTPS sécurisées, adoptez l’une des approches suivantes :

  • Configurez l’application pour gérer les connexions locales sécurisées. Pour plus d’informations, consultez la section Configuration HTTPS.

  • Configurez l’application pour qu’elle s’exécute au niveau du point de terminaison non sécurisé :

    • Désactivez l’intergiciel de redirection HTTPS dans l’environnement de développement (Program.cs) :

      if (!app.Environment.IsDevelopment())
      {
          app.UseHttpsRedirection();
      }
      

      Pour plus d’informations, consultez Utiliser plusieurs environnements dans ASP.NET Core.

    • Supprimez https://localhost:5001 (le cas échéant) de la propriété applicationUrl dans le fichier Properties/launchSettings.json.

Pour plus d’informations sur la configuration selon l’environnement, consultez Utiliser plusieurs environnements dans ASP.NET Core.

Exécutez dotnet publish à partir de l’environnement de développement pour empaqueter une application dans un répertoire (par exemple, bin/Release/{TARGET FRAMEWORK MONIKER}/publish, où l’espace réservé {TARGET FRAMEWORK MONIKER} est le moniker de framework cible (TFM ) exécutable sur le serveur :

dotnet publish --configuration Release

L’application peut également être publiée en tant que déploiement autonome si vous préférez ne pas gérer le runtime .NET Core sur le serveur.

Copiez l’application ASP.NET Core sur le serveur à l’aide d’un outil qui s’intègre au flux de travail de l’organisation (par exemple, SCP, SFTP). Il est courant de placer les applications web sous le répertoire var (par exemple, var/www/helloapp).

Remarque

Dans un scénario de déploiement en production, un workflow d’intégration continue effectue le travail de publication de l’application et de copie des composants sur le serveur.

Testez l’application :

  1. À partir de la ligne de commande, exécutez l’application : dotnet <app_assembly>.dll.
  2. Dans un navigateur, accédez à http://<serveraddress>:<port> pour vérifier que l’application fonctionne sur Linux localement.

Configurer un serveur proxy inverse

Un proxy inverse est une configuration courante pour traiter les applications web dynamiques. Un proxy inverse met fin à la requête HTTP et la transfère à l’application ASP.NET Core.

Utiliser un serveur proxy inverse

Kestrel est idéal pour servir du contenu dynamique à partir d’ASP.NET Core. Toutefois, les fonctionnalités de service web ne sont pas aussi complètes que les serveurs tels qu’IIS, Apache ou Nginx. Un serveur proxy inverse peut décharger du travail tel que le traitement du contenu statique, la mise en cache des requêtes, la compression des requêtes et l’arrêt HTTPS à partir du serveur HTTP. Un serveur proxy inverse peut résider sur un ordinateur dédié ou peut être déployé à côté d’un serveur HTTP.

Pour les besoins de ce guide, nous utilisons une seule instance de Nginx. Elle s’exécute sur le même serveur, en plus du serveur HTTP. Selon les exigences, un paramétrage différent peut être choisi.

Comme les demandes sont transférées par proxy inverse, utilisez l’intergiciel d’en-têtes transférés du package Microsoft.AspNetCore.HttpOverrides, qui est inclus automatiquement dans les applications ASP.NET Core via le métapaquet Microsoft.AspNetCore.App du framework partagé. Le middleware met à jour le Request.Scheme, à l’aide de l’en-tête X-Forwarded-Proto, afin que les URI de redirection et d’autres stratégies de sécurité fonctionnent correctement.

Le middleware Forwarded Headers doit s’exécuter avant tout autre middleware. Cet ordre permet au middleware qui repose sur les informations des en-têtes transférés d’utiliser les valeurs d’en-tête pour le traitement. Pour exécuter le middleware Forwarded Headers après les middlewares Diagnostics et Error Handling, consultez Ordre du middleware Forwarded Headers.

Appelez la méthode UseForwardedHeaders avant d’appeler d’autres intergiciels. Configurez le middleware pour transférer les en-têtes X-Forwarded-For et X-Forwarded-Proto :

using Microsoft.AspNetCore.HttpOverrides;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddAuthentication();

var app = builder.Build();

app.UseForwardedHeaders(new ForwardedHeadersOptions
{
    ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto
});

app.UseAuthentication();

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

app.Run();

Si aucune option ForwardedHeadersOptions n’est spécifiée au middleware, les en-têtes par défaut à transférer sont None.

Les serveurs proxy exécutés sur les adresses de bouclage (127.0.0.0/8, [::1]), notamment l’adresse localhost standard (127.0.0.1), sont approuvés par défaut. Si d’autres serveurs proxys ou réseaux approuvés au sein de l’organisation gèrent les requêtes entre Internet et le serveur web, ajoutez-les à la liste des KnownProxies ou des KnownNetworks avec ForwardedHeadersOptions. L’exemple suivant ajoute un serveur proxy de confiance avec l’adresse IP 10.0.0.100 aux KnownProxies d’intergiciels des en-têtes transférés :

using Microsoft.AspNetCore.HttpOverrides;
using System.Net;

var builder = WebApplication.CreateBuilder(args);

// Configure forwarded headers
builder.Services.Configure<ForwardedHeadersOptions>(options =>
{
    options.KnownProxies.Add(IPAddress.Parse("10.0.0.100"));
});

builder.Services.AddAuthentication();

var app = builder.Build();

app.UseForwardedHeaders(new ForwardedHeadersOptions
{
    ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto
});

app.UseAuthentication();

app.MapGet("/", () => "10.0.0.100");

app.Run();

Pour plus d’informations, consultez l’article Configurer ASP.NET Core pour l’utilisation de serveurs proxy et d’équilibreurs de charge.

Installer Nginx

Utilisez apt-get pour installer Nginx. Le programme d’installation crée un script d’initialisation systemd qui exécute Nginx en tant que démon au démarrage du système. Suivez les instructions d’installation pour Ubuntu sur le site Nginx : Les packages officiels Debian/Ubuntu.

Remarque

Si des modules Nginx facultatifs sont requis, il peut s’avérer nécessaire de configurer Nginx à partir de la source.

Comme il s’agit de l’installation initiale de Nginx, vous devez le démarrer explicitement en exécutant :

sudo service nginx start

Vérifiez qu’un navigateur affiche la page d’accueil par défaut de Nginx. La page d’accueil est accessible à l’adresse http://<server_IP_address>/index.nginx-debian.html.

Configurer Nginx

Pour configurer Nginx en tant que proxy inverse pour transférer des requêtes HTTP à l’application ASP.NET Core, modifiez /etc/nginx/sites-available/default et recréez le lien symbolique. Une fois le fichier /etc/nginx/sites-available/default créé, utilisez la commande suivante pour créer le lien symbolique :

sudo ln -s /etc/nginx/sites-available/default /etc/nginx/sites-enabled/default

Ouvrez /etc/nginx/sites-available/default dans un éditeur de texte et remplacez le contenu par l’extrait suivant :

map $http_connection $connection_upgrade {
  "~*Upgrade" $http_connection;
  default keep-alive;
}

server {
  listen        80;
  server_name   example.com *.example.com;
  location / {
      proxy_pass         http://127.0.0.1:5000/;
      proxy_http_version 1.1;
      proxy_set_header   Upgrade $http_upgrade;
      proxy_set_header   Connection $connection_upgrade;
      proxy_set_header   Host $host;
      proxy_cache_bypass $http_upgrade;
      proxy_set_header   X-Forwarded-For $proxy_add_x_forwarded_for;
      proxy_set_header   X-Forwarded-Proto $scheme;
  }
}

S’il s’agit d’une application SignalR ou Blazor Server, consultez Hébergement et mise à l’échelle de la production SignalR ASP.NET Core et Héberger et déployer des applications Blazor ASP.NET Core côté serveur, respectivement pour plus d’informations.

Si aucun server_name ne correspond, Nginx utilise le serveur par défaut. Si aucun serveur par défaut n’est défini, le premier serveur dans le fichier de configuration est le serveur par défaut. En guise de bonne pratique, ajoutez un serveur par défaut spécifique qui retourne un code d’état 444 dans votre fichier de configuration. Voici un exemple de configuration de serveur par défaut :

server {
    listen   80 default_server;
    # listen [::]:80 default_server deferred;
    return   444;
}

Avec les fichier de configuration et le serveur par défaut précédents, Nginx accepte le trafic public sur le port 80 avec un en-tête d’hôte example.com ou *.example.com. Les requêtes qui ne correspondent pas à ces hôtes ne sont pas transférées à Kestrel. Nginx transfère les requêtes correspondantes à Kestrel à l’adresse http://127.0.0.1:5000/. Pour plus d’informations, consultez Comment nginx traite une requête. Pour changer le port/l’adresse IP de Kestrel, consultez Kestrel : configuration du point de terminaison.

Avertissement

La spécification d’une directive server_name incorrecte expose votre application à des failles de sécurité. Une liaison générique de sous-domaine (par exemple, *.example.com) ne présente pas ce risque de sécurité si vous contrôlez le domaine parent en entier (par opposition à *.com, qui est vulnérable). Pour plus d’informations, consultez RFC 9110 : Sémantique HTTP (Section 7.2 : Hôte et autorité).

Une fois la configuration de Nginx établie, exécutez sudo nginx -t pour vérifier la syntaxe des fichiers de configuration. Si le test de fichier de configuration réussit, forcez Nginx à appliquer les modifications en exécutant sudo nginx -s reload.

Pour exécuter directement l’application sur le serveur :

  1. Accédez au répertoire de l’application.
  2. Exécutez l’application : dotnet <app_assembly.dll>, où app_assembly.dll est le nom de fichier d’assembly de l’application.

Si l’application s’exécute sur le serveur, mais ne répond pas sur Internet, vérifiez le pare-feu du serveur et confirmez que le port 80 est ouvert. Si vous utilisez une machine virtuelle Azure Ubuntu, ajoutez une règle de groupe de sécurité réseau (NSG) qui autorise le trafic entrant sur le port 80. Il est inutile d’activer une règle de trafic sortant sur le port 80, car le trafic sortant est accordé automatiquement quand la règle de trafic entrant est activée.

Lorsque vous avez terminé de tester l’application, arrêtez l’application en appuyant sur Ctrl+C (Windows) ou +C (macOS) à l’invite de commandes.

Augmenter les keepalive_requests

keepalive_requests peut être augmenté pour atteindre des performances plus élevées. Pour plus d’informations, consultez ce problème GitHub.

Surveiller l’application

Le serveur est configuré pour transférer les requêtes faites à http://<serveraddress>:80 à l’application ASP.NET Core s’exécutant sur http://127.0.0.1:5000 à l’adresse Kestrel. Toutefois, Nginx n’est pas configuré pour gérer le processus Kestrel. systemd peut être utilisé pour créer un fichier de service afin de démarrer et de surveiller l’application web sous-jacente. systemd est un système d’initialisation qui fournit de nombreuses fonctionnalités puissantes pour démarrer, arrêter et gérer des processus.

Créer le fichier de service

Créez le fichier de définition de service :

sudo nano /etc/systemd/system/kestrel-helloapp.service

Voici un exemple de fichier de service .ini pour l’application :

[Unit]
Description=Example .NET Web API App running on Linux

[Service]
WorkingDirectory=/var/www/helloapp
ExecStart=/usr/bin/dotnet /var/www/helloapp/helloapp.dll
Restart=always
# Restart service after 10 seconds if the dotnet service crashes:
RestartSec=10
KillSignal=SIGINT
SyslogIdentifier=dotnet-example
User=www-data
Environment=ASPNETCORE_ENVIRONMENT=Production
Environment=DOTNET_NOLOGO=true

[Install]
WantedBy=multi-user.target

Dans l’exemple précédent, l’utilisateur qui gère le service est spécifié par l’option User. L’utilisateur (www-data) doit exister et être le propriétaire légitime des fichiers de l’application.

Utilisez TimeoutStopSec pour configurer la durée d’attente de l’arrêt de l’application après la réception du signal d’interruption initial. Si l’application ne s’arrête pas pendant cette période, le signal SIGKILL est émis pour mettre fin à l’application. Indiquez la valeur en secondes sans unité (par exemple, 150), une valeur d’intervalle de temps (par exemple, 2min 30s) ou infinity pour désactiver le délai d’attente. Lé valeur de TimeoutStopSec prend la valeur par défaut de DefaultTimeoutStopSec dans le fichier de configuration du manager (systemd-system.conf, system.conf.d, systemd-user.conf, user.conf.d). Le délai d’expiration par défaut pour la plupart des distributions est de 90 secondes.

# The default value is 90 seconds for most distributions.
TimeoutStopSec=90

Linux possède un système de fichiers respectant la casse. La définition de ASPNETCORE_ENVIRONMENT sur Production entraîne la recherche du fichier de configuration appsettings.Production.json, et non de appsettings.production.json.

Certaines valeurs (par exemple, les chaînes de connexion SQL) doivent être placées dans une séquence d’échappement afin que les fournisseurs de configuration puissent lire les variables d’environnement. Utilisez la commande suivante pour générer une valeur correctement placée dans une séquence d’échappement en vue de son utilisation dans le fichier de configuration :

systemd-escape "<value-to-escape>"

Les séparateurs : (signe deux-points) ne sont pas pris en charge dans les noms de variables d’environnement. Utilisez un double trait de soulignement (__) à la place d’un signe deux-points. Le fournisseur de configuration de variables d’environnement convertit les doubles traits de soulignement en signes deux-points quand les variables d’environnement sont lues dans la configuration. Dans l’exemple suivant, la clé de chaîne de connexion ConnectionStrings:DefaultConnection est définie dans le fichier de définition de service en tant que ConnectionStrings__DefaultConnection :

Environment=ConnectionStrings__DefaultConnection={Connection String}

Enregistrez le fichier et activez le service.

sudo systemctl enable kestrel-helloapp.service

Démarrez le service et vérifiez qu’il s’exécute.

sudo systemctl start kestrel-helloapp.service
sudo systemctl status kestrel-helloapp.service

◝ kestrel-helloapp.service - Example .NET Web API App running on Linux
    Loaded: loaded (/etc/systemd/system/kestrel-helloapp.service; enabled)
    Active: active (running) since Thu 2016-10-18 04:09:35 NZDT; 35s ago
Main PID: 9021 (dotnet)
    CGroup: /system.slice/kestrel-helloapp.service
            └─9021 /usr/local/bin/dotnet /var/www/helloapp/helloapp.dll

Le proxy inverse étant configuré et Kestrel étant géré via systemd, l’application web est maintenant entièrement configurée et accessible à partir d’un navigateur sur l’ordinateur local à l’adresse http://localhost. Elle est également accessible à partir d’un ordinateur distant, sauf en cas de blocage par un pare-feu. Lors de l’inspection des en-têtes de réponse, on constate que l’en-tête Server indique que l’application ASP.NET Core est traitée par Kestrel.

HTTP/1.1 200 OK
Date: Tue, 11 Oct 2016 16:22:23 GMT
Server: Kestrel
Keep-Alive: timeout=5, max=98
Connection: Keep-Alive
Transfer-Encoding: chunked

Afficher les journaux d’activité

Puisque l’application web utilisant Kestrel est gérée à l’aide de systemd, tous les événements et les processus sont consignés dans un journal centralisé. Toutefois, ce journal inclut toutes les entrées pour tous les services et les processus gérés par systemd. Pour afficher les éléments propres à kestrel-helloapp.service, utilisez la commande suivante :

sudo journalctl -fu kestrel-helloapp.service

Pour obtenir un filtrage supplémentaire, des options chronologiques, comme --since today, --until 1 hour ago ou une combinaison de ces options, peuvent réduire le nombre d’entrées retournées.

sudo journalctl -fu kestrel-helloapp.service --since "2016-10-18" --until "2016-10-18 04:00"

Protection des données

La pile de protection des données ASP.NET Core est utilisée par plusieurs intergiciels ASP.NET Core, notamment des intergiciels d’authentification (par exemple, l’intergiciel cookie) et les protections contre la falsification de requête intersites (CSRF, Cross Site Request Forgery). Même si les API de protection des données ne sont pas appelées par le code de l’utilisateur, la protection des données doit être configurée pour créer un magasin de clés de chiffrement persistantes. Si la protection des données n’est pas configurée, les clés sont conservées en mémoire et ignorées au redémarrage de l’application.

Si le Key Ring est stocké en mémoire, au redémarrage de l’application :

  • Tous les jetons d’authentification basés sur cookie sont invalidés.
  • Les utilisateurs doivent se reconnecter pour envoyer leur prochaine demande.
  • toutes les données protégées par le Key Ring ne peuvent plus être déchiffrées. Ceci peut inclure des jetons CSRF et des cookies TempData ASP.NET Core MVC.

Pour configurer la protection des données de façon à conserver et chiffrer le porte-clés (Key Ring), consultez :

Longs champs d'en-tête de demande

Les paramètres par défaut du serveur proxy limitent généralement les champs des en-têtes de demande à 4 ou 8 K en fonction de la plateforme. Une application peut nécessiter des champs plus longs que la valeur par défaut (par exemple, les applications qui utilisent Microsoft Entra ID). Si des champs de longueur supérieure sont nécessaires, les paramètres par défaut du serveur proxy doivent être ajustés. Les valeurs à appliquer dépendent du scénario. Pour plus d'informations, voir la documentation du serveur.

Avertissement

N’augmentez pas les valeurs par défaut des mémoires tampons de proxy à moins que ce ne soit nécessaire. Leur augmentation augmente le risque de dépassement de mémoire tampon (dépassement de capacité) et d’attaques par déni de service (DoS) par des utilisateurs malveillants.

Sécuriser l’application

Activer AppArmor

Linux Security Modules (LSM) est un framework qui fait partie du noyau Linux depuis Linux 2.6. LSM prend en charge différentes implémentations de modules de sécurité. AppArmor est un LSM qui implémente un système de contrôle d’accès obligatoire permettant de confiner le programme à un ensemble limité de ressources. Vérifiez qu’AppArmor est activé et configuré correctement.

Configurer le pare-feu

Fermez tous les ports externes qui ne sont pas en cours d’utilisation. Uncomplicated firewall (ufw) fournit un front-end pour iptables en assurant une interface de ligne de commande (CLI) afin de configurer le pare-feu.

Avertissement

Un pare-feu mal configuré bloque l’accès à l’ensemble du système. Si vous utilisez SSH pour vous connecter au système, votre accès sera effectivement bloqué si vous ne spécifiez pas le port SSH approprié. Le numéro de port par défaut est 22. Pour plus d’informations, consultez la présentation d’ufw et le manuel.

Installez ufw et configurez-le de façon à autoriser le trafic sur les ports nécessaires.

sudo apt-get install ufw

sudo ufw allow 22/tcp
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp

sudo ufw enable

Sécuriser Nginx

Changer le nom de la réponse Nginx

Modifiez src/http/ngx_http_header_filter_module.c:

static char ngx_http_server_string[] = "Server: Web Server" CRLF;
static char ngx_http_server_full_string[] = "Server: Web Server" CRLF;

Configurer des options

Configurez le serveur avec les modules nécessaires supplémentaires. Pour renforcer l’application, vous pouvez utiliser un pare-feu d’application web tel que ModSecurity.

Configuration HTTPS

Configurer l’application pour les connexions locales sécurisées (HTTPS)

La commande dotnet run utilise le fichier Properties/launchSettings.json de l’application, qui configure l’application pour l’écoute sur les URL fournies par la propriété applicationUrl. Par exemple, https://localhost:5001;http://localhost:5000

Configurez l’application pour utiliser un certificat en développement pour la commande dotnet run ou l’environnement de développement (F5 ou Ctrl+F5 dans Visual Studio Code) en adoptant l’une des approches suivantes :

Configurer le proxy inverse pour les connexions clientes sécurisées (HTTPS)

Avertissement

La configuration de sécurité présentée dans cette section est une configuration générale qu’il convient d’utiliser comme point de départ pour plus de personnalisation. Nous ne pouvons pas fournir de support pour les outils, serveurs et systèmes d’exploitation tiers. L’utilisation de la configuration présentée dans cette section est à vos propres risques. Pour plus d’informations, accédez aux ressources suivantes :

  • Configurez le serveur pour qu’il écoute le trafic HTTPS sur le port 443 en spécifiant un certificat valide émis par une autorité de certification de confiance.

  • Renforcez la sécurité en appliquant certaines des pratiques mentionnées dans le fichier /etc/nginx/nginx.conf suivant.

  • L’exemple suivant ne configure pas le serveur pour rediriger les requêtes non sécurisées. Nous vous recommandons d’utiliser l’intergiciel de redirection HTTPS. Pour plus d’informations, consultez Appliquer HTTPS dans ASP.NET Core.

    Remarque

    Pour les environnements de développement où la configuration du serveur gère la redirection sécurisée à la place de l’intergiciel de redirection HTTPS, nous vous recommandons d’utiliser des redirections temporaires (302) plutôt que des redirections permanentes (301). La mise en cache des liens peut entraîner un comportement instable dans les environnements de développement.

  • L’ajout d’un en-tête Strict-Transport-Security (HSTS) garantit que toutes les demandes ultérieures du client s’effectuent par le biais du protocole HTTPS. Pour obtenir de l’aide sur la définition de l’en-tête Strict-Transport-Security, consultez Appliquer HTTPS dans ASP.NET Core.

  • Si HTTPS est désactivé à l’avenir, utilisez l’une des approches suivantes :

    • N’ajoutez pas l’en-tête HSTS.
    • Choisissez une valeur max-age courte.

Ajoutez le fichier de configuration /etc/nginx/proxy.conf :

proxy_redirect          off;
proxy_set_header        Host $host;
proxy_set_header        X-Real-IP $remote_addr;
proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header        X-Forwarded-Proto $scheme;
client_max_body_size    10m;
client_body_buffer_size 128k;
proxy_connect_timeout   90;
proxy_send_timeout      90;
proxy_read_timeout      90;
proxy_buffers           32 4k;

Remplacez le contenu du fichier de configuration /etc/nginx/nginx.conf par le fichier suivant. Dans l’exemple, les sections http et server figurent dans un même fichier de configuration.

http {
    include        /etc/nginx/proxy.conf;
    limit_req_zone $binary_remote_addr zone=one:10m rate=5r/s;
    server_tokens  off;

    sendfile on;
    # Adjust keepalive_timeout to the lowest possible value that makes sense 
    # for your use case.
    keepalive_timeout   29;
    client_body_timeout 10; client_header_timeout 10; send_timeout 10;

    upstream helloapp{
        server 127.0.0.1:5000;
    }

    server {
        listen                    443 ssl http2;
        listen                    [::]:443 ssl http2;
        server_name               example.com *.example.com;
        ssl_certificate           /etc/ssl/certs/testCert.crt;
        ssl_certificate_key       /etc/ssl/certs/testCert.key;
        ssl_session_timeout       1d;
        ssl_protocols             TLSv1.2 TLSv1.3;
        ssl_prefer_server_ciphers off;
        ssl_ciphers               ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;
        ssl_session_cache         shared:SSL:10m;
        ssl_session_tickets       off;
        ssl_stapling              off;

        add_header X-Frame-Options DENY;
        add_header X-Content-Type-Options nosniff;

        #Redirects all traffic
        location / {
            proxy_pass http://helloapp;
            limit_req  zone=one burst=10 nodelay;
        }
    }
}

Remarque

Les applications Blazor WebAssembly nécessitent une valeur de paramètre burst plus élevée pour prendre en charge le nombre plus élevé de requêtes effectuées par une application. Pour plus d’informations, consultez Héberger et déployer ASP.NET Core Blazor WebAssembly.

Remarque

L’exemple précédent désactive l’agrafage OCSP (Online Certificate Status Protocol). Si elle est activée, vérifiez que le certificat prend en charge la fonctionnalité. Pour plus d’informations et d’aide sur l’activation de l’OCSP, consultez les propriétés suivantes dans l’article Module ngx_http_ssl_module (documentation Nginx) :

  • ssl_stapling
  • ssl_stapling_file
  • ssl_stapling_responder
  • ssl_stapling_verify

Sécuriser Nginx contre le détournement de clic

Le détournement de clic, également appelé UI redress attack, est une attaque malveillante qui amène le visiteur d’un site web à cliquer sur un lien ou un bouton sur une page différente de celle qu’il est en train de visiter. Utilisez X-FRAME-OPTIONS pour sécuriser le site.

Pour atténuer les attaques par détournement de clic :

  1. Modifiez le fichier nginx.conf :

    sudo nano /etc/nginx/nginx.conf
    

    Dans le bloc de code http{}, ajoutez la ligne : add_header X-Frame-Options "SAMEORIGIN";

  2. Enregistrez le fichier.

  3. Redémarrez Nginx.

Détection de type MIME

Cet en-tête empêche la plupart des navigateurs de détourner le type MIME d’une réponse et de remplacer le type de contenu déclaré, car l’en-tête indique au navigateur qu’il ne doit pas substituer le type de contenu de la réponse. Avec l’option nosniff, si le serveur indique que le contenu est text/html, le navigateur l’affiche en tant que text/html.

  1. Modifiez le fichier nginx.conf :

    sudo nano /etc/nginx/nginx.conf
    

    Dans le bloc de code http{}, ajoutez la ligne : add_header X-Content-Type-Options "nosniff";

  2. Enregistrez le fichier.

  3. Redémarrez Nginx.

Suggestions Nginx supplémentaires

Après la mise à niveau de l’infrastructure partagée sur le serveur, redémarrez les applications ASP.NET Core hébergées par le serveur.

Ressources supplémentaires

Ce guide explique comment configurer un environnement ASP.NET Core prêt pour la production sur un serveur Ubuntu 16.04. Ces instructions fonctionnent normalement avec les versions d’Ubuntu plus récentes, mais elles n’ont pas fait l’objet de tests avec ces versions.

Pour plus d’informations sur les autres distributions Linux prises en charge par ASP.NET Core, consultez Prérequis pour .NET Core sur Linux.

Remarque

Pour Ubuntu 14.04,il est recommandé d’utiliser supervisord comme solution pour la surveillance du processus Kestrel. systemd n’est pas disponible sur Ubuntu 14.04. Pour obtenir des instructions pour Ubuntu 14.04, consultez la version précédente de cette rubrique.

Ce guide montre comment effectuer les opérations suivantes :

  • Placer une application ASP.NET Core existante derrière un serveur proxy inverse.
  • Configurer le serveur proxy inverse pour transférer les requêtes au serveur web Kestrel.
  • S’assurer que l’application web s’exécute au démarrage en tant que démon.
  • Configurer un outil de gestion des processus pour aider à redémarrer l’application web.

Prérequis

  • Accédez à un serveur Ubuntu 16.04 avec un compte d’utilisateur standard disposant de privilèges sudo.
  • Dernière version non disponible en préversion du runtime .NET installée sur le serveur.
  • Une application ASP.NET Core existante.

Puis, à n’importe quel moment après la mise à niveau de l’infrastructure partagée, redémarrez les applications ASP.NET Core hébergées par le serveur.

Publier et copier sur l’application

Configurez l’application pour un déploiement dépendant du framework.

Si l’application est exécutée localement dans l’environnement de développement et n’est pas configurée par le serveur pour établir des connexions HTTPS sécurisées, adoptez l’une des approches suivantes :

  • Configurez l’application pour gérer les connexions locales sécurisées. Pour plus d’informations, consultez la section Configuration HTTPS.

  • Configurez l’application pour qu’elle s’exécute au niveau du point de terminaison non sécurisé :

    • Désactivez l’intergiciel de redirection HTTPS dans l’environnement de développement (Program.cs) :

      if (!app.Environment.IsDevelopment())
      {
          app.UseHttpsRedirection();
      }
      

      Pour plus d’informations, consultez Utiliser plusieurs environnements dans ASP.NET Core.

    • Supprimez https://localhost:5001 (le cas échéant) de la propriété applicationUrl dans le fichier Properties/launchSettings.json.

Pour plus d’informations sur la configuration selon l’environnement, consultez Utiliser plusieurs environnements dans ASP.NET Core.

Exécutez dotnet publish à partir de l’environnement de développement pour empaqueter une application dans un répertoire (par exemple, bin/Release/{TARGET FRAMEWORK MONIKER}/publish, où l’espace réservé {TARGET FRAMEWORK MONIKER} est le moniker de framework cible/TFM) exécutable sur le serveur :

dotnet publish --configuration Release

L’application peut également être publiée en tant que déploiement autonome si vous préférez ne pas gérer le runtime .NET Core sur le serveur.

Copiez l’application ASP.NET Core sur le serveur à l’aide d’un outil qui s’intègre au flux de travail de l’organisation (par exemple, SCP, SFTP). Il est courant de placer les applications web sous le répertoire var (par exemple, var/www/helloapp).

Remarque

Dans un scénario de déploiement en production, un workflow d’intégration continue effectue le travail de publication de l’application et de copie des composants sur le serveur.

Testez l’application :

  1. À partir de la ligne de commande, exécutez l’application : dotnet <app_assembly>.dll.
  2. Dans un navigateur, accédez à http://<serveraddress>:<port> pour vérifier que l’application fonctionne sur Linux localement.

Configurer un serveur proxy inverse

Un proxy inverse est une configuration courante pour traiter les applications web dynamiques. Un proxy inverse met fin à la requête HTTP et la transfère à l’application ASP.NET Core.

Utiliser un serveur proxy inverse

Kestrel est idéal pour servir du contenu dynamique à partir d’ASP.NET Core. Toutefois, les fonctionnalités de service web ne sont pas aussi complètes que les serveurs tels qu’IIS, Apache ou Nginx. Un serveur proxy inverse peut décharger du travail tel que le traitement du contenu statique, la mise en cache des requêtes, la compression des requêtes et l’arrêt HTTPS à partir du serveur HTTP. Un serveur proxy inverse peut résider sur un ordinateur dédié ou peut être déployé à côté d’un serveur HTTP.

Pour les besoins de ce guide, nous utilisons une seule instance de Nginx. Elle s’exécute sur le même serveur, en plus du serveur HTTP. Selon les exigences, un paramétrage différent peut être choisi.

Les requêtes étant transférées par le proxy inverse, vous devez utiliser l’intergiciel des en-têtes transférés à partir du package Microsoft.AspNetCore.HttpOverrides. Le middleware met à jour le Request.Scheme, à l’aide de l’en-tête X-Forwarded-Proto, afin que les URI de redirection et d’autres stratégies de sécurité fonctionnent correctement.

Le middleware Forwarded Headers doit s’exécuter avant tout autre middleware. Cet ordre permet au middleware qui repose sur les informations des en-têtes transférés d’utiliser les valeurs d’en-tête pour le traitement. Pour exécuter le middleware Forwarded Headers après les middlewares Diagnostics et Error Handling, consultez Ordre du middleware Forwarded Headers.

Appelez la méthode UseForwardedHeaders en haut de Program.cs avant d’appeler d’autres intergiciels. Configurez le middleware pour transférer les en-têtes X-Forwarded-For et X-Forwarded-Proto :

// requires using Microsoft.AspNetCore.HttpOverrides;
app.UseForwardedHeaders(new ForwardedHeadersOptions
{
    ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto
});

app.UseAuthentication();

Si aucune option ForwardedHeadersOptions n’est spécifiée au middleware, les en-têtes par défaut à transférer sont None.

Les serveurs proxy exécutés sur les adresses de bouclage (127.0.0.0/8, [::1]), notamment l’adresse localhost standard (127.0.0.1), sont approuvés par défaut. Si d’autres proxys ou réseaux approuvés au sein de l’organisation gèrent les requêtes entre Internet et le serveur web, ajoutez-les à la liste des KnownProxies ou des KnownNetworks avec ForwardedHeadersOptions. L’exemple suivant ajoute un serveur proxy approuvé avec l’adresse IP 10.0.0.100 au middleware des en-têtes transférés KnownProxies dans Program.cs :

using System.Net;

var builder = WebApplication.CreateBuilder(args);

builder.Services.Configure<ForwardedHeadersOptions>(options =>
{
    options.KnownProxies.Add(IPAddress.Parse("10.0.0.100"));
});

Pour plus d’informations, consultez l’article Configurer ASP.NET Core pour l’utilisation de serveurs proxy et d’équilibreurs de charge.

Installer Nginx

Utilisez apt-get pour installer Nginx. Le programme d’installation crée un script d’initialisation systemd qui exécute Nginx en tant que démon au démarrage du système. Suivez les instructions d’installation pour Ubuntu sur le site Nginx : Les packages officiels Debian/Ubuntu.

Remarque

Si des modules Nginx facultatifs sont requis, il peut s’avérer nécessaire de configurer Nginx à partir de la source.

Comme il s’agit de l’installation initiale de Nginx, vous devez le démarrer explicitement en exécutant :

sudo service nginx start

Vérifiez qu’un navigateur affiche la page d’accueil par défaut de Nginx. La page d’accueil est accessible à l’adresse http://<server_IP_address>/index.nginx-debian.html.

Configurer Nginx

Pour configurer Nginx en tant que proxy inverse pour transférer les requêtes HTTP à votre application ASP.NET Core, modifiez /etc/nginx/sites-available/default. Ouvrez-le dans un éditeur de texte et remplacez le contenu par l’extrait de code suivant :

server {
    listen        80;
    server_name   example.com *.example.com;
    location / {
        proxy_pass         http://127.0.0.1:5000;
        proxy_http_version 1.1;
        proxy_set_header   Upgrade $http_upgrade;
        proxy_set_header   Connection keep-alive;
        proxy_set_header   Host $host;
        proxy_cache_bypass $http_upgrade;
        proxy_set_header   X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header   X-Forwarded-Proto $scheme;
    }
}

S’il s’agit d’une application SignalR ou Blazor Server, consultez Hébergement et mise à l’échelle de la production SignalR ASP.NET Core et Héberger et déployer des applications Blazor ASP.NET Core côté serveur, respectivement pour plus d’informations.

Si aucun server_name ne correspond, Nginx utilise le serveur par défaut. Si aucun serveur par défaut n’est défini, le premier serveur dans le fichier de configuration est le serveur par défaut. En guise de bonne pratique, ajoutez un serveur par défaut spécifique qui retourne un code d’état 444 dans votre fichier de configuration. Voici un exemple de configuration de serveur par défaut :

server {
    listen   80 default_server;
    # listen [::]:80 default_server deferred;
    return   444;
}

Avec les fichier de configuration et le serveur par défaut précédents, Nginx accepte le trafic public sur le port 80 avec un en-tête d’hôte example.com ou *.example.com. Les requêtes qui ne correspondent pas à ces hôtes ne sont pas transférées à Kestrel. Nginx transfère les requêtes correspondantes à Kestrel à l’adresse http://127.0.0.1:5000. Pour plus d’informations, consultez Comment nginx traite une requête. Pour changer le port/l’adresse IP de Kestrel, consultez Kestrel : configuration du point de terminaison.

Avertissement

La spécification d’une directive server_name incorrecte expose votre application à des failles de sécurité. Une liaison générique de sous-domaine (par exemple, *.example.com) ne présente pas ce risque de sécurité si vous contrôlez le domaine parent en entier (par opposition à *.com, qui est vulnérable). Pour plus d’informations, consultez RFC 9110 : Sémantique HTTP (Section 7.2 : Hôte et autorité).

Une fois la configuration de Nginx établie, exécutez sudo nginx -t pour vérifier la syntaxe des fichiers de configuration. Si le test de fichier de configuration réussit, forcez Nginx à appliquer les modifications en exécutant sudo nginx -s reload.

Pour exécuter directement l’application sur le serveur :

  1. Accédez au répertoire de l’application.
  2. Exécutez l’application : dotnet <app_assembly.dll>, où app_assembly.dll est le nom de fichier d’assembly de l’application.

Si l’application s’exécute sur le serveur, mais ne répond pas sur Internet, vérifiez le pare-feu du serveur et confirmez que le port 80 est ouvert. Si vous utilisez une machine virtuelle Azure Ubuntu, ajoutez une règle de groupe de sécurité réseau (NSG) qui autorise le trafic entrant sur le port 80. Il est inutile d’activer une règle de trafic sortant sur le port 80, car le trafic sortant est accordé automatiquement quand la règle de trafic entrant est activée.

Lorsque vous avez terminé de tester l’application, arrêtez l’application en appuyant sur Ctrl+C (Windows) ou +C (macOS) à l’invite de commandes.

Surveiller l’application

Le serveur est configuré pour transférer les requêtes faites à http://<serveraddress>:80 à l’application ASP.NET Core s’exécutant sur http://127.0.0.1:5000 à l’adresse Kestrel. Toutefois, Nginx n’est pas configuré pour gérer le processus Kestrel. systemd peut être utilisé pour créer un fichier de service afin de démarrer et de surveiller l’application web sous-jacente. systemd est un système d’initialisation qui fournit de nombreuses fonctionnalités puissantes pour démarrer, arrêter et gérer des processus.

Créer le fichier de service

Créez le fichier de définition de service :

sudo nano /etc/systemd/system/kestrel-helloapp.service

Voici un exemple de fichier de service pour l’application :

[Unit]
Description=Example .NET Web API App running on Ubuntu

[Service]
WorkingDirectory=/var/www/helloapp
ExecStart=/usr/bin/dotnet /var/www/helloapp/helloapp.dll
Restart=always
# Restart service after 10 seconds if the dotnet service crashes:
RestartSec=10
KillSignal=SIGINT
SyslogIdentifier=dotnet-example
User=www-data
Environment=ASPNETCORE_ENVIRONMENT=Production
Environment=DOTNET_NOLOGO=true

[Install]
WantedBy=multi-user.target

Dans l’exemple précédent, l’utilisateur qui gère le service est spécifié par l’option User. L’utilisateur (www-data) doit exister et être le propriétaire légitime des fichiers de l’application.

Utilisez TimeoutStopSec pour configurer la durée d’attente de l’arrêt de l’application après la réception du signal d’interruption initial. Si l’application ne s’arrête pas pendant cette période, le signal SIGKILL est émis pour mettre fin à l’application. Indiquez la valeur en secondes sans unité (par exemple, 150), une valeur d’intervalle de temps (par exemple, 2min 30s) ou infinity pour désactiver le délai d’attente. Lé valeur de TimeoutStopSec prend la valeur par défaut de DefaultTimeoutStopSec dans le fichier de configuration du manager (systemd-system.conf, system.conf.d, systemd-user.conf, user.conf.d). Le délai d’expiration par défaut pour la plupart des distributions est de 90 secondes.

# The default value is 90 seconds for most distributions.
TimeoutStopSec=90

Linux possède un système de fichiers respectant la casse. La définition de ASPNETCORE_ENVIRONMENT sur Production entraîne la recherche du fichier de configuration appsettings.Production.json, et non de appsettings.production.json.

Certaines valeurs (par exemple, les chaînes de connexion SQL) doivent être placées dans une séquence d’échappement afin que les fournisseurs de configuration puissent lire les variables d’environnement. Utilisez la commande suivante pour générer une valeur correctement placée dans une séquence d’échappement en vue de son utilisation dans le fichier de configuration :

systemd-escape "<value-to-escape>"

Les séparateurs : (signe deux-points) ne sont pas pris en charge dans les noms de variables d’environnement. Utilisez un double trait de soulignement (__) à la place d’un signe deux-points. Le fournisseur de configuration de variables d’environnement convertit les doubles traits de soulignement en signes deux-points quand les variables d’environnement sont lues dans la configuration. Dans l’exemple suivant, la clé de chaîne de connexion ConnectionStrings:DefaultConnection est définie dans le fichier de définition de service en tant que ConnectionStrings__DefaultConnection :

Environment=ConnectionStrings__DefaultConnection={Connection String}

Enregistrez le fichier et activez le service.

sudo systemctl enable kestrel-helloapp.service

Démarrez le service et vérifiez qu’il s’exécute.

sudo systemctl start kestrel-helloapp.service
sudo systemctl status kestrel-helloapp.service

◝ kestrel-helloapp.service - Example .NET Web API App running on Ubuntu
    Loaded: loaded (/etc/systemd/system/kestrel-helloapp.service; enabled)
    Active: active (running) since Thu 2016-10-18 04:09:35 NZDT; 35s ago
Main PID: 9021 (dotnet)
    CGroup: /system.slice/kestrel-helloapp.service
            └─9021 /usr/local/bin/dotnet /var/www/helloapp/helloapp.dll

Le proxy inverse étant configuré et Kestrel étant géré via systemd, l’application web est maintenant entièrement configurée et accessible à partir d’un navigateur sur l’ordinateur local à l’adresse http://localhost. Elle est également accessible à partir d’un ordinateur distant, sauf en cas de blocage par un pare-feu. Lors de l’inspection des en-têtes de réponse, on constate que l’en-tête Server indique que l’application ASP.NET Core est traitée par Kestrel.

HTTP/1.1 200 OK
Date: Tue, 11 Oct 2016 16:22:23 GMT
Server: Kestrel
Keep-Alive: timeout=5, max=98
Connection: Keep-Alive
Transfer-Encoding: chunked

Afficher les journaux d’activité

Puisque l’application web utilisant Kestrel est gérée à l’aide de systemd, tous les événements et les processus sont consignés dans un journal centralisé. Toutefois, ce journal inclut toutes les entrées pour tous les services et les processus gérés par systemd. Pour afficher les éléments propres à kestrel-helloapp.service, utilisez la commande suivante :

sudo journalctl -fu kestrel-helloapp.service

Pour obtenir un filtrage supplémentaire, des options chronologiques, comme --since today, --until 1 hour ago ou une combinaison de ces options, peuvent réduire le nombre d’entrées retournées.

sudo journalctl -fu kestrel-helloapp.service --since "2016-10-18" --until "2016-10-18 04:00"

Protection des données

La pile de protection des données ASP.NET Core est utilisée par plusieurs intergiciels ASP.NET Core, notamment des intergiciels d’authentification (par exemple, l’intergiciel cookie) et les protections contre la falsification de requête intersites (CSRF, Cross Site Request Forgery). Même si les API de protection des données ne sont pas appelées par le code de l’utilisateur, la protection des données doit être configurée pour créer un magasin de clés de chiffrement persistantes. Si la protection des données n’est pas configurée, les clés sont conservées en mémoire et ignorées au redémarrage de l’application.

Si le Key Ring est stocké en mémoire, au redémarrage de l’application :

  • Tous les jetons d’authentification basés sur cookie sont invalidés.
  • Les utilisateurs doivent se reconnecter pour envoyer leur prochaine demande.
  • toutes les données protégées par le Key Ring ne peuvent plus être déchiffrées. Ceci peut inclure des jetons CSRF et des cookies TempData ASP.NET Core MVC.

Pour configurer la protection des données de façon à conserver et chiffrer le porte-clés (Key Ring), consultez :

Longs champs d'en-tête de demande

Les paramètres par défaut du serveur proxy limitent généralement les champs des en-têtes de demande à 4 ou 8 K en fonction de la plateforme. Une application peut nécessiter des champs de longueur supérieure à la valeur par défaut (par exemple, les applications qui utilisent Azure Active Directory). Si des champs de longueur supérieure sont nécessaires, les paramètres par défaut du serveur proxy doivent être ajustés. Les valeurs à appliquer dépendent du scénario. Pour plus d'informations, voir la documentation du serveur.

Avertissement

N’augmentez pas les valeurs par défaut des mémoires tampons de proxy à moins que ce ne soit nécessaire. Leur augmentation augmente le risque de dépassement de mémoire tampon (dépassement de capacité) et d’attaques par déni de service (DoS) par des utilisateurs malveillants.

Sécuriser l’application

Activer AppArmor

Linux Security Modules (LSM) est un framework qui fait partie du noyau Linux depuis Linux 2.6. LSM prend en charge différentes implémentations de modules de sécurité. AppArmor est un LSM qui implémente un système de contrôle d’accès obligatoire permettant de confiner le programme à un ensemble limité de ressources. Vérifiez qu’AppArmor est activé et configuré correctement.

Configurer le pare-feu

Fermez tous les ports externes qui ne sont pas en cours d’utilisation. Uncomplicated firewall (ufw) fournit un front-end pour iptables en assurant une interface de ligne de commande (CLI) afin de configurer le pare-feu.

Avertissement

Un pare-feu mal configuré bloque l’accès à l’ensemble du système. Faute d’avoir spécifié le port SSH approprié, vous ne pourrez pas accéder au système si vous utilisez SSH pour vous y connecter. Le numéro de port par défaut est 22. Pour plus d’informations, consultez la présentation d’ufw et le manuel.

Installez ufw et configurez-le de façon à autoriser le trafic sur les ports nécessaires.

sudo apt-get install ufw

sudo ufw allow 22/tcp
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp

sudo ufw enable

Sécuriser Nginx

Changer le nom de la réponse Nginx

Modifiez src/http/ngx_http_header_filter_module.c:

static char ngx_http_server_string[] = "Server: Web Server" CRLF;
static char ngx_http_server_full_string[] = "Server: Web Server" CRLF;

Configurer des options

Configurez le serveur avec les modules nécessaires supplémentaires. Pour renforcer l’application, vous pouvez utiliser un pare-feu d’application web tel que ModSecurity.

Configuration HTTPS

Configurer l’application pour les connexions locales sécurisées (HTTPS)

La commande dotnet run utilise le fichier Properties/launchSettings.json de l’application, qui configure l’application pour l’écoute sur les URL fournies par la propriété applicationUrl. Par exemple, https://localhost:5001;http://localhost:5000

Configurez l’application pour utiliser un certificat en développement pour la commande dotnet run ou l’environnement de développement (F5 ou Ctrl+F5 dans Visual Studio Code) en adoptant l’une des approches suivantes :

Configurer le proxy inverse pour les connexions clientes sécurisées (HTTPS)

Avertissement

La configuration de sécurité présentée dans cette section est une configuration générale qu’il convient d’utiliser comme point de départ pour plus de personnalisation. Nous ne pouvons pas fournir de support pour les outils, serveurs et systèmes d’exploitation tiers. L’utilisation de la configuration présentée dans cette section est à vos propres risques. Pour plus d’informations, accédez aux ressources suivantes :

  • Configurez le serveur pour qu’il écoute le trafic HTTPS sur le port 443 en spécifiant un certificat valide émis par une autorité de certification de confiance.

  • Renforcez la sécurité en appliquant certaines des pratiques mentionnées dans le fichier /etc/nginx/nginx.conf suivant.

  • L’exemple suivant ne configure pas le serveur pour rediriger les requêtes non sécurisées. Nous vous recommandons d’utiliser l’intergiciel de redirection HTTPS. Pour plus d’informations, consultez Appliquer HTTPS dans ASP.NET Core.

    Remarque

    Pour les environnements de développement où la configuration du serveur gère la redirection sécurisée à la place de l’intergiciel de redirection HTTPS, nous vous recommandons d’utiliser des redirections temporaires (302) plutôt que des redirections permanentes (301). La mise en cache des liens peut entraîner un comportement instable dans les environnements de développement.

  • L’ajout d’un en-tête Strict-Transport-Security (HSTS) garantit que toutes les demandes ultérieures du client s’effectuent par le biais du protocole HTTPS. Pour obtenir de l’aide sur la définition de l’en-tête Strict-Transport-Security, consultez Appliquer HTTPS dans ASP.NET Core.

  • Si HTTPS est désactivé à l’avenir, utilisez l’une des approches suivantes :

    • N’ajoutez pas l’en-tête HSTS.
    • Choisissez une valeur max-age courte.

Ajoutez le fichier de configuration /etc/nginx/proxy.conf :

proxy_redirect          off;
proxy_set_header        Host $host;
proxy_set_header        X-Real-IP $remote_addr;
proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header        X-Forwarded-Proto $scheme;
client_max_body_size    10m;
client_body_buffer_size 128k;
proxy_connect_timeout   90;
proxy_send_timeout      90;
proxy_read_timeout      90;
proxy_buffers           32 4k;

Remplacez le contenu du fichier de configuration /etc/nginx/nginx.conf par le fichier suivant. Dans l’exemple, les sections http et server figurent dans un même fichier de configuration.

http {
    include        /etc/nginx/proxy.conf;
    limit_req_zone $binary_remote_addr zone=one:10m rate=5r/s;
    server_tokens  off;

    sendfile on;
    # Adjust keepalive_timeout to the lowest possible value that makes sense 
    # for your use case.
    keepalive_timeout   29;
    client_body_timeout 10; client_header_timeout 10; send_timeout 10;

    upstream helloapp{
        server 127.0.0.1:5000;
    }

    server {
        listen                    443 ssl http2;
        listen                    [::]:443 ssl http2;
        server_name               example.com *.example.com;
        ssl_certificate           /etc/ssl/certs/testCert.crt;
        ssl_certificate_key       /etc/ssl/certs/testCert.key;
        ssl_session_timeout       1d;
        ssl_protocols             TLSv1.2 TLSv1.3;
        ssl_prefer_server_ciphers off;
        ssl_ciphers               ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;
        ssl_session_cache         shared:SSL:10m;
        ssl_session_tickets       off;
        ssl_stapling              off;

        add_header X-Frame-Options DENY;
        add_header X-Content-Type-Options nosniff;

        #Redirects all traffic
        location / {
            proxy_pass http://helloapp;
            limit_req  zone=one burst=10 nodelay;
        }
    }
}

Remarque

Les applications Blazor WebAssembly nécessitent une valeur de paramètre burst plus élevée pour prendre en charge le nombre plus élevé de requêtes effectuées par une application. Pour plus d’informations, consultez Héberger et déployer ASP.NET Core Blazor WebAssembly.

Remarque

L’exemple précédent désactive l’agrafage OCSP (Online Certificate Status Protocol). Si elle est activée, vérifiez que le certificat prend en charge la fonctionnalité. Pour plus d’informations et d’aide sur l’activation de l’OCSP, consultez les propriétés suivantes dans l’article Module ngx_http_ssl_module (documentation Nginx) :

  • ssl_stapling
  • ssl_stapling_file
  • ssl_stapling_responder
  • ssl_stapling_verify

Sécuriser Nginx contre le détournement de clic

Le détournement de clic, également appelé UI redress attack, est une attaque malveillante qui amène le visiteur d’un site web à cliquer sur un lien ou un bouton sur une page différente de celle qu’il est en train de visiter. Utilisez X-FRAME-OPTIONS pour sécuriser le site.

Pour atténuer les attaques par détournement de clic :

  1. Modifiez le fichier nginx.conf :

    sudo nano /etc/nginx/nginx.conf
    

    Ajoutez la ligne : add_header X-Frame-Options "SAMEORIGIN";

  2. Enregistrez le fichier.

  3. Redémarrez Nginx.

Détection de type MIME

Cet en-tête empêche la plupart des navigateurs de détourner le type MIME d’une réponse et de remplacer le type de contenu déclaré, car l’en-tête indique au navigateur qu’il ne doit pas substituer le type de contenu de la réponse. Avec l’option nosniff, si le serveur indique que le contenu est text/html, le navigateur l’affiche en tant que text/html.

  1. Modifiez le fichier nginx.conf :

    sudo nano /etc/nginx/nginx.conf
    

    Ajoutez la ligne : add_header X-Content-Type-Options "nosniff";

  2. Enregistrez le fichier.

  3. Redémarrez Nginx.

Suggestions Nginx supplémentaires

Après la mise à niveau de l’infrastructure partagée sur le serveur, redémarrez les applications ASP.NET Core hébergées par le serveur.

Ressources supplémentaires

Ce guide explique comment configurer un environnement ASP.NET Core prêt pour la production sur un serveur Ubuntu 16.04. Ces instructions fonctionnent normalement avec les versions d’Ubuntu plus récentes, mais elles n’ont pas fait l’objet de tests avec ces versions.

Pour plus d’informations sur les autres distributions Linux prises en charge par ASP.NET Core, consultez Prérequis pour .NET Core sur Linux.

Remarque

Pour Ubuntu 14.04,il est recommandé d’utiliser supervisord comme solution pour la surveillance du processus Kestrel. systemd n’est pas disponible sur Ubuntu 14.04. Pour obtenir des instructions pour Ubuntu 14.04, consultez la version précédente de cette rubrique.

Ce guide montre comment effectuer les opérations suivantes :

  • Placer une application ASP.NET Core existante derrière un serveur proxy inverse.
  • Configurer le serveur proxy inverse pour transférer les requêtes au serveur web Kestrel.
  • S’assurer que l’application web s’exécute au démarrage en tant que démon.
  • Configurer un outil de gestion des processus pour aider à redémarrer l’application web.

Prérequis

  • Accédez à un serveur Ubuntu 16.04 avec un compte d’utilisateur standard disposant de privilèges sudo.
  • Dernière version non disponible en préversion du runtime .NET installée sur le serveur.
  • Une application ASP.NET Core existante.

Puis, à n’importe quel moment après la mise à niveau de l’infrastructure partagée, redémarrez les applications ASP.NET Core hébergées par le serveur.

Publier et copier sur l’application

Configurez l’application pour un déploiement dépendant du framework.

Si l’application est exécutée localement dans l’environnement de développement et n’est pas configurée par le serveur pour établir des connexions HTTPS sécurisées, adoptez l’une des approches suivantes :

  • Configurez l’application pour gérer les connexions locales sécurisées. Pour plus d’informations, consultez la section Configuration HTTPS.

  • Configurez l’application pour qu’elle s’exécute au niveau du point de terminaison non sécurisé :

    • Désactivez l’intergiciel de redirection HTTPS dans l’environnement de développement (Program.cs) :

      if (!app.Environment.IsDevelopment())
      {
          app.UseHttpsRedirection();
      }
      

      Pour plus d’informations, consultez Utiliser plusieurs environnements dans ASP.NET Core.

    • Supprimez https://localhost:5001 (le cas échéant) de la propriété applicationUrl dans le fichier Properties/launchSettings.json.

Pour plus d’informations sur la configuration selon l’environnement, consultez Utiliser plusieurs environnements dans ASP.NET Core.

Exécutez dotnet publish à partir de l’environnement de développement pour empaqueter une application dans un répertoire (par exemple, bin/Release/{TARGET FRAMEWORK MONIKER}/publish, où l’espace réservé {TARGET FRAMEWORK MONIKER} est le moniker de framework cible/TFM) exécutable sur le serveur :

dotnet publish --configuration Release

L’application peut également être publiée en tant que déploiement autonome si vous préférez ne pas gérer le runtime .NET Core sur le serveur.

Copiez l’application ASP.NET Core sur le serveur à l’aide d’un outil qui s’intègre au flux de travail de l’organisation (par exemple, SCP, SFTP). Il est courant de placer les applications web sous le répertoire var (par exemple, var/www/helloapp).

Remarque

Dans un scénario de déploiement en production, un workflow d’intégration continue effectue le travail de publication de l’application et de copie des composants sur le serveur.

Testez l’application :

  1. À partir de la ligne de commande, exécutez l’application : dotnet <app_assembly>.dll.
  2. Dans un navigateur, accédez à http://<serveraddress>:<port> pour vérifier que l’application fonctionne sur Linux localement.

Configurer un serveur proxy inverse

Un proxy inverse est une configuration courante pour traiter les applications web dynamiques. Un proxy inverse met fin à la requête HTTP et la transfère à l’application ASP.NET Core.

Utiliser un serveur proxy inverse

Kestrel est idéal pour servir du contenu dynamique à partir d’ASP.NET Core. Toutefois, les fonctionnalités de service web ne sont pas aussi complètes que les serveurs tels qu’IIS, Apache ou Nginx. Un serveur proxy inverse peut décharger du travail tel que le traitement du contenu statique, la mise en cache des requêtes, la compression des requêtes et l’arrêt HTTPS à partir du serveur HTTP. Un serveur proxy inverse peut résider sur un ordinateur dédié ou peut être déployé à côté d’un serveur HTTP.

Pour les besoins de ce guide, nous utilisons une seule instance de Nginx. Elle s’exécute sur le même serveur, en plus du serveur HTTP. Selon les exigences, un paramétrage différent peut être choisi.

Les requêtes étant transférées par le proxy inverse, vous devez utiliser l’intergiciel des en-têtes transférés à partir du package Microsoft.AspNetCore.HttpOverrides. Le middleware met à jour le Request.Scheme, à l’aide de l’en-tête X-Forwarded-Proto, afin que les URI de redirection et d’autres stratégies de sécurité fonctionnent correctement.

Le middleware Forwarded Headers doit s’exécuter avant tout autre middleware. Cet ordre permet au middleware qui repose sur les informations des en-têtes transférés d’utiliser les valeurs d’en-tête pour le traitement. Pour exécuter le middleware Forwarded Headers après les middlewares Diagnostics et Error Handling, consultez Ordre du middleware Forwarded Headers.

Appelez la méthode UseForwardedHeaders en haut de Startup.Configure avant d’appeler d’autres intergiciels. Configurez le middleware pour transférer les en-têtes X-Forwarded-For et X-Forwarded-Proto :

using Microsoft.AspNetCore.HttpOverrides;

...

app.UseForwardedHeaders(new ForwardedHeadersOptions
{
    ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto
});

app.UseAuthentication();

Si aucune option ForwardedHeadersOptions n’est spécifiée au middleware, les en-têtes par défaut à transférer sont None.

Les serveurs proxy exécutés sur les adresses de bouclage (127.0.0.0/8, [::1]), notamment l’adresse localhost standard (127.0.0.1), sont approuvés par défaut. Si d’autres proxys ou réseaux approuvés au sein de l’organisation gèrent les requêtes entre Internet et le serveur web, ajoutez-les à la liste des KnownProxies ou des KnownNetworks avec ForwardedHeadersOptions. L’exemple suivant ajoute un serveur proxy approuvé avec l’adresse IP 10.0.0.100 au middleware des en-têtes transférés KnownProxies dans Startup.ConfigureServices :

using System.Net;

...

services.Configure<ForwardedHeadersOptions>(options =>
{
    options.KnownProxies.Add(IPAddress.Parse("10.0.0.100"));
});

Pour plus d’informations, consultez l’article Configurer ASP.NET Core pour l’utilisation de serveurs proxy et d’équilibreurs de charge.

Installer Nginx

Utilisez apt-get pour installer Nginx. Le programme d’installation crée un script d’initialisation systemd qui exécute Nginx en tant que démon au démarrage du système. Suivez les instructions d’installation pour Ubuntu sur le site Nginx : Les packages officiels Debian/Ubuntu.

Remarque

Si des modules Nginx facultatifs sont requis, il peut s’avérer nécessaire de configurer Nginx à partir de la source.

Comme il s’agit de l’installation initiale de Nginx, vous devez le démarrer explicitement en exécutant :

sudo service nginx start

Vérifiez qu’un navigateur affiche la page d’accueil par défaut de Nginx. La page d’accueil est accessible à l’adresse http://<server_IP_address>/index.nginx-debian.html.

Configurer Nginx

Pour configurer Nginx en tant que proxy inverse pour transférer les requêtes HTTP à votre application ASP.NET Core, modifiez /etc/nginx/sites-available/default. Ouvrez-le dans un éditeur de texte et remplacez le contenu par l’extrait de code suivant :

server {
    listen        80;
    server_name   example.com *.example.com;
    location / {
        proxy_pass         http://127.0.0.1:5000;
        proxy_http_version 1.1;
        proxy_set_header   Upgrade $http_upgrade;
        proxy_set_header   Connection keep-alive;
        proxy_set_header   Host $host;
        proxy_cache_bypass $http_upgrade;
        proxy_set_header   X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header   X-Forwarded-Proto $scheme;
    }
}

S’il s’agit d’une application SignalR ou Blazor Server, consultez Hébergement et mise à l’échelle de la production SignalR ASP.NET Core et Héberger et déployer des applications Blazor ASP.NET Core côté serveur, respectivement pour plus d’informations.

Si aucun server_name ne correspond, Nginx utilise le serveur par défaut. Si aucun serveur par défaut n’est défini, le premier serveur dans le fichier de configuration est le serveur par défaut. En guise de bonne pratique, ajoutez un serveur par défaut spécifique qui retourne un code d’état 444 dans votre fichier de configuration. Voici un exemple de configuration de serveur par défaut :

server {
    listen   80 default_server;
    # listen [::]:80 default_server deferred;
    return   444;
}

Avec les fichier de configuration et le serveur par défaut précédents, Nginx accepte le trafic public sur le port 80 avec un en-tête d’hôte example.com ou *.example.com. Les requêtes qui ne correspondent pas à ces hôtes ne sont pas transférées à Kestrel. Nginx transfère les requêtes correspondantes à Kestrel à l’adresse http://127.0.0.1:5000. Pour plus d’informations, consultez Comment nginx traite une requête. Pour changer le port/l’adresse IP de Kestrel, consultez Kestrel : configuration du point de terminaison.

Avertissement

La spécification d’une directive server_name incorrecte expose votre application à des failles de sécurité. Une liaison générique de sous-domaine (par exemple, *.example.com) ne présente pas ce risque de sécurité si vous contrôlez le domaine parent en entier (par opposition à *.com, qui est vulnérable). Pour plus d’informations, consultez RFC 9110 : Sémantique HTTP (Section 7.2 : Hôte et autorité).

Une fois la configuration de Nginx établie, exécutez sudo nginx -t pour vérifier la syntaxe des fichiers de configuration. Si le test de fichier de configuration réussit, forcez Nginx à appliquer les modifications en exécutant sudo nginx -s reload.

Pour exécuter directement l’application sur le serveur :

  1. Accédez au répertoire de l’application.
  2. Exécutez l’application : dotnet <app_assembly.dll>, où app_assembly.dll est le nom de fichier d’assembly de l’application.

Si l’application s’exécute sur le serveur, mais ne répond pas sur Internet, vérifiez le pare-feu du serveur et confirmez que le port 80 est ouvert. Si vous utilisez une machine virtuelle Azure Ubuntu, ajoutez une règle de groupe de sécurité réseau (NSG) qui autorise le trafic entrant sur le port 80. Il est inutile d’activer une règle de trafic sortant sur le port 80, car le trafic sortant est accordé automatiquement quand la règle de trafic entrant est activée.

Lorsque vous avez terminé de tester l’application, arrêtez l’application en appuyant sur Ctrl+C (Windows) ou +C (macOS) à l’invite de commandes.

Surveiller l’application

Le serveur est configuré pour transférer les requêtes faites à http://<serveraddress>:80 à l’application ASP.NET Core s’exécutant sur http://127.0.0.1:5000 à l’adresse Kestrel. Toutefois, Nginx n’est pas configuré pour gérer le processus Kestrel. systemd peut être utilisé pour créer un fichier de service afin de démarrer et de surveiller l’application web sous-jacente. systemd est un système d’initialisation qui fournit de nombreuses fonctionnalités puissantes pour démarrer, arrêter et gérer des processus.

Créer le fichier de service

Créez le fichier de définition de service :

sudo nano /etc/systemd/system/kestrel-helloapp.service

Voici un exemple de fichier de service pour l’application :

[Unit]
Description=Example .NET Web API App running on Ubuntu

[Service]
WorkingDirectory=/var/www/helloapp
ExecStart=/usr/bin/dotnet /var/www/helloapp/helloapp.dll
Restart=always
# Restart service after 10 seconds if the dotnet service crashes:
RestartSec=10
KillSignal=SIGINT
SyslogIdentifier=dotnet-example
User=www-data
Environment=ASPNETCORE_ENVIRONMENT=Production
Environment=DOTNET_PRINT_TELEMETRY_MESSAGE=false

[Install]
WantedBy=multi-user.target

Dans l’exemple précédent, l’utilisateur qui gère le service est spécifié par l’option User. L’utilisateur (www-data) doit exister et être le propriétaire légitime des fichiers de l’application.

Utilisez TimeoutStopSec pour configurer la durée d’attente de l’arrêt de l’application après la réception du signal d’interruption initial. Si l’application ne s’arrête pas pendant cette période, le signal SIGKILL est émis pour mettre fin à l’application. Indiquez la valeur en secondes sans unité (par exemple, 150), une valeur d’intervalle de temps (par exemple, 2min 30s) ou infinity pour désactiver le délai d’attente. Lé valeur de TimeoutStopSec prend la valeur par défaut de DefaultTimeoutStopSec dans le fichier de configuration du manager (systemd-system.conf, system.conf.d, systemd-user.conf, user.conf.d). Le délai d’expiration par défaut pour la plupart des distributions est de 90 secondes.

# The default value is 90 seconds for most distributions.
TimeoutStopSec=90

Linux possède un système de fichiers respectant la casse. La définition de ASPNETCORE_ENVIRONMENT sur Production entraîne la recherche du fichier de configuration appsettings.Production.json, et non de appsettings.production.json.

Certaines valeurs (par exemple, les chaînes de connexion SQL) doivent être placées dans une séquence d’échappement afin que les fournisseurs de configuration puissent lire les variables d’environnement. Utilisez la commande suivante pour générer une valeur correctement placée dans une séquence d’échappement en vue de son utilisation dans le fichier de configuration :

systemd-escape "<value-to-escape>"

Les séparateurs : (signe deux-points) ne sont pas pris en charge dans les noms de variables d’environnement. Utilisez un double trait de soulignement (__) à la place d’un signe deux-points. Le fournisseur de configuration de variables d’environnement convertit les doubles traits de soulignement en signes deux-points quand les variables d’environnement sont lues dans la configuration. Dans l’exemple suivant, la clé de chaîne de connexion ConnectionStrings:DefaultConnection est définie dans le fichier de définition de service en tant que ConnectionStrings__DefaultConnection :

Environment=ConnectionStrings__DefaultConnection={Connection String}

Enregistrez le fichier et activez le service.

sudo systemctl enable kestrel-helloapp.service

Démarrez le service et vérifiez qu’il s’exécute.

sudo systemctl start kestrel-helloapp.service
sudo systemctl status kestrel-helloapp.service

◝ kestrel-helloapp.service - Example .NET Web API App running on Ubuntu
    Loaded: loaded (/etc/systemd/system/kestrel-helloapp.service; enabled)
    Active: active (running) since Thu 2016-10-18 04:09:35 NZDT; 35s ago
Main PID: 9021 (dotnet)
    CGroup: /system.slice/kestrel-helloapp.service
            └─9021 /usr/local/bin/dotnet /var/www/helloapp/helloapp.dll

Le proxy inverse étant configuré et Kestrel étant géré via systemd, l’application web est maintenant entièrement configurée et accessible à partir d’un navigateur sur l’ordinateur local à l’adresse http://localhost. Elle est également accessible à partir d’un ordinateur distant, sauf en cas de blocage par un pare-feu. Lors de l’inspection des en-têtes de réponse, on constate que l’en-tête Server indique que l’application ASP.NET Core est traitée par Kestrel.

HTTP/1.1 200 OK
Date: Tue, 11 Oct 2016 16:22:23 GMT
Server: Kestrel
Keep-Alive: timeout=5, max=98
Connection: Keep-Alive
Transfer-Encoding: chunked

Afficher les journaux d’activité

Puisque l’application web utilisant Kestrel est gérée à l’aide de systemd, tous les événements et les processus sont consignés dans un journal centralisé. Toutefois, ce journal inclut toutes les entrées pour tous les services et les processus gérés par systemd. Pour afficher les éléments propres à kestrel-helloapp.service, utilisez la commande suivante :

sudo journalctl -fu kestrel-helloapp.service

Pour obtenir un filtrage supplémentaire, des options chronologiques, comme --since today, --until 1 hour ago ou une combinaison de ces options, peuvent réduire le nombre d’entrées retournées.

sudo journalctl -fu kestrel-helloapp.service --since "2016-10-18" --until "2016-10-18 04:00"

Protection des données

La pile de protection des données ASP.NET Core est utilisée par plusieurs intergiciels ASP.NET Core, notamment des intergiciels d’authentification (par exemple, l’intergiciel cookie) et les protections contre la falsification de requête intersites (CSRF, Cross Site Request Forgery). Même si les API de protection des données ne sont pas appelées par le code de l’utilisateur, la protection des données doit être configurée pour créer un magasin de clés de chiffrement persistantes. Si la protection des données n’est pas configurée, les clés sont conservées en mémoire et ignorées au redémarrage de l’application.

Si le Key Ring est stocké en mémoire, au redémarrage de l’application :

  • Tous les jetons d’authentification basés sur cookie sont invalidés.
  • Les utilisateurs doivent se reconnecter pour envoyer leur prochaine demande.
  • toutes les données protégées par le Key Ring ne peuvent plus être déchiffrées. Ceci peut inclure des jetons CSRF et des cookies TempData ASP.NET Core MVC.

Pour configurer la protection des données de façon à conserver et chiffrer le porte-clés (Key Ring), consultez :

Longs champs d'en-tête de demande

Les paramètres par défaut du serveur proxy limitent généralement les champs des en-têtes de demande à 4 ou 8 K en fonction de la plateforme. Une application peut nécessiter des champs de longueur supérieure à la valeur par défaut (par exemple, les applications qui utilisent Azure Active Directory). Si des champs de longueur supérieure sont nécessaires, les paramètres par défaut du serveur proxy doivent être ajustés. Les valeurs à appliquer dépendent du scénario. Pour plus d'informations, voir la documentation du serveur.

Avertissement

N’augmentez pas les valeurs par défaut des mémoires tampons de proxy à moins que ce ne soit nécessaire. Leur augmentation augmente le risque de dépassement de mémoire tampon (dépassement de capacité) et d’attaques par déni de service (DoS) par des utilisateurs malveillants.

Sécuriser l’application

Activer AppArmor

Linux Security Modules (LSM) est un framework qui fait partie du noyau Linux depuis Linux 2.6. LSM prend en charge différentes implémentations de modules de sécurité. AppArmor est un LSM qui implémente un système de contrôle d’accès obligatoire permettant de confiner le programme à un ensemble limité de ressources. Vérifiez qu’AppArmor est activé et configuré correctement.

Configurer le pare-feu

Fermez tous les ports externes qui ne sont pas en cours d’utilisation. Uncomplicated firewall (ufw) fournit un front-end pour iptables en assurant une interface de ligne de commande (CLI) afin de configurer le pare-feu.

Avertissement

Un pare-feu mal configuré bloque l’accès à l’ensemble du système. Faute d’avoir spécifié le port SSH approprié, vous ne pourrez pas accéder au système si vous utilisez SSH pour vous y connecter. Le numéro de port par défaut est 22. Pour plus d’informations, consultez la présentation d’ufw et le manuel.

Installez ufw et configurez-le de façon à autoriser le trafic sur les ports nécessaires.

sudo apt-get install ufw

sudo ufw allow 22/tcp
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp

sudo ufw enable

Sécuriser Nginx

Changer le nom de la réponse Nginx

Modifiez src/http/ngx_http_header_filter_module.c:

static char ngx_http_server_string[] = "Server: Web Server" CRLF;
static char ngx_http_server_full_string[] = "Server: Web Server" CRLF;

Configurer des options

Configurez le serveur avec les modules nécessaires supplémentaires. Pour renforcer l’application, vous pouvez utiliser un pare-feu d’application web tel que ModSecurity.

Configuration HTTPS

Configurer l’application pour les connexions locales sécurisées (HTTPS)

La commande dotnet run utilise le fichier Properties/launchSettings.json de l’application, qui configure l’application pour l’écoute sur les URL fournies par la propriété applicationUrl. Par exemple, https://localhost:5001;http://localhost:5000

Configurez l’application pour utiliser un certificat en développement pour la commande dotnet run ou l’environnement de développement (F5 ou Ctrl+F5 dans Visual Studio Code) en adoptant l’une des approches suivantes :

Configurer le proxy inverse pour les connexions clientes sécurisées (HTTPS)

Avertissement

La configuration de sécurité présentée dans cette section est une configuration générale qu’il convient d’utiliser comme point de départ pour plus de personnalisation. Nous ne pouvons pas fournir de support pour les outils, serveurs et systèmes d’exploitation tiers. L’utilisation de la configuration présentée dans cette section est à vos propres risques. Pour plus d’informations, accédez aux ressources suivantes :

  • Configurez le serveur pour qu’il écoute le trafic HTTPS sur le port 443 en spécifiant un certificat valide émis par une autorité de certification de confiance.

  • Renforcez la sécurité en appliquant certaines des pratiques mentionnées dans le fichier /etc/nginx/nginx.conf suivant.

  • L’exemple suivant ne configure pas le serveur pour rediriger les requêtes non sécurisées. Nous vous recommandons d’utiliser l’intergiciel de redirection HTTPS. Pour plus d’informations, consultez Appliquer HTTPS dans ASP.NET Core.

    Remarque

    Pour les environnements de développement où la configuration du serveur gère la redirection sécurisée à la place de l’intergiciel de redirection HTTPS, nous vous recommandons d’utiliser des redirections temporaires (302) plutôt que des redirections permanentes (301). La mise en cache des liens peut entraîner un comportement instable dans les environnements de développement.

  • L’ajout d’un en-tête Strict-Transport-Security (HSTS) garantit que toutes les demandes ultérieures du client s’effectuent par le biais du protocole HTTPS. Pour obtenir de l’aide sur la définition de l’en-tête Strict-Transport-Security, consultez Appliquer HTTPS dans ASP.NET Core.

  • Si HTTPS est désactivé à l’avenir, utilisez l’une des approches suivantes :

    • N’ajoutez pas l’en-tête HSTS.
    • Choisissez une valeur max-age courte.

Ajoutez le fichier de configuration /etc/nginx/proxy.conf :

proxy_redirect          off;
proxy_set_header        Host $host;
proxy_set_header        X-Real-IP $remote_addr;
proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header        X-Forwarded-Proto $scheme;
client_max_body_size    10m;
client_body_buffer_size 128k;
proxy_connect_timeout   90;
proxy_send_timeout      90;
proxy_read_timeout      90;
proxy_buffers           32 4k;

Remplacez le contenu du fichier de configuration /etc/nginx/nginx.conf par le fichier suivant. Dans l’exemple, les sections http et server figurent dans un même fichier de configuration.

http {
    include        /etc/nginx/proxy.conf;
    limit_req_zone $binary_remote_addr zone=one:10m rate=5r/s;
    server_tokens  off;

    sendfile on;
    # Adjust keepalive_timeout to the lowest possible value that makes sense 
    # for your use case.
    keepalive_timeout   29;
    client_body_timeout 10; client_header_timeout 10; send_timeout 10;

    upstream helloapp{
        server 127.0.0.1:5000;
    }

    server {
        listen                    443 ssl http2;
        listen                    [::]:443 ssl http2;
        server_name               example.com *.example.com;
        ssl_certificate           /etc/ssl/certs/testCert.crt;
        ssl_certificate_key       /etc/ssl/certs/testCert.key;
        ssl_session_timeout       1d;
        ssl_protocols             TLSv1.2 TLSv1.3;
        ssl_prefer_server_ciphers off;
        ssl_ciphers               ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;
        ssl_session_cache         shared:SSL:10m;
        ssl_session_tickets       off;
        ssl_stapling              off;

        add_header X-Frame-Options DENY;
        add_header X-Content-Type-Options nosniff;

        #Redirects all traffic
        location / {
            proxy_pass http://helloapp;
            limit_req  zone=one burst=10 nodelay;
        }
    }
}

Remarque

Les applications Blazor WebAssembly nécessitent une valeur de paramètre burst plus élevée pour prendre en charge le nombre plus élevé de requêtes effectuées par une application. Pour plus d’informations, consultez Héberger et déployer ASP.NET Core Blazor WebAssembly.

Remarque

L’exemple précédent désactive l’agrafage OCSP (Online Certificate Status Protocol). Si elle est activée, vérifiez que le certificat prend en charge la fonctionnalité. Pour plus d’informations et d’aide sur l’activation de l’OCSP, consultez les propriétés suivantes dans l’article Module ngx_http_ssl_module (documentation Nginx) :

  • ssl_stapling
  • ssl_stapling_file
  • ssl_stapling_responder
  • ssl_stapling_verify

Sécuriser Nginx contre le détournement de clic

Le détournement de clic, également appelé UI redress attack, est une attaque malveillante qui amène le visiteur d’un site web à cliquer sur un lien ou un bouton sur une page différente de celle qu’il est en train de visiter. Utilisez X-FRAME-OPTIONS pour sécuriser le site.

Pour atténuer les attaques par détournement de clic :

  1. Modifiez le fichier nginx.conf :

    sudo nano /etc/nginx/nginx.conf
    

    Ajoutez la ligne : add_header X-Frame-Options "SAMEORIGIN";

  2. Enregistrez le fichier.

  3. Redémarrez Nginx.

Détection de type MIME

Cet en-tête empêche la plupart des navigateurs de détourner le type MIME d’une réponse et de remplacer le type de contenu déclaré, car l’en-tête indique au navigateur qu’il ne doit pas substituer le type de contenu de la réponse. Avec l’option nosniff, si le serveur indique que le contenu est text/html, le navigateur l’affiche en tant que text/html.

  1. Modifiez le fichier nginx.conf :

    sudo nano /etc/nginx/nginx.conf
    

    Ajoutez la ligne : add_header X-Content-Type-Options "nosniff";

  2. Enregistrez le fichier.

  3. Redémarrez Nginx.

Suggestions Nginx supplémentaires

Après la mise à niveau de l’infrastructure partagée sur le serveur, redémarrez les applications ASP.NET Core hébergées par le serveur.

Ressources supplémentaires