Remote users IPV6 address shows as localhost

Я только что заметил, что IP-адреса многих участников моего форума сохраняются как 172.17.0.1. У меня не настроен обратный прокси или что-то подобное — между вами и Docker-контейнером Discourse ничего нет. Есть какие-то идеи?

Вы используете CloudFlare или что-то подобное?

Только для DNS (серый режим). (Технически, я думаю, что у меня оранжевый режим для www.intfiction.org, но он будет перенаправлен на корневой домен intfiction.org, прежде чем попадет на мой сервер.) В моем файле app.yml есть следующее, хотя я не думал, что какая-либо из этих частей будет актуальна:

  after_web_config:
    - replace:
        filename: /etc/nginx/nginx.conf
        from: /sendfile.+on;/
        to: |
          server_names_hash_bucket_size 64;
          sendfile on;
    - file:
        path: /etc/nginx/conf.d/discourse_redirect_1.conf
        contents: |
          server {
            listen 80;
            server_name www.intfiction.org;
            return 301 $scheme://intfiction.org$request_uri;
          }

Смотрите Last IP address and action_dispatch.trusted_proxies - #3 by mpalmer

Разве это актуально только в том случае, если перед моим сервером стоит прокси?

У меня тоже возникает эта проблема после миграции моего Discourse на новый сервер и решения НЕ использовать Cloudflare.

Я полностью переустановил Discourse, а затем восстановил резервную копию.
Я никогда не добавлял опцию шаблона Cloudflare в app.yml.

Я также попытался добавить код из другой темы:

- replace:
filename: /etc/nginx/conf.d/discourse.conf
from: "types {"
to: |
  set_real_ip_from 10.0.0.0/24;
  set_real_ip_from 172.17.0.0/24;
  real_ip_header X-Forwarded-For;
  real_ip_recursive on;
  types {

в app.yml, но проблема осталась:

У всех пользователей IPv6 последним IP-адресом отображается 172.17.0.1.

Адреса пользователей IPv4 отображаются корректно.

На этом сервере не используется обратный прокси или что-либо подобное — только стандартная установка Discourse, как описано в документации, обслуживающая трафик на портах 80/443.

Я думаю, что знаю, почему это происходит.

Для IPv4 Docker вставляет правила брандмауэра в iptables для обратного NAT с открытого адреса/порта хоста на порт контейнера. Это позволяет контейнеру видеть исходный адрес.
Для IPv6 Docker использует пользовательский прокси (docker-proxy), который просто перенаправляет трафик с одного порта на другой. Из-за этого контейнер видит исходный адрес как localhost. Это не HTTP-прокси, а просто перенаправление портов, поэтому он не может добавлять заголовки X-Forwarded-For.

Основной проект Docker не добавил поддержку NAT для IPv6, либо потому, что они считают IPv6 NAT нежелательным, либо потому, что ещё не дошли до этого.

Однако вы можете исправить это, включив IPv6 для Docker и запустив контейнер, который автоматически вставляет правильные правила IPv6 NAT.

Смотрите https://medium.com/@skleeschulte/how-to-enable-ipv6-for-docker-containers-on-ubuntu-18-04-c68394a219a2 для руководства по настройке.

TLDR: Убедитесь, что IPv6 работает в ваших контейнерах, а затем запустите GitHub - robbertkl/docker-ipv6nat: Extend Docker with IPv6 NAT, similar to IPv4 · GitHub

Это нужно изменить внутри приложения/контейнера Docker, снаружи или в обоих случаях? Я предполагаю, что в обоих… но это звучит как административные задачи высокого уровня. Если это подтвердится, было бы очень полезно получить простое пошаговое руководство по включению IPv6 для Discourse (Docker).

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

К сожалению, это оказалось сложнее, чем ожидалось, из-за моих ограниченных знаний в Docker. В данный момент я экспериментирую с проксированием Discourse через nginx, запущенный на домашнем сервере, чтобы обойти это ограничение. Если ничего не сработает, я вернусь к использованию Cloudflare, но мне бы не хотелось полагаться на них для работы сайта.

Короткое замечание для всех заинтересованных: Размещение Discourse за nginx — самое простое решение этой проблемы. Используйте ссылку в комментариях к файлу app.yml по умолчанию для настройки Discourse на сокет. Дополнительным преимуществом для меня стала возможность настроить отображение пользовательской страницы ошибок во время пересборки.