阻止从 Docker 个容器到私有 IP 的传出连接
Block outgoing connections to private IPs from Docker containers
我们 运行 在我们服务器上使用 Docker 的一些服务尝试连接到私有 IP 地址(10.0.0.0/8、192.0.0.0/16、172.16.0.0/ 12, 100.64.0.0/10).
这种行为是正常的,但我们的服务器提供商会检测到这种流量并向我们发送警报。
我们只想停止传出流量,而不是使用 iptables 的传入流量。
这是我们当前的设置:
-A OUTPUT -d 192.168.0.0/16 -m owner --uid-owner `id -u dockeruser` -j REJECT --reject-with icmp-port-unreachable
-A OUTPUT -d 100.64.0.0/10 -m owner --uid-owner `id -u dockeruser` -j REJECT --reject-with icmp-port-unreachable
-A OUTPUT -d 172.16.0.0/12 -m owner --uid-owner `id -u dockeruser` -j REJECT --reject-with icmp-port-unreachable
-A OUTPUT -d 10.0.0.0/8 -m owner --uid-owner `id -u dockeruser` -j REJECT --reject-with icmp-port-unreachable
但这似乎不起作用,因为 Docker 创建了以下规则:
Chain FORWARD (policy ACCEPT)
target prot opt source destination
DOCKER-ISOLATION all -- anywhere anywhere
DOCKER all -- anywhere anywhere
对于服务:
Chain DOCKER (1 references)
target prot opt source destination
ACCEPT tcp -- anywhere 172.17.0.2 tcp dpt:1234
ACCEPT tcp -- anywhere 172.17.0.4 tcp dpt:1234
最后:
Chain DOCKER-ISOLATION (1 references)
target prot opt source destination
RETURN all -- anywhere anywhere
欢迎任何反馈。
您在错误的链中添加了规则。来自 docker 容器的流量通过 filter
table 的 FORWARD
链,而不是 OUTPUT
链。这是因为从主机的角度来看,流量是从docker0
接口传入的,主机只是充当转发器。
为了区分入站和出站流量,使用-i
和-o
选项指定接口。此外,您不能使用 uid 来确定流量是否来自 docker 容器(因为数据不是本地来源的)。检查传入接口就足够了。
因此,将以下规则添加到 DOCKER-ISOLATION
链(从 FORWARD
链调用):
-A DOCKER-ISOLATION -d 192.168.0.0/16 -i docker0 ! -o docker0 -j REJECT --reject-with icmp-port-unreachable
-A DOCKER-ISOLATION -d 100.64.0.0/10 -i docker0 ! -o docker0 -j REJECT --reject-with icmp-port-unreachable
-A DOCKER-ISOLATION -d 172.16.0.0/12 -i docker0 ! -o docker0 -j REJECT --reject-with icmp-port-unreachable
-A DOCKER-ISOLATION -d 10.0.0.0/8 -i docker0 ! -o docker0 -j REJECT --reject-with icmp-port-unreachable
将 docker0
替换为 docker 创建的虚拟接口的名称。
(注意:如果链DOCKER-ISOLATION
不存在,直接追加到FORWARD
链)。
另请查看 iptables -vL
和 iptables -t nat -vL
的输出,以更好地了解地址的转换方式。
无法在已接受的答案下发表评论,所以这是我的解决方案:
Docker provides 它是自己的特殊 DOCKER-USER
链,设计用于在任何其他链之前使用:
Chain FORWARD (policy DROP 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
0 0 DOCKER-USER all -- any any anywhere anywhere
0 0 DOCKER-ISOLATION-STAGE-1 all -- any any anywhere anywhere
0 0 ACCEPT all -- any docker0 anywhere anywhere ctstate RELATED,ESTABLISHED
0 0 DOCKER all -- any docker0 anywhere anywhere
0 0 ACCEPT all -- docker0 !docker0 anywhere anywhere
0 0 ACCEPT all -- docker0 docker0 anywhere anywhere
所以现在您可以像这样添加一个新的拒绝规则:
-I DOCKER-USER -p tcp -d 10.0.0.0/8 --dport 443 -j DROP
我们 运行 在我们服务器上使用 Docker 的一些服务尝试连接到私有 IP 地址(10.0.0.0/8、192.0.0.0/16、172.16.0.0/ 12, 100.64.0.0/10).
这种行为是正常的,但我们的服务器提供商会检测到这种流量并向我们发送警报。
我们只想停止传出流量,而不是使用 iptables 的传入流量。
这是我们当前的设置:
-A OUTPUT -d 192.168.0.0/16 -m owner --uid-owner `id -u dockeruser` -j REJECT --reject-with icmp-port-unreachable
-A OUTPUT -d 100.64.0.0/10 -m owner --uid-owner `id -u dockeruser` -j REJECT --reject-with icmp-port-unreachable
-A OUTPUT -d 172.16.0.0/12 -m owner --uid-owner `id -u dockeruser` -j REJECT --reject-with icmp-port-unreachable
-A OUTPUT -d 10.0.0.0/8 -m owner --uid-owner `id -u dockeruser` -j REJECT --reject-with icmp-port-unreachable
但这似乎不起作用,因为 Docker 创建了以下规则:
Chain FORWARD (policy ACCEPT)
target prot opt source destination
DOCKER-ISOLATION all -- anywhere anywhere
DOCKER all -- anywhere anywhere
对于服务:
Chain DOCKER (1 references)
target prot opt source destination
ACCEPT tcp -- anywhere 172.17.0.2 tcp dpt:1234
ACCEPT tcp -- anywhere 172.17.0.4 tcp dpt:1234
最后:
Chain DOCKER-ISOLATION (1 references)
target prot opt source destination
RETURN all -- anywhere anywhere
欢迎任何反馈。
您在错误的链中添加了规则。来自 docker 容器的流量通过 filter
table 的 FORWARD
链,而不是 OUTPUT
链。这是因为从主机的角度来看,流量是从docker0
接口传入的,主机只是充当转发器。
为了区分入站和出站流量,使用-i
和-o
选项指定接口。此外,您不能使用 uid 来确定流量是否来自 docker 容器(因为数据不是本地来源的)。检查传入接口就足够了。
因此,将以下规则添加到 DOCKER-ISOLATION
链(从 FORWARD
链调用):
-A DOCKER-ISOLATION -d 192.168.0.0/16 -i docker0 ! -o docker0 -j REJECT --reject-with icmp-port-unreachable
-A DOCKER-ISOLATION -d 100.64.0.0/10 -i docker0 ! -o docker0 -j REJECT --reject-with icmp-port-unreachable
-A DOCKER-ISOLATION -d 172.16.0.0/12 -i docker0 ! -o docker0 -j REJECT --reject-with icmp-port-unreachable
-A DOCKER-ISOLATION -d 10.0.0.0/8 -i docker0 ! -o docker0 -j REJECT --reject-with icmp-port-unreachable
将 docker0
替换为 docker 创建的虚拟接口的名称。
(注意:如果链DOCKER-ISOLATION
不存在,直接追加到FORWARD
链)。
另请查看 iptables -vL
和 iptables -t nat -vL
的输出,以更好地了解地址的转换方式。
无法在已接受的答案下发表评论,所以这是我的解决方案:
Docker provides 它是自己的特殊 DOCKER-USER
链,设计用于在任何其他链之前使用:
Chain FORWARD (policy DROP 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
0 0 DOCKER-USER all -- any any anywhere anywhere
0 0 DOCKER-ISOLATION-STAGE-1 all -- any any anywhere anywhere
0 0 ACCEPT all -- any docker0 anywhere anywhere ctstate RELATED,ESTABLISHED
0 0 DOCKER all -- any docker0 anywhere anywhere
0 0 ACCEPT all -- docker0 !docker0 anywhere anywhere
0 0 ACCEPT all -- docker0 docker0 anywhere anywhere
所以现在您可以像这样添加一个新的拒绝规则:
-I DOCKER-USER -p tcp -d 10.0.0.0/8 --dport 443 -j DROP