那个隧道地址是对端,不是你可以浏览的网段
点对点链路上的掩码描述的是远端,而不是一片邻居。在断定网段看起来不对之前,先读一读对端地址。
客户端连接后会显示一对地址,或者一个带着 255.255.255.255 掩码的地址,第一反应往往是服务器发下来的东西坏了。其实没有坏:隧道接口是一条点对点链路,掩码描述的是这一条链路的远端,而不是一片邻居。把这对地址读成本地地址和对端,那个奇怪的掩码、旁边那条单主机路由、缺失的邻居表就都有了解释。同样的读法不能开脱的,是与办公网重叠的地址规划。
为什么隧道链路上的掩码看起来不对
在以太网接口上,地址和掩码说明两件事:这台主机拥有该地址,前缀内的一切都是直接邻居。内核据此推导出链路上的路由,然后为它认为存在的邻居解析链路地址。点对点接口保留归属、去掉邻居,所以客户端那一行里的第二个地址是远端,而不是共享网段上的另一台主机。这里没有硬件寻址、没有解析流量,也没有可加入的广播域,因此接口的行为就像一根只有一个终点的管道。
宽掩码旁边出现单主机路由之所以正常而不是症状,原因也在这里。这条链路上的可达性就是一个地址,内核写下的正是这一点。 把两个地址放在一起读 再断定配置有错,因为任何一个单独看都像错误。
两种拓扑,两种地址形态
较早的点对点拓扑给每个客户端一小段,并使用中间两个地址,因此掩码看起来像网段的一个碎片,而不是一个池子。网段拓扑则从池子里分配带池掩码的地址,并把服务器的隧道地址称为对端。两者都能建立有效链路,区别只在于配置文件中出现哪些地址,以及用户可能质疑哪个掩码。
| Topology | Client address shape | Peer | Route to expect |
|---|---|---|---|
| Point-to-point block per client | Two neighbouring addresses inside a small block | The far address of that block | A single host route on the tunnel device |
| Shared pool | One address carrying the pool mask | The server's tunnel address | A 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
如果这三者一致,配置文件就在按它的设定工作,剩下的问题在别处。只在能说出缺失能力的时候才改拓扑,一个不熟悉的掩码不算理由。