iptables ist der traditionelle Paketfilter für Linux. Er kontrolliert ein- und ausgehenden Netzwerkverkehr basierend auf Regeln.

Grundkonzepte

Tabellen

filter:    Paketfilterung (Standard)
nat:       Network Address Translation
mangle:    Paket-Modifikation
raw:       Ausnahmen von Connection Tracking

Chains

INPUT:     Eingehende Pakete für diesen Host
OUTPUT:    Ausgehende Pakete von diesem Host
FORWARD:   Pakete, die weitergeleitet werden
PREROUTING:  Vor dem Routing (NAT)
POSTROUTING: Nach dem Routing (NAT)

Paketfluss

                    PREROUTING
                         │
                         ▼
                    ┌─────────┐
              ┌─────│ Routing │─────┐
              │     └─────────┘     │
              ▼                     ▼
          INPUT                  FORWARD
              │                     │
              ▼                     │
         [Lokaler                   │
          Prozess]                  │
              │                     │
              ▼                     │
          OUTPUT                    │
              │                     │
              └──────┐     ┌────────┘
                     ▼     ▼
                  POSTROUTING
                         │
                         ▼
                    [Netzwerk]

Grundlegende Befehle

Status anzeigen

# Alle Regeln anzeigen
iptables -L
iptables -L -v -n

# Mit Zeilennummern
iptables -L --line-numbers

# Bestimmte Tabelle
iptables -t nat -L

Regeln verwalten

# Regel hinzufügen (am Ende)
iptables -A INPUT -p tcp --dport 80 -j ACCEPT

# Regel einfügen (an Position)
iptables -I INPUT 1 -p tcp --dport 22 -j ACCEPT

# Regel löschen (nach Nummer)
iptables -D INPUT 3

# Regel löschen (nach Spezifikation)
iptables -D INPUT -p tcp --dport 80 -j ACCEPT

# Alle Regeln löschen
iptables -F

Standard-Policy

# Policy setzen
iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -P OUTPUT ACCEPT

Einfache Regeln

Port freigeben

# HTTP
iptables -A INPUT -p tcp --dport 80 -j ACCEPT

# HTTPS
iptables -A INPUT -p tcp --dport 443 -j ACCEPT

# SSH
iptables -A INPUT -p tcp --dport 22 -j ACCEPT

# Mehrere Ports
iptables -A INPUT -p tcp -m multiport --dports 80,443 -j ACCEPT

IP-Adressen

# Von bestimmter IP erlauben
iptables -A INPUT -s 192.168.1.100 -j ACCEPT

# IP blockieren
iptables -A INPUT -s 10.0.0.5 -j DROP

# Subnetz
iptables -A INPUT -s 192.168.1.0/24 -j ACCEPT

# Ziel-Adresse
iptables -A OUTPUT -d 8.8.8.8 -j ACCEPT

Protokolle

# TCP
iptables -A INPUT -p tcp --dport 22 -j ACCEPT

# UDP
iptables -A INPUT -p udp --dport 53 -j ACCEPT

# ICMP (Ping)
iptables -A INPUT -p icmp -j ACCEPT

Connection Tracking

# Bestehende Verbindungen erlauben
iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT

# Oder älter:
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

Basis-Firewall

Minimale Konfiguration

#!/bin/bash
# firewall.sh

# Alte Regeln löschen
iptables -F
iptables -X

# Standard-Policies
iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -P OUTPUT ACCEPT

# Loopback erlauben
iptables -A INPUT -i lo -j ACCEPT
iptables -A OUTPUT -o lo -j ACCEPT

# Bestehende Verbindungen
iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT

# SSH (anpassen!)
iptables -A INPUT -p tcp --dport 22 -j ACCEPT

# HTTP/HTTPS
iptables -A INPUT -p tcp --dport 80 -j ACCEPT
iptables -A INPUT -p tcp --dport 443 -j ACCEPT

# Ping erlauben
iptables -A INPUT -p icmp --icmp-type echo-request -j ACCEPT

# Logging
iptables -A INPUT -j LOG --log-prefix "IPTables-Dropped: " --log-level 4

Webserver

# HTTP/HTTPS
iptables -A INPUT -p tcp -m multiport --dports 80,443 -j ACCEPT

# FTP (wenn nötig)
iptables -A INPUT -p tcp --dport 21 -j ACCEPT
iptables -A INPUT -p tcp --dport 20 -j ACCEPT

Mailserver

# SMTP
iptables -A INPUT -p tcp --dport 25 -j ACCEPT
iptables -A INPUT -p tcp --dport 465 -j ACCEPT
iptables -A INPUT -p tcp --dport 587 -j ACCEPT

# IMAP
iptables -A INPUT -p tcp --dport 143 -j ACCEPT
iptables -A INPUT -p tcp --dport 993 -j ACCEPT

# POP3
iptables -A INPUT -p tcp --dport 110 -j ACCEPT
iptables -A INPUT -p tcp --dport 995 -j ACCEPT

Datenbankserver

# MySQL (nur intern)
iptables -A INPUT -p tcp --dport 3306 -s 192.168.1.0/24 -j ACCEPT

# PostgreSQL (nur intern)
iptables -A INPUT -p tcp --dport 5432 -s 192.168.1.0/24 -j ACCEPT

Erweiterte Funktionen

Rate Limiting

# SSH Brute-Force-Schutz
iptables -A INPUT -p tcp --dport 22 -m conntrack --ctstate NEW -m limit --limit 3/min --limit-burst 3 -j ACCEPT
iptables -A INPUT -p tcp --dport 22 -m conntrack --ctstate NEW -j DROP

# SYN-Flood-Schutz
iptables -A INPUT -p tcp --syn -m limit --limit 1/s --limit-burst 3 -j ACCEPT

Geoblocking

# ipset für Länder-Blocking
apt install ipset

# Set erstellen
ipset create blocked_countries hash:net

# IPs hinzufügen (Beispiel)
ipset add blocked_countries 1.2.3.0/24

# Mit iptables nutzen
iptables -A INPUT -m set --match-set blocked_countries src -j DROP

Port-Knocking

# Erste Stufe
iptables -A INPUT -p tcp --dport 1234 -m recent --name knock1 --set -j DROP

# Zweite Stufe
iptables -A INPUT -p tcp --dport 5678 -m recent --name knock1 --rcheck -m recent --name knock2 --set -j DROP

# SSH öffnen nach Knock-Sequenz
iptables -A INPUT -p tcp --dport 22 -m recent --name knock2 --rcheck --seconds 5 -j ACCEPT

NAT/Masquerading

Internet-Sharing

# IP-Forwarding aktivieren
echo 1 > /proc/sys/net/ipv4/ip_forward

# Masquerading
iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE

# Forwarding erlauben
iptables -A FORWARD -i eth1 -o eth0 -j ACCEPT
iptables -A FORWARD -i eth0 -o eth1 -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT

Port-Forwarding

# Extern 8080 → Intern 192.168.1.10:80
iptables -t nat -A PREROUTING -p tcp --dport 8080 -j DNAT --to-destination 192.168.1.10:80
iptables -A FORWARD -p tcp -d 192.168.1.10 --dport 80 -j ACCEPT

SNAT (Source NAT)

# Feste Quell-IP
iptables -t nat -A POSTROUTING -o eth0 -j SNAT --to-source 203.0.113.10

Regeln speichern

Debian/Ubuntu

# Regeln speichern
iptables-save > /etc/iptables.rules

# Beim Boot laden
# /etc/network/if-pre-up.d/iptables

#!/bin/bash
/sbin/iptables-restore < /etc/iptables.rules

Mit iptables-persistent

apt install iptables-persistent

# Speichern
netfilter-persistent save

# Laden
netfilter-persistent reload

CentOS/RHEL

# Service nutzen
systemctl enable iptables
service iptables save

Logging

Log-Regel

# Alle gedroppten Pakete loggen
iptables -A INPUT -j LOG --log-prefix "iptables-dropped: " --log-level 4

# Mit Limit (weniger Spam)
iptables -A INPUT -m limit --limit 5/min -j LOG --log-prefix "iptables-dropped: "

Rsyslog-Konfiguration

# /etc/rsyslog.d/iptables.conf

:msg, contains, "iptables" /var/log/iptables.log
& stop

Log lesen

tail -f /var/log/iptables.log
dmesg | grep iptables

Debugging

Regeln zählen

# Pakete und Bytes pro Regel
iptables -L -v -n

# Zähler zurücksetzen
iptables -Z

Regel testen

# Paket simulieren
iptables -C INPUT -p tcp --dport 80 -j ACCEPT
echo $?  # 0 = Regel existiert

TRACE-Logging

# Raw-Tabelle für Tracing
iptables -t raw -A PREROUTING -p tcp --dport 80 -j TRACE
iptables -t raw -A OUTPUT -p tcp --dport 80 -j TRACE

# Log prüfen
dmesg | grep TRACE

Komplettes Skript

#!/bin/bash
# /etc/firewall/firewall.sh

# Variablen
SSH_PORT=22
HTTP_PORT=80
HTTPS_PORT=443
ALLOWED_SSH_IPS="192.168.1.0/24 10.0.0.5"

# Funktionen
flush_rules() {
    iptables -F
    iptables -X
    iptables -t nat -F
    iptables -t nat -X
}

set_policies() {
    iptables -P INPUT DROP
    iptables -P FORWARD DROP
    iptables -P OUTPUT ACCEPT
}

allow_loopback() {
    iptables -A INPUT -i lo -j ACCEPT
    iptables -A OUTPUT -o lo -j ACCEPT
}

allow_established() {
    iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
}

allow_ssh() {
    for ip in $ALLOWED_SSH_IPS; do
        iptables -A INPUT -p tcp --dport $SSH_PORT -s $ip -j ACCEPT
    done
}

allow_web() {
    iptables -A INPUT -p tcp -m multiport --dports $HTTP_PORT,$HTTPS_PORT -j ACCEPT
}

allow_ping() {
    iptables -A INPUT -p icmp --icmp-type echo-request -m limit --limit 1/s -j ACCEPT
}

log_dropped() {
    iptables -A INPUT -m limit --limit 5/min -j LOG --log-prefix "iptables-dropped: " --log-level 4
}

# Hauptprogramm
case "$1" in
    start)
        echo "Firewall starten..."
        flush_rules
        set_policies
        allow_loopback
        allow_established
        allow_ssh
        allow_web
        allow_ping
        log_dropped
        echo "Firewall aktiv."
        ;;
    stop)
        echo "Firewall stoppen..."
        flush_rules
        iptables -P INPUT ACCEPT
        iptables -P FORWARD ACCEPT
        iptables -P OUTPUT ACCEPT
        echo "Firewall deaktiviert."
        ;;
    restart)
        $0 stop
        $0 start
        ;;
    status)
        iptables -L -v -n --line-numbers
        ;;
    *)
        echo "Usage: $0 {start|stop|restart|status}"
        exit 1
        ;;
esac

exit 0
chmod +x /etc/firewall/firewall.sh
/etc/firewall/firewall.sh start

nftables (Nachfolger)

# nftables ist der moderne Ersatz für iptables
# Kompatibilitätsebene vorhanden

# iptables-Regeln zu nftables konvertieren
iptables-save > rules.v4
iptables-restore-translate -f rules.v4 > rules.nft

Zusammenfassung

| Befehl | Funktion | |--------|----------| | iptables -L | Regeln anzeigen | | iptables -A | Regel anhängen | | iptables -I | Regel einfügen | | iptables -D | Regel löschen | | iptables -F | Alle Regeln löschen | | iptables -P | Policy setzen |

| Chain | Verwendung | |-------|------------| | INPUT | Eingehend | | OUTPUT | Ausgehend | | FORWARD | Weiterleitung | | PREROUTING | DNAT | | POSTROUTING | SNAT/Masquerade |

Fazit

iptables bietet umfassende Firewall-Funktionalität für Linux. Die Regelstruktur mit Chains und Tables ermöglicht präzise Kontrolle über den Netzwerkverkehr. Für neue Installationen empfiehlt sich der Blick auf nftables als modernen Nachfolger. Testen Sie Regeln immer sorgfältig, um sich nicht vom Server auszusperren.