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
| Mot | Ce que ça veut dire | Exemple |
|---|---|---|
| Proxy inverse | un serveur qui passe les requêtes à l'application derrière lui | |
| Amont | l'application à laquelle un proxy passe les requêtes | |
| Répartition de charge | répartir les requêtes sur plusieurs serveurs | |
| 502 | le statut qui dit que le proxy n'a eu aucune réponse de l'application | Bad Gateway |
| X-Forwarded-For | un en-tête qui porte l'adresse du vrai visiteur | |
| Rechargement | faire 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
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
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
docker exec web nginx -tAffiché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
docker exec web nginx -s reloadAffiché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
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
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
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.conf | Ce 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 Host | Le 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
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
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
docker logs web 2>&1 | grep -F "Connection refused" | tail -n 1Affiché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
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
for i in 1 2 3 4; do curl -s http://web:8080/; doneAffiché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
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.