客户端连接后会显示一对地址,或者一个带着 255.255.255.255 掩码的地址,第一反应往往是服务器发下来的东西坏了。其实没有坏:隧道接口是一条点对点链路,掩码描述的是这一条链路的远端,而不是一片邻居。把这对地址读成本地地址和对端,那个奇怪的掩码、旁边那条单主机路由、缺失的邻居表就都有了解释。同样的读法不能开脱的,是与办公网重叠的地址规划。

为什么隧道链路上的掩码看起来不对

在以太网接口上,地址和掩码说明两件事:这台主机拥有该地址,前缀内的一切都是直接邻居。内核据此推导出链路上的路由,然后为它认为存在的邻居解析链路地址。点对点接口保留归属、去掉邻居,所以客户端那一行里的第二个地址是远端,而不是共享网段上的另一台主机。这里没有硬件寻址、没有解析流量,也没有可加入的广播域,因此接口的行为就像一根只有一个终点的管道。

宽掩码旁边出现单主机路由之所以正常而不是症状,原因也在这里。这条链路上的可达性就是一个地址,内核写下的正是这一点。 把两个地址放在一起读 再断定配置有错,因为任何一个单独看都像错误。

两种拓扑,两种地址形态

较早的点对点拓扑给每个客户端一小段,并使用中间两个地址,因此掩码看起来像网段的一个碎片,而不是一个池子。网段拓扑则从池子里分配带池掩码的地址,并把服务器的隧道地址称为对端。两者都能建立有效链路,区别只在于配置文件中出现哪些地址,以及用户可能质疑哪个掩码。

TopologyClient address shapePeerRoute to expect
Point-to-point block per clientTwo neighbouring addresses inside a small blockThe far address of that blockA single host route on the tunnel device
Shared poolOne address carrying the pool maskThe server's tunnel addressA single host route on the tunnel device

无论哪一行对得上你的客户端,先读对端,因为它点名了远端,从而解释了掩码。在不同拓扑的服务器之间复制配置文件,会让它在新环境里显示错误的形态,这种不一致很容易被误认为服务器故障。

当地址池和办公网争夺同一批比特

由于链路是路由的,地址池需要一个在服务器可达的所有网络中都不出现的前缀。一旦共享,客户端对一段意味着两个地方的地址就只有一条路由,而最后安装的那条路由决定谁赢。故障出现在客户端,可它背后的决定属于地址规划。用户报告的是隧道一起来本地路由器就消失,或者只有部分办公主机有回应。

只是看起来相似的前缀是另一回事,用眼睛比对八位组并不是前缀比较。把两者写出来数一数被掩住的位数:192.168.4.0/24 与 192.168.6.0/24 在前 22 位一致,在第 23 位分岔,因为第三个八位组读作 00000100 与 00000110,所以这两个网络确实彼此独立。把 10.8.0.0/24 放在另一个 10.8.0.0/24 旁边,24 位掩码全部一致,这意味着一条路由无法同时表达两个地方。掩码长度决定比较在哪里停下,后安装的那个网络才是输家。

路由链路给不了的东西

广播和组播不会跨过路由链路,而不少熟悉的特性就建立在它们之上。浏览列表、名称公告和服务发现都假定同一个网段,所以文件服务器可以按地址回应每个请求,却始终不出现在列表里。依赖链路本地广播的名称解析同样会失败,任何配置改动都改变不了隧道能承载什么。这件事重不重要,是需求问题,不是路由问题。

确实需要这些投递的客户端需要桥接接口,它承载以太网帧,因而保留广播域。代价是链路更嘈杂、失去上文所述的干净寻址,以及一旦出现环路就大得多的故障面。切换之前先为需求给出理由,当需求只关乎名称时,优先选择能在路由链路上工作的名称服务。

在改动配置之前先读接口

问内核装了什么,而不是配置文件看起来说了什么。地址输出会显示解释掩码的对端,路由输出会显示是否存在通往它的路径。两者对着隧道设备跑一遍只需片刻,问题就定了。

ip -4 addr show dev tun0
ip route show dev tun0
ip route get 10.8.0.1

如果这三者一致,配置文件就在按它的设定工作,剩下的问题在别处。只在能说出缺失能力的时候才改拓扑,一个不熟悉的掩码不算理由。

相关文章