如果 Linux 主机收到并接受 ICMP 重定向(accept_redirects=1
在相关接口上),则此路由的缓存和观察时间是多久?我可以缩短该时间吗?
我之所以问这个问题,是因为我有许多系统被虚假路由污染了,而这些路由很可能是由于不幸的 ICMP 重定向造成的:
$ ip route get 10.2.2.2 10.2.2.2 via 10.2.2.2 dev eth0 src 10.1.1.2 cache <redirected>
他们只是不要忘记重定向,即使在收到最后一个 ICMP 重定向后已超过 12 小时!我必须手动ip route flush cache
删除该条目并恢复正确的路线:
$ ip route get 10.2.2.2 10.2.2.2 via 10.1.1.1 dev eth0 src 10.1.1.2 cache
我首先知道 ICMP 重定向是如何以及为何被发送、接收和接受的,这个问题与此无关。
我认为这与问题无关,但这里有一些细节:
我们有一个内部网络,例如 10.1.0.0/16。其中一台机器 10.1.1.1 是 OpenVPN 服务器,远程客户端在 10.2.0.0/16 内获得分配的地址。其他内部机器有一条静态路由 10.0.0.0/8 --> 10.1.1.1。它故意比 10.2.0.0/16 更宽,因为 VPN 服务器将来可能会为更多客户端提供服务。
不幸的是,我们的配置管理将更宽泛的静态路由 10/8-->10.1.1.1 也推送到 VPN 服务器本身,在那里它被设置为 10/8-->eth0。这种不必要的路由通常没有任何作用。
在正常情况下,此设置工作正常。但随后发生了以下情况:
- VPN 服务器 10.1.1.1 重新启动
- 当 VPN 服务器的 IP 堆栈启动时,其他一些内部主机(例如 10.1.1.2)尝试联系 VPN 客户端(例如 10.2.2.2),但此时 OpenVPN 尚未启动,因此到 10.2.0.0/16 的路由尚未建立
- VPN 服务器
send_redirects=1
在其内部接口上有 eth0,由于路由 10/8->eth0 出现故障,它会将相应的 ICMP 重定向发送回 10.1.1.2 - 10.1.1.2
accept_redirects=1
在其内部接口上缓存了 ICMP 重定向中通告的路由,并拼命向内部网络发送针对 10.2.2.2 的 ARP 请求:
不久之后,VPN 服务器建立其 VPN 路由并停止发送重定向,所有其他 VPN 连接均正常工作。
到目前为止一切顺利。我想我明白发生了什么以及为什么会发生,而且我知道各种短期(在内部主机上)和长期补救的方法(当然,在 VPN 服务器上删除更宽的路由;但我们也可以在内部主机上ip route flush cache
设置;或者在 VPN 服务器上设置),所以就是这样accept_redirects=0
send_redirects=0
不是我的问题。
笔记:
- Ubuntu 内核 3.13.0-141
- Ubuntu 内核 4.4.0-116 的行为似乎有所不同:它还接受 ICMP 重定向(如果
accept_redirects=1
),因为它还开始向目的地发送本地 ARP 请求。但至少只要这些请求没有得到答复,它就会继续将 IP 数据包发送到原始下一跳,并且ip route get 10.2.2.2
仍然显示原始的、未重定向的下一跳。 - 根据https://vincent.bernat.im/en/blog/2011-ipv4-route-cache-linux,
net.ipv4.route.gc_interval
可能在 2.6.38(2011)之前可以统治这个,但之后就不行了。
答案1
ICMP 重定向缓存的时间由 gc_timeout ( /proc/sys/net/ipv4/gc_timeout
) 指定。但请注意,超时从最后一个活动开始,因此在某些情况下故障可能会永远持续下去。
我不确定所有 Ubuntu 发行版是否都具有此功能。