Skip to content

Commit

Permalink
Document setup needed for UEFI Secureboot signing
Browse files Browse the repository at this point in the history
This includes how to setup builder disposable template, socket->qrexec
proxy and all relevant parameters
This moves some of the setup steps from README.md in vmm-xen-unified
repo.

QubesOS/qubes-issues#8206
  • Loading branch information
marmarek committed Jan 11, 2025
1 parent dd8e333 commit 391fa39
Show file tree
Hide file tree
Showing 4 changed files with 113 additions and 0 deletions.
82 changes: 82 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,88 @@ $ qvm-prefs work-qubesos default_dispvm qubes-builder-dvm
```


### Qubes executor for secureboot signing

The `vmm-xen-unified` component builds a signed unified Xen+Linux binary. It
requires additional setup for the signing process. This approach will use
separate disposable template for just `vmm-xen-unified` component and have that
disposable access to the signing service.

Building `vmm-xen-unified` with docker executor is currently not supported.

First, you will need to generate (or otherwise obtain) signing key. This step
is not specific to qubes-builderv2, can be done with any tool. See README in
`vmm-xen-unified` for example approach. Store the keys in a separate
(preferably network-disconnected) qube (if you use HSM or other hardware token
- configure its usage in that qube). Later steps in this instruction use
`vault-pesign` name for this qube, but it can be anything. Copy
`rpc/qubesbuilder.PESign` to `/usr/local/etc/qubes-rpc` in the key-holding qube
and make sure it's executable:
```
chmod +x /usr/local/etc/qubes-rpc/qubesbuilder.PESign
```

If extra parameters for using the key are needed for `pesign`, add `/home/user/.config/qubes-pesign/CERT_NICKNAME` (where `CERT_NICKNAME` is a name used for `KEY_NAME` value later in this instruciton) to set the arguments, for example:
```
# dbpath with pkcs11 module configured
PESIGN_ARGS+=( "--certdir=$HOME/pesign-token-db" )
# token name
PESIGN_ARGS+=( "--token=token name" )
# pinfile path, if relevant
PESIGN_ARGS+=( "--pinfile=$HOME/pesign-token-pin.txt" )
# you can also override CERTIFICATE
CERTIFICATE="certificate name as on the token"
```

After doing that, create new disposable template following the above
instructions, but name it `qubes-pesign-builder-dvm`.

Then, in the `qubes-pesign-builder-dvm` do the following:
```
mkdir -p /rw/bind-dirs/etc/systemd/system/
mkdir -p /usr/local/etc/default
# adjust value if you used different key nickname, replace spaces with __
echo 'KEY_NAME="Qubes__OS__Unified__Kernel__Image__Signing__Key"' > /usr/local/etc/default
mkdir -p /rw/config/qubes-bind-dirs.d
cat <<EOF > /rw/config/qubes-bind-dirs.d/50_qubes-pesign.conf
binds+=( '/etc/systemd/system/qubes-pesign.socket' )
binds+=( '/etc/systemd/system/[email protected]' )
EOF
```

Copy `rpc/qubes-pesign*` from qubes-builderv2 into `/rw/bind-dirs/etc/systemd/system/` in `qubes-pesign-builder-dvm` and set appropriate SELinux context (if SELinux is enabled there):
```
restorecon /rw/bind-dirs/etc/systemd/system/*
```

Add starting the service in `/rw/config/rc.local`:
```
systemctl daemon-reload
systemctl start qubes-pesign.socket
```

Next step is to adjust qrexec policy to allow signing. To not depend on specific dispvm name, the policy will use tags. The `rpc/policy/50-qubesbuilder.policy` file contains commented-out example. Adjust key-holding qube name and possibly certificat nickname there.
And then add appropriate tag to the `qubes-pesign-builder-dvm`:
```
qvm-tags qubes-pesign-builder-dvm add pesign-allow
```

And finally, enable building `vmm-xen-unified` using just configured disposable
template by adding the following to your `builder.yml`:

```
+components:
- vmm-xen-unified:
packages: true
stages:
- build:
executor:
type: qubes
options:
dispvm: qubes-pesign-builder-dvm
```


## Build stages

The build process consists of the following stages:
Expand Down
7 changes: 7 additions & 0 deletions rpc/policy/50-qubesbuilder.policy
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,10 @@ qubesbuilder.FileCopyOut * work-qubesos @tag:disp-created-by-work-qubesos allow
qubes.Filecopy * work-qubesos @tag:disp-created-by-work-qubesos allow
qubes.WaitForSession * work-qubesos @tag:disp-created-by-work-qubesos allow
qubes.VMShell * work-qubesos @tag:disp-created-by-work-qubesos allow


# Enable for secureboot signing
#admin.vm.CreateDisposable * work-qubesos qubes-pesign-builder-dvm allow target=dom0
# adjust key-holding qube name (vault-pesign) and cert nickname (the service
# argument)
#qubesbuilder.PESign +Qubes__OS__Unified__Kernel__Image__Signing__Key @tag:pesign-allow @default allow target=vault-pesign
10 changes: 10 additions & 0 deletions rpc/qubes-pesign.socket
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
[Unit]
Description=Forward pesign call to vault

[Socket]
ListenStream=/run/qubes-pesign
Accept=yes
SocketGroup=qubes

[Install]
WantedBy=sockets.target
14 changes: 14 additions & 0 deletions rpc/[email protected]
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
[Unit]
Description=Forward pesign call to vault
CollectMode=inactive-or-failed

[Service]
EnvironmentFile=/usr/local/etc/default/qubes-pesign
ExecStart=/usr/bin/qrexec-client-vm @default qubesbuilder.PESign+${KEY_NAME}
StandardInput=socket
StandardOutput=inherit
StandardError=journal


binds+=( '/etc/systemd/system/qubes-pesign.socket' )
binds+=( '/etc/systemd/system/[email protected]' )

0 comments on commit 391fa39

Please sign in to comment.