feat: allow disp-sys-usb to be an AudioVM

- End qrexec policy with deny rules;
- Move the USB setup from sys-audio to sys-usb; and
- Document the pros and cons of the different types of USB devices
  assignment to client qubes or to the server.
This commit is contained in:
Ben Grande 2024-02-28 22:22:59 +01:00
parent 7e973630bc
commit ead4073bcf
4 changed files with 168 additions and 48 deletions

View File

@ -8,12 +8,13 @@ Audio operations in Qubes OS.
* [Installation](#installation)
* [Usage](#usage)
* [Audio control](#audio-control)
* [Client switched it's AudioVM](#client-switched-its-audiovm)
* [Client started before it's AudioVM](#client-started-before-its-audiovm)
* [Client turned off with a device attached](#client-turned-off-with-a-device-attached)
* [How to use devices](#how-to-use-devices)
* [How to use USB devices](#how-to-use-usb-devices)
* [How to use Bluetooth](#how-to-use-bluetooth)
* [How to make the Bluetooth icon appear in the system tray](#how-to-make-the-bluetooth-icon-appear-in-the-system-tray)
* [How to attach the Bluetooth controller to the AudioVM persistenly](#how-to-attach-the-bluetooth-controller-to-the-audiovm-persistenly)
* [How to attach the Bluetooth controller to the AudioVM persistently](#how-to-attach-the-bluetooth-controller-to-the-audiovm-persistently)
## Description
@ -49,11 +50,11 @@ sudo qubesctl --skip-dom0 --targets=tpl-sys-audio state.apply sys-audio.install-
### Audio control
The qube `disp-sys-audio` will be used for audio capabilities for speakers and
microphone, with builtin modules, Jack port or Bluetooth. You are be able to
control the volume via the volume icon that appears on the system tray.
The qube `disp-sys-audio` will be used for audio capabilities for speakers
and microphone, with builtin modules, Jack port or Bluetooth. You are be able
to control the volume via the volume icon that appears on the system tray.
The basics are very simple to use:
Audio control basics:
- Left click toggles the volume; and
- Scrolling the mouse from left to right changes the volume;
@ -61,6 +62,11 @@ The basics are very simple to use:
For more advanced features, right click the icon and click on `Open Mixer` or
`Prefences`. For greater control, use the command `amixer`.
### Client switched it's AudioVM
If the client has already started when you decided to switch the AudioVM, you
will need to restart the client qube until [upstream issue is fixed](https://github.com/QubesOS/qubes-issues/issues/8975).
### Client started before it's AudioVM
Audio will not automatically connect if the AudioVM starts after the client.
@ -75,22 +81,13 @@ If you shutdown a client qube with a device attached, such as a microphone or
speaker, normal operation to attach the device to the same or any other qube
will fail. To be able to use the device again:
- Restart the audio server `disp-sys-audio`;
- Restart the AudioVM `disp-sys-audio`;
- Restart the audio client; and
- Attach the device to the audio client;
- Attach the device to the audio client.
### How to use devices
### How to use USB devices
Bluetooth and Camera are normally integrated in laptops, but they still are
USB devices internally. They will be held by `(disp-)sys-usb` or
`(disp-)sys-net`, else `dom0`.
Built-in microphones on the other hand, are directly attached to `dom0`.
To use these devices, you have to attach them to their respective qubes:
- audio server: Bluetooth; and
- audio client: cameras, speakers, microphones.
Please refer to the [sys-usb formula instructions](../sys-usb/README.md).
### How to use Bluetooth
@ -102,13 +99,13 @@ system tray is to attach the Bluetooth controller persistently to the AudioVM.
If you don't do this, you will have to attach the Bluetooth controller
manually to `disp-sys-audio` after it has started and also run `blueman-tray`.
#### How to attach the Bluetooth controller to the AudioVM persistenly
#### How to attach the Bluetooth controller to the AudioVM persistently
If using Bluetooth, you probably want to have it persistently attached to the
AudioVM. Bluetooth devices are held by the USB stack, thus you need to attach
from you `(disp-)sys-usb` to the `disp-sys-audio`.
from your `(disp-)sys-usb` to the `disp-sys-audio`.
Note that if you attach the device, the AudioVM will
Note that if you attach the device persistently, the AudioVM will
[not be able to start](https://github.com/QubesOS/qubes-issues/issues/8877)
without first starting the backend holding the USB stack. You can move the
controller from the USB qube to the Audio qube, but this would decrease your

View File

@ -7,33 +7,48 @@
## Do not modify this file, create a new policy with with a lower number in the
## file name instead. For example `30-user.policy`.
{% set audiovm = 'disp-' ~ sls_path %}
## Literal name 'sys-usb' in case user has not installed via our formula.
admin.vm.device.usb.Available * @tag:audiovm sys-usb allow target=dom0
admin.vm.device.usb.Available * @tag:audiovm @tag:usbvm allow target=dom0
admin.vm.device.usb.Available * @tag:audiovm @anyvm deny
## Literal name 'sys-usb' in case user has not installed from our formula.
admin.vm.device.usb.Available * disp-{{ sls_path }} sys-usb allow target=dom0
admin.vm.device.usb.Available * disp-{{ sls_path }} @tag:usbvm allow target=dom0
admin.vm.device.mic.Available * disp-{{ sls_path }} @adminvm allow target=dom0
admin.vm.device.mic.Available * @tag:audiovm @adminvm allow target=dom0
admin.vm.device.mic.Available * @anyvm @anyvm deny
admin.Events * disp-{{ sls_path }} disp-{{ sls_path }} allow target=dom0
admin.Events * disp-{{ sls_path }} @adminvm allow target=dom0
admin.Events * disp-{{ sls_path }} @tag:audiovm-disp-{{ sls_path }} allow target=dom0
admin.Events * {{ audiovm }} @tag:audiovm-{{ audiovm }} allow target=dom0
admin.Events * @tag:audiovm @adminvm allow target=dom0
admin.Events * @tag:audiovm @anyvm deny
admin.vm.CurrentState * disp-{{ sls_path }} disp-{{ sls_path }} allow target=dom0
admin.vm.CurrentState * disp-{{ sls_path }} @adminvm allow target=dom0
admin.vm.CurrentState * disp-{{ sls_path }} @tag:audiovm-disp-{{ sls_path }} allow target=dom0
admin.vm.CurrentState * {{ audiovm }} @tag:audiovm-{{ audiovm }} allow target=dom0
admin.vm.CurrentState * @tag:audiovm @adminvm allow target=dom0
admin.vm.CurrentState * @tag:audiovm @anyvm deny
admin.vm.List * disp-{{ sls_path }} disp-{{ sls_path }} allow target=dom0
admin.vm.List * disp-{{ sls_path }} @adminvm allow target=dom0
admin.vm.List * disp-{{ sls_path }} @tag:audiovm-disp-{{ sls_path }} allow target=dom0
admin.vm.List * {{ audiovm }} @tag:audiovm-{{ audiovm }} allow target=dom0
admin.vm.List * @tag:audiovm @adminvm allow target=dom0
admin.vm.List * @tag:audiovm @anyvm deny
admin.vm.property.Get +audiovm disp-{{ sls_path }} @tag:audiovm-disp-{{ sls_path }} allow target=dom0
admin.vm.property.Get +xid disp-{{ sls_path }} @tag:audiovm-disp-{{ sls_path }} allow target=dom0
admin.vm.property.Get +stubdom_xid disp-{{ sls_path }} @tag:audiovm-disp-{{ sls_path }} allow target=dom0
admin.vm.property.Get +audiovm {{ audiovm }} @tag:audiovm-{{ audiovm }} allow target=dom0
admin.vm.property.Get +audiovm @anyvm @tag:audiovm-{{ audiovm }} deny
admin.vm.feature.CheckWithTemplate +audio disp-{{ sls_path }} @tag:audiovm-disp-{{ sls_path }} allow target=dom0
admin.vm.feature.CheckWithTemplate +audio-model disp-{{ sls_path }} @tag:audiovm-disp-{{ sls_path }} allow target=dom0
admin.vm.feature.CheckWithTemplate +supported-service.pipewire disp-{{ sls_path }} @tag:audiovm-disp-{{ sls_path }} allow target=dom0
admin.vm.feature.CheckWithTemplate +audio-low-latency disp-{{ sls_path }} @tag:audiovm-disp-{{ sls_path }} allow target=dom0
admin.vm.property.Get +stubdom_xid {{ audiovm }} @tag:audiovm-{{ audiovm }} allow target=dom0
admin.vm.property.Get +stubdom_xid @anyvm @tag:audiovm-{{ audiovm }} deny
admin.vm.property.GetAll * disp-{{ sls_path }} disp-{{ sls_path }} allow target=dom0
admin.vm.property.GetAll * disp-{{ sls_path }} @tag:audiovm-disp-{{ sls_path }} allow target=dom0
admin.vm.property.Get +xid {{ audiovm }} @tag:audiovm-{{ audiovm }} allow target=dom0
admin.vm.property.Get +xid @anyvm @tag:audiovm-{{ audiovm }} deny
admin.vm.feature.CheckWithTemplate +audio {{ audiovm }} @tag:audiovm-{{ audiovm }} allow target=dom0
admin.vm.feature.CheckWithTemplate +audio @anyvm @tag:audiovm-{{ audiovm }} deny
admin.vm.feature.CheckWithTemplate +audio-low-latency {{ audiovm }} @tag:audiovm-{{ audiovm }} allow target=dom0
admin.vm.feature.CheckWithTemplate +audio-low-latency @anyvm @tag:audiovm-{{ audiovm }} deny
admin.vm.feature.CheckWithTemplate +audio-model {{ audiovm }} @tag:audiovm-{{ audiovm }} allow target=dom0
admin.vm.feature.CheckWithTemplate +audio-model @anyvm @tag:audiovm-{{ audiovm }} deny
admin.vm.feature.CheckWithTemplate +supported-service.pipewire {{ audiovm }} @tag:audiovm-{{ audiovm }} allow target=dom0
admin.vm.feature.CheckWithTemplate +supported-service.pipewire @anyvm @tag:audiovm-{{ audiovm }} deny
admin.vm.property.GetAll * {{ audiovm }} @tag:audiovm-{{ audiovm }} allow target=dom0
admin.vm.property.GetAll * @anyvm @tag:audiovm-{{ audiovm }} deny
## vim:ft=qrexecpolicy

View File

@ -6,8 +6,15 @@ PCI handler of USB devices in Qubes OS.
* [Description](#description)
* [Installation](#installation)
* [Keyboard installation](#keyboard-installation)
* [AudioVM installation](#audiovm-installation)
* [Client installation](#client-installation)
* [Client USB proxy installation](#client-usb-proxy-installation)
* [Client cryptsetup installation](#client-cryptsetup-installation)
* [Client CTAP installation](#client-ctap-installation)
* [Access control](#access-control)
* [Usage](#usage)
* [How to use audio devices](#how-to-use-audio-devices)
* [Credits](#credits)
## Description
@ -32,22 +39,46 @@ sudo qubesctl --skip-dom0 --targets=tpl-sys-usb state.apply sys-usb.install
```
<!-- pkg:end:post-install -->
### Keyboard installation
If you use an USB keyboard, also run:
```sh
sudo qubesctl state.apply sys-usb.keyboard
```
### AudioVM installation
If you plan to use `disp-sys-usb` as an AudioVM:
```sh
sudo qubesctl --skip-dom0 --targets=tpl-sys-usb state.apply sys-audio.install
sudo qubesctl --skip-dom0 --targets=dvm-sys-usb state.apply sys-audio.configure-dvm
qvm-tags disp-sys-usb add audiovm
qvm-features disp-sys-usb service.audiovm 1
```
And set the qube preference `audiovm` to `disp-sys-usb`:
```sh
qvm-prefs QUBE audiovm disp-sys-usb
```
### Client installation
#### Client USB proxy installation
Install the proxy on the client template:
```sh
sudo qubesctl --skip-dom0 --targets=tpl-QUBE state.apply sys-usb.install-client-proxy
```
#### Client cryptsetup installation
If the client requires decrypting a device, install on the client template:
```sh
sudo qubesctl --skip-dom0 --targets=tpl-QUBE state.apply sys-usb.install-client-cryptsetup
```
If the client requires a FIDO device, install on the client template:
#### Client CTAP installation
If the client requires a CTAP device, install on the client template:
```sh
sudo qubesctl --skip-dom0 --targets=tpl-QUBE state.apply sys-usb.install-client-fido
```
@ -70,9 +101,34 @@ Depending on you system, one or more USB qubes will be created to hold the
different controllers. The qube names are `disp-sys-usb`, `disp-sys-usb-left`,
`disp-sys-usb-dock`.
Start a USB qube an connect a device to it. USB PCI devices will appear on
the system tray icon `qui-devices`. From there, assign it to the intended
qube.
Start a USB qube an connect a device to it. USB PCI devices will appear on the
system tray icon `qui-devices`. From there, assign it to the intended qube.
### How to use audio devices
Bluetooth and Camera are normally integrated in laptops, but they still are
USB devices internally. They will be held by `(disp-)sys-usb` or
`(disp-)sys-net`, else `dom0`.
Built-in microphones on the other hand, are directly attached to `dom0`.
To use these devices, there are two options:
1. Attaching the device (USB passthrough) to the audio client:
- Advantages:
- Easier setup as it doesn't require an AudioVM.
- Disadvantages:
- Increased latency;
- Only one qube can use the device; and
- Less secure as it exposes the Audio stack to the client.
2. Leaving devices to the AudioVM (`(disp-)sys-usb` as AudioVM):
- Advantages:
- More secure as the devices are not on the client;
- Less latency; and
- All audio clients will have the same audio capabilities.
- Disadvantages:
- Some applications might not work due to not finding the device.
## Credits

View File

@ -4,6 +4,8 @@
## Do not modify this file, create a new policy with with a lower number in the
## file name instead. For example `30-user.policy`.
# Input {{{
{% if salt['pillar.get']('qvm:sys-usb:mouse-action', 'ask') == 'ask' -%}
{% set mouse_action = 'ask default_target=dom0' -%}
{% elif salt['pillar.get']('qvm:sys-usb:mouse-action', 'ask') == 'allow' -%}
@ -36,7 +38,9 @@ qubes.InputKeyboard * @tag:usbvm @adminvm deny
qubes.InputTablet * @tag:usbvm @adminvm {{ tablet_action }}
qubes.InputTablet * @tag:usbvm @adminvm deny
# }}}
# CTAP {{{
ctap.ClientPin * @anyvm @tag:usbvm ask user=root default_target=disp-{{ sls_path }}
ctap.ClientPin * @anyvm @default ask user=root default_target=disp-{{ sls_path }}
ctap.ClientPin * @anyvm @anyvm deny
@ -55,4 +59,52 @@ u2f.Register * @anyvm @anyvm deny
policy.RegisterArgument +u2f.Authenticate @tag:usbvm @anyvm allow target=dom0
policy.RegisterArgument +u2f.Authenticate @anyvm @anyvm deny
# }}}
# Audio {{{
{# Keep in sync with sys-audio policy #}
{% set audiovm = 'disp-' ~ sls_path %}
admin.vm.device.usb.Available * @tag:audiovm @tag:usbvm allow target=dom0
admin.vm.device.usb.Available * @tag:audiovm @anyvm deny
admin.vm.device.mic.Available * @tag:audiovm @adminvm allow target=dom0
admin.vm.device.mic.Available * @anyvm @anyvm deny
admin.Events * {{ audiovm }} @tag:audiovm-{{ audiovm }} allow target=dom0
admin.Events * @tag:audiovm @adminvm allow target=dom0
admin.Events * @tag:audiovm @anyvm deny
admin.vm.CurrentState * {{ audiovm }} @tag:audiovm-{{ audiovm }} allow target=dom0
admin.vm.CurrentState * @tag:audiovm @adminvm allow target=dom0
admin.vm.CurrentState * @tag:audiovm @anyvm deny
admin.vm.List * {{ audiovm }} @tag:audiovm-{{ audiovm }} allow target=dom0
admin.vm.List * @tag:audiovm @adminvm allow target=dom0
admin.vm.List * @tag:audiovm @anyvm deny
admin.vm.property.Get +audiovm {{ audiovm }} @tag:audiovm-{{ audiovm }} allow target=dom0
admin.vm.property.Get +audiovm @anyvm @tag:audiovm-{{ audiovm }} deny
admin.vm.property.Get +stubdom_xid {{ audiovm }} @tag:audiovm-{{ audiovm }} allow target=dom0
admin.vm.property.Get +stubdom_xid @anyvm @tag:audiovm-{{ audiovm }} deny
admin.vm.property.Get +xid {{ audiovm }} @tag:audiovm-{{ audiovm }} allow target=dom0
admin.vm.property.Get +xid @anyvm @tag:audiovm-{{ audiovm }} deny
admin.vm.feature.CheckWithTemplate +audio {{ audiovm }} @tag:audiovm-{{ audiovm }} allow target=dom0
admin.vm.feature.CheckWithTemplate +audio @anyvm @tag:audiovm-{{ audiovm }} deny
admin.vm.feature.CheckWithTemplate +audio-low-latency {{ audiovm }} @tag:audiovm-{{ audiovm }} allow target=dom0
admin.vm.feature.CheckWithTemplate +audio-low-latency @anyvm @tag:audiovm-{{ audiovm }} deny
admin.vm.feature.CheckWithTemplate +audio-model {{ audiovm }} @tag:audiovm-{{ audiovm }} allow target=dom0
admin.vm.feature.CheckWithTemplate +audio-model @anyvm @tag:audiovm-{{ audiovm }} deny
admin.vm.feature.CheckWithTemplate +supported-service.pipewire {{ audiovm }} @tag:audiovm-{{ audiovm }} allow target=dom0
admin.vm.feature.CheckWithTemplate +supported-service.pipewire @anyvm @tag:audiovm-{{ audiovm }} deny
admin.vm.property.GetAll * {{ audiovm }} @tag:audiovm-{{ audiovm }} allow target=dom0
admin.vm.property.GetAll * @anyvm @tag:audiovm-{{ audiovm }} deny
# }}}
# vim:ft=qrexecpolicy