Docker-Compose端口映射异常下的检测结果差异疑问
核心现象回顾
测试Bitnami Redis应用时,配置错误的端口映射7000:4444(容器侧4444端口不存在):
# docker-compose.yml 片段 ports: - '7000:4444'
检测结果:
# netstat显示端口被docker-proxy监听 netstat -naptu | grep LISTEN tcp 0 0 0.0.0.0:7000 0.0.0.0:* LISTEN 22893/docker-proxy # nmap扫描结果 nmap -p 7000 0.0.0.0 --> 7000/tcp open nmap -p 7000 127.0.0.1 --> 7000/tcp open nmap -p 7000 192.168.0.1 --> 7000/tcp closed
而正确映射7000:6379时,三个nmap扫描结果均显示open。
原因解析
1. docker-proxy的监听逻辑
Docker启动时会自动创建docker-proxy进程,负责处理主机端口到容器端口的转发。只要你在docker-compose.yml中配置了ports映射,不管容器侧的端口是否实际被监听,docker-proxy都会在主机上绑定并监听指定的主机端口——这就是为什么netstat始终显示0.0.0.0:7000处于LISTEN状态。
2. 本地回环(127.0.0.1)与外部IP的扫描差异
本地回环扫描:nmap扫描
127.0.0.1:7000时,直接检查主机本地是否有进程绑定监听该端口。因为docker-proxy确实在监听,所以nmap直接返回open,不会实际发起完整的TCP连接验证(即使后续转发会失败)。你可以用telnet 127.0.0.1 7000验证:连接会被立即重置(RST),但nmap的本地扫描逻辑只判断端口是否被监听,不关注连接后的结果。外部IP扫描:当扫描主机的外部IP(如
192.168.0.1:7000)时,请求需要经过主机的iptables规则转发。Docker会为正确的端口映射添加对应的iptables规则,将外部流量转发到docker-proxy,再由其转发到容器。但如果容器侧端口不存在,Docker不会生成有效的转发规则,或者docker-proxy在尝试转发时发现容器端口无监听,会直接拒绝外部请求,导致nmap无法完成TCP三次握手,最终返回closed。
3. 正确映射的情况
当容器侧6379端口正常监听时,docker-proxy能成功将流量转发到容器,不管是本地回环还是外部IP的请求,都能完成完整的TCP连接,因此nmap扫描所有地址都会返回open。
内容的提问来源于stack exchange,提问作者IgorZ

