Contexte
Discourse doit être au courant de l’adresse IP réelle de l’utilisateur final.
Cependant, un utilisateur final ne se connecte jamais directement à Discourse car il y a toujours un ou plusieurs serveurs web en amont (nginx fonctionnant dans le conteneur Discourse) en place. Ainsi, nous avons besoin d’un moyen de transmettre ces informations à Discourse de manière fiable.
L’en-tête x-forwarded-for est la solution. Dans ce sujet, je décrirai les mécanismes spécifiques pour gérer correctement ces informations et comment nous nous attendons à ce qu’elles soient propagées.
Modèles
Les différents modèles pour faire confiance aux proxys en amont (par exemple cloudflare.template.yml ou fastly.template.yml) ont été mis à jour pour utiliser des noms de fichiers prévisibles dans les sorties plutôt que de dépendre de la substitution de texte (ce qui est fragile).
Noms de fichiers
server/real-ip-header.conf
Ce fichier contient l’en-tête que nginx fonctionnant dans le conteneur utilisera comme source de vérité, par exemple :
real_ip_header x-forwarded-for;
ou tel que défini dans le modèle Cloudflare :
real_ip_header cf-connecting-ip;
server/real-ip-recursive.conf
Si ce fichier existe, il contrôle la récursion dans le traitement de l’en-tête “IP réelle”. Vous devrez l’activer s’il y a plus d’un proxy devant le conteneur Discourse.
real_ip_recursive on;
Exemple :
Cloudflare → Load Balancer → Conteneur Discourse (qui est nginx + Discourse lui-même)
Avec cette configuration, nginx recevra un x-forwarded-for qui ressemble à :
x-forwarded-for: real_end_user_ip, cloudflare_ip
sur une connexion depuis une IP Load Balancer.
Pour traiter cela, nginx détermine d’abord si l’adresse source de la connexion (l’IP Load Balancer) est de confiance (voir set_real_ip_from) et, si c’est le cas, traitera la dernière IP de l’en-tête x-forwarded-for.
Puisque cette adresse IP est cloudflare_ip, nginx doit ensuite faire cela à nouveau, en vérifiant si cloudflare_ip est de confiance, et en utilisant la prochaine adresse IP qui est real_end_user_ip.
server/set-real-ip-from-ENVIRONMENT.conf
Ce fichier contient des directives qui indiquent à nginx quelles adresses IP sont de confiance, et nous pouvons avoir autant de fichiers et de directives que nécessaire.
Les modèles dans discourse_docker créent ces fichiers au besoin (par exemple set-real-ip-from-cloudflare.conf) et si vous avez des besoins supplémentaires, vous pouvez ajouter les vôtres.
Exemple :
Si vous fonctionnez sur AWS et avez un ALB devant le conteneur Discourse, vous pouvez ajouter un fichier supplémentaire en ajoutant ce qui suit à votre définition de conteneur (adapté à votre environnement) :
run:
- file:
path: /etc/nginx/conf.d/outlets/server/set-real-ip-from-aws.conf
chmod: 644
# AWS VPC est 10.42.0.0/16, faites confiance à toutes les connexions des réseaux ALB
contents: |
set_real_ip_from 10.42.66.0/24;
set_real_ip_from 10.42.67.0/24;
- file:
path: /etc/nginx/conf.d/outlets/server/real-ip-header.conf
chmod: 644
contents: |
real_ip_header x-forwarded-for;