Docker自定义网络中Nginx容器IP访问控制规则失效,如何传递真实客户端IP?
Docker自定义网络中Nginx容器IP访问控制规则失效,如何传递真实客户端IP?
嗨,我碰到过一模一样的问题!你说得没错,这就是Docker自定义网络的IP伪装(IP masquerade)在搞鬼——默认情况下,Docker会把客户端的真实IP替换成网桥的网关IP(就是你看到的172.19.0.1),导致Nginx的allow MY_IP规则完全匹配不到,自然返回403。
给你两个靠谱的解决思路,按需选择:
方法一:关闭自定义网络的IP伪装(推荐,不影响自定义网络使用)
直接修改你的docker-compose.yml,在自定义网络的配置里添加禁用IP伪装的参数,这样Docker就不会替换客户端的真实IP了:
version: '3.8' services: nginx-proxy: image: nginx:1.18.0-alpine restart: always ports: - "80:80" - "443:443" networks: - internal-network # 可选:搭配Nginx realip模块让解析更稳妥,把下面配置挂载到容器里 volumes: - ./nginx-realip.conf:/etc/nginx/conf.d/realip.conf networks: internal-network: driver: bridge driver_opts: com.docker.network.bridge.enable_ip_masquerade: "false"
然后创建nginx-realip.conf文件,内容如下(适配你的自定义网络子网):
set_real_ip_from 172.19.0.0/16; # 这里填你的internal-network子网段 real_ip_header X-Forwarded-For; real_ip_recursive on;
这个配置会让Nginx把X-Forwarded-For里的真实客户端IP替换成$remote_addr,确保你的allow MY_IP规则能正常匹配。
方法二:直接使用host网络模式(简单但限制多)
如果你的Nginx容器不需要和自定义网络里的其他服务通信,也可以直接把容器放到宿主机的网络命名空间里,完全绕过Docker的NAT:
services: nginx-proxy: image: nginx:1.18.0-alpine restart: always network_mode: host # 关键配置 # 注意:host模式下不需要再写ports配置,容器直接使用宿主机端口
这种方法最直接,Nginx拿到的$remote_addr就是客户端真实IP,但缺点是容器无法再加入自定义网络,没法和其他容器通过内部域名通信,适合单容器独立使用的场景。
最后重启容器测试一下——不管用哪种方法,你再查看$remote_addr或者日志里的IP,应该就是你的真实IP了,allow规则也能正常生效啦。
备注:内容来源于stack exchange,提问作者webnoob
相关产品推荐
相关产品推荐

