Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unable to Run non-root VM with SWTPM #840

Open
kasualkeef opened this issue Mar 18, 2024 · 12 comments
Open

Unable to Run non-root VM with SWTPM #840

kasualkeef opened this issue Mar 18, 2024 · 12 comments

Comments

@kasualkeef
Copy link

I maintain RHEL9 development machines which are configured to allow libvirt/qemu VMs to be run by regular (non-root/sudo) users. We use Unix socket groups to facilitate this non-root access and it works well.

The problem comes in when trying to use SWTPM. I can configure the swtpm_group setting in /etc/libvirt/qemu.conf and it works to change the group ownership of the swtpm socket in /run/libvirt/qemu/swtpm/. However, the POSIX permissions on the socket are 0600, so the group ownership change is moot; even though the socket is owned by the correct group, users still cannot use the socket.

Steps to reproduce the behavior:

  1. Install swtpm on RHEL9
    dnf install swtpm swtwpm-tools
  2. Edit /etc/libvirt/qemu.conf, setting swtpm_group to a group of which the standard users are members
  3. Install a VM with swtpm TPM
    virt-install --connect qemu:///system --name vm01 --memory=8192 --vcpus=4 --cdrom /shared-scratch/virtual-machines/standard.user/BOOT_ISO.iso --disk /data/scratch/vms/standard.user/vm01-system.qcow2,cache=writeback,bus=virtio --disk /data/scratch/vms/standard.user/vm01-storage.qcow2,cache=writeback,bus=virtio --graphics=vnc --tpm backend.type=emulator,backend.version=2.0,model=tpm-tis --os-variant=rhel9.3 --console pty,target_type=serial

Expected behavior

I expect the swtpm socket to be accessible by the standard user based on group membership.

Instead, the following error is displayed:

Starting install...
ERROR    internal error: process exited while connecting to monitor: 2024-03-18T15:36:09.123841Z qemu-kvm: -chardev socket,id=chrtpm,path=/run/libvirt/qemu/swtpm/2-vm01-swtpm.sock: Failed to connect to '/run/libvirt/qemu/swtpm/2-vm01-swtpm.sock': Permission denied
Domain installation does not appear to have been successful.
If it was, you can restart your domain by running:
  virsh --connect qemu:///system start vm01
otherwise, please restart your installation.

The socket perms look as follows:

[standard.user@dev01 ~]$  ls -l /run/libvirt/qemu/swtpm/
total 4
-rw-r--r--. 1 root root   4 Mar 18 10:29 2-vm01-swtpm.pid
srw-------. 1 tss  users  0 Mar 18 10:29 2-vm01-swtpm.sock

Desktop:

  • OS: Red Hat Enterprise Linux
  • Version: 9.3

Versions of relevant components

  • libvirtd: 9.5.0-7.2
  • qemu: 8.0.0-16
  • swtpm: 0.8.0-1
  • swtpm-libs: 0.8.0-1
@stefanberger
Copy link
Owner

Has this socket file been used before ? Before the swtpm_group was changed? Does manual adjustment of the group ownership of the socket resolve the issue?

@kasualkeef
Copy link
Author

The socket file is created automatically and is torn down after the virt-install failure.

@stefanberger
Copy link
Owner

Did you restart libvirtd so it re-reads the config file?

@kasualkeef
Copy link
Author

Yes. I tried restarting the services and rebooting.

The changes to swtpm_group in /etc/libvirt/qemu.conf definitely work. I can change it to other groups and see the socket group change. However, the POSIX mode is always 0600.

@stefanberger
Copy link
Owner

stefanberger commented Mar 18, 2024

I think it's a libvirt issue because libvirt is setting ownership on the socket file in virSecurityDACSetTPMFileLabel() it seems. I have been experimenting with libvirt 9.7 and here the swtpm.sock file always gets the user and group of the qemu process (specified via user and group in /etc/libvirt/qemu.conf) so that the qemu process can access the socket file with 0600 without a problem.

@kasualkeef
Copy link
Author

I think I got it working!

I changed the swtpm_user to the qemu user in /etc/libvirt/qemu.conf and then gave the qemu user ownership of /var/lib/swtpm-localca

I'm testing now but it looks good so far.

@stefanberger
Copy link
Owner

stefanberger commented Mar 18, 2024

It's quite possible that with my user changing experiments I did not hit the same issue you are seeing. Your issue may be during the swtpm_setup phase. I did change swtpm_group to libvirt but kept swtpm_user at tss , which still allows access to this here:

$ ls -l /var/lib/ | grep swtpm-localca
drwxr-x---.  2 tss            root            187 Aug 15  2023 swtpm-localca

@stefanberger
Copy link
Owner

Maybe this additional sentence, if acceptable to libvirt community, would help resolve the issue:

diff --git a/src/qemu/qemu.conf.in b/src/qemu/qemu.conf.in
index f406df8749..5b16eb8835 100644
--- a/src/qemu/qemu.conf.in
+++ b/src/qemu/qemu.conf.in
@@ -918,6 +918,8 @@
 #
 # Default is 'tss'; this is the same user that tcsd (TrouSerS) installs
 # and uses; alternative is 'root'
+# The user / group specified here must have access to
+# /var/lib/swtpm-localca/ and the files located there.
 #
 #swtpm_user = "tss"
 #swtpm_group = "tss"

@kasualkeef
Copy link
Author

kasualkeef commented Mar 18, 2024

I think it's also worth noting that the qemu user will need to be set for swtpm_user if you want non-root libvirt users to access the swtpm socket because non-root libvirt still runs as qemu.

@stefanberger
Copy link
Owner

I think it's also worth noting that the qemu user will need to be set for swtpm_user if you want non-root libvirt users to access the swtpm socket because non-root libvirt still runs as qemu.

Are you sure? I thought that the swtpm socket always gets user and group of the QEMU process so that the QEMU process can access the socket (with mode 0600). swtpm_user defines the uid under which the swtpm process will run and that puts requirements on directories and file ownership but this ownership is independent of the ownership of the unix socket file that is adjusted by libvirt after swtpm was started.

@kasualkeef
Copy link
Author

At least on my systems, it was definitely creating the swtpm socket with tss user ownership. I changed swtpm_user to qemu in /etc/libvirt/qemu.conf and the socket is now being created with qemu ownership and it works.

@zippy2
Copy link
Contributor

zippy2 commented Jul 2, 2024

Libvirt runs swtpm with socket --ctrl type=unixio,path=%s,mode=0600 see https://gitlab.com/libvirt/libvirt/-/blob/master/src/qemu/qemu_tpm.c?ref_type=heads#L606 which makes sense - swtpm and QEMU are in 1:1 relationship (i.e. each QEMU process has its own swtpm instance).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants