Docker 容器网络隔离,防止被横向渗透攻击
许多刚接触Docker的用户常忽略一个安全陷阱:默认情况下,同一台宿主机上的所有容器默认通过bridge网络互通。
攻击者一旦攻破一个脆弱容器,就能轻松扫描、跳转到其他容器,形成横向渗透。
这篇文章就手把手教你如何用最简单的命令切断这种后门。
准备条件
在开始操作前,请确认:
- 已安装Docker(运行
docker --version检查) - 拥有sudo权限(或当前用户已加入docker组)
- 没有任何重要生产容器在运行(测试环境最佳)
第一步:创建独立的内部网络
不要把容器都扔到默认的 bridge 网络里。
为每个服务组创建一个自定义网络,使用 --internal 参数让容器无法访问外网,同时与其他网络彻底隔离。
docker network create --driver bridge --internal my-internal-net
--driver bridge:指定网络类型为桥接(容器间可通信)--internal:禁止容器访问宿主机外部网络,也阻止了跨网络通信
执行后可用 docker network ls 看到新网络。
第二步:将容器连接到隔离网络
启动容器时直接指定网络,确保它只存在于隔离空间:
docker run -d --name web --network my-internal-net nginx:alpine
如果容器已存在,也可以运行时再加入:
docker network connect my-internal-net web
关键点:不要同时连接默认bridge和自定义网络。
如果你需要容器对外提供服务,可单独映射端口,但网络层面仍保持隔离。
第三步:禁止容器桥接到宿主机默认网络
即使创建了自定义网络,Docker默认仍然会为每个容器分配默认bridge的虚拟网卡(除非你明确移除)。
在执行 docker run 时加一条参数即可禁用:
docker run -d --name app --network my-internal-net --net=none nginx:alpine
但更推荐的方式是:启动容器时不要加入默认bridge,并且在启动后立即断开它:
docker network disconnect bridge app # 假设app容器刚启动时自动连接了bridge
这样容器就彻底脱离了公共网络,攻击者即使从宿主机也无法通过默认bridge进入容器。
避坑指南
- 忘记指定网络:如果使用
docker-compose,务必在networks段只定义内部网络,且不要留空default。 - 端口映射≠网络隔离:即使容器在内部网络,通过
-p 8080:80映射的端口仍然能从宿主机IP访问。这属于主机级别的暴露,需额外用防火墙限制来源IP。 - 内部网络容器需要访问外网:如果容器需要下载包或连外部API,不要使用
--internal,而是创建一个普通自定义bridge网络,只允许出站,并通过iptables规则限制入站。新手可暂时保留出站,等理解后再收紧。 - 容器重启后网络失效:
docker network disconnect操作不会持久化到容器重启。更可靠的方法是在docker run时直接指定网络,或者用docker-compose固定网络配置。
效果验证
验证隔离是否生效,分为两步:
- 检查容器IP与网络:
docker inspect web | grep -A 10 "Networks"
输出中只会出现 my-internal-net,不应有 bridge。
- 测试跨网络连通性:
在另一个未加入该网络的容器中测试能否ping通:
docker run --rm alpine ping -c 2 web
应返回 ping: bad address 'web' 或超时。
如果再创建一个同样在 my-internal-net 的容器,则能正常ping通——这正是预期的内部通信。
小结
通过三步操作——创建内部网络、指定容器连接、断开默认bridge——你就实现了最基础的Docker容器网络隔离。
这套配置能有效防止攻击者通过一个失陷容器向同机其他容器发起横向渗透。
如果生产环境中需要更精细的规则(如限制出站或跨宿主机安全),可以在此基础上叠加Calico或Cilium网络策略。
只要牢牢记住“不信任默认bridge,每个服务组独立网络”这条原则,你的容器安全就能上一个台阶。
如果你正在处理Docker容器网络隔离,防止被横向渗透攻击,建议先按本文步骤完整执行,再根据自己的环境做微调;
遇到异常时优先回看避坑和高频问题部分。