IPTables/Docker 设置将数据包路由到 INPUT 链而不是 FORWARD

IPTables/Docker 设置将数据包路由到 INPUT 链而不是 FORWARD

我正在使用 docker 和 iptables 运行多个安装。这些安装的目的之一是转发系统日志消息。我有时会遇到网络数据包停止到达容器的中断情况。在我当前的情况下,系统日志通过端口 514 发送到主机,主机应该将它们转发到容器。根据日志源,数据包通过 UDP 或 TCP 到达。目前,在一个安装中,UDP 数据包不会到达容器。

这是设置:

(1) 容器为 TCP+UDP 暴露端口 514:

/usr/bin/docker run --rm --detach \
-p 514:514/udp \
-p 514:514/tcp \
syslog-container \
${@}

(2)用netstat确认:

root@cc-01-m:~# netstat -plantu | grep 514

tcp  0 0 192.168.8.134:55228 10.68.8.70:514 ESTABLISHED 6844/rsyslogd
tcp6 0 0            :::514             :::* LISTEN      71629/docker-proxy
udp6 0 0            :::514             :::*             71644/docker-proxy

(3) IPTables FORWARD(过滤器)和 DOCKER(预路由)链:

Chain FORWARD (policy DROP 0 packets, 0 bytes)
pkts bytes target           prot opt in out     source      destination
285M 444G  DOCKER-ISOLATION all  --  *  *       0.0.0.0/0   0.0.0.0/0
203M 225G  DOCKER           all  --  *  docker0 0.0.0.0/0   0.0.0.0/0

Chain PREROUTING (policy ACCEPT 8087 packets, 4046K bytes)
 pkts bytes target     prot opt in     out     source               destination
1138M 904G  DOCKER     all  --  *      *       0.0.0.0/0            0.0.0.0/0            ADDRTYPE match dst-type LOCAL

Chain DOCKER (2 references)
pkts bytes target prot opt in      out source    destination
   0     0 RETURN all  --  docker0 *   0.0.0.0/0 0.0.0.0/0
   1    52 DNAT   tcp  -- !docker0 *   0.0.0.0/0 0.0.0.0/0   tcp dpt:514 to:172.17.0.2:514
   0     0 DNAT   udp  -- !docker0 *   0.0.0.0/0 0.0.0.0/0   udp dpt:514 to:172.17.0.2:514

我对此的看法:

  • TCP 和 UDP 的设置相同
  • PREROUTING/DNAT 与 514/UDP 不匹配
  • 下面有一个更新:我同时添加了端口 1514/UDP,它也正在工作......

(4) dmesg 中的结果:

但在 dmesg 中我看到:

工作示例(TCP,OUT=docker0)

[1220244.781877] [FW-ACCEPT] IN=ens192 OUT=docker0 MAC=00:50:56:9c:a0:21:00:09:0f:09:00:21:08:00 SRC=172.16.104.81 DST=172.17.0.2 LEN=2475 TOS=0x00 PREC=0x00 TTL=125 ID=10684 DF PROTO=TCP SPT=57211 DPT=514 WINDOW=8212 RES=0x00 ACK PSH URGP=0

不起作用的示例(UDP、OUT=,表示 INPUT 而不是 FORWARD):

[1219701.100893] [FW-ACCEPT] IN=ens192 OUT= MAC=00:50:56:9c:a0:21:00:09:0f:09:00:21:08:00 SRC=172.16.102.19 DST=192.168.8.134 LEN=793 TOS=0x00 PREC=0x00 TTL=62 ID=13050 DF PROTO=UDP SPT=35541 DPT=514 LEN=773

172.17.0.2是docker容器IP,192.168.8.134是主机IP。因此,尽管有匹配的 PREROUTING,但没有完成路由/转发,但它是匹配的不知何故输入。

(5) DOCKER过滤器链确认

Chain DOCKER (2 references)
pkts  bytes target prot opt in out source destination
1562K 2347M ACCEPT tcp -- !docker0 docker0 0.0.0.0/0 172.17.0.2 tcp dpt:514
   0     0  ACCEPT udp -- !docker0 docker0 0.0.0.0/0 172.17.0.2 udp dpt:514

这里没有 UDP 计数器,PREROUTING 失败。

(六,结论

我只能断定这是一个缺陷。

(7) 问题

有人能明白这一点吗?是否有进一步解决或缓解问题的步骤?

非常感谢你,安德烈亚斯

(八)更新

我为端口 1514/UDP 添加了类似的设置(无论如何都是需要的)。这才有效。我一无所知。会不会是负载问题?端口 514/UDP 上有大量流量。也许流量在 docker 接口出现之前就开始了,并且默认为输入,因为 PREROUTING(尚)不可能???有人吗?

当我尝试使用 TRACE 目标确定差异时,它看起来像这样:

(A) 工作示例(为了可读性而缩短,端口 1514):

[ 4760.393530] TRACE: raw:PREROUTING:policy:2 IN=ens192 OUT= 
SRC=172.16.102.9 DST=192.168.8.134 ID=31601 PROTO=UDP SPT=63830 DPT=1514 LEN=472

[ 4760.393541] TRACE: filter:FORWARD:rule:1 IN=ens192 OUT=docker0 SRC=172.16.102.9 DST=172.17.0.2 ID=31601 PROTO=UDP SPT=63830 DPT=1514 
LEN=472

[ 4760.393546] TRACE: filter:DOCKER-ISOLATION:return:1 IN=ens192 OUT=docker0 SRC=172.16.102.9 DST=172.17.0.2 ID=31601 PROTO=UDP SPT=63830 DPT=1514 
LEN=472

[ 4760.393551] TRACE: filter:FORWARD:rule:2 IN=ens192 OUT=docker0 SRC=172.16.102.9 DST=172.17.0.2 ID=31601 PROTO=UDP SPT=63830 DPT=1514 
LEN=472

[ 4760.393556] TRACE: filter:DOCKER:rule:1 IN=ens192 OUT=docker0 SRC=172.16.102.9 DST=172.17.0.2 ID=31601 PROTO=UDP SPT=63830 DPT=1514 
LEN=472

(B) 不起作用的示例(为了可读性而缩短,端口 514):

[ 5122.397806] TRACE: raw:PREROUTING:policy:2 IN=ens192 OUT= SRC=172.16.102.19 DST=192.168.8.134 ID=55657 DF PROTO=UDP SPT=35541 DPT=514 LEN=451

[ 5122.397811] TRACE: filter:INPUT:rule:7 IN=ens192 OUT= 
SRC=172.16.102.19 DST=192.168.8.134 ID=55657 DF PROTO=UDP SPT=35541 DPT=514 LEN=451

[ 5122.397822] TRACE: filter:OK:return:2 IN=ens192 OUT= 
SRC=172.16.102.19 DST=192.168.8.134 ID=55657 DF PROTO=UDP SPT=35541 DPT=514 LEN=451

备注:我确实有一条记录并接受的链“OK”。

相关内容