我尝试使用 Docker 运行 2 个容器(该问题并不特定于它们):
- MySQL(官方容器)
- Redmine(官方容器)
每个容器都有一个转发端口:
- MySQL的:
127.0.0.1:3000 -> 3000/tcp
- Redmine:
127.0.0.1:3306 -> 3306/tcp
正如你所见,目标是让它们变得易于访问仅在宿主内。
Nginx 服务器(未通过 Docker 安装)监听端口 80 并将任何请求重定向到 Redmine 容器端口(使用代理功能:proxy_pass
等)。
到目前为止一切都运行正常,当我转到服务器 IP 时,我可以访问 Redmine。
但是,我想使用 iptables 增加一些安全性。因此,目标是:
- 默认全部DROP(这一点是可以的)
- 允许Docker仅在本地主机内开展业务
- 允许容器访问互联网(下载依赖项、更新......)
- 允许访问 SSH 和 Nginx(也可以)
首先,我尝试添加--iptables=false
选项以阻止 docker 干扰我的 iptables。重启后,我认为,使用干净的 iptables(所有策略都设置为ACCEPT
默认设置,因此尚未执行任何操作),一切都会正常工作。但事实并非如此,我收到了"502 Bad Gateway"
Nginx 的响应。我不明白为什么 Docker 无法在不添加其他规则的情况下工作(如果所有规则都打开,它应该可以工作……不是吗?)。
我尝试阅读有关 Docker 中高级网络的文档,也尝试了多个教程,但我找不到阻碍 Docker 的原因:
我不是 Linux/Docker/SysAdmin 专家,所以也许对于你们中的一些人来说这是显而易见的(至少,我希望如此!)。
如果需要的话,请随时向我询问更多详细信息。
提前感谢您的回答。
答案1
Docker 默认添加了 iptables 规则,以便可以访问暴露给主机的端口。您可以尝试将其添加到 DOCKER-USER 链中:
iptables -I DOCKER-USER -i eth0 ! -s 127.0.0.0/8 -j DROP
这将丢弃来自外部接口(在本例中为 eth0)且没有环回源的所有数据包。这可能需要执行后你启动docker服务。
更新:正如 Luca 所说,你可能只需要
iptables -I DOCKER-USER -i eth0 -j DROP
或者
iptables -I DOCKER-USER ! -s 127.0.0.0/8 -j DROP