Zur Manipulation des Paketfilters steht eine Reihe von Routinen zur Verfügung, mit deren Hilfe man Ketten (engl. "`Chains"') und Regeln hinzufügen und wieder löschen kann. Eine Kette ist eine benannte und geordnete Liste von Regeln. Es gibt einen Satz vordefinierter Ketten (PREROUTING, INPUT, FORWARD, OUTPUT, POSTROUTING); mit Hilfe dieser Funktionen können weitere Ketten nach Bedarf erstellt werden.
add_rule <table> <chain> <rule> <comment> ins_rule <table> <chain> <rule> <position> <comment> del_rule <table> <chain> <rule> <comment>
wobei die Parameter folgende Bedeutung haben:
fli4l konfiguriert den Paketfilter mit einem gewissen Standardregelsatz. Will man eigene Regeln einfügen, wird man diese in der Regel nach dem Standardregelsatz einfügen wollen. Ebenfalls wird man wissen wollen, was denn die vom Nutzer gewünschte Aktion beim Verwerfen eines Paketes ist. Diese Informationen bekommt man für die FORWARD- und INPUT-Ketten durch Aufruf zweier Funktionen, get_defaults und get_count. Nach Aufruf von
get_defaults <chain>
erhält man die folgenden Ergebnisse:
Nach Aufruf von
get_count <chain>
erhält man in der Variable res die Anzahl der Regeln in der Kette <chain>. Diese Position ist insofern wichtig, als man nicht einfach add_rule verwenden kann, um eine Regel am Ende der vordefinierten "`filter"'-Ketten INPUT, FORWARD und OUTPUT einzufügen. Dies liegt daran, dass diese Ketten mit einer Standardregel abgeschlossen werden, welche alle verbliebenen Pakete behandelt, je nach Belegung der PF_<Kette>_POLICY-Variablen. Ein Einfügen hinter dieser letzten Regel hat also keine Auswirkungen. Die Funktion get_count erlaubt es nun hingegen, die Stelle direkt vor dieser letzten Regel zu ermitteln und die Position dann an die ins_rule-Funktion im Parameter <position> zu übergeben, um die Regel wie gewünscht am Ende der jeweiligen Kette, aber vor der letzten Auffang-Regel einzubauen.
Ein Beispiel aus dem Skript opt/etc/rc.d/rc390.dns_dhcp des Pakets "`dns_dhcp"' soll dies verdeutlichen:
case $OPT_DHCPRELAY in yes) begin_script DHCRELAY "starting dhcprelay ..." idx=1 interfaces="" while [ $idx -le $DHCPRELAY_IF_N ] do eval iface='$DHCPRELAY_IF_'$idx get_count INPUT ins_rule filter INPUT "prot:udp if:$iface:any 68 67 ACCEPT" \ $res "dhcprelay access" interfaces=$interfaces' -i '$iface idx=`expr $idx + 1` done dhcrelay $interfaces $DHCPRELAY_SERVER end_script ;; esac
Hier sieht man inmitten der Schleife einen Aufruf von get_count, gefolgt von einem Aufruf der ins_rule-Funktion, der unter anderem die res-Variable als position-Parameter übergeben wird.
fli4l verwendet in den Paketfilterregeln die Syntax match:params, um zusätzliche Bedingungen an die Pakete zu stellen (siehe mac:, limit:, length:, prot:, ...). Will man zusätzliche Tests hinzufügen, wird das folgendermaßen gemacht:
Wenn der Paketfilter-Test in IPv6-Regeln verwendet werden soll,
dann muss darauf geachtet werden, dass der Name keine gültige
IPv6-Adresskomponente ist!
# IPv4 extension is available foo_p=yes # the actual IPv4 extension, adding matches to match_opt do_foo() { param=$1 get_negation $param match_opt="$match_opt -m foo $neg_opt --fooval $param" } # IPv6 extension is available foo6_p=yes # the actual IPv6 extension, adding matches to match_opt do6_foo() { param=$1 get_negation6 $param match_opt="$match_opt -m foo $neg_opt --fooval $param" }
Der Paketfilter-Test muss nicht zwingend sowohl für IPv4 als auch für IPv6 implementiert sein (obwohl dies zu bevorzugen ist, falls er für beide Layer-3-Protokolle sinnvoll ist).
$ cd opt/etc/rc.d $ sh test-rules.sh 'foo:bar ACCEPT' add_rule filter FORWARD 'foo:bar ACCEPT' iptables -t filter -A FORWARD -m foo --fooval bar -s 0.0.0.0/0 \ -d 0.0.0.0/0 -m comment --comment foo:bar ACCEPT -j ACCEPT
+FW_GENERIC_MATCH(OPT_FOO) = 'foo:bar' : '' +FW_GENERIC_MATCH6(OPT_FOO) = 'foo:bar' : ''