在大规模分布式系统中,路由协议的设计始终是核心挑战。传统的 BGP 路由表膨胀、收敛慢、中心化依赖等问题在互联网规模的网络中愈发突出,而现代无线 Mesh 网络的拓扑动态性又使得传统协议难以适配。Yggdrasil Network 作为一款实验性的开源 Mesh VPN 实现,给出了一种截然不同的答案:基于生成树(Spanning Tree)的路由坐标系统,配合 Bloom Filter 进行邻居可达性传播,从而在完全去中心化的前提下实现高效的包转发。本文将从工程实现角度,深入解析其自组织路由协议与 IPv6 Overlay 网络架构的关键设计。
身份与寻址:公钥即身份
Yggdrasil 的设计哲学极其简洁:一个节点的唯一身份就是其公钥。当节点启动时,会生成一对 Ed25519 或 Curve25519 密钥对,公钥经过 SHA-512 哈希后截取前 16 字节转换为 IPv6 地址。这一地址推导过程是确定性的,意味着同一个节点无论在何处重新加入网络,只要密钥不变,其 IPv6 地址始终一致。这种设计省去了传统网络中必需的地址分配服务器或 DHCP 机制,同时天然绑定了身份与位置 —— 只要知道目标的 IPv6 地址,就可以推导出对应的公钥进行加密通信。
从工程实现来看,这种映射关系是透明的。Yggdrasil 路由器在内部维护一个从 IPv6 地址到部分公钥的映射表,用于加密目的地的数据时直接使用目标地址对应的公钥对数据包进行端到端加密。即使中间节点需要转发流量,它们也无法解密 payload 内容,因为加密层使用的是目标节点的公钥而非中间节点的密钥。这一设计使得 Yggdrasil 网络可以类比为一个完全不可信的传输层 —— 所有穿越其他节点的数据均为密文,安全性不依赖于对中间节点的信任。
树状路由:World Tree 坐标系统
Yggdrasil 最核心的创新在于其树状路由机制,通常被称为 “World Tree”。与传统的基于目的地址最长前缀匹配或 OSPF 链路状态数据库不同,Yggdrasil 中的每个节点都会参与构建一棵全局分布式生成树,并为自身分配一组树坐标(Tree Coordinates)。这棵生成树不依赖任何中心根节点,而是通过节点间的分布式协调自动形成。
每个节点在生成树中都有父节点和子节点,树的构建过程采用了类似于 DHT 中 Kademlia 的递归查找机制。新节点加入网络时,首先需要连接到至少一个已知 peer,随后通过这些 peer 获取当前网络的拓扑信息,逐步推算出自身在生成树中的位置。树坐标本质上一个多维向量,节点通过计算与目标节点在树坐标空间中的距离来决定转发方向 —— 这就是 Yggdrasil 路由的 “贪心前进” 策略。当节点需要转发一个数据包时,它会检查所有邻居节点的树坐标,选择那个在树空间中距离目标最近的节点作为下一跳。这种基于几何距离的转发决策使得每个节点仅需维护少量路由状态即可完成全网范围内的数据包转发,极大降低了路由表规模。
值得注意的是,Yggdrasil 的路由并不完全依赖生成树。当源节点到目标节点之间存在比生成树路径更短的网络路径时,系统会使用源路由(Source Routing)建立一条更直接的路径。源路由的信息被嵌入在数据包头部,中间节点根据预计算的路径信息进行转发。如果这条源路由路径因网络拓扑变化而失效,系统会自动回退到基于树坐标的逐跳转发。这种双模式路由机制既保证了在拓扑频繁变化时的鲁棒性,又在网络相对稳定时提供了接近最优的转发路径。
邻居可达性传播:Bloom Filter 的妙用
在树状路由体系中,如何让每个节点知道 “哪个邻居可以到达哪些目标” 是一个关键问题。传统的做法是每个节点周期性地广播完整的可达性信息,但在节点数量庞大的网络中,这种广播会导致显著的带宽消耗。Yggdrasil 采用了 Bloom Filter(布隆过滤器)来解决这一难题。
每个节点会周期性地构建一个 Bloom Filter,其中包含其已知可达的节点公钥或 IPv6 地址前缀。当节点之间交换路由信息时,它们相互发送自己维护的 Bloom Filter。收到邻居的 Bloom Filter 后,本地节点可以快速判断某个目标地址是否可能通过该邻居到达 —— 如果目标地址的哈希在 Bloom Filter 中出现,则认为存在一条可能的转发路径。由于 Bloom Filter 存在假阳性(false positive)概率,Yggdrasil 在实际使用中将其控制在可接受范围内,偶尔的误判会导致数据包沿着非最优路径转发,但不会导致路由失败。
这种设计的优势在于信息压缩效率极高。相较于传输完整的可达性列表,Bloom Filter 只需用极少的比特位就能表达大量的地址信息。工程实现中,每个 Bloom Filter 通常只有几千字节,却能编码数万甚至数十万目标地址的可达性状态。这使得节点在仅存储少量状态信息的前提下,就能做出相当合理的转发决策。根据官方描述,大多数 Yggdrasil 节点的路由表只有几十到几百条记录,远小于 BGP 路由器中动辄数万条的路由表规模。
端到端加密与安全模型
在 Yggdrasil 中,端到端加密是默认且强制的。所有穿越网络的用户流量都会使用目标节点的公钥进行加密,即使应用层协议本身未加密,Yggdrasil 也会在其基础上再加一层加密保护。这种设计使得中间转发节点完全无法窥探用户数据的内容,只能看到加密后的流量。
加密的实现基于 NaCl(Networking and Cryptography Library)的 /libsodium 密码库,使用 Curve25519 进行密钥交换,XSalsa20-Poly1305 进行对称加密。每个节点在启动时生成密钥对,并在与邻居建立 peering 连接时交换各自的部分信息。需要特别指出的是,peer 之间的传输层连接通常也使用 TLS 1.3 保护,因此有两层加密:传输层加密保护 peering 通道本身,应用层加密保护最终用户数据不被任何中间节点解密。
安全模型上,Yggdrasil 将整个网络视为不可信环境,类似于公共 Wi-Fi 或直接的互联网连接。节点身份由公钥锁定,无法伪造 —— 协议消息使用私钥签名,接收方会验证签名以防止篡改或伪造。这种设计使得网络本身不需要任何信任基础设施(CA 或 PKI),因为每个节点自身的密钥就是其信任锚点。
自组织与自愈机制
Yggdrasil 的另一个核心优势是其强大的自组织能力。节点可以通过两种方式建立 peering:第一种是用户手动配置静态 peering,指定远端节点的 IP 地址和端口;第二种是启用 link-local 组播发现,同一本地网络中的 Yggdrasil 节点会相互发现并自动建立连接。后者使得真正的 “即插即用” Mesh 网络成为可能 —— 只要两台设备在同一个局域网中,Yggdrasil 就能自动发现对方并建立加密通道。
自愈能力体现在多个层面。当生成树中的某个节点离线时,其子节点会重新与网络中的其他节点协调,重新计算自身的树坐标并接入生成树。这一过程通常在数秒内完成,期间丢包率极低。源路由路径的失效同样会触发回退机制 —— 当预计算的直接路径不可用时,数据包会自动切换到基于树坐标的逐跳转发。整个过程对上层应用透明,无需人工干预。
公平队列(Fair Queuing)机制进一步增强了网络的稳定性。每个节点在转发来自不同邻居的流量时,会采用轮转或加权公平队列的方式分配带宽,防止单个恶意节点或高流量节点抢占过多资源。这种分布式拥塞控制使得网络在面对不理性或攻击性流量时仍能保持基本的服务质量。
工程实现与性能特征
Yggdrasil 的当前实现采用 Go 语言编写,运行在用户空间,通过 TUN 接口与操作系统网络栈交互。这意味着它不需要额外的内核模块,可以在大多数主流操作系统上直接运行 —— 包括 Linux、macOS、Windows、iOS 和 Android。Go 语言的并发模型非常适合这种 I/O 密集型的网络代理场景,每个 peering 连接通常对应一个独立的 goroutine,事件的处理高效且代码结构清晰。
从性能角度,Yggdrasil 的转发延迟受网络拓扑深度影响。在典型的互联网 overlay 场景下,跨国转发的延迟通常在几十毫秒到一百毫秒之间,主要取决于物理链路的跳数和拥塞状况,而非协议本身的处理开销。对于局域网的 Mesh 场景,延迟可以控制在几毫秒以内。吞吐量方面,单个节点的处理能力主要受限于 CPU 加密运算和用户态 / 内核态上下文切换的开销,在现代硬件上通常可以达到数百兆比特每秒的转发能力。
部署上,Yggdrasil 的配置极为简洁。安装完成后,仅需在配置文件中指定要连接的 peer 节点(可以是公网 peer 或本地节点),或者直接启用组播发现即可加入网络。没有复杂的路由策略、没有 BGP 会话管理、也不需要额外部署路由服务器。对于希望在不受信任的网络环境中构建安全通信渠道的团队或个人,这种极简的部署模型具有显著的吸引力。
总结
Yggdrasil Network 代表了一种全新的去中心化路由范式:通过将公钥作为身份、将生成树坐标作为路由度量、使用 Bloom Filter 压缩可达性信息,实现了在完全自组织条件下的高效数据包转发。其端到端加密设计确保了穿越不可信网络的通信隐私,而自愈机制与公平队列则为网络的鲁棒性与公平性提供了保障。尽管目前仍处于 alpha 阶段,但其设计理念和技术选型已经为未来的大规模 mesh 网络和隐私通信场景提供了值得关注的工程参考。
资料来源:
- Yggdrasil Network 官方实现文档(https://yggdrasil-network.github.io/implementation.html)
- The World Tree 路由概念说明(https://yggdrasil-network.github.io/2018/07/17/world-tree.html)