2026 年 4 月 18 日,WireGuard 创始人 Jason Donenfeld 正式宣布 WireGuardNT 与 WireGuard for Windows 达到 1.0 稳定版。这一版本解决了长期困扰开发者的两个核心阻塞问题,标志着 WireGuard 在 Windows 平台上的工程成熟度迈上新台阶。本文从内核驱动与用户态两个维度,深入剖析此次更新的关键技术实现。
第一个重大改进:稳定的设备上下文获取机制
WireGuard 在 Windows 上采用 NDIS(Network Driver Interface Specification)架构实现内核级数据平面。其 IOCTL 机制通过 piggyback 在 NDIS 设备节点上实现,从而继承 NDIS 的设置与权限模型。每个 IOCTL 请求通过设备的 “功能设备对象”(Functional Device Object,FDO)传递。问题的关键在于:如何从 FDO 的指针获取 WireGuard 专用的状态结构。
在 Windows NT 内核中,FDO 的 DeviceExtension 字段指向 NDIS_MINIPORT_BLOCK 结构,该结构内部包含指向驱动程序私有状态的指针。然而,这个指针位于 NDIS_MINIPORT_BLOCK 的非文档化偏移位置,意味着微软可能在未来版本中调整这一结构,导致兼容性问题。此前的实现使用 FDO 的 Reserved 成员存储指针,但这是一个未定义用途的字段,堪称 “定时炸弹”。
WireGuard 1.0 解决方案是调用 NdisWdfGetAdapterContextFromAdapterHandle () 函数。该函数原本是 NetAdapterCx(新一代网络适配器框架)引入的,自 Windows 10 首个版本起就已存在,具有极高的稳定性保证。其内部实现正是访问 NDIS_MINIPORT_BLOCK 中存放驱动特定状态的正确偏移位置。代码实现简洁优雅:通过检查 DeviceType 为 FILE_DEVICE_PHYSICAL_NETCARD 且 DeviceExtension 有效后,直接调用该函数返回 WG_DEVICE 指针。开发者 Jason 在公告中表示,这一改动将确保未来版本的可靠性。
第二个重大改进:MTU 变更通知的精确捕获
MTU(Maximum Transmission Unit)管理是 WireGuard 实现安全性的关键一环。WireGuard 将数据包填充至最近的 16 字节倍数,但上限为接口的 MTU 值,以此抵御流量分析攻击。这意味着内核驱动必须精确知晓当前接口的 MTU 值。
在 Linux 平台上,这一看似简单的需求极易满足 ——MTU 是网络接口的固有属性,通过 skb->dev->mtu 即可获取。然而在 Windows 系统中,MTU 是多重属性的组合:网络适配器的最小与最大 MTU、TCP/IP 接口层选定的 MTU(区分 IPv4 与 IPv6)、以及子接口级别的 MTU 配置。PowerShell 的 Set-NetIpInterface 通过 SetIpInterfaceEntry () 修改接口级 MTU,而 netsh.exe 则修改子接口级 MTU,两者相互影响且行为微妙。
更棘手的问题是获取变更通知。标准做法是调用 NotifyIpInterfaceChange () 注册回调,在 MTU 变化时触发通知。然而,微软的回调机制根本不触发 MTU 变更事件 —— 这是文档中明确缺失的一环。2021 年微软相关团队曾表示 “这是一个简单的疏忽,应该修复”,甚至提及会 backport 到 2019 年版本,但至今未实现。
WireGuard 之前的 workaround 堪称 “恐怖”:启动一个独立线程,每 3 秒轮询所有 WireGuard 适配器的 GetIpInterfaceEntry ()。开发者本人形容为 “gross dot net”,但这是当时唯一有文档支持的方式。
1.0 版本实现了优雅的解决方案:通过附加到 \Device\Nsi 设备(NSI 是 Windows 网络栈的核心组件),拦截 IOCTL_NSI_SET_ALL_PARAMETERS 消息。具体做法是 reverse engineer 该 IOCTL 的数据结构,匹配 NlInterfaceObject 与 NlSubInterfaceObject 对象类型,从 NSI_IP_INTERFACE_RW 与 NSI_IP_SUBINTERFACE_RW 结构中读取 NlMTU 参数。开发者耗时数周实现了独立的 driver/nsi.c 源代码文件。现在 WireGuard 驱动可以实时响应 MTU 变更,响应时间从 3 秒缩短至毫秒级。
用户态改进与兼容性增强
除上述两大内核级改动外,WireGuard for Windows 1.0 还包含 42 项各类 bug 修复。编译环境升级至 C23 模式,得以使用 typeof () 关键字。在旧版 Windows 10(1809 之前)的 DNS 配置方面,团队 reverse engineering 了 netsh.exe 的底层实现:通过修改注册表特定变量并向 Dnscache 服务发送 SERVICE_CONTROL_PARAMCHANGE 控制信号,取代了之前的 shell 调用方式,消除了对外部进程的依赖。
工程启示
WireGuard Windows 1.0 的发布历程揭示了跨平台网络协议实现的典型挑战:在 Linux 上简洁的需求,在 Windows 复杂而文档缺失的网络栈模型中可能需要数十倍的工程投入。开发者选择深入操作系统内核细节而非依赖不稳定的 workaround,这种对工程质量的坚持值得借鉴。对于需要在 Windows 环境中部署 VPN 的运维团队,1.0 版本提供了更可靠的 MTU 管理和更稳定的驱动模型,建议优先采用。
资料来源:WireGuard 官方邮件列表公告(2026 年 4 月 18 日)。