Eine Tabelle enthält eine Gruppe von IPv4- und/oder IPv6-Adressen. Es ist
wesentlich schneller - und verbraucht weniger Prozessorzeit und Speicher -
Adressen aus Tabellen auszulesen als aus
Listen. Aus diesem Grund sind Tabellen ideal,
um große Gruppen von Adressen aufzunehemen. Das Auslesen einer Tabelle,
die 50.000 Adressen enthält, dauert nur wenig länger als
das einer Tabelle mit 50 Adressen. Tabellen können auf folgende Art und
Weise benutzt werden:
Zieladresse in route-to-, reply-to- und
dup-to-Filterregel-Optionen.
Tabellen werden entweder in der
pf.conf oder mit
pfctl(8) erzeugt.
Konfiguration
In der Datei pf.conf werden die Tabellen mittels der
table-Direktive erzeugt. Die folgenden Eigenschaften können
zusätzlich für jede Tabelle festgelegt werden:
const - Der Inhalt der Tabelle kann nicht mehr verändert
werden nachdem diese erzeugt wurde. Ohne Vergabe dieser Eigenschaft ist es
möglich, jederzeit mit
pfctl(8) der Tabelle Adressen hinzuzufügen oder aus ihr
zu entfernen, selbst wenn das System unter einem
securelevel(7) von zwei oder höher läuft.
persist - Veranlasst den Kernel, die Tabelle im Speicher zu
behalten, selbst wenn keine Regel sie mehr verwendet. Ohne die Vergabe
dieser Eigenschaft entfernt der Kernel die Tabelle automatisch aus dem
Speicher sobald die letzte Regel, die von der Tabelle Gebrauch machte,
entfernt wurde.
block in on fxp0 from { <rfc1918>, <spammers> } to any
pass in on fxp0 from <goodguys> to any
Adressen können auch mit dem Negierermodifizierer (oder ,not')
angegeben werden:
table <goodguys> { 192.0.2.0/24, !192.0.2.5 }
Die Tabelle goodguys entspricht nun allen Adressen des
192.0.2.0/24er Netzwerkes mit Ausnahme der Adresse 192.2.0.5.
Der Name einer Tabelle steht immer zwischen spitzen Klammern <
>.
Tabellen können den Inhalt einer Textdatei enthalten, die aus
einer Aufzählung von IP- oder Netzwerk-Adressen besteht:
table <spammers> persist file "/etc/spammers"
block in on fxp0 from <spammers> to any
Die Datei /etc/spammers enthält eine Liste von IP-Adressen
und/oder CIDR-Netzwerkbereichen
- eine pro Zeile. Auch hier ist jede Zeile, die mit einem # beginnt,
eine Kommentarzeile und wird ignoriert.
Manipulationen mit pfctl
Tabellen können während der Laufzeit mit
pfctl(8) verändert werden. Hier ein Beispiel, um einen Eintrag
zur weiter oben erzeugten Tabelle <spammers> hinzuzufügen:
# pfctl -t spammers -T add 218.70.0.0/16
Sollte die Tabelle <spammers> vorher noch nicht existiert haben, wird
sie erzeugt. Der folgende Befehl dient dazu, die Adressen einer Tabelle
aufzulisten:
# pfctl -t spammers -T show
Die Option -v kann zusammen mit -T show benutzt werden, um
eine Statistik für die Tabelle zu zeigen. Der folgende Befehl dient dazu,
Adressen aus einer Tabelle zu entfernen:
# pfctl -t spammers -T delete 218.70.0.0/16
Weitere Informationen, wie Tabellen mit pfctl verändert werden,
finden sich in der Manualseite von
pfctl(8).
Adressen angeben
Außer der IP-Adresse kann auch der Hostname
angegeben werden. Sobald der Hostname in eine IP-Adresse aufgelöst wird,
werden alle sich daraus ergebenden IPv4- und IPv6-Adressen in die Tabelle
eingefügt. Außerdem kann eine IP-Adresse durch die Angabe des Namens eines
gültigen Interfaces oder des self-Schlüsselwortes in eine
Tabelle eingefügt werden.
Die Tabelle enthält dann alle IP-Addressen, die dem Interface oder
der Maschine zugewiesen sind (einschließlich der Loopback-Adressen).
Eine Ausnahme beim Angeben von Adressen ist, dass 0.0.0.0/0 und
0/0 nicht in Tabellen funktionieren.
Die Alternative ist das Festlegen der Adresse oder die
Benutzung eines
Makros.
Wann eine Adresse zutrifft
Eine Adressabfrage an die Tabelle gibt den am besten zutreffenden Eintrag
zurück. Dieses erlaubt, Tabellen wie folgt aufzubauen:
block in on dc0 all
pass in on dc0 from <goodguys> to any
Die Quell-Adresse jeden Paketes, das dc0 durchläuft, wird mit den
Einträgen der Tabelle <goodguys> verglichen:
172.16.50.5 - die nächste Übereinstimmung ist 172.16.0.0/16;
das Paket entspricht einem Tabelleneintrag und wird das Interface passieren
172.16.1.25 - die nächste Übereinstimmung ist !172.16.1.0/24;
das Paket entspricht einem Tabelleneintrag, dieser ist jedoch in der
Verneinungsform (mit dem vorangestelltem !) angegeben; das Paket wird also
blockiert werden
172.16.1.100 - entspricht genau 172.16.1.100; das Paket entspricht
einem Tabelleneintrag und wird das Interface passieren
10.1.4.55 - kommt nicht in der Tabelle vor und wird geblockt