写在前面
有时存在这么一种情况,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 地址了