bypass-dhcp 到底给 OpenVPN 路由方案加了什么
这个标志只安装一条指向隧道外 DHCP 服务器的主机路由。它不是互联网转发、DNS 策略、IPv6 覆盖,也不是移动网络的修复方案。
带有 redirect-gateway def1 bypass-dhcp 的配置把对 IPv4 默认路由的覆盖与一个很窄的例外组合在一起。人们读到最后一个词,就以为它能让移动连接恢复正常,然后花一下午研究这套标志从未支持过的 DHCP 理论。每个部分只做一件事,而那个例外远比它的名声小。
在把只在手机数据下出现的故障归咎于地址分配之前,先把这几个标志拆开看。这一串的两半彼此毫无关系。
两个标志,两件互不相关的事
加上 def1 后,客户端不是替换已有的默认路由,而是添加两条 IPv4 半默认路由。0.0.0.0/1 覆盖地址空间的下半部分,128.0.0.0/1 覆盖上半部分,因此两者合起来能到达任何目的地,同时各自仍比 0.0.0.0/0 更具体。原来的默认路由因此留在路由表里却没赢下这些查找,这让客户端显式路由的一切仍可通过旧网关到达。它还会在表里留下两条互相重叠的默认路由,所以路由转储看起来可能比配置所暗示的更奇怪。
bypass-dhcp 是独立的,它完全不碰默认路由。OpenVPN 2.6 手册把它描述为添加一条通往不在本地子网上的 DHCP 服务器的直连路由,好让租约流量走到隧道之外,并指出该行为只在 Windows 客户端上实现,其他地方可能不可用。
它存在的原因是机械性的。一旦半默认路由抢走出站流量,发往物理网络上 DHCP 服务器的续租就会被打进隧道,除非有东西把那个地址钉在真实接口上。这个标志就是那根钉子。
这个例外实际上管到哪里
连接成功后的一张示意路由表显示了形状:两条经隧道的半默认路由,以及一条经物理网关通往 DHCP 服务器的主机路由。把它当作形状来读,而不是你自己的地址。
0.0.0.0/1 via 10.8.0.1 dev tun0
128.0.0.0/1 via 10.8.0.1 dev tun0
192.168.1.1/32 via 192.168.1.254 dev wlan0第三行只点名一个目的地。它不是解析器设置,不是对本地网络的一般许可,也不是服务器上的出站规则。蜂窝网络上的手机可能根本没有客户端能这样识别的 DHCP 服务器,所以这个标志在那里什么也改不了。
检查客户端实际装上了什么
要区分写在配置里的选项、服务器提供的选项,以及连接所有者真正应用的路由。拒绝不支持标志的客户端可能保留其余配置,于是隧道照样起来,而那个例外干脆不存在。请读客户端自己的日志和最终路由表,而不是假定文件里的那一行已经生效。这三件事可以同时成立,而只有最后一件改变数据包真正去哪里。
同时保持通往 VPN 端点的那条路由可用。端点例外和 DHCP 例外是两个不同的要求,缺了它,隧道可能把维持自身的那条传输也吞掉。
对于某个应用目的地,要在它失败的上下文里看实际查找结果。更具体的本地路由、策略路由和按应用的排除都会改变答案,所以存在两条半默认路由并不等于盘点了所有流量。
剩下的路径不在这个标志里
服务器仍然需要被允许转发客户端的互联网流量,并且要有能把流量送回去的出口安排。客户端侧的任何路由都变不出服务器上缺失的转发或源地址转换,也没有哪个标志能替代一条可用的回程。
名称解析和 IPv6 各自都需要自己的策略。IPv4 覆盖既不会把解析器指向隧道侧的服务器,也不会建立 IPv6 覆盖,而只重定向 v4 的客户端会让 v6 路径原样保留。
在配置和目的地保持不变的情况下,用同一个被批准的无害请求,分别在可用和失败的访问路径上比较。记录差异究竟在名称解析、隧道建立、路由选择还是被转发的流量上,并把结论和配置放在一起。正是这份记录让下一个人不会把 DHCP 够不着的问题算在它头上。