Installer NginX mainline sous Ubuntu Server

Une faille dans le traitement de certaines requêtes HTTP/2 peut faire consommer des ressources excessives à NginX. Ubuntu a publié des correctifs pour ses paquets, y compris pour des versions amont antérieures à 1.29.8. Ce retour d’expérience sur Apollo explique comment vérifier le paquet installé et présente, en option, la migration vers le dépôt officiel NginX mainline.

Le symptôme : un serveur qui tombe sans raison apparente

En ce début de semaine, skyminds.net était indisponible au petit matin, deux jours de suite. C’est exceptionnellement rare : la configuration du serveur dédié OVH Apollo est stable et n’est jamais modifiée sur un coup de tête.

Après quelques heures à éplucher les logs et le statut des services, le constat était clair : des requêtes épuisaient les workers NginX à une vitesse anormale, sans pic de trafic visible côté Cloudflare ni signe d’attaque volumétrique classique. Le coupable n’était donc pas une simple charge excessive, mais un mécanisme bien plus sournois.

Kinsta: Premium Managed WordPress hosting

La cause : la faille HTTP/2 Bomb

L’avis de sécurité Ubuntu décrit un défaut de traitement de certains en-têtes de cookies dans l’implémentation HTTP/2 de NginX. Une requête réseau spécialement conçue peut entraîner une consommation excessive de ressources et un déni de service. Vérifiez le statut du paquet correspondant à votre distribution plutôt que de déduire l’exposition du seul numéro de version amont.

Ubuntu référence CVE-2026-49975 pour ses paquets NginX et indique que le correctif amont est arrivé avec NginX 1.29.8 et la directive max_headers. Le même identifiant apparaît aussi dans les avis Apache ; il ne faut donc pas le présenter comme le nom générique d’une attaque touchant tous les serveurs HTTP/2.

Vérifier le correctif fourni par Ubuntu

Le correctif amont de NginX est apparu dans la version 1.29.8 avec la directive max_headers, dont la valeur par défaut est 1000. Les distributions peuvent rétroporter un correctif dans une version amont plus ancienne : le numéro de version seul ne permet donc pas de savoir si le paquet est corrigé.

Ubuntu a rétroporté le correctif dans ses paquets : pour CVE-2026-49975, l’avis USN-8398-3 donne notamment 1.28.3-2ubuntu1.5 pour Ubuntu 26.04, 1.24.0-2ubuntu7.12 pour 24.04 et 1.18.0-6ubuntu14.15 pour 22.04. Installez les mises à jour de sécurité de votre version et vérifiez la révision complète du paquet avec dpkg-query -W -f='${Version}\n' nginx. Passer au dépôt NginX mainline est un choix de gestion distinct, pas une condition pour obtenir ce correctif Ubuntu.

Migration facultative : sauvegarder la configuration existante

Si vous choisissez de migrer d’Ubuntu vers le dépôt NginX mainline, cette opération remplacera le paquet nginx et peut supprimer des paquets de modules tiers. Avant cette migration facultative, sauvegardez la configuration :

sudo cp -a /etc/nginx /etc/nginx.bak-$(date +%F)Langage du code : JavaScript (javascript)

Cette copie permet de revenir en arrière instantanément en cas de souci, simplement en restaurant le dossier et en réinstallant les paquets Ubuntu d’origine.

Étape 1 : auditer et neutraliser les modules NginX tiers existants

Ubuntu packages les modules NginX différemment du dépôt officiel : plusieurs fonctionnalités sont fournies par des paquets séparés (libnginx-mod-*), alors que le paquet mainline les regroupe ou les omet selon les cas. On fait d’abord un état des lieux des modules réellement chargés :

ls -lah /etc/nginx/modules-enabled/
total 28K
drwxr-xr-x 2 root root 4.0K Jun  9 06:42 .
drwxr-xr-x 10 root root 4.0K Jun  9 06:42 ..
lrwxrwxrwx 1 root root 62 Apr 25 10:45 50-mod-http-brotli-filter.conf -> /usr/share/nginx/modules-available/mod-http-brotli-filter.conf
lrwxrwxrwx 1 root root 62 Apr 25 10:45 50-mod-http-brotli-static.conf -> /usr/share/nginx/modules-available/mod-http-brotli-static.conf
lrwxrwxrwx 1 root root 54 Sep  3  2023 50-mod-http-geoip.conf -> /usr/share/nginx/modules-available/mod-http-geoip.conf
lrwxrwxrwx 1 root root 55 Apr 23 18:38 50-mod-http-geoip2.conf -> /usr/share/nginx/modules-available/mod-http-geoip2.conf
lrwxrwxrwx 1 root root 68 Dec 17  2024 50-mod-http-headers-more-filter.conf -> /usr/share/nginx/modules-available/mod-http-headers-more-filter.conf
lrwxrwxrwx 1 root root 61 Sep  3  2023 50-mod-http-image-filter.conf -> /usr/share/nginx/modules-available/mod-http-image-filter.conf
lrwxrwxrwx 1 root root 60 Sep  3  2023 50-mod-http-xslt-filter.conf -> /usr/share/nginx/modules-available/mod-http-xslt-filter.conf
lrwxrwxrwx 1 root root 48 Sep  3  2023 50-mod-mail.conf -> /usr/share/nginx/modules-available/mod-mail.conf
lrwxrwxrwx 1 root root 50 Sep  3  2023 50-mod-stream.conf -> /usr/share/nginx/modules-available/mod-stream.conf
lrwxrwxrwx 1 root root 56 Sep  3  2023 70-mod-stream-geoip.conf -> /usr/share/nginx/modules-available/mod-stream-geoip.conf
lrwxrwxrwx 1 root root 57 Apr 23 18:38 70-mod-stream-geoip2.conf -> /usr/share/nginx/modules-available/mod-stream-geoip2.confLangage du code : JavaScript (javascript)

Onze modules sont déclarés, ce qui ne veut pas dire qu’ils sont tous utilisés activement dans la configuration. On vérifie ensuite quels modules sont effectivement chargés via load_module :

grep -R "load_module" /etc/nginx/nginx.conf /etc/nginx/modules-enabled -nLangage du code : JavaScript (javascript)

Plutôt que de supprimer ces modules directement, on les déplace dans un dossier temporaire, puis on teste la configuration :

sudo mkdir -p /root/nginx-modules-disabled

sudo mv /etc/nginx/modules-enabled/50-mod-http-brotli-filter.conf /root/nginx-modules-disabled/ 2>/dev/null
sudo mv /etc/nginx/modules-enabled/50-mod-http-brotli-static.conf /root/nginx-modules-disabled/ 2>/dev/null
sudo mv /etc/nginx/modules-enabled/50-mod-http-headers-more-filter.conf /root/nginx-modules-disabled/ 2>/dev/null
sudo mv /etc/nginx/modules-enabled/50-mod-http-geoip2.conf /root/nginx-modules-disabled/ 2>/dev/null
sudo mv /etc/nginx/modules-enabled/70-mod-stream-geoip2.conf /root/nginx-modules-disabled/ 2>/dev/null

sudo nginx -t && sudo systemctl restart nginxLangage du code : JavaScript (javascript)
2026/06/09 09:27:29 [emerg] 1611560#1611560: unknown directive "more_set_headers" in /etc/nginx/snippets/exclusions.conf:221
nginx: configuration file /etc/nginx/nginx.conf test failedLangage du code : PHP (php)

Le module headers-more était bien utilisé : deux directives more_set_headers non essentielles trônaient dans un snippet. Elles ont été supprimées. Les directives liées à Brotli ont également été retirées, puisque c’est désormais Cloudflare qui gère la compression en amont — inutile de la dupliquer côté origine.

Pour les modules restants, on vérifie par un simple grep qu’ils ne sont référencés nulle part dans la configuration avant de les considérer comme inutiles :

sudo grep -R "more_set_headers\|more_clear_headers\|headers_more" /etc/nginx -n || true
sudo grep -R "geoip\|geoip2" /etc/nginx -n || true
sudo grep -R "image_filter\|xslt\|mail\s*{\|stream\s*{" /etc/nginx -n || trueLangage du code : JavaScript (javascript)

Aucune de ces directives n’apparaît dans la configuration active (à part les déclarations load_module elles-mêmes). Le terrain est dégagé : on peut basculer sur le dépôt mainline sans craindre de casser une fonctionnalité encore en service.

Kinsta: Premium Managed WordPress hosting

Étape 2 : ajouter le dépôt officiel NginX mainline

On installe d’abord les outils nécessaires à l’ajout d’un dépôt signé, puis on récupère la clé de signature officielle de NginX :

sudo apt update
sudo apt install -y curl ca-certificates gnupg lsb-release ubuntu-keyring

curl https://nginx.org/keys/nginx_signing.key | gpg --dearmor \
    | sudo tee /usr/share/keyrings/nginx-archive-keyring.gpg >/dev/nullLangage du code : JavaScript (javascript)

On déclare ensuite le dépôt mainline comme source APT, en l’associant à la clé qu’on vient d’importer :

echo "deb [signed-by=/usr/share/keyrings/nginx-archive-keyring.gpg] \
https://nginx.org/packages/mainline/ubuntu $(lsb_release -cs) nginx" \
    | sudo tee /etc/apt/sources.list.d/nginx.listLangage du code : PHP (php)

Sans précaution supplémentaire, APT pourrait continuer à privilégier le paquet d’Ubuntu lors d’une future mise à jour. On épingle donc le dépôt nginx.org pour qu’il ait toujours la priorité :

echo -e "Package: *\nPin: origin nginx.org\nPin: release o=nginx\nPin-Priority: 900\n" \
    | sudo tee /etc/apt/preferences.d/99nginxLangage du code : PHP (php)

Avant d’installer pour de vrai, une simulation permet de vérifier ce qu’APT va réellement modifier — particulièrement utile pour repérer à l’avance les paquets qui seront supprimés :

sudo apt update
sudo apt install --simulate nginx

Une fois la simulation jugée cohérente, on procède à l’installation réelle :

sudo apt install nginx
Upgrading:
  nginx

REMOVING:
  libnginx-mod-http-brotli-filter  libnginx-mod-http-headers-more-filter  libnginx-mod-stream         nginx-core
  libnginx-mod-http-brotli-static  libnginx-mod-http-image-filter         libnginx-mod-stream-geoip
  libnginx-mod-http-geoip          libnginx-mod-http-xslt-filter          libnginx-mod-stream-geoip2
  libnginx-mod-http-geoip2         libnginx-mod-mail                      nginx-common

Summary:
  Upgrading: 1, Installing: 0, Removing: 13, Not Upgrading: 0
  Download size: 1264 kB
  Space needed: 1348 kBLangage du code : JavaScript (javascript)

APT supprime bien tous les paquets de modules Ubuntu au profit du paquet nginx.org, conformément à ce qu’on avait anticipé à l’étape précédente.

Étape 3 : valider et relancer le service

On recharge systemd, on réinitialise l’état du service, puis on redémarre proprement :

sudo systemctl daemon-reload
sudo systemctl reset-failed nginx.service
sudo systemctl restart nginx
sudo systemctl status nginx --no-pagerLangage du code : CSS (css)
● nginx.service - nginx - high performance web server
     Loaded: loaded (/usr/lib/systemd/system/nginx.service; enabled; preset: enabled)
     Active: active (running) since Wed 2026-06-10 14:26:00 CEST; 16ms ago
       Docs: https://nginx.org/en/docs/
    Process: 2155646 ExecStart=/usr/sbin/nginx -c ${CONFFILE} (code=exited, status=0/SUCCESS)
   Main PID: 2155647 (nginx)
      Tasks: 19 (limit: 34590)
     Memory: 143.6M (peak: 143.6M)
     CGroup: /system.slice/nginx.service
             ├─2155647 "nginx: master process /usr/sbin/nginx -c /etc/nginx/nginx.conf"
             ├─2155648 "nginx: worker process"
             ├─2155649 "nginx: worker process"
             ├─2155670 "nginx: cache manager process"
             └─2155672 "nginx: cache loader process"

Jun 10 14:26:00 apollo systemd[1]: Starting nginx.service - nginx - high performance web server...
Jun 10 14:26:00 apollo systemd[1]: Started nginx.service - nginx - high performance web server.Langage du code : JavaScript (javascript)

On confirme enfin la version installée :

nginx -V
nginx version: nginx/1.31.2
built by gcc 15.2.0 (Ubuntu 15.2.0-16ubuntu1)
built with OpenSSL 3.5.5 27 Jan 2026
TLS SNI support enabledLangage du code : JavaScript (javascript)

Dans ce cas précis, la 1.31.1 était la dernière mainline disponible au moment de l’opération. Si vous suivez ce tutoriel aujourd’hui, apt install nginx installera directement la dernière version publiée sur nginx.org — au moment de la rédaction, la 1.31.2 du 17 juin 2026, qui corrige en plus trois failles de sécurité sans rapport avec HTTP/2 Bomb. Vérifiez systématiquement le numéro de version après installation plutôt que de vous fier à un chiffre lu dans un article.

La protection max_headers est active par défaut dès la 1.29.8, sans configuration supplémentaire. Pour la rendre explicite dans votre configuration — ce qui facilite l’audit futur — ajoutez la directive dans le bloc http :

http {
    max_headers 1000;
}

Puis rechargez sans coupure de service :

sudo nginx -t && sudo systemctl reload nginx

Étape 4 : nettoyer les anciens fichiers de modules

L’installation du paquet nginx.org a désactivé les anciens fichiers de modules sans les supprimer : ils portent désormais l’extension .removed et ne sont plus chargés.

ls -lah /etc/nginx/modules-enabled/
50-mod-http-brotli-filter.conf.removed
50-mod-http-brotli-static.conf.removed
50-mod-http-geoip.conf.removed
50-mod-http-geoip2.conf.removed
50-mod-http-headers-more-filter.conf.removed
50-mod-http-image-filter.conf.removed
50-mod-http-xslt-filter.conf.removed
50-mod-mail.conf.removed
50-mod-stream.conf.removed
70-mod-stream-geoip.conf.removed
70-mod-stream-geoip2.conf.removedLangage du code : CSS (css)

On les supprime purement et simplement, puisqu’ils ne pointent plus vers rien d’actif :

sudo find /etc/nginx/modules-enabled -type l -name '*.removed' -deleteLangage du code : JavaScript (javascript)

Dernière vérification, pour s’assurer qu’aucune trace de configuration obsolète ne subsiste :

sudo grep -R "brotli\|more_set_headers\|more_clear_headers\|geoip2\|image_filter\|xslt" /etc/nginx -n || trueLangage du code : JavaScript (javascript)

Il ne reste qu’une ancienne référence à Brotli dans un commentaire de configuration, qui n’est plus chargée activement. L’installation est propre.

Distingo propose un taux d'intérêt de 4,5 % pendant 3 mois, plus 80 euros, jusqu'au 30 octobre 2026

Et si vous êtes encore sous Ubuntu 24.04 LTS ou Debian ?

La procédure reste identique : seul le codename récupéré par lsb_release -cs change automatiquement (noble pour Ubuntu 24.04, bookworm ou trixie pour Debian). Si vous partez d’une installation initiale plutôt que d’une migration, l’article installer NginX avec support HTTP/2 et certificat SSL sous Debian couvre la mise en place complète de la pile, à laquelle vous pouvez ensuite appliquer ce basculement vers le dépôt mainline.

Une couche de défense supplémentaire, en complément du correctif

Un CDN ou un proxy peut filtrer une partie du trafic malveillant, mais ne remplace pas la mise à jour du serveur d’origine. Maintenez NginX à jour et vérifiez que les accès directs à l’origine sont également protégés.

Si vous utilisez déjà Cloudflare devant NginX, vérifiez simplement que le proxy reste activé — et si vous rencontrez des erreurs 526 en sortie, l’article résoudre l’erreur 526 entre Cloudflare et NginX couvre ce cas précis.

Versions corrigées dans les paquets Ubuntu

L’avis officiel Ubuntu USN-8398-3 du 15 juin 2026 indique les versions corrigées suivantes pour les paquets NginX :

Version UbuntuVersion corrigée du paquet nginx
26.04 LTS1.28.3-2ubuntu1.5
25.101.28.0-6ubuntu1.7
24.04 LTS1.24.0-2ubuntu7.12
22.04 LTS1.18.0-6ubuntu14.15
Kinsta: Premium Managed WordPress hosting

Checklist avant de considérer le serveur protégé

  • Sauvegarder /etc/nginx avant toute modification
  • Identifier les modules réellement chargés via load_module
  • Désactiver (sans supprimer) les modules, puis tester avec nginx -t
  • Vérifier l’avis de sécurité de sa distribution et installer le paquet corrigé
  • Simuler l’installation avant de l’exécuter pour de vrai
  • Valider la configuration, redémarrer le service, vérifier nginx -V
  • Nettoyer les anciens fichiers de modules .removed
  • Surveiller les logs d’erreur les jours suivants

Foire aux questions

Faut-il utiliser la branche mainline ou stable de NginX ?

Pour cette vulnérabilité, les paquets Ubuntu pris en charge ont reçu des correctifs rétroportés. Choisissez entre les paquets de la distribution et le dépôt NginX mainline selon vos besoins de maintenance et de compatibilité ; dans les deux cas, vérifiez les avis de sécurité et la version complète du paquet installé.

Ce basculement va-t-il casser ma configuration WordPress ?

Non, tant que vos blocs server et vos directives FastCGI restent identiques. Seuls les modules tiers packagés séparément par Ubuntu disparaissent : si vous n’en utilisez aucun, comme c’était le cas ici une fois nettoyé, le site continue de fonctionner sans aucune modification de configuration.

Le dépôt mainline survit-il à une prochaine mise à jour Ubuntu ?

Oui, à condition de conserver le fichier d’épinglage dans /etc/apt/preferences.d/. Lors d’une migration de version Ubuntu, pensez simplement à vérifier que le codename dans /etc/apt/sources.list.d/nginx.list correspond toujours à votre nouvelle version.

Cloudflare suffit-il sans patcher NginX ?

Un proxy peut réduire le trafic malveillant qui atteint l’origine, mais il ne remplace pas l’installation du correctif. Gardez le paquet NginX d’origine à jour et vérifiez aussi les chemins d’accès qui ne passent pas par le proxy.

Conclusion

Les paquets Ubuntu corrigés permettent de traiter cette vulnérabilité sans migration obligatoire vers mainline. Si vous choisissez néanmoins cette migration, l’audit des modules avant changement aide à éviter les mauvaises surprises au redémarrage. Une fois cette base posée, c’est aussi l’occasion de revoir les autres réglages réseau du serveur : l’article optimiser TCP sous Linux complète bien cette démarche, tout comme le suivi régulier des versions PHP si vous gérez plusieurs sites WordPress sur la même machine, comme détaillé dans installer PHP 8.5 sous Ubuntu Server. Pensez aussi à surveiller le changelog nginx.org plutôt que d’attendre la prochaine panne pour découvrir un correctif déjà disponible depuis des semaines.

Besoin d’un audit de votre serveur ou de votre hébergement ?

Suivre chaque CVE NginX, Apache ou OpenSSL demande du temps que vous n’avez pas forcément. J’accompagne les sites WordPress et WooCommerce sur :

  • L’audit et le durcissement de la configuration NginX et PHP-FPM
  • La migration vers des versions LTS récentes (Ubuntu, PHP, MySQL/MariaDB)
  • La mise en place de sauvegardes fiables avant toute opération sensible
  • Le suivi et l’application des correctifs de sécurité critiques

Pour discuter de votre infrastructure, contactez-moi.

Sources

Laisser un commentaire