Linux下WireGuard站点到站点VPN中,下一跳不可达时自动移除路由条目
这个问题其实挺常见的——Linux静态路由默认不会因为下一跳不可达就自动移除,毕竟内核默认假设静态路由是你明确要保留的。不过不用自己写繁琐的定时ping脚本,有几个更优雅的办法解决:
利用Linux内核的邻居可达性检测(NUD)优化静态路由
你可以在添加路由的时候加上onlink参数,强制内核把下一跳当作直连在WireGuard接口上的邻居,这样内核会自动通过NUD机制追踪这个IP的可达性:ip route add 10.0.0.0/24 via 192.168.192.10 dev wg0 onlink当内核检测到192.168.192.10不可达(比如邻居状态变为
FAILED),这条路由会被标记为不可用,流量不会再走它。不过要注意,这个路由条目不会从路由表中消失,只是进入不可用状态;如果之后下一跳恢复正常,内核会自动把它改回可用状态。用
ip monitor结合轻量脚本自动删除/恢复路由
如果你确实想让路由条目在不可达时彻底从路由表中消失,可以用ip neigh monitor来监听邻居状态的实时变化,然后触发路由的删除或恢复操作。比如写个简单的bash脚本:#!/bin/bash TARGET_NEXTHOP="192.168.192.10" ROUTE="10.0.0.0/24 via $TARGET_NEXTHOP dev wg0" ip neigh monitor | while read -r line; do if echo "$line" | grep -q "$TARGET_NEXTHOP.*FAILED"; then ip route del $ROUTE 2>/dev/null echo "Removed unreachable route: $ROUTE" elif echo "$line" | grep -q "$TARGET_NEXTHOP.*REACHABLE"; then ip route add $ROUTE 2>/dev/null echo "Restored route: $ROUTE" fi done把这个脚本做成systemd服务,就能实现事件驱动的路由管理,比定时ping高效得多——只有当邻居状态变化时才会执行操作,不用周期性轮询。
使用动态路由协议(适合复杂网络场景)
如果你的网络架构比较复杂,或者有多个VPN链路需要故障切换,可以考虑用轻量的动态路由工具,比如BIRD或者FRRouting。这些工具会自动和对端交换路由信息,一旦检测到对端不可达,会自动移除相关路由条目。比如配置OSPF协议,只需要在两端的WireGuard接口上启用OSPF,就能实现路由的自动失效和恢复,完全不用手动维护静态路由。
另外补充一下,你之前尝试的ip route add 10.0.0.0/24 dev wg0这种方式,是把子网直接关联到WireGuard接口上,内核只会检查接口本身是否处于up状态,不会追踪下一跳的可达性,所以不符合你的需求。
备注:内容来源于stack exchange,提问作者rs232




