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. The libvirt-<uuid> file is the same between all VMs and libvirt-<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:

  1. 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 use aa-complain. This makes troubleshooting AppArmor profiles more difficult.
  2. 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.

comments powered by Disqus