How to set up USB keyboard on a laptop?

I am usin QubesOS 4.1 on a Thinkpad X220. I also have a lenovo KU-1255 USB-keyboard that I want to attach to my Thinkpad and use it with.

The readings about USB keyboard setup I did in QubesOS docs has left me confused on a few topics:

  1. It seems like the docs assume that the USB keyboard setup is mainly written for people with computers which only have USB keyboards. In such a case, it seems like the sys-usb qube doesn’t get created upon QubesOS installation? In my case, I have Qubes running on this thinkpad laptop, and I have had the sys-usb (I made it disposable btw) set up for me by the Qubes installer itself. So, the the docs assumes that I don’t have a sys-usb and walks me through creating one. Do I skip this part? Do I directly move to this header in the guide? However, that part still talks about creating a usb-qube (does usb-qube mean sys-usb specifically? If so, I already have that qube—and that’s just confusing).

  2. There are really “scary” disclaimers, such as the usb keyboard “taking over the whole system”. Might be true, but that’s unconstructively scary, and makes me paranoid about getting my USB keyboard setup right about all the minute details of the setup process.

  3. So, about the 2nd bullet point: do I create a new usb qube only for the USB keyboard, and then allow usb passthrough (not sure if that’s the correct term) to the dom0? If indeed a maliciously exploited bug compomises my disposable sys-usb qube, I wouldn’t want my USB keyboard connected to that sys-usb and then have a “wormhole pass” into the dom0.

How do I navigate this? Can someone tell me what steps do I follow on the qubesOS doc at least?

OK, I have done some reading on this forum on the topic of my questions.

  1. It seems like there is this thing called “usb controllers.” These are “hubs” (?) on your computer which own the physical USB ports. Important thing about these USB controllers is that the physical USB ports that are assigned to these USB controllers share the same “data bus”. For example, let’s say the two physical USB ports on the left hand side of your computer case are controlled by one of your specific USB controllers. Then, the devices that you connect to these physical USB ports share the same physical “data bus”, and if one of the connected USB devices got compromised and run malware, the malware can access the data the other USB device receives/transmits on the same USB controller.

    (dom0) $ qvm-pci | grep "USB controller"
    dom0:00_1a.0  USB controller: Intel Corporation 6 Series/C200 Series Chipset Family USB Enhanced Host Controller #2              sys-usb (no-strict-reset=True)
    dom0:00_1d.0  USB controller: Intel Corporation 6 Series/C200 Series Chipset Family USB Enhanced Host Controller #1              sys-usb (no-strict-reset=True)
    

    It seems like my X220 has two USB controllers. So, I should pick one the physical USB ports on my computer chasis and find out which USB controller that is associated with, then find which one of the other 3 physical USB ports are also associated with that particular USB controller, and finally use those physical USB ports ONLY for USB-keyboard. I should never attach USB devices to the USB controller that I associate my USB-keyboard with. Since it seems like I will have to pass my USB-keyboard to the dom0 in order to use the USB-keyboard, and thus I need to be diligent in what gets passed to dom0 domain.

  2. On sys-usb (which is a disposable VM in my QubesOS 4.1), I open a terminal, and issue lsusb command:

    (sys-usb) $ lsusb
    Bus 003 Device 002: ID 8087:0024 Intel Corp. Integrated Rate Matching Hub
    Bus 003 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
    Bus 002 Device 006: ID 04f2:b217 Chicony Electronics Co., Ltd Lenovo Integrated Camera (0.3MP)
    Bus 002 Device 005: ID 0a5c:217f Broadcom Corp. BCM2045B (BDC-2.1)
    Bus 002 Device 004: ID 147e:2016 Upek Biometric Touchchip/Touchstrip Fingerprint Sensor
    Bus 002 Device 003: ID 0424:2514 Microchip Technology, Inc. (formerly SMSC) USB 2.0 Hub
    Bus 002 Device 002: ID 8087:0024 Intel Corp. Integrated Rate Matching Hub
    Bus 002 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
    Bus 001 Device 002: ID 0627:0001 Adomax Technology Co., Ltd QEMU USB Tablet
    Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
    

    Then, I plug my lenovo KU-1255 USB-keyboard, and reissue the same lsusb command. This time, I see my USB-keyboard assigned to Bus 03. I plug-off/-on the same USB-keyboard one by one on the available physical USB-ports, and notice that the two of them on the left hand side are grouped under “Bus 003”.

Question: what’s the difference between the USB-controller and a Bus? On dom0, qvm-pci command reported I have 2 USB-controllers. On sys-usb, lsusb command reported I have “Bus 003, Bus 002, and Bus 001”. So I have 2 USB-controllers and 3 Buses? What does this mean?

I intuit that I have to clone my existing sys-usb dispVM. Then assign the USB-controller that controls “Bus 003” to the newly cloned sys-usb. And use this new sys-usb ONLY for attaching the USB-keyboard.

Am I more or less on the right track so far? Please advise me if I have faults in my understanding. I would like to discuss the further steps, too.

2 Likes

@tanky0u, your goal is to get your USB keyboard/mouse into dom0, right?

If it is, check out this guide:

There’s a chance that you haven’t set up the qubes-rpc policies correctly.

No offence meant, but you’ve always got to ask the obvious questions first :slight_smile:

If you’ve already done that….well….then we have a mystery on our hands to solve :laughing:

Controller = the chip that ”translates” between the USB ports and the CPU

Bus = The ”pipes” of the CPU chip that data from various “sections” of the computer travel down

So, for your purposes, no difference at all :slight_smile:

You probably have 3 of each, but your BIOS/motherboard firmware is telling the Linux kernel that it’s something else, like an internal component. Nothing to worry about.

OK. I have cloned my existing minimal, disposable sys-usb qube and created a new "usb-keyboard’ qube. I have identified which USB controller on my computer is responsible for the USB ports that I would like to devote to USB keyboard. I have removed that USB controller from the reach of sys-usb (Qube Manager → sys-usb → Settings → Devices, and then remove that USB controller). Also, I gave the control of that USB controller to the newly created “usb-keyboard” qube.

On dom0, I have added the following line:
usb-keyboard dom0 allow
to the top-most of the file /etc/qubes-rpc/policy/qubes.InputKeyboard.

Then, I have identified the of the USB-keyboard device using lsusb and then readlink commands on the usb-keyboard qube. It is 00:06.0.

After that, I have added the following lines to the following file:
/etc/default/grub:

...
$GRUB_CMDLINE_LINUX="$GRUB_CMDLINE_LINUX rd.qubes.hide_all_usb usbcore.authorized_default=0 rd.qubes.dom0_usb=00_06.0"

I saved the file and quitted.

Then I run sudo grub2-mkconfig -o /boot/grub2/grub.cfg and rebooted.

Two problems:

  1. During the boot-up, in the grub screen I saw the warning: bogus option rd.qubes.dom0_usb. Check your grub file! (or something like that, can’t remember the exact wording, but the point is, dracut was complaining about the rd.qubes.dom0_usb parameter).

  2. Even though the usb-keyboard qube is up and running, and the USB Keyboard device is plugged into the specific USB port, the USB keyboard device isn’t working. I cannot control neither the keyboard nor the mouse with its trackpoint.

Any further help please?

It needs to be rd.qubes.dom0_usb=00:06.0

I could be wrong, but I think it means you want to connect the usb controller to dom0, without using sys-usb.

2 Likes

I think you missed this part of a doc:

  1. Proceed with creating a USB qube normally. The selected USB controller will remain in dom0.

So, you don’t need this most probably.

Also, if it still doesn’t work after removing said part from the grub, you can try to add

usb-keyboard dom0 allow,user=root

to /etc/qubes-rpc/policy/qubes.InputKeyboard. Note that there isn’t space after comma.

Okay. I fixed it as you said, and dracut no longer complains. But the USB keyboard is not able to command the keyboard nor the trackpoint (even though USB keyboard’s power LED lights on when it is plugged into the USB port).

I don’t get it. Why does the guide want me to create sys-usb again? I already have the sys-usb created for me back when I first installed QubesOS??

I don’t need what ? Can you be more specific?

If you remove the controller from the usb-keyboard qube it will probably work.

You are attaching the controller to dom0 and the keyboard qube at the same time, I don’t think this is going to work.

1 Like

I removed the USB-controller (00:1d.0 — which is the one that controls the two USB ports on the left hand side of my laptop’s chasis) from “usb-keyboard” qube’s Devices list (using Qube Manager interface).

This didn’t work. The computer is still unresponsive to the USB keyboard’s keypresses.

I also don’t get it: if I remove the USB controller that controls the USB ports that I want to use with my USB keyboard, QubesOS becomes completely oblivious to these USB ports (doesn’t even register they exist, let alone my plugging-on/-off of my USB keyboard hardware). How is removing that USB controller from “usb-keyboard” qube’s Devices list supposed to work?

Hey, I managed to get it working.

This was basically correct.

First, I changed the rd.qubes.dom0_usb=00:06.0 into rd.qubes.dom0_usb=00:1d.0. Basically, I instructed the whole USB controller designated by “00.1d.0” to the rd.qubes.dom0_usb in the /etc/default/grub file.

This part is curious, because it seems like the guide on this is different? According to the guide, I should’ve worked with “00:06.0” value, which is the output of the readlink command. But that didn’t work getting the keyboard working.

Next, I have removed the 00:1d.0 USB Controller from the “usb-keyboard” qube’s Devices list.

Then, I have restarted the QubesOS and voila! the keyboard is working.

Yet, I have a few questions to get a better understanding at what I am doing:

  1. It seems like I have directly exposed the two USB ports on my machine (which are controlled by the 00:1d.0 USB controller) directly to the dom0, meaning, any USB device that gets attached to these two ports will be directly attached to the dom0. This is a bit concerning.

  2. Since the USB Keyboard is directly attached to the dom0 now, it seems like my newly cloned “usb-keyboard” qube is redundant. Indeed, the USB Keyboard is working without that qube being started on my QubesOS. So, is the usb-keyboard dom0 allow line that I have added to the topmost line of the file /etc/qubes-rpc/policy/qubes.InputKeyboard unnecessary?

  3. Due to point 1), I think I would be more comfortable with having the USB Keyboard being attached to a disposable usb qube (like my “usb-keyboard” qube) and then, it’s actions being forwarded to the dom0. That way, I think, I wouldn’t be exposing my two USB ports that are controlled by 00:1d.0 USB controller directly to the dom0. Is this true? How can I get the USB keyboard get attached to a usb qube first, and then be forwarded to the dom0?

I think you mixed up things. As I see it. you should leave the controller to usb-keyboard, then to set the policy as I wrote above, and in a grub to add only rd.qubes.hide_all_usb after the word quiet, folowing with sudo grub2-mkconfig -o /boot/grub2/grub.cfg and a reboot. Please not that I’m not sure if this would lock you up on an encryption password screen, because I have PS/2 port (you have laptop?). If so, then probably you would want to hide all controllers to dom0 except the one with keyboard.

That’s all, and it should work as if you were “attached” keyboard to dom0 as you would any other device to any other qube via sys-usb (usb-keyboard in this case)

I didn’t read it carefully, so apologize if I’m the one that mixed things.

1 Like

You said you were using usbcore.authorized_default=0 it prevents non-input devices from attaching to dom0.

1 Like

Yeah, my computer is a laptop, and I can use its keyboard to decrypt the disk, no problem.

rd.qubes.hide_all_usb was already there, as follows:

GRUB_CMDLINE_LINUX=$GRUB_CMDLINE_LINUX rd.qubes.hide_all_usb

Nice, that’s what I am trying to achieve.

So, OK, let me do your suggestions and report back.

@enmus it’s not working.

I have cloned the existing sys-usb qube and created “usb-keyboard” qube. I gave usb-keyboard the USB controller device (using the Qube Manager interface → settings → devices).

Then, I have edited the /etc/qubes-rpc/policy/qubes.InputKeyboard file. Here is its full content:

usb-keyboard dom0 allow

I have also tried allow,user=root, but that also didn’t work.

Further, here is my current /etc/default/grub file:

...
GRUB_CMDLINE_LINUX="rd.linux.uuid=luks-<REDACTED> [...] rhgb quiet"
...
GRUB_CMDLINE_LINUX="$GRUB_CMDLINE_LINUX rd.qubes.hide_all_usb"

Given all of these, how do I achieve getting my USB keyboard device workin through “usb-keyboard” disposable, minimal debian qube (which itself is the clone of the sys-usb qube) ?

Then I suspect you are missing qubes-usb-proxy and qubes-input-proxy-sender packages in a usb-keyboard’s template:

USB qube, such as the template for sys-usb: qubes-usb-proxy to provide USB devices to other Qubes and qubes-input-proxy-sender to provide keyboard or mouse input to dom0.

2 Likes

That was it! The usb-keyboard qube’s template was missing qubes-input-proxy-sender package.

Here’s how I made it work:’

  1. Clone the existing sys-usb qube’s templateVM using the Qube Manager GUI and name it “d11m-usb-keyboard” (d11m is my short-hand notation for (m)inimal (d)ebian (11) qube templates).

  2. Then, on the dom0 terminal, use the following command to install qubes-input-proxy-sender package into the d11m-usb-keyboard template: (dom0) $ qvm-run --pass-io --user root d11m-usb-keyboard 'sudo apt install qubes-input-proxy-sender -y'

  3. Then, clone the disposable template of sys-usb qube and name it “d11m-usb-keyboard-d”. Make sure you change this newly cloned disposable template’s templateVM to “d11m-usb-keyboard” template from Qube Manager GUI.

  4. Lastly, clone the existing “sys-usb” qube, name it “usb-keyboard” and change the “usb-keyboard” qube’s template to “d11m-usb-keyboard-d”, so that it uses the proper disposable template. Also, using the Qube Manager GUI, assign the proper USB controller device to “usb-keyboard” qube.

Make sure you have the following line top-most set on /etc/qubes-rpc/policy/qubes.InputKeyboard :

usb-keyboard dom0 allow

Lastly, for added security, add usbcore.authorized_default=0 parameter to the $GRUB_CMDLINE_LINUX line on /etc/default/grub file and rebuild the grub as described above in this thread.

And voila! Upon connecting your USB keyboard to the USB ports that are controlled by the specific USB controller device that you’ve assigned to the “usb-keyboard” qube, you will be able to use your USB keyboard.

Thanks to everyone who helped!

2 Likes

Great you made it. Just now after all, to note that for some laptops internal keyboard can be on a USB controller, so yes, you can lock yourself in such case if you hide all controllers from dom0. But, as far as I know there is a workaround. You enter the grub on boot, delete the switch and boot normally.

Thanks for the headsup. In my Thinkpad X220, the internal keyboard isn’t a USB one. So I am able to enter my disk decryption passphrase upon boot.

1 Like