winget install usbipd
usbipd list
管理员powershell
usbipd bind --busid \<busid>
usbipd attach --busid \<busid> --wsl
sudo apt install libpam-u2f pcscd
**libpam-u2f**:Yubico 提供的 PAM模块,用于通过U2F/FIDO2密钥进行身份验证。我们将利用它让 sudo 识别 YubiKey
**pcscd**(PC/SC 智能卡服务):用于支持 YubiKey 的智能卡接口(CCID)。安装 pcscd 可以使诸如 YubiKey 管理工具、GPG 智能卡等功能在 WSL 中可用。虽然使用 pam-u2f 不一定需要 pcscd,但建议安装以确保全面识别 YubiKey。
sudo systemctl enable --now pcscd
接下来我们编译一个启用HIDRAW和HIDDEV驱动支持的自定义wsl2 linux kernel和相关库, 加入usb硬件支持.
WSL2:
cd ~ && git clone https://github.com/microsoft/WSL2-Linux-Kernel
`cd WSL2-Linux-Kernel`
sudo apt-get update
sudo apt-get install -y build-essential flex bison libssl-dev libelf-dev bc dwarves libncurses-dev libssl-dev libelf-dev cpio qemu-utils
`make menuconfig KCONFIG_CONFIG=Microsoft/config-wsl`进入图形页面
按下'/'输入hidraw hiddev进行选项搜索
![[Pasted image 20250227030000.png]]
或者直接nvim Microsoft/config-wsl 修改对应项为y
官方教程提供的流程主要是生成一个个性化编译的内核镜像以及一个包含外部模块(通过 modules_install 安装到 VHDX 镜像里的)的环境。也就是说,默认情况下那些驱动是以模块(module)的形式存在,而不是内建进内核镜像中。
如果你希望将这些模块直接集成进内核(即在编译时就内建,而不是后期加载外部模块),你需要在编译前修改内核配置文件(.config),将相关驱动的选项从模块(m)改为内建(y)。例如,将 CONFIG_USBIP_VHCI_HCD 从 "m" 改为 "y"。这样在编译后生成的内核镜像就会包含这些驱动,而不需要额外的模块文件。
目前并没有官方的工具或方法可以在生成 VHDX 后再将外部模块“合并”到内核镜像中;必须在编译阶段决定哪些驱动以内建形式集成。这样做的优点是启动时无需再加载模块,但缺点是灵活性降低,且内核体积可能会增大。
建议修改 **内核本地版本号**用于标识自定义内核。例如在 menuconfig 的 **“General setup -> Local version”** 中添加一个标识字符串(如 “-custom”)。这样编译出的内核版本号 (`uname -r`) 会带有该后缀
make -j$(nproc) KCONFIG_CONFIG=Microsoft/config-wsl 并行编译
make INSTALL_MOD_PATH="$PWD/modules" modules_install 将库文件(内核链接好的但是没有装进内核)编译到这里
`sudo cp -a "$PWD/modules/lib/modules/$(uname -r)"/. "/lib/modules/$(uname -r)/"`
- `-a`(相当于 `--archive`)可以尽量保持原文件的属性(权限、时间戳等)。
- 使用 `"/."` 结尾可以把源目录下的所有内容(含隐藏文件)复制到目标目录,而不是把源目录整体再套一层到目标里
sudo depmod 重新生成模块依赖信息
`sudo modprobe vhci_hcd`
cp ./vmlinux /mnt/e/Debian_WSL/custom_kernel
make clean
Powershell:
sed -i '/kernel/d' ~/.wslconfig
sed -i 's/\[wsl2\]/[wsl2]\nkernel=E:\\\\Debian_WSL\\\\custom_kernel/' ~/.wslconfig
注意: 更改wsl内核可能导致docker出现问题.....需要谨慎.
PS C:\Users\L> usbipd bind --busid 1-9
usbipd: info: Device with busid '1-9' was already shared.
PS C:\Users\L> usbipd attach --wsl --busid 1-9
usbipd: info: Using WSL distribution 'Debian' to attach; the device will be available in all WSL 2 distributions.
usbipd: info: Loading vhci_hcd module.
usbipd: error: Loading vhci_hcd failed.
解决方法: modprobe进行安装
sudo modprobe vhci_hcd
YubiKey 管理工具
sudo apt install yubikey-manager fido2-tools
ykman list
`lsusb`
能够识别
FIDO_DEBUG=1 fido2-token -L
发现权限不足以访问/dev/hidraw*
运行sudo chmod a+rw /dev/hidraw0 /dev/hidraw1
再次尝试, 成功
```shell
sudo nvim /etc/udev/rules.d/99-yubikey.rules
```
```
KERNEL=="hidraw*", SUBSYSTEM=="hidraw", MODE="0666", TAG+="uaccess", GROUP="plugdev", ATTRS{idVendor}=="xxxx", ATTRS{idProduct}=="xxxx"
```
生成u2f密钥:
mkdir -p ~/.config/Yubico
pamu2fcfg > ~/.config/Yubico/u2f_keys
触摸yubikey完成注册
移动密钥文件, 保证权限安全
sudo mkdir -p /etc/Yubico
sudo mv ~/.config/Yubico/u2f_keys /etc/Yubico/u2f_keys
sudo chmod 600 /etc/Yubico/u2f_keys && sudo chown root:root /etc/Yubico/u2f_keys
配置 PAM 模块:
sudo sed -i '/@include common-auth/i auth sufficient pam_u2f.so authfile=/etc/Yubico/u2f_keys userpresence=0 cue debug interactive' /etc/pam.d/sudo
注意: yubikey在pam_u2f时硬件强制要求进行一次按压验证. userpresence=0在软件层面的限制无效.
interactive会在尝试验证前要求用户press enter确认设备已经插入. 可以解决莫名失败fallback到剩下的验证方式的情况.
接下来我们会实现智能的usbipd attach&detach
`param(`
`[string]$GuidPattern = "6feaa3b5-3b08-46d2-a719-5c9f109c7d93"`
`)`
`$usbStateOutput = usbipd state | Out-String`
`$jsonData = $usbStateOutput | ConvertFrom-Json`
`if ($jsonData.PSObject.Properties.Name -contains "Devices") {`
`$deviceList = $jsonData.Devices`
`} else {`
`$deviceList = $jsonData`
`}`
`$matchedDevices = $deviceList | Where-Object { $_.PersistedGuid -like $GuidPattern }`
`$yubiKeyBusId = $matchedDevices.BusId`
`if ($yubiKeyBusId) {`
`usbipd detach --busid $yubiKeyBusId`
`Start-Sleep -Seconds 0.8 # To prevent: usbipd: error: There is no device with busid '1-9'.`
`usbipd attach --wsl --busid $yubiKeyBusId`
`Write-Host "YubiKey attached to WSL with busid $yubiKeyBusId."`
`} else {`
`Write-Host "YubiKey not found."`
`}`
修正版:
`param(`
`[string[]]$GuidPatterns = @("6feaa3b5-3b08-46d2-a719-5c9f109c7d93", "076ce816-76bf-4582-a2e4-7f20990e964c")`
`)`
`$usbStateOutput = usbipd state | Out-String`
`$jsonData = $usbStateOutput | ConvertFrom-Json`
`if ($jsonData.PSObject.Properties.Name -contains "Devices") {`
`$deviceList = $jsonData.Devices`
`} else {`
`$deviceList = $jsonData`
`}`
`$matchedDevices = $deviceList | Where-Object { $_.PersistedGuid -in $GuidPatterns }`
`foreach ($device in $matchedDevices) {`
`$yubiKeyBusId = $device.BusId`
`if ($yubiKeyBusId) {`
`usbipd detach --busid $yubiKeyBusId`
`Start-Sleep -Seconds 0.8 # To prevent: usbipd: error: There is no device with busid '1-9'.`
`usbipd attach --wsl --busid $yubiKeyBusId`
`Write-Host "YubiKey attached to WSL with busid $yubiKeyBusId."`
`} else {`
`Write-Host "YubiKey not found."`
`}`
`}`
然后sudo nvim /etc/wsl.conf
`[boot]
`command = "sh -c 'psFile=$(wslpath -w <ps1脚本在wsl里的路径>) && /mnt/c/Windows/System32/WindowsPowerShell/v1.0/powershell.exe -ExecutionPolicy Bypass -File \"$psFile\"'"`
https://docs.yubico.com/software/yubikey/tools/ykman/webdocs.pdf 手册内提到似乎可以禁用yubikey的验证
但是apt-get 获取到的版本是落后的
因此, 首先安装最新版本的yubikey-mamager
wget https://developers.yubico.com/yubikey-manager/Releases/yubikey_manager-5.5.1.tar.gz
tar -xvzf yubikey_manager-5.5.1.tar.gz
cd ./yubikey_manager-5.5.1
poetry install (报错自己补依赖)
poetry run ykman -v
poetry run which ykman得到path
`sudo apt-get remove yubikey-manager`
`sudo ln -s <得到的path> /usr/local/bin/ykman`
然后发现没有卵用....pam u2f还是要触摸进行第一次验证
`ykman fido config toggle-always-uv` 默认是关闭的....