Plus facile à lire avec un fond crème, une teinte, plus de contraste ou un texte plus grand ? Choisissez vos couleurs et votre texte, une fois pour toutes les pages.

Leçon gratuite

Un proxy inverse devant une application

Après cette leçon: Je peux placer nginx devant une application et dire ce que l'application voit.

Leçon de 55 min13 commandesLab de durcissement d’un serveur web : corriger une configuration nginx faible et la vérifier avec curl

Une seule porte d'entrée pour trois applications

Une entreprise gère une boutique, un blog et un outil interne. Chacun est un petit programme sur son propre port, et aucun ne devrait faire face à Internet seul.

Une porte d'entrée unique accueille chaque visiteur, passe chacun au bon programme et écrit un seul journal. Cette porte est un proxy inverse, et cette leçon en construit un.

À la fin de cette leçon

Remarque

Je peux placer nginx devant une application et dire ce que l'application voit.

Mots clés

MotCe que ça veut direExemple
Proxy inverseun serveur qui passe les requêtes à l'application derrière lui
Amontl'application à laquelle un proxy passe les requêtes
Répartition de chargerépartir les requêtes sur plusieurs serveurs
502le statut qui dit que le proxy n'a eu aucune réponse de l'applicationBad Gateway
X-Forwarded-Forun en-tête qui porte l'adresse du vrai visiteur
Rechargementfaire relire ses réglages à un serveur en marche

Les cellules que les étudiants remplissent restent vides dans cet aperçu.

Un proxy inverse répond pour l'application

Un visiteur parle au proxy inverse. Le proxy interroge l'application, l'amont, et rend la réponse. Le visiteur ne rencontre jamais l'application.

Ici l'application est faite de nginx lui-même, sur 127.0.0.1 port 9000, que seule cette machine peut joindre. Le proxy est sur le port 8080. Chacun prend un fichier.

Écrire l'application sur le port 9000

Commande
docker exec web sh -c "printf '%s\n' 'server {' '  listen 127.0.0.1:9000;' '  location / { return 200 \"serveur applicatif : hote=\$host transmis=\$http_x_forwarded_for depuis=\$remote_addr\n\"; }' '}' > /etc/nginx/conf.d/app.conf"

Affichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.

Écrire le proxy sur le port 8080

Commande
docker exec web sh -c "printf '%s\n' 'server {' '  listen 8080;' '  location / {' '    proxy_pass http://127.0.0.1:9000;' '    proxy_set_header Host \$host;' '    proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;' '  }' '}' > /etc/nginx/conf.d/proxy.conf"

Affichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.

Tester les réglages avant de les utiliser

Commande
docker exec web nginx -t

Affichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.

Recharger nginx pour qu'il lise les nouveaux fichiers

Commande
docker exec web nginx -s reload

Affichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.

Demander à travers le proxy

Commande
curl -s http://web:8080/

Affichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.

Demander directement à l'application, sans le proxy

Commande
curl -sS -m 2 http://web:9000/; echo "code de sortie $?"

Affichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.

Les en-têtes disent qui demande

L'application a vu le proxy comme expéditeur. Pour savoir qui a vraiment demandé, le proxy écrit l'adresse du visiteur dans l'en-tête X-Forwarded-For.

Il passe aussi le nom que le visiteur a tapé, dans l'en-tête Host. Sans cette ligne, nginx envoie à la place le nom de l'amont.

Envoyer une requête avec un faux expéditeur

Commande
curl -s -H 'X-Forwarded-For: 203.0.113.9' http://web:8080/

Affichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.

Une erreur fréquente

Attention

On croit souvent que la première adresse de X-Forwarded-For est toujours le vrai visiteur. Un visiteur peut écrire cet en-tête lui-même. Ne faites confiance qu'à l'adresse ajoutée par votre propre proxy, la dernière de la liste.

Exemple : ce que le proxy transmet

Ligne de proxy.confCe que l'application apprend
proxy_set_header Host $host;Le nom que le visiteur a tapé, ici web
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;L'adresse du visiteur ajoutée à la fin de la liste
pas de ligne HostLe nom de l'amont, comme groupe

Les cellules que les étudiants remplissent restent vides dans cet aperçu.

Une application en panne donne un 502

Si l'amont ne répond pas, le proxy ne peut pas chercher la page. Il répond 502, Bad Gateway : le proxy va bien, l'application derrière lui non.

Deux applications derrière un seul nom, c'est la répartition de charge. nginx leur donne les requêtes à tour de rôle, donc l'une peut tomber et l'autre répond encore.

Pointer le proxy vers un port mort

Commande
docker exec web sh -c "printf '%s\n' 'server {' '  listen 8080;' '  location / { proxy_pass http://127.0.0.1:9009; }' '}' > /etc/nginx/conf.d/proxy.conf && nginx -t && nginx -s reload"

Affichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.

Demander par le proxy, lire le statut

Commande
curl -s -i http://web:8080/

Affichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.

Lire ce que nginx a écrit sur l'échec

Commande
docker logs web 2>&1 | grep -F "Connection refused" | tail -n 1

Affichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.

Mettre deux applications derrière un nom

Commande
docker exec web sh -c "printf '%s\n' 'upstream groupe {' '  zone groupe 64k;' '  server 127.0.0.1:9000;' '  server 127.0.0.1:9001;' '}' 'server {' '  listen 127.0.0.1:9001;' '  location / { return 200 \"deuxieme serveur applicatif\n\"; }' '}' > /etc/nginx/conf.d/pool.conf && sed -i 's#127.0.0.1:9009#groupe#' /etc/nginx/conf.d/proxy.conf && nginx -t && nginx -s reload"

Affichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.

Demander quatre fois et voir les tours

Commande
for i in 1 2 3 4; do curl -s http://web:8080/; done

Affichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.

Supprimer les trois fichiers et recharger

Commande
docker exec web sh -c "rm -f /etc/nginx/conf.d/app.conf /etc/nginx/conf.d/proxy.conf /etc/nginx/conf.d/pool.conf; nginx -s reload"

Affichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.

Pour aller plus loin : la réponse hote=groupe

Revenez aux quatre réponses. Un genre de réponse dit hote=groupe et pas hote=web.

Quelle ligne du tableau des en-têtes l'explique ? Écrivez la ligne unique que vous ajouteriez au bloc location du proxy pour que l'application dise de nouveau hote=web.