Unternehmensnetzwerk-Simulation mit KVM/QEMU & virt-manager
Erstellt: 05.11.2026 · Zuletzt aktualisiert: 06.11.2026 · Nejat Hakan
Das Entwerfen, Härten und Analysieren von Multi-Zonen-Netzwerkarchitekturen – mit Perimeter-Firewalls, isolierten DMZs, internen LANs, autoritativen DNS-Servern und Reverse Proxies – verlangt eine realitätsnahe Testumgebung. Ein solches Lab mit physischen Switches, Routern und Servern aufzubauen, ist kostspielig, laut und starr.
Durch die Kombination von Kernel-based Virtual Machine (KVM), QEMU, libvirt und virt-manager verwandeln wir eine Linux-Workstation oder einen Server in ein Typ-1-Enterprise-Virtualisierungslabor, das komplette Multi-Subnetz-Netzwerktopologien nahezu mit nativer Hardwaregeschwindigkeit ausführt.
1. Die Linux-Virtualisierungsarchitektur (KVM + QEMU + libvirt)
Ein häufiges Missverständnis ist die Abgrenzung von KVM, QEMU, libvirt und virt-manager. Sie stehen nicht in Konkurrenz zueinander, sondern bilden einen klar geschichteten 4-Layer-Virtualisierungs-Stack:
%%{init: {'flowchart': {'wrappingWidth': 600}}}%%
flowchart TB
L4["🖥️ Layer 4: Management-Clients & UIs<br/>virt-manager (GUI) · virsh / virt-install (CLI) · Cockpit (Web-UI)"]
L3["⚙️ Layer 3: libvirtd Orchestrierungs-Daemon<br/>qemu:///system · XML-Domänen · Storage-Pools · virbr0 Linux-Bridges"]
L2["📦 Layer 2: QEMU Machine-Emulator (User Space)<br/>qemu-system-x86_64 Instanzen · VirtIO Paravirtualisierung · UEFI (OVMF)"]
L1["🐧 Layer 1: KVM Kernelmodul-Hypervisor (/dev/kvm)<br/>kvm-intel / kvm-amd · Direkte Hardware-Virtualisierung von vCPU & vRAM"]
HW["🔩 Bare-Metal Host-Hardware<br/>Intel VT-x / AMD-V CPU-Extensions & NVMe / SSD Storage"]
L4 ==>|"UNIX RPC-Socket: /run/libvirt/libvirt-sock"| L3
L3 ==>|"Prozess-Lifecycle & XML-Generierung"| L2
L2 <==>|"ioctl(/dev/kvm) System-Calls"| L1
L1 <==>|"Ring -1 Root-Mode CPU-Ausführung"| HW
Die vier Kernkomponenten
-
1. KVM (
kvm.ko) — Der Hypervisor-Kern
Ein Mainline-Linux-Kernelmodul, das den Linux-Kernel in einen Typ-1 Bare-Metal-Hypervisor transformiert. Es stellt
/dev/kvmbereit, um CPU-Befehle von Gästen direkt auf Intel VT-x oder AMD AMD-V auszuführen. -
2. QEMU — Hardware- & VirtIO-Emulator
Während KVM CPU und RAM virtualisiert, läuft QEMU als unprivilegierter User-Space-Prozess pro VM und emuliert Mainboards, UEFI (
OVMF), PCI-Busse und paravirtualisierte VirtIO-Datenträger und Netzwerkkarten. -
3.
libvirtd&virsh— Die Steuerungsebene
Ein Hintergrunddienst zur Verwaltung von VM-Lebenszyklen, deklarativen XML-Konfigurationen, virtuellen Layer-2-Switches (
virbr*),dnsmasq-DHCP/DNS-Instanzen und Speicherpools. -
4.
virt-manager— Grafische Konsole
Ein Desktop-GUI-Client mit integrierten SPICE / VNC-Grafikkonsolen, Snapshot-Verwaltung und Live-Metriken (CPU, RAM, Disk, Netzwerk), der lokal oder via SSH mit
libvirtdkommuniziert.
2. Host-Vorbereitung & Hardware-Verifikation
Schritt 1: Hardware-Virtualisierung prüfen
Überprüfe vorab, ob Intel VT-x (vmx) oder AMD AMD-V (svm) im BIOS/UEFI aktiviert ist:
# 1. CPU-Virtualisierungsunterstützung ermitteln
lscpu | grep -i virtualization
# 2. Geladene KVM-Module überprüfen
lsmod | grep kvm
# 3. Berechtigungen der /dev/kvm Gerätedatei kontrollieren
ls -la /dev/kvm
Schritt 2: Den vollständigen Virtualisierungs-Stack installieren
Wähle deine Linux-Distribution, um KVM, QEMU, libvirt, virt-manager, bridge-utils und UEFI (OVMF)-Unterstützung zu installieren:
sudo apt update
sudo apt install -y qemu-kvm libvirt-daemon-system libvirt-clients \
bridge-utils virt-manager virtinst ovmf swtpm spice-vdagent cpu-checker
# Benutzer zur libvirt- und kvm-Gruppe hinzufügen
sudo usermod -aG libvirt,kvm $(whoami)
# KVM-Beschleunigung verifizieren
kvm-ok
Schritt 3: libvirtd und Standardnetzwerk überprüfen
sudo systemctl is-active libvirtd
virsh list --all
virsh net-list --all
virsh pool-list --all
3. Virtuelle Festplatten, Speicherpools & Snapshots
Virtuelle Maschinen speichern ihr Betriebssystem in Storage Volumes innerhalb von Storage Pools (standardmäßig unter /var/lib/libvirt/images/).
Festplattenformate im Vergleich: qcow2 vs. raw
| Merkmal | qcow2 (QEMU Copy-On-Write v2) |
raw (Bitgenaues Image) |
|---|---|---|
| Speicherbelegung | Thin Provisioned (Wächst dynamisch nach Bedarf) | Thick Provisioned (Reserviert volle Größe sofort) |
| Interne Snapshots | ✅ Ja (Unterstützt Disk- und RAM-Snapshots) | ❌ Nein (Erfordert LVM/ZFS/Btrfs-Snapshots) |
| Linked Clones | ✅ Ja (Sofortige CoW-Klone von Basis-Images) | ❌ Nein |
| Kompression & Verschlüsselung | ✅ Ja (zstd-Kompression & LUKS-Verschlüsselung) |
❌ Nein |
| Empfohlener Einsatz | Standard für 99 % aller Labor- und Server-VMs | Hochlast-Datenbanken auf Block-Storage |
Hands-On Lab 1: qemu-img Erstellung, Prüfung & Konvertierung
mkdir -p ~/kvm_disk_lab && cd ~/kvm_disk_lab
# 1. Dynamisch wachsendes (sparse) 5-GiB-qcow2-Image anlegen
qemu-img create -f qcow2 thin_disk.qcow2 5G
# 2. Virtuelle Größe (5 GiB) vs. tatsächlichen Speicherplatz (~200 KiB) prüfen
qemu-img info thin_disk.qcow2
# 3. Raw-Disk erstellen und in komprimiertes qcow2 konvertieren
qemu-img create -f raw thick_disk.raw 1G
qemu-img convert -c -f raw -O qcow2 thick_disk.raw converted_disk.qcow2
qemu-img info converted_disk.qcow2
cd ~ && rm -rf ~/kvm_disk_lab
4. Virtuelle Netzwerkmodi in libvirt & KVM
Zur Simulation von Netzwerkinfrastrukturen bietet libvirt drei Kernmodi über Linux-Kernel-Bridges (virbr*) und TAP-Interfaces (vnet*):
%%{init: {'flowchart': {'wrappingWidth': 600, 'subGraphTitleMargin': {'top': 15, 'bottom': 15}}}}%%
flowchart TB
subgraph TopLevel ["🖥️ Virtuelle Maschinen (KVM / QEMU Guest Tier)"]
VM_NAT["🖥️ NAT-VM<br/>(192.168.122.x)"]
VM_ISO1["🖥️ Isolierte VM A<br/>(10.0.1.10)"]
VM_ISO2["🖥️ Isolierte VM B<br/>(10.0.1.50)"]
VM_BR["🖥️ LAN-Bridge VM<br/>(192.168.1.x)"]
end
subgraph Bridges ["🐧 Linux KVM Host: libvirt Bridges & Kernel Switches"]
direction TB
B_NAT["1️⃣ virbr0 (NAT-Bridge)<br/>192.168.122.1 / dnsmasq"]
B_ISO["2️⃣ virbr1 (Isolierter L2-Switch)<br/>Reine Bridge (Kein Routing)"]
B_BR["3️⃣ br0 (Physische Host-Bridge)<br/>Enslaved eth0 im LAN"]
end
VM_NAT <==>|"vnet0"| B_NAT
VM_ISO1 <==>|"vnet1"| B_ISO
VM_ISO2 <==>|"vnet2"| B_ISO
VM_BR <==>|"vnet3"| B_BR
NIC["🌐 Physische Host-Netzwerkkarte (eth0)"]
UPLINK(("🏠 Physischer LAN-Router & Internet<br/>(192.168.1.1)"))
B_NAT ==>|"Host-NAT / MASQUERADE"| NIC
B_BR ==>|"Layer-2 Trunk"| NIC
NIC <==> UPLINK
Die 3 Netzwerkmodi im Vergleich
| Modus | Internetzugriff? | Aus dem physischen LAN erreichbar? | Primärer Einsatzzweck |
|---|---|---|---|
1. NAT (default / virbr0) |
✅ Ja (via Host-NAT) | ❌ Nein | WAN-Uplink für pfSense oder Standalone-VMs |
2. Isoliert (lan1-net, dmz1-net) |
❌ Nein (Strikte Trennung) | ❌ Nein | Interne LAN- & DMZ-Segmente, geroutet via Firewall |
3. Host-Bridge (br0) |
✅ Ja (Direkt im LAN) | ✅ Ja (Eigene LAN-IP) | VM direkt ins physische Heim-/Büronetzwerk einbinden |
5. Das 3-Zonen-Unternehmenslabor: Topologie & IP-Planung
%%{init: {'flowchart': {'wrappingWidth': 600, 'subGraphTitleMargin': {'top': 15, 'bottom': 15}}}}%%
flowchart TB
Internet(("🌍 Internet & Host-NAT<br/>virbr0 (192.168.122.0/24)<br/>Gateway: 192.168.122.1"))
Internet <==>|"WAN (vtnet0)<br/>DHCP: 192.168.122.x"| FW
subgraph Firewall ["🛡️ Perimeter-Router & Stateful Firewall"]
FW["🔥 fw01 (pfSense CE)<br/>WAN: vtnet0 (DHCP)<br/>LAN: vtnet1 (10.0.1.1/24)<br/>DMZ: vtnet2 (10.0.2.1/24)"]
end
FW <==>|"LAN-Interface (vtnet1)<br/>Gateway: 10.0.1.1"| SwitchLAN["🖧 Isolierter Switch: lan1-net<br/>Subnetz: 10.0.1.0/24"]
FW <==>|"DMZ-Interface (vtnet2)<br/>Gateway: 10.0.2.1"| SwitchDMZ["🖧 Isolierter Switch: dmz1-net<br/>Subnetz: 10.0.2.0/24"]
subgraph ZoneLAN ["🏢 Internes vertrauenswürdiges LAN (10.0.1.0/24)"]
SRV01["🗄️ srv01.yourlab.lan<br/>Ubuntu Server (BIND9 DNS)<br/>Statische IP: 10.0.1.10/24"]
CLIENT01["💻 client01.yourlab.lan<br/>Linux Client + Wireshark<br/>Statische/DHCP IP: 10.0.1.50/24"]
end
subgraph ZoneDMZ ["🌐 Demilitarisierte Zone / DMZ (10.0.2.0/24)"]
DMZ01["🚀 dmz01.yourlab.lan<br/>Ubuntu Server (Nginx VHosts)<br/>Statische IP: 10.0.2.20/24"]
end
SwitchLAN === SRV01 & CLIENT01
SwitchDMZ === DMZ01
IP- & VM-Zuweisungstabelle
| VM-Name | Hostname (FQDN) | Rolle & Dienste | vCPUs / RAM / Disk | Netzwerkinterfaces & IP-Adressen |
|---|---|---|---|---|
fw01 |
fw01.yourlab.lan |
pfSense Firewall, NAT & DHCP | 1 vCPU / 1 GB / 10 GB |
• WAN (vtnet0): default (192.168.122.x)• LAN ( vtnet1): lan1-net (10.0.1.1/24)• DMZ ( vtnet2): dmz1-net (10.0.2.1/24) |
ubuntu-server-01 |
srv01.yourlab.lan |
BIND9 Autoritative & Rekursive DNS | 2 vCPU / 2 GB / 20 GB |
• LAN (enp1s0): lan1-net (10.0.1.10/24, GW 10.0.1.1) |
client-vm-01 |
client01.yourlab.lan |
Admin-Workstation & Wireshark | 2 vCPU / 2 GB / 15 GB |
• LAN (enp1s0): lan1-net (10.0.1.50/24, GW 10.0.1.1) |
dmz-server-01 |
dmz01.yourlab.lan |
Nginx Webserver (Multi-VHost) | 1 vCPU / 1 GB / 15 GB |
• DMZ (enp1s0): dmz1-net (10.0.2.20/24, GW 10.0.2.1) |
Schritt 1: Reine Layer-2 Virtuelle Switches anlegen (virsh)
Da pfSense (fw01) als Gateway (10.0.1.1 und 10.0.2.1) und DHCP-Server fungiert, erstellen wir lan1-net und dmz1-net als reine Layer-2-Switches ohne integriertes DHCP von libvirt:
cat << 'EOF' > /tmp/lan1-net.xml
<network>
<name>lan1-net</name>
<bridge name='virbr1' stp='on' delay='0'/>
</network>
EOF
cat << 'EOF' > /tmp/dmz1-net.xml
<network>
<name>dmz1-net</name>
<bridge name='virbr2' stp='on' delay='0'/>
</network>
EOF
virsh net-define /tmp/lan1-net.xml && virsh net-start lan1-net && virsh net-autostart lan1-net
virsh net-define /tmp/dmz1-net.xml && virsh net-start dmz1-net && virsh net-autostart dmz1-net
rm -f /tmp/lan1-net.xml /tmp/dmz1-net.xml
Schritt 2: Statische IPs auf Server-VMs konfigurieren (Netplan)
6. Perimeter-Firewall bereitstellen (pfSense auf fw01)
- Erstelle die VM
fw01invirt-managermit 3 Netzwerkkarten: - NIC 1 (
vtnet0— WAN):default(NAT) - NIC 2 (
vtnet1— LAN):lan1-net(Isoliert) - NIC 3 (
vtnet2— DMZ):dmz1-net(Isoliert) - Weise in der pfSense-Konsole die IPs zu:
- LAN:
10.0.1.1/24, DHCP:10.0.1.100–10.0.1.200 - DMZ:
10.0.2.1/24, DHCP:10.0.2.100–10.0.2.200 - Wichtig: Unter Interfaces → WAN im pfSense WebGUI (
https://10.0.1.1) die Option „Block private networks and loopback addresses“ deaktivieren, da das WAN-Interface im privaten Subnetz von KVM (192.168.122.0/24) liegt!
Zero-Trust-Firewallregeln (LAN vs. DMZ)
| Interface | Aktion | Protokoll | Quelle | Ziel | Port | Zweck |
|---|---|---|---|---|---|---|
LAN |
🟢 Pass |
Any |
LAN net |
Any |
Any |
Voller Zugriff für vertrauenswürdige Admins |
DMZ |
🟢 Pass |
TCP/UDP |
DMZ net |
10.0.1.10 (srv01) |
53 |
DMZ darf nur den internen DNS abfragen |
DMZ |
🔴 Block |
Any |
DMZ net |
LAN net (10.0.1.0/24) |
Any |
Zero-Trust: Verhindert Übergreifen auf das interne LAN |
DMZ |
🟢 Pass |
TCP/UDP |
DMZ net |
Any (Internet) |
80, 443, 123 |
OS-Updates via apt und NTP |
7. Interner DNS-Server mit BIND9 auf srv01 (10.0.1.10)
Installiere BIND9 auf srv01 zur internen Auflösung von *.yourlab.lan und der Reverse-Zonen:
sudo apt update && sudo apt install -y bind9 bind9utils dnsutils
Konfiguriere /etc/bind/named.conf.options mit strikter ACL:
acl "internal-nets" {
127.0.0.0/8;
10.0.1.0/24;
10.0.2.0/24;
};
options {
directory "/var/cache/bind";
listen-on port 53 { 127.0.0.1; 10.0.1.10; };
allow-query { internal-nets; };
recursion yes;
forwarders { 10.0.1.1; 1.1.1.1; };
dnssec-validation auto;
};
8. Webserver mit Nginx Virtual Hosts in der DMZ (dmz01)
Auf dmz01 (10.0.2.20) richten wir Nginx mit zwei Virtual Hosts ein:
sudo apt update && sudo apt install -y nginx
sudo mkdir -p /var/www/dmz01_yourlab_lan/html /var/www/app_yourlab_lan/html
echo "<h1>Willkommen auf dmz01.yourlab.lan (10.0.2.20)</h1>" | sudo tee /var/www/dmz01_yourlab_lan/html/index.html
echo "<h1>Willkommen auf app.yourlab.lan (10.0.2.20)</h1>" | sudo tee /var/www/app_yourlab_lan/html/index.html
9. Paketanalyse & Protokollinspektion mit Wireshark
Da virbr1 und virbr2 direkte Kernel-Bridges auf dem KVM-Host sind, kannst du Wireshark direkt auf deinem Host ausführen und den gesamten VM-Verkehr mitlesen:
%%{init: {'flowchart': {'wrappingWidth': 600, 'subGraphTitleMargin': {'top': 15, 'bottom': 15}}}}%%
flowchart TB
subgraph Phase1 ["1️⃣ Phase 1: UDP Port 53 — DNS-Auflösung (auf virbr1)"]
D1["client01 (10.0.1.50) → srv01<br/>DNS-Anfrage: A app.yourlab.lan"]
D2["srv01 (10.0.1.10) → client01<br/>DNS-Antwort: A 10.0.2.20"]
D1 ==> D2
end
subgraph Phase2 ["2️⃣ Phase 2: TCP Port 80 — Drei-Wege-Handshake (Geroutet via fw01)"]
T1["client01 → dmz01:80<br/>TCP-Flags: [SYN] Seq=0"]
T2["dmz01:80 → client01<br/>TCP-Flags: [SYN, ACK] Seq=0 Ack=1"]
T3["client01 → dmz01:80<br/>TCP-Flags: [ACK] Seq=1 Ack=1"]
T1 ==> T2 ==> T3
end
subgraph Phase3 ["3️⃣ Phase 3: HTTP Layer-7 Payload & Verbindungsabbau"]
H1["client01 → dmz01<br/>HTTP GET / (Host: app.yourlab.lan)"]
H2["dmz01 → client01<br/>HTTP/1.1 200 OK (Startseite)"]
H3["[FIN, ACK] ↔ [FIN, ACK]<br/>(Verbindung geschlossen)"]
H1 ==> H2 ==> H3
end
Phase1 ==> Phase2 ==> Phase3
Wichtige Wireshark-Filter
| Filterausdruck | Wirkung |
|---|---|
dns |
Alle DNS-Anfragen und -Antworten isolieren |
icmp |
Ping-Echo-Requests und -Replies anzeigen |
ip.addr == 10.0.1.50 && ip.addr == 10.0.2.20 |
Verkehr zwischen Client und DMZ-Webserver filtern |
tcp.flags.syn == 1 && tcp.flags.ack == 0 |
Verbindungsversuche aufdecken (hilfreich bei blockierten Ports) |
10. Weitere Netzwerk-Leitfäden
-
Netzwerk-Grundlagen
IPv4/IPv6-Adressierung, Subnetzmasken, Gateways, DNS-Grundlagen und CLI-Werkzeuge (
ip,ping,ss). -
Fortgeschrittene Konfiguration & Dienste
Statische Schnittstellen, DHCP, SSH-Härtung, Firewall-Regeln (
ufw/nftables) und Netzwerkdienste. -
Virtualisierung & Routing
Linux-Kernel-Routing-Tabellen, VLAN-Tagging (
802.1Q), Netzwerk-Namespaces und Traffic Control (tc). -
Container-Netzwerkisolation
Wie Linux-Netzwerk-Namespaces und Netavark moderne Microservice-Segmentierung in Rootless Podman steuern.