一台设备可以同时面向两个方向:漫游用户向内接入,而同一台盒子向外连接到出口提供商,使选定的流量经由另一张网络离开。启用两项服务只要几分钟;让二者共存却需要设计,因为第二个角色会重写第一个角色所依赖的路由表。三个条件决定这套安排是否可行,即入站服务是否保留自己的回程、出站隧道是否仍能到达对端、以及你想转发的流量是否被选中走向出口。错一个,你就会得到两条都报告已连接、而彼此之间没有任何有用流量通过的隧道。下面的检查按故障通常出现的顺序逐一确立每个条件。

动任何设置之前,先给两个角色命名

为每个实例记下四项事实:它的远端对端、它的认证材料、它下发的地址池,以及它背后的网络。两个实例是设备上彼此独立的对象,在你的笔记里也应保持独立。后来几乎每一个令人困惑的症状都来自把两者的值混在一起,而两个实例共用一套笔记,正是错误的池落进错误字段的原因。

入站服务需要一张不与出站隧道地址、也不与设备所路由的任何私有网络重叠的隧道网。重叠是唯一会同时让两个角色出症状的错误,而在纸上抓住它便宜得多。配置任何一项服务之前,把两个池和每一条被路由的私有网络放在一处比较。

共用硬件并不意味着共用凭据,来自远程访问池的客户端证书不应当能在出口提供商那边使用。材料分开也让吊销成为本地决定,而不是整个机队的事件。

让服务器的应答留在 WAN 路径上

设备自己生成的应答是粗心默认路由的第一个牺牲品。当漫游用户的封装包到达时,应答是本地发起的流量,必须从该用户进来的那个接口出去。如果出站客户端装了一条会把它截走的默认路由,应答就进了错误的隧道,服务看着仍然健康,会话却停住了。

没有哪一个复选框能一锤定音,因为决定的是出站客户端可以截走哪些流量。要么完全不拉路由、只导向你选定的部分,要么拉取路由并补上那些让设备自身服务继续工作的例外。把选择写在实例旁边,否则下一个人会假设成另一种。

netstat -rn | head -20
pfctl -sr | grep -i vpn
ifconfig | grep -A3 ovpn

按最长匹配读路由表,而不是按你配置任何东西的顺序。问题是哪一个条目在出站对端的地址上胜出、哪一个条目在入站服务的应答上胜出,而这两个答案可能不同。

别让出站隧道吃掉自己的端点

出站客户端必须能到达对端的公网地址,才谈得上建立隧道。如果这个地址本身被路由进隧道,客户端就是在追自己的尾巴:传输永远起不来,或者刚起来就在路由装入的那一刻掉线。日志看起来像认证超时而不是路由故障,所以更该先查路由。

在凭据之前检查路由,隧道起来之后再查一次,因为条目可能在启动时正确、一分钟后却错了。对端的地址必须指向普通 WAN 路径,绝不能指向隧道设备。传输稳定之后,有意思的问题转到被转发的流量上,那是下一个决定。

netstat -rn | grep -F '198.51.100.10'
traceroute -n 198.51.100.10

选择哪些用户获得出口

源策略属于流量进入设备的入口,所以要选远程访问池,或池内更窄的身份。保住那些绝不能送往出口的私有目的地和管理例外,并把那些规则放在宽规则之前。出口路径随后需要自己的地址转换或一条被路由的回程安排,在多数设计里就是在出口接口上做覆盖该池的出站 NAT。转换不选择出口;它只重写已经离开的东西,所以无关 WAN 上的 NAT 规则对选择毫无改变。

确认远端允许来自这套设计的转发流量,因为有的提供商会放行,有的不会。差别表现为隧道连上了却什么也不搬运,这很容易被误读成本地故障。把三条流分开测试,因为它们各自独立失败,而三条中两条对,只是搭了一半的设计。

openvpn --config user07.ovpn
curl -sS https://ifconfig.me
curl --interface 10.10.10.1 -sS https://intranet.corp.example/health

第一条命令是漫游用户的外层连接,当客户端报告初始化序列完成时它就算工作。第二条在那台已连上的笔记本上运行,应当报告出口提供商的地址,而不是你的 WAN 地址。第三条在设备上绑定池中某个地址运行,它在完全不牵涉远程用户的情况下检验转发流量的源策略。如果它反而从 WAN 应答,说明策略没有匹配,改多少 NAT 都修不好选择问题。

决定出口失败时会发生什么

在故障发生之前写清行为:出站隧道掉线时,用户是退回普通 WAN,还是被阻断直到出口恢复?两种答案都站得住,而设备不会替你选。删掉一条路由、或让策略指向一个死网关,并不会自动产生完全阻断的结果。想要阻断,策略必须明确写出来,并且要用拿走出口的方式去测,而不是靠推理。想要退回,就要向用户公布,因为悄悄走普通路径的流量,正是有人以为被覆盖的那些流量。

停用客户端实例,观察已连上的用户还能到达什么,然后再启动它。超时的请求就是你要求的完全阻断结果;用 WAN 地址应答的请求,就是你没有记录在案的退回。对 IPv6 和 DNS 也重复这项检查,因为为 IPv4 写的策略对 AAAA 流量只字未提,而任何一条隧道推下去的解析器,都会从查询真正离开的地方应答。

pfSsh.php playback svc stop openvpn client 2
curl --max-time 6 -sS https://ifconfig.me
pfSsh.php playback svc start openvpn client 2

Netgate 的受路由 OpenVPN 配方 展示了源策略、接口分配与出站转换如何配合,它站点到站点的适用范围正是不能照单全抄的部分。它不会告诉你的是:上面三个条件里,你自己的设计已经弄坏了哪一个。

相关文章