iptables 链 DOCKER-USER 似乎不起作用

iptables 链 DOCKER-USER 似乎不起作用

我使用 ipset 来阻止我的服务器上来自许多国家(除法国和法语国家外几乎全世界)的 IP 范围。

我在 ipset 中有两个规则集: badbadworld1 和 badbadworld2

我的主机正在运行docker:一个Nginx docker,以及其他用于不同服务的docker。

# docker -v
Docker version 20.10.17, build 100c701

我想将我的 ipset 添加到 netfilter(在我的主机上),以便仅从我选择的国家/地区访问 Nginx(以及其背后的其他服务)。

当我将 DROP 规则添加到 DOCKER-USER 链时,我没有看到任何数据包被丢弃。

当我将相同的规则添加到 DOCKER 链时,我看到丢弃的数据包。

在这两种情况下,我都可以使用来自被阻止国家/地区的在线代理进行测试。

我可以向两个链都添加 DROP 规则,根据文档,DOCKER-USER 在 DOCKER 之前进行评估,因此在这种情况下,数据包必须由 DOCKER-USER 丢弃,而不是由 DOCKER 链丢弃,对吗?

我测试了这个:

iptables -I DOCKER-USER -m set --match-set badbadworld2 src -j DROP
iptables -I DOCKER-USER -m set --match-set badbadworld1 src -j DROP
iptables -I DOCKER -m set --match-set badbadworld2 src -j DROP
iptables -I DOCKER -m set --match-set badbadworld1 src -j DROP

几分钟后,我的 iptables -v -n -L 如下:

[...]

    Chain FORWARD (policy DROP 0 packets, 0 bytes)
     pkts bytes target     prot opt in     out     source               destination         
     1596  253K DOCKER-ISOLATION-STAGE-1  all  --  *      *       0.0.0.0/0            0.0.0.0/0           
     1188  162K ACCEPT     all  --  *      br-a4cbc882767a  0.0.0.0/0            0.0.0.0/0            ctstate RELATED,ESTABLISHED
       56  3324 DOCKER     all  --  *      br-a4cbc882767a  0.0.0.0/0            0.0.0.0/0           
      352 87455 ACCEPT     all  --  br-a4cbc882767a !br-a4cbc882767a  0.0.0.0/0            0.0.0.0/0           
       43  2580 ACCEPT     all  --  br-a4cbc882767a br-a4cbc882767a  0.0.0.0/0            0.0.0.0/0           
        0     0 DOCKER-USER  all  --  *      *       0.0.0.0/0            0.0.0.0/0           
        0     0 ACCEPT     all  --  *      docker0  0.0.0.0/0            0.0.0.0/0            ctstate RELATED,ESTABLISHED
        0     0 DOCKER     all  --  *      docker0  0.0.0.0/0            0.0.0.0/0           
        0     0 ACCEPT     all  --  docker0 !docker0  0.0.0.0/0            0.0.0.0/0           
        0     0 REJECT     all  --  *      *       0.0.0.0/0            0.0.0.0/0            reject-with icmp-host-prohibited
        0     0 DROP       all  --  docker0 docker0  0.0.0.0/0            0.0.0.0/0 
    
    [...]
    
    Chain DOCKER (2 references)
     pkts bytes target     prot opt in     out     source               destination         
       10   584 DROP       all  --  *      *       0.0.0.0/0            0.0.0.0/0            match-set badbadworld1 src
        1    40 DROP       all  --  *      *       0.0.0.0/0            0.0.0.0/0            match-set badbadworld2 src
        2   120 ACCEPT     tcp  --  !br-a4cbc882767a br-a4cbc882767a  0.0.0.0/0            172.18.0.6           tcp dpt:443
        0     0 ACCEPT     tcp  --  !br-a4cbc882767a br-a4cbc882767a  0.0.0.0/0            172.18.0.6           tcp dpt:80
    
    [...]
    
    Chain DOCKER-USER (1 references)
     pkts bytes target     prot opt in     out     source               destination         
        0     0 DROP       all  --  *      *       0.0.0.0/0            0.0.0.0/0            match-set badbadworld1 src
        0     0 DROP       all  --  *      *       0.0.0.0/0            0.0.0.0/0            match-set badbadworld2 src
        0     0 RETURN     all  --  *      *       0.0.0.0/0            0.0.0.0/0

[...]

您可以看到,对于相同的规则,DOCKER 链中丢弃了 11 个数据包,而 DOCKER-USER 中丢弃了 0 个数据包。

注意:我首先测试仅添加到 DOCKER-USER 链,但我很惊讶没有看到任何丢弃的数据包(可以肯定的是,我试图连接来自被封锁国家的在线代理,我可以连接),向两个链都添加规则是没用的,但这只是为了演示问题。

谢谢 !

答案1

跳转到 DOCKER-USER 链之前所有数据包都已被接受或丢弃。
数据包检查从链中的第一条规则开始,直到匹配到某条规则。如果匹配规则的目标是最终规则,如 ACCEPT、DROP、REJECT,数据包将被接受或丢弃,并且不会再对下一条规则进行检查。在 DOCKER-USER 链之前,您的所有数据包都已匹配了多个 ACCEPT 和 DROP。这就是 -j DOCKER-USER 规则的计数器为零的原因。

    0     0 DOCKER-USER  all  --  *      *       0.0.0.0/0            0.0.0.0/0           

具有 ACCEPT、DROP、REJECT 目标的匹配规则是最终规则- 它停止进一步检查。
在你的情况下,所有被前一个“吃掉”的数据包匹配FORWARD 链中的 ACCEPT 和 DROP 规则,永远不会到达你的 DOCKER-USER 链。

如果 FORWARD 中的所有规则都是自动生成的,并且您无法更改它们的顺序,则可能是 docker 的错误或文档错误。

否则,您应该更改 FORWARD 规则顺序,以便跳转到 DOCKER-USER 位于 ACCEPT ESTABLISHED 规则(#2 规则)之前,或者将您的 DROP 规则直接插入到 ESTABLISHED 之前的 FORWARD 中。

如果 DROP 遵循 ESTABLISHED 规则,则 DROP 将不会立即对已经建立的连接起作用,直到它们明确关闭或超时。

您还应该检查规则的输入/输出接口,因为不清楚您有哪些接口以及您想要丢弃哪些接口的数据包。

相关内容