我有两台位于不同位置的 Debian 机器,并想通过 GRE 启用两个内部子网之间的路由。
我的通用路由已经正常工作,这意味着任何内部机器都会将流量导向通过 GRE 连接的两台机器,并且流量也会通过隧道发送,但是在接收此流量时,它不再转发到本地子网。
我在这两台机器上的配置(不使用实际IP):
主机A(172.19.0.1):
ip tunnel add tun0 mode gre remote 172.20.0.1 local 172.19.0.1
ip addr add 10.10.10.1/24 dev tun0
ip link set tun0 up
主机 B(172.20.0.1):
ip tunnel add tun0 mode gre remote 172.19.0.1 local 172.20.0.1
ip addr add 10.10.10.2/24 dev tun0
ip link set tun0 up
echo 1 > /proc/sys/net/ipv4/ip_forward
对隧道接口 IP(10.10.10.1 和 10.10.10.2)上的任一机器进行 ping 操作都很顺利,但是当我尝试通过隧道 ping 内部 IP(例如ping 10.100.77.8 -I tun0
在主机 AI 上运行)时,没有得到响应。tcpdump
显示甚至没有生成任何响应,这表明数据包在被 GRE 解包后从未到达接口。
root@hostb:~# tcpdump -i any host 172.19.0.1
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on any, link-type LINUX_SLL (Linux cooked), capture size 262144 bytes
10:36:10.983403 IP 10.10.10.1 > 172.20.0.1: GREv0, length 88: IP 10.10.10.1 > 10.100.77.8: ICMP echo request, id 20422, seq 8, length 64
10:36:10.983419 IP 10.10.10.1 > 10.100.77.8: ICMP echo request, id 20422, seq 8, length 64
10:36:11.991415 IP 10.10.10.1 > 172.20.0.1: GREv0, length 88: IP 10.10.10.1 > 10.100.77.8: ICMP echo request, id 20422, seq 9, length 64
10:36:11.991427 IP 10.10.10.1 > 10.100.77.8: ICMP echo request, id 20422, seq 9, length 64
我看不到目标机器 10.100.77.8 上有 ICMP 数据包进入。iptables 中没有配置任何规则,而默认操作始终为ACCEPT
。
答案1
问题解决了。rp_filter
已为隧道接口启用
$ cat /proc/sys/net/ipv4/conf/all/rp_filter
1
$ cat /proc/sys/net/ipv4/conf/tun0/rp_filter
1
更改这两者即可0
解决问题。
答案2
源地址选择似乎有问题,因为 GRE 数据包的外部报头中包含内部隧道地址。外部报头的源地址应该是172.19.0.1
,而不是10.10.10.1
。
10:36:10.983403 IP
10.10.10.1
> 172.20.0.1: GREv0, length 88:\ IP 10.10.10.1 > 10.100.77.8: ICMP echo request, id 20422, seq 8, length 64
检查ip route get 10.100.77.8
主机Aip route get 10.100.77.8 from 10.10.10.1 iif tun0
。还请检查主机B。如果您看到类似的内容,invalid cross-device link
则应禁用rp_filter
。
ip -4 r ls
另外,显示两个主机的“ ”命令的输出。
答案3
我今天遇到的另一个问题也有类似的表现,是由于CentOS 8.3 和 VXLAN 或 GRE 隧道中的错误。
解决方案是禁用 tx-checksum-ip-generic ethtool -K nic1 tx off
。
根据 Redhat 解决方案,该问题应该在 Redhat 8.4 中得到修复。