Hi,
I’m running Debian 13 (Trixie) with Kicksecure hardening on bare metal, and I’m troubleshooting a Ledger Nano S+ USB authorization problem.
The Ledger itself is working correctly. I have tested two different Nano S+ devices, two original Ledger USB cables, and three different USB ports.
The interesting part is that the kernel detects the Ledger correctly, but USBGuard rejects it.
USBGuard configuration
USBGuard is active:
usbguard.service - USBGuard daemon
Active: active (running)
The kernel USB authorization default is:
$ cat /sys/module/usbcore/parameters/authorized_default
1
USBGuard is configured with:
$ sudo usbguard get-parameter ImplicitPolicyTarget
block
So the default policy is to block unknown USB devices.
Ledger detection
When I plug in the Ledger, dmesg shows:
usb 1-2: new full-speed USB device number 5 using xhci_hcd
usb 1-2: New USB device found, idVendor=2c97, idProduct=5000, bcdDevice= 2.01
usb 1-2: New USB device strings: Mfr=1, Product=2, SerialNumber=3
usb 1-2: Product: Nano S+
usb 1-2: Manufacturer: Ledger
usb 1-2: SerialNumber: 0001
usb 1-2: Device is not authorized for usage
usb 1-2: USB disconnect, device number 5
The same happens on a second connection attempt.
USBGuard watch shows the reason
Running:
sudo usbguard watch
produces:
[device] PresenceChanged: id=63
event=Insert
target=block
device_rule=block id 2c97:5000 serial "0001" name "Nano S+"
...
with-interface { 03:00:00 ff:ff:ff 03:01:01 }
[device] PolicyChanged: id=63
target_old=block
target_new=reject
...
rule_id=39
[device] PolicyApplied: id=63
target_new=reject
...
rule_id=39
[device] PresenceChanged: id=63
event=Remove
target=reject
I then checked the actual USBGuard policy:
$ sudo usbguard list-rules | nl -ba | sed -n '35,42p'
35 35: reject with-interface all-of { 03:*:* dc:*:* }
36 36: reject with-interface all-of { 03:*:* e0:*:* }
37 37: reject with-interface all-of { 03:*:* ef:*:* }
38 38: reject with-interface all-of { 03:*:* fe:*:* }
39 39: reject with-interface all-of { 03:*:* ff:*:* }
40 40: reject with-interface one-of { ef:04:* }
41 41: allow with-interface 03:01:01 if !allowed-matches(with-interface equals { 03:01:01 })
42 42: allow with-interface 03:01:02 if !allowed-matches(with-interface equals { 03:01:02 })
The Ledger reports these interfaces:
{ 03:00:00 ff:ff:ff 03:01:01 }
Therefore rule 39 appears to match the Ledger because of:
ff:ff:ff
and USBGuard changes the device from block to reject.
The kernel then reports:
Device is not authorized for usage
and disconnects it.
However, rebooting changes the situation
I discovered an interesting workaround.
If I connect the Ledger, enter the PIN, and then reboot the system, after reboot the Nano can become available.
In the working state:
$ lsusb | grep -i -E 'ledger|2c97'
Bus 001 Device 002: ID 2c97:5000 Ledger Nano S+
and USBGuard shows:
55: allow id 2c97:5000 serial "0001" name "Nano S+"
...
via-port "1-2"
with-interface { 03:00:00 ff:ff:ff 03:01:01 }
Ledger Live then recognizes the device and I have verified the backup.
Interestingly, ImplicitPolicyTarget is still:
block
so I am not using ImplicitPolicyTarget=allow as a permanent workaround.
I also tested temporarily setting:
sudo usbguard set-parameter ImplicitPolicyTarget allow
but I don’t want to weaken the USB security policy just to make the Ledger work.
Question
Could someone explain the intended USBGuard/Kicksecure configuration for a Ledger Nano S+ in this situation?
Specifically:
- Is rule 39 (
reject with-interface ... ff:*:*) expected to reject the Ledger’sff:ff:ffinterface? - Should there be a Ledger-specific exception that takes precedence over this rule?
- Why does a reboot allow the Ledger to become usable despite the same generic reject rule being present?
- What is the recommended way under Kicksecure to permanently allow this specific Ledger while keeping:
ImplicitPolicyTarget=block
?
I would prefer not to remove rule 39 globally, since it appears to be a security rule for a reason.
Thanks!
Note: This investigation and forum post were prepared with assistance from ChatGPT.