Comment configurer Nginx avec le support HTTP / 2 sur Ubuntu 16.04

introduction

NGINX est un serveur Web open source rapide et fiable. Il a gagné sa popularité en raison de son faible encombrement mémoire, de sa grande évolutivité, de sa facilité de configuration et de la prise en charge de la grande majorité des protocoles.

L'un des protocoles pris en charge est le relativement nouveau HTTP / 2, publié en mai 2015. Le principal avantage de HTTP / 2 est sa grande vitesse de transfert pour les sites Web riches en contenu.

Ce didacticiel vous aidera à configurer un serveur Nginx rapide et sécurisé prenant en charge HTTP / 2.

Conditions préalables

Avant de commencer, nous aurons besoin de quelques choses:

C'est tout. Si vous avez tout ce qui est énuméré ci-dessus, vous êtes prêt à partir.

Différences entre HTTP 1.1 et HTTP / 2

HTTP/2 is a new version of the Hypertext Transport Protocol, which is used on the Web to deliver pages from server to browser. HTTP/2 is the first major update of HTTP in almost two decades: HTTP1.1 was introduced to the public back in 1999 when webpages were usually just a single HTML file with inline CSS stylesheet. L'Internet a radicalement changé depuis lors, et maintenant nous sommes confrontés aux limites de HTTP 1.1 - le protocole limite les vitesses de transfert potentielles pour la plupart des sites Web modernes car il télécharge des parties d'une page dans une file d'attente (la partie précédente doit être téléchargée complètement avant le téléchargement de la partie suivante commence), et une page Web moderne moyenne nécessite environ 100 requêtes à télécharger (chaque requête est une image, un fichier js, un fichier css, etc.).

HTTP/2 solves this problem because it brings a few fundamental changes:

  • Toutes les demandes sont téléchargées en parallèle, pas dans une file d'attente

  • Les en-têtes HTTP sont compressés

  • Les pages sont transférées sous forme de fichier binaire, pas sous forme de fichier texte, ce qui est plus efficace

  • Les serveurs peuvent «pousser» les données même sans la demande de l'utilisateur, ce qui améliore la vitesse de traitement des utilisateurs avec une latence élevée.

Même si HTTP / 2 ne nécessite pas de cryptage, les développeurs des deux navigateurs les plus répandus, Google Chrome et Mozilla Firefox, ont déclaré que, pour des raisons de sécurité, ils ne prendraient en charge HTTP / 2 que pour les connexions HTTPS. Par conséquent, si vous décidez de configurer des serveurs prenant en charge HTTP / 2, vous devez également les sécuriser avec HTTPS.

[[step-1 -—- Installing-the-latest-version-of-nginx]] == Étape 1 - Installation de la dernière version de Nginx

La prise en charge du protocole HTTP / 2 a été introduite dans Nginx 1.9.5. Heureusement, le référentiel par défaut dans Ubuntu 16.04 contient une version supérieure à celle-ci, nous n’avons donc pas besoin d’ajouter de référentiel tiers.

Commencez par mettre à jour la liste des paquets disponibles dans le système de conditionnement d’apt:

sudo apt-get update

Ensuite, installez Nginx:

sudo apt-get install nginx

Une fois le processus d'installation terminé, vous pouvez vérifier la version de Nginx en tapant:

sudo nginx -v

La sortie devrait ressembler à ceci:

Sortie de sudo nginx -v

nginx version: nginx/1.10.0 (Ubuntu)

Au cours des prochaines étapes, nous modifierons les fichiers de configuration Nginx. Chaque étape changera une option de configuration Nginx. Nous allons tester la syntaxe du fichier de configuration en cours de route. Enfin, nous allons vérifier que Nginx prend en charge HTTP / 2 et apporter quelques modifications pour optimiser les performances.

[[step-2 -—- changer-le-port-d'écoute-et-activer-http-2]] == Étape 2 - Changer le port d'écoute et activer HTTP / 2

Le premier changement que nous apporterons sera de changer le port d'écoute de80 à443.

Ouvrons le fichier de configuration:

sudo nano /etc/nginx/sites-available/default

Par défaut, Nginx est configuré pour écouter le port 80, qui est le port HTTP standard:

/etc/nginx/sites-available/default

listen 80 default_server;
listen [::]:80 default_server;

Comme vous pouvez le voir, nous avons deux variableslisten différentes. Le premier concerne toutes les connexions IPv4. Le second concerne les connexions IPv6. Nous allons activer le cryptage pour les deux.

Modifiez le port d'écoute en443, qui est utilisé par le protocole HTTPS:

/etc/nginx/sites-available/default

listen 443 ssl http2 default_server;
listen [::]:443 ssl http2 default_server;

Notez qu'en plus dessl, nous avons également ajoutéhttp2 à la ligne. Cette variable indique à Nginx d'utiliser HTTP / 2 avec les navigateurs pris en charge.

[[step-3 -—- changer-le-nom-du-serveur]] == Étape 3 - Changer le nom du serveur

Nous utilisons l'entréeserver_name pour spécifier quel domaine doit être associé au fichier de configuration. Recherchez l'entréeserver_name dans le fichier de configuration.

Par défaut,server_name est défini sur_ (trait de soulignement), ce qui signifie que le fichier de configuration est responsable de toutes les demandes entrantes. Remplacez_ par votre domaine actuel, comme ceci:

/etc/nginx/sites-available/default

server_name example.com;

Enregistrez le fichier de configuration et éditez l’éditeur de texte.

Chaque fois que vous apportez des modifications aux fichiers de configuration Nginx, vous devez vérifier la configuration pour rechercher des erreurs de syntaxe, comme suit:

sudo nginx -t

Si la syntaxe est sans erreur, vous verrez le résultat suivant:

Sortie de sudo nginx -t

nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

[[step-4-— add-the-ssl-certificates]] == Étape 4 - Ajout des certificats SSL

Ensuite, vous devez configurer Nginx pour utiliser votre certificat SSL. Si vous ne savez pas ce qu'est un certificat SSL ou n'en avez pas actuellement, veuillez suivre l'un des didacticiels de la section Conditions préalables de cet article.

Créez un répertoire pour stocker vos certificats SSL dans le répertoire de configuration Nginx:

sudo mkdir /etc/nginx/ssl

Copiez votre certificat et la clé privée à cet emplacement. Nous allons également renommer les fichiers pour indiquer le domaine auquel ils sont associés. Cela vous sera utile à l’avenir, lorsque vous aurez plus d’un domaine associé à ce serveur. Remplacezexample.com par votre nom d'hôte actuel:

sudo cp /path/to/your/certificate.crt /etc/nginx/ssl/example.com.crt
sudo cp /path/to/your/private.key /etc/nginx/ssl/example.com.key

Maintenant, ouvrons à nouveau notre fichier de configuration et configurons SSL.

sudo nano /etc/nginx/sites-available/default

Sur les nouvelles lignes à l'intérieur du blocserver, définissez l'emplacement de vos certificats:

/etc/nginx/sites-available/default

ssl_certificate /etc/nginx/ssl/example.com.crt;
ssl_certificate_key /etc/nginx/ssl/example.com.key;

Enregistrez le fichier et quittez l'éditeur de texte.

[[step-5 -—- avoid-old-cipher-suites]] == Étape 5 - Éviter les anciennes suites de chiffrement

HTTP/2 has a huge blacklist of old and insecure ciphers, so we must avoid them. Les suites de chiffrement sont un ensemble d’algorithmes de chiffrement qui décrivent comment les données transférées doivent être chiffrées.

Nous allons utiliser un ensemble de chiffrement très populaire, dont la sécurité a été approuvée par des géants de l'Internet tels que CloudFlare. Il n'autorise pas l'utilisation du cryptage MD5 (connu depuis 1996 comme non sécurisé, mais malgré cela, son utilisation est répandue, même à ce jour).

Ouvrez le fichier de configuration suivant:

sudo nano /etc/nginx/nginx.conf

Ajoutez cette ligne aprèsssl_prefer_server_ciphers on;.

/etc/nginx/nginx.conf

ssl_ciphers EECDH+CHACHA20:EECDH+AES128:RSA+AES128:EECDH+AES256:RSA+AES256:EECDH+3DES:RSA+3DES:!MD5;

Enregistrez le fichier et quittez l'éditeur de texte.

Encore une fois, vérifiez la configuration pour les erreurs de syntaxe:

sudo nginx -t

[[step-6 -—- growth-key-exchange-security]] == Étape 6 - Augmentation de la sécurité d'échange de clés

La première étape de l’établissement d’une connexion sécurisée est l’échange des clés privées entre le serveur et le client. Le problème est que, jusqu'à ce stade, la connexion entre eux n'est pas cryptée - ce qui signifie que le transfert de données est visible par tout tiers. C'est pourquoi nous avons besoin de l'algorithme Diffie – Hellman – Merkle. Les détails techniques sur son fonctionnement sont une question compliquée qui ne peut pas être expliquée en un mot, mais si vous êtes vraiment intéressé par les détails, vous pouvez regarderthis YouTube video.

Par défaut, Nginx utilise une clé DHE (Ephemeral Diffie-Hellman) de 1028 bits, qui est relativement facile à déchiffrer. Pour assurer une sécurité maximale, nous devons créer notre propre clé DHE, plus sécurisée.

Pour ce faire, lancez la commande suivante:

sudo openssl dhparam -out /etc/nginx/ssl/dhparam.pem 2048

[.note] # Gardez à l'esprit que nous devons générer des paramètres DH dans le même dossier que nos certificats SSL. Dans ce didacticiel, les certificats sont situés dans/etc/nginx/ssl/. La raison en est que Nginx recherche toujours la clé DHE fournie par l'utilisateur dans le dossier des certificats et l'utilise si elle existe.
#

La variable après le chemin du fichier (dans notre cas, c'est2048) spécifie la longueur de la clé. Une clé d'une longueur de 2048 bits est suffisamment sécurisée etrecommended by the Mozilla Foundation, mais si vous recherchez encore plus de cryptage, vous pouvez la changer en4096.

Le processus de génération prendra environ 5 minutes.

Une fois terminé, rouvrez le fichier de configuration par défaut de Nginx:

sudo nano /etc/nginx/sites-available/default

Sur une nouvelle ligne à l'intérieur du blocserver, définissez l'emplacement de votre clé DHE personnalisée:

/etc/nginx/sites-available/default

ssl_dhparam  /etc/nginx/ssl/dhparam.pem;

[[step-7 -—- redirecting-all-http-request-to-https]] == Étape 7 - Redirection de toutes les requêtes HTTP vers HTTPS

Étant donné que nous souhaitons servir le contenu via HTTPS uniquement, nous devrions indiquer à Nginx ce qu’il devrait faire si le serveur reçoit une requête HTTP.

Au bas de notre fichier, nous allons créer un nouveau bloc serveur pour rediriger toutes les demandes HTTP vers HTTPS (veillez à remplacer le nom du serveur par votre nom de domaine actuel):

/etc/nginx/sites-available/default

server {
       listen         80;
       listen    [::]:80;
       server_name    example.com;
       return         301 https://$server_name$request_uri;
}

Enregistrez le fichier et quittez le fichier de configuration.

Vérifiez la configuration pour les erreurs de syntaxe:

sudo nginx -t

[[step-8 -—- reloading-nginx]] == Étape 8 - Rechargement de Nginx

C’est tout pour toutes les modifications de la configuration de Nginx. Comme nous avons vérifié les erreurs de syntaxe à chaque modification, vous devriez être prêt à redémarrer Nginx et à tester vos modifications.

Pour résumer, en ignorant les lignes commentées, votre fichier de configuration devrait maintenant ressembler à ceci:

/etc/nginx/sites-available/default

server {
        listen 443 ssl http2 default_server;
        listen [::]:443 ssl http2 default_server;

        root /var/www/html;

        index index.html index.htm index.nginx-debian.html;

        server_name example.com;

        location / {
                try_files $uri $uri/ =404;
        }

        ssl_certificate /etc/nginx/ssl/example.com.crt;
        ssl_certificate_key /etc/nginx/ssl/example.com.key;
        ssl_dhparam /etc/nginx/ssl/dhparam.pem;
}


server {
       listen         80;
       listen    [::]:80;
       server_name    example.com;
       return         301 https://$server_name$request_uri;
}

Pour appliquer les modifications, redémarrez le serveur Nginx.

sudo systemctl restart nginx

[[step-9 -—- verifying-the-changes]] == Étape 9 - Vérification des modifications

Vérifions que notre serveur est opérationnel. Ouvrez votre navigateur Web et accédez à votre domaine (remplacezexample.com par votre nom de domaine réel):

example.com

Si tout a été configuré correctement, vous devriez être automatiquement redirigé vers HTTPS. Maintenant, vérifions que HTTP / 2 fonctionne: ouvrez les outils de développement Chrome (ViewDeveloperDeveloper Tools) et rechargez la page (ViewReload This Page). Ensuite, accédez à l'ongletNetwork, cliquez sur la ligne d'en-tête du tableau qui commence parName, cliquez dessus avec le bouton droit de la souris et sélectionnez l'optionProtocol.

Vous devriez maintenant voirh2 (qui signifie HTTP / 2) dans une nouvelle colonne pour votre site Web servant du contenu HTTP / 2.

Chrome Developer Tools HTTP/2 check

À ce stade, notre serveur est prêt à servir le contenu via le protocole HTTP / 2, mais il reste certaines choses à faire pour préparer le serveur à être utilisé en production.

[[step-10 -—- optimizing-nginx-for-best-performance]] == Étape 10 - Optimiser Nginx pour obtenir les meilleures performances

Dans cette étape, nous allons ajuster le fichier de configuration principal de Nginx pour optimiser les performances et la sécurité.

Tout d'abord, ouvronsnginx.conf en tapant ce qui suit dans la console:

sudo nano /etc/nginx/nginx.conf

Activation de la mise en cache des informations d'identification de connexion

Par rapport à HTTP, le protocole HTTPS prend relativement plus de temps pour établir la connexion initiale entre le serveur et l'utilisateur. Pour minimiser cette différence de vitesse de chargement des pages, nous allons activer la mise en cache des informations d'identification de connexion. Cela signifie qu'au lieu de créer une nouvelle session sur chaque page demandée, le serveur utilisera plutôt une version en cache des informations d'identification.

Pour activer la mise en cache de session, ajoutez ces lignes à la fin du blochttp de votre fichiernginx.conf:

/etc/nginx/nginx.conf

ssl_session_cache shared:SSL:5m;
ssl_session_timeout 1h;

ssl_session_cache spécifie la taille du cache qui contiendra les informations de session. 1 Mo de celui-ci peut stocker des informations pour environ 4000 sessions. La valeur par défaut de 5 Mo sera plus que suffisante pour la plupart des utilisateurs, mais si vous vous attendez à un trafic très important, vous pouvez augmenter cette valeur en conséquence.

ssl_session_timeout limite la durée pendant laquelle des sessions particulières sont stockées dans le cache. Cette valeur ne doit pas être trop grande (plus d’une heure), mais définir une valeur trop basse est également inutile.

Activation de la sécurité du transport strict HTTP (HSTS)

Même si nous avons déjà redirigé toutes les requêtes HTTP habituelles vers HTTPS dans notre fichier de configuration Nginx, nous devons également activer HTTP Strict Transport Security pour éviter de devoir effectuer ces redirections en premier lieu.

Si le navigateur trouve un en-tête HSTS, il n'essaiera pas de se connecter au serveur via HTTP de nouveau pour la période donnée. Quoi qu’il en soit, il échangera des données en utilisant uniquement une connexion HTTPS chiffrée. Cet en-tête devrait également nous protéger des attaques de rétrogradation de protocole.

Ajoutez cette ligne dansnginx.conf:

/etc/nginx/nginx.conf

add_header Strict-Transport-Security "max-age=15768000" always;

Lemax-age est défini en secondes. 15768000 secondes équivalent à 6 mois.

Par défaut, cet en-tête n'est pas ajouté aux demandes de sous-domaine. Si vous avez des sous-domaines et que vous souhaitez que HSTS s'applique à tous, vous devez ajouter la variableincludeSubDomains à la fin de la ligne, comme ceci:

/etc/nginx/nginx.conf

add_header Strict-Transport-Security "max-age=15768000; includeSubDomains" always;

Enregistrez le fichier et quittez l'éditeur de texte.

Encore une fois, vérifiez la configuration pour les erreurs de syntaxe:

sudo nginx -t

Enfin, redémarrez le serveur Nginx pour appliquer les modifications.

sudo systemctl restart nginx

Conclusion

Votre serveur Nginx sert maintenant des pages HTTP / 2. Si vous souhaitez tester la force de votre connexion SSL, veuillez visiterQualys SSL Lab et lancer un test sur votre serveur. Si tout est configuré correctement, vous devriez obtenir une marque A + pour la sécurité.