CentOS7 PREROUTING 之后数据包消失

CentOS7 PREROUTING 之后数据包消失

尝试将数据包转发至 libvirt 机器时,数据包消失了。

传入的请求到达我的接口/公共 IP

Chain PREROUTING (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination
  165  8580 DNAT       tcp  --  em4    *       0.0.0.0/0            50.x.y.z            tcp dpt:80 to:192.168.122.100
...

Chain POSTROUTING (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination
    0     0 MASQUERADE  all  --  *      *       192.168.122.0/24    !192.168.122.0/24
    0     0 MASQUERADE  all  --  *      em4     0.0.0.0/0            0.0.0.0/0
...

并且我对 FORWARD 和 OUTPUT 都有匹配的规则,但都没有命中。

Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination
    0     0 ACCEPT     tcp  --  *      *       0.0.0.0/0            192.168.122.100      tcp dpt:80
...

Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination
    0     0 ACCEPT     tcp  --  *      *       0.0.0.0/0            192.168.122.100      tcp dpt:80
...

所有接口均启用转发:

net.ipv4.conf.all.forwarding = 1
net.ipv4.conf.default.forwarding = 1
net.ipv4.conf.em4.forwarding = 1
net.ipv4.conf.virbr0.forwarding = 1
net.ipv4.conf.vnet5.forwarding = 1

我相信路由是正确的,我可以从我的主机正确访问端点

# ip route get 192.168.122.100
192.168.122.100 dev virbr0 src 192.168.122.1 uid 0
    cache

# curl --head http://192.168.122.100/
HTTP/1.1 302 Found
...

我有完整的规则链,包括所有默认的虚拟器规则。所有链都以 LOG / DROP 结尾,但没有任何相关内容会触及这些规则。我一直tcpdump在所有接口上使用,我看到同步来自请求的数据包是初始 PREROUTING 规则中看到的数据包,但之后什么都没有。

# uname -r
5.5.10-1.el7.elrepo.x86_64

经过 PREROUTING 规则后,这些数据包还能去哪里?我是不是漏掉了什么?


编辑

Gerrit 让我查看了rp_filter似乎正在丢弃数据包的。我确实有 MASQUERADE 规则,但看起来它们可能是错误的。

kernel: IPv4: martian source 192.168.122.100 from 24.xx.yy.zz, on dev em4
kernel: ll header: 00000000: 78 2b cb 34 d5 70 98 52 4a 60 53 5d 08 00        x+.4.p.RJ`S]..

答案1

由于此接口上的路由被拆分为多个接口别名,因此 em4 上的 rp_filter 会丢弃传入的数据包。

通常,使用 DNAT 规则时,回复数据包的 NAT 应在输出时自动反转,以便答案看起来好像来自激活 DNAT 的接口。这似乎在这里不起作用,rp_filter 指示它在回复数据包中看到了未损坏的源地址(这原来是由 DNAT 引起的,它混淆了内核消息)。

或者实际的传入数据包在某种程度上是火星数据包,并且您的系统与它进入的接口有不同的路由,并且由于 DNAT,内核日志消息令人困惑(有迹象表明,当涉及 DNAT 时,此消息确实显示了错误的地址被称为火星)。

基本上,如果ip route get address/32不等于传入接口,则该数据包是火星数据包!您还可以使用松散 rp 过滤(设置为 2),仅在地址不在机器上任何地方时才进行过滤。或者您可以自己设置静态路由,以使这些火星数据包不属于火星数据包。

在 iptables 中,您不能使用 em0:2 之类的接口别名。它只接受主设备。

相关内容