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.htaccess
et.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.conf
mais 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 Passthrough 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
Et c'est vraiment la galère comme pas permis.
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ù”.
À ce stade de mes expérimentations, je n'arrive pas du tout à faire un usage mixte où certains sites ont leur certbot sur le proxy et d'autres sur leur backend. Donc ce qui suit est en mode “tout en backend pour certbot”. Mais j'ai perdu comment demander le certificat dans mes bidouilles.
Par contre, on va avoir deux fichiers à faire : SSL Passthrough, comme son nom l'indique, ne concerne que ssl (donc 443); il faut toujours configurer les ports 80 des backends.
Le fichier dans la partie “site” pour servir le port 80
Faut probablement faire une règle spéciale pour well-known.
- /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; }
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:443 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 :