数据包似乎绕过了 netfilter 预路由钩子

网络工程 路由 linux 包分析 日志记录
2021-08-03 17:45:01

为了调试网络问题,我引入了 iptables 日志记录:

for chain in INPUT FORWARD OUTPUT; do
    iptables -A $chain -j LOG --log-level info --log-prefix filter_$chain
done
for chain in PREROUTING INPUT OUTPUT POSTROUTING; do
    iptables -t nat -A $chain -j LOG --log-level info --log-prefix nat_$chain
done

现在出于测试目的,我创建了两个网络命名空间和两个 v​​eth 对,以便网络命名空间通过默认命名空间进行通信:

namespace a               default namespace         namespace b
10.20.30.50 ---- 10.20.30.40  <------>  1.2.3.4 ---- 1.2.3.5
          veth pair          forwarding        veth pair

当我输入命名空间 a 并在命名空间 b 中 ping 主机 1.2.3.5 时,回显请求和回复将在默认命名空间中转发。在系统日志中,我看到以下内容:

nat_PREROUTING [...] SRC=10.200.30.50 DST=1.2.3.5 [...] TTL=64 ID=16847 DF PROTO=ICMP TYPE=8 CODE=0 ID=14460 SEQ=1
filter_FORWARD [...] SRC=10.200.30.50 DST=1.2.3.5 [...] TTL=63 ID=16847 DF PROTO=ICMP TYPE=8 CODE=0 ID=14460 SEQ=1
nat_POSTROUTING [...] SRC=10.200.30.50 DST=1.2.3.5 [...] TTL=63 ID=16847 DF PROTO=ICMP TYPE=8 CODE=0 ID=14460 SEQ=1

filter_FORWARD [...] SRC=1.2.3.5 DST=10.200.30.50 [...] TTL=63 ID=36035 PROTO=ICMP TYPE=0 CODE=0 ID=14460 SEQ=1

filter_FORWARD [...] SRC=10.200.30.50 DST=1.2.3.5 [...] TTL=63 ID=16866 DF PROTO=ICMP TYPE=8 CODE=0 ID=14460 SEQ=2
filter_FORWARD [...] SRC=1.2.3.5 DST=10.200.30.50 [...] TTL=63 ID=36274 PROTO=ICMP TYPE=0 CODE=0 ID=14460 SEQ=2

我想知道为什么只有第一个回显请求命中 PREROUTING 和 POSTROUTING 链中的日志目标,而所有后续包仅命中 FORWARD 链中的日志目标。

1个回答

这是路由缓存和连接跟踪的副作用。新流的数据包将通过完整堆栈,所有后续数据包都匹配现有流(conntrack 条目)并立即转发。