在其中一个站点的工作站上打开终端,并连接到另一个站点的服务器。这条唯一的 TCP 会话现在要穿过四台网关而不是两台,有意思的并不是它在顺利时能不能用。有意思的是前进方向选了哪一对网关、回程由哪一对承载,以及在这期间由谁持有该流的状态。路由表里没有任何东西替你决定这些。

先画四台网关,再画路由

每个站点两台独立 VPN 防火墙、每个运营商一对的双活设计,给你两条可用路径和三种把它弄坏的方式。在配置任何东西之前先把地址写下来:客户端在每台网关前后的样子、服务器同样如此、前进方向的下一跳和回程方向的下一跳。

那张表就是设计。此后的一切都是设备是否与这张表一致的问题。

前进路径是怎么选出来的

等价多路径路由层通过对首部字段做哈希,把流分摊到下一跳,RFC 2992 对此有详细描述。这种选择可以完全无状态:它不需要连接跟踪表项,只需要对不变字段做稳定哈希。只要路径集合与哈希输入保持不变,流的每个报文都会选中同一台下一跳。

按流选择避免了逐包均衡在时延不同的链路上造成的乱序。它并不承诺等价路由成本意味着实测时延相等,因为事实并非如此。而当路径成员发生变化时,流会被重新映射,因此故障期间的连接存活是与路径选择分开的另一项要求。

回程路径真正需要什么

到这里,这套走查不再对称。稳定的前进哈希完全说明不了对端站点会拿回程怎么办。如果一台独立防火墙必须看到连接的两个方向才能维持有用的状态,绕过它的回程路由会让流量什么都匹配不上。两台规则集相似的设备并不等于共享状态。

确认实际实现的双向行为,或者写下明确的策略,让所需边界保持一致。这里的猜测会在故障时被发现,而且发现的人不会觉得愉快。

翻译替你做决定的地方

NAT 是另一个杠杆,而且它是可选项而非必需项。按路径区分的转换身份可以把回程引导回持有状态的那台网关,这是一种正当设计。但它也会增加映射、回程路由和该状态的归属者,所以只为你能够大声说出口的需求承担这份负担。

如果需求只是两条路径都承载流量、并且任一条在运营商中断后存活,那么普通的按流多路径加一致的回程路由通常是更小的设计。

按顺序走完验收

按这个顺序测试并记录每一步的地址:路径 A 上的新连接及其回程路径、路径 B 上同样一遍,然后断掉一个运营商,再恢复。对每个结果,记下哪些已建立的流发生了迁移、哪些必须重连,以及此后新流去了哪里。先把期望值写下来,再与抓包对比。两条已建立的隧道证明不了其中任何一条。

当写下的表与抓包显示的内容一致时,设计才算完成,而不是两条隧道都起来的时候。

相关文章