在CapRover中向Docker容器暴露客户端真实IP的问题
解决思路
1. 调整Docker Swarm服务的Endpoint Mode
从你的服务检查输出可见Endpoint Mode: vip,这是Docker Swarm默认的负载均衡模式。即便端口设置了PublishMode=host,VIP模式下流量会先经过Swarm入口网关,导致客户端真实IP被替换为Swarm节点的内网IP(10.0.0.2)。
需要将服务的Endpoint Mode改为host,让流量绕过Swarm负载均衡直达容器绑定的主机端口:
- 通过CapRover应用配置界面的高级部署选项,添加或修改服务的Endpoint Mode参数为
host; - 或直接用Docker命令修改服务:
docker service update --endpoint-mode host <你的exim4服务名>
2. 确认CapRover未接管SMTP端口
确保CapRover内置反向代理未拦截25端口。CapRover默认仅处理80/443端口,但自定义配置可能导致25端口被代理接管,进而丢失源IP:
- 检查CapRover全局设置,确认未将25端口添加到反向代理规则;
- 在应用端口映射设置中,确保是直接将容器25端口以
host模式发布到主机,而非通过CapRover反向代理转发。
3. 切换容器网络模式为host
如果容器使用host网络模式,会直接共享主机网络栈,无需端口映射,客户端真实IP会被exim4直接记录:
- 在CapRover部署时,将网络模式设置为
host(注意:该模式在Swarm集群中仅支持单节点部署)。
4. 验证exim4日志配置
确认exim4日志格式正确配置,确保记录的是客户端源IP而非本地连接IP:
- 查看exim4主配置文件(通常为
/etc/exim4/exim4.conf),检查log_selector参数是否包含host_lookup,或日志格式是否包含$sender_host_address变量。
内容的提问来源于stack exchange,提问作者be4i
相关产品推荐
相关产品推荐

