Windows 上 dev tun 仍显示 TAP 适配器,这样算错吗?
dev tun 配置下出现 TAP-Windows 适配器是正常的。三层驱动是一个可选的开关,判断实际跑的是哪一个要看客户端日志,而不是适配器名称。
设备管理器显示的是 TAP-Windows Adapter V9,而配置里写的是 dev tun,隧道却能正常工作。这种组合并不是配置错误,来回切换模式也不会改变它。适配器名称反映的是客户端加载了哪个 Windows 驱动,而不是隧道承载哪些数据包。动手修改之前,先读客户端日志里的驱动那一行。
为什么3 层隧道会拿到一块以太网适配器
在客户端 Windows 版本的大部分历史里,并不存在可用的虚拟 3 层适配器。唯一的选择是 TAP-Windows 驱动,它对外呈现的是一个以太网接口。于是客户端模拟了缺失的 2 层行为,好让 Windows 能够对其进行配置。正是因为这段模拟,适配器至今看起来仍像一块网卡。
只要留心,就能看到这段模拟的两个部分:客户端会为隧道地址应答 ARP,并向本机发放一个小型的 DHCP 租约。因此 Windows 看到的是一块带 MAC 地址和 NDIS 驱动的普通以太网适配器,而隧道本身承载的是裸 IP 数据包。以太网这层外衣属于驱动,而不属于隧道模式。
去找驱动那一行,而不是凭名称下判断
不同版本的驱动可能共用同一个名称,所以光看名称无法判断实际跑的是哪一个。客户端日志会写明它打开了哪个设备,较新的版本还会写明它选择了哪个驱动;这才是该读的那一行。
在日志里按顺序查三件事:客户端究竟有没有打开适配器、它报告的是哪个驱动、失败之后有没有回退。回退那一行很容易被漏掉,因为连接照样能建立,只是隧道跑在较旧的驱动上,而用户还以为新驱动已经生效。
切换到 3 层驱动,并确认必须具备哪些条件
WireGuard 项目提供的3 层驱动从客户端版本 2.5 起可用,但它是可选项。加一条指令即可选中它:
windows-driver wintun
驱动必须安装在机器上,官方版本会附带一份已签名的副本。如果你自己打包客户端,就要分发那份已签名的版本,因为私下编译的驱动会与其他 VPN 产品安装的副本发生冲突。这类冲突造成的故障很难归因,通常要等到机器上出现第二个 VPN 客户端才显现。相比之下,驱动缺失反而会在日志里留下清晰的一行。
驱动的权限要求也更严格,所以客户端要通过以特权账户运行的交互式服务来创建适配器。如果把客户端当作普通用户进程启动、没有那个服务,指令就可能失败,于是先前安装的适配器仍然可见,看起来像是切换被忽略了。
什么时候 TAP 仍是正确答案
如果隧道必须承载以太网帧、广播流量或非 IP 协议,那就需要 2 层适配器,TAP 驱动正是由这一需求决定的。Windows 上的桥接方案也有同样的限制,因为接口必须加入某个 2 层域。
在适配器名称这个层面,性能不是二选一的理由。版本 2.6 增加了数据通道卸载驱动,把数据包处理移入内核,而改变吞吐特性的正是这个选项。它属于能力上的取舍,而不是连接的前提,并且取决于版本和已安装的软件包。没有它也能工作的配置依然照常工作。
| What the tunnel must carry | Adapter family | Where it is selected |
|---|---|---|
| IPv4 and IPv6 packets | Layer-3 driver, or the older TAP emulation | Client directive plus installed signed driver |
| Ethernet frames, non-IP protocols | TAP-Windows | Profile mode and the TAP driver package |
| Higher throughput on a supported build | Data-channel offload driver | Client build and driver package, separately from the profile |
切换之后的清理
删除旧适配器与添加新适配器同样重要。 残留的 TAP 接口可能保留上一次会话的地址和路由,而这些条目比创建它们的那次连接存活得更久。在设备管理器里删除那个陈旧设备,然后重新连接,确认路由表里不再提到它。
如果装了多个 VPN 产品,在排查配置之前先记下各自捆绑的是哪一套驱动包。两个客户端安装同一驱动的不同版本,这种冲突无论怎么改配置都解决不了。卸载不再使用的客户端并重启,然后到设备管理器里查找重复的适配器。只有做完这一步,再去比较两个产品的日志行才有意义。