Einleitung

Eine Firewall ist immer gut, insbesondere wenn es sich um einen öffentlichen Server handelt. FreeBSD hat die, höchsten Ansprüchen gerechte, "pf" Firewall aus dem OpenBSD Projekt seit Jahren im Basissystem integriert. Zitat aus dem FreeBSD Handbuch: "Firewalls ermöglichen es, den ein- und ausgehenden Netzwerkverkehr eines Systems zu filtern. Dazu verwendet eine Firewall eine oder mehrere Gruppen von "Regeln", um ankommende Netzwerkpakete zu untersuchen und entweder durchzulassen oder zu blockieren. Die Regeln einer Firewall untersuchen charakteristische Eigenschaften von Datenpaketen, darunter den Protokolltyp, die Quell- und Zieladresse sowie den Quell- und Zielport." Schöner kann ich es nicht schreiben. Neben der ganz einfachen Notwendigkeit eines Schutzes, werden darüber auch die Zugriffe auf genutzte Jails und BHYE VMs geregelt.

Ziele

Das Ziel ist eine sehr einfache Firewall, die jeglichen abgehenden Verkehr, einkommende Ping Anfragen und SSH Verbindungen erlaubt und das NAT für VMs und BHYVE ermöglicht. Alles was nicht explizit erlaubt ist, wird abgelehnt (default block).

NEU: Für ganz ungeduldige habe ich einen Konsole only Abschnitt. Da gibts nur Befehle, keine Erklärungen.

Letzte Aktualisierung:

  • 01.12.2024: Initiale Version

Grundbedingungen

  • Ein FreeBSD Server ist eingerichtet und vorbereitet
  • Die Netzwerkkarte des Host Systems mit Zugriff auf das LAN Netzwerk ist bekannt, z.B.igb0. Die Schnittstelle muss an eure primäre Netzwerkkarte angepasst werden. Die aktuelle mit dem Internet verbundene Schnittstelle kann mit route -n get default | grep 'interface:' | grep -o '[^ ]*$' ermittelt werden, z.B. bge0 (um mal ein anderes Beispiel zu erwähnen)

PF

Die Konfiguration der pf-Firewall erfolgt über die zentrale /etc/pf.conf Datei.
Darin werden alle benötigten Regeln hinterlegt und mit ee /etc/pf.conf bearbeitet:

# Hier die ermittelte Netzwerk Schnittstelle einsetzen
ext_if="igb0"

# Dies führt dazu, dass bei TCP-Paketen ein TCP RST und bei anderen Pakettypen ein ICMP UNREACHABLE zurückgegeben wird
set block-policy return

# Setzt die Fragmente wieder zusammen und stellt sicher, dass alle TCP-Paketinformationen korrekt sind
scrub in on $ext_if all fragment reassemble

# Überspringen der gesamten PF-Verarbeitung auf der Schnittstelle lo
set skip on lo

# Tabellen für späteres NAT 
table <jails> persist
table <vms> persist
nat on $ext_if from <jails> to any -> ($ext_if:0)
nat on $ext_if from <vms> to any -> ($ext_if:0)
rdr-anchor "rdr/*"

# Eingehender Verkehr wird blockiert
block in all

# Ausgehender Verkehr ist erlaubt
pass out quick keep state

# Blockieren von gefälschten Paketen
antispoof for $ext_if inet

# Erlaubt eingehende ICMP Pakete (z.B. Ping)
pass in inet proto icmp

# Erlaubt eingehende TCP Pakete auf Port 22 (SSH)
pass in inet proto tcp from any to any port ssh flags S/SA keep state

Mit service pf enable wird die Firewall aktiviert und sind per service pf enable gestartet. Nach Änderungen an dem Regelsatz werden diese nach einem service pf reload aktiv.

Konsole

Voilá