Add Custom Libvirt AppArmor Permissions
For reasons detailed in my post about setting QEMU 9pfs’s fmode/dmode features via libvirt, I recently needed to figure out how to allow a particular libvirt/QEMU-based virtual machine (VM) access to enumerated folder(s) on the host. This wasn’t as straight forward as I would have hoped as the AppArmor profiles are both dynamicaly generated and ephemeral.
How VM AppArmor Profiles are Generated
Both this section and the next are heavily based off the libvirt AppArmor documentation with some added personal observations.
Everytime a VM is started, virt-aa-helper
is launched and does one of two things:
- If an AppArmor profile already exists at
/etc/apparmor.d/libvirt/libvirt-<uuid>
(where <uuid> is the domain UUID), it will use it. - If an AppArmor profile does not exist,
virt-aa-helper
parses the domain XML and creates a tailored profile for that particular VM at/etc/apparmor.d/libvirt/libvirt-<uuid>
and/etc/apparmor.d/libvirt/libvirt-<uuid>.files
. Thelibvirt-<uuid>
file is the same between all VMs andlibvirt-<uuid>.files
contains all of the VM-specific files/folders (including paths parsed out of shares).
Additionally all libvirt/QEMU AppArmor profiles include /etc/apparmor.d/abstractions/libvirt-qemu
so you can apply extra file rules across all libvirt/QEMU profiles.
How VM AppArmor Profiles are Removed
Everytime a VM is shutdown, virt-aa-helper
unconditionally deletes both /etc/apparmor.d/libvirt/libvirt-<uuid>
and /etc/apparmor.d/libvirt/libvirt-<uuid>.files
.
Where The Problems Arise
This setup causes several problems:
- The first thing most guides say to do when debugging is to set a particular AppArmor profile to “complain” mode using
aa-complain
which logs, rather than enforces, all the AppArmor rules. Since the libvirt AppArmor profiles are ephemeral, you cannot useaa-complain
. This makes troubleshooting AppArmor profiles more difficult. - The documentation states that you can tweak a particular domain’s AppArmor profile by modifying
/etc/apparmor.d/libvirt-<uuid>
which is true… once. You can edit that file and it will be used for the next VM start. However, it will be unconditionally deleted when the VM shuts downs. This means you cannot have a persistent VM-specific AppArmor rule.
Solution/Workaround
Unfortunately there is no way of adding a VM-specific AppArmor rule due to problem #2 above. The best you can do, as I alluded to earlier, is to use the libvirt/QEMU-wide /etc/apparmor.d/abstractions/libvirt-qemu
file. This has the downside of affecting all VMs rather than just the one you care about.
I have some half-formed ideas on how virt-aa-helper
could be modified to allow for persistent VM-specific rules but my personal use-case for this particular functionality is only relevant until libvirt v6.10 is released. If you’re interested, shoot me a note and I’m happy to chat about it.