Logo Khaganat
Traductions de cette page?:

Cette page est noté comme étant en brouillon. Votre participation pour l'améliorer est requise !

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 :

CC Attribution-Share Alike 4.0 International Driven by DokuWiki
fr/nginx.txt · Dernière modification : 2025/02/15 13:21 de zatalyz

Licences Mentions légales Accueil du site Contact