四个独立的步骤才能把一台路由器的整个 LAN 放到同一条隧道后面。隧道设备需要有归属、有防火墙区域、有朝向上行链路的转换目标;如果部分客户端必须留在 VPN 之外,还需要按源地址分流。连上了却什么都不通,通常就是这四者缺了一个。按依赖顺序做,最后的故障一定属于你刚改的那一步。下面每一步都以可观察的结果收尾,下一步因此不必靠猜。

先决定谁共享这条隧道

负责分发 Wi-Fi 和 DHCP 的那台路由器可以自己跑客户端。这样所有接入设备无需逐台配置就都在隧道后面,多数小型站点要的正是这种形态。它也是隧道一断影响面最大的方案,因为所有设备会同时失去出口。LAN 里不会剩下任何可用的对外路径。

在第一台之后再加一台路由器、让它用自己的子网跑客户端,可以把隧道限制在它自己的设备上。撤掉更容易,交接时也更好解释。代价是两侧之间若没有路由或端口转发就无法互访。

无论哪种做法,都要让两边的 LAN 子网不同。相同的网段会让一侧看起来是直连的,而 由此产生的黑洞会被当成 VPN 故障 查上好几个小时。

给隧道一个归属

把隧道声明为一个网络接口,有名字、有设备、没有自己的协议。之后网络系统负责创建和管理这个设备,下游一切都按名字而不是按设备引用它。区域正是靠这个找到它。

不要在两处创建同一个设备。在已声明的接口旁边再手工建一条隧道,会得到一个存在却不属于任何区域的设备,或者一个重载后就消失的设备。两者看起来都像客户端失败,而且都不会报出指明真实原因的错。选声明式的那条路,把手写的删掉。

网络、防火墙和 VPN 三处配置里的名字必须完全一致。区域是按名字列举网络的,所以一个拼写错误就会让隧道落在所有区域之外,而接口本身看起来仍然健康。健康却没有策略的接口,是最难察觉的状态。

先划进区域,再放行转发

防火墙区域是策略所在之处:输入、输出、转发与 masquerade。不在任何区域里的隧道由你并未选择的默认值支配,这很少是路由器客户端需要的。下面的配置声明接口、把它放进区域,并允许 LAN 流量进入该区域。

config interface 'vpn'
    option device 'tun0'
    option proto 'none'

config zone
    option name 'vpn'
    list network 'vpn'
    option input 'REJECT'
    option output 'ACCEPT'
    option forward 'REJECT'
    option masq '1'

config forwarding
    option src 'lan'
    option dest 'vpn'

在早于 21.02 的版本里,同一行接口写法是 option ifname,所以粘贴前先确认已安装的固件认哪一种。转发那条配置是允许 LAN 流量使用隧道的许可。没有它,设备在跑、客户端已连、却没有任何 LAN 主机能到达隧道。路由器客户端上最常见的连着但上不了网就是这个。

VPN 区域的 masquerade 会在数据包发出前,把每个 LAN 地址都折算成路由器的隧道地址。这样就省掉了对端回你子网的返回路由。

如果对端已经为你的 LAN 做了路由,关掉 masquerade 能让源地址保持可见,也让按客户端统计的日志有意义。二选一并写下来选的是哪个,因为两种选择日后会带来不同的支持问题。移除默认的 LAN 到 WAN 转发是另一件有自身后果的决定。把它去掉,路由器自己的上网能力也会一起消失。

在 NAT 里写对真正的上行接口

在转换规则靠手写的固件里,出站接口正是最容易写错的那一栏。规则里写着 vlan2 时,如果会话是落在 ppp0 上结束,它什么也不做。完全不带接口的规则还会转换本应保持私密的流量。两种错误都不会自己声张,因为隧道照旧能用。

iptables -t nat -A POSTROUTING -o ppp0 -j MASQUERADE

把这条规则里的 ppp0 换成来自 ip route 或运行中接口列表里的接口,然后在一台 LAN 主机打开页面时看计数器。单运营商的路由器上,针对上行的一条 masquerade 规则通常就够。再给隧道接口加第二条规则,并不能代替第一条。

然后补上决定什么进入隧道的客户端选项。redirect-gateway 指令会把客户端的上网流量送进 VPN,没有它隧道只承载服务器推送的路由。先看生成的路由表,再去动 DNS。

用第二张表拆分 Wi-Fi

一张路由表放不下两个默认路由。因此必须绕开隧道的第二个 SSID 要有自己的子网和自己的表。给走隧道的 SSID 分配独立网段,再用一条选表的规则只把该网段送进隧道。

OpenWrt 上的策略路由套件表达的正是这种组合。手工也能做:一条源地址规则,外加一张默认指向隧道设备的表。

从两个网络分别验证。走隧道的 SSID 上的客户端应显示 VPN 的出口地址,普通 SSID 上的客户端应显示运营商地址。两者看起来一样时,说明规则匹配错了源,或者那张表根本没被查询。重连之后还要再测,因为依赖接口名的规则会在设备重新编号时失效。

怀疑时钟与设备标志位

「 persist-tun 」标志会让隧道设备跨重启保留。这对服务器合适,却会干扰状态本就该从头重建的客户端。排查路由器客户端时先去掉它,因为熬过一次失败协商的设备会掩盖究竟是哪一步坏了。等客户端能稳定连接之后再放回去,不要提前。

另一个悄无声息的故障是时钟。没有电池时钟的路由器从纪元开始计时,也就是说在 NTP 追上之前,证书检查都会失败。动证书之前,先把日志时间戳和真实时间对比一下,因为开机一分钟后才连上的客户端,通常只是在等时间同步。

相关文章