AppArmorLibvirtProfile

Differences between revisions 2 and 17 (spanning 15 versions)
Revision 2 as of 2009-06-17 12:48:17
Size: 3301
Editor: pool-71-114-225-43
Comment: initial writeup
Revision 17 as of 2009-07-08 12:09:23
Size: 9509
Editor: pool-71-114-225-43
Comment: add test case table
Deletions are marked like this. Additions are marked like this.
Line 16: Line 16:
plugin architecture to confine a virtual machine, and includes a SELinux plugin architecture to confine a virtual machine, and includes an SELinux
Line 22: Line 22:
Libvirt now contains AppArmor integration. By default libvirtd will use a
non-restrictive profile and virtual machines launched by libvirt can be
confined with individual AppArmor profiles.
Libvirt now contains AppArmor integration when using KVM or QEMU. Libvirtd
can be configured to launch virtual machines that are confined by uniquely
restrictive AppArmor profiles. This feature significantly improves
virtualization in Ubuntu by providing user-space host protection as well
as guest isolation.
Line 40: Line 42:
To be determined. First pass might be to simply allow creating of profile names
(ie 'labels' in libvirt parlance) by manually modifying the XML and the libvirt
profile. Eventually having dynamic labelling where a new profile is created
for each VM when the VM is started is desirable.
When a virtual machine is started, determine if a profile is currently defined
for the machine, and use it if available. If not, generate a new profile for
the machine based on a template, which is by default a very restrictive profile
allowing access to ```disk``` files, and anything else needed to run, such as
the pid and log files.

Virtual machines should have a unique profile specific to that machine. To
ensure uniqueness, the profile name will be derived from the UUID of the
virtual machine. These profiles should be configurable, either by adjusting
the profile template for new machines, creating/modifying the VM profile
directly or through the use of AppArmor abstractions. This will allow for
administrators to fine-tune confinement for individual machines if desired.

In addition to the above, initially confine ```libvirtd``` itself with a
permissive (perhaps even complain-mode only) profile. ```libvirtd``` should not
be allowed to create arbitrary profiles or modify profiles directly, so as to
not allow ```libvirtd``` to potentially (ie via a security bug in libvirtd
itself) bootstrap out of AppArmor confinement, should it be in a restrictive
enforcing profile.

Note that the upstream security plugin framework in libvirt 0.6.1 only works
with qemu (and kvm), and not other technologies like Xen or OpenVZ. If and when
these technologies are supported by the upstream framework, AppArmor
confinement should work with them as well.
Line 47: Line 69:
 * Create an AppArmor plugin for libvirt using the security plugin framework
   provided be libvirt 0.6.1.
 * Provide an unrestricted libvirt AppArmor profile (initially)
 * Provide a restricted AppArmor abstration for guest profiles to include
 * MORE HERE
 * Create an AppArmor plugin for libvirt using the security plugin framework provided by libvirt 0.6.1. Use aa_change_profile() from (sys/apparmor.h) in the hook for virExecWithHook(). This allows ```libvirtd``` to run in it's own profile and then change to a new profile in the kvm child after fork().
 * Provide a permissive libvirt AppArmor profile (```/etc/apparmor.d/usr.sbin.libvirtd```)
 * Provide a restrictive AppArmor abstraction for guest profiles to include (```/etc/apparmor.d/abstractions/libvirt-qemu```)
 * Provide a restrictive AppArmor template to be used when generating new profiles (```/etc/apparmor.d/libvirt/TEMPLATE```).
 * Write ```virt-aa-helper``` which ```libvirtd``` calls to create/update the profiles and load them. This application can create a profile based on TEMPLATE, load a profile, unload a profile and delete a profile.
 * Provide a restrictive AppArmor profile for ```virt-aa-helper``` (as part of ```/etc/apparmor.d/usr.sbin.libvirtd```)

=== Blocked by ===
 * [[https://bugs.launchpad.net/ubuntu/+source/linux/+bug/375422|bug #375422]]: AppArmor not available in 9.10
 * [[https://bugs.launchpad.net/ubuntu/+source/apparmor/+bug/390810|bug #390810]]: prevents using ```aa_change_profile()``` while in enforce mode
Line 55: Line 82:
 * libvirt tests:
  * ```virsh capabilities```
  * ```virsh dominfo <guest>```
 * guest tests:
  * add a disk in the confined directory (should be allowed)
  * add a disk outside the confined directory (should be denied)
  * add a CDROM iso (should be allowed)
  * add hardware to the guest (should be allowed)
  * modifying hardware in the guest (should be allowed)
 * remote vs local tests
  * guest on local host with AppArmor (confined)
  * guest local host without AppArmor (unconfined)
  * unconfined virsh client starts guest on remote host with AppArmor (confined)
  * unconfined virsh client starts guest on remote host without AppArmor (unconfined)
  * confined virsh client^1 starts guest on remote host with AppArmor (confined)
  * confined virsh client^1 starts guest on remote host without AppArmor (unconfined)
=== libvirtd (daemon) ===
All of the libvirtd tests should be done with with AppArmor enabled (default
install), with AppArmor not started (```sudo /etc/init.d/apparmor stop```) and
with AppArmor disabled (boot with apparmor.enabled=0).
|| Test || Jaunty || Karmic ||
|| ```virsh capabilities``` (when enabled, should show apparmor secmodel under <host>) || || ||
|| ```virsh dominfo <guest>``` (when enabled, should show 'Security model: apparmor') || || ||
|| ```virsh dumpxml <guest>``` (when enabled, should show <seclabel> section) || || ||
|| ```virsh start <guest>``` (when enabled, should be confined (use ```sudo aa-status```) || || ||
|| ```virsh shutdown <guest>``` (when enabled, should unload the profile (use ```sudo aa-status```) || || ||
|| ```virsh destroy <guest>``` (when enabled, should unload the profile (use ```sudo aa-status```) || || ||
|| If enabled, start libvirtd confined, guest should be confined on start || || ||
|| If enabled, start libvirtd unconfined, guest should be unconfined on start || || ||

Note that libvirtd will always need to be restarted if you change its profile
from unconfined to complain/enforcing or vice-versa.

=== Guests ===
|| Test || Jaunty || Karmic ||
|| start confined libvirtd, guest confined on start) || || ||
|| ```virsh dumpxml <guest>``` (when enabled, should show <seclabel> section) || || ||
|| add a disk via virt-manager || || ||
|| add a disk via ```virsh define``` || || ||
|| hotplugging a disk || || ||
|| add a CDROM iso || || ||
|| install with vmbuilder || || ||
|| install with virt-install || || ||
|| add non-disk hardware to the guest || || ||
|| modifying hardware in the guest || || ||

=== Hypervisors ===
|| Test || Jaunty || Karmic ||
|| kvm (should be confined) || || ||
|| qemu (should be confined) || || ||
|| kqemu (should be confined) || || ||
|| xen (should not be confined (this is an upstream test)) || || ||
|| openvz (should not be confined (this is an upstream test)) || || ||

=== Remote vs local ===
|| Test || Jaunty || Karmic ||
|| guest on local host with AppArmor (confined) || || ||
|| guest on local host without AppArmor (unconfined) || || ||
|| unconfined virsh client starts guest on remote host with AppArmor (confined) || || ||
|| unconfined virsh client starts guest on remote host without AppArmor (unconfined) || || ||
|| confined virsh client^1^ starts guest on remote host with AppArmor (confined) || || ||
|| confined virsh client^1^ starts guest on remote host without AppArmor (unconfined) || || ||
Line 72: Line 130:


=== Upstream bugs ===
  * verify https://bugzilla.redhat.com/show_bug.cgi?id=499569 is fixed (TODO)
  * verify https://bugzilla.redhat.com/show_bug.cgi?id=507555 is not a problem (TODO)
  * verify https://bugzilla.redhat.com/show_bug.cgi?id=493692 is not a problem (TODO-- needs profile update)

Describe SecurityTeam/Specifications/AppArmorLibvirtProfile here.

Summary

Virtual machines started by libvirt run unconfined. If there is a bug in the hypervisor, a guest could potentially attack other guests or the host. Providing an AppArmor profile would help protect against this. As of libvirt 0.6.1, sVirt has been merged and contains all the necessary hooks through a plugin architecture to confine a virtual machine, and includes an SELinux plugin. Providing an AppArmor plugin would help increase security and contain virtual machines in Ubuntu.

Release Note

Libvirt now contains AppArmor integration when using KVM or QEMU. Libvirtd can be configured to launch virtual machines that are confined by uniquely restrictive AppArmor profiles. This feature significantly improves virtualization in Ubuntu by providing user-space host protection as well as guest isolation.

Rationale

Virtual machines started by libvirt run unconfined. Since virtual machines with security bugs, misconfigured software or nefarious users could be deployed, it is imperative that the host machine is protected from attack by a malicious guest and guests be isolated from each other. Generally speaking, the hypervisor takes care of this isolation, however, bugs in the hypervisor may allow attackers to circumvent the hypervisor's protections.

AppArmor can increase security and help protect the host and isolate guests in the event of bugs in the hypervisor.

Design

When a virtual machine is started, determine if a profile is currently defined for the machine, and use it if available. If not, generate a new profile for the machine based on a template, which is by default a very restrictive profile allowing access to disk files, and anything else needed to run, such as the pid and log files.

Virtual machines should have a unique profile specific to that machine. To ensure uniqueness, the profile name will be derived from the UUID of the virtual machine. These profiles should be configurable, either by adjusting the profile template for new machines, creating/modifying the VM profile directly or through the use of AppArmor abstractions. This will allow for administrators to fine-tune confinement for individual machines if desired.

In addition to the above, initially confine libvirtd itself with a permissive (perhaps even complain-mode only) profile. libvirtd should not be allowed to create arbitrary profiles or modify profiles directly, so as to not allow libvirtd to potentially (ie via a security bug in libvirtd itself) bootstrap out of AppArmor confinement, should it be in a restrictive enforcing profile.

Note that the upstream security plugin framework in libvirt 0.6.1 only works with qemu (and kvm), and not other technologies like Xen or OpenVZ. If and when these technologies are supported by the upstream framework, AppArmor confinement should work with them as well.

Implementation

  • Create an AppArmor plugin for libvirt using the security plugin framework provided by libvirt 0.6.1. Use aa_change_profile() from (sys/apparmor.h) in the hook for virExecWithHook(). This allows libvirtd to run in it's own profile and then change to a new profile in the kvm child after fork().

  • Provide a permissive libvirt AppArmor profile (/etc/apparmor.d/usr.sbin.libvirtd)

  • Provide a restrictive AppArmor abstraction for guest profiles to include (/etc/apparmor.d/abstractions/libvirt-qemu)

  • Provide a restrictive AppArmor template to be used when generating new profiles (/etc/apparmor.d/libvirt/TEMPLATE).

  • Write virt-aa-helper which libvirtd calls to create/update the profiles and load them. This application can create a profile based on TEMPLATE, load a profile, unload a profile and delete a profile.

  • Provide a restrictive AppArmor profile for virt-aa-helper (as part of /etc/apparmor.d/usr.sbin.libvirtd)

Blocked by

Test/Demo Plan

libvirtd (daemon)

All of the libvirtd tests should be done with with AppArmor enabled (default install), with AppArmor not started (sudo /etc/init.d/apparmor stop) and with AppArmor disabled (boot with apparmor.enabled=0).

Test

Jaunty

Karmic

virsh capabilities (when enabled, should show apparmor secmodel under <host>)

virsh dominfo <guest> (when enabled, should show 'Security model: apparmor')

virsh dumpxml <guest> (when enabled, should show <seclabel> section)

virsh start <guest> (when enabled, should be confined (use sudo aa-status)

virsh shutdown <guest> (when enabled, should unload the profile (use sudo aa-status)

virsh destroy <guest> (when enabled, should unload the profile (use sudo aa-status)

If enabled, start libvirtd confined, guest should be confined on start

If enabled, start libvirtd unconfined, guest should be unconfined on start

Note that libvirtd will always need to be restarted if you change its profile from unconfined to complain/enforcing or vice-versa.

Guests

Test

Jaunty

Karmic

start confined libvirtd, guest confined on start)

virsh dumpxml <guest> (when enabled, should show <seclabel> section)

add a disk via virt-manager

add a disk via virsh define

hotplugging a disk

add a CDROM iso

install with vmbuilder

install with virt-install

add non-disk hardware to the guest

modifying hardware in the guest

Hypervisors

Test

Jaunty

Karmic

kvm (should be confined)

qemu (should be confined)

kqemu (should be confined)

xen (should not be confined (this is an upstream test))

openvz (should not be confined (this is an upstream test))

Remote vs local

Test

Jaunty

Karmic

guest on local host with AppArmor (confined)

guest on local host without AppArmor (unconfined)

unconfined virsh client starts guest on remote host with AppArmor (confined)

unconfined virsh client starts guest on remote host without AppArmor (unconfined)

confined virsh client1 starts guest on remote host with AppArmor (confined)

confined virsh client1 starts guest on remote host without AppArmor (unconfined)

[1] confined virsh client means that a local libvirtd is confined, not virsh itself

Upstream bugs

Unresolved issues

To be determined.


CategorySpec

SecurityTeam/Specifications/Karmic/AppArmorLibvirtProfile (last edited 2011-05-04 13:55:02 by pool-71-114-233-7)