FreeBSD 5.3 und pf

XPectIT

the just
Vermutlich einer der besten Gründe um einem Router die neue FreeBSD 5.3 (beta hin oder her) zu spendieren ist die Implementierung von pf im Kernel.

Hier geht es jetzt nicht um die Konfiguration oder die Filterregeln, sondern um den Schritt davor. Wie bringe ich meinem FreeBSD bei mit pf zu arbeiten. Da ich im Netz dazu nicht viel gefunden habe, und sich das meiste auf das pf in den Ports bezieht, schreibe ich mal meine Erfahrungen hier rein.

Spätestens wenn man /usr/src/UPDATING liest, sollte man auch etwas von pf sehen. Es müssen 2 User und 2/3 Gruppen angelegt werden. Das ist aber nicht so schwer, immerhin verweigert "make installworld" sonst seine Dienste. :)

Nachdem man die Manpage zu rc.conf liest, merkt man, das es im Kernel zwei Zeilen braucht:
"device pf" (muss eingefügt werden) und
"options PFIL_HOOKS" (das ist aber im GENERIC enthalten)

und in die /etc/rc.conf sollte mindestens
"pf_enable=YES" rein und weil man vermutlich auch logs haben will noch die Zeile mit den pflogs (habe ich gerade nicht auswändig).

Kernel kompilieren und neustarten. Jedesmal wenn jetzt die Regeln geladen werden, erscheint eine Meldung, das kein ALTQ-Support im Kernel ist und die ALTQ Funktionen deaktiviert sind. Irgendwo im Netz fand ich dann, das es noch eine option für den Kernel gibt:
"options ALTQ"

Kernel kompilieren und neustarten. So, bei genauer Betrachtung fällt eine error-Zeile beim Start auf, die einem sagt, dass pflogd nicht starten kann. :confused:
Irgendwann fand ich einen Hinweis, das pflog ein device sein sollte und dieses nicht vorhanden ist. Das war gestern Abend um 23 Uhr irgendwann. Ich habe dann noch (auf gut Glück)
"device pflog" im Kernel hinterlegt und neu kompiliert. Allerdings hatte ich heute morgen keine Zeit nachzusehen ob es geklappt hat.

Gibts dazu echt keine Anleitung, oder habe ich nur keine Gefunden?
Das Ganze werde ich wohl auch noch fürs wiki schreiben, wenn es fertig ist.
 
Zuletzt bearbeitet:
pf mit FreeBSD

Einleitung
***************************
Da pf für FreeBSD noch sehr jung ist, findest Du keine brauchbare Anleitung. Empfehlenswerte Informationsquellen für solche Betriebssystemänderungen sind /usr/src/UPDATING und:

http://www.xl0.org/FreeBSD/
(siehe die Berichte vom 14. März 2004 und 29. Februar 2004)

Anleitung
*************************
Da ich zur Zeit nur FreeBSD 4.10 verwende, korrigiert mich bitte, wenn etwas in der Anleitung nicht stimmt:

/etc/rc.conf
--------------
Zuerst einen Blick in /etc/defaults/rc.conf werfen, welche Optionen für /etc/rc.conf überhaupt vorhanden. Dann die Optionen für pf suchen:

# more /etc/defaults/rc.conf | grep pf | grep -v ipf |grep -v swap

Jetzt müssen nur die Optionen in /etc/rc.conf eingetragen werden, welche nicht den Default-Werten in /etc/defaults/rc.conf entsprechen sollen, z.B.:

pf_enable="YES"
pflog_enable="YES"

Firewallregeln
----------------
Nach:

pf_rules="/etc/pf.conf"

werden defaultmässig die pf-Firewallregeln unter /etc/pf.conf gesucht. Hier meine als Beispiel, Homerechner mit Internetanschluss (DHCP) :

Code:
# /etc/pf.conf
# OpenBSD-PF-Firewall-Konfiguration
# Andy, am 6.3.2004


# Makros
#------------------------------------------------------------------------

# Netzwerkkarten
hard_if  = "fxp0"

# Private Netzwerke
priv_nets = "{ 127.0.0.0/8, 192.168.0.0/16, 172.16.0.0/12, 10.0.0.0/8 }"


# Regeln
#-------------------------------------------------------------------------

# Keine Rueckmeldung bei Blockierungen
set block-policy drop

# Es soll Statistik gefuehrt werden
set loginterface $hard_if

# Warte-Verhalten
set optimization aggressive

# Keine Ahnung
set require-order yes

# Erkennung der Betriebssysteme
set fingerprints "/etc/pf.os"

# scrub incoming packets
scrub in all

# silently drop broadcasts (cable modem noise)
block in quick on $hard_if from any to 255.255.255.255

# setup a default deny policy
block drop in log all
block drop out log all

# Diverser Netzverkehrlaerm (tcp)
block drop in on $hard_if inet proto tcp from any to ($hard_if) port www
block drop in on $hard_if inet proto tcp from any to ($hard_if) port ftp
block drop in on $hard_if inet proto tcp from any to ($hard_if) port 4662
block drop in on $hard_if inet proto tcp from any to ($hard_if) port 1731
block drop in on $hard_if inet proto tcp from any to ($hard_if) port 135
block drop in on $hard_if inet proto tcp from any to ($hard_if) port 445
block drop in on $hard_if inet proto tcp from any to ($hard_if) port 139

# Diverser Netzverkehrlaerm (udp)
block drop in on $hard_if inet proto udp from any to ($hard_if) port www
block drop in on $hard_if inet proto udp from any to ($hard_if) port ftp
block drop in on $hard_if inet proto udp from any to ($hard_if) port 4662
block drop in on $hard_if inet proto udp from any to ($hard_if) port 1731
block drop in on $hard_if inet proto udp from any to ($hard_if) port 135
block drop in on $hard_if inet proto udp from any to ($hard_if) port 445
block drop in on $hard_if inet proto udp from any to ($hard_if) port 139

# pass traffic on the loopback interface in either direction
pass quick on lo0 all

# Blockiere den externen Verkehr mit privaten Adressen
block drop in  log quick on $hard_if from $priv_nets to any
block drop out log quick on $hard_if from any to $priv_nets

# activate spoofing protection for the internal interface.
antispoof log quick for $hard_if inet

# pass tcp, udp, and icmp out on the external (Internet) interface.
# keep state on udp and icmp and modulate state on tcp.
pass out on $hard_if proto tcp all modulate state flags S/SA
pass out on $hard_if proto { udp, icmp } all keep state

# allow ssh connections in on the external interface as long as they're
# NOT destined for the firewall (i.e., they're destined for a machine on
# the local network). log the initial packet so that we can later tell
# who is trying to connect. use the tcp syn proxy to proxy the connection.
pass in on $hard_if proto tcp from any to ($hard_if) port ssh flags S/SA synproxy state

Eine sehr gute Anleitung zu den pf-Firewallregeln findet man unter:

http://www.openbsd.org/faq/pf/

Kernel
--------------
Nach einem Neustart sollte pf einwandfrei laufen. Eine Kernel-Neukompilierung sollte nicht notwendig sein, da durch den /etc/rc.conf-Eintrag pf als Kernelmodul beim Computer-Aufstarten nachgeladen wird.
 
Zuletzt bearbeitet:
Jetzt mal eine dumme Frage, ihr dürft mich danach auch chipigen wenns nötig ist aber wie läufts bei pf mit NAT? Muss man wie bei IPFilter extra NAT-Rules erzeugen bzw. NAT explizit in der rc.conf aufrufen oder macht das pf von selbst?
 
@AndreasMeyer
Danke für die Anleitung.
Die möglichen Angaben in der rc.conf habe ich ja gefunden, nur bislang noch keine Liste mit Kerneldevices und -optionen.
Von ALTQ steht zwar etwas in der rc.conf aber nichts davon, das dazu eine option im Kernel benötigt wird. Mittlerweile fand ich noch eine Liste mit optionen die alle mit ALTQ in Zusammenhang stehen:
Code:
The complete set of options for ALTQ3.0:

# ALTQ options
options         ALTQ            #alternate queueing
options         ALTQ_CBQ        #class based queueing
[color=red]##options       ALTQ_WFQ        #weighted fair queueing
##options       ALTQ_FIFOQ      #fifo queueing[/color]
options         ALTQ_RED        #random early detection
[color=red]##options       ALTQ_FLOWVALVE  #flowvalve for RED (needs RED)[/color]
options         ALTQ_RIO        #triple red for diffserv (needs RED)
[color=red]##options       ALTQ_LOCALQ     #local use[/color]
options         ALTQ_HFSC       #hierarchical fair service curve
[color=red]##options       ALTQ_ECN        #ecn extention to tcp (needs RED)
##options       ALTQ_IPSEC      #check ipsec in IPv4[/color]
options         ALTQ_CDNR       #diffserv traffic conditioner
[color=red]##options       ALTQ_BLUE       #blue by wu-chang feng[/color]
options         ALTQ_PRIQ       #priority queue
[color=red]##options       ALTQ_NOPCC      #don't use processor cycle counter[/color]
options         ALTQ_DEBUG      #for debugging
Ob ich diese verwenden kann/muss wird wohl auf einen Versuch hinauslaufen.

Edit:
Ich habe die oben genannten options durchprobiert und die mit "##" gekennzeichnet die beim make buildkernel als ungültig angezeigt werden.
Loggin funktioniert mit "device pflog" wunderbar.
 
Zuletzt bearbeitet:
Ich bin wieder einen Schritt weiter.
Das pflog die Daten als tcpdump lesbar und nicht in txt-form in /var/log/pflog schreibt ist zwar gewöhnungsbedürftig, aber auch änderbar (verweis auf die FAQ).
Ist im Kernel nur "options ALTQ" und keine der weiteren Optionen enthalten, verschwindet zwar die Meldung, das kein ALTQ support im Kernel enthalten ist und die ALTQ Funktionen nicht verfügbar sind, aber das queueing funktioniert nur ohne die schönen Feinheiten (cbq oder red). Versucht man diese trotzdem in die /etc/pf.conf einzubauen, erhält man beim laden der Regeln eine Meldung, das die queue nicht definiert wurde.
Also sollten schon wenigstens die options ALTQ_RED, ALTQ_CBQ und natürlich ALTQ in den Kernel kommen.
 
Es läuft mittlerweile alles bis auf NAT. Also auch NAT funktioniert, allerdings erst wenn ich die Regeln neu lade wenn sich die IP von tun0 ändert.

Meine nat-regel sieht folgendermassen aus:
nat on tun0 from vr0:network to any -> (tun0)

Die Klammern sollten dafür sorgen, das pf diese Regel automatisch anpasst wenn sich die IP auf diesem Interface ändert. Nur macht der Rechner das nicht.
Lade ich die Regeln neu mit "pfctl -Fa -f /etc/pf.conf" kann ich problemlos von den Clients ins Netz. Vom Router selber geht es jederzeit. :confused:
 
Danke asg.
Über den mpd liest man da ja so einiges gutes, nur war ich (bis jetzt) mit dem userland-ppp zufrieden und wollte an dessen Einstellungen nicht so viel ändern - hat mich Blut und Wasser gekostet meine ISDN-Verbindung hinzukriegen ;)
Und jetzt mpd verwenden, dem ppp entsagen, ins kalte Wasser springen... naja. Ich hab ja noch ein freies Slice worauf ich erstmal dumpen kann.
 
20040914:
The format of the pflogd(8) logfile "/var/log/pflog" has changed for
architectures that have a 64 bit long type to make it compatible to
the standard pcap format. In order to prevent corruption move away
any old logfile before using a new pflogd(8).
 
XPectIT schrieb:
Es läuft mittlerweile alles bis auf NAT. Also auch NAT funktioniert, allerdings erst wenn ich die Regeln neu lade wenn sich die IP von tun0 ändert.

Meine nat-regel sieht folgendermassen aus:
nat on tun0 from vr0:network to any -> (tun0)

Die Klammern sollten dafür sorgen, das pf diese Regel automatisch anpasst wenn sich die IP auf diesem Interface ändert. Nur macht der Rechner das nicht.
Lade ich die Regeln neu mit "pfctl -Fa -f /etc/pf.conf" kann ich problemlos von den Clients ins Netz. Vom Router selber geht es jederzeit. :confused:
Ich gebe mir mal selbst eine Lösung:
Ich konnte pf nicht dazu bewegen die Regel dynamisch anzupassen, also wollte ich die Regeln bei der Anwahl neu laden.
  • ppp kennt ein "ppp.linkup"-Script, das wird aber ausgeführt wenn der Link hergestellt wird und nicht bei jeder Anwahl. z.b. bei Dial-on-Demand ist das nicht brauchbar, weil das Script nur das erste mal ausgeführt wird (zumindest war das bei meinen Tests so)
  • isdnd kennt ein "connectprog", nur führt er das aus mir unerklärlichen Gründen nicht aus.
  • isdnd hat noch die Möglichkeit bei auftreten einer reg-expr in der log-Datei ein bestimmtes Programm auszuführen. Da bei meiner Anwahl immer das gleich im Log auftaucht, habe es es nach einem "sleep 3" im Script geschafft die Regeln für pf neu zu laden damit auch NAT funktioniert

Irgendwie glaube ich aber das es einfacher funktionieren sollte. :o
 
/etc/ppp/ppp-linkup:

versanet:
! /usr/local/sbin/pfctl -Fa -f /etc/pf.conf
!bg /usr/sbin/ntpdate ntp1.ptb.de ntp2.ptb.de
# !bg su -m noip -c '/usr/local/bin/noip' 2>/dev/null >/dev/null

Dat klappt eigentlich bei jeder einwahl :) Mein ppp connect eintrag heisst, wie zu sehen, versanet. Vielleicht haste den irgendwie vergessen?

Achja, nochmal zum installieren:
Ein Update auf 5.3-beta und ein (5.3!) GENERIC kernel mit:
options ALTQ
options ALTQ_CBQ # Class Bases Queueing
options ALTQ_RED # Random Early Drop
options ALTQ_RIO # RED In/Out
options ALTQ_HFSC # Hierarchical Packet Scheduler
options ALTQ_CDNR # Traffic conditioner
options ALTQ_PRIQ # Priority Queueing
#options ALTQ_NOPCC # Required for SMP build
#options ALTQ_DEBUG
hat bei mir vollkommen ausgerichtet um pf mit altq zum rennen zu bringen.


In der rc.conf dann noch:

ppp_enable="YES"
ppp_mode="ddial"
ppp_profile="versanet"
ppp_nat="NO"
ipsec_enable="NO"
pf_enable="YES"
pflog_enable="YES"

eine funktionstüchtige /etc/pf.conf und dann lüppt der laden (mit firewall, nat und traffic shaping). Nur ist mein pf script noch nicht wirklich toll :)
 
Zurück
Oben