如何在Docker容器内运行的服务中获取客户端源IP地址
问题描述
Windows系统下基于WSL2使用Docker Desktop,按照官方说明host网络模式在此环境下无法生效。默认配置运行Docker容器时,所有连接到转发端口的客户端都会显示Docker网络驱动的IP地址,如何正确运行Docker容器,才能将真实客户端IP地址暴露给容器内的服务?
解决方案
以下方案均适配host网络不可用的WSL2 Docker Desktop场景:
方案一:开启镜像网络模式(推荐,适配Docker Desktop v4.18及以上版本)
新版本Docker Desktop提供了WSL2镜像网络模式,开启后可直接支持真实IP透传:
- 打开Docker Desktop设置面板,根据版本不同,镜像网络开关可能位于「Resources > Network」或「Features in Development」选项卡
- 勾选「启用镜像网络模式(mirrored networking mode)」相关选项
- 点击「Apply & Restart」等待服务重启完成
- 容器启动时正常使用
-p参数做端口映射即可,容器内服务可直接读取到真实客户端IP,无需额外修改配置
方案二:通过X-Forwarded-For头透传IP(兼容所有版本)
如果Docker版本较低无法使用镜像网络,可通过反向代理层透传客户端IP:
- 在WSL2宿主或单独的代理容器内部署Nginx反向代理,监听对外服务端口
- 编辑Nginx转发配置,添加头信息透传规则:
location / { proxy_pass http://容器IP:容器端口; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; }
- 容器内的业务服务配置信任代理IP,读取
X-Real-IP或X-Forwarded-For头的首段值作为真实客户端IP即可
方案三:手动修改WSL2 iptables规则
如果不想引入反向代理,可直接修改NAT规则取消端口转发的SNAT:
- 进入WSL2终端,执行以下命令查看Docker生成的端口转发规则,将命令中的
<容器端口>替换为实际服务端口:iptables -t nat -L DOCKER -n --line-number | grep <容器端口> - 记下返回结果中的规则编号,执行以下命令删除对应MASQUERADE规则:
iptables -t nat -D POSTROUTING <规则编号> - 该配置在Docker重启后会失效,可写入WSL2开机脚本自动执行
内容的提问来源于stack exchange,提问作者Menas
相关产品推荐
相关产品推荐

