【问题标题】:Block outgoing connections to private IPs from Docker containers阻止从 Docker 容器到私有 IP 的传出连接
【发布时间】:2017-04-27 16:22:49
【问题描述】:

我们使用 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

感谢任何反馈。

【问题讨论】:

  • 我不是 iptables 专家,但您可以通过在启动时将 --iptables=false 作为标志传递给守护程序来阻止 Docker 修改您的 iptables。
  • 感谢您的建议,但我们希望 Docker 添加它自己的防火墙规则
  • 全有或全无 atm afaik。

标签: docker firewall iptables


【解决方案1】:

您在错误的链中添加了规则。源自 docker 容器的流量通过filter 表的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 -vLiptables -t nat -vL 的输出,以更好地了解地址是如何被翻译的。

【讨论】:

  • 直到我们将规则插入FORWARD 链的第一个位置,-I FORWARD 1 才起作用。我已经编辑了您的答案,但如果违反规则,请自行更新,以便其他人受益。
  • FORWARD 链的开头插入这些规则不是一个好主意,因为它会阻止来自这些 IP 范围的传入流量(您希望允许)。在FORWARD 链的末尾追加,或者如果你有一个名为DOCKER-ISOLATION 的链,追加到它。
  • 原始答案无效,因为DOCKER 链仅用于传出流量(docker0 到物理接口)。我已经编辑了答案。
【解决方案2】:

无法在接受的答案下发表评论,所以这是我的解决方案:

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

【讨论】:

    猜你喜欢
    • 2018-03-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-08
    • 1970-01-01
    • 1970-01-01
    • 2015-10-03
    • 1970-01-01
    • 2019-06-15
    相关资源
    最近更新 更多