Im Hauptteil meines pf-Tutorials bin ich nicht auf die NAT-Funktionen von pf eingegangen, da der Umfang bereits sehr groß war. Für die Jails die wir später einrichten, wollen wir aus Kostengründen nicht zwangsläufig externe IPs einkaufen (diese kosten bei den meisten Providern zumindest Einrichtungsgebühr) die wir dann den Jails zuordnen können. Wir machen das intern.

Was wir in diesem kleinen Exkurs machen ist lediglich das Erklären der Weiterleitungsregeln und NAT für die Jails. Diese Regeln kannst du kopieren und an deine Bedürfnisse anpassen.

  1. Wir öffnen also wieder unsere '/etc/pf.conf', die wir im Hauptartikel ja bereits angelegt haben. Wir müssen dabei beachten, dass es für die Definitionen von Regeln und Makros Vorschriften, was die Reihenfolge in der pf.conf betrifft, gibt. So muss folgende Reihenfolge eingehalten werden:
    • Makros
    • Tabellen
    • Optionen
    • Scrub
    • Queueing
    • Übersetzung
    • Filterregeln

  2. Makros hatten wir ja bereits definiert, wir hatten unser Interface in einem Makro definiert. Wir fügen also nach unseren Interface-Makro noch weitere ein, und zwar für die weiterzuleitenden Ports. Da ich später zunächst 2 Jails anlegen werde (Mail, WWW), definiere ich mir 2 Makros für die SSH-Ports:

    j1_tcp = "{ 8801 }"
    j1_udp = "{ 8801 }"
    j2_tcp = "{ 8802 }"
    j2_udp = "{ 8802 }"

  3. Weiters setzen wir noch jeweils eine Variable für die IP-Adressen der Jails, sowie für die externe IP. Die externe IP ist bei mir auch eine "interne IP", da mein Server vorerst im Intranet läuft, wo dieser IP-Kreis zum Einsatz kommt. Zusätzlich legen wir noch ein Makro mit allen internen IPs an. Diese brauchen wir später für unsere NAT-Regel.

    jails = "{ 10.0.0.0/24 }"
    ext_ip = 192.168.0.10
    mail = 10.0.0.1
    www = 10.0.0.2

  4. Jetzt kommen wir zu den eigentlichen Regeln. Unterhalb von "scrub in all" schreiben wir für jede Jail je zwei Regeln, für jedes Protokoll eine:

    rdr pass on $if proto tcp from any to $if port $j1_tcp -> $mail
    rdr pass on $if proto udp from any to $if port $j1_udp -> $mail

  5. Um nun zu erreichen, dass die Jails auch Zugriff auf das Netz nach außen erhalten, richten wir NAT ein. Hierfür legen wir erstmal für die Firewall folgende Regel an:

    nat on $if proto {tcp udp icmp} from $jails to any -> $ext_ip

  6. Um nun das Host-System als Gateway einzurichten, tragen wir folgende Zeilen in unsere '/etc/rc.conf' ein:

    gateway_enable="YES"

  7. Wir dürfen später nicht vergessen, als Gateway bei den Jails die IP unseres Host-Systems anzugeben (in der rc.conf). Um die Jails später erfolgreich laufen lassen zu können, müssen der Netzwerkkarte weitere IP-Adressen (Aliase) zugewiesen werden. Wie das geht beschreibe ich euch im Abschnitt "Jails".

Ich will meine Jails alle per SSH pflegen und warten. Das finde ich persönlich erheblich angenehmer. Da ich aber nicht ständig meinen Webserver per SSH erreichen will/muss, habe ich neben den oben genannten statische Regeln, mein Webserver soll/muss immer auf dem Port 80 lauschen, bereits erwähnt "anchor" verwendet. Da ich bei den Jails nur Weiterleitungen ("rdr") habe, sieht das bei mir so aus:

  • Anchor einfügen: rdr-anchor www_ssh
  • Anchor laden: # pfctl -a www_ssh -f /etc/pf_anchors/www_ssh
  • Anchor entladen: # pfctl -a www_ssh -F all 
    (statt all kannst du auch nur nat verwenden, wenn du nur rdr's hast)

Eine solche Anchor-Datei enthält bei mir dann die entsprechende "rdr"-Regel, die normalerweise in der '/etc/pf.conf' stünde.