iptables 将所有流量路由到两个不同的链?

iptables 将所有流量路由到两个不同的链?

我正在调试一个不是我写的 iptables 设置。这个设置应该为路由器本身上运行的一些 Docker 容器(Portainer 和 Nginx Proxy Manager)提供防火墙,但出了点问题,两个 Docker 容器都无法向 WAN 提供网站服务。iptables -L -v -n输出如下所示:

root@FriendlyWrt:/proc/sys/net/bridge# iptables -L -v -n
# Warning: iptables-legacy tables present, use iptables-legacy to see them
Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination         

Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination         
1400K  251M DOCKER-USER  all  --  *      *       0.0.0.0/0            0.0.0.0/0           
1397K  251M DOCKER-ISOLATION-STAGE-1  all  --  *      *       0.0.0.0/0            0.0.0.0/0           
 5815  404K ACCEPT     all  --  *      docker0  0.0.0.0/0            0.0.0.0/0            ctstate RELATED,ESTABLISHED
 2580  116K DOCKER     all  --  *      docker0  0.0.0.0/0            0.0.0.0/0           
15447 7639K ACCEPT     all  --  docker0 !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           

Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination         

Chain DOCKER (1 references)
 pkts bytes target     prot opt in     out     source               destination         
   83  4836 ACCEPT     tcp  --  !docker0 docker0  0.0.0.0/0            172.17.0.2           tcp dpt:9443
    1    60 ACCEPT     tcp  --  !docker0 docker0  0.0.0.0/0            172.17.0.2           tcp dpt:8000
   29  1740 ACCEPT     tcp  --  !docker0 docker0  0.0.0.0/0            172.17.0.3           tcp dpt:443
    1    60 ACCEPT     tcp  --  !docker0 docker0  0.0.0.0/0            172.17.0.3           tcp dpt:81
    2   120 ACCEPT     tcp  --  !docker0 docker0  0.0.0.0/0            172.17.0.3           tcp dpt:80

Chain DOCKER-ISOLATION-STAGE-1 (1 references)
 pkts bytes target     prot opt in     out     source               destination         
15447 7639K DOCKER-ISOLATION-STAGE-2  all  --  docker0 !docker0  0.0.0.0/0            0.0.0.0/0           
1397K  251M RETURN     all  --  *      *       0.0.0.0/0            0.0.0.0/0           

Chain DOCKER-ISOLATION-STAGE-2 (1 references)
 pkts bytes target     prot opt in     out     source               destination         
    0     0 DROP       all  --  *      docker0  0.0.0.0/0            0.0.0.0/0           
15447 7639K RETURN     all  --  *      *       0.0.0.0/0            0.0.0.0/0           

Chain DOCKER-MAN (1 references)
 pkts bytes target     prot opt in     out     source               destination         
 8395  519K RETURN     all  --  br-lan docker0  0.0.0.0/0            0.0.0.0/0           
 2805  167K DROP       all  --  *      docker0  0.0.0.0/0            0.0.0.0/0            ctstate INVALID,NEW
  236 59251 RETURN     all  --  *      docker0  0.0.0.0/0            0.0.0.0/0            ctstate RELATED,ESTABLISHED
1388K  251M RETURN     all  --  *      *       0.0.0.0/0            0.0.0.0/0           

Chain DOCKER-USER (1 references)
 pkts bytes target     prot opt in     out     source               destination         
1400K  251M DOCKER-MAN  all  --  *      *       0.0.0.0/0            0.0.0.0/0           
  236 59251 REJECT     all  --  eth0   docker0  0.0.0.0/0            0.0.0.0/0            reject-with icmp-port-unreachable
1397K  251M RETURN     all  --  *      *       0.0.0.0/0            0.0.0.0/0           

看起来在“forward”链的开头,所有流量都被发送到“docker-user”链,然后在下一个规则中,所有剩余流量都被发送到“docker-isolation-stage-1”链。我认为在将所有内容发送到“docker-user”后,将不再有流量需要排序,并且链的其余部分将完全未使用。但似乎每条规则捕获的流量数量相等,然后更多的流量继续到第 3 行。这是怎么回事?“forward”的前两行实际上在测试什么?

答案1

在移动设备上,评论太长

似乎您认为将数据包发送到自定义/新链意味着它不会从那里返回。这有点不正确。

iptables 中的规则会按顺序进行检查

当数据包与对该数据包的命运做出最终决定的规则匹配时,处理将停止(通常是 ACCEPT、DROP、REJECT 以及我可能忽略的其他规则)

当规则跳转到新的/自定义的链时:

  • 进入该链
  • 按顺序检查该链中的所有规则,直到对该数据包的命运做出最终决定
  • 如果没有对数据包的命运做出最终决定:
    返回上一个链

这就是 DOCKER-USER 链中发生的情况,只有少数数据包与 DOCKER-MAN 链中的规则或后续 REJECT 规则匹配,从而导致最终决策。几乎所有进入的数据包都不符合最终决策并返回到 FORWARD 链,在那里它们由下一条规则处理,它们将进入 DOCKER-ISOLATION-STAGE-1 链

相关内容