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/07/04 14:00] – [SSL Passthrough sur proxy Nginx] 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 110: Ligne 111:
  
 ===== SSL Passthrough sur proxy Nginx ===== ===== 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// 
- 
-Et c'est vraiment la galère comme pas permis. 
-</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 121: 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.
  
-<WRAP center round tip 60%>+<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).  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). 
 +
 +<WRAP center round important 60%>
 +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>
 +
 </WRAP> </WRAP>
  
-<WRAP center round info 100%> 
 Pour notre exemple :  Pour notre exemple : 
-  * Le proxy Nginx reçoit tout le trafic (HTTP/HTTPS) pour monsite.org et autresite.net+  * Le proxy Nginx reçoit tout le trafic (HTTP/HTTPS) pour monsite.org et autresite.net. Son ip locale est 192.168.1.100.
   * Suivant le nom de domaine demandé, il redirige le flux vers les bonnes ip en backend.   * 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.100 et autresite.net a 192.168.1.200. Et les deux sont avec Apache, sinon ce n'est pas drôle.  +  * 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. 
-</WRAP>+
  
 +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. 
  
-Notre configuration des sites avec "**//stream//**" sera dans un dossier différent de "sites-avalaible/sites-enabledmême logique mais avec "stream+ 
 +==== 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>include /etc/nginx/stream-enabled/*.conf;</code> 
 + 
 +Et on crée deux dossiers dont celui qui est lu 
  
 <code>sudo mkdir -p /etc/nginx/stream-enabled <code>sudo mkdir -p /etc/nginx/stream-enabled
 sudo mkdir -p /etc/nginx/stream-avalaible</code> sudo mkdir -p /etc/nginx/stream-avalaible</code>
  
-Il faut aussi modifier le fichier "nginx.conf" afin que ce dossier soit lu et pris en compte en ajoutant la ligne suivante : +<WRAP center round tip 60%> 
 +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.conf, parait-il). Faudrait d'ailleurs que je prévois de découper, sans doute... on va voir à l'usage.  
 +</WRAP>
  
-<code> +Voici à quoi ressemble un fichier de stream 
-include /etc/nginx/stream-enabled/*.conf; +
-</code>+
  
-Exemple dans le fichier :  +<code bash /etc/nginx/stream-available/nosites443.conf># Table de routage : nom de domaine -> IP backend 
-<code bash /etc/nginx/nginx.conf> +stream { 
-user www-data; + map $ssl_preread_server_name $backend { 
-worker_processes auto; + monsite.org 192.168.1.207:443
-pid /run/nginx.pid+ autresite.net  192.168.1.208:443
-error_log /var/log/nginx/error.log+ # Optionnel : où on redirige si le nom de domaine n'existe pas ? 
-include /etc/nginx/modules-enabled/*.conf+ default        192.168.1.207:443
-include /etc/nginx/stream-enabled/*.conf;+ }
  
-events +# HTTPS - SSL Passthrough 
-        worker_connections 768+ server 
-        multi_accept on; + listen 192.168.1.100:443
-}+ 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>
  
-http { +  * ''map'' indique la correspondance entre les noms de domaine, et les ip où se trouvent réellement les sites.  
-[...] +  * ''listen'' : on écoute sur le port 443 du proxy 
-</code>+  * Et le reste est commenté ;)
  
 +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;
  
 +        location / {
 +            proxy_pass http://192.168.1.207:80;
 +            proxy_set_header Host $host;
 +            proxy_set_header X-Real-IP $remote_addr;
 +        }
 +    }
  
-Il n'y a pas forcément besoin de faire un fichier de configuration par domaine, puisqu'on liste surtout "quel domaine redirige "où"+    server { 
 +        listen 80; 
 +        server_name autresite.net.fr;
  
-<WRAP center round tip 100%> +        location / { 
-À 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 backendDonc ce qui suit est en mode "tout en backend pour certbot"Mais j'ai perdu comment demander le certificat dans mes bidouilles+            proxy_pass http://192.168.1.208:80; 
-</WRAP>+            proxy_set_header Host $host; 
 +            proxy_set_header X-Real-IP $remote_addr; 
 +        } 
 +    }
  
-Par contre, on va avoir deux fichiers à faire : SSL Passthrough, comme son nom l'indiquene concerne que ssl (donc 443); il faut toujours configurer les ports 80 des backends. +</code> 
 +Ici c'est vraiment très basiquemais 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
  
-Le fichier dans la partie "site" pour servir le port 80 +<code bash /etc/nginx/sites-available/nosites80.conf>server {
-<WRAP center round todo 60%> +
-Faut probablement faire une règle spéciale pour well-known. +
-</WRAP> +
- +
-<code bash /etc/nginx/sites-avalaible/tostream.conf> +
-server {+
     listen 80;     listen 80;
-    # Liste de tous les domaines +    server_name monsite.org;
-    server_name domain1.org domain2.org;  +
  
-    # Rediriger toutes les requêtes HTTP vers HTTPS +    # Rediriger tout vers HTTPS (sauf /.well-known/) 
-    return 301 https://$host$request_uri; +    location /.well-known/acme-challenge/ { 
-+        proxy_pass http://192.168.1.207:80
- +        proxy_set_header Host $host;
-</code> +
- +
-Et à présent le stream :  +
-<code bash /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 +    location / 
-        listen 10.0.0.10:443 proxy_protocol; +        return 301 https://$host$request_uri;
-        proxy_pass $backend; +
-        ssl_preread on;+
     }     }
-}+}</code>
  
-</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 265: 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 292: 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.1751637636.txt.gz · Dernière modification : de zatalyz

Licences Mentions légales Accueil du site Contact Inclusion