route-gateway 不是 redirect-gateway:真正改变的是什么
这个选项只为 OpenVPN 安装的路由提供下一跳。删除它并不会关闭被推送的完整隧道,修复应落在重定向设置上。
隧道已经建立,私有子网也有响应,可即便有人从配置文件中删掉了网关那一行,普通上网流量仍然消失在 VPN 里。这种组合正是改错指令的指纹。被删掉的那行只是在为客户端安装的路由提供下一跳;而继续捕获流量的设置来自别处,是由服务端推送的。覆盖范围和下一跳是两件不同的事,只有前者决定公网目标是否走隧道。
你删掉的那行是下一跳,不是策略开关
客户端安装的每条路由都需要一个网关地址作为指向,当路由本身没有指定地址时,网关指令就是该地址的来源。删掉它,这些路由就无处挂靠,要么安装失败,要么落到一条不通往任何地方的路径上。私有子网正是这类路由所承载的内容。
与此同时,存活下来的行为另有作者:推送块中的重定向选项,它按自身标志把普通出站流量移入隧道。删除网关既不会关闭它,也不会削弱它。结果是两种状态中最糟的一种:公网流量仍被捕获,而当初让隧道有意义的私有目标却无法访问。这也正是同样思路下的第二处改动毫无效果的原因。
四个杠杆,四件不同的事
在这场讨论里,四条指令常被混着引用,而其中只有一条决定覆盖范围,也就是哪些目标会走隧道。第二条设定路由使用的下一跳,第三条安装单个前缀,第四条则丢弃服务端推送的一切,包括部署所需的私有路由。表格按管理员想改变的内容而非按名称排序,因为混淆恰恰来自名称。请把它们当作四个彼此独立的决定,只改你真正想撤销的那一个。
实践中这四条往往成块推送、逐行出现,看起来像同一项设置的各部分。它们并不是,OpenVPN 参考文档正因如此才把它们记作不同机制。弄清自己在撤销哪个决定才是难点,改动本身只有一行。
| What you are trying to change | Directive that decides it | What it leaves alone |
|---|---|---|
| Which destinations use the tunnel | redirect-gateway | Per-prefix routes and resolver choice |
| The next hop a pushed route points at | route-gateway | Coverage of public destinations |
| One reachable prefix | route | Every other destination, default path included |
| All pushed routing and DNS at once | route-nopull | Nothing, which is the problem |
过滤推送行,保留下一跳
如果你反对的覆盖范围是以推送选项的形式到达的,那么范围最小的做法是按名称忽略该选项,让推送块的其余部分保持原样。写成过滤器就是下面这一行,它应放在受影响客户端的配置文件里,而不是服务端配置里。
pull-filter ignore "redirect-gateway"
“窄”正是关键。过滤器比较的是文本前缀,更短的写法也会匹配到下一跳指令,从而恰好剥掉私有路由赖以生存的信息,让原来的错误换件衣服重演。过滤器也只作用于推送选项,因此永远不会碰到本地写入或由网络管理器强加的同义行。之后要重新连接,因为活动会话不会重新评估服务端推送的内容。
读查找结果,别看路由表
重新加载配置后,问问内核两个目标究竟会走向哪里:一个在私有前缀内部,一个在公网。完整转储主路由表更难读,也更容易误读,因为一条路由可以存在却在更具体的匹配面前落败。在策略路由下,规则、路由表和源地址也都要检查。
ip route get 10.40.7.25
ip route get 203.0.113.77
ip rule show
def1 变体值得熟悉,因为它让旧的默认条目仍然可见,而一对半默认条目却赢下查找。因此输出里的 0.0.0.0/0 条目本身证明不了什么。查找回答的是列表看似回答、实则没有回答的问题。
DNS、IPv6 和私有路由仍须正常工作
拒绝一条 IPv4 重定向并不能说明解析器的情况,所以被推送的 DNS 选项仍可能把查询送进隧道,而路由看起来一切正常。IPv6 默认路由也可能对一个 IPv4 检查从未触及的地址族做同样的事。两者都需要明确决定,而不是想当然。随后要确认私有服务仍能响应,因为丢掉私有路由的分离隧道不是分离隧道,而是坏掉的隧道。
还有一个范围更大的工具值得提醒:route-nopull 会丢弃所有推送路由和所有推送的 DNS 选项,它当然能止住完整隧道,也同样当然会破坏部署所依赖的私有路由,所以它比只针对一个选项的名称过滤器重得多。每次改动之后都要检查私有目标、公网目标和解析器,并把一次完成的握手只当作握手本身的证据。