两个办公室都使用 192.168.77.0/24,于是有人提议建一条隧道,让它们成为一个网络。这个说法听起来简单,却藏了三种完全不同的设计:两个相互冲突的独立 LAN;一条刻意跨越 WAN 延伸的以太网段;以及一种替远端地址应答的 proxy-ARP 安排。你手里是哪一种,决定了主机如何处理数据包,而这个答案在任何 VPN 网关介入之前就已经可见。

主机会先于路由器做出决定

地址为 192.168.77.10/24 的主机把目的地址与自己的前缀比较。落在该前缀内的一切都在本地链路上,于是主机直接解析目的地址的链路层地址。落在外面的则交给默认网关。

这个判断发生在主机的协议栈里,而不是隧道里。在网关上添加路由,救不回一台主机根本没有发出去的数据包。

所以当 192.168.77.20 只存在于另一处站点时,本地主机为它发 ARP 却得不到应答。VPN 握手可以完全健康,而这一步照样失败。这个故障看起来像主机已经死掉,而不像路由问题。认出这个特征,能省下一小时的隧道排障时间。

ARP 问的是本地链路

ARP 问的是这个链路上谁拥有某个地址,而回答必须来自能听见广播的东西。IPsec 隧道另一端的路由器听不到,除非设计把两个站点变成了同一个广播域。

两台设备拥有同一个地址会更糟:即便解析成功,也说不清是谁应答的。

地址重复不是路由缺陷,也没有任何路由能修好它。要么把两个站点重新编址到不同前缀,要么有意让它们成为一个链路层域。

延伸网段承载的是帧,不是路由

承载以太网并接到网桥上的隧道,让两个站点同属一个链路层域。ARP 广播能到达对端,每座网桥学习哪些 MAC 地址在哪里。Linux 网桥文档描述了这条基于 MAC 的转发边界。

在这里,远端网关根本不在两个相同的子网之间做路由。帧穿过自身运行 IP 路由的底层网络,而网桥把以太网会话延长。

代价是更大的影响范围。未知目的的泛洪、环路、DHCP 分配和地址唯一性都需要一份跨两个站点的方案。WAN 一断,主机会丢掉它们认为属于本地的流量。网桥上的过滤和 VLAN 规则可以限制什么东西穿过去,但承载仍然不保证每一个链路本地控制帧都能送达。

Proxy ARP 是第三种设计

路由器可以替远端地址应答 ARP,然后向那里路由。这让远端主机在发送方看来就在本地链路上,而不必拉伸广播域。

它比网桥更窄:依赖转发、回程路由,以及每个地址都有明确归属。

它也不会让任意的非 IP 协议变得可路由,更不复制以太网广播域。只有当需求恰好就是这种替换时才用它,不要把它当成推迟重新编址的捷径。

从需求出发选择,然后验证

对于办公室之间普通的应用访问,不同前缀加显式路由给出更清晰的边界。当需求真的是链路层邻接时才用网桥。如果共享前缀的唯一理由只是还没人动手,那就重新编址。

要确认实际是哪种设计,可以问主机它如何处理目的地址:

ip route get 192.168.77.20
ip neigh show 192.168.77.20

邻居表项失败而结果显示在本地链路上,说明缺少链路层通路。via 结果的输出点名了网关,把问题转到路由。在网桥上,查转发表看看 MAC 是否从隧道学到的。每种输出都在收窄设计问题,而不是从头开始。

相关文章