Gestion de la "chaîne de confiance" de l'IP réelle de l'utilisateur final

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;
4 « J'aime »