YubiKey VM Redirection Guide

This documentation provides the complete, step-by-step process for making a physical YubiKey (on a Windows Host) accessible to Firefox on an Ubuntu VM running on Hyper-V using the open-source USB/IP project.
Phase 0: Ubuntu VM Installation Prerequisite & Network Security
The VM must run a standard kernel and be securely isolated for the USB tunnel.
- Use Canonical’s ISO: Install the latest Ubuntu LTS release directly using the ISO file downloaded from Canonical.
- Avoid Quick Create: Do NOT use “Quick Create” in Hyper-V Manager. This often installs an Azure-optimized kernel which lacks the essential
vhci-hcd
driver required for USB/IP. - VM Network Configuration: The VM must use a private virtual network for communication with the Windows host. Avoid using a physical (external or bridged) network connection for the USB/IP tunnel to prevent interception.
Phase 1: YubiKey Pre-Configuration on Windows
Configure the YubiKey to ensure its FIDO/CCID interfaces are ready and the default OTP function doesn’t interfere.
- Install YubiKey Manager: Download and install the official YubiKey Manager application on your local Windows machine.
- Insert YubiKey: Plug in your YubiKey.
- Delete Short Touch OTP: Go to Applications → OTP. Under Short Touch (Slot 1), select Delete.
- Enable All Interfaces: Go to Interfaces. Ensure OTP, FIDO, and CCID are all enabled for the USB interface.
Phase 2: Windows Host Setup (usbipd-win
Server)
This machine hosts the YubiKey and shares it across the network.
- Install
usbipd-win
: Open PowerShell as an Administrator and install the modern USB/IP server.
winget install --interactive --exact dorssel.usbipd-win
- Bind the YubiKey: Run the following command to list devices. The YubiKey often appears as
USB Input Device, Microsoft Usbccid Smartcard Reader (WUDF
)
. Find its Bus ID (e.g.,9-1
), and then bind it.
usbpid list
usbipd list usbipd bind --busid <YubiKey-Bus-ID>
- Configure Windows Firewall: The
usbipd
service should run automatically. Ensure the Windows Firewall is configured to allow traffic on port 3240 only for your VM’s private network and is blocked on Public and Domain networks to prevent external access to your USB devices. Run the following command to create the firewall rule:
New-NetFirewallRule -DisplayName "USBIP Daemon (3240)" -Direction Inbound -LocalPort 3240 -Protocol TCP -Action Allow -Profile Private
Phase 3: Ubuntu VM Setup (usbip
Client)
This configures the VM to receive the virtual USB device.
- Install
usbip
Tools: Install the client utilities that match your running kernel.
sudo apt update sudo apt install linux-tools-generic
- Load Kernel Modules (Temporary): Load the required modules for the current session.
sudo modprobe usbip_core sudo modprobe vhci-hcd
- Enable Modules on Boot: Configure the modules to load automatically every time the VM starts by adding them to the
/etc/modules
file.
echo "usbip_core" | sudo tee -a /etc/modules
echo "vhci-hcd" | sudo tee -a /etc/modules
- Attach the YubiKey: Run the command to attach the remote YubiKey, making it appear as a local device.
sudo usbip attach --remote <Windows-IP-Address> --busid <YubiKey-Bus-ID>
- Verify USB Mounting: Run the
lsusb
command to confirm the YubiKey was successfully mounted.
lsusb
# Look for an entry similar to: ID 1050:0407 Yubico.com Yubikey 4/5 OTP+U2F+CCID
Phase 4: Ubuntu Permissions and Services
This phase installs necessary software and fixes security permissions using PolicyKit.
- Install PCSC and FIDO Tools: Install tools for smart card access (CCID), FIDO/U2F access, and the YubiKey manager.
sudo apt install pcscd libpcsclite1 libu2f-udev ykcs11 yubikey-manager
sudo udevadm control --reload-rules
- Configure PolicyKit Rules (Access Control): Create a rule file to grant your user explicit permission to access the PC/SC daemon and the smart card.
sudo nano /etc/polkit-1/rules.d/50-pcsc-access.rules
- Paste the following code (replace
richard
with your actual username):
polkit.addRule(function(action, subject) {
if (action.id == "org.debian.pcsc-lite.access_pcsc" && subject.user == "richard") {
return polkit.Result.YES;
}
});
polkit.addRule(function(action, subject) {
if (action.id == "org.debian.pcsc-lite.access_card" && subject.user == "richard") {
return polkit.Result.YES;
}
});
- Finalize Permissions: Set file permissions and restart the service.
sudo chmod 644 /etc/polkit-1/rules.d/50-pcsc-access.rules
sudo systemctl restart pcscd.service
- Crucially, log out of the RDP session and log back in to ensure all user permissions are updated.
Phase 5: Firefox Installation and Configuration
The Firefox Snap package must be replaced with the .deb
package to ensure proper integration with system services like pcscd
.
- Uninstall Firefox Snap: Close all Firefox windows, then remove the Snap package.
sudo snap remove --purge firefox
- Install Firefox Deb: Add the official Mozilla APT repository to get the system package.
sudo install -d -m 0755 /etc/apt/keyrings
wget -q <https://packages.mozilla.org/apt/repo-signing-key.gpg> -O- | sudo tee /etc/apt/keyrings/packages.mozilla.org.asc > /dev/null
echo "deb [signed-by=/etc/apt/keyrings/packages.mozilla.org.asc] <https://packages.mozilla.org/apt> mozilla main" | sudo tee -a /etc/apt/sources.list.d/mozilla.list > /dev/null
# Set priority to prefer the Mozilla package
echo 'Package: *
Pin: origin packages.mozilla.org
Pin-Priority: 1000' | sudo tee /etc/apt/preferences.d/mozilla
sudo apt update sudo apt install firefox
- Add PKCS#11 Module: Load the Yubico library into Firefox.
- In Firefox, go to Settings → Privacy & Security → Certificates → Security Devices.
- Click Load, name the module (e.g., “Yubico PKCS#11”), and enter the file path:
/usr/lib/x86_64-linux-gnu/libykcs11.so
- Enable U2F/WebAuthn:
- In the Firefox address bar, navigate to
about:config
. - Search for
security.webauthn.u2f
and set its value totrue
.
- In the Firefox address bar, navigate to
Final Verification
- System Check: Run
ykman info
to ensure the key’s details are displayed.
Device type: YubiKey 5C NFC
Serial number: <redacted>
Firmware version: 5.7.1
Form factor: Keychain (USB-C)
Enabled USB interfaces: OTP, FIDO, CCID
NFC transport is enabled.
Applications USB NFC
OTP Enabled Enabled
FIDO U2F Enabled Enabled
FIDO2 Enabled Enabled
OATH Enabled Enabled
PIV Enabled Enabled
OpenPGP Enabled Enabled
YubiHSM Auth Enabled Enabled
- WebAuthn Test: Navigate to
https://webauthn.io
and successfully register or authenticate.