Logo Khaganat

Différences

Ci-dessous, les différences entre deux révisions de la page.

Lien vers cette vue comparative

Les deux révisions précédentesRévision précédente
Prochaine révision
Révision précédente
fr:nginx [2025/02/11 09:02] – [Rediriger les sous-domaines non existant vers une adresse précise] zatalyzfr:nginx [2025/07/15 05:46] (Version actuelle) – [Sur le backend (Apache)] zatalyz
Ligne 61: Ligne 61:
 └── win-utf</code> └── win-utf</code>
  
-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 [[fr:lamp|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''.+  * Le fichier principal de configuration est ''nginx.conf'', il fixe les paramètres globaux et c'est utile de l'adapter à ses besoins (backend ou proxy => pas les mêmes contraintes) 
 +  * Tout comme pour [[fr:lamp|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 /etc/nginx/sites-enabled/*''.
  
  
Ligne 92: Ligne 93:
   sudo service nginx restart   sudo service nginx restart
  
-===== Rediriger les sous-domaines non existant vers une adresse précise =====+==== Rediriger les sous-domaines non existant vers une adresse précise ====
 Créez un fichier de configuration redirigeant tout ce qui ne matche pas :  Créez un fichier de configuration redirigeant tout ce qui ne matche pas : 
 <code> <code>
Ligne 109: Ligne 110:
 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. 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.
  
-===== Proxy Nginx ne gérant pas le ssl ===== +===== SSL Passthrough sur proxy Nginx =====
-<WRAP center round todo 60%> +
-Cette partie est vraiment en brouillon mais si je ne note pas mes tests à mesure, je ne vais pas m'y retrouver. +
- --- //[[wiki:user:zatalyz|zatalyz]] 2025/02/11 08:28// +
-</WRAP>+
  
 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.  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. 
Ligne 119: Ligne 116:
 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. 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"+<WRAP center round tip 100%> 
 +On ne peux pas avoir à la fois des services sans ssl passthrough et d'autres avec. Soit tout ce qui passe sur 443 est redirigé vers les bons services (stream), soit c'est notre proxy qui gère les certificats ssl et transmet ensuite le flux en clair (site)
  
-sudo mkdir -p /etc/nginx/stream-enabled +<WRAP center round important 60%> 
-sudo mkdir -p /etc/nginx/stream-avalaible+Ce type de configuration est riche en prise de tête. Ce n'est pas la peine d'essayer de le complexifier encore plus... 
 +</WRAP>
  
-Il faut aussi modifier le fichier "nginx.conf" afin que ce dossier soit lu et pris en compte en ajoutant la ligne suivante : +</WRAP>
  
-<code> +Pour notre exemple :  
-include /etc/nginx/stream-enabled/*.conf; +  * Le proxy Nginx reçoit tout le trafic (HTTP/HTTPS) pour monsite.org et autresite.net. Son ip locale est 192.168.1.100. 
-</code>+  Suivant le nom de domaine demandé, il redirige le flux vers les bonnes ip en backend
 +  * monsite.org a comme IP interne : 192.168.1.207 et autresite.net a 192.168.1.208. Et les deux sont avec Apache, sinon ce n'est pas drôle. 
  
-Exemple dans le fichier :  +Ici "le proxy" fait référence à la VM qui centralise les flux avant de les redispatcher et "le backend" à toute VM/Container derrière, qui reçoit ce que le proxy a transmis
-<code bash /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 { +==== Sur le proxy ==== 
-[...] +On modifie ''/etc/nginx/nginx.conf'' pour ajouter la ligne suivante (attention, pas dans le bloc "http" ; plutôt à la suite de ''include /etc/nginx/modules-enabled/*.conf;'' par exemple : 
-</code>+<code>include /etc/nginx/stream-enabled/*.conf;</code>
  
 +Et on crée deux dossiers dont celui qui est lu : 
  
-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.+<code>sudo mkdir -p /etc/nginx/stream-enabled 
 +sudo mkdir -p /etc/nginx/stream-avalaible</code>
  
-<WRAP center round help 60%> +<WRAP center round tip 60%> 
-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+On suit avec "stream-*" une logique similaire aux dossiers "site-*"cela permet d'activer/désactiver une configuration suivant le besoin. Et c'est parce que notre proxy gère beaucoup de domaines, on peut faire ça dans un seul fichier sur ''/etc/nginx/conf.d/stream/mystream.conf'' aussi (dans ce cas pas besoin de l'include dans nginx.confparait-il). Faudrait d'ailleurs que je prévois de découper, sans doute... on va voir à l'usage
 </WRAP> </WRAP>
  
-Primo on fait un fichier dans la partie "site" pour renvoyer... vers un "stream+Voici à quoi ressemble un fichier de stream 
-<code bash /etc/nginx/sites-avalaible/tostream.conf> +
-server { +
-    listen 80; +
-    # Listez de tous tes domaines +
-    server_name domain1.org domain2.org;  +
  
-    # Rediriger toutes les requêtes HTTP vers HTTPS +<code bash /etc/nginx/stream-available/nosites443.conf># Table de routage : nom de domaine -> IP backend 
-    return 301 https://$host$request_uri+stream { 
-}+ map $ssl_preread_server_name $backend { 
 + monsite.org 192.168.1.207:443; 
 + autresite.net  192.168.1.208:443; 
 + # Optionnel : où on redirige si le nom de domaine n'existe pas ? 
 + default        192.168.1.207:443
 + }
  
-Configuration HTTPS pour tous les domaines +# HTTPS - SSL Passthrough 
-server { + server { 
-    listen 443; + listen 192.168.1.100:443; 
-    server_name domain1.org domain2.org + # Lit les nom de domaine sans déchiffrer le reste 
 + ssl_preread on; 
 + # Route vers la VM correspondante 
 + proxy_pass $backend; 
 + # Transmet l'IP réelle des visiteuses 
 + proxy_protocol on; 
 +
 +}</code>
  
-    location / { +  * ''map'' indique la correspondance entre les noms de domaine, et les ip où se trouvent réellement les sites.  
-        # Configurer la connexion au backend via stream (port 1443) +  ''listen'' : on écoute sur le port 443 du proxy 
-        proxy_pass https://127.0.0.1:1443;   +  * Et le reste est commenté ;)
-        # 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; +
-    } +
-}+
  
-</code>+Nous devons aussi déclarer le flux sur le port 80 ; mais là ça ne peut pas être du "stream", on revient au mode de proxy plus traditionnel. Donc, on déclare les sites sur ''/sites-enabled''
 +<code bash /etc/nginx/sites-available/nosites80.conf> 
 +    server { 
 +        listen 80; 
 +        server_name monsite.org;
  
-Et à présent le stream  +        location / { 
-<code bash /etc/nginx/stream-avalaible/domaine.conf> +            proxy_pass http://192.168.1.207:80
-stream { +            proxy_set_header Host $host
-    map $ssl_preread_server_name $backend { +            proxy_set_header X-Real-IP $remote_addr; 
-    # 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 {     server {
-        listen 10.0.0.10:1443 proxy_protocol+        listen 80; 
-        proxy_pass $backend+        server_name autresite.net.fr; 
-        ssl_preread on;+ 
 +        location / { 
 +            proxy_pass http://192.168.1.208:80; 
 +            proxy_set_header Host $host
 +            proxy_set_header X-Real-IP $remote_addr; 
 +        }
     }     }
-} 
  
 </code> </code>
 +Ici c'est vraiment très basique, mais il serait possible de rediriger dès maintenant vers une connexion sécurisée (443) sauf ce qui est nécessaire à l'obtention d'un certificat ssl
 +
 +<code bash /etc/nginx/sites-available/nosites80.conf>server {
 +    listen 80;
 +    server_name monsite.org;
 +
 +    # Rediriger tout vers HTTPS (sauf /.well-known/)
 +    location /.well-known/acme-challenge/ {
 +        proxy_pass http://192.168.1.207:80;
 +        proxy_set_header Host $host;
 +    }
 +
 +    location / {
 +        return 301 https://$host$request_uri;
 +    }
 +}</code>
 +
 +Mais je préfère faire simple et gérer les ennuis côté apache, parce que les possibilités de bizarreries restent élevées avec ce genre de configuration.
  
 On valide tout ça :  On valide tout ça : 
-<code>sudo ln -s /etc/nginx/sites-avalaible/tostream.conf /etc/nginx/sites-enabled/tostream.conf +<code>sudo ln -s /etc/nginx/sites-available/nosites80.conf /etc/nginx/sites-enabled/nosites80.conf 
-sudo ln -s /etc/nginx/stream-avalaible/domaine.conf /etc/nginx/stream-enabled/domaine.conf+sudo ln -s /etc/nginx/stream-avalaible/nosites443.conf /etc/nginx/stream-enabled/nosites443.conf
 sudo nginx -t sudo nginx -t
 sudo systemctl restart nginx sudo systemctl restart nginx
 </code> </code>
  
-<WRAP center round todo 60%> +==== Sur le backend (Apache) ==== 
-Cela demandera aussi ce genre de config côté apache/backend +Je pars du principe que le backend est avec Apache. Ça pourrait aussi être du nginx, mais je vous laisse faire la doc.
  
-a2enmod remoteip+On commence par ''/etc/apache2/conf-available/remoteip.conf''
 +<code bash /etc/apache2/conf-available/remoteip.conf> 
 +# Déclare le proxy afin de recevoir les vraies ip des clients. 
 +# Remplacer l'ip par celle du proxy ! 
 +RemoteIPInternalProxy 192.168.1.206 
 +RemoteIPTrustedProxy 192.168.1.206 
 +RemoteIPHeader X-Forwarded-For 
 +</code>
  
-<code><VirtualHost *:443+Puis  
-    RemoteIPProxyProtocol On +<code>  
-    RemoteIPHeader X-Forwarded-For +sudo a2enmod remoteip ssl 
-    RemoteIPInternalProxy 10.0.0.10+</code>
  
-    Autres directives... +Et on configure ensuite notre site, quasiment comme s'il était sur un dédié :  
-</VirtualHost></code> +<code bash /etc/apache2/sites-available/org.monsite.conf> 
-</WRAP>+<VirtualHost *:80> 
 + ServerName monsite.org 
 + DocumentRoot /var/www/org.monsite 
 +  
 + Redirection vers 443 sauf pour la demande de certificat 
 + RewriteEngine On 
 + RewriteCond %{REQUEST_URI} !.well-known/acme-challenge 
 + RewriteRule ^(.*)$ https://%{SERVER_NAME}$1 [R=301,L] 
 +</VirtualHost> 
 + 
 +<VirtualHost *:443> 
 + ServerName monsite.org 
 + # Important avec le ssl passthrough !!! 
 + RemoteIPProxyProtocol On 
 +  
 + DocumentRoot /var/www/org.monsite 
 + <Directory /var/www/org.monsite/
 + Options FollowSymLinks MultiViews 
 + AllowOverride All 
 + Require all granted 
 + </Directory> 
 +  
 + SSLEngine On 
 + SSLCertificateFile /etc/letsencrypt/live/monsite.org/fullchain.pem 
 + SSLCertificateKeyFile /etc/letsencrypt/live/monsite.org/privkey.pem 
 +</VirtualHost> 
 +</code> 
 + 
 +Sur le VirtualHost le point vraiment essentiel est de mettre le paramètre ''RemoteIPProxyProtocol On'' dans la partie 443. Non, on ne peux pas la mettre sur remoteip.conf, même entre les balises ''<IfModule mod_ssl.c>'' ; ça s'applique même sur 80 et ça fait planter (sur le 80 uniquement, ce qui n'est pas grave jusqu'au moment où on renouvelle le certificat).  
 + 
 +On valide tout ça  
 + 
 +<code> 
 +sudo a2ensite org.monsite 
 +sudo apachectl -t 
 +sudo service apache2 restart 
 +</code>
  
-===== Exemple de configuration ===== +===== Exemples de configuration ===== 
-==== Notre proxy =====+==== Proxy sans ssl passthrough =====
 Exemple simple: Exemple simple:
 <code bash> <code bash>
Ligne 262: Ligne 316:
 server { server {
     listen      192.168.20.10:80;     listen      192.168.20.10:80;
-    server_name "exemple.khagouille.net";+    server_name "exemple.net";
          
-    return      301 https://exemple.khaganat.net$request_uri;+    return      301 https://exemple.net$request_uri;
 } }
  
 server { server {
     listen      192.168.20.10:443 ssl http2;     listen      192.168.20.10:443 ssl http2;
-    server_name "exemple.khaganat.net";+    server_name "exemple.net";
  
-    ssl_certificate /etc/letsencrypt/live/exemple.khaganat.net/fullchain.pem; +    ssl_certificate /etc/letsencrypt/live/exemple.net/fullchain.pem; 
-    ssl_certificate_key /etc/letsencrypt/live/exemple.khaganat.net/privkey.pem;+    ssl_certificate_key /etc/letsencrypt/live/exemple.net/privkey.pem;
    
     location / {     location / {
Ligne 289: Ligne 343:
   *[[fr:dokuwiki_farm#nginx|Dokuwiki]]   *[[fr:dokuwiki_farm#nginx|Dokuwiki]]
  
-==== Demander un certificat let'encrypt ====+===== Demander un certificat let'encrypt =====
 Voir [[fr:https_ssl#sur_nginx]]. Voir [[fr:https_ssl#sur_nginx]].
  
CC Attribution-Share Alike 4.0 International Driven by DokuWiki
fr/nginx.1739264559.txt.gz · Dernière modification : de zatalyz

Licences Mentions légales Accueil du site Contact Inclusion