我刚刚注意到,我的论坛上许多成员的 IP 地址都被存储为 172.17.0.1。我没有运行反向代理或其他任何中间服务——你和 Discourse 的 Docker 之间没有任何东西。有什么想法吗?
您使用的是 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;
}
这不只有在服务器前面有代理的情况下才相关吗?
我也遇到了这个问题,在将我的 Discourse 迁移到新服务器并决定不使用 Cloudflare 之后。
我重新安装了 Discourse,然后恢复了备份。
我从未在 app.yml 中重新添加 Cloudflare 模板选项。
我还尝试添加了其他线程中的代码:
- 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 {
但问题仍然存在:
所有 IPv6 用户的最后 IP 都显示为 172.17.0.1。
IPv4 用户的地址显示完全正确。
该服务器上没有任何反向代理或其他工具在使用——只是按照 文档 中的说明进行了标准的 Discourse 安装,并为 80/443 端口提供流量服务。
我想我知道为什么会发生这种情况。
对于 IPv4,Docker 会在 iptables 中插入防火墙规则,以将暴露的主机地址/端口反向 NAT 到容器的地址/端口。这使得容器能够看到原始源地址。
对于 IPv6,Docker 使用用户态代理(docker-proxy)来简单地从一个端口转发到另一个端口。这导致容器看到的源地址为 localhost。这并不是一个感知 HTTP 的代理,它只是端口转发,因此无法插入 X-Forwarded-For 头部。
Docker 核心项目尚未添加对 IPv6 NAT 的支持,可能是因为他们认为 IPv6 NAT 不可取,或者他们还没有着手实现。
但你可以通过为 Docker 启用 IPv6,然后运行一个自动插入正确 IPv6 NAT 规则的容器来解决这个问题。
请参阅 https://medium.com/@skleeschulte/how-to-enable-ipv6-for-docker-containers-on-ubuntu-18-04-c68394a219a2 以获取设置指南。
TLDR:确保 IPv6 在您的容器中正常工作,然后运行 https://github.com/robbertkl/docker-ipv6nat。
这是需要在应用/Docker 容器内部、外部还是两者都进行修改?我猜是两者都需要……但这听起来像是高级管理员的工作。如果确认的话,非常希望能提供一份易于操作的指南,说明如何在 Docker 中启用 Discourse 的 IPv6 支持。
我稍后会在自己的网站上尝试实现这个功能,并记录下我的步骤。我绝非 Docker 专家,但我觉得这应该不会太困难。
遗憾的是,由于我的 Docker 知识有限,这比预期的要棘手得多。目前我正在尝试通过在家庭服务器上运行 Nginx 来代理 Discourse,以绕过这一限制。如果其他方法都无效,我将重新使用 Cloudflare,但我更不希望依赖它来维持网站的正常运行。
给任何感兴趣的人提个醒:将 Discourse 置于 nginx 之后是解决此问题最简便的方案。请使用默认 app.yml 注释中的链接来配置基于 socket 的 Discourse。对我而言,额外的好处是能够在重建期间设置自定义错误页面。