我在 CentOS 6.2(内核 2.6.32-220)上遇到了路由问题
设置如下:一台主机位于我的本地网络上。它与远程位置上的两台几乎相同的主机通信。这两台远程主机位于相同的网络上,彼此充当冗余备份。
我从本地主机设置了两个 GRE 隧道,每个远程主机一个:
ip tunnel add name tunnel1 mode gre local 10.2.1.2 remote 10.2.1.1
ip link set dev tunnel1 up
ip route add 172.16.1.0/24 dev tunnel1 metric 101
ip tunnel add name tunnel2 mode gre local 10.2.1.4 remote 10.2.1.3
ip link set dev tunnel2 up
ip route add 172.16.1.0/24 dev tunnel2 metric 102
传出数据包路由正确,没有问题。传入数据包很奇怪。似乎任何具有更高度量的路由的隧道(上例中的隧道 2)都会忽略传入数据包。它们可以正常进入,并且可以在本地计算机上使用“tcpdump -i tunnel2”看到它们,但它们没有正确路由到本地网络。它们只是被丢弃了。我可以切换两个度量,然后隧道 1 将丢弃所有传入数据包。具有较低路由度量的隧道将正确路由数据包,包括传入和传出。
这是“按设计工作”吗?当然,我希望的是两个隧道上的所有数据包都能正确转发。这可能吗?
快速更新:有人建议(我不确定为什么)在“ip tunnel”命令中添加“key”参数。我尝试了这种方法,既为每个隧道使用不同的密钥,也为两个隧道使用相同的密钥,但两次尝试都没有效果。
答案1
感谢 netdev 邮件列表,我找到了答案。有一个我从未听说过的功能,称为“反向路径过滤”。启用后,如果传入数据包到达的接口不是用于将数据包发送到源地址的接口,则此内核路由功能将默默丢弃传入数据包。它旨在用作安全功能,在大多数情况下都是很好的默认设置,特别是当您没有仔细设置 iptables 时。
CentOS(可能还有 RHEL)在 /etc/sysctl.conf(net.ipv4.conf.default.rp_filter = 1)中默认启用反向路径过滤。我在安装脚本中添加了以下命令:
echo 0 > /proc/sys/net/ipv4/conf/tunnel1/rp_filter
echo 0 > /proc/sys/net/ipv4/conf/tunnel2/rp_filter
这将关闭两个伪接口的反向路径过滤,现在一切正常。
请注意,向 sysctl.conf 添加特定接口对我来说不起作用,因为这些接口是“动态”创建的,并且 sysctl.conf 仅在启动时读取。当然,我可以更改 sysctl.conf 中的默认值,但我不想为其他接口禁用该功能。