iptables/nat/prerouting 忽略 UDP 数据包吗?

use*_*554 6 nat iptables linux-networking dnat

在许多具有不同内核版本的服务器上具有相同的效果。

Iptables DNAT 规则有多种:

iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 12345 -j DNAT --to-destination 10.20.30.40:5678
iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 23456 -j DNAT --to-destination 10.11.12.13:5789
....
iptables -t nat -A PREROUTING -i eth0 -p udp --dport 34567 -j LOG --log-prefix 'natudp: '
iptables -t nat -A PREROUTING -i eth0 -p udp --dport 34567 -j DNAT --to-destination 10.55.66.77:34567
Run Code Online (Sandbox Code Playgroud)

问题:UDP 规则不适用于来自 eth0 的传入请求。
它们的数据包和字节计数器的值为零。
简化(删除 dport)没有效果。
结果,请求被传递到过滤器/输入链而不是转发。

来自虚拟接口(tap、veth)的数据包不存在这样的问题 - 它们被预路由规则捕获。
TCP 则没有这样的问题。
UDP答案没有这样的问题。
但来自 eth0 的传入 UDP 请求会被预路由规则忽略:

# iptables -t nat -nvL PREROUTING
Chain PREROUTING (policy ACCEPT 3 packets, 174 bytes)
 pkts bytes target   prot opt in     out   source        destination         

(testing rules)
    2   126 LOG      udp  --  *      *     0.0.0.0/0     0.0.0.0/0      LOG flags 0 level 4 prefix "prerouting-udp: "
    0     0          udp  --  *      *     1.2.3.4       0.0.0.0/0               
    0     0          udp  --  *      *     1.2.3.4       0.0.0.0/0      udp dpt:25826
    0     0          udp  --  eth0   *     0.0.0.0/0     0.0.0.0/0      udp dpt:25826
    0     0          udp  --  eth0   *     1.2.3.4       0.0.0.0/0           
    0     0          udp  --  eth0   *     1.2.3.4       0.0.0.0/0      udp dpt:25826

(production rules)
    7   412 DNAT     tcp  --  eth0   *     0.0.0.0/0     0.0.0.0/0      tcp dpt:12345 to:10.20.30.40:8080
   63  3804 DNAT     tcp  --  eth0   *     0.0.0.0/0     0.0.0.0/0      tcp dpt:56789 to:10.30.40.50:8000
    0     0 DNAT     udp  --  eth0   *     1.2.3.4       0.0.0.0/0      udp dpt:25826 to:10.40.50.60:25826
Run Code Online (Sandbox Code Playgroud)

有任何想法吗?

Ben*_*Ben 1

这里同样的事情。作为最后要检查的事情,请检查 conntrack 表。就我而言,重置跟踪的连接可以使规则立即生效。

apt install conntrack -y
# see current UDP connection
conntrack -L -p udp --dport 34567
# in OP's case purge tracking entries per rule U:dport=34567
conntrack -D -p udp --dport 34567
# if not care
# conntrack -D -p udp
Run Code Online (Sandbox Code Playgroud)

或者,如果正常运行时间对设备来说并不重要,只需重新启动即可,这是另一种方式conntrack -D