Nitrokey udev rules not working

Hello I’m trying to use a nitrokey passkey or nitrokey3 with my nixos system.
I managed to use it as a fido2 device for unlocking my luks partitions thnaks to systemd-cryptenroll. But when my system is booted and I wnat to use e.g. nitropy list as a user, I don’t see any of my keys. Running sudo nitropy list works without a problem.

I found this wiki article from which I copied the line:

services.udev.packages = [ pkgs.nitrokey-udev-rules ];

The udev rules should usually take care of this problem, at least that was the case on my old debian system.
Since I don’t use the gpg card functionality of the keys I didn’t install gpg-agent.

Edit:
The udev rules for the device are the following:

KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="20a0", ATTRS{idProduct}=="42f3", TAG+="uaccess"

despite that the hidraw device looks like this:

ls -la /dev/hidraw0                    
crw------- 1 root root 247, 0 16. Jan 18:17 /dev/hidraw0

If I change it manually to

crw-rw---- 1 root wheel 247, 0 16. Jan 18:17 /dev/hidraw0

I can use nitropy with the device. But shouldn’t this be done by the udev rule in the first place?

Is there anything else that I need to enable in order to make the nitrokeys accessible to my user?

Or is there a way to completely reload/reexecute all the udev rules?

Some more debugging, sudo rmmod usbhid && sudo modprobe gives me the following output in udevadm monitor:

KERNEL[1472.237599] add      /devices/pci0000:00/0000:00:15.0/usb1/1-2/1-2:1.1/0003:20A0:42F3.0004 (hid)
KERNEL[1472.237756] add      /devices/pci0000:00/0000:00:15.0/usb1/1-2/1-2:1.1/usbmisc/hiddev0 (usbmisc)
KERNEL[1472.238282] add      /devices/pci0000:00/0000:00:15.0/usb1/1-2/1-2:1.1/0003:20A0:42F3.0004/hidraw/hidraw0 (hidraw)
KERNEL[1472.238354] bind     /devices/pci0000:00/0000:00:15.0/usb1/1-2/1-2:1.1/0003:20A0:42F3.0004 (hid)
KERNEL[1472.238401] bind     /devices/pci0000:00/0000:00:15.0/usb1/1-2/1-2:1.1 (usb)
KERNEL[1472.238438] add      /bus/usb/drivers/usbhid (drivers)
KERNEL[1472.238466] add      /module/usbhid (module)
UDEV  [1472.247325] add      /devices/pci0000:00/0000:00:15.0/usb1/1-2/1-2:1.1/0003:20A0:42F3.0004 (hid)
UDEV  [1472.249150] add      /devices/pci0000:00/0000:00:15.0/usb1/1-2/1-2:1.1/usbmisc/hiddev0 (usbmisc)
UDEV  [1472.251582] add      /bus/usb/drivers/usbhid (drivers)
UDEV  [1472.252962] add      /module/usbhid (module)
UDEV  [1472.264066] add      /devices/pci0000:00/0000:00:15.0/usb1/1-2/1-2:1.1/0003:20A0:42F3.0004/hidraw/hidraw0 (hidraw)
UDEV  [1472.266221] bind     /devices/pci0000:00/0000:00:15.0/usb1/1-2/1-2:1.1/0003:20A0:42F3.0004 (hid)
UDEV  [1472.268787] bind     /devices/pci0000:00/0000:00:15.0/usb1/1-2/1-2:1.1 (usb)

If I filter for uaccess with udevadm monitor -t uaccess and repeat the above process I see that uaccess should be run for the device

DEV  [1789.847397] add      /devices/pci0000:00/0000:00:15.0/usb1/1-2/1-2:1.1/0003:20A0:42F3.0005/hidraw/hidraw0 (hidraw)

When executing

sudo udevadm control --reload && sudo udevadm test $(udevadm info --query=path --name=hidraw0)

I see the following:

Trying to open "/etc/systemd/hwdb/hwdb.bin"...
Trying to open "/etc/udev/hwdb.bin"...
=== trie on-disk ===
tool version:          256
file size:        12815504 bytes
header size             80 bytes
strings            2694832 bytes
nodes             10120592 bytes
Loading kernel module index.
Loaded 'libkmod.so.2' via dlopen()
Found cgroup2 on /sys/fs/cgroup/, full unified hierarchy
Found container virtualization none.
Using default interface naming scheme 'v255'.
Parsed configuration file "/nix/store/bl5dgjbbr9y4wpdw6k959mkq4ig0jwyg-systemd-256.10/lib/systemd/network/99-default.link"
Parsed configuration file "/nix/store/bl5dgjbbr9y4wpdw6k959mkq4ig0jwyg-systemd-256.10/lib/systemd/network/80-vm-vt.link"
Parsed configuration file "/nix/store/bl5dgjbbr9y4wpdw6k959mkq4ig0jwyg-systemd-256.10/lib/systemd/network/80-namespace-ns.link"
Parsed configuration file "/nix/store/bl5dgjbbr9y4wpdw6k959mkq4ig0jwyg-systemd-256.10/lib/systemd/network/80-container-vz.link"
Parsed configuration file "/nix/store/bl5dgjbbr9y4wpdw6k959mkq4ig0jwyg-systemd-256.10/lib/systemd/network/80-container-ve.link"
Parsed configuration file "/nix/store/bl5dgjbbr9y4wpdw6k959mkq4ig0jwyg-systemd-256.10/lib/systemd/network/80-container-vb.link"
Parsed configuration file "/nix/store/bl5dgjbbr9y4wpdw6k959mkq4ig0jwyg-systemd-256.10/lib/systemd/network/80-6rd-tunnel.link"
Parsed configuration file "/etc/systemd/network/40-enp3s0.link"
Created link configuration context.
Reading rules file: /nix/store/wzjh8wimwrjy1ppy3ndhbxx6cbisnz8q-udev-rules/00-path.rules
Reading rules file: /nix/store/wzjh8wimwrjy1ppy3ndhbxx6cbisnz8q-udev-rules/10-dm.rules
Reading rules file: /nix/store/wzjh8wimwrjy1ppy3ndhbxx6cbisnz8q-udev-rules/11-dm-lvm.rules
Reading rules file: /nix/store/wzjh8wimwrjy1ppy3ndhbxx6cbisnz8q-udev-rules/13-dm-disk.rules
Reading rules file: /nix/store/wzjh8wimwrjy1ppy3ndhbxx6cbisnz8q-udev-rules/41-nitrokey.rules
Reading rules file: /nix/store/bl5dgjbbr9y4wpdw6k959mkq4ig0jwyg-systemd-256.10/lib/udev/rules.d/50-udev-default.rules
Reading rules file: /nix/store/bl5dgjbbr9y4wpdw6k959mkq4ig0jwyg-systemd-256.10/lib/udev/rules.d/60-autosuspend.rules
Reading rules file: /nix/store/bl5dgjbbr9y4wpdw6k959mkq4ig0jwyg-systemd-256.10/lib/udev/rules.d/60-block.rules
Reading rules file: /nix/store/bl5dgjbbr9y4wpdw6k959mkq4ig0jwyg-systemd-256.10/lib/udev/rules.d/60-cdrom_id.rules
Reading rules file: /nix/store/bl5dgjbbr9y4wpdw6k959mkq4ig0jwyg-systemd-256.10/lib/udev/rules.d/60-dmi-id.rules
Reading rules file: /nix/store/bl5dgjbbr9y4wpdw6k959mkq4ig0jwyg-systemd-256.10/lib/udev/rules.d/60-drm.rules
Reading rules file: /nix/store/bl5dgjbbr9y4wpdw6k959mkq4ig0jwyg-systemd-256.10/lib/udev/rules.d/60-evdev.rules
Reading rules file: /nix/store/bl5dgjbbr9y4wpdw6k959mkq4ig0jwyg-systemd-256.10/lib/udev/rules.d/60-fido-id.rules
Reading rules file: /nix/store/bl5dgjbbr9y4wpdw6k959mkq4ig0jwyg-systemd-256.10/lib/udev/rules.d/60-infiniband.rules
Reading rules file: /nix/store/bl5dgjbbr9y4wpdw6k959mkq4ig0jwyg-systemd-256.10/lib/udev/rules.d/60-input-id.rules
Reading rules file: /nix/store/bl5dgjbbr9y4wpdw6k959mkq4ig0jwyg-systemd-256.10/lib/udev/rules.d/60-persistent-alsa.rules
Reading rules file: /nix/store/bl5dgjbbr9y4wpdw6k959mkq4ig0jwyg-systemd-256.10/lib/udev/rules.d/60-persistent-input.rules
Reading rules file: /nix/store/bl5dgjbbr9y4wpdw6k959mkq4ig0jwyg-systemd-256.10/lib/udev/rules.d/60-persistent-storage-mtd.rules
Reading rules file: /nix/store/bl5dgjbbr9y4wpdw6k959mkq4ig0jwyg-systemd-256.10/lib/udev/rules.d/60-persistent-storage-tape.rules
Reading rules file: /nix/store/bl5dgjbbr9y4wpdw6k959mkq4ig0jwyg-systemd-256.10/lib/udev/rules.d/60-persistent-storage.rules
Reading rules file: /nix/store/bl5dgjbbr9y4wpdw6k959mkq4ig0jwyg-systemd-256.10/lib/udev/rules.d/60-persistent-v4l.rules
Reading rules file: /nix/store/bl5dgjbbr9y4wpdw6k959mkq4ig0jwyg-systemd-256.10/lib/udev/rules.d/60-sensor.rules
Reading rules file: /nix/store/bl5dgjbbr9y4wpdw6k959mkq4ig0jwyg-systemd-256.10/lib/udev/rules.d/60-serial.rules
Reading rules file: /nix/store/bl5dgjbbr9y4wpdw6k959mkq4ig0jwyg-systemd-256.10/lib/udev/rules.d/64-btrfs.rules
Reading rules file: /nix/store/wzjh8wimwrjy1ppy3ndhbxx6cbisnz8q-udev-rules/69-bcache.rules
Reading rules file: /nix/store/wzjh8wimwrjy1ppy3ndhbxx6cbisnz8q-udev-rules/69-dm-lvm.rules
Reading rules file: /nix/store/bl5dgjbbr9y4wpdw6k959mkq4ig0jwyg-systemd-256.10/lib/udev/rules.d/70-camera.rules
Reading rules file: /nix/store/bl5dgjbbr9y4wpdw6k959mkq4ig0jwyg-systemd-256.10/lib/udev/rules.d/70-joystick.rules
Reading rules file: /nix/store/bl5dgjbbr9y4wpdw6k959mkq4ig0jwyg-systemd-256.10/lib/udev/rules.d/70-memory.rules
Reading rules file: /nix/store/bl5dgjbbr9y4wpdw6k959mkq4ig0jwyg-systemd-256.10/lib/udev/rules.d/70-mouse.rules
Reading rules file: /nix/store/bl5dgjbbr9y4wpdw6k959mkq4ig0jwyg-systemd-256.10/lib/udev/rules.d/70-power-switch.rules
Reading rules file: /nix/store/bl5dgjbbr9y4wpdw6k959mkq4ig0jwyg-systemd-256.10/lib/udev/rules.d/70-touchpad.rules
Reading rules file: /nix/store/bl5dgjbbr9y4wpdw6k959mkq4ig0jwyg-systemd-256.10/lib/udev/rules.d/70-uaccess.rules
Reading rules file: /nix/store/bl5dgjbbr9y4wpdw6k959mkq4ig0jwyg-systemd-256.10/lib/udev/rules.d/71-seat.rules
Reading rules file: /nix/store/bl5dgjbbr9y4wpdw6k959mkq4ig0jwyg-systemd-256.10/lib/udev/rules.d/73-seat-late.rules
Reading rules file: /nix/store/bl5dgjbbr9y4wpdw6k959mkq4ig0jwyg-systemd-256.10/lib/udev/rules.d/75-net-description.rules
Reading rules file: /nix/store/bl5dgjbbr9y4wpdw6k959mkq4ig0jwyg-systemd-256.10/lib/udev/rules.d/75-probe_mtd.rules
Reading rules file: /nix/store/bl5dgjbbr9y4wpdw6k959mkq4ig0jwyg-systemd-256.10/lib/udev/rules.d/78-sound-card.rules
Reading rules file: /nix/store/bl5dgjbbr9y4wpdw6k959mkq4ig0jwyg-systemd-256.10/lib/udev/rules.d/80-drivers.rules
Reading rules file: /nix/store/bl5dgjbbr9y4wpdw6k959mkq4ig0jwyg-systemd-256.10/lib/udev/rules.d/80-net-setup-link.rules
Reading rules file: /nix/store/bl5dgjbbr9y4wpdw6k959mkq4ig0jwyg-systemd-256.10/lib/udev/rules.d/81-net-dhcp.rules
Reading rules file: /nix/store/bl5dgjbbr9y4wpdw6k959mkq4ig0jwyg-systemd-256.10/lib/udev/rules.d/90-iocost.rules
Reading rules file: /nix/store/bl5dgjbbr9y4wpdw6k959mkq4ig0jwyg-systemd-256.10/lib/udev/rules.d/90-vconsole.rules
Reading rules file: /nix/store/wzjh8wimwrjy1ppy3ndhbxx6cbisnz8q-udev-rules/95-dm-notify.rules
Reading rules file: /nix/store/wzjh8wimwrjy1ppy3ndhbxx6cbisnz8q-udev-rules/98-ipv6-privacy-extensions.rules
Skipping empty file: /nix/store/wzjh8wimwrjy1ppy3ndhbxx6cbisnz8q-udev-rules/99-ipv6-privacy-extensions.rules
Reading rules file: /nix/store/wzjh8wimwrjy1ppy3ndhbxx6cbisnz8q-udev-rules/99-local.rules
Reading rules file: /nix/store/bl5dgjbbr9y4wpdw6k959mkq4ig0jwyg-systemd-256.10/lib/udev/rules.d/99-systemd.rules
sd-device: Failed to chase symlinks in "/devices/pci0000:00/0000:00:15.0/usb1/1-2/1-2:1.1/0003:20A0:42F3.0005/hidraw/hidraw0".
hidraw0: /nix/store/bl5dgjbbr9y4wpdw6k959mkq4ig0jwyg-systemd-256.10/lib/udev/rules.d/50-udev-default.rules:17 Importing properties from results of builtin command 'hwdb'
hidraw0: hwdb modalias key: "hid:b0003g0001v000020A0p000042F3"
hidraw0: hwdb modalias key: "usb:v20A0p42F3d0106dcEFdsc02dp01ic03isc00ip00in01"
hidraw0: /nix/store/bl5dgjbbr9y4wpdw6k959mkq4ig0jwyg-systemd-256.10/lib/udev/rules.d/60-fido-id.rules:5 Importing properties from results of 'fido_id'
hidraw0: Starting 'fido_id'
Successfully forked off '(spawn)' as PID 1468.
hidraw0: 'fido_id'(err) 'Failed to get current device from environment: Invalid argument'
hidraw0: Process 'fido_id' failed with exit code 1.
hidraw0: /nix/store/bl5dgjbbr9y4wpdw6k959mkq4ig0jwyg-systemd-256.10/lib/udev/rules.d/60-fido-id.rules:5 Command "fido_id" returned 1 (error), ignoring
hidraw0: /nix/store/bl5dgjbbr9y4wpdw6k959mkq4ig0jwyg-systemd-256.10/lib/udev/rules.d/71-seat.rules:74 Importing properties from results of builtin command 'path_id'
hidraw0: /nix/store/bl5dgjbbr9y4wpdw6k959mkq4ig0jwyg-systemd-256.10/lib/udev/rules.d/73-seat-late.rules:16 RUN 'uaccess'
Properties:
  DEVPATH=/devices/pci0000:00/0000:00:15.0/usb1/1-2/1-2:1.1/0003:20A0:42F3.0005/hidraw/hidraw0
  DEVNAME=/dev/hidraw0
  MAJOR=247
  MINOR=0
  ACTION=add
  PATH=/nix/store/ivihhvgh248javsi3yisng4filnfpmpf-udev-path/bin:/nix/store/ivihhvgh248javsi3yisng4filnfpmpf-udev-path/sbin
  SUBSYSTEM=hidraw
  TAGS=:seat:security-device:uaccess:
  CURRENT_TAGS=:seat:uaccess:
  ID_USB_CLASS_FROM_DATABASE=Miscellaneous Device
  ID_USB_PROTOCOL_FROM_DATABASE=Interface Association
  ID_VENDOR_FROM_DATABASE=Clay Logic
  ID_PATH_WITH_USB_REVISION=pci-0000:00:15.0-usbv2-0:2:1.1
  ID_PATH=pci-0000:00:15.0-usb-0:2:1.1
  ID_PATH_TAG=pci-0000_00_15_0-usb-0_2_1_1
  ID_FOR_SEAT=hidraw-pci-0000_00_15_0-usb-0_2_1_1
  USEC_INITIALIZED=1789828112
  ID_PROCESSING=1
Tags:
  seat
  security-device
  uaccess
Inotify watch:
  disabled
Queued commands:
  RUN{builtin} : uaccess
Unload kernel module index.
Unloaded link configuration context.

It seems the rules are applied but uaccess is not executed for the device. The Queued commands section worries me here.
Is there a way to look further in to this? Is this a problem with the rules or a bug in regards to uaccess?

As a workaround I use

  services.udev.extraRules = 
  ''
    KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="20a0", ATTRS{idProduct}=="42f3", TAG+="uaccess", MODE="0666"  
  '';

But this defeats the point of having the nitropy rules with uaccess in the first place.

uaccess does not change the permissions of the device directly but sets up an ACL. You can check it with getfacl. For example:

$ ls -l /dev/hidraw0
crw-rw----+ 1 root root 246, 0 Jan 17 11:13 /dev/hidraw0

$ getfacl /dev/hidraw0
getfacl: Removing leading '/' from absolute path names
# file: dev/hidraw0
# owner: root
# group: root
user::rw-
user:robin:rw-
group::---
mask::rw-
other::---

In this case, user:robin:rw- is the line that indicates that the udev rules work for me. Can you share your getfacl output?

My udevadm test output looks very similar to yours, so that should not be the problem.

Thank you for your reply! I tested a bit furter and the rpoblem seems to be indeed uaccess or systemd-logind. I should mention that I use this host only via ssh. When I invoke getfacl after I login via ssh, I get:

getfacl: Removing leading '/' from absolute path names
# file: dev/hidraw0
# owner: root
# group: root
user::rw-
group::rw-
other::---

I attached a monitor and logged in physicaly on the host, since what I read so far about uaccess and systemd-logind made me a bit suspicious. And here is the proof, after a “regular” login on the console of my device I get this as getfacl output:

getfacl: Removing leading '/' from absolute path names
# file: dev/hidraw0
# owner: root
# group: root
user::rw-
user:manji:rw-
group::rw-
mask::rw-
other::---

Nitropy can access the device as user if I perform a “regular” login.
To be honest I’m even more lost than before, is this intended behaviour? To me it feels kinda like a bug, it should not matter how the user logged in.
Should I report this? If so where?

I think this is how the uaccess mechanism is supposed to work. It only grants access to local users. There is an open issue for systemd to improve the documentation of this mechanisms that contains some context: Document the uaccess mechanism / dynamic device permissions · Issue #4288 · systemd/systemd · GitHub

I’m not aware of a way to tell systemd to enable uaccess devices for remote users as well. I guess the best solution is to use a custom udev rule to set MODE or OWNER.

Yeah I saw that 9 year old issue on my search.

TBH I think not, at least the parts systemd-logind and pam-systemd seem to work as described in the manual pages, no matter if ssh login or physical login. So the only thing that is left is the black box uaccess.

Yeah that will be my only option for now, I’ll use the nitrokey-old rules and change the group to wheel.

My understanding is that uaccess grants access based on seats which are local logins:

A seat consists of all hardware devices assigned to a specific workplace.
A session is bound to one or no seats (the latter for ‘virtual’ ssh logins).

sd-login(3)

See also: systemd/src/udev/udev-builtin-uaccess.c at ce2ef96c2b8ad7569a288a1ecc5aaf06bf34bd07 · systemd/systemd · GitHub

1 Like

Ah ok, yes that makes sense. Thanks for pointing the session part out, I read over that part.

It would be nice to know if there is a way to assign a virtual session to a seat. But I guess that is a topic for my backlog. Thank you so much for your help!