Zum Inhalt

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) &nbsp;·&nbsp; virsh / virt-install (CLI) &nbsp;·&nbsp; 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/kvm bereit, 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 libvirtd kommuniziert.


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:

Terminal: CPU-Virtualisierungsflags & KVM-Kernelmodule prüfen
# 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:

Terminal: KVM/QEMU-Stack unter Debian/Ubuntu 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
Terminal: KVM/QEMU-Stack unter Fedora/RHEL installieren
sudo dnf install -y @virtualization virt-manager virt-install edk2-ovmf swtpm
sudo systemctl enable --now libvirtd
sudo usermod -aG libvirt,kvm $(whoami)
Terminal: KVM/QEMU-Stack unter Arch Linux installieren
sudo pacman -Syu --needed qemu-full libvirt virt-manager virt-install \
  dnsmasq iptables-nft bridge-utils edk2-ovmf swtpm
sudo systemctl enable --now libvirtd
sudo usermod -aG libvirt,kvm $(whoami)
Terminal: KVM/QEMU-Stack unter openSUSE installieren
sudo zypper install -y qemu-kvm libvirt virt-manager virt-install bridge-utils qemu-ovmf-x86_64
sudo systemctl enable --now libvirtd
sudo usermod -aG libvirt,kvm $(whoami)

Schritt 3: libvirtd und Standardnetzwerk überprüfen

Terminal: Libvirt-Daemon & Standard-Netzwerk prü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

Terminal: Virtuelle Disks erstellen, inspizieren und konvertieren
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:

Terminal: Virtuelle Switches virbr1 und virbr2 definieren
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)

/etc/netplan/00-installer-config.yaml auf srv01
network:
  version: 2
  renderer: networkd
  ethernets:
    enp1s0:
      dhcp4: false
      addresses: [10.0.1.10/24]
      routes:
        - to: default
          via: 10.0.1.1
      nameservers:
        addresses: [127.0.0.1, 10.0.1.1]
        search: [yourlab.lan]
/etc/netplan/00-installer-config.yaml auf client01
network:
  version: 2
  renderer: networkd
  ethernets:
    enp1s0:
      dhcp4: false
      addresses: [10.0.1.50/24]
      routes:
        - to: default
          via: 10.0.1.1
      nameservers:
        addresses: [10.0.1.10, 10.0.1.1]
        search: [yourlab.lan]
/etc/netplan/00-installer-config.yaml auf dmz01
network:
  version: 2
  renderer: networkd
  ethernets:
    enp1s0:
      dhcp4: false
      addresses: [10.0.2.20/24]
      routes:
        - to: default
          via: 10.0.2.1
      nameservers:
        addresses: [10.0.1.10, 10.0.2.1]
        search: [yourlab.lan]

6. Perimeter-Firewall bereitstellen (pfSense auf fw01)

  1. Erstelle die VM fw01 in virt-manager mit 3 Netzwerkkarten:
  2. NIC 1 (vtnet0 — WAN): default (NAT)
  3. NIC 2 (vtnet1 — LAN): lan1-net (Isoliert)
  4. NIC 3 (vtnet2 — DMZ): dmz1-net (Isoliert)
  5. Weise in der pfSense-Konsole die IPs zu:
  6. LAN: 10.0.1.1/24, DHCP: 10.0.1.100 – 10.0.1.200
  7. DMZ: 10.0.2.1/24, DHCP: 10.0.2.100 – 10.0.2.200
  8. 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:

Terminal auf srv01: BIND9 installieren
sudo apt update && sudo apt install -y bind9 bind9utils dnsutils

Konfiguriere /etc/bind/named.conf.options mit strikter ACL:

/etc/bind/named.conf.options
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:

Terminal auf dmz01: Nginx & zwei Virtual Hosts anlegen
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).

    Grundlagen: Verbindungsaufbau

  • Fortgeschrittene Konfiguration & Dienste


    Statische Schnittstellen, DHCP, SSH-Härtung, Firewall-Regeln (ufw / nftables) und Netzwerkdienste.

    Netzwerkdienste konfigurieren

  • Virtualisierung & Routing


    Linux-Kernel-Routing-Tabellen, VLAN-Tagging (802.1Q), Netzwerk-Namespaces und Traffic Control (tc).

    Routing & VLANs

  • Container-Netzwerkisolation


    Wie Linux-Netzwerk-Namespaces und Netavark moderne Microservice-Segmentierung in Rootless Podman steuern.

    Podman Netzwerk-Leitfaden