AppArmorLibvirtProfile
|
Size: 17735
Comment: add new blocker
|
Size: 17748
Comment:
|
| Deletions are marked like this. | Additions are marked like this. |
| Line 83: | Line 83: |
| * [[https://bugs.launchpad.net/ubuntu/+source/linux/+bug/401931|bug #401931]]: [karmic] aa_change_profile() no longer works (Fix Released) * [[https://bugs.launchpad.net/ubuntu/+source/apparmor/+bug/408773|bug #408773]]: apparmor capabilities not working properly |
* [[https://bugs.launchpad.net/ubuntu/+source/linux/+bug/401931|bug #401931]]: [karmic] aa_change_profile() no longer works '''NEEDED''' * [[https://bugs.launchpad.net/ubuntu/+source/apparmor/+bug/408773|bug #408773]]: apparmor capabilities not working properly (Fix Released) |
Describe SecurityTeam/Specifications/AppArmorLibvirtProfile here.
Launchpad Entry: security-karmic-missing-profiles
Created: 2009-06-17
Contributors: jdstrand
Packages affected: libvirt and apparmor
Launchpad Bug: 388422
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. Because root privileges are needed to manipulate AppArmor profiles, qemu:///session will not be supported at this time. As such, the implementation and profile must allow for a confined libvirtd with qemu:///session guests running unconfined.
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)
libvirt 0.6.4 requires a patch to add back in virDomainObjPtr argument to RestoreSecurityImageLabel since AppArmor labels are not stored on disk. This was not an issue with 0.6.1, but an upstream change made the (wrong) assumption that MAC labelling is always stored with the file. Patch is very small.
Blocked by
bug #375422: AppArmor not available in 9.10 (Fix Released)
bug #401931: [karmic] aa_change_profile() no longer works NEEDED
bug #408773: apparmor capabilities not working properly (Fix Released)
Test/Demo Plan
Please note that 9.04 packages for libvirt 0.6.1 will be supplied in a PPA. Due to bug #390810, the libvirtd profile must be in complain mode, and not enforcing (though virt-aa-helper and guests will be in enforce mode).
Packages for 9.04 and 9.10 can be found in https://launchpad.net/~jdstrand/+archive/ppa.
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). Note that libvirtd will always need to be restarted if you change its profile from unconfined to complain/enforcing or vice-versa. All tests assume qemu:///system unless otherwise noted.
Test case |
9.04 |
9.10 |
virsh capabilities (when enabled, should show apparmor secmodel under <host>) |
pass |
pass3 |
virsh dominfo <guest> (when enabled, should show 'Security model: apparmor')1 |
pass |
pass |
virsh dumpxml <guest> (when enabled, should show <seclabel> section)1 |
pass |
pass |
virsh start <guest> (when enabled, should be confined, otherwise unconfined)2 |
pass |
pass |
virsh shutdown <guest> (when enabled, should unload the profile)2 |
pass |
pass |
virsh destroy <guest> (when enabled, should unload the profile)2 |
pass |
pass |
virsh -c qemu:///session start <guest> (should be unconfined) |
pass |
pass |
virsh -c qemu:///session shutdown <guest> |
pass |
pass |
virsh -c qemu:///session destroy <guest> |
pass |
pass |
- needs to be started first
use sudo aa-status
requires patch for upstream bug #505625
Guests
Test case |
9.04 |
9.10 |
start confined libvirtd, guest without existing profile confined on start |
pass |
pass |
start confined libvirtd, guest with existing profile confined on start |
pass |
pass |
virsh dumpxml <guest> (when enabled, should show <seclabel> section)1 |
pass |
pass |
add a disk via virt-manager2 |
pass |
pass |
add a disk via virsh define2 |
pass |
pass |
uses a disk with '/./' or '/../' in the path3 |
pass |
pass |
uses a disk with symlink in the path4 |
pass |
pass |
uses a non-existent disk (should fail gracefully) |
pass |
pass |
hotplugging a disk (add a USB disk with virt-manager) |
FAIL4 |
FAIL4 |
add a CDROM iso |
pass |
pass |
disconnect a connected CDROM iso2 |
pass |
pass |
install with virt-install |
pass |
pass |
install with vmbuilder |
pass |
NEEDED6 |
install with virt-manager and local ISO |
pass |
pass |
install with virt-manager and local ISO with no storage |
N/A |
pass |
install with virt-manager and network tree |
NEEDED |
NEEDED |
install with virt-manager and local cdrom |
pass |
pass |
install with virt-manager and PXE |
NEEDED |
NEEDED |
virt-clone |
pass |
pass |
add non-disk hardware to the guest |
pass (added tablet) |
pass (added tablet) |
modifying hardware in the guest |
pass (changed memory) |
pass (changed memory) |
default networking (NAT with dnsmasq) |
pass |
pass |
bridged networking |
pass |
NEEDED |
- guest may need to be started first
disk is removed from /etc/apparmor.d/libvirt/libvir-<uuid>.disks on next machine boot
AppArmor will normalize the path, virt-aa-helper should do the same
/etc/apparmor.d/libvirt/libvir-<uuid>.disks is updated and the profile reloaded, but the disk doesn't work until reboot of guest
- while initial install is ok, subsequent reboots don't work (no disks in the profile even though it is in the xml)
could not test due to bug #403216
Hypervisors
The security plugin framework in libvirt 0.6.1 and higher currently only supports kvm/qemu and not xen, openvz, etc. When using a hypervisor that doesn't support the security driver, libvirt simply ignores the driver.
Test case |
9.04 |
9.10 |
kvm (should be confined) |
pass |
pass |
qemu (should be confined) |
pass1,2 |
pass1,2 |
kqemu (should be confined) |
pass2 |
pass2 |
xen (should not be confined (this is an upstream test)) |
NEEDED (possibly) |
NEEDED (possibly) |
openvz (should not be confined (this is an upstream test)) |
NEEDED (possibly) |
NEEDED (possibly) |
- works but if error the label doesn't get removed, so libvirtd has to be started (may be limitation of security plugin framework)
- guest created with virt-manager
Remote vs local
Please note that if testing this on a virtual machine, you'll need to change the virtual machine's libvirt network configuration like so:
$ virsh net-dumpxml default | sed 's/192.168.122/192.168.123/g' > /tmp/foo.xml $ virsh net-define /tmp/foo.xml $ virsh net-destroy default $ virsh net-start default
Otherwise, you will lose network connectivity in the guest.
Test case |
9.04 |
9.10 |
unconfined client runs virsh -c qemu+ssh://<confined host>/system capabilities (shows apparmor secmodel under <host>) |
pass |
pass3 |
unconfined client runs virsh -c qemu+ssh://<confined host>/system dominfo <guest> (has 'Security model: apparmor')1 |
pass |
pass |
unconfined client runs virsh -c qemu+ssh://<confined host>/system dumpxml <guest> (has seclabel)1 |
pass |
pass |
unconfined client starts guest on remote host with AppArmor (remote guest is confined) |
pass |
pass |
unconfined client shuts down guest on remote host with AppArmor (profile removed) |
pass |
pass |
unconfined client destroys guest on remote host with AppArmor (profile removed) |
pass |
pass |
confined client2 runs virsh -c qemu+ssh://<unconfined host>/system capabilities (no security driver) |
pass |
pass |
confined client2 runs virsh -c qemu+ssh://<unconfined host>/system dominfo <guest> (no security model) |
pass |
pass |
confined client2 runs virsh -c qemu+ssh://<unconfined host>/system dumpxml <guest> (no seclabel) |
pass |
pass |
confined client2 starts guest on remote host without AppArmor |
pass |
pass |
confined client2 shuts down guest on remote host without AppArmor |
pass |
pass |
confined client2 destroys guest on remote host without AppArmor |
pass |
pass |
unconfined client runs virsh -c qemu+ssh://<unconfined host>/system capabilities (no security driver) |
pass |
pass |
unconfined client runs virsh -c qemu+ssh://<unconfined host>/system dominfo <guest> (no security model) |
pass |
pass |
unconfined client runs virsh -c qemu+ssh://<unconfined host>/system dumpxml <guest> (no seclabel) |
pass |
pass |
unconfined client starts guest on remote host without AppArmor (remote guest is unconfined) |
pass |
pass |
unconfined client shuts down guest on remote host without AppArmor |
pass |
pass |
unconfined client destroys guest on remote host without AppArmor |
pass |
pass |
- guest may need to be started first
'confined client' means AppArmor is enabled on this host, not that virsh has a profile
requires patch for upstream bug #505625
Upstream bugs
verify https://bugzilla.redhat.com/show_bug.cgi?id=499569 is fixed (CONFIRMED OK)
verify https://bugzilla.redhat.com/show_bug.cgi?id=507555 is not a problem (CONFIRMED OK)
verify https://bugzilla.redhat.com/show_bug.cgi?id=493692 is not a problem (CONFIRMED OK)
verify https://bugzilla.redhat.com/show_bug.cgi?id=505625 is not a problem on Karmic (CONFIRMED OK)
Other investigations
These haven't been tested, but should be considered:
- vde
- kvm-pxe
- storage pools
- migration
Unresolved issues
qemu://session is not supported because libvirtd is started as a non-root user and cannot write and load AppArmor profiles.
SecurityTeam/Specifications/Karmic/AppArmorLibvirtProfile (last edited 2011-05-04 13:55:02 by pool-71-114-233-7)