Cannot use U2F device with chrome/chromium or firefox/iceweasel
Using either the Chromium or the Firefox docker images and their associated run commands in the dotfiles repo, I'm not able to get the browser to recognize a U2F device that's plugged into the host. For Chromium, this is the run command I'm using:
docker run -d \
--memory 3gb \
-v /etc/localtime:/etc/localtime:ro \
-v /tmp/.X11-unix:/tmp/.X11-unix \
-e "DISPLAY=unix${DISPLAY}" \
-v "${HOME}/Downloads:/root/Downloads" \
-v "${HOME}/Pictures:/root/Pictures" \
-v "${HOME}/Torrents:/root/Torrents" \
-v "${HOME}/.chrome:/data" \
-v /dev/shm:/dev/shm \
-v /etc/hosts:/etc/hosts \
--security-opt seccomp:$HOME/chrome.json \
--device /dev/snd \
--device /dev/dri \
--device /dev/usb \
--device /dev/bus/usb \
--group-add audio \
--group-add video \
--name chrome \
${DOCKER_REPO_PREFIX}/chromium --user-data-dir=/data \
--proxy-server="$proxy" \
--host-resolver-rules="$map" "$args"
On the host machine, the Yubikey is available as /dev/usb/hiddev<n>, so I believe the device should be visible. However, registration and authentication fail at the Yubico test page: https://demo.yubico.com/u2f
I'm able to use the device successfully on the host with both browsers. The Firefox/iceweasel containers aren't executed with a seccomp profile, so I don't think that's the issue either.
Note: for Firefox, you'll have to enable security.webauth.u2f in about:config to enable U2F support.
--privileged -v /dev:/dev
works for me
You may need to give access to the plugdev group in the container. If it needs to be created, make sure that it has the same GID as on the host.
If launching the container as an unprivileged user, the UID and GID of the user should match that of your user on the host that is launching the container.
Running the container with --privileged -v /dev:/dev is not a good idea, and defeats some of the security provided by this approach in the first place.
You may also need device access to the appropriate hidrawX devices:
docker run --rm -d \
-c 4 \
-m 4096M \
-v /etc/localtime:/etc/localtime:ro \
-v /tmp/.X11-unix:/tmp/.X11-unix \
-e "DISPLAY=unix${DISPLAY}" \
-v "${HOME}/Downloads:/home/chromium/Downloads" \
-v "${HOME}/.config/chromium:/home/chromium/data" \
-v /dev/shm:/dev/shm \
-v /etc/hosts:/etc/hosts \
--security-opt seccomp="${HOME}/chrome.json" \
--device /dev/snd \
--device /dev/dri \
--device /dev/usb \
--device /dev/bus/usb \
--device /dev/hidraw0 \
--device /dev/hidraw1 \
--name chromium \
${user}/chromium:${tag} \
--user-data-dir="/home/chromium/data" \
--proxy-server="$proxy" \
--enable-native-gpu-memory-buffers
I got it working properly on Chrome and Chromium after taking @bghost's advice with the following:
docker run --dit --rm --device /dev/bus/usb/001/012 --device /dev/hidraw5 --group-add plugdev
There is probably a more elegant way but to find the hidraw device I just found the highest one with the following command with my yubikey unplugged. Then I plugged it in and ran it again for the next highest hidraw and that was the one assigned to my yubikey.
udevadm info --query=all --name=/dev/hidraw1 --attribute-walk
You can find the USB device with the output of lsusb:
Bus 001 Device 012: ID 1050:0407 Yubico.com
Then substitute your numbers in the following path:
/dev/bus/usb/<bus>/<device>
Oh and I'm on Linux Mint 19 and had to following the directions here. But you shouldn't need to do that if your yubikey works in your host's non-containerzied browser.