I use CTAP Proxy based on the Qubes documentation for U2F MFA with a security key. It works.
However, sometimes I have a need to attach the security key to a VM for various reasons not related to U2F MFA.
The problem I encountered was that when I detach they key from the VM (return the key to sys-usb), the CTAP Proxy for U2F MFA no longer works (I receive no indication that I should touch the key to perform authentication). This can easily be worked around by physically reconnecting the key, but it gets tedious and Iām worried about wear and tear.
So after a bit of research I came up with this script that allows the key to be reconnected without physically touching it. I hope someone else finds it useful. At some point when I have time I would like to find a way (maybe with the new devices API?) to run it automatically when the key is detached from a VM:
#!/usr/bin/env bash
# Based on https://unix.stackexchange.com/questions/762514/how-to-disconnect-and-reconnect-usb-devices-on-the-command-line/763713
[[ $EUID -eq 0 ]] || { printf 'Please run script as root\n'; exit 1; }
# Get the device ID as can be seen after "sys-usb:" in the Qubes Devices menu
DEVID="$(dmesg | grep -ioE 'usb [[:digit:]]-[[:digit:]].*key' | tail -n1 | awk '{print $2}' | tr -d :)"
[[ $? -eq 0 && -e /sys/bus/usb/devices/$DEVID/port/disable ]] || { printf 'Failed to determine device ID\n'; exit 1; }
# Get the physical directory without symbolic links, because the symlink path will disappear when the device is disabled
PORT_PATH="$(cd "/sys/bus/usb/devices/$DEVID/port" && pwd -P || exit 1)"
[[ $? -eq 0 && -e $PORT_PATH/disable ]] || { printf 'Failed to determine port path\n'; exit 1; }
# Disable and re-enable the port
echo 1 > "$PORT_PATH/disable"
sleep 1s
echo 0 > "$PORT_PATH/disable"