Comment obtenir l'adresse IP de l'utilisateur après la mise à jour du commit b4a3389

Après la mise à jour

l’adresse IP de dernière utilisation de tous les utilisateurs est devenue la passerelle Docker, par exemple 172.17.0.1

L’architecture que j’utilise est la suivante :

Cloudflare → Nginx VPS → Nginx Docker Discourse → Discourse

J’ai une configuration similaire à la tienne, voici ce que j’ai ajouté à ma configuration nginx hôte pour qu’il transmette l’IP de l’utilisateur :

location / {
  set_real_ip_from 103.21.244.0/22;
  set_real_ip_from 103.22.200.0/22;
  set_real_ip_from 103.31.4.0/22;
  set_real_ip_from 104.16.0.0/13;
  set_real_ip_from 104.24.0.0/14;
  set_real_ip_from 108.162.192.0/18;
  set_real_ip_from 131.0.72.0/22;
  set_real_ip_from 141.101.64.0/18;
  set_real_ip_from 162.158.0.0/15;
  set_real_ip_from 172.64.0.0/13;
  set_real_ip_from 173.245.48.0/20;
  set_real_ip_from 188.114.96.0/20;
  set_real_ip_from 190.93.240.0/20;
  set_real_ip_from 197.234.240.0/22;
  set_real_ip_from 198.41.128.0/17;
  set_real_ip_from 2400:cb00::/32;
  set_real_ip_from 2405:8100::/32;
  set_real_ip_from 2405:b500::/32;
  set_real_ip_from 2606:4700::/32;
  set_real_ip_from 2803:f800::/32;
  set_real_ip_from 2a06:98c0::/29;
  set_real_ip_from 2c0f:f248::/32;

  real_ip_header X-Forwarded-For;

  proxy_pass http://unix:/var/discourse/shared/standalone/nginx.http.sock:;

  proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
  proxy_set_header X-Real-IP $remote_addr;
  proxy_set_header Host $http_host;
  proxy_set_header X-Forwarded-Proto $scheme;

  proxy_http_version 1.1;
  proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
  proxy_set_header X-Forwarded-Proto https;
}

bonjour @CLOUD_PHT - bienvenue sur Meta :slight_smile:

je suppose que vous hébergez plus d’un site web sur la même configuration machine ? (comme un site WordPress + Discourse)

le problème est que vous acheminez le trafic via le réseau interne de Docker (mappage de ports), ce qui masque toutes les requêtes entrantes sous l’adresse IP de la passerelle Docker (172.17.0.1). comme le nginx interne ne reconnaît pas 172.17.0.1 comme une adresse IP Cloudflare, il supprime l’en-tête CF-Connecting-IP pour des raisons de sécurité.

pour résoudre ce problème, vous devez modifier votre configuration pour utiliser un socket Unix - cela permet à votre nginx externe de transmettre le trafic (et les en-têtes) directement à Discourse sans que le réseau de Docker ne corrompe les adresses IP.

suivez ce guide officiel, et assurez-vous de conserver cloudflare.template.yml dans votre fichier app.yml lors de la reconstruction.

Cet engagement a corrigé une erreur de configuration sur laquelle vous vous appuyiez, mais qui aurait également pu permettre à tout utilisateur final de falsifier son adresse IP en définissant cet en-tête.

Il existe en réalité une méthode plus simple qui ne nécessite pas l’utilisation d’un socket : je viens de rédiger un guide expliquant comment procéder.

Pour votre configuration @CLOUD_PHT, vous devez ajouter ceci à la définition de votre conteneur (si une section run existe déjà, ajoutez ces directives à celle-ci, sinon ajoutez la section run) :

run:
  - file:
      path: /etc/nginx/conf.d/outlets/server/real-ip-header.conf
      chmod: 644
      contents: |
        real_ip_header x-forwarded-for;
  - file:
      path: /etc/nginx/conf.d/outlets/server/set-real-ip-from-host.conf
      chmod: 644
      contents: |
        set_real_ip_from 172.17.0.1;

Vous pourriez également avoir besoin de ce qui suit :

  - file:
      # we need to turn on recursive since we'll have at least two entries; one from the host, one from CloudFlare
      path: /etc/nginx/conf.d/outlets/server/real-ip-recursive.conf
      chmod: 644
      contents: |
        real_ip_recursive on;

cela dépend de savoir si l’instance nginx exécutée sur votre serveur traite elle-même l’en-tête Cloudflare pour déterminer l’adresse IP réelle de l’utilisateur final (ce qui est recommandé) ou se contente d’ajouter le sien par-dessus. Consultez https://meta.discourse.org/t/handling-the-chain-of-trust-of-the-end-users-real-ip/406372#p-2001772-more-than-one-proxy-7 pour plus de détails.


Autres lecteurs : sachez que cette directive

run:
  - file:
      path: /etc/nginx/conf.d/outlets/server/set-real-ip-from-host.conf
      chmod: 644
      contents: |
        set_real_ip_from 172.17.0.1;

n’est pas adaptée à toutes les configurations. Ne le faites que si toutes les connexions vers le conteneur Discourse provenant de cette adresse IP sont de confiance.

Plus précisément, un problème connu avec les configurations IPv6 est que les connexions IPv6 vers le serveur sont redirigées par Docker via IPv4 : la manière dont cela est implémenté fait apparaître toutes les connexions comme provenant de l’adresse IP docker0 de l’hôte. Si vous appliquez la directive ci-dessus à votre configuration, cela permettra à tous les utilisateurs se connectant via IPv6 de falsifier leur adresse IP à leur guise.