Zum Inhalt

Erweitertes Linux-Networking: Kernel-Routing, 802.1Q-VLANs, LACP-Bonding & Netzwerk-Namespaces

Erstellt: 06.11.2026  ·  Zuletzt aktualisiert: 06.11.2026  ·  Nejat Hakan

Management Summary: Hinter kommerziellen Hardware-Routern, Cloud-SDN-Strukturen, Kubernetes-CNI-Plugins und KVM-Hypervisoren arbeitet das Netzwerk-Subsystem des Linux-Kernels. Ohne proprietäre Spezialappliances kann ein Standard-Debian-Linux-Server Millionen Pakete pro Sekunde über 802.1Q-VLAN-Trunks vermitteln, redundante 10GbE/25GbE-Netzwerkkarten via 802.3ad LACP-Bonding bündeln, Datenverkehr über mehrere Uplinks mittels Policy-Based Routing (ip rule) steuern und virtuelle Topologien direkt im RAM über Netzwerk-Namespaces (ip netns), veth-Paare und Layer-2-Bridges aufbauen.

  • Kernel-Routing & Richtlinienregeln


    Debian mit ip_forward, nftables SNAT/DNAT und quellbasiertem Routing über mehrere Tabellen (ip rule) in einen L3-Router verwandeln.

  • 802.1Q-VLANs & LACP-Bonding


    DMZ-, Storage- und Management-Traffic über getaggte 802.1Q-Subinterfaces auf redundanten, gebündelten 802.3ad-LACP-Netzwerkkarten isolieren.

  • Namespaces, veth & Bridges


    Die Kernprimitive (ip netns, virtuelle Ethernet-Kabel und Softwareschalter) verstehen und steuern, die Podman, Docker und KVM antreiben.

  • 10GbE+ TCP & BBR-Tuning


    Bufferbloat eliminieren und Bandbreiten voll ausschöpfen durch Aktivierung von Google BBR-Überlastungskontrolle und Fair Queue (fq) Packet-Scheduling.


1. Linux als Multi-Interface Layer-3 Router & NAT-Gateway

Standardmäßig agiert ein Linux-Host als Endpunkt: Erreicht ein Paket eth0 mit einer Ziel-IP, die nicht dem Host selbst gehört, verwirft der Kernel das Paket stillschweigend. Durch die Aktivierung von IP Forwarding via sysctl wird der Kernel zum vollwertigen Layer-3-Router.

%%{init: {'flowchart': {'wrappingWidth': 600}}}%%
flowchart TB
    LAN["🏢 Internes Server-VLAN<br/>10.10.20.0/24<br/>(Gateway: 10.10.20.1)"]
    RTR["🛡️ Debian Linux Router<br/>eth1: 10.10.20.1/24<br/>eth0: 203.0.113.5/24<br/>net.ipv4.ip_forward = 1"]
    WAN["🌍 Öffentliches Internet / ISP<br/>Upstream-Gateway<br/>203.0.113.1"]

    LAN ==>|"1. Private Quell-IP<br/>10.10.20.11"| RTR
    RTR ==>|"2. nftables Masquerade<br/>Quelle -> 203.0.113.5"| WAN

Schritt 1: Kernel-Paketweiterleitung & Anti-Spoofing (rp_filter) aktivieren

# Datei: /etc/sysctl.d/99-linux-router.conf
# IPv4- und IPv6-Paketweiterleitung über Schnittstellen aktivieren
net.ipv4.ip_forward = 1
net.ipv6.conf.all.forwarding = 1

# Strikten Reverse Path Filter (RFC 3704) gegen IP-Spoofing erzwingen
net.ipv4.conf.all.rp_filter = 1
net.ipv4.conf.default.rp_filter = 1

# ICMP-Broadcasts und Redirects ignorieren
net.ipv4.icmp_echo_ignore_broadcasts = 1
net.ipv4.conf.all.accept_redirects = 0
net.ipv4.conf.all.send_redirects = 0

Sofort anwenden: sudo sysctl --system

Schritt 2: Stateful SNAT (Masquerading) & DNAT (Portweiterleitung) in nftables

#!/usr/bin/env nft -f
# Datei: /etc/nftables-router.conf

table inet nat_router {
    chain prerouting {
        type nat hook prerouting priority dstnat; policy accept;

        # DNAT-Beispiel: Öffentliches TCP/443 auf eth0 an internen Reverse Proxy weiterleiten
        iifname "eth0" tcp dport 443 dnat ip to 10.10.20.15:443
    }

    chain forward {
        type filter hook forward priority filter; policy drop;

        # Antwortpakete bestehender Verbindungen erlauben
        ct state vmap { established : accept, related : accept, invalid : drop }

        # Ausgehenden Traffic vom internen LAN (eth1) ins WAN (eth0) erlauben
        iifname "eth1" oifname "eth0" accept

        # DNAT-weitergeleiteten HTTPS-Traffic zum Proxy erlauben
        iifname "eth0" oifname "eth1" ip daddr 10.10.20.15 tcp dport 443 accept
    }

    chain postrouting {
        type nat hook postrouting priority srcnat; policy accept;

        # SNAT / Masquerading für ausgehende LAN-Pakete auf WAN-Interface eth0
        oifname "eth0" ip saddr 10.10.20.0/24 masquerade
    }
}

2. Policy-Based Routing (ip rule & Mehrere Routingtabellen)

Klassisches IP-Routing entscheidet rein anhand der Ziel-IP-Adresse. Besitzt ein Server jedoch zwei WAN-Uplinks (oder einen WireGuard-Split-Tunnel neben der öffentlichen Netzwerkkarte), muss der Datenverkehr anhand von Quell-IP, Firewall-Markierung (fwmark) oder Eingangsschnittstelle gesteuert werden (Policy-Based Routing, PBR).

# Datei: /opt/net-ops/policy_based_routing.sh
#!/usr/bin/env bash
set -euo pipefail

# 1. Benannte Routingtabelle (ID 200: 'vpn_uplink') registrieren
if ! grep -q "200 vpn_uplink" /etc/iproute2/rt_tables; then
    echo "200 vpn_uplink" | sudo tee -a /etc/iproute2/rt_tables
fi

# 2. Tabelle 'vpn_uplink' mit eigenem Standard-Gateway über WireGuard wg0 befüllen
sudo ip route replace default dev wg0 table vpn_uplink
sudo ip route replace 10.10.30.0/24 dev eth2 src 10.10.30.1 table vpn_uplink

# 3. Regel hinzufügen: Traffic aus Subnetz 10.10.30.0/24 nutzt Tabelle 'vpn_uplink'
sudo ip rule add from 10.10.30.0/24 table vpn_uplink priority 1000

# 4. Aktive Regeln prüfen und Kernel-Pfadabfrage testen
ip rule show
ip route get 9.9.9.9 from 10.10.30.55

3. LACP-Bonding (802.3ad) & 802.1Q VLAN-Trunking

In Produktionsumgebungen darf eine einzelne Netzwerkkarte kein Ausfallrisiko darstellen:

  1. Layer-2 Bündelung (bond0): Fasst zwei physische Netzwerkkarten (eno1 + eno2) zu einem ausfallsicheren IEEE 802.3ad LACP-Verbund zusammen.
  2. IEEE 802.1Q VLAN-Tagging: Überträgt mehrere isolierte Sicherheitszonen (VLAN 10 Management, VLAN 20 DMZ, VLAN 30 Storage) über denselben Bündel-Trunk.
%%{init: {'flowchart': {'wrappingWidth': 600, 'subGraphTitleMargin': {'top': 15, 'bottom': 15}}}}%%
flowchart TB
    subgraph PhysicalLayer["🔌 Physischer NIC-Trunk"]
        NIC1["eno1 (10GbE SFP+)"]
        NIC2["eno2 (10GbE SFP+)"]
        BOND["bond0 (802.3ad LACP)<br/>Aktiv-Aktiv + Failover"]
        NIC1 --> BOND
        NIC2 --> BOND
    end

    subgraph VlanSub["🏷️ 802.1Q Getaggte VLANs"]
        V10["bond0.10 (VLAN 10)<br/>Mgmt: 10.10.10.50/24"]
        V20["bond0.20 (VLAN 20)<br/>DMZ-Bridge (br-dmz)"]
        V30["bond0.30 (VLAN 30)<br/>NVMe/NFS: 10.10.30.50/24"]
        BOND --> V10
        BOND --> V20
        BOND --> V30
    end

Konfiguration von LACP-Bonding & VLANs (systemd-networkd vs. iproute2)

# Datei: /etc/systemd/network/10-bond0.netdev
[NetDev]
Name=bond0
Kind=bond

[Bond]
Mode=802.3ad
TransmitHashPolicy=layer3+4
MIIMonitorSec=100ms
LACPTransmitRate=fast
# Datei: /etc/systemd/network/20-vlan10.netdev
[NetDev]
Name=bond0.10
Kind=vlan

[VLAN]
Id=10
# Datei: /etc/systemd/network/30-bond0-trunk.network
[Match]
Name=bond0

[Network]
VLAN=bond0.10
BindCarrier=eno1 eno2
# Datei: /opt/net-ops/create_bond_and_vlans.sh
#!/usr/bin/env bash
set -euo pipefail

# 1. Kernel-Module laden
sudo modprobe bonding
sudo modprobe 8021q

# 2. 802.3ad LACP bond0 anlegen und Schnittstellen unterordnen
sudo ip link add bond0 type bond mode 802.3ad miimon 100 xmit_hash_policy layer3+4
sudo ip link set eno1 down && sudo ip link set eno1 master bond0
sudo ip link set eno2 down && sudo ip link set eno2 master bond0
sudo ip link set bond0 up

# 3. Getaggtes 802.1Q VLAN 10 Subinterface auf bond0 erstellen
sudo ip link add link bond0 name bond0.10 type vlan id 10
sudo ip addr add 10.10.10.50/24 dev bond0.10
sudo ip link set bond0.10 up

# 4. Status der LACP-Partnerverhandlung inspizieren
cat /proc/net/bonding/bond0

4. Netzwerk-Virtualisierungsprimitive: ip netns, veth & Bridges

Wie weisen Podman, Docker und Kubernetes Containern eigene Schnittstellen, Routingtabellen und Firewalls zu, ohne virtuelle Maschinen zu starten? Durch die Kombination von drei Linux-Kernel-Primitiven:

  1. Network Namespace (ip netns): Eine isolierte Instanz des Kernel-Netzwerkstacks (Schnittstellen, Routen, Firewallregeln, Sockets).
  2. Virtual Ethernet Pair (veth): Ein bidirektionales virtuelles Netzwerkkabel mit zwei Enden – Pakete an einem Ende treten am anderen Ende wieder aus.
  3. Linux Kernel Bridge (type bridge): Ein virtueller Layer-2-Switch im Kernel, der mehrere veth-Hostenden oder KVM-tap-Schnittstellen zusammenschaltet.
%%{init: {'flowchart': {'wrappingWidth': 600, 'subGraphTitleMargin': {'top': 15, 'bottom': 15}}}}%%
flowchart TB
    subgraph HostNS["🖥️ Root-Host-Namespace"]
        BR["🔀 Linux Bridge: br-app0<br/>Gateway-IP: 10.88.0.1/24"]
        VH1["veth-app1-br<br/>(Bridge-Port)"]
        VH2["veth-app2-br<br/>(Bridge-Port)"]
        BR --- VH1
        BR --- VH2
    end

    subgraph NS1["📦 NetNS: ns-app1"]
        VC1["eth0 (veth peer)<br/>IP: 10.88.0.11/24"]
    end

    subgraph NS2["📦 NetNS: ns-app2"]
        VC2["eth0 (veth peer)<br/>IP: 10.88.0.12/24"]
    end

    VH1 <==>|"Virtuelles Patchkabel"| VC1
    VH2 <==>|"Virtuelles Patchkabel"| VC2

Praxis-Labor: Ein Containernetzwerk von Grund auf selbst aufbauen

# Datei: /opt/net-ops/build_netns_bridge_fabric.sh
#!/usr/bin/env bash
set -euo pipefail

# 1. Virtuellen Layer-2 Switch (Linux Bridge) auf dem Host anlegen
sudo ip link add name br-app0 type bridge
sudo ip addr add 10.88.0.1/24 dev br-app0
sudo ip link set dev br-app0 up

# 2. Zwei isolierte Netzwerk-Namespaces erzeugen
sudo ip netns add ns-app1
sudo ip netns add ns-app2

# 3. Zwei veth-Patchkabel anlegen (Host-Seite <-> Namespace-Seite)
sudo ip link add veth-app1-br type veth peer name eth0 netns ns-app1
sudo ip link add veth-app2-br type veth peer name eth0 netns ns-app2

# 4. Host-Enden an die Bridge binden und aktivieren
sudo ip link set veth-app1-br master br-app0 up
sudo ip link set veth-app2-br master br-app0 up

# 5. IP-Adressen und Standard-Gateways in den Namespaces konfigurieren
sudo ip -n ns-app1 link set lo up
sudo ip -n ns-app1 addr add 10.88.0.11/24 dev eth0
sudo ip -n ns-app1 link set eth0 up
sudo ip -n ns-app1 route add default via 10.88.0.1

sudo ip -n ns-app2 link set lo up
sudo ip -n ns-app2 addr add 10.88.0.12/24 dev eth0
sudo ip -n ns-app2 link set eth0 up
sudo ip -n ns-app2 route add default via 10.88.0.1

# 6. Konnektivität zwischen den isolierten Namespaces testen
sudo ip netns exec ns-app1 ping -c 2 10.88.0.12
bridge link show

5. TCP-Überlastungssteuerung für Hochgeschwindigkeitsnetze (Google BBR & fq)

Klassische Algorithmen wie cubic erkennen Netzüberlastung primär durch verworfene Pakete. Bei 10GbE-Verbindungen mit hoher Latenz führt das zu Durchsatzeinbrüchen. Google BBR (bbr) in Kombination mit dem Fair Queue (fq)-Scheduler taktet Pakete anhand der tatsächlichen Bandbreite und Round-Trip-Zeiten:

# Datei: /etc/sysctl.d/99-tcp-bbr-tuning.conf
# Fair Queue Scheduler und BBR-Überlastungskontrolle aktivieren
net.core.default_qdisc = fq
net.ipv4.tcp_congestion_control = bbr

# Socket-Puffer für 10GbE+-Strecken anpassen (max. 16 MB)
net.core.rmem_max = 16777216
net.core.wmem_max = 16777216
net.ipv4.tcp_rmem = 4096 87380 16777216
net.ipv4.tcp_wmem = 4096 65536 16777216

# TCP Fast Open (TFO) für Client- und Server-Sockets aktivieren
net.ipv4.tcp_fastopen = 3

Nächste Schritte

Setzen Sie diese Kernel-Networking-Primitive in virtuellen Laboren und Container-Umgebungen ein:

  • KVM/QEMU-Netzwerk-Infrastrukturlabor


    Linux-Bridges, libvirt-Netzwerke und Routing in einer vollständigen Multi-VM-KVM-Simulation kombinieren.

    Zum KVM/QEMU-Labor

  • Rootless Podman-Container


    Erfahren, wie Podman netavark, pasta und User-Namespaces einsetzt, um Container ohne Root-Rechte zu vernetzen.

    Zum Podman-Guide

  • Fortgeschrittenes Networking & Firewalls


    Zustandsbehaftete nftables-Regeln, OpenSSH-ProxyJump-Bastions und tcpdump-Paketanalysen wiederholen.

    Zum Intermediate-Leitfaden