Secure Your KVM Virtual Machines
Jailbreak: Guard Against Breakouts on Your Virtual Machines
Virtual machines give the impression of a small jail, but administrators should not be fooled by this idea. As early as the Black Hat security conference in 2011, Nelson Elhage presented a breakout vector [1] that exploited vulnerabilities in the contemporary versions of KVM or Qemu.
Installing the Virtio driver on the guest also allowed a breakout by exploiting existing or undiscovered bugs. Once malware gains control of the host system, it can also directly hijack and control the other virtual machines running there. Administrators should therefore take care to keep KVM, Qemu, and the Virtio drivers up to date at all times. This is especially true for Windows guests, which – in contrast to Linux distributions – cannot update Virtio drivers automatically.
Walled In
To guard against a breakout, admins need to build virtual safety perimeters around their virtual machines. It helps that the virtual machines appear to be normal processes from the host system's point of view. These processes in turn can be regulated by SELinux, AppArmor, or some other mandatory access control system. The sVirt component in libvirt
0.6.1 and newer actually does some of the work for SELinux and AppArmor [2]. For example, in SELinux, sVirt attaches labels to virtual machines, which can then be isolated selectively.
You also can lock virtual machines in cgroups and thus control their resource consumption and access. Incidentally, this practice protects you against a crashed machine running wild or using too much CPU time, or a DoS attack blocking network access to other virtual machines. Normally, libvirt
automatically produces a corresponding cgroup hierarchy [3]; the access to resources can be controlled in a targeted way using the virsh
tool.
The following command, for example, restricts the computational time for a virtual machine called webserver to 100 shares (this is often equivalent to about 10 percent of the computing power):
virsh schedinfo --set cpu_shares=100 webserver
However, virsh
and KVM do not let you regulate all of your resources. The virsh
man page lists the options below schedinfo
.
HR Department
If you boot the virtual machine directly using sudo qemu-kvm -m 512
…, you are giving the VM – and any program that breaks out of jail – system privileges (Figure 1). Fortunately, root privileges are not necessary: Most distributions give normal users from the kvm
group access to /dev/kvm
. It is therefore perfectly okay to add your own user account to the kvm
group and then use this account to run qemu-kvm
… in the future. If you give the virtual machine access to the network via a TAP interface, you must also create the interface for the user and group under which the virtual machine will be running. Usually, this is qemu
in the qemu
group.
Alternatively, you can use the libvirt
tools to manage your virtual machines. They automatically start a virtual machine as the non-privileged qemu
user. A number of pitfalls exist here, however: On some distributions, such as Ubuntu, all users in the libvirtd
group are allowed to run virsh
. However, if you have access to virsh
, you can use it not only to manage all of the virtual machines, you can also use virsh nodeinfo
to query the host's hardware specs (Figure 2). Thus, virsh
and the like should only be used by selected administrators. If you integrate virsh
into your scripts, you should also check the rights these scripts have.
Furthermore, the libvirtd
daemon running on the host system likes to have root privileges. If attackers were able to contact libvirtd
, they could hijack the virtual machine and, in the worst case, the whole system. Consequently, you need to limit access to libvirtd
. In particular, you must make sure that the /etc/libvirt/libvirtd.conf
configuration file does not have a listen_tcp = 1
line. In this case, libvritd
would accept TCP connections from anyone – assuming the firewall on the host system does not block the appropriate port (by default, 16509).
Personals
Administrators also should use encryption. libvirtd
and its tools optionally can tunnel their communication via SSH, use authentication via SASL/Kerberos, or open an encrypted SSL/TLS TCP connection. In most cases, an SSH connection is probably the best bet, which means running an SSH server on the host system. Because root privileges are needed, the connection is opened with, for example:
virt-manager -c qemu+ssh://root@example.com/system
For security reasons, the SSH server should require a user login and reject root. As a compromise, you could go for certificate- or public/private key-based authentication. In case of SSL/TLS encryption, you should also change the port number in the /etc/libvirt/libvirtd.conf
configuration file so that at least direct attacks are difficult.
Finally, admins should definitely consider the contents of the LIBVIRT_DEFAULT_URI
environmental variable. It specifies the URI that virsh
and virt-manager
use by default to establish a connection. If the variable contains, for example, the value qemu://host/system
, virsh
opens an unencrypted connection if no parameters prevent this.
Buy this article as PDF
(incl. VAT)