Attention, cet article a plus d'une année d'ancienneté. Il est possible que les informations présentées ne soient plus à jour, spécialement dans le cadre d'un article technique.
Bonjour à tous,
Aujourd’hui, j’avais envie de vous expliquer quelles sont les (bonnes) raisons qui peuvent vous pousser à compiler Nginx à la main au lieu d’utiliser les paquets Debian, Dotdeb ou autre.
Et évidemment, je vais vous expliquer comment le compiler 🙂
Pourquoi compiler NGINX ?
Généralement lorsqu’on cherche un faire un serveur en production qui aura un taux de disponibilité maximum on commence par utiliser uniquement les paquets des branches stables ou long term support de notre distribution Linux.
On évite donc au maximum les dépôts tiers et surtout les trucs compilés à la main …
… Mais, parce qu’il y’a souvent un mais, personnellement je compile presque toujours deux choses à la main sur mes serveurs de production.
La première, c’est mes kernels. Pour avoir le dernier disponible en y ajoutant le support de GrSecurity.
La deuxième, c’est NGINX pour différentes raisons que je vais détailler.
La sécurité
La première raison pour laquelle on souhaite compiler NGINX c’est pour en augmenter la sécurité.
Soit pour remplacer OpenSSL par LibreSSL ou BoringSSL qui dispose de moins de code et donc de moins de failles possibles.
Soit pour utiliser la dernière version de OpenSSL qui propose tout un tas de trucs sympas comme Chacha, X25519 ou encore le support de plusieurs courbes ECDH (ce qui n’est pas possible avec Libre ou Boring SSL).
Vous pouvez aussi rajouter le support de Naxsi et virer tous les modules qui ne vous servent à rien.
Les performances
Utiliser la version mainline de Nginx avec la dernière version de OpenSSL vous permettra d’utiliser CHACHA20_POLY1305 et X25519.
Le premier est plus performant sur les mobiles qui ne supportent pas le chiffrement AES en natif tandis que le second est plus performant tout court.
Le support de ces algorithmes n’est pas encore déployé à grande échelle, mais tous les appareils récents supportent au moins CHACHA donc pourquoi s’en priver ?
On peut également parler du support des Threads AIO et des enregistrements TLS dynamiques qui ne feront que réduire la charge de votre serveur et améliorer le confort de vos utilisateurs finaux.
Et toutes ces petites choses réunies font que (c’est mon avis en tout cas) ça vaut le coup de compiler nginx à la main et maintenir ça même sur des serveurs de production.
Comment compiler NGINX ?
La grande question 🙂
Avant de vous balancer le script automatique qui fait aussi le café, on va voir comment faire ça à la main (sous Debian 8 comme d’habitude).
Pour commencer, il faut installer tous les paquets nécessaires pour faire un build (machine à café en option) :
apt-get update && apt-get install curl libgeoip-dev libxslt-dev libpcre3 libpcre3-dev build-essential zlib1g-dev libbz2-dev libssl-dev tar unzip curl git -y
Le bordel est installé ? Fine.
Maintenant on va créer un dossier et récupérer tous les sources nécessaires :
cd /usr/src latest_nginx=$(curl -L http://nginx.org/en/download.html | egrep -o "nginx\-[0-9.]+\.tar[.a-z]*" | head -n 1) curl -fLRO "https://www.openssl.org/source/openssl-1.1.0c.tar.gz" && tar -xaf "openssl-1.1.0c.tar.gz" curl -fLRO "http://nginx.org/download/${latest_nginx}" && tar -xaf "${latest_nginx}"
Ensuite, nettoyez toutes les archives téléchargées :
rm /usr/src/*.tar.gz
Allez maintenant dans les sources de nginx :
latest_openssl=$(echo openssl-1.1.0*) cd "${latest_nginx//.tar*}"
Et ajoutez les deux patchs pour le support des enregistrements TLS dynamiques et le support de OpenSSL 1.1.0 dans NGINX :
wget https://raw.githubusercontent.com/cloudflare/sslconfig/master/patches/nginx__1.11.5_dynamic_tls_records.patch wget https://raw.githubusercontent.com/stylersnico/nginx-openssl-chacha-naxsi/master/misc/0001-Fix-nginx-build.patch patch -p1 < nginx__1.11.5_dynamic_tls_records.patch && patch -p1 < 0001-Fix-nginx-build.patch
Maintenant, il faut configurer NGINX en spécifiant tous les options que vous souhaitez :
./configure \ --http-client-body-temp-path=/usr/local/etc/nginx/body \ --http-fastcgi-temp-path=/usr/local/etc/nginx/fastcgi \ --http-proxy-temp-path=/usr/local/etc/nginx/proxy \ --http-scgi-temp-path=/usr/local/etc/nginx/scgi \ --http-uwsgi-temp-path=/usr/local/etc/nginx/uwsgi \ --user=www-data \ --group=www-data \ --prefix=/etc/nginx \ --sbin-path=/usr/sbin/nginx \ --conf-path=/etc/nginx/nginx.conf \ --error-log-path=/var/log/nginx/error.log \ --http-log-path=/var/log/nginx/access.log \ --pid-path=/usr/local/etc/nginx.pid \ --lock-path=/usr/local/etc/nginx.lock \ --with-pcre-jit \ --with-http_v2_module \ --with-debug \ --with-http_stub_status_module \ --with-http_realip_module \ --with-http_addition_module \ --with-http_dav_module \ --with-http_gzip_static_module \ --with-http_sub_module \ --with-http_xslt_module \ --with-file-aio \ --with-threads \ --with-http_ssl_module \ --with-http_geoip_module \ --with-openssl=/usr/src/${latest_openssl} \ --with-ld-opt=-lrt \
Et lancez l’installation du bordel :
make && make install
Pour finir, il va falloir installer tous les scripts de démarrage pour init.d :
cd /etc/init.d/ rm nginx && nginx-debug -f wget https://raw.githubusercontent.com/stylersnico/nginx-openssl-chacha-naxsi/master/misc/init.d/nginx wget https://raw.githubusercontent.com/stylersnico/nginx-openssl-chacha-naxsi/master/misc/init.d/nginx-debug chmod +x nginx && chmod +x nginx-debug
Ceux pour SystemD :
cd /lib/systemd/system/ rm nginx.service -f wget https://raw.githubusercontent.com/stylersnico/nginx-openssl-chacha-naxsi/master/misc/systemd/system/nginx.service chmod +x nginx.service systemctl enable nginx
La configuration logrotate :
cd /etc/logrotate.d/ rm nginx -f wget https://raw.githubusercontent.com/stylersnico/nginx-openssl-chacha-naxsi/master/misc/logrotate.d/nginx
Créer le répertoire du cache de NGINX :
mkdir -p /usr/local/etc/nginx/
Télécharger une configuration de NGINX :
cd /etc/nginx/ rm nginx.conf wget https://raw.githubusercontent.com/stylersnico/nginx-secure-config/master/nginx.conf
Et démarrer ce joyeux bordel 😀
service nginx stop service nginx start
Sympa non ? Encore plus sympa, le script que j’utilise pour maintenir mon infra et qui permets de faire tout ça automatiquement est disponible ici : https://github.com/stylersnico/nginx-openssl-chacha-naxsi/ 🙂
[…] J’ai déjà fait un article en détail sur la compilation de NGINX, nous n’y reviendrons pas ici : https://www.abyssproject.net/2016/11/compiler-nginx-pourquoi-comment/ […]
Merci Nicolas, super article 😉
A la base, j’étais parti pour essayer d’utiliser la version des dépots debian avec une version d’openSSL 1.0.2 avant de me rendre compte que seulement la version 1.1.0 semble fonctionner pour activer le HTTP2 sur debian et nginx.
Finalement, j’ai repris ta configuration pour le « configure ».
Juste une petite erreur au redémarrage (surement propre a mon instance) :
[emerg] mkdir() « /usr/local/etc/nginx/body »
un petit : mkdir -p /usr/local/etc/nginx/body
J’avoue pas comprendre pourquoi, mais maintenant ça fonctionne et surtout le http2 est supporté 😉
Merci et bon week end
Question bête, mais… ton script fonctionnera sur du Ubuntu 16.04 aussi ? 🙂
Tu nous dira 🙂
Hahaha :p
D’accord.
Ca fonctione semble-t-il 🙂
Pourquoi le pied est-il compilé dans /usr/local/etc/nginx.pid et renseigné comme /run/nginx.pid dans logrorate ?
La configuration de nginx reprendra le dessus en indiquant bien le pid dans /run/.
On est un petit groupe qui retravaille le process de build en ce moment, on devrait changer des choses dans le script, y compris ça 🙂
Salut,
Si Nginx est compilé une première fois et que par la suite j’ai besoin de le compiler à nouveau avec autre chose…
ça se passe comment ?
Tu penses qu’installer des versions mainline au lieu de stable ça ne craint rien (en prod) ?
Salut,
Il suffit de recompiler Nginx pour faire une mise à jour.
Personnellement j’utilise la branche mainline depuis 1 an et je n’ai jamais eu de problèmes.
Je fais un peu la même chose que toi, recompiler sur mes serveur en Debian Stable les dernières versions d’Nginx. En ce qui concerne la sécurité, je compile avec la dernière version d’OpenSSL pour bénéficier de Chacha20 et des courbes elliptiques sympas comme X25519. Je rajoute deux choses vis à vis de ta façon de compiler : – Je wrappe le make avec DEB_BUILD_HARDENING=1. Cette macro est fournie par le paquet hardening-wrapper, qui sert à compiler les binaires avec des options de sécurité fournies par GCC (_FORTIFY_SOURCE, PIE, etc), dont lal iste est disponible ici : https://wiki.debian.org/Hardening#Environment_variables – Je rajoute… Voir plus »
Sinon moi je fais
pkg install nginx
et étrangement, je suis toujours à jour. Bizarre…Sinon toi étrangement tu n’as pas lu l’article. Bizarre …