Linux als Layer-3 Router & NAT-Gateway: IP-Forwarding, SNAT-Masquerading & DNAT
Erstellt: 08.11.2026 · Zuletzt aktualisiert: 08.11.2026 · Nejat Hakan
Management Summary: Standardmäßig agiert jede Linux-Installation strikt als Endsystem (Host): Empfängt eine Netzwerkschnittstelle ein Paket, dessen Ziel-IP nicht zu den eigenen Adressen des Systems gehört, wird es vom Kernel lautlos verworfen. Durch das Aktivieren des Kernel-IP-Forwardings verwandelt sich ein herkömmlicher Debian-Server in einen performanten Layer-3-Router und ein NAT-Gateway. Dieser Leitfaden behandelt die Kernel-Forwarding-Parameter, striktes Reverse-Path-Filtering (RFC 3704), stateful SNAT-Masquerading, DNAT-Portweiterleitungen und das Tuning der Verbindungstabelle (
conntrack).
-
Kernel-Layer-3-Forwarding
Debian zum Enterprise-Router machen: TTLs dekrementieren, ICMP-Meldungen erzeugen und Subnetze ohne Spezial-Hardware koppeln.
-
Anti-Spoofing (
rp_filter)
Striktes Reverse-Path-Filtering (RFC 3704) erzwingen, um gefälschte IP-Pakete (IP-Spoofing) direkt an der Schnittstelle zu verwerfen.
-
Stateful SNAT & DNAT
Private RFC-1918-Netze via
nftables-Masquerading ins Internet leiten und öffentliche Ports gezielt an interne Server weiterleiten. -
Conntrack-Tuning
Limits der Kernel-Verbindungstabelle (
nf_conntrack_max) und TCP-Timeouts für tausende gleichzeitige Verbindungen optimieren.
1. Die Kernel-Routing-Pipeline: Endsystem vs. Router-Modus
Wenn ein Ethernet-Frame an eth1 eintrifft, übergibt der Treiber die Struktur struct sk_buff an ip_rcv(). Der Kernel prüft die Ziel-IP gegen seine lokalen Adressen:
%%{init: {'flowchart': {'wrappingWidth': 350}}}%%
flowchart TB
A["Paket an Ingress (eth1)"] --> B["ip_rcv(): Header prüfen"]
B --> C{"Ziel-IP lokal?"}
C -->|"JA: Lokale IP"| D["An lokalen Socket<br/>INPUT Hook"]
C -->|"NEIN: Fremde IP"| E{"ip_forward == 1?"}
E -->|"0 (Deaktiviert)"| DROP["LAUTLOSER DROP<br/>Endsystem-Modus"]
E -->|"1 (Aktiviert)"| F["FORWARD Hook<br/>TTL - 1, Firewall<br/>Routingtabelle"]
F --> G["POSTROUTING Hook<br/>SNAT / Masquerading"]
G --> H["Über Egress (eth0) senden"]
2. Router-Härtung im Linux-Kernel (sysctl.d)
Ein Routing-Host benötigt strikte Kernel-Sicherheitsregeln, um nicht als offener Reflektor missbraucht oder durch IP-Spoofing getäuscht zu werden:
# Datei: /etc/sysctl.d/70-linux-router.conf
# 1. Layer-3-Paketweiterleitung für IPv4 und IPv6 aktivieren
net.ipv4.ip_forward = 1
net.ipv6.conf.all.forwarding = 1
net.ipv6.conf.default.forwarding = 1
# 2. Striktes Reverse-Path-Filtering (RFC 3704 / BCP 38)
# Verwirft Pakete, deren Quell-IP nicht über denselben Pfad zurückgeroutet werden würde
net.ipv4.conf.all.rp_filter = 1
net.ipv4.conf.default.rp_filter = 1
# 3. ICMP-Redirects deaktivieren (Schutz vor Man-in-the-Middle Route-Poisoning)
net.ipv4.conf.all.accept_redirects = 0
net.ipv4.conf.default.accept_redirects = 0
net.ipv4.conf.all.send_redirects = 0
net.ipv4.conf.default.send_redirects = 0
# 4. Fehlerhafte ICMP-Broadcasts ignorieren (Smurf-Angriffsschutz)
net.ipv4.icmp_echo_ignore_broadcasts = 1
# 5. SYN-Flood-Schutz auf hochbelasteten Routern
net.ipv4.tcp_syncookies = 1
Ohne Neustart anwenden:
3. NAT im Detail: SNAT vs. Masquerading vs. DNAT
Network Address Translation (NAT) greift an zwei unterschiedlichen Stellen im Netfilter-System:
%%{init: {'flowchart': {'wrappingWidth': 350}}}%%
flowchart TB
subgraph SNAT_FLOW ["1. Source NAT (POSTROUTING)"]
direction TB
S1["Interner Host<br/>10.10.20.11:49210"] --> S2["Router eth0 (WAN)<br/>203.0.113.5"]
S2 --> S3["Ausgehendes Paket<br/>Src wird WAN-IP"]
end
subgraph DNAT_FLOW ["2. Destination NAT (PREROUTING)"]
direction TB
D1["Internet-Client<br/>an 203.0.113.5:443"] --> D2["Router PREROUTING<br/>Port-Forward Hook"]
D2 --> D3["Paket Ziel-IP wird<br/>10.10.20.15:443"]
end
SNAT_FLOW -->|"NAT Pipeline"| DNAT_FLOW
- SNAT (Source NAT): Verändert die Quell-IP ausgehender Pakete. Wird genutzt, wenn die WAN-Schnittstelle über eine feste, statische öffentliche IP verfügt.
- Masquerading: Eine dynamische Form von SNAT für Schnittstellen mit wechselnden DHCP-IPs. Der Kernel ermittelt die Schnittstellen-IP für jede Verbindung dynamisch.
- DNAT (Destination NAT / Portweiterleitung): Schreibt die Ziel-IP vor der Routingentscheidung um (
PREROUTING). Leitet eingehende Anfragen an interne Server weiter.
4. Multi-Interface-Routertopologie
Typisches Szenario mit zwei Netzwerkkarten:
* eth0 (WAN): Öffentliches Subnetz (203.0.113.5/24, Gateway: 203.0.113.1).
* eth1 (LAN): Privates internes Subnetz (10.10.20.1/24, für Server und Clients).
# Datei: /etc/systemd/network/10-wan-eth0.network
[Match]
Name=eth0
[Network]
Address=203.0.113.5/24
Gateway=203.0.113.1
DNS=9.9.9.9
5. Vollständiges Produktiv-Regelwerk in /etc/nftables.conf
Diese Konfiguration schützt den Router selbst, filtert den gerouteten Transit-Verkehr, maskiert ausgehende Pakete und leitet HTTPS-Anfragen an einen internen Reverse-Proxy weiter:
#!/usr/sbin/nft -f
# Datei: /etc/nftables.conf
flush ruleset
table inet router {
# 1. Destination NAT (Portweiterleitung)
chain prerouting {
type nat hook prerouting priority dstnat; policy accept;
# Öffentliches HTTPS (443) an internen Reverse-Proxy (10.10.20.15:443) weiterleiten
iifname "eth0" tcp dport 443 dnat ip to 10.10.20.15:443
}
# 2. Host-Firewall: Schützt den Router selbst
chain input {
type filter hook input priority filter; policy drop;
# Bestehende Verbindungen und Loopback gestatten
ct state established,related accept
ct state invalid drop
iifname "lo" accept
# ICMP und ICMPv6 erlauben
ip protocol icmp accept
ip6 nexthdr icmpv6 accept
# SSH-Administration NUR aus dem internen LAN (eth1) erlauben
iifname "eth1" tcp dport 22 accept
}
# 3. Transit-Firewall: Kontrolliert den gerouteten Verkehr zwischen LAN und WAN
chain forward {
type filter hook forward priority filter; policy drop;
# Bestehende und zugehörige Antwortpakete erlauben
ct state established,related accept
ct state invalid drop
# Ausgehenden Verkehr aus dem internen LAN (eth1) ins Internet (eth0) erlauben
iifname "eth1" oifname "eth0" accept
# Eingehenden DNAT-Verkehr zum internen Reverse-Proxy erlauben
iifname "eth0" oifname "eth1" ip daddr 10.10.20.15 tcp dport 443 accept
}
# 4. Source NAT (Masquerading)
chain postrouting {
type nat hook postrouting priority srcnat; policy accept;
# Privaten LAN-Verkehr beim Verlassen über eth0 maskieren
oifname "eth0" ip saddr 10.10.20.0/24 masquerade
}
}
Aktivieren:
sudo nft -c -f /etc/nftables.conf && sudo nft -f /etc/nftables.conf
sudo systemctl enable --now nftables
6. High-Throughput Connection Tracking (conntrack) optimieren
Unter Hochlast (tausende Clients, viele gleichzeitige TCP-Streams) kann die Verbindungstabelle des Kernels volllaufen. Ist die Tabelle voll, verwirft der Kernel neue Verbindungen (nf_conntrack: table full, dropping packet):
Dimensionierung der conntrack-Tabelle
# Datei: /etc/sysctl.d/80-conntrack-tuning.conf
# Maximale Anzahl gleichzeitiger Verbindungen (jede belegt ~320 Byte Kernel-RAM)
# 262144 Verbindungen * 320 Byte ~= 84 MB RAM
net.netfilter.nf_conntrack_max = 262144
# Idle-Timeout für bestehende TCP-Verbindungen von 5 Tagen auf 1 Stunde senken
net.netfilter.nf_conntrack_tcp_timeout_established = 3600
# Beendete Verbindungen schneller aus dem Speicher entfernen
net.netfilter.nf_conntrack_tcp_timeout_close_wait = 60
net.netfilter.nf_conntrack_tcp_timeout_fin_wait = 120
net.netfilter.nf_conntrack_tcp_timeout_time_wait = 120
Aktivieren:
Zustand der Verbindungstabelle prüfen
# Aktuelle Belegung gegen das Maximum prüfen
sysctl net.netfilter.nf_conntrack_count net.netfilter.nf_conntrack_max
# Überlauf- und Drop-Statistiken abrufen
sudo conntrack -S
7. Nächste Schritte
Nachdem der Debian-Router Datenpakete zwischen Subnetzen weiterleitet und maskiert, folgt die intelligente Steuerung des Datenverkehrs über mehrere WAN-Leitungen oder VPN-Tunnel:
-
Policy-Based Routing (PBR) & Multiple Routing-Tabellen
Pakete anhand von Quell-IP, Firewall-Markierungen (
fwmark) und Schnittstellen gezielt über alternative Gateways leiten.