WSL2 运行在虚拟机中,无法直接访问宿主机的 USB 设备。要在 WSL2 里使用 YubiKey,需要借助 usbipd-win 将 USB 设备从 Windows 转发到 WSL2,再在 WSL2 中安装相应的工具来与 YubiKey 交互。
安装 usbipd-win
在 Windows 端安装 usbipd-win,用于将 USB 设备共享到 WSL2:
winget install usbipd
安装 WSL2 端依赖
WSL2 端需要安装 USB/IP 客户端工具和智能卡相关的包(这里以 Arch Linux 为例):
paru -S usbutils pcsclite ccid opensc yubikey-manager
启用 pcscd 服务:
sudo systemctl enable --now pcscd.socket
需要在
/etc/wsl.conf中设置[boot] systemd=true以使用 systemd。
配置 polkit 授权
pcscd 默认只允许 root 用户访问智能卡设备。需要添加 polkit 规则允许 wheel 组的用户访问:
// /etc/polkit-1/rules.d/99-pcscd.rules
polkit.addRule(function(action, subject) {
if ((action.id == "org.debian.pcsc-lite.access_pcsc" ||
action.id == "org.debian.pcsc-lite.access_card") &&
subject.isInGroup("wheel")) {
return polkit.Result.YES;
}
});
如果你的用户不在
wheel组中,将"wheel"替换为你所在的组。
转发 YubiKey 到 WSL2
在 Windows 端(需要管理员权限)列出所有 USB 设备:
usbipd list
输出类似如下:
Connected:
BUSID VID:PID DEVICE STATE
1-1 1050:0407 USB Input Device, Microsoft Usbccid Smartcard Reader (WUDF) Not shared
2-1 046d:c52b Logitech USB Input Device, USB Input Device Not shared
...
其中 VID:PID 列的 VID(Vendor ID)是 USB 厂商标识,1050 是 Yubico 的 VID。找到对应的 Bus ID 后,绑定并附加到 WSL2:
usbipd bind --busid <busid>
usbipd attach --wsl --busid <busid>
但 Bus ID 会随插入的 USB 口变化。更好的方式是用脚本自动识别 YubiKey 并附加,创建 ~\.local\scripts\attach-yubikey.ps1:
# 创建目录
New-Item -ItemType Directory -Force -Path "$env:USERPROFILE\.local\scripts"
# ~\.local\scripts\attach-yubikey.ps1
$device = usbipd list | Select-String "1050:" | ForEach-Object {
if ($_ -match "^(\S+)") { $matches[1] }
}
if ($device) {
usbipd bind --busid $device 2>$null
usbipd attach --wsl --busid $device --auto-attach
} else {
Write-Host "YubiKey not found"
}
--auto-attach 会持续监听设备插拔并自动重新附加。可以通过 Windows 计划任务实现开机自启:
$scriptPath = "$env:USERPROFILE\.local\scripts\attach-yubikey.ps1"
$action = New-ScheduledTaskAction `
-Execute "powershell.exe" `
-Argument "-WindowStyle Hidden -File `"$scriptPath`""
$trigger = New-ScheduledTaskTrigger -AtLogOn
Register-ScheduledTask -TaskName "Auto Attach YubiKey to WSL" `
-Action $action -Trigger $trigger -RunLevel Highest
在 WSL2 中验证设备是否可见:
$ lsusb | grep -i yubi
Bus 001 Device 002: ID 1050:0407 Yubico.com Yubikey 4/5 OTP+U2F+CCID
配置 GPG 智能卡
如果你的 YubiKey 配置了 OpenPGP,可以通过 GPG 使用它。
在 WSL2 中,scdaemon 默认通过 CCID 直连 USB 设备,但这条路径在 USB 转发场景下通常无法工作。需要让它改走 pcscd:
# ~/.gnupg/scdaemon.conf
disable-ccid
重启 GPG 相关服务:
gpg-connect-agent "scd killscd" /bye
gpg-connect-agent reloadagent /bye
然后验证:
gpg --card-status
如果能正确显示卡片信息,说明 YubiKey 已经可以使用。
将 GPG 用作 SSH Agent
YubiKey 上的 Authentication 子密钥可以用作 SSH 密钥。启用 GPG Agent 的 SSH 支持:
# ~/.config/environment.d/20-gpg-agent.conf
SSH_AUTH_SOCK=${XDG_RUNTIME_DIR}/gnupg/S.gpg-agent.ssh
在 GPG Agent 配置中启用 SSH 支持:
# ~/.gnupg/gpg-agent.conf
enable-ssh-support
重启 GPG Agent:
gpg-connect-agent reloadagent /bye
验证 SSH 密钥是否可用:
ssh-add -L
常见问题
GPG 提示 "No such device"
scdaemon 默认使用 CCID 直连,在 WSL2 的 USB 转发场景下不可用。确认 ~/.gnupg/scdaemon.conf 中已添加 disable-ccid,然后重启服务:
gpg-connect-agent "scd killscd" /bye
gpg-connect-agent reloadagent /bye
GPG 提示 "Service is not running"
pcscd 服务未启动,或者通过 socket 激活未能成功拉起。手动启动服务:
sudo systemctl start pcscd.service
如果 pcscd 已在运行但仍然报错,说明是 polkit 授权问题。确认 /etc/polkit-1/rules.d/99-pcscd.rules 中同时包含了 access_pcsc 和 access_card 两个 action 的授权,参考上文配置 polkit 授权章节。
pcscd 日志提示 "LIBUSB_ERROR_BUSY"
pcscd 无法打开设备,因为其他进程(通常是之前 sudo gpg 残留的 root scdaemon)占用了 USB 接口。先释放设备再重启:
# 杀掉所有 scdaemon
sudo gpg-connect-agent "scd killscd" /bye
gpg-connect-agent "scd killscd" /bye
# 重启 pcscd
sudo systemctl restart pcscd.service
pcscd 无法识别 YubiKey
确认 ccid 驱动已安装,检查 USB 设备是否已正确附加:
lsusb | grep -i yubi
如果设备不可见,回到 Windows 端重新执行 usbipd attach。