# Préambule
- Ce tutoriel sâadresse aux gens sous GNU/Linux, il a Ă©tĂ© fait sous Debian 10 (avec un compte root).
- Il est possible que certaines commandes changent suivant votre distribution (et surtout de votre package manager) ou quâil y ai besoin dâutiliser sudo.
# Installation des prérequis
apt update && apt install -y apt-transport-https ca-certificates curl gnupg2 software-properties-common
bash
# Installation de Nginx
On va ici utiliser directement les repositories de Nginx plutĂŽt que ceux de Debian:
# On va dans /tmp pour ne pas polluer notre ~home cd /tmp # On télécharge la clef wget https://nginx.org/keys/nginx_signing.key # On ajoute la clef précedement téléchargée apt-key add nginx_signing.key # OK # On ajoute le repository de Nginx dans nos sources nano /etc/apt/sources.list.d/nginx.list
bash
Ă ajouter dans /etc/apt/sources.list.d/nginx.list
deb http://nginx.org/packages/mainline/debian buster nginx deb-src https://nginx.org/packages/mainline/debian/ buster nginx
/etc/apt/sources.list.d/nginx.list
Et enfin
apt update && apt install nginx
bash
# Tuning de la configuration
Le point dâentrĂ©e de la configuration de Nginx est /etc/nginx/nginx.conf
.
# block racine
# worker_processes
Par dĂ©faut cette directive est Ă 1, celĂ veux dire quâil nây a quâun seul processus Nginx qui tourne, or de nos jours il est frĂ©quent dâavoir des serveurs avec plus dâun core CPU.
Malheureusement un processus Nginx nâest pas capable dâutiliser plus dâun core Ă la fois âŠ
Heureusement il est possible de faire tourner plusieurs processus de Nginx, en plus câest super simple avec la directive worker_processes
.
Le plus simple est de définir worker_processes
Ă auto
, cela va crĂ©er autant de processus Nginx quâil y a de core.
Mais attends ?!
Comment câest possible que plusieurs processus Ă©coutent sur le mĂȘme port ?
- Nginx se lance une 1Ăšre fois en root (bien obligĂ© pour Ă©couter sur les ports infĂ©rieurs Ă 1024 sans utiliser CAP_NET_BIND_SERVICE) et bind les sockets (Ă©coute sur le port 80 par exemple pour faire simple), on lâappelle
master
. - Puis il se dĂ©double en autant dâexemplaire que dĂ©fini par la directive
worker_processes
, se sont desworkers
. - Les
workers
changent dâutilisateur conformĂ©ment Ă la directiveuser
.
Lâastuce rĂ©side dans le fork (le dĂ©doublage), le processus pĂšre partage toutes les ressources quâil a Ă son nouveau fils, y compris fichiers et ports ouverts.
en rĂ©alitĂ© fichier et ports sont la mĂȘme chose sous Unix, se sont des files descriptor ⊠mais ça câest un autre sujet.
# block events
# multi_accept
si multi_accept
est Ă on
un processus worker va accepter toutes les nouvelles connexions en mĂȘme temps, au contraire si si la directive est Ă off
il ne pourra en accepter quâune Ă la fois.
Par défaut cette directive est sur off
.
# worker_connections
rĂšgle le nombre maximal de connexions simultanĂ©es quâun worker peut ouvrir en mĂȘme temps.
Il faut garder Ă lâesprit que ça inclue toutes les connexions (connexion avec un backend proxiĂ© par exemple).
On peut augmenter ce paramĂštre Ă 1024 sans trop de soucis.
Par défaut ce paramÚtre est à 512
requĂȘtes simultanĂ©es par workers.
# block http
# sendfile
Utilise lâappel kernel sendfile dans le cas oĂč nginx doit servir des fichiers statiques, plutĂŽt quâune combinaison de write et read. Par dĂ©faut ce paramĂštre est Ă off
.
# aio
Permet de ne pas bloquer la boucle dâĂ©vĂ©nement du processus worker dans le cas oĂč une opĂ©ration bloquante est en cours (lecture de fichier par exemple)
Par défaut cette directive est à off
.
# tcp_nopush
Permet dâenvoyer les entĂȘtes HTTP et le dĂ©but (ou la totalitĂ©) du fichier en un seul packet.
Par défaut cette directive est à off
.
# gzip
Permet de compresser la réponse renvoyée par Nginx. Par défaut cette directive est à off
.
# gzip_proxied
Permet de compresser les rĂ©ponses pour des requĂȘtes proxiĂ©es suivant les entĂȘtes HTTP
Je conseille dâutiliser any
pour tout le temps activer la compression. Par défaut cette directive est à off
.
# gzip_comp_level
Permet de plus ou moins compresser la réponse, une valeur élevée entrainera une consommation CPU plus importante
Le juste milieu entre usage CPU et usage réseau se situe au alentour de 5
/6
.
Par défaut le niveau est à 1
.
# Mise en cache
dans etc/nginx/nginx.conf
proxy_cache_path /tmp/cache levels=1:2 keys_zone=my_cache:10m inactive=10m;
etc/nginx/nginx.conf
Cette directive permet de créer une zone de cache nommée my_cache
qui a un index de 10mb (ce qui doit ĂȘtre suffisant pour le commun des mortels)/tmp/cache
dĂ©fini oĂč le cache sera Ă©crit sur le disque, dans le cas de forte activitĂ© le kernel Linux devrait ĂȘtre assez malin pour mettre les fichiers dans un cache LRU, pas besoin donc dâun montage de type tmpfsinactive
permet de stipuler au bout de combien de temps les fichiers de cache devraient ĂȘtre purger si le cache nâest pas utilisĂ©.
proxy_cache my_cache; proxy_cache_methods GET HEAD; proxy_cache_valid 200 302 10s; add_header X-Cache-Status $upstream_cache_status;
/etc/nginx/sites-enabled/monsite.fr.conf
proxy_cache
permet de dire quâon va utiliser le cache nommĂ©my_cache
, défini dans le block http juste au dessus.proxy_cache_methods
permet de dire sur quelles methodes on va mettre en place le cache. par défaut se sont les méthodes GET et HEAD qui sont misent en cache.proxy_cache_valid
permet de définir quels status code seront mis en cache et pour combien de temps. Par exampleproxy_cache_valid 200 302 10s;
met en cache toutes les rĂ©ponses 200 et 302 de lâapi proxiĂ©e avec une durĂ©e de validitĂ© de 10 secondes.add_header
nâest pas une directive propre Ă la mise en cache, cependant la variableupstream_cache_status
indique si la requĂȘte a Ă©tĂ© ou non tirĂ©e du cache, cela nous permet donc de savoir si les donnĂ©es viennent de lâapi ou du cache.
# ratelimit
dans etc/nginx/nginx.conf
on va définir tout comme pour le cache une zone de ratelimit
limit_req_zone $binary_remote_addr zone=1reqPer1Second:10m rate=1r/s;
etc/nginx/nginx.conf
On crĂ©e donc une zone qui sâappelle 1reqPer1Second
avec comme clef de dictionnaire $binary_remote_addr
et comme taille maximale du dictionnaire 10mb.
dans /etc/nginx/sites-enabled/monsite.fr.conf
limit_req zone=1reqPer1Second burst=50 nodelay; limit_req_status 429;
/etc/nginx/sites-enabled/monsite.fr.conf
limit_req zone=1reqPer1Second burst=50 nodelay;
permet de dire quâon va utiliser la zone prĂ©cĂ©dement crĂ©Ă©e, pourburst
il va falloir utiliser lâanalogie du seau percĂ©- On prends un seau qui peut contenir 50 unitĂ©es (des requĂȘtes ici)
- toutes les secondes une unitĂ© sâĂ©coule du seau
- quand le seau arrive Ă 50 il dĂ©borde, la requĂȘte nâest pas traitĂ©e
limit_req_status
dĂ©fini le status de la rĂ©ponse renvoyĂ© par Nginx dans le cas dâun ratelimit
# Bonus: redirection en HTTPS sur tous vos vhosts
On va rediriger toutes les requĂȘtes qui sont sur le port 80 (http) vers le port 443 (https)
server { listen 80; listen [::]:80; server_name _; return 301 https://$host$request_uri; }
/etc/nginx/sites-enabled/redirect-https.conf
server_name
.# RĂ©capitulatif
user nginx; worker_processes auto; error_log /var/log/nginx/error.log warn; pid /var/run/nginx.pid; events { multi_accept on; worker_connections 1024; } http { limit_req_zone $binary_remote_addr zone=1reqPer1Second:10m rate=1r/s; proxy_cache_path /tmp/cache levels=1:2 keys_zone=my_cache:10m inactive=10m; ## # Basic Settings ## sendfile on; aio on; tcp_nopush on; types_hash_max_size 2048; include /etc/nginx/mime.types; default_type application/octet-stream; ## # SSL Settings ## # ssl_protocols TLSv1 TLSv1.1 TLSv1.2; # Dropping SSLv3, ref: POODLE ssl_protocols TLSv1.2 TLSv1.3; # Dropping SSLv3, ref: POODLE ssl_prefer_server_ciphers on; ## # Logging Settings ## access_log /var/log/nginx/access.log; error_log /var/log/nginx/error.log; ## # Gzip Settings ## gzip on; gzip_proxied any; gzip_comp_level 6; gzip_http_version 1.1; gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript; ## # Virtual Host Configs ## server { listen 80; listen [::]:80; server_name _; return 301 https://$host$request_uri; } include /etc/nginx/conf.d/*.conf; include /etc/nginx/sites-enabled/*.conf; }
/etc/nginx/nginx.conf
server { listen 443 ssl http2; listen [::]:443 ssl http2; server_name monsite.fr www.monsite.fr; location / { limit_req zone=1reqPer1Second burst=50 nodelay; limit_req_status 429; proxy_cache my_cache; proxy_cache_methods GET HEAD; proxy_cache_valid 200 302 10s; add_header X-Cache-Status $upstream_cache_status; proxy_pass http://unix:/tmp/monsite.fr.sock; include /etc/nginx/proxy_params; } ssl_certificate /etc/letsencrypt/live/flapili.fr/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/flapili.fr/privkey.pem; }
/etc/nginx/sites-enabled/monsite.fr.conf