写在前面
有时存在这么一种情况,docker 里跑着某个运行在 apache2 上的 HTTP 站点, nginx 服务器安装在主机对其进行反向代理。出于安全防护、统计等原因,你需要站点能获得访问者真实的 IP 地址,却发现通常 nginx 做反向代理时传递 X-Real-IP
和 X-Forwarded-For
的方法不管用了。
这是因为 docker 默认的 userland-proxy 转发方式会剥离数据包的原始地址,导致以桥接模式运行的 docker 容器获取到的 REMOTE_ADDR
变成了 docker 网关地址。X-Real-IP
和 X-Forwarded-For
虽然传递过去了,但因为有 apache2 的缘故,我们需要额外做些处理。
解决方案
-
nginx 中
proxy_set_header
的设置依旧必不可少,这几乎是惯例配置,适用于绝大多数站点。proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme;
-
apache2 启用 mod_remoteip 模块
sudo a2enmod remoteip
-
创建
/etc/apache2/conf-available/remoteip.conf
文件,并添加以下内容RemoteIPHeader X-Real-IP RemoteIPTrustedProxy 172.16.0.0/12
-
启用配置并激活新配置
sudo a2enconf remoteip sudo service apache2 reload
-
现在,你的站点可以获得正确的访问者 IP 地址了