![在转发之前通过 TUN 设备路由所有数据包](https://linux22.com/image/176534/%E5%9C%A8%E8%BD%AC%E5%8F%91%E4%B9%8B%E5%89%8D%E9%80%9A%E8%BF%87%20TUN%20%E8%AE%BE%E5%A4%87%E8%B7%AF%E7%94%B1%E6%89%80%E6%9C%89%E6%95%B0%E6%8D%AE%E5%8C%85.png)
我有一个应用程序,它创建一个 TUN 设备,然后检查进入该接口的所有数据包,并在检查成功时将它们原封不动地写回 TUN。 (想想防火墙)数据包的来源是运行我的防火墙应用程序的同一设备。该机器(VM,10.0.2.15
)可以使用主路由表到达另一台机器(主机,192.168.1.151
)(无需设置)。我现在的问题是,每当我通过防火墙应用程序发送数据包时,内核似乎都会丢弃它们。具体来说,当我在 TUN 接口上运行 tcpdump 时,我会看到以下内容:
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on tun0, link-type RAW (Raw IP), capture size 262144 bytes
12:24:21.548119 IP 10.0.2.15 > 192.168.1.151: ICMP echo request, id 9967, seq 1, length 64
12:24:21.548248 IP 10.0.2.15 > 192.168.1.151: ICMP echo request, id 9967, seq 1, length 64
12:24:22.555972 IP 10.0.2.15 > 192.168.1.151: ICMP echo request, id 9967, seq 2, length 64
12:24:22.556087 IP 10.0.2.15 > 192.168.1.151: ICMP echo request, id 9967, seq 2, length 64
可以看到每个数据包都被记录了两次。一次当它进入我的应用程序时,一次当它出来时。然而,从那里开始,它似乎消失了。在应该向我的主机发出的接口上执行 tcpdump 时不会显示任何内容。
我在我的虚拟机上配置了以下内容:
# enable forwarding and disable reverse path filtering
sudo sysctl net.ipv4.conf.default.rp_filter=0
sudo sysctl net.ipv4.conf.all.rp_filter=0
sudo sysctl net.ipv4.ip_forward=1
# routes for the packets to take
sudo ip rule add to 192.168.1.151/32 lookup 11 prio 11
sudo ip rule add iif tun0 lookup main priority 10
表 11 告诉数据包进入我的 TUN 设备。其工作原理如 tcpdump 所示。
我还将 iptables FORWARD 和 OUTPUT 链默认设置为 ACCEPT。另外,我使用带有 UDP 的 netcat 测试了流量,以排除数据包找不到返回路径的问题。
我缺少什么?内核丢弃我的数据包的原因可能是什么?
答案1
我有一个应用程序,它创建一个 TUN 设备,然后检查进入该接口的所有数据包,并在检查成功时将它们原封不动地写回 TUN。
我现在的问题是,每当我通过防火墙应用程序发送数据包时,内核似乎都会丢弃它们。
内核看到它发出的数据包进来,因此它得出结论,网络中的某个地方一定存在路由循环,并且为了防止网络被淹没,丢弃数据包。
您已经尝试使用 禁用该行为rp_filter
,但您可能还需要设置accept_local
,因为您的 TUN 接口有一个本地地址。
更好的方法是真正将应用程序用作防火墙,让它创建两个 TUN 接口,一个传入,一个传出,并将其中一个或两个移动到需要的网络命名空间/VM。
这样,您就可以避免看似路由循环的情况。