Im ersten Moment mag sich so mancher Administrator wundern, warum er Arbeit auf die Sicherheit seiner virtualisierten System verwenden soll. Führen nicht alle Anbieter erhöhte Sicherheit als Argument für den Einsatz der Virtualisierung an? Schließlich ist mit dem Einsatz von virtuellen Maschinen doch sehr einfach eine Trennung zwischen den verschiedensten Diensten einzurichten. Waren früher einmal zwei physische Rechner nötig, um den Webserver vom Datenbank-Backend zu trennen, so genügt heute danke Virtualisierung dafür eine echte Maschine. Auf dieser kann der Administrator dank Xen, KVM oder einer anderen Virtualisierungslösung, problemlos eine Vielzahl von virtuellen Maschinen-Instanzen installieren und die gewünschten Dienste auf diesen verteilen. Aber wie so oft im Leben steckt der Teufel im Detail. Dieser Artikel gibt einen Überblick über die einzelnen Komponenten.
In den allermeisten Linux-Distributionen findet der Zugriff auf den Hypervisor – die Software die für die Virtualisierung zuständig ist – über das Libvirt-Framework [1]statt. Hierbei handelt es sich um eine Art Virtualisierungsschicht zwischen dem eigentlichen Virtualisierungs-Backend und dem Benutzerbereich. Über einheitliche Verwaltungstools kann der Anwender dann auf das jeweilige Backend zugreifen. Libvirt unterstützt als Backends neben Xen und KVM/QEMU derzeit auch noch LXC, OpenVZ, UML und Virtualbox. Mit »virt-manager
«
, »virt-install
«
und der »virsh
«
stehen Tools bereit, mit denen der Admin, unabhängig vom eingesetzten Backend, neue Systeme einrichten, verwalten und überwachen kann.
Die beiden Tools »virt-manager
«
und »virt-install
«
helfen dabei, recht einfach virtuelle Maschinen einzurichten oder bestehende im Betrieb zu verwalten. Beide Tools verbinden sich in der Standardeinstellung mit dem Hypervisor auf derselben Maschine, auf der sie gestartet wurden. Allerdings lässt sich auch eine Verbindung zu einem Hypervisor auf einer anderen Maschine aufbauen. Wer nicht möchte, dass sowohl seine Anmelde- als auch die Nutzdaten im Klartext über das Netzwerk wandern, der wählt beim Einrichten einer neue Verbindung über den Virt-Manager eine sichere Verbindung zur Gegenseite aus. Zur Auswahl stehen SSH, TLS/SSL mit X.509-Zertifikaten und Kerberos. Im Beispiel des Artikels wandern die Daten durch einen gesicherten SSH-Tunnel (Abbildung 1). Hierfür ist auf der Maschine, auf der Virt-Manager laufen soll, erstmal ein passender SSH-Schlüsselbund nötig:
ssh-keygen -t dsa ssh-copy-id -i ~/.ssh/id_dsa.pub root@↩ remote.example.com
Anschließend ist auf dem entfernten Rechner sicherzustellen, dass sowohl der SSH- wie auch der Libvirt-Daemon aktiv sind. Starten Sie nun den »virt-manager
«
, sehen Sie die neu eingerichtete Verbindung und können nun mittels Libvirt auf den entfernten Hypervisor zugreifen und bereits existierende Maschinen verwalten oder neue einrichten. Natürlich lassen sich die virtuellen Maschinen-Instanzen auch auf der Kommandozeile mittels »virt-install
«
einrichten. Die Installation einer virtuellen Maschine auf einem entfernten Rechner sieht damit zum Beispiel so aus wie in Listing 1.
Listing 1
Neue VM mit <C>virt-install<C>
virt-install \ --hvm --connect qemu+ssh://root@remote.example.com/system --name demo \ --ram 512 \ --disk path=/var/lib/libvirt/images/demo.img,size=10 \ --network network:default \ --vnc \ --location ftp://local.example.com/pub/fedora/f11/ --extra-args ks=ftp://local.example.com/pub/ks/fedora.cfg
Im diesem Beispiel verwendet die neu eingerichtete Maschine ein Netzwerk mit dem Namen »default
«
. Hierbei handelt es sich um ein virtuelles Netzwerk, das zur Default-Konfiguration von Libvirt gehört. Das Tool »virsh
«
kann nun anzeigen, wie dieses Netzwerk konfiguriert ist (Listing 2).
Listing 2
<C>virsh<C> zeigt VM-Config
$ virsh net-dumpxml default <network> <name>default</name> <uuid>478de122-05dc-4d12-b7f0-52349b59f8ef</uuid> <forward mode='nat'/> <bridge name='virbr0' stp='on' forwardDelay='0' /> <ip address='192.168.122.1' netmask='255.255.255.0'> <dhcp> <range start='192.168.122.2' end='192.168.122.254' /> </dhcp> </ip> </network>
Die Maschine bekommt also eine eigene IP-Adresse aus dem Netzwerk 192.168.122.0/24 zugewiesen. Verantwortlich hierfür ist ein Dienst namens »dnsmasq
«
. Über das Netzwerkgerät »virbr0
«
auf dem Host kann die virtuelle Maschine dann mittels Source-NAT (SNAT) mit der Außenwelt kommunizieren. Für eingehenden Netzwerkverkehr sind entsprechende Destination-NAT-Regel (DNAT) zu schreiben. Die SNAT-Regeln richtet »libvirt
«
standardmäßig ein, wie ein Aufruft von »iptables -t nat -L POSTROUTING
«
zeigt:
Chain POSTROUTING (policy ACCEPT) target prot opt source ↩ destination MASQUERADE all -- 192.168.122.0/24 ↩ !192.168.122.0/24
Nun ist aber manchmal die Kommunikation mit der Außenwelt gar nicht erwünscht. Warum sollte zum Beispiel im eingangs erwähnten Szenario die Datenbank mit der Außenwelt kommunizieren können? Stattdessen wäre es besser, für den Webserver zwei Netzwerkkarten konfigurieren. Die erste Karte kommuniziert über NAT mit der Außenwelt, die zweite Karte ist Teil eines eigenen virtuellen Netzwerks, in dem sich auch der Datenbank-Server befindet. Ein NAT'ing findet für dieses Netzwerk dann nicht statt. Hierzu bedarf es zuerst einer Konfigurationsdatei für das neue Netz (Listing 3).
Listing 3
Privates Netz der VM
$ cat > /tmp/private-net <<EOF <network> <name>private-net</name> <uuid>478d1122-05dc-4d12-b7f0-5234911911ef</uuid> <ip address='192.168.130.1' netmask='255.255.255.0'> <dhcp> <range start='192.168.130.2' end='192.168.130.254' /> </dhcp> </ip> </network> EOF
Die so erzeugte Konfigurationsdatei kann macht »virsh
«
dann der Libvirt-Konfiguration bekannt und aktiviert das Netzwerk (Listing 4).
Listing 4
Netzwerk aktivieren
$ virsh net-define /tmp/private-net Network private-net defined from /tmp/private-net $ virsh net-start private-net Network private-net started [root@tiffy ~]# virsh net-list Name State Autostart ----------------------------------------- default active yes private-net active no
Nun ist es im nächsten Schritt möglich, dem Webserver eine zweite Netzwerkkarte zuweisen und an dieses Netzwerk binden. Beim Einrichten des Datenbank-Server verwendet man bei der Installation direkt dieses neue Netzwerk. Somit ist der Webserver in der Lage, mit der Außenwelt zu kommunizieren, der Datenbank-Server ist jedoch auf eine Kommunikation mit Rechnern aus dem privaten Netzwerk beschränkt.
Wie sieht jedoch die Konfiguration aus, wenn der Administrator gar kein virtuelles Netzwerk verwendet sondern die Rechner in bereits existierende Netz integrieren möchte? Hierfür kann er eine Bridge konfigurieren, die dann an die Libvirt-Konfiguration weitergereicht wird. Meistens sollen aber die Netzwerkpakete zwischen den verschiedenen virtuellen Maschinen getrennt bleiben. Besonders dann, wenn die Maschinen vollkommen unabhängig voneinander arbeiten. Man stelle sich nur die Installation bei einem Internet-Provider vor. Hier möchte wahrscheinlich kein Kunde, dass ein anderer den eigenen Netzwerkverkehr mitlesen können. Zur Lösung könnte der ISP zum Beispiel VLANs einsetzen und die virtuellen Maschinen auf sie vteilen. Dazu genügt es, as VLAN-Device an die entsprechende Bridge zu binden.
Im folgenden Beispiel geht es um zwei voneinander getrennte Kundensysteme. Das eine System hängt im VLAN mit das Tag 100, das andere VLAN verwendet das Tag 200. Für beide Netze ist zuerst die entsprechende Konfiguration der Netzwerkkarten vorzunehmen (Listing 5).
Listing 5
VLAN-Konfiguration
$ cat > /etc/sysconfig/network-scripts/ifcfg-eth0.100 <<EOF DEVICE=eth0.100 ONBOOT=yes BRIDGE=br100 VLAN=yes EOF $ cat > /etc/sysconfig/network-scripts/ifcfg-eth0.200 <<EOF DEVICE=eth0.200 ONBOOT=yes BRIDGE=br200 VLAN=yes EOF
Anschließend erzeugt der Administrator die notwendigen Bridging-Geräte (Listing 6).
Listing 6
Bridge-Geräte
$ cat > /etc/sysconfig/network-scripts/ifcfg-br100 <<EOF DEVICE=br100 BOOTPROTO=static IPADDR=192.168.100.1 NETMASK=255.255.255.0 ONBOOT=yes TYPE=Bridge
$ cat > /etc/sysconfig/network-scripts/ifcfg-br200 <<EOF DEVICE=br200 BOOTPROTO=static IPADDR=192.168.200.1 NETMASK=255.255.255.0 ONBOOT=yes TYPE=Bridge
Nach einem Neustart des Netzwerkes sollten die neuen Bridges dann zur Verfügung stehen. Ein Aufruf von »brctl
«
bestätigt dies (Listing 7).
Listing 7
<C>brctl<C>
$ brctl show bridge name bridge id STP enabled interfaces br100 8000.000e0cb30440 no eth0.100 br200 8000.000e0cb30450 no eth0.200
Installiert der Admin nun eine neue virtuelle Maschine und möchte diese in das VLAN 100 hängen, erreicht er das durch den Aufruf von »virt-install
«
über die Option »--network bridge:br100
«
. Alternativ bietet Virt-Manager die neuen Bridges in einem Pull-Down Menü zur Auswahl an.