![使用 iptables 删除与 Docker 容器的外部连接](https://linux22.com/image/677243/%E4%BD%BF%E7%94%A8%20iptables%20%E5%88%A0%E9%99%A4%E4%B8%8E%20Docker%20%E5%AE%B9%E5%99%A8%E7%9A%84%E5%A4%96%E9%83%A8%E8%BF%9E%E6%8E%A5.png)
我正在尝试在运行 Docker 容器的服务器上设置 iptables。Docker 生成的默认规则将默认策略设置为 ACCEPT,但我希望以更严格的方式设置它:将默认策略设置为 DROP 并仅向 Internet 公开特定端口(HTTP、SSH 等)。
我有一个应用程序容器-p 0.0.0.0:8080:3000
在端口 80 上作为 nginx 反向代理的上游运行。
以下是我目前拥有的 iptables 规则:
*nat
:PREROUTING ACCEPT [259:17205]
:INPUT ACCEPT [112:6660]
:OUTPUT ACCEPT [100:6000]
:POSTROUTING ACCEPT [45:2680]
:DOCKER - [0:0]
-A PREROUTING -m addrtype --dst-type LOCAL -j DOCKER
-A OUTPUT ! -d 127.0.0.0/8 -m addrtype --dst-type LOCAL -j DOCKER
-A POSTROUTING -s 172.17.0.0/16 ! -o docker0 -j MASQUERADE
-A POSTROUTING -s 172.17.0.4/32 -d 172.17.0.4/32 -p tcp -m tcp --dport 3000 -j MASQUERADE
-A POSTROUTING -s 172.17.0.4/32 -d 172.17.0.4/32 -p tcp -m tcp --dport 3000 -j MASQUERADE
-A POSTROUTING -s 172.17.0.4/32 -d 172.17.0.4/32 -p tcp -m tcp --dport 3000 -j MASQUERADE
-A POSTROUTING -s 172.17.0.4/32 -d 172.17.0.4/32 -p tcp -m tcp --dport 3000 -j MASQUERADE
-A POSTROUTING -s 172.17.0.4/32 -d 172.17.0.4/32 -p tcp -m tcp --dport 3000 -j MASQUERADE
-A DOCKER -i docker0 -j RETURN
-A DOCKER ! -i docker0 -p tcp -m tcp --dport 8080 -j DNAT --to-destination 172.17.0.4:3000
COMMIT
# Completed on Thu Feb 18 12:57:58 2016
# Generated by iptables-save v1.4.21 on Thu Feb 18 12:57:58 2016
*filter
:INPUT DROP [9:449]
:FORWARD DROP [0:0]
:OUTPUT DROP [5:300]
:DOCKER - [0:0]
:DOCKER-ISOLATION - [0:0]
-A INPUT -i lo -j ACCEPT
-A INPUT -p tcp -m tcp --dport 22 -m state --state NEW,ESTABLISHED -j ACCEPT
-A INPUT -p tcp -m tcp --sport 22 -m state --state ESTABLISHED -j ACCEPT
-A INPUT -p tcp -m state --state NEW,ESTABLISHED -m tcp --dport 2376 -j ACCEPT
-A INPUT -p tcp -m state --state NEW,ESTABLISHED -m tcp --dport 80 -j ACCEPT
-A INPUT -p tcp -m tcp --sport 80 -m state --state ESTABLISHED -j ACCEPT
-A INPUT -p tcp -m tcp --sport 443 -m state --state ESTABLISHED -j ACCEPT
-A INPUT -p udp -m udp --sport 53 -j ACCEPT
-A INPUT -p icmp -m icmp --icmp-type 8 -j ACCEPT
-A INPUT -p icmp -m icmp --icmp-type 0 -j ACCEPT
-A FORWARD -j DOCKER-ISOLATION
-A FORWARD -o docker0 -j DOCKER
-A FORWARD -o docker0 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-A FORWARD -i docker0 ! -o docker0 -j ACCEPT
-A FORWARD -i docker0 -o docker0 -j ACCEPT
-A OUTPUT -o lo -j ACCEPT
-A OUTPUT -p tcp -m tcp --sport 22 -m state --state ESTABLISHED -j ACCEPT
-A OUTPUT -p tcp -m tcp --dport 22 -m state --state NEW,ESTABLISHED -j ACCEPT
-A OUTPUT -p tcp -m state --state ESTABLISHED -m tcp --sport 2376 -j ACCEPT
-A OUTPUT -p tcp -m state --state ESTABLISHED -m tcp --sport 80 -j ACCEPT
-A OUTPUT -p tcp -m tcp --dport 80 -m state --state NEW,ESTABLISHED -j ACCEPT
-A OUTPUT -p tcp -m tcp --dport 443 -m state --state NEW,ESTABLISHED -j ACCEPT
-A OUTPUT -p udp -m udp --dport 53 -j ACCEPT
-A OUTPUT -p icmp -m icmp --icmp-type 0 -j ACCEPT
-A OUTPUT -p icmp -m icmp --icmp-type 8 -j ACCEPT
-A DOCKER -d 172.17.0.4/32 ! -i docker0 -o docker0 -p tcp -m tcp --dport 3000 -j ACCEPT
-A DOCKER-ISOLATION -j RETURN
COMMIT
问题是它们的限制太多:nginx 无法访问容器。
我发现如果我运行:
iptables -I INPUT -i docker0 -j ACCEPT
iptables -I OUTPUT -o docker0 -j ACCEPT
它可以工作,而且还会使容器可通过互联网访问。
我尝试添加-s 0.0.0.0
但没有帮助。
我究竟做错了什么?
答案1
当我删除
-A POSTROUTING -s 172.17.0.4/32 -d 172.17.0.4/32 -p tcp -m tcp --dport 3000 -j MASQUERADE
从nat
表和
-A DOCKER -d 172.17.0.4/32 ! -i docker0 -o docker0 -p tcp -m tcp --dport 3000 -j ACCEPT
从filter
表中可以看出,一切都按照我想要的方式进行。