OpenBSD PF Firewall: Stateful Security ohne Komplexität
OpenBSD PF (Packet Filter) ist eine moderne Firewall für Admins, die verstehen möchten, was ihr System tut. Dieser Guide erklärt Stateful Filtering, Threat Detection und zentrale Observability — ohne Komplexität.
Warum OpenBSD?
Wenn du Linux-Admin bist, kennst du iptables, firewalld, nftables. Sie funktionieren, aber OpenBSD PF (Packet Filter) bietet einen anderen Ansatz:
- Designphilosophie: „Deny by default, allow by exception" — die gesamte OS ist sicherheitsfokussiert, nicht nur ein Subsystem
- Einfache Syntax: PF-Regeln sind lesbar und wartbar, auch bei komplexer Policy
- Integrierte Monitoring: Observability ist built-in, nicht nachträglich geklebt
- Minimal Attack Surface: OpenBSD reduziert Standard-Services auf das Nötigste
- Firmware + Kernel: Regelmäßige Security Patches (OpenBSD ist berühmt für Sicherheit)
Du möchtest eine Firewall, die einfach verständlich ist, wenig Wartung braucht, und bei der Security nicht optional ist. Nicht: „Lass mich iptables rules stacken bis zum Himmel."
PF Firewall Grundlagen
Was ist PF?
PF ist ein Kernel-basiertes Firewall-System. Im Gegensatz zu Linux iptables, die über netfilter laufen, ist PF direkt im OpenBSD-Kernel implementiert und optimiert.
Kernfunktionen:
- Stateful Inspection: PF merkt sich Verbindungen. Rückverkehr wird automatisch erlaubt
- Network Address Translation (NAT): Interne IPs nach außen masqueraden
- Source Tracking: IPs tracken, die viele Verbindungen öffnen (Port Scanner, Brute Force)
- Rate Limiting: Bestimmte Verkehrsmuster drosseln oder blocken
- Antispoof: Automatisch spoofed Pakete filtern (reverse path check)
PF vs. Linux iptables/nftables
| Aspekt | PF (OpenBSD) | Linux iptables |
|---|---|---|
| Ort im Stack | Kernel-integriert | Kernel-Subsystem (netfilter) |
| Syntax | Deklarativ, top-to-bottom | Imperativ, Regel-für-Regel |
| Default Policy | Explicit Deny | Je nach Konfiguration |
| State Table | Zentral, automatisch optimiert | Durch Conntrack-Modul |
| Reload | Atomic (Regel + State Table) | Braucht teilweise Flush/Reload |
Architektur: Stateful Filtering
Wie Stateful Filtering funktioniert
Im Gegensatz zu Stateless-Firewalls, die jedes Paket einzeln prüfen, merkt sich eine Stateful Firewall den Kontext:
Praktischer Vorteil: Du schreibst nur „erlauben, dass interne Hosts außen erreichen" — Rückverkehr ist automatisch klar.
Beispiel-Regelwerk (konzeptionell)
# Default: Alles blocken
set block-policy drop
# Interne Schnittstelle definieren
int_if = "re0"
ext_if = "pppoe0"
# Erlauben: Loopback, internal traffic
pass on lo0
pass on $int_if proto tcp from any to any port 22
# Erlauben: Outbound, automatisch Inbound
pass out on $ext_if proto tcp from any to any
# Rate Limiting: Zu viele Verbindungen von einer Source
pass in on $ext_if proto tcp to any port 22 \
(max-src-conn 10, max-src-conn-rate 5/60)
# Source Tracking: IPs blocken, die Portscans starten
pass in on $ext_if proto tcp flags SYN/SYN,ACK
table <bruteforce> persist
block in quick from <bruteforce>
Anmerkung: Echte Produktionsregeln sind länger und granularer.
Threat Detection & Monitoring
OpenBSD Firewall allein reicht nicht
PF filtert Layer 3/4 (IP/TCP/UDP). Aber:
- Malicious Payloads in Layer 7 (Anwendung) sind unsichtbar
- Zero-Day HTTP Exploits kommen durch legitimen Port 80 durch
- Brute Force Attacks sind nur durch Rate Limiting sichtbar
Lösung: Zusätzlich Threat Detection (IDS) + Centralized Logging.
Die drei Schichten
| Layer | Tool | Erkennt |
|---|---|---|
| 3/4 (IP/TCP) | OpenBSD PF | Portscans, SYN Floods, Rate Anomalies |
| 7 (Anwendung) | IDS (Suricata/Snort) | HTTP Payloads, SQL Injection, Exploits |
| Everywhere | Centralized Logging (Syslog) | Korrelation, Zeitreihen, Anomalien |
Monitoring Setup (vereinfacht)
Was man beobachtet:
- Neue Connections pro Minute (Abnormitäten erkennen)
- Top Blocked IPs (Botnet C2?)
- Slow Brute Force (SSH Attempts über Stunden)
- IDS Alert Trends (Exploit Attempts)
- Regel Reload Fehler (Config Probleme)
Überprüfung: Logs kommen zentral an, kein Manuelles SSH auf Router nötig. Everything is queryable.
Praktische Übersicht
Hardware
- Prozessor: 4 Kerne, 2+ GHz (passend für Stateful Inspection)
- RAM: 4–8 GB (State Table + Logs im Memory)
- Speicher: SSD bevorzugt (schneller Zugriff auf Rules)
- Netzwerk: 2+ Ethernet-Interfaces (WAN, LAN)
Kompakte Hardware (z.B. Mini-PCs, alte Workstations) funktionieren perfekt. Du brauchst keinen Enterprise-Appliance.
Routing- und Filtering-Flow
Typische Probleme
- Rule Order: PF evaluiert Top-to-Bottom. Zuerst blockierende Rules, dann Exceptions.
- State Table Limits: Bei vielen Verbindungen (z.B. DDoS) kann State Table volllaufen. Limit setzen und monitoren.
- NAT Hairpinning: Internal Hosts können externe IPs des Routers intern nicht erreichen. RDR Regel fixen.
- Asymmetric Routing: Wenn Return Traffic über anderen Path kommt, kann PF es blocken. Policy-based Routing nötig.
Best Practices
1. Least Privilege
- Default: Block alles
- Explicit Allow: Nur was nötig ist
- Regelmäßig Review: Alte Allow-Rules löschen
2. Monitoring im Design
- Syslog vom Anfang einrichten (nicht später nachdenken)
- SNMP Metrics exportieren
- Grafana Dashboard fürs Daily Operations
3. Testing vor Deployment
- Regeln in einer Test-VM üben (Virtual Box mit OpenBSD)
pfctl -n -f rules.confcheckt Syntax ohne zu ladenpfctl -srzeigt aktuell geladene Rules
4. Dokumentation
- Jede Rule muss ein Kommentar haben: Warum ist sie da?
- Beispiel:
# Allow SSH from admin subnet - Wartung in 6 Monaten wird's dir danken
5. Inkrementelle Komplexität
- Phase 1: Basic Filtering + NAT
- Phase 2: Rate Limiting + Source Tracking
- Phase 3: IDS Integration
- Phase 4: Centralized Monitoring + Alerting
Nicht alles auf einmal. Jede Phase soll stabil laufen, bevor nächste kommt.
Zusammenfassung
- OpenBSD PF: Kernel-basiert, einfach verständlich, Security-first
- Stateful Filtering: Merkt sich Verbindungen, reduziert Rule Komplexität
- Threat Detection: PF (L3/4) + IDS (L7) + Centralized Logging
- Monitoring: Nicht optional — zentrale Observability ist Teil des Designs
- Hardware: Kompakt, günstig, aber Monitoring braucht dich