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-helperparses the domain XML and creates a tailored profile for that particular VM at
libvirt-<uuid>file is the same between all VMs and
libvirt-<uuid>.filescontains 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
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-complainwhich logs, rather than enforces, all the AppArmor rules. Since the libvirt AppArmor profiles are ephemeral, you cannot use
aa-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.
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.