Как получить IP-адрес пользователя после обновления коммита b4a3389

После обновления

адрес последнего использования для всех пользователей изменился на шлюз Docker, например, 172.17.0.1

Моя архитектура выглядит следующим образом:

Cloudflare → VPS Nginx → Discourse Docker Nginx → Discourse

У меня похожая конфигурация, вот что я добавил в свой основной конфиг nginx, чтобы передавать IP-адрес пользователя:

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;
}

привет @CLOUD_PHT — добро пожаловать в Meta :slight_smile:

я предполагаю, что вы запускаете более одного сайта на одной и той же конфигурации машины? (например, сайт на WordPress + Discourse)

проблема в том, что вы маршрутизируете трафик через внутреннюю сеть docker (маппинг портов), что маскирует все входящие запросы под ip-адрес шлюза docker (172.17.0.1). поскольку внутренний nginx не распознает 172.17.0.1 как ip-адрес cloudflare, он отбрасывает заголовок CF-Connecting-IP в целях безопасности.

чтобы исправить это, вам нужно переключить вашу настройку на использование unix-сокета — это позволит вашему внешнему nginx передавать трафик (и заголовки) напрямую в Discourse, не искажая ip-адреса из-за сети docker.

следуйте этому официальному руководству и убедитесь, что вы оставляете cloudflare.template.yml в вашем файле app.yml при пересборке.

Этот коммит исправил ошибку конфигурации, на которую вы опирались, но также он мог позволять любому конечному пользователю подделать свой IP-адрес, задавая этот заголовок.

Если вы уверены, что больше ничего не может взаимодействовать с вашим контейнером, есть на самом деле более простой способ, не требующий использования сокета — я только что написал руководство о том, как это сделать.

Для вашей конфигурации @CLOUD_PHT вам следует добавить следующее в определение вашего контейнера (если раздел run уже существует, добавьте эти директивы в него, иначе добавьте раздел 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;

Возможно, вам также понадобится следующее:

  - 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;

в зависимости от того, обрабатывает ли nginx, запущенный на вашем сервере, заголовок Cloudflare для определения реального IP-адреса конечного пользователя (это рекомендуется) или просто добавляет свой собственный сверху. Подробнее см. в https://meta.discourse.org/t/handling-the-chain-of-trust-of-the-end-users-real-ip/406372#p-2001772-more-than-one-proxy-7.


Другие читатели: имейте в виду, что эта директива

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;

не подходит для всех конфигураций. Делайте это только если все подключения к контейнеру Discourse с этого IP-адреса являются доверенными.

В частности, известная проблема с IPv6-конфигурациями заключается в том, что IPv6-подключения к серверу перенаправляются docker через IPv4 — способ, которым это осуществляется, делает все подключения похожими на те, которые поступают с IP-адреса docker0 хоста. Если вы примените указанную выше директиву к вашей конфигурации, это позволит всем пользователям, подключающимся через IPv6, подделывать свой IP-адрес по своему усмотрению.