Ceci est une ancienne révision du document !
Nginx
Installation
Pour Debian, installez les paquets de base :
sudo apt install nginx-full
Pour PHP :
sudo apt install php php-gd php-imagick php-curl php-intl php-fpm
Ces paquets installent les autres dépendances utiles.
Pour php, les modules complémentaires sont ceux qui nous sont utiles sur Khaganat, mais suivant les CMS ils peuvent être inutiles, ou avoir besoin d'être complétés.
Aperçu de Nginx
La configuration de Nginx et des sites se trouve dans /etc/nginx.
nginx ├── conf.d ├── custom │ ├── acme_http-01.conf │ ├── apache_compat.conf │ ├── headers.conf │ ├── headers_nocsp.conf │ └── tls.conf ├── fastcgi.conf ├── fastcgi_params ├── koi-utf ├── koi-win ├── mime.types ├── modules-available ├── modules-enabled │ ├── 50-mod-http-auth-pam.conf -> /usr/share/nginx/modules-available/mod-http-auth-pam.conf │ ├── 50-mod-http-dav-ext.conf -> /usr/share/nginx/modules-available/mod-http-dav-ext.conf │ ├── 50-mod-http-echo.conf -> /usr/share/nginx/modules-available/mod-http-echo.conf │ ├── 50-mod-http-geoip.conf -> /usr/share/nginx/modules-available/mod-http-geoip.conf │ ├── 50-mod-http-image-filter.conf -> /usr/share/nginx/modules-available/mod-http-image-filter.conf │ ├── 50-mod-http-subs-filter.conf -> /usr/share/nginx/modules-available/mod-http-subs-filter.conf │ ├── 50-mod-http-upstream-fair.conf -> /usr/share/nginx/modules-available/mod-http-upstream-fair.conf │ ├── 50-mod-http-xslt-filter.conf -> /usr/share/nginx/modules-available/mod-http-xslt-filter.conf │ ├── 50-mod-mail.conf -> /usr/share/nginx/modules-available/mod-mail.conf │ └── 50-mod-stream.conf -> /usr/share/nginx/modules-available/mod-stream.conf ├── nginx.conf ├── proxy_params ├── scgi_params ├── sites-available │ ├── default │ └── test.conf ├── sites-enabled │ └── test.conf -> ../sites-available/test.conf ├── snippets │ ├── fastcgi-php.conf │ └── snakeoil.conf ├── uwsgi_params └── win-utf
Le fichier principal de configuration est nginx.conf, il fixe les paramètres globaux et il y a donc assez peu de raisons de le modifier. Tout comme pour Apache, le dossier sites-enabled contient les liens symboliques vers les fichiers de configuration des différents sites situés dans sites-available. Ces autres fichiers de configuration sont inclus depuis le fichier de configuration principal nginx.conf grâce à la directive include.
La spécificité de Khaganat est la création du dossier custom qui contient des fichiers de configuration destinés à être inclus au cas par cas dans la configuration de chaque site. Les fichiers de custom sont les suivants :
acme_http-01.conf: Configuration nécessaire pour la résolution du challenge HTTP-01 lors d'un renouvellement de certificat initié par ACMEd.apache_compat.conf: Interdit l'accès aux fichiers dont le nom commence par.ht(notamment.htaccesset.htpasswd) afin de ne pas faire fuiter les éventuels résidus de fichiers de configuration spécifiques à Apache.headers.conf: Ajoute tous les headers HTTP classiques dont un site a normalement besoin.Attention, ceci inclut des CSP très sévères.
headers_nocsp.conf: Identique àheaders.confmais n'inclut aucune CSP afin de laisser la libre configuration de ces dernières.tls.conf: Configuration TLS.
Ajouter un domaine ou sous-domaine
Créez un fichier de configuration pour votre nom de domaine dans /etc/nginx/sites-available/monsite.conf.
Un exemple de fichier est disponible dans /etc/nginx/sites-available/default. Copiez-le, adaptez-le, puis enregistrez-le avec un nom compréhensible.
Vous pouvez vérifier que vous n'avez pas fait d'erreur de syntaxe avec la commande suivante :
nginx -t
Ou vous pouvez voir la configuration lue par nginx (en plus de la tester) avec cette commande :
nginx -T | less
Activez ensuite le site en créant un lien symbolique dans /etc/nginx/sites-enabled/ :
cd /etc/nginx/sites-enabled/ sudo ln -s ../sites-available/monsite.conf
Puis dites à nginx de prendre en compte la nouvelle configuration en le redémarrant :
sudo service nginx restart
Rediriger les sous-domaines non existant vers une adresse précise
Créez un fichier de configuration redirigeant tout ce qui ne matche pas :
# En cas d'erreur de sous-domaine, renvoie sur example.org.
server {
listen 10.0.0.10:80 default_server;
listen 10.0.0.10:443 ssl default_server;
# Toutes requêtes non définie par ailleurs
server_name _;
include snippets/snakeoil.conf;
access_log off;
error_log off;
return 301 https://example.org/404.html;
}
Le snippets snakeoil ici est pour le https, c'est un certificat autosigné, c'est mieux que “rien”, mais ça fera des erreurs dans les navigateurs des visiteuses.
SSL Passthrogh sur proxy Nginx
Cette partie est vraiment en brouillon mais si je ne note pas mes tests à mesure, je ne vais pas m'y retrouver. — zatalyz 2025/02/11 08:28
Un proxy est un outil qui peut faire beaucoup de choses, ou très peu. Dans notre cas, l'utilité principale est qu'en ayant une seule ipv4, on containerise les diverses applications histoire de limiter les dégâts si un des logiciels est troué. Donc tout arrive sur le serveur dédié, les flux sur les ports 80 et 443 sont redirigés vers le container du proxy, qui suivant les noms de domaine demandés renvoie vers un des containers ou un autre.
Il est assez simple de gérer les certificats ssl au niveau du proxy, mais cela a pour conséquence que le trafic entre le proxy et les containers passe “en clair”. Une attaque MITM à ce stade ne fais pas vraiment partie de notre modèle de menace, cependant certains CMS fonctionnent mal s'ils ne sont pas en https. Pour contourner ce problème, on peut donc dire au proxy de rediriger le flux mais sans s'occuper de ssl : il ne va rien déchiffrer et laisse ça au “backend”. Cela passe par l'usage de “stream” plutôt que de “http” au niveau de nginx.
Notre configuration des sites avec “stream” sera dans un dossier différent de “sites-avalaible/sites-enabled” : même logique mais avec “stream”.
sudo mkdir -p /etc/nginx/stream-enabled sudo mkdir -p /etc/nginx/stream-avalaible
Il faut aussi modifier le fichier “nginx.conf” afin que ce dossier soit lu et pris en compte en ajoutant la ligne suivante :
include /etc/nginx/stream-enabled/*.conf;
Exemple dans le fichier :
- /etc/nginx/nginx.conf
user www-data; worker_processes auto; pid /run/nginx.pid; error_log /var/log/nginx/error.log; include /etc/nginx/modules-enabled/*.conf; include /etc/nginx/stream-enabled/*.conf; events { worker_connections 768; # multi_accept on; } http { [...]
Il n'y a pas forcément besoin de faire un fichier de configuration par domaine, puisqu'on liste surtout “quel domaine redirige “où”. Par contre, on va avoir deux fichiers à faire, afin que les ports 80 et 443 du serveur puissent aussi servir des sites web en direct.
Pourquoi ? Parce que. On pourrait rediriger tout 443 vers le stream, ça marcherait, mais je fais mes tests avec des sites en prod à côté donc je vais éviter de tout casser. Par ailleurs, cette méthode va permettre d'avoir une page web sur le proxy pour les noms de domaine qui n'existent pas, et ça c'est assez classe.
Primo on fait un fichier dans la partie “site” pour renvoyer… vers un “stream”
- /etc/nginx/sites-avalaible/tostream.conf
server { listen 80; # Liste de tous les domaines server_name domain1.org domain2.org; # Rediriger toutes les requêtes HTTP vers HTTPS return 301 https://$host$request_uri; } # Configuration HTTPS pour tous les domaines server { listen 443; server_name domain1.org domain2.org; location / { # Configurer la connexion au backend via stream (port 1443) proxy_pass https://127.0.0.1:1443; # Transmettre l'IP des visiteuses proxy_set_header X-Forwarded-For $proxy_protocol_addr; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-Proto $scheme; proxy_buffering off; proxy_request_buffering off; } }
Et à présent le stream :
- /etc/nginx/stream-avalaible/domaine.conf
stream { map $ssl_preread_server_name $backend { # Cette partie liste les domaines et "où" ça renvoie domain1.org 10.0.0.30:443; domain2.org 10.0.0.32:443; # Default est utile : si pas de domaines, ça renvoie là. default 10.0.0.30:443; } server { listen 10.0.0.10:1443 proxy_protocol; proxy_pass $backend; ssl_preread on; } }
On valide tout ça :
sudo ln -s /etc/nginx/sites-avalaible/tostream.conf /etc/nginx/sites-enabled/tostream.conf sudo ln -s /etc/nginx/stream-avalaible/domaine.conf /etc/nginx/stream-enabled/domaine.conf sudo nginx -t sudo systemctl restart nginx
Cela demandera aussi ce genre de config côté apache/backend :
a2enmod remoteip
<VirtualHost *:443>
RemoteIPProxyProtocol On
RemoteIPHeader X-Forwarded-For
RemoteIPInternalProxy 10.0.0.10
# Autres directives...
</VirtualHost>
Exemple de configuration
Notre proxy
Exemple simple:
server { listen ip.du.pro.xy:80; server_name exemple.khaganat.net; location / { proxy_pass http://IP.DE.LA.VMàjoindre; include /etc/nginx/proxy.conf; } }
Création d'une conf commune :
nano /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; client_max_body_size 50m; client_body_buffer_size 512k; proxy_connect_timeout 90; proxy_send_timeout 90; proxy_read_timeout 90; proxy_buffers 32 4k;
Exemple plus complet:
server { listen 192.168.20.10:80; server_name "exemple.khagouille.net"; return 301 https://exemple.khaganat.net$request_uri; } server { listen 192.168.20.10:443 ssl http2; server_name "exemple.khaganat.net"; ssl_certificate /etc/letsencrypt/live/exemple.khaganat.net/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/exemple.khaganat.net/privkey.pem; location / { 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; proxy_buffering off; proxy_pass http://IP.DE.LA.VMàjoindre/; } }
D'autres exemples (ajouter des liens vers les autres tuto) :
Demander un certificat let'encrypt
Voir sur_nginx.
Sources et liens
En cas de besoin, la documentation d'nginx est très complète. La lecture des articles suivants est recommandée :





