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 [2020/03/29 10:17] – [Sources et liens] 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''+  * 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 67: Ligne 68:
  
   * ''acme_http-01.conf'' : Configuration nécessaire pour la résolution du challenge HTTP-01 lors d'un renouvellement de certificat initié par [[fr:acmed|ACMEd]].   * ''acme_http-01.conf'' : Configuration nécessaire pour la résolution du challenge HTTP-01 lors d'un renouvellement de certificat initié par [[fr:acmed|ACMEd]].
-  * ''apache_compat.conf'' : Interdit l'accès aux fichiers dont le nom commence par ''.ht'' afin de ne pas faire fuiter les éventuels résidus de fichiers de configuration spécifiques à Apache. +  * ''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.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.   * ''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.   * ''tls.conf'' : Configuration TLS.
Ligne 78: Ligne 79:
  
 Vous pouvez vérifier que vous n'avez pas fait d'erreur de syntaxe avec la commande suivante : 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   nginx -T | less
  
-Activez ensuite le site en créant un lien symbolique dans ''/etc/nginx/sites-enabled''+Activez ensuite le site en créant un lien symbolique dans ''/etc/nginx/sites-enabled/''
-  sudo ln -s /etc/nginx/sites-available/monsite.conf /etc/nginx/sites-enabled/monsite.conf+  cd /etc/nginx/sites-enabled/ 
 +  sudo ln -s ../sites-available/monsite.conf
  
-Puis prenez la nouvelle configuration en compte en redémarrant Nginx :+Puis dites à nginx de prendre en compte la nouvelle configuration en le redémarrant :
   sudo service nginx restart   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 : 
 +<code>
 +# 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;
 +}
 +</code>
 +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 =====
 +
 +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.
 +
 +<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). 
 +
 +<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>
 +
 +Pour notre exemple : 
 +  * 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.
 +  * 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. 
 +
 +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. 
 +
 +
 +==== 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
 +sudo mkdir -p /etc/nginx/stream-avalaible</code>
 +
 +<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>
 +
 +Voici à quoi ressemble un fichier de stream : 
 +
 +<code bash /etc/nginx/stream-available/nosites443.conf># Table de routage : nom de domaine -> IP backend
 +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;
 + }
 +
 +# HTTPS - SSL Passthrough
 + server {
 + 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>
 +
 +  * ''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
 +  * 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;
 +        }
 +    }
 +
 +    server {
 +        listen 80;
 +        server_name autresite.net.fr;
 +
 +        location / {
 +            proxy_pass http://192.168.1.208:80;
 +            proxy_set_header Host $host;
 +            proxy_set_header X-Real-IP $remote_addr;
 +        }
 +    }
 +
 +</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 : 
 +<code>sudo ln -s /etc/nginx/sites-available/nosites80.conf /etc/nginx/sites-enabled/nosites80.conf
 +sudo ln -s /etc/nginx/stream-avalaible/nosites443.conf /etc/nginx/stream-enabled/nosites443.conf
 +sudo nginx -t
 +sudo systemctl restart nginx
 +</code>
 +
 +==== Sur le backend (Apache) ====
 +Je pars du principe que le backend est avec Apache. Ça pourrait aussi être du nginx, mais je vous laisse faire la doc.
 +
 +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>
 +
 +Puis 
 +<code> 
 +sudo a2enmod remoteip ssl
 +</code>
 +
 +Et on configure ensuite notre site, quasiment comme s'il était sur un dédié : 
 +<code bash /etc/apache2/sites-available/org.monsite.conf>
 +<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 102: Ligne 295:
  
 } }
- 
 </code> </code>
  
-Création d'une conf commune:+Création d'une conf commune :
   nano /etc/nginx/proxy.conf   nano /etc/nginx/proxy.conf
 <code bash> <code bash>
Ligne 118: Ligne 310:
 proxy_read_timeout      90; proxy_read_timeout      90;
 proxy_buffers           32 4k; proxy_buffers           32 4k;
- 
 </code> </code>
 +
 Exemple plus complet: Exemple plus complet:
 <code bash> <code bash>
 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 145: Ligne 337:
     }     }
 } }
- 
 </code> </code>
  
-D'autre exemple (lien vers les autres tuto)+D'autres exemples (ajouter des liens vers les autres tuto) :\\ 
 +  *[[fr:kloud#nginx|Nextcloud]] 
 +  *[[fr:dokuwiki_farm#nginx|Dokuwiki]] 
 + 
 +===== Demander un certificat let'encrypt ===== 
 +Voir [[fr:https_ssl#sur_nginx]]. 
  
 ===== Sources et liens ===== ===== Sources et liens =====
CC Attribution-Share Alike 4.0 International Driven by DokuWiki
fr/nginx.1585477027.txt.gz · Dernière modification : (modification externe)

Licences Mentions légales Accueil du site Contact Inclusion