WireGuard 无法创建其接口:内核还是权限?
任何对端发起握手之前,接口创建就已经失败。读懂错误信息,区分缺失的模块、权限边界与已存在的接口所有者。
WireGuard 无法创建自己的接口,于是没有设备可配置、没有密钥可交换、也没有握手可调试。失败完全停留在本机,错误文本会说明本地协议栈的哪一层拒绝了请求。正确读懂它,比重新安装对端配置更快。各层是可以分开的,而消息点名了拒绝的那一层。
错误在任何对端开口之前就已发生
创建接口,是向内核发出的一条 netlink 请求,要求一个 wireguard 类型的设备。内核要么有理解该类型的驱动,要么没有,答复会立刻返回。这一步没有任何数据包离开本机,所以端点地址和服务器密钥都不可能是原因。
这个顺序对诊断很重要。如果命令从未创建设备,问题就不可能是公钥写错,也不可能是 UDP 端口被封。先修好本地创建路径,然后再向外看。
究竟该由哪个实现拥有设备
两种实现都可以回应这条请求。内核内的模块注册 wireguard 设备类型,而 wireguard-go 之类的用户态实现以另一种机制提供同样的接口。如果模块缺失,内核会以不支持该设备的错误拒绝请求,解决办法要么是加载模块,要么让工具指向用户态实现。
在两者之间选择之前,先确认实际存在的是什么。第一条命令显示模块是否已加载,第二条则直接向内核发问:
lsmod | grep wireguard
ip link add wgtest0 type wireguard
第二条命令是最小的复现:只要一个设备,别的都不要。如果它以“不支持的类型”失败,缺失的那一环是实现,而不是你的配置文件。
| Error text | What refused | Next step |
|---|---|---|
| Unknown device type or operation not supported | The kernel has no wireguard driver | Load the module or use the userspace implementation |
| Operation not permitted | Missing privilege | Use the service context or grant the capability |
| File exists | The name is already in use | Inspect the owner before touching it |
| No such device in a container | No tunnel device or capability | Add the device and NET_ADMIN to the container |
权限与容器边界
创建并配置网络设备需要权限,要么以 root 身份,要么具备网络管理的权能。普通用户会话做不到,这个限制本身就是设计,而不是可以靠运行一个没审过的安装脚本来绕过的障碍。
在容器里边界翻倍。容器需要访问隧道设备,也需要配置它的权能,而授予这些的标志与 Linux 上的 VPN 容器所用的相同。一个平时能正常上网的受限客户机仍然创建不了接口,因为浏览网页并不需要这种权能。把权能给需要它的服务,而不是给主机上的每个会话。
先解决名称冲突,然后重试
已存在的接口并不自动是残留物。另一个管理器可能占着这个名字,而且正在使用它,所以动手删除之前先查看:
ip link show wg0
sudo wg show wg0
如果所有者是正在运行的服务,就配置该服务,而不是再建一个设备。如果它确实已经废弃,就用创建它的工具删除,然后用文档中给出的客户端或 unit 把接口拉起来,让配置与设备保持一致。
一旦创建成功,下一次失败属于更靠后的阶段,设备已经存在之后报告失败的 unit,与从未创建过的设备是两回事。再次改动权限之前,先把两者分开。