Einführung
tacNET ist eine Software zur Virtualisierung von Netzwerkumgebungen bestehend aus Hosts, die miteinander vernetzt sind. Eine solche Netzwerkumgebung wird als Modul bezeichnet. tacNET ermöglicht es, mehrere Module vorzuhalten und bei Bedarf zu aktivieren, d.h. alle zum Modul gehörigen Hosts zu erzeugen und diese entsprechend der Modulbeschreibung zu vernetzen.
Die zentralen Elemente eines jeden Moduls sind der Host, welcher ein virtuelles Hostsystem repräsentiert und der Switch, mittels dessen die Hosts auf Layer-2 miteinander verbunden werden. Die Module sind untereinander unabhängig voneinander. Sie bestehen im Wesentlichen aus zwei Teilen. Zum einen aus der Modulspezifikation welche die Eigenschaften der Hosts und der Switch beschreibt und zum anderen aus den Festplattenabbildern der Hosts.
Die Modulspezifikation ist ein XML-Dokument, dessen Aufbau im Folgenden erläutert wird. Ferner gehört zur Modulspezifikation gegebenenfalls eine Modulbeschreibung in Form eines HTML-Dokumentes. Darüber hinaus können Icons zur Darstellung der Hosts und Switche hinterlegt werden, um das Erscheinungsbild des Moduls in der Web-Oberfläche zu modifizieren.
Festplattenabbilder werden seperat von der Modulbeschreibung im Format qcow2 gespeichert.
Technische Realisierung
Jedes Modul besteht aus einem Storage-Pool, indem alle Festplattenabbilder und gegebenenfalls CD-ISO-Dateien hinterlegt werden. Dieser Storage-Pool ist gleichnamig zu dem jeweiligen Modul. Beim Aktivieren eines Moduls werden diese Abbilder zur Simulation der Festplatten und CD-ROM-Laufwerke genutzt.
Wesentliche Eigenschaft von tacNET ist es, das diese Abbilder nie automatisch modifiziert werden. Um dennoch temporäre Änderungen vornehmen zu können, werden sogenannte Copy-on-Write (CoW) Abbilder erzeugt. Diese CoW-Abbilder speichern alle Änderungen, also schreibende Festplattenzugriffe, die die Hosts durchführen. Die Änderungen bleiben bis zur nächsten Aktivierung eines Moduls oder bis zum Zurücksetzen des entsprechenden Hosts über die Weboberfläche bestehen.
Dies bedeutet insbesondere, dass der Zustand aller Hosts nach der Aktivierung des Moduls stets in dem Ausgangszustand, also in dem Zustand der durch die Festplattenabbilder und die Modulspezifikation definiert wird, ist. Das persistent machen von Änderungen an Festplattenbbildern, z.B. wärend der Ausarbeitung eines Moduls wird im Abschnitt TODO beschrieben.
Die Virtualisierung von Hosts und die Verwaltung der Storage-Pools wird durch libvirt und kvm realisiert.
Darüber hinaus besteht jedes Modul aus einer Modulspezifikation. Diese beschreibt zum einen die Eigenschaften der Hosts, wie z.B. Größe des Arbeitsspeichers, Anzahl der zugeordneten CPU-Kerne und Laufwerke mit Verweis auf das jeweilige Festplattenabbild. Ferner sind in ihr alle Switche des Moduls aufgeführt und dessen Verbindung zu den Hosts.
Die Virtualisierung der Switche wird hierbei durch die Bridging-Funktion des Linux-Kernels umgesetzt. Ferner wird jedem virtuellen Switch ein VLAN zugeordnet. Dies ermöglicht einen Zugriff von externen realen Netzwerkkomponenten auf die virtuellen Netze.
Speziel für diesen Zweck steht das Element Uplink zur Verfügung, welches mit einem virtuellen Switch verbunden werden kann und eine eigene VLAN-ID bekommt. Der Einsatz des Uplinks zur Einbindung von externen Geräten solle gegenüber der Nutzung des dem Switch zugewiesenen VLANs bevorzugt werden. Der Grund hierfür ist u.a. das ein Umhängen der realen Geräte von einem virtuellen Switch zu einem anderen virtuellen Switch zur Laufzeit des Moduls nur mittels eines Uplinks möglich ist.
Die Netzwerkschnittstelle des realen Servers auf dem tacNET ausgeführt wird, markiert alle Ethernet-Frames aus virtuellen Umgebungen, gemäß IEEE 802.1Q mit der entsprechenden Switch- bzw. der Uplink-VLAN-ID. Zur Einbindung realer Komponenten kann somit ein VLAN-fähigen Switch genutzt werden.
Nutzt der reale Switch, an dem der tacNET-Server angeschlossen ist, bereits aus anderen Gründen VLANs, so ist folgendes zu beachten: Wird einem virtuellen Netz die gleiche VLAN-ID wie einem realen VLAN zugeordnet und akzeptiert der reale Switch an dem der tacNET-Server angeschlossen ist entsprechend markierte Ethernet-Frames, so können die virtuellen und realen Geräte direkt miteinander kommunizieren. Dies kann u.U. zu Störungen im realen Netz führen. Um dies auszuschließen, sollte sichergestellt werden, dass der Port des realen Switches, an dem der tacNET-Server angeschlossen ist, entsprechend konfiguriert ist. Wenngleich VLAN-fähige Switche i.d.R. ebensolche Frames standardmäßig blocken, so sollte dies im Zweifellsfall vor dem Einsatz von tacNET überprüft und sichergestellt werden.
Serverkonfiguration
Einführung
Konfigurationen für die Software tacNET, die modulübergreifend Anwendung finden, werden in der Datei /etc/tacNET.conf festgehalten. Dies beinhaltet vor allem die Angabe der Speicherorte der Modulspezifikation, als auch der Storge-Pools mit den Festplattenabbildern. Zur Konfiguration des Systems ist ein Shell-Zugang erforderlich. Dieser kann mittels ssh, des Benutzernahmens root und des bei der Installation festgelegten Kennworts hergestellt werden.
Referenz
Die Konfiguration von tacNET besteht aus Name-Wert-Paaren, dessen Syntax hier beschrieben wird. Folgende Optionen können gesetzt werden:
- title
- Titel der in der GUI angezeigt wird.
- logo
- Absoluter Pfad zu einer Datei, die als Logo ganz links oben in der GUI angezeigt werden soll
- logoMimeType
- MimeType des Logos (bsp. "image/png")
- port
- Der Port auf dem der Server hören soll. Voreinstellung: Wenn useHttps=true, dann 443 ansonsten 80.
- path
- Das Verzeichnis in dem die Module gespeichert sind. Voreinstellung: /var/lib/tacNET
- storagePath
- Verzeichnis mit den Festplattenabbildern. Für jedes Modul muss ein Unterverzeichnis existieren, das gleichnamig wie das Modul ist und alle Festplattenabilder des Moduls enthält. Voreinstellung: /var/lib/tacNET/modules
- usePam
- Gibt an ob PAM zur Authentifizierung genutzt werden soll. Ist 'false' angegeben, wird keine Authentifizierung durchgeführt. Voreinstellung: false.
- pamServiceName
- Servicename für die Pam-Konfiguration. Voreinstellung: tacNET.
- useHttps
- Gibt an, ob HTTPS anstelle von HTTP verwendet werden soll. Voreinstellung: false
- redirectToHttps
- Gibt an, ob Port 80 auf HTTPS weitergeleitet werden soll. Findet nur Verwendung wenn useHttps=true. Voreinstellung: true
- keystore
- Absoluter Pfad zum Java-Keystore, indem das Zertifikat für die HTTPS-Verbindung enthalten ist. Findet nur Verwendung wenn useHttps=true.
- keystorePassword
- Passwort für den Java-Keystore. Findet nur Verwendung wenn useHttps=true.
- keyPassword
- Passwort für das Zertifikat im Java-Keystore. Findet nur Verwendung wenn useHttps=true.
- defaultLibvirtUser
- Benutzer der beim Hinzufügen eines Servers mittels IP-Adresse oder DNS-Namen verwendet wird. Default: root
- cowPoolName
- Name des CoW-Pools. Default: cow
- vlanMin
- Niedrigste zu verwendende VLAN-ID. Der Parameter wird nur für automatische Vergabe von VLAN-IDs verwendet. Der Parameter beeinflusst die Vergabe von VLAN-IDs, die in der module.xml spezifiziert sind, nicht. Voreinstellung: 200
- vlanMax
- Höchste zu verwendende VLAN-ID. Der Parameter wird nur für automatische Vergabe von VLAN-IDs verwendet. Der Parameter beeinflusst die Vergabe von VLAN-IDs, die in der module.xml spezifiziert sind, nicht. Voreinstellung: 300
Beispiel
title=tacNET logo=/root/logo.jpg logoMimeType=image/jpg storeagePath=/root/pools
Zertifikationserzeugung
Sofern HTTPS genutzt werden soll, muss ein Zertifikat erstellt werden und im Java-Keystore hinterlegt werden. Durch den Aufruf keytool -genkeypair
kann ein einfaches selbstsigniertes Zertifikat erstellt werden. Hierbei werden die Zertifikationsattribute interaktiv abgefragt.
Weiterführende Informationen zu diesem Thema stehen hier und hier zur Verfügung.
Modulkonfiguration
Einführung
Ein Modul besteht aus einer Menge von vorkonfigurierten Hosts, Switchen und Uplinks. Diese Komponenten werden bei Aktivierung des Moduls mehrfach instanziiert (siehe Konfiguration) und bilden daher mehrere gleichartige aber voneinander unabhängige Umgebungen.
Jedes Modul besteht aus einem Verzeichnis, das unterhalb des Modul-Verzeichnisses standardmäßig /var/lib/tacNET/modules gespeichert ist. Der Name dieses Verzeichnisses gibt die Position des Moduls in der Modulauswahl an, ist ansonsten aber unbedeutend. Ferner muss in diesem Verzeichnis eine Datei Namens module.xml, das die Modulspezifikation enthält, existieren.
Referenz
Folgend werden alle Elemente der Konfigurationsdatei tabellarisch aufgeführt. Hierbei wird dem Namen von XML-Attributen ein @ vorangestellt. Alle Pfade können, sofern nicht anders angegeben, absolut oder relativ angegeben werden. Relative Pfadangaben beziehen sich auf das Verzeichnis in dem die jeweilige module.xml gespeichert ist.
Element | Elternelement | Bedeutung |
---|---|---|
modul | - | Wurzelelement |
@description | modul | Pfadangabe zu einer HTML-Datei (mit der Endung "html") oder zu einem Verzeichnis. Im ersten Fall wird die Datei als Modulbeschreibung ausgeliefert und in der Modulauswahl angezeigt. Im zweiten Fall wird die Datei "index.html" im angegebenen Verzeichnis als Modulbeschreibung ausgeliefert und angezeigt. Darüber hinaus sind alle anderen Dateien in dem Verzeichnis ebenfalls abrufbar und können relativ ohne Pfadangaben referenziert werden.
Liegen beispielsweise die Dateien index.html und logo.png in dem angegebenen Verzeichnis, so kann durch das Hinzufügen von <img src="logo.png"/> das Bild in die Modulbeschreibung eingefügt werden. |
@icons | modul | Verzeichnis in dem Icons für die Netzwerkkomponenten gespeichert sind. |
environment | modul | Container zur Auflistung aller Netzwerkkomponenten |
host | environment | Spezifikation eines Hosts |
switch | environment | Spezifikation eines Switches |
uplink | environment | Spezifikation eines Uplinks |
@mem | host | Arbeitsspeicher des Hosts in MB |
@cpuCount | host | Anzahl der CPU-Kerne die dem Host zugeordnet werden. Wird der Parameter nicht angegeben, wird dem Host ein einzelner CPU-Kern zugeordnet. |
@arch | host | Architektur des Hosts. Typischerweise entweder "i686" für 32-Bit-Maschinen oder x86_64 für 64-Bit-Maschinen. Standard: "x86_64". |
disk | host | Pfadangabe zu der Imagedatei die für den Host als virtuelle Festplatte genutzt werden soll. Beim Starten des Hosts wird hiervon ein Copy-on-Write-Overlay erstellt, so dass die angegebene Datei nicht verändert wird. Der Parameter kann mehrfach angegeben werden, wodurch der Host mehrere virtuelle Festplatten erhält. |
cdrom | host | Pfadangabe zu der Imagedatei die für den Host als CD- oder DVD-Laufwerk genutzt werden soll. Das Image wird schreibgeschützt an den Host übergeben, so dass die angegebenen Datei nicht verändert wird. Der Parameter kann mehrfach angegeben werden, wodurch der Host mehrere virtuelle Laufwerke erhält. |
nic | host | Spezifikation einer virtuellen Netzwerkkarte. Der Parameter kann mehrfach angegeben werden, wodurch der Host mehrere virtuelle Netzwerkkarten erhält. |
@mac | nic | MAC-Adresse des Hosts in Hexadezimal-Schreibweise. Wird der Parameter nicht angegeben wird dem Host eine zufällige MAC zugewiesen. Da bei zufälliger Zuweisung sich die MAC-Adresse eines Host mit jeder Aktivierung des Moduls verändern kann, wird empfohlen eine MAC-Adresse vorzugeben. Ferner wird empfohlen, dass die MAC-Adresse mit "52:54:00" beginnt. |
@connectedTo | nic, uplink | Name des Switches mit dem die Komponente beim Start des Moduls verbunden sein soll. |
@model | disk, cdrom, nic, host | Name des zu verwendenden Models einer Festplatte, eines CDROMs, einer Netzwerkkarte bzw. eines Hosts. Das spezifizierte Modell wird direkt an libvirt weitergereicht, womit jedes der von libvirt unterstützen Modelle angegeben werden kann. Wird der Parameter nicht angegeben, so wird bei Festplatten das Model "scsi", bei CDROMs das Model "ide", bei Netzwerkkarten das Model "rtl8139" und bei dem Host der Typ "pc-1.0" genutzt. |
@graphics | host | Name des zu verwendenden Grafikkarten-Typs. Der spezifizierte Typ wird direkt an libvirt weitergereicht. |
@autostart | host | Ist autostart true wird der Host während der Aktivierung des Moduls automatisch gestartet. Default: true. |
@clock | host | Art der Zeitangabe im Client. Gültige Werte sind 'localtime', 'utc'. Standard: 'localtime' |
@cpuPassthrough | host | Ist cpuPassthrough true wird die pysikalische CPU an den Gast durchgereicht. Dies ermöglicht z.B. verschachtelte Virtualisierung (nested virtualization). Andernfalls wird dem Gast eine generische CPU angezeigt. Default: false |
vnc | host | Optionale VNC-Konfiguration. |
@port | vnc | Port auf dem der VNC-Server horchen soll. Die Angabe wird nur dann verwendet, wenn lediglich eine einzelne Umgebung gestartet wird. Ist das Attribute nicht spezifiziert oder es werden mehrere Umgebungen gestartet, wird der Port automatisch vergeben. |
@keymap | vnc | Die Keymap des VNC-Servers. Standard: 'de' |
IPv4 | switch | IPv4-Konfiguration |
IPv6 | switch | IPv6-Konfiguration |
@address | IPv4, IPv6 | IPv4- bzw. IPv6-Adresse |
@prefix | IPv4, IPv6 | IPv4- bzw. IPv6-Prefix (z.B. "24") |
@forwarding | switch | Ist Forwarding true, dann dürfen Pakete an die externe Schnittstelle weitergeleitet werden. Default: false. |
@name | modul, host, switch, uplink | Name der Netzwerkkomponente, der im gesamten Modul eindeutig sein muss oder Name des Moduls, der in der Menge aller Modulnamen eindeutig sein muss. |
description | host | Beschreibung eines Hosts (optional) |
@x | host, switch, uplink | Position des Icons in der GUI auf der x-Achse in Pixeln. Wird dieser Parameter nicht angegeben, so beträgt die Position 0. |
@y | host, switch, uplink | Position des Icons in der GUI auf der y-Achse in Pixeln. Wird dieser Parameter nicht angegeben, so beträgt die Position 0. |
@icon | host, switch, uplink | Name der Datei, die als Icon in der GUI benutzt werden soll. Diese Datei muss in dem Icon-Verzeichnis liegen, das im Element "modul" aufgeführt ist. Wird dieser Parameter nicht angegeben, so wird ein Standard-Icon genutzt. |
@baseVlan | switch, uplink | Vlan-Adresse die dem Switch bzw. dem Uplink in der ersten Umgebung zugeordnet wird. In der zweiten Umgebung wird die Vlan-Adresse vlanBase+1, der in der dritten vlanBase+2, usw. zugewiesen. |
Beispielmoduldefinition
<module name="BeispielModul" description="desc" icons="icons"> <environment> <uplink name="Uplink" baseVlan="110" x="220" y="500" icon="uplink.png" connectedTo="Internet"/> <switch name="Internet" x="130" y="250" forwarding="true"> <IPv4 address="192.168.150.10" prefix="24"/> </switch> <switch name="DMZ" x="465" y="250"/> <switch name="LAN" x="970" y="250"/> <host name="Firewall" mem="128" x="300" y="250" icon="fw.png"> <disk model="virtio">firewall.qcow2</disk> <nic mac="52:54:00:60:46:01" connectedTo="Internet"/> <nic mac="52:54:00:60:46:02" connectedTo="DMZ"/> </host> <host name="Mail-Server" mem="256" x="550" y="85" icon="server.png"> <disk model="virtio">mail-server.qcow2</disk> <nic mac="52:54:00:60:46:b9" connectedTo="DMZ"/> </host> <host name="Web-Server" mem="512" x="400" y="85" icon="server.png"> <disk model="ide">web-server.qcow2</disk> <nic mac="52:54:00:60:46:c0" connectedTo="DMZ"/> </host> <host name="Router" mem="128" x="705" y="250" icon="router.png"> <disk model="virtio">router.qcow2</disk> <nic mac="52:54:00:60:46:03" connectedTo="DMZ"/> <nic mac="52:54:00:60:46:04" connectedTo="LAN"/> </host> <host name="Client1" mem="1024" x="830" y="85" icon="win7.png" autostart="false"> <disk model="ide">client1.qcow2</disk> <nic mac="52:54:00:60:50:01" connectedTo="LAN"/> </host> <host name="Client2" mem="1024" x="970" y="85" icon="linux.png"> <disk model="virtio">client2.qcow2</disk> <nic mac="52:54:00:60:50:02" connectedTo="LAN"/> </host> <host name="Client3" mem="512" x="1120" y="85" icon="linux.png" autostart="false"> <disk model="virtio">client3.qcow2</disk> <nic mac="52:54:00:60:50:03" connectedTo="LAN"/> </host> <host name="DHCP" mem="128" x="690" y="450" icon="server.png"> <disk model="virtio">dhcp.qcow2</disk> <nic mac="52:54:00:60:46:05" connectedTo="DMZ"/> <nic mac="52:54:00:60:46:06" connectedTo="LAN"/> </host> </environment> </modul>
Festplattenabbilder
Die Festplattenabbilder der Hosts müssen jeweils in die Storage-Pools kopiert werden. Hierzu muss in dem Verzeichnis, das in /etc/tacNET.conf als storagePath angegeben ist, ein Verzeichnis erstellt werden, das gleichnamig mit dem Modul ist. Hierbei ist zu beachten, dass der Name des Modules nicht der Verzeichnisname ist, indem die module.xml liegt, sondern der in der module.xml angegebene Name. In das Storage-Pool-Verzeichnis müssen alle Festplattenabbilder kopiert oder verlinkt werden, die zum jeweiligen Modul gehören.
Zur Erstellung eines neuen Festplattenabbildes wird der Befehl qemu-img create -f qcow2 <VOLLSTÄNDIGER PFAD ZUR ZU ERSTELLENDEN DATEI> <GRÖßE>
in einer Shell auf dem tacNET-Server ausgeführt.
Die Angabe der Größe des Festplattenabbildes wird dabei in Gigabyte mit einem abschließenden großen G, also z.b. 20G angegeben.
Es ist sicherzustellen, dass der Dateiname des Festplattenabbildes identisch dem Dateinamen ist, der in der Modulspezifikation aufgeführt ist und, dass der Pfad in dem das Abbild erstellt wird, der Pfad des Storage-Pools des jeweiligen Moduls ist.
Hiernach kann das Modul aktiviert und z.B. über ein virtuelles CD-ROM-Laufwerk ein Betriebssystem installiert werden. Sofern die Einrichtung des Hosts abgeschlossen ist, müssen die Änderungen, wie nachfolgend beschrieben, persisten gemacht werden.
Um Änderungen an einem Host persistent zu machen, also diese in das Festplattenabbild zu übernehmen, so dass diese nicht durch ein erneutes Aktivieren des Moduls verworfen werden, muss der Host zuerst heruntergefahren werden.
Sobald der Host inaktiv ist, können die Änderungen durch Eingabe des Befehls qemu-img commit <PFAD ZUM COW-ABBILD DES FESTPLATTENABBILDS>
vom CoW-Abbild in das Festplattenabbild kopiert werden.
Hierbei ist zu beachten, dass der anzugebende Parameter den Pfad zum CoW-Abbild und nicht zum eigentlichen Festplattenbbild angibt. Der entsprechende Pfad ist z.B. durch den Aufruf des Befehls virsh dumpxml <NAME DES HOST>
zu ermitteln.
Ferner sei darauf hingewiesen, dass das Übernehmen der Änderungen im CoW-Abbild auf andere als die hier beschriebene Weise, insbesondere wenn das Herunterfahren des Hosts ausgelassen wird, das Festplattenabbild irreparabel beschädigen kann.