我有一台运行 Docker 的 CentOS 服务器,我正在尝试使用 iptables 保护它。我不知道如何让容器访问互联网,而它们的端口不能从外部访问。
我已经使用‘--iptables = false’命令停止 Docker 处理我的 iptables,现在正在努力手动配置 iptables。
我想要设置防火墙以便:
- 除非我特意打开,否则输入会被丢弃
- 容器可以通过本地主机连接相互通信
- 容器可以连接到互联网来下载代码等
我有前两个,但无论我尝试启用第三个,都会使第一个无效!
我有两个测试容器。一个 httpd 容器转发其 Web 输出端口 3333 - 另一个容器运行 Debian。
IPTables 配置为
iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -P OUTPUT ACCEPT
iptables -A INPUT -i lo -j ACCEPT
因此,我无法从外部访问 myserver:3333。但我可以从主机运行:curl localhost:3333 并获得访问权限。
我接着补充道:
iptables -A INPUT -i docker0 -j ACCEPT
现在我可以在我的 debian 测试容器中运行 curl 172.17.0.1:3333,并且它也能正常工作。
但是如果我在测试容器中尝试:curl httpbin.org/ip 我不会得到任何响应。
我正在读https://fralef.me/docker-and-iptables.html并尝试了建议:
iptables-A FORWARD -i docker0 -o eth0 -j ACCEPT
iptables-A FORWARD -i eth0 -o docker0 -j ACCEPT
有了这些,我现在可以从测试容器中退出,但这也向世界开放了 3333!如何配置 iptables 以允许容器访问,但阻止访问?
答案1
我发现的解决方案似乎提供了我想要的东西:
iptables -A INPUT -i docker0 -j ACCEPT
iptables -A FORWARD -i docker0 -o eth0 -j ACCEPT
iptables -A FORWARD -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
这似乎允许
- Docker 容器之间的通信
- 容器与互联网的通信(通过我服务器上的 eth0)
- 回复沟通(相关/已建立)
但这些端口并不向外界开放。
我认为我的问题是我不明白我添加到 INPUT 的相关/已建立指令没有转换为 FORWARD。
答案2
默认的防火墙行为将为您提供良好的服务。要限制传出访问,请使用在目标域上具有 ACL 的代理。您甚至可以根据容器限制访问;我上周使用 Squid 的 ident ACL 类型和返回容器名称的自定义 ident 服务器实现了一些功能。
详情请见https://distracted-it.blogspot.co.nz/2017/11/provisioning-limited-access-via-squid.html
您还需要阻止容器服务器不通过代理直接建立连接。