Subsections


3.10 Der Paketfilter

Der von fli4l verwendete Linux-Kern stellt einen Paketfilter zur Verfügung. Mit Hilfe dieses Paketfilters wird gesteuert, wer mit dem Router bzw. über ihn hinweg kommunizieren darf. Weiterhin können Dinge wie Port-Weiterleitung (ein an den Router gerichtetes Paket wird an einen anderen internen Rechner weitergereicht) und Maskierung (engl. ``Masquerading''; Pakete, die von einem Rechner hinter dem Router kommen, werden so verändert, dass sie so aussehen, als kämen sie vom Router selbst) realisiert werden.

Die Struktur des Paketfilters ist in Abbildung 3.1 angedeutet. Pakete kommen über eine Netzwerk-Schnittstelle herein und durchlaufen die PREROUTING-Kette (eng. ``chain''). Hier werden die an den Router gerichteten Pakete an einen anderen Rechner weitergereicht, indem die Zieladresse und der Zielport manipuliert werden. Ist das Paket an den Router gerichtet, wird es an die INPUT-Kette, andernfalls an die FORWARD-Kette weitergereicht. Beide Ketten prüfen, ob das Paket zulässig ist. Wird das Paket akzeptiert, wird es an den lokalen Zielprozess zugestellt oder über die POSTROUTING-Kette (in der das Maskieren von Paketen stattfindet) an diejenige Netzwerk-Schnittstelle weitergereicht, über die das Paket sein Ziel erreichen kann. Lokal generierte Pakete werden in der OUTPUT-Kette gefiltert und schließlich (falls erfolgreich) über die POSTROUTING-Kette ebenfalls an die korrekte Netzwerk-Schnittstelle weitergereicht.

Figure 3.1: Struktur des Paketfilters
\includegraphics[width=\columnwidth]{firewall}

Mit der Paketfilterkonfiguration lassen sich die einzelnen Ketten des Paketfilters direkt konfigurieren. Dazu gibt es für jede relevante Kette ein eigenes Array, d.h. eine für die INPUT-Kette (PF_INPUT_%), eine für die FORWARD-Kette (PF_FORWARD_%), eine für die OUTPUT-Kette (PF_OUTPUT_%), eine für die PREROUTING-Kette, in der die Portweiterleitung durchgeführt wird (PF_PREROUTING_%), und eine für die POSTROUTING-Kette, in der das Maskieren der Pakete durchgeführt wird (PF_POSTROUTING_%).

Ein Eintrag in einem dieser Arrays besteht im Wesentlichen aus einer Aktion (s.u.), die durch zusätzliche Bedingungen eingeschränkt werden kann. Diese Bedingungen beziehen sich auf Eigenschaften des betrachteten Paketes. Ein Paket enthält Informationen über seine Herkunft (Quelle, welcher Rechner hat das Paket losgeschickt), sein Ziel (an welchen Rechner und welche Anwendung soll das Paket gehen) u.a.m. Bedingungen können sich auf folgende Eigenschaften eines Paketes beziehen:

Kommt ein Paket herein, werden die Einträge bzw. die daraus generierten Regeln von oben nach unten abgearbeitet und die erste Aktion ausgeführt, bei der alle Bedingungen gelten. Trifft keine der Regeln zu, wird die Standardaktion ausgeführt, die man für (fast) jede Tabelle angeben kann.

Ein Eintrag hat dabei folgendes Format, wobei zu beachten ist, dass alle Einschränkungen optional sind:

    restriction{0,} [[source] [destination]] action [BIDIRECTIONAL|LOG|NOLOG]

An allen Stellen, an denen Netzwerke, IP-Adressen oder Hosts angegeben werden müssen, kann man sich auch auf IP_NET_%, IP_NET_%_IPADDR oder via @hostname auf einen Host aus HOST_% beziehen. Ist OPT_DNS aktiviert, dann können außerhalb von Aktionen via @fqdn auch Hosts über ihren Namen referenziert werden, die nicht in HOST_% zu finden sind. Das ist insbesondere dann sinnvoll, wenn es sich um externe Hosts handelt, die zudem viele (und wechselnde) IP-Adressen besitzen.


3.10.1 Aktionen des Paketfilters

Aktionen können die folgenden sein:

Table 3.5: Aktionen in Paketfilterregeln
Aktion Kette(n) Bedeutung
     
ACCEPT alle Akzeptiere das Paket.
DROP
 INPUT  
 FORWARD  
 OUTPUT  
Verwirf das Paket (der Absender erkennt das nur daran, dass keine Antwort, aber auch keine Fehlermeldung zurückkommt).
REJECT
 INPUT  
 FORWARD  
 OUTPUT  
Weise das Paket zurück (der Absender erhält eine entsprechende Fehlermeldung).
LOG alle Protokolliere das Paket und gehe zur nächsten Regel. Um verschiedene Protokoll-Einträge auseinanderhalten zu können, kann ein Präfix verwendet werden, das via LOG:log-prefix angegeben wird. Dieses Präfix darf maximal 28 Zeichen lang sein und kann aus Buchstaben, Ziffern, dem Bindestrich (-) und dem Unterstrich (_) bestehen.
MASQUERADE POSTROUTING Maskiere das Paket: Ersetze die Quelladresse des Paketes durch die eigene, der Schnittstelle zugewiesenen Adresse und sorge dafür, dass Antworten für diese Verbindung an den richtigen Rechner weitergeleitet werden.
SNAT POSTROUTING Ersetze die Quelladresse und den Quellport des Paketes durch die als Parameter für SNAT angegebene Adresse (für alle Pakete, die zu der gerade betrachteten Verbindung gehören).
DNAT PREROUTING Ersetze die Zieladresse und den Zielport des Paketes durch die als Parameter für DNAT angegebene Adresse (für alle Pakete, die zu der gerade betrachteten Verbindung gehören).
REDIRECT
 PREROUTING  
 OUTPUT  
Ersetze den Zielport des Paketes durch den als Parameter für REDIRECT angegebenen Port und stelle das Paket lokal zu (für alle Pakete, die zu der gerade betrachteten Verbindung gehören).
NETMAP
 PREROUTING  
 POSTROUTING  
Bilde die Ziel- bzw. Quelladresse des Paketes in den als Parameter für NETMAP angegebenen Bereich ab, die Ports bleiben unverändert (für alle Pakete, die zu der gerade betrachteten Verbindung gehören; in der PREROUTING-Kette wird die Zieladresse verändert, in der POSTROUTING-Kette die Quelladresse).
   

Einige dieser Aktionen können durch die Optionen BIDIRECTIONAL, LOG oder NOLOG in ihrem Verhalten modifiziert werden. BIDIRECTIONAL generiert die gleiche Regel noch einmal, nur mit vertauschter Quell- und Zieladresse (und vertauschtem Quell- und Zielport und/oder vertauschter ein- und ausgehender Netzwerk-Schnittstelle, falls angegeben). LOG/NOLOG aktivieren bzw. deaktivieren das Protokollieren für diese eine Regel.


3.10.2 Einschränkungen in den Regeln

Einschränkungen können durch die in den folgenden Abschnitten aufgeführten Bedingungen vorgenommen werden. Bei den Bedingungen kann man immer any angeben, wenn man an irgendeiner Stelle keine Einschränkung vornehmen will, aber trotzdem etwas angeben will/muss. Einschränkungen können in beliebiger Reihenfolge angegeben werden, wenn sie einen vorangestellten Präfix haben. Das gilt für alle Einschränkungen, außer für die Angabe einer Quell- bzw. Zieladresse. Diese müssen immer direkt vor der Aktion stehen, die anderen Einschränkungen müssen vorher erfolgen. Einschränkungen können auch negiert werden, dazu wird einfach ein ! vorangestellt.

3.10.2.1 Einschränkungen der Quelle und des Ziels

Jedes Paket enthält eine Quell- und eine Zielangabe, jeweils in Form eines Tupels einer IP-Adresse und eines Ports.3.2 Diese Quelle bzw. dieses Ziel kann für eine Einschränkung herangezogen werden. Die Angabe für die Quelle bzw. das Ziel kann folgendermaßen vorgenommen werden:

Table 3.6: Quell- und Zieleinschränkungen in Paketfilterregeln
Ausdruck Bedeutung
   
ip eine einfache IP-Adresse
network eine Netzwerkangabe der Form <ip>/<netmask>
port[-port] ein Port bzw. ein Port-Bereich
IP_NET_x_IPADDR die IP-Adresse der Schnittstelle x des Routers
IP_NET_x das Subnetz x des Routers
IP_ROUTE_x das in der Route x angegebene Subnetz (Default-Routen können nicht verwendet werden, sie würden any entsprechen und werden vorsichtshalber ausgeklammert)
@name einer der via HOST_%_* vergebenen Namen oder Aliase; es wird die zugehörige IP-Adresse an dieser Stelle eingesetzt
<ip oder netzwerk>:port[-port] Host- bzw. Netzwerk-Adresse in einer der obigen Varianten, kombiniert mit einem Port bzw. Port-Bereich
   

Das könnte z.B. wie folgt aussehen: '192.168.6.2 any DROP'

Tauchen zwei dieser Angaben auf, wird die erste als Quelle, die zweite als Ziel betrachtet. In diesem Beispiel verwerfen wir also Pakete, die vom Rechner mit der IP-Adresse 192.168.6.2 gesendet wurden, unabhängig davon, an welches Ziel sie gerichtet sind.

Taucht nur eine Angabe auf, wird anhand des Wertes entschieden, ob die Quelle oder das Ziel gemeint ist, wobei die Entscheidung relativ einfach ist:

Wenn wir also z.B. das obige Beispiel abkürzen wollten, könnten wir einfach '192.168.6.2 DROP' schreiben. Es ist kein Port angegeben, die Bedingung gilt also für die Quelle, den Rechner, von dem das Paket gesendet wurde.

Wollen wir die Kommunikation mit dem ssh-Dämon erlauben, können wir 'any any:22 ACCEPT' (Pakete von einem beliebigen Rechner an den ssh-Port 22 eines beliebigen Rechners werden akzeptiert) oder kürzer '22 ACCEPT' schreiben: Es ist nur ein Port angegeben, also meinen wir das Ziel und damit Pakete, die an den Port 22 gerichtet sind.

Zur Vereinfachung der Regelmenge kann man an die Aktion ein BIDIRECTIONAL dranhängen, um auszudrücken, dass die Regel für beide Kommunikationsrichtungen gilt. Es werden dann Regeln generiert, in denen einfach die Quell- und die Ziel-Adressen und eventuell angegebenene Ports und Netzwerk-Schnittstellen vertauscht sind und der Rest gleich bleibt.

Beispiele:


  127.0.0.1 ACCEPT Lokale Kommunikation (Quelle 127.0.0.1) ist erlaubt  
  any 192.168.12.1 DROP Pakete an die Adresse 192.168.12.1 werden weggeworfen  
  any 192.168.12.1 DROP LOG Pakete an die Adresse 192.168.12.1 werden weggeworfen und zusätzlich protokolliert  
  any 192.168.12.1 DROP NOLOG Pakete an die Adresse 192.168.12.1 werden weggeworfen, werden aber nicht protokolliert  
  22 ACCEPT Pakete an den Port 22 (ssh) werden akzeptiert  
  IP_NET_1_NET ACCEPT Pakete aus dem an der ersten Schnittstelle hängenden Subnetz werden akzeptiert  
  IP_NET_1_NET IP_NET_2_NET Kommunikation zwischen den an der ersten und zweiten  
  ACCEPT BIDIRECTIONAL Schnittstelle hängenden Subnetzen ist gestattet  

3.10.2.2 Einschränkung der Schnittstelle

Eine Regel kann eingeschränkt werden in Bezug auf die Schnittstelle, über die ein Paket hereinkam bzw. hinausgeht. Das Format sieht wie folgt aus: if:in:out

In der INPUT-Kette kann man die Schnittstelle für hinausgehende Pakete nicht einschränken (das Paket geht ja nicht mehr hinaus), in der POSTROUTING-Kette kann man die Schnittstelle für hereinkommende Pakete nicht einschränken, da die Information darüber nicht mehr vorhanden ist. Lediglich in der FORWARD-Kette kann man für beides Bedingungen angeben.

Möglich sind folgende Werte für in bzw. out:

3.10.2.3 Einschränkungen des Protokolls

Eine Regel kann eingeschränkt werden in Bezug auf das Protokoll, zu dem ein Paket gehört. Das Format sieht wie folgt aus: prot:protocol bzw. prot:icmp:icmp-type. protocol kann dabei einen der folgenden Werte annehmen:

Wenn eine solche Einschränkung nicht vorhanden ist, aber dennoch Portnummern in einer Regel verwendet werden, dann wird die Regel zweimal angelegt, nämlich einmal für das tcp- und einmal für das udp-Protokoll.

3.10.2.4 Einschränkung der MAC-Adresse

Mittels mac:mac-address kann eine Einschränkung bezüglich der MAC-Adresse vorgenommen werden.

3.10.2.5 Einschränkungen in Bezug auf den Zustand eines Paketes

Der von fli4l verwendete Paketfilter sammelt Informationen über den Zustand von Verbindungen. Diese Informationen kann man dann nutzen, um Pakete zu filtern, also z.B. nur Pakete durchzulassen, die zu bereits bestehenden Verbindungen gehören. Die Zustände einer Verbindung können sein:3.3

Table 3.7: Zustandseinschränkungen in Paketfilterregeln
Zustand Bedeutung
   
INVALID Das Paket gehört zu keiner bekannten Verbindung.
ESTABLISHED Das Paket gehört zu einer Verbindung, über die bereits in beide Richtungen Pakete geflossen sind.
NEW Das Paket hat eine neue Verbindung aufgebaut oder gehört zu einer Verbindung, bei der noch nicht Pakete in beide Richtungen geflossen sind.
RELATED Das Paket baut eine neue Verbindung auf, hat aber eine Beziehung zu einer bestehenden Verbindung (z.B. baut ftp eine separate Verbindung für den eigentlichen Datentransfer auf).
   

Die Zustände werden wie folgt angegeben: state:state(s). Will man mehrere Zustände angeben, werden diese mit Komma getrennt. Um z.B. nur Pakete durchzulassen, die direkt oder indirekt zu bestehenden Verbindungen gehören, kann man state:ESTABLISHED,RELATED schreiben (dies ist in der INPUT- oder FORWARD-Kette sinnvoll).

3.10.2.6 Einschränkung der Häufigkeit einer Aktion

Unter bestimmten Umständen möchte man die Häufigkeit von Aktionen begrenzen, z.B. nur eine ICMP-Echo-Anforderung pro Sekunde zulassen. Das kann man mit der limit-Einschränkung erreichen, die wie folgt aussieht: limit:Häufigkeit:Burst. Die Häufigkeit wird dabei als n/Zeiteinheit (second, minute, hour, day) angegeben, wobei zusätzlich noch Ereignisse gehäuft auftreten können (Burst). Die Angabe limit:3/minute:5 heißt z.B., dass höchstens drei Ereignisse pro Minute erlaubt sind, wobei auch mal fünf Ereignisse dicht aufeinander folgend akzeptiert werden.


3.10.3 Der Einsatz von Schablonen im Paketfilter

Um den Umgang mit dem Paketfilter weiter zu vereinfachen, gibt es die Möglichkeit, häufig vorkommende Regeln zu sogenannten Schablonen (Templates) zusammenzufassen. Damit ist es möglich, eine ganze Reihe von Paketfilterregeln zusammenzufassen und dieser Sammlung von Regeln einen symbolischen Namen zu geben. Anstatt direkt mit Protokollen und Portnummern zu hantieren, verwenden Sie dann Einträge wie tmpl:ssh, wenn Sie das ssh-Protokoll in einer Regel verwenden wollen. Wie mit Schablonen zu verfahren ist, wird hier am Beispiel von ssh gezeigt.

Wollen Sie Ihren fli4l-Router vom Internet aus per ssh erreichen, so schreiben Sie in einen Eintrag der Array-Variable PF_INPUT_% den entsprechenden Dienstnamen (hier ssh) mit vorangestelltem tmpl: und der Aktion, die für diesen Dienst gelten soll. Beispiel:

    PF_INPUT_2='tmpl:ssh ACCEPT'

Hierbei steht tmpl: dafür, dass eine Regel auf einer Schablone basieren soll. Den Namen des Dienstes geben Sie nach dem `:' an, in unserem Beispiel also ssh. Zum Schluss geben Sie an, welche Aktion mit dem Dienst verbunden werden soll. Da Sie den fli4l-Router aus dem Internet erreichen wollen, erlauben wir die Verbindung mit ACCEPT. Einschränkungen von IP-Adressen oder Netzen sind nicht angegeben, also ist der ssh-Dienst von allen Netzen und über alle Schnittstellen erreichbar. Sie könnten bei Bedarf die gewohnten Schreibweisen vom Paketfilter benutzen, um den Zugriff auf den ssh-Dienst weiter einzuschränken.

Für welche Dienste Regeln vorbereitet sind (d.h. Schablonen existieren), kann in der Schablonen-Datei in opt/etc/fwrules.tmpl/templates nachgelesen werden. Im Folgenden finden Sie die Aufstellung in Tabellenform (siehe Tabelle 3.8).

Table 3.8: Im Lieferumfang von fli4l enthaltene Schablonen
Schablone Protokoll Port(s)
dhcp udp 67-68
dns tcp/udp 53
elster tcp 159.154.8.2:21
elster tcp 159.154.8.35:21
elster tcp 193.109.238.26:8000
elster tcp 193.109.238.27:8000
elster tcp 193.109.238.58:80
elster tcp 193.109.238.59:80
elster tcp 62.157.211.58:8000
elster tcp 62.157.211.59:8000
elster tcp 62.157.211.60:8000
elster tcp 80.146.179.2:80
elster tcp 80.146.179.3:80
ftp tcp 21
http tcp 80
https tcp 443
hylafax tcp 4559
imap tcp 143
imaps tcp 993
imond tcp 5000
ipmi tcp 22
ipmi tcp 2937
ipmi tcp 443
ipmi tcp 5120
ipmi tcp 5123
ipmi tcp 5900
ipmi tcp 5901
ipmi tcp 80
ipmi tcp 8889
ipmi udp 623
irc tcp 6667
ldap tcp/udp 389
mail tcp 110
mail tcp 143
mail tcp 25
mail tcp 465
mail tcp 587
mail tcp 993
mail tcp 995
mysql tcp 3306
nfs tcp/udp 111
nfs tcp/udp 2049
nntp tcp 119
ntp udp 123
oracle tcp 1521
pcanywhere tcp 5631-5632
ping icmp:0
ping icmp:8
pop3 tcp 110
pop3s tcp 995
privoxy tcp 8118
proxmox tcp 8006
proxmox tcp 5900
proxmox tcp 3128
rdp tcp 3389
rsync tcp 873
samba tcp 139
samba tcp 445
samba udp 137-138
sip tcp/udp 5060-5061
smtp tcp 25
snmp tcp/udp 161
socks tcp 1080
squid tcp 3128
ssh tcp 22
ssmtp tcp 465
submission tcp 587
svn tcp 3690
syslog udp 514
teamspeak tcp 14534
teamspeak tcp 51234
teamspeak udp 8767
telmond tcp 5001
telnet tcp 23
teredo udp 3544
tftp udp 69
time tcp/udp 37
traceroute udp 33404-33464
vdr tcp 6419
vnc tcp 5900
whois tcp 43
xbl tcp/udp 3074
xbl udp 88
xmppclient tcp 5222
xmppserver tcp 5269

Die Syntax für diese Form der Paketfilterregeln lautet also immer

    tmpl:<Name des Dienstes> <Einschränkungen> <Gewünschte Aktion>

wobei als <Einschränkungen> alles erlaubt ist, was unter 3.10.2 beschrieben wird. Die möglichen Werte für <Gewünschte Aktion> sind in 3.10.1 aufgelistet und beschrieben.

Ein paar weitere Beispiele sollen die Arbeitsweise verdeutlichen. Zuerst wollen wir uns PF_PREROUTING ansehen:

    PF_PREROUTING_N='2'
    PF_PREROUTING_1='tmpl:xbl dynamic DNAT:@xbox'
    PF_PREROUTING_2='tmpl:https dynamic DNAT:192.168.193.250'

Die Regel PF_PREROUTING_1 versorgt die Xbox mit allem, was für Xbox Live notwendig ist. Im einzelnen werden mit tmpl:xbl alle Ports und Protokolle, die für Xbox Live notwendig sind, an den Host xbox weitergeleitet. Anstelle der IP-Adresse wird ein Eintrag aus dem HOST_%_NAME-Array benutzt. Durch dynamic weiß der fli4l, dass die Ports von der Internet-Schnittstelle weitergeleitet werden sollen.

Die zweite Regel leitet das https-Protokoll an einen Webserver in der DMZ weiter.

Jetzt sehen wir uns an, wie es mit PF_INPUT weitergeht:

    PF_INPUT_N='3'
    PF_INPUT_1='if:IP_NET_1_DEV:any ACCEPT'
    PF_INPUT_2='if:pppoe:any prot:tcp 113 ACCEPT'
    PF_INPUT_3='if:br0:any tmpl:dns @xbox IP_NET_1_IPADDR ACCEPT'

Die erste Regel lässt alle aus dem Netz, das mit IP_NET_1 definiert ist, auf den Router zugreifen. Die zweite Regel ist für das oident-Paket. Dort wird der ident-Port geöffnet. Die dritte und letzte Regel erlaubt der Xbox den Zugriff auf den DNS Server auf dem fli4l. Hier ist auch wieder schön zu sehen, wie man einen Host-Alias einsetzt.

In PF_FORWARD und PF_POSTROUTING steht nichts tmpl-spezifisches mehr.

Figure 3.2: Verzeichnisstruktur fli4l
Image etc_fwrules_tmpl_dir

Es ist auch möglich, dass Sie eigene Schablonen anlegen oder dass Pakete ihre eigenen Schablonen mitbringen. Um eine eigene Schablone anzulegen, muss lediglich eine Datei mit den Namen der Schablone erstellt und die entsprechenden Regeln dort aufgenommen werden. Wenn Sie eine private Schablonendatei anlegen wollen, erstellen Sie diese in dem Verzeichnis etc/fwrules.tmpl unterhalb Ihres config-Verzeichnisses, so wie es die Abbildung 3.2 zeigt. Wenn das Verzeichnis etc/fwrules.tmpl unterhalb Ihres config-Verzeichnisses noch nicht existiert, legen Sie bitte zuerst beide Verzeichnisse an. Alternativ können Paket-Entwickler oder Benutzer, die Schablonen für mehr als eine Konfiguration anlegen wollen, ihre Regeln direkt in das Verzeichnis opt/etc/fwrules.tmpl ablegen. In dieses Verzeichnis kommen dann die neuen Schablonen. Dabei gilt die Regel, dass die Schablonen im config-Verzeichnis des Benutzers vorrangig behandelt werden. Zum Schluss wird die Schablonendatei, die zum Lieferumfang von fli4l gehört, ausgewertet. Sie können also Einträge in der fli4l-Schablonendatei dadurch überschreiben, indem Sie eine Schablonendatei mit dem Namen der zu überschreibenden Schablone in Ihrem config-Verzeichnis anlegen.

Wenn Sie zum Beispiel die Schablone vpn_freunde anlegen wollen, legen Sie die Datei vpn_freunde an. Das Template soll die Dienste ssh, smtp, dns und samba enthalten. Also schreiben Sie in die Datei vpn_freunde Folgendes:

    prot:tcp 22
    prot:tcp 25
    53
    prot:udp 137-138
    prot:tcp 139
    prot:tcp 445

Wann immer Sie jetzt die Schablone vpn_freunde benutzen, werden daraus Regeln für alle darin aufgeführten Protokolle und Ports erzeugt. PF_FORWARD_x='tmpl:vpn_freunde ACCEPT' etwa erstellt folgende FORWARD-Regeln:

    prot:tcp 22 ACCEPT
    prot:tcp 25 ACCEPT
    53 ACCEPT
    prot:udp 137-138 ACCEPT
    prot:tcp 139 ACCEPT
    prot:tcp 445 ACCEPT

3.10.4 Die Konfiguration des Paketfilters

Der Paketfilter wird im Wesentlichen durch vier Array-Variablen konfiguriert:

Für alle folgenden Ketten gilt die in PF_LOG_LEVEL vorgenommene Einstellung der Protokoll-Stufe, deren Inhalt auf einen der folgenden Werte gesetzt werden kann: debug, info, notice, warning, err, crit, alert, emerg.

3.10.4.1 Die INPUT-Kette

Über die INPUT-Kette wird konfiguriert, wer auf den Router zugreifen darf. Trifft keine der Regeln der INPUT-Kette zu, bestimmt die Standard-Aktion, was mit dem Paket passieren soll, und die Protokoll-Variable bestimmt, ob es bei einer Ablehnung ins System-Protokoll geschrieben werden soll.

Bei den verwendeten Parametern gibt es die folgenden Einschränkungen:

PF_INPUT_POLICY
Diese Variable beschreibt die Standard-Aktion, die angewandt wird, wenn keine der anderen Regeln zutrifft. Möglich sind:

PF_INPUT_ACCEPT_DEF
Steht diese Variable auf `yes', werden Standard-Regeln generiert, die für ein korrektes Funktionieren des Routers notwendig sind. Standardmäßig sollte man hier `yes' eintragen.

Möchte man das Verhalten komplett selbst definieren, kann man hier `no' eintragen, muss dann jedoch alle Regeln selbst definieren. Eine zum Standardverhalten äquivalente Konfiguration würde wie folgt aussehen (die Beschreibung der Liste für benutzerdefinierte Ketten erfolgt hier):

    PF_INPUT_ACCEPT_DEF='no'
    #
    # limit ICMP echo requests - use a separate chain
    #
    PF_USR_CHAIN_N='1'
    PF_USR_CHAIN_1_NAME='usr-in-icmp'
    PF_USR_CHAIN_1_RULE_N='2'
    PF_USR_CHAIN_1_RULE_1='prot:icmp:echo-request length:0-150 limit:1/second:5 ACCEPT'
    PF_USR_CHAIN_1_RULE_2='state:RELATED ACCEPT'

    PF_INPUT_N='4'
    PF_INPUT_1='prot:icmp usr-in-icmp'
    PF_INPUT_2='state:ESTABLISHED,RELATED ACCEPT'
    PF_INPUT_3='if:lo:any ACCEPT'
    PF_INPUT_4='state:NEW 127.0.0.1 DROP BIDIRECTIONAL'

Die erste Regel verzweigt zur ratenlimitierenden ``usr-in-icmp''-Kette. Die zweite Regel akzeptiert nur solche Pakete, die zu bestehenden Verbindungen gehören (also Paketen, die entweder den Zustand ESTABLISHED oder RELATED besitzen), und die dritte erlaubt lokale Kommunikation (if:lo:any ACCEPT). Die vierte filtert Pakete heraus, die behaupten, lokale Kommunikation zu sein, aber nicht bereits von der vorherigen Regel akzeptiert wurden.

Arbeitet man mit OpenVPN, muss man die Regeln noch ergänzen, um die von diesen Paketen verwendeteten Ketten einzubinden.

    PF_INPUT_N='5'
    ...
    PF_INPUT_5='ovpn-chain'

PF_INPUT_LOG
Definiert, ob abgelehnte Pakete vom Kernel protokolliert werden sollen. Dabei können die Meldungen durch Aktivierung von OPT_KLOGD über den syslog-Dämon entsprechend der Konfiguration ausgegeben werden.

PF_INPUT_LOG_LIMIT
Definiert, wie häufig Log-Einträge generiert werden. Die Häufigkeit wird analog zur Limit-Einschränkung als n/Zeiteinheit mit Bursts beschrieben, also z.B. 3/minute:5. Ist dieser Eintrag leer, wird der Standardwert 1/second:5 verwendet; enhält er none, wird keine Limitierung durchgeführt.

PF_INPUT_REJ_LIMIT PF_INPUT_UDP_REJ_LIMIT
Definiert, wie häufig bei einer Ablehnung eines hereinkommenden Paketes auch ein entsprechendes REJECT-Paket generiert wird. Die Häufigkeit wird analog zur Limit-Einschränkung als n/Zeiteinheit mit Bursts beschrieben, also z.B. 3/minute:5. Ist das Limit überschritten, wird das Paket einfach ignoriert (DROP). Ist dieser Eintrag leer, wird der Standardwert 1/second:5 verwendet; enhält er none, wird keine Limitierung durchgeführt.

PF_INPUT_ICMP_ECHO_REQ_LIMIT
Definiert, wie häufig auf eine ICMP-Echo-Anfrage reagiert werden soll. Die Häufigkeit wird analog zur Limit-Einschränkung als n/Zeitein-heit mit Bursts beschrieben, also z.B. /minute:5. Ist das Limit überschritten, wird das Paket einfach ignoriert (DROP). Ist dieser Eintrag leer, wird der Standardwert 1/second:5 verwendet; enhält er none, wird keine Limitierung durchgeführt.

PF_INPUT_ICMP_ECHO_REQ_SIZE
Definiert, wie groß eine empfangene ICMP-Echo-Anfrage sein darf (in Bytes). In dieser Angabe sind neben den ``Nutzdaten'' auch die Paket-Header mit zu berücksichtigen. Der Standard-Wert liegt bei 150 Bytes.

PF_INPUT_N PF_INPUT_x PF_INPUT_x_COMMENT
Liste der Regeln, die beschreiben, welche Pakete vom Router angenommen bzw. verworfen werden.

3.10.4.2 Die FORWARD-Kette

Über die FORWARD-Kette wird konfiguriert, welche Pakete vom Router weitergeleitet werden. Trifft keine der Regeln der FORWARD-Kette zu, bestimmt die Standard-Aktion, was mit dem Paket passieren soll,und die Protokoll-Variable bestimmt, ob es bei einer Ablehnung ins System-Protokoll geschrieben werden soll.

Bei den verwendeten Parametern gibt es die Einschränkung, dass nur ACCEPT, DROP und REJECT als Aktion angegeben werden können.

PF_FORWARD_POLICY
Diese Variable beschreibt die Standard-Aktion, die angewandt wird, wenn keine der anderen Regeln zutrifft. Möglich sind:

PF_FORWARD_ACCEPT_DEF
Bestimmt, ob der Router Pakete akzeptiert, die zu bestehenden Verbindungen gehören. Steht diese Variable auf `yes', generiert fli4l automatisch eine Regel, die Pakete mit dem entsprechenden Zustand akzeptiert:

'state:ESTABLISHED,RELATED ACCEPT',

weiterhin eine Regel, die Pakete mit unbekanntem Zustand verwirft:

'state:INVALID DROP'.

und schließlich eine Regel, die Pakete mit gefälschten IP-Adressen verwirft:

'state:NEW 127.0.0.1 DROP BIDIRECTIONAL'.

Zusätzlich generieren die anderen Subsysteme auch noch Standardregeln - eine Konfiguration ohne Standardregeln mit Portweiterleitung und OpenVPN würde mindestens folgende Regeln enthalten:

    PF_FORWARD_ACCEPT_DEF='no'
    PF_FORWARD_N='5'
    PF_FORWARD_1='state:ESTABLISHED,RELATED ACCEPT'
    PF_FORWARD_2='state:INVALID DROP'
    PF_FORWARD_3='state:NEW 127.0.0.1 DROP BIDIRECTIONAL'
    PF_FORWARD_4='pfwaccess-chain'
    PF_FORWARD_5='ovpn-chain'

PF_FORWARD_LOG
Definiert, ob abgelehnte Pakete vom Kernel protokolliert werden sollen. Dabei können die Meldungen durch Aktivierung von OPT_KLOGD über den syslog-Dämon entsprechend der Konfiguration ausgegeben werden.

PF_FORWARD_LOG_LIMIT
Definiert, wie häufig Log-Einträge generiert werden. Die Häufigkeit wird analog zur Limit-Einschränkung als n/Zeiteinheit mit Bursts beschrieben, also z.B. 3/minute:5. Ist dieser Eintrag leer, wird der Standardwert 1/second:5 verwendet; enhält er none, wird keine Limitierung durchgeführt.

PF_FORWARD_REJ_LIMIT PF_FORWARD_UDP_REJ_LIMIT
Definiert, wie häufig bei einer Ablehnung eines hereinkommenden Paketes auch ein entsprechendes REJECT-Paket generiert wird. Die Häufigkeit wird analog zur Limit-Einschränkung als n/Zeiteinheit mit Bursts beschrieben, also z.B. 3/minute:5. Ist das Limit überschritten, wird das Paket einfach ignoriert (DROP). Ist dieser Eintrag leer, wird der Standardwert 1/second:5 verwendet; enhält er none, wird keine Limitierung durchgeführt.

PF_FORWARD_N PF_FORWARD_x PF_FORWARD_x_COMMENT
Liste der Regeln, die beschreiben, welche Pakete vom Router weitergeleitet bzw. verworfen werden.

3.10.4.3 Die OUTPUT-Kette

Über die OUTPUT-Kette wird konfiguriert, worauf der Router selbst zugreifen darf. Trifft keine der Regeln der OUTPUT-Kette zu, bestimmt die Standard-Aktion, was mit dem Paket passieren soll, und die Protokoll-Variable bestimmt, ob es bei einer Ablehnung ins System-Protokoll geschrieben werden soll.

Bei den verwendeten Parametern gibt es die folgenden Einschränkungen:

PF_OUTPUT_POLICY
Diese Variable beschreibt die Standard-Aktion, die angewandt wird, wenn keine der anderen Regeln zutrifft. Möglich sind:

PF_OUTPUT_ACCEPT_DEF
Steht diese Variable auf `yes', werden Standard-Regeln generiert, die für ein korrektes Funktionieren des Routers notwendig sind. Standardmäßig sollte man hier `yes' eintragen.

Möchte man das Verhalten komplett selbst definieren, kann man hier `no' eintragen, muss dann jedoch alle Regeln selbst definieren. Eine zum Standardverhalten äquivalente Konfiguration würde wie folgt aussehen:

    PF_OUTPUT_ACCEPT_DEF='no'

    PF_OUTPUT_N='1'
    PF_OUTPUT_1='state:ESTABLISHED,RELATED ACCEPT'

Die erste (und einzige) Regel akzeptiert nur solche Pakete, die zu bestehenden Verbindungen gehören (also Paketen, die entweder den Zustand ESTABLISHED oder RELATED besitzen).

PF_OUTPUT_LOG
Definiert, ob abgelehnte Pakete vom Kernel protokolliert werden sollen. Dabei können die Meldungen durch Aktivierung von OPT_KLOGD über den syslog-Dämon entsprechend der Konfiguration ausgegeben werden.

PF_OUTPUT_LOG_LIMIT
Definiert, wie häufig Log-Einträge generiert werden. Die Häufigkeit wird analog zur Limit-Einschränkung als n/Zeiteinheit mit Bursts beschrieben, also z.B. 3/minute:5. Ist dieser Eintrag leer, wird der Standardwert 1/second:5 verwendet; enhält er none, wird keine Limitierung durchgeführt.

PF_OUTPUT_REJ_LIMIT PF_OUTPUT_UDP_REJ_LIMIT
Definiert, wie häufig bei einer Ablehnung eines hereinkommenden Paketes auch ein entsprechendes REJECT-Paket generiert wird. Die Häufigkeit wird analog zur Limit-Einschränkung als n/Zeiteinheit mit Bursts beschrieben, also z.B. 3/minute:5. Ist das Limit überschritten, wird das Paket einfach ignoriert (DROP). Ist dieser Eintrag leer, wird der Standardwert 1/second:5 verwendet; enhält er none, wird keine Limitierung durchgeführt.

PF_OUTPUT_N PF_OUTPUT_x PF_OUTPUT_x_COMMENT
Liste der Regeln, die beschreiben, welche Pakete vom Router versandt bzw. verworfen werden.


3.10.4.4 Benutzerdefinierte Listen

Aus verschiedenen Gründen besteht manchmal der Bedarf, eigene Ketten anzulegen und dort die Pakete genauer zu filtern. Diese Ketten kann man mittels PF_USR_CHAIN_% definieren und mit Regeln füllen. Die Namen der Ketten müssen dabei mit usr- beginnen und können nach ihrer Definition überall in der INPUT- oder FORWARD-Kette statt einer Aktion eingesetzt werden. Als Beispiel soll hier die bereits vorher verwendete ICMP-Filterkette dienen:

    PF_USR_CHAIN_N='1'
    #
    # create usr-in-icmp
    #
    PF_USR_CHAIN_1_NAME='usr-in-icmp'
    #
    # add rule to usr-in-icmp
    #
    PF_USR_CHAIN_1_RULE_N='2'
    PF_USR_CHAIN_1_RULE_1='prot:icmp:echo-request length:0-150 limit:1/second:5 ACCEPT'
    PF_USR_CHAIN_1_RULE_2='state:RELATED ACCEPT'
    #
    # use chain in PF_INPUT
    #
    PF_INPUT_2='prot:icmp usr-in-icmp'

PF_USR_CHAIN_N
Definiert die Anzahl der benutzerdefinierten Ketten.

PF_USR_CHAIN_x_NAME
Definiert den Namen der benutzerdefinierten Kette. Dieser muss mit usr- beginnen.

PF_USR_CHAIN_x_RULE_N
PF_USR_CHAIN_x_RULE_x
PF_USR_CHAIN_x_RULE_x_COMMENT
Hier werden die Regeln definiert, die in die benutzerdefinierte Kette eingefügt werden sollen. Es können alle Regeln verwendet werden, die auch in einer FORWARD-Kette verwendet werden könnten. Sollte keine Regel der benutzerdefinierten Kette zutreffen, wird zur Ausgangskette zurückgekehrt und mit der Regel nach der Verzweigung fortgefahren.

3.10.4.5 Die NAT-Ketten (Network Address Translation)

Pakete können vor und nach Routing-Entscheidungen noch manipuliert werden. Sie können zum Beispiel eine neue Zieladresse erhalten, um an einen anderen Rechner weitergeleitet zu werden (Portweiterleitung) oder eine andere Quelladresse erhalten, um das hinter dem Router liegende Netzwerk zu maskieren. Maskieren nutzt man beispielsweise, um ein privates Netz über eine öffentliche IP ins Netz zu bringen oder in einem DMZ-Setup die Struktur des lokalen Netzes vor den Rechnern in der DMZ zu verbergen.

Die Konfiguration erfolgt über zwei Ketten, die PREROUTING- und die POSTROUTING-Kette. Über die POSTROUTING-Kette wird konfiguriert, welche Pakete vom Router maskiert werden. Trifft keine der Regeln der POSTROUTING-Kette zu, werden die Pakete unmaskiert weitergeleitet.

Beim Maskieren gibt es zwei Varianten: eine für Netzwerk-Schnittstellen, die bei der Einwahl erst eine IP-Adresse zugewiesen bekommen (MASQUERADE) und eine für Netzwerk-Schnittstellen mit statischer IP-Adresse (SNAT). SNAT erwartet dabei zusätzlich die IP-Adresse, die im Paket als Quelle eingetragen werden soll. Diese kann als

angegeben werden.

Sowohl bei SNAT als auch bei MASQUERADE kann schließlich ein Port bzw. Portbereich angegeben werden, auf den der Quellport abgebildet werden soll. Normalerweise ist das nicht nötig, da der Kern die Ports allein auswählen kann. Es gibt aber Anwendungen, die verlangen, dass der Quellport unverändert bleibt (und somit ein 1:1-NAT erfordern) oder die ein PAT (Port Address Translation) oder NAPT (Network Address and Port Translation) verbieten. Der Portbereich wird einfach hinten angehängt, z.B. so: SNAT:IP_NET_1_IPADDR:4000-8000.

Bei der POSTROUTING-Kette können nur ACCEPT, SNAT, NETMAP und MASQUERADE als Aktionen verwendet werden.

PF_POSTROUTING_N PF_POSTROUTING_x PF_POSTROUTING_x_COMMENT

Eine Liste der Regeln, die beschreiben, welche Pakete vom Router maskiert werden (bzw. unmaskiert weitergeleitet werden). Will man Pakete vom Maskieren ausklammern, kann man eine ACCEPT-Regel für die auszuklammernden Pakete der MASQUERADE-Regel voranstellen.

Über die PREROUTING-Kette wird konfiguriert, welche Pakete an einen anderen Rechner weitergeleitet werden sollen. Trifft keine der Regeln der PREROUTING-Kette zu, werden die Pakete unverändert weiterbehandelt. Die Aktion DNAT erwartet dabei die IP-Adresse, die im Paket als Ziel eingetragen werden soll. Diese kann als

angegeben werden.

Schließlich kann noch ein Port bzw. Portbereich angegeben werden, auf den der Zielport abgebildet werden soll. Das ist aber nur nötig, wenn der Port geändert werden soll. Der Port bzw. Portbereich wird einfach hinten angehängt, z.B. so: DNAT:@server:21.

REDIRECT verhält sich wie DNAT, nur dass die Ziel-IP-Adresse immer auf die (primäre) IP-Adresse der Schnittstelle, auf der das Paket hereinkam, gesetzt wird und damit das Paket lokal zugestellt wird. Dies wird z.B. für transparente Proxys benötigt, siehe OPT_TRANSPROXY.

Will man eine Portweiterleitung auf Schnittstellen mit dynamischen Adressen machen, weiß man zum Zeitpunkt der Konfiguration noch nicht, an welche IP die Pakete gerichtet sein werden. Daher kann man in der PREROUTING-Kette dynamic als Platzhalter für die später zugewiesene IP verwenden, etwa wie folgt:

    'dynamic:80  DNAT:1.2.3.4'           # leite http-Pakete an die
                                         # IP-Adresse 1.2.3.4 weiter
    'prot:gre any dynamic DNAT:1.2.3.4'  # leite gre-Pakete (Teil des PPTP-
                                         # Protokolls) an die IP-Adresse
                                         # 1.2.3.4 weiter

Bei der PREROUTING-Kette können nur ACCEPT, DNAT, NETMAP und REDIRECT als Aktionen verwendet werden.

Für weitere Beispiele zur Portweiterleitung siehe den nächsten Abschnitt.

PF_PREROUTING_N PF_PREROUTING_x PF_PREROUTING_x_COMMENT

Eine Liste der Regeln, die beschreiben, welche Pakete vom Router an ein anderes Ziel weitergeleitet werden sollen.

3.10.5 Beispiele

Im Folgenden sind einige Beispiele für die Paketfilter-Konfiguration angegeben.

3.10.5.1 Die fli4l-Standardkonfiguration

Die fli4l-Standardkonfiguration der Distribution sieht für die INPUT-Kette wie folgt aus:

    PF_INPUT_POLICY='REJECT'
    PF_INPUT_ACCEPT_DEF='yes'
    PF_INPUT_LOG='no'
    PF_INPUT_N='1'
    PF_INPUT_1='IP_NET_1 ACCEPT'

Damit erreichen wir, dass

Für die FORWARD-Kette sieht das so ähnlich aus: Nur Pakete unseres lokalen Netzes und Pakete, die zu Verbindungen gehören, die von Rechnern im lokalen Netz aufgebaut wurden, sollen weitergeleitet werden. Des Weiteren werden NetBIOS- und CIFS-Pakete verworfen.

    PF_FORWARD_POLICY='REJECT'
    PF_FORWARD_ACCEPT_DEF='yes'
    PF_FORWARD_LOG='no'
    PF_FORWARD_N='2'
    PF_FORWARD_1='tmpl:samba DROP'
    PF_FORWARD_2='IP_NET_1 ACCEPT'

Was man hier gut sieht, ist die Abhängigkeit von der Reihenfolge der Regeln: Zuerst werden NetBIOS-Pakete verworfen, und danach werden die Pakete des lokalen Netzes akzeptiert.

Nun kann das lokale Netz mit dem Router kommunizieren, seine Pakete werden weitergeleitet, es fehlt nur noch das Maskieren, welches für den Zugriff eines privaten Netzwerkes auf das Internet notwendig ist:

    PF_POSTROUTING_N='1'
    PF_POSTROUTING_1='IP_NET_1 MASQUERADE'

3.10.5.2 Trusted Nets

Wollen wir lokal mehrere Subnetze haben, die frei und unmaskiert miteinander kommunizieren können, müssen wir dafür sorgen, dass Pakete zwischen diesen Subnetzen nicht verworfen und auch nicht maskiert werden. Dazu fügen wir einfach eine Regel hinzu oder modifizieren die vorhandene.

Angenommen, wir haben einen DSL-Zugang über PPPoE, und die beiden Subnetze sind IP_NET_1 (192.168.6.0/24) und IP_NET_2 (192.168.7.0/24). Dann würde die Konfiguration wie folgt aussehen:

    PF_FORWARD_POLICY='REJECT'
    PF_FORWARD_ACCEPT_DEF='yes'
    PF_FORWARD_LOG='no'
    PF_FORWARD_N='4'
    PF_FORWARD_1='IP_NET_1 IP_NET_2 ACCEPT BIDIRECTIONAL'
    PF_FORWARD_2='tmpl:samba DROP'
    PF_FORWARD_3='IP_NET_1 ACCEPT'
    PF_FORWARD_4='IP_NET_2 ACCEPT'

    PF_POSTROUTING_N='3'
    PF_POSTROUTING_1='IP_NET_1 IP_NET_2 ACCEPT BIDIRECTIONAL'
    PF_POSTROUTING_2='IP_NET_1 MASQUERADE'
    PF_POSTROUTING_3='IP_NET_2 MASQUERADE'

Regel eins sorgt jetzt dafür, dass Pakete zwichen den beiden Subnetzen ohne weitere Prüfung weitergeleitet werden. Die Regeln drei und vier sorgen dafür, dass beide Subnetze auch ins Internet kommen. Die erste Regel der POSTROUTING-Kette sorgt dafür, dass die Kommunikation zwischen den Subnetzen unmaskiert erfolgt.

Alternativ könnten wir auch sagen, dass nur Pakete, die über die pppoe-Schnittstelle hinausgehen, maskiert werden sollen:

    PF_POSTROUTING_N='1'
    PF_POSTROUTING_1='if:any:pppoe MASQUERADE'

Genauso hätte man die Filterung der Ports auch auf die pppoe-Schnittstelle beschränken und die beiden Subnetze zu einem zusammenfassen können, das würde dann wie folgt aussehen:

    PF_FORWARD_POLICY='REJECT'
    PF_FORWARD_ACCEPT_DEF='yes'
    PF_FORWARD_LOG='no'
    PF_FORWARD_N='2'
    PF_FORWARD_1='if:any:pppoe tmpl:samba DROP'
    PF_FORWARD_2='192.168.6.0/23 ACCEPT'

    PF_POSTROUTING_N='1'
    PF_POSTROUTING_1='if:any:pppoe MASQUERADE'

Pakete, die über die pppoe-Schnittstelle hinausgehen und die an die udp-Ports 137-138 oder an die tcp-Ports 139 und 445 adressiert sind, werden verworfen (Regel 1), alle anderen Pakete, die aus dem Subnetz 192.168.6.0/23 kommen, werden weitergeleitet (Regel 2).

3.10.5.3 Route Network

Fügen wir dem Ganzen noch ein Netzwerk 10.0.0.0/24 hinzu (z.B. ein Dial-In-Netzwerk), mit dem wir unmaskiert kommunizieren wollen, wobei Pakete an die udp-Ports 137-138 sowie an die tcp-Ports 139 und 445 verworfen werden sollen, dann würde das wie folgt aussehen:

    PF_FORWARD_POLICY='REJECT'
    PF_FORWARD_ACCEPT_DEF='yes'
    PF_FORWARD_LOG='no'
    PF_FORWARD_N='4'
    PF_FORWARD_1='IP_NET_1 IP_NET_2 ACCEPT BIDIRECTIONAL'
    PF_FORWARD_2='tmpl:samba DROP'
    PF_FORWARD_3='192.168.6.0/23 ACCEPT'
    PF_FORWARD_4='10.0.0.0/24 ACCEPT'

    PF_POSTROUTING_N='2'
    PF_POSTROUTING_1='10.0.0.0/24 ACCEPT BIDIRECTIONAL'
    PF_POSTROUTING_2='192.168.6.0/23 MASQUERADE'

Alternativ ginge auch:

    PF_POSTROUTING_N='1'
    PF_POSTROUTING_1='if:any:pppoe MASQUERADE'

Diese Regel besagt, dass nur Pakete, die über die pppoe-Schnittstelle hinausgehen, maskiert werden.

3.10.5.4 Blacklists, Whitelists

Blacklists (ein Rechner in dieser Liste darf etwas nicht) und Whitelists (ein Rechner in dieser Liste darf etwas) werden prinzipiell ähnlich umgesetzt. Es werden Regeln geschrieben, die am Anfang sehr speziell sind und nach hinten immer allgemeiner werden. Bei einer Blacklist stehen am Anfang Regeln, die etwas verbieten und am Ende Regeln, die allen bisher nicht erwähnten etwas erlauben. Bei einer Whitelist ist es genau umgekehrt.

Beispiel 1: Alle Rechner im Subnetz 192.168.6.0/24 außer Rechner 12 dürfen ins Internet, solange sie nicht mit den CIFS Ports 137-138 (udp), 139 und 445 (tcp) kommunizieren wollen:

    PF_FORWARD_POLICY='REJECT'
    PF_FORWARD_ACCEPT_DEF='yes'
    PF_FORWARD_LOG='no'
    PF_FORWARD_N='3'
    PF_FORWARD_1='192.168.6.12 DROP'
    PF_FORWARD_2='tmpl:samba DROP'
    PF_FORWARD_3='192.168.6.0/23 ACCEPT'

    PF_POSTROUTING_N='1'
    PF_POSTROUTING_2='192.168.6.0/24 MASQUERADE'

Beispiel 2: Nur Rechner 12 darf ins Internet (aber nicht an die o.g. Ports ...), alle anderen dürfen nur lokal mit einem anderen Subnetz kommunizieren:

    PF_FORWARD_POLICY='REJECT'
    PF_FORWARD_ACCEPT_DEF='yes'
    PF_FORWARD_LOG='no'
    PF_FORWARD_N='3'
    PF_FORWARD_1='192.168.6.0/24 192.168.7.0/24 ACCEPT BIDIRECTIONAL'
    PF_FORWARD_2='tmpl:samba DROP'
    PF_FORWARD_3='192.168.6.12 ACCEPT'

    PF_POSTROUTING_N='1'
    PF_POSTROUTING_1='if:any:pppoe MASQUERADE'

3.10.6 Standardkonfigurationen

3.10.6.1 Einfacher maskierender Router mit einem Netz dahinter

#
# Zugriff auf den Router
#
PF_INPUT_POLICY='REJECT'
PF_INPUT_ACCEPT_DEF='yes'
PF_INPUT_LOG='no'
PF_INPUT_N='1'
PF_INPUT_1='IP_NET_1 ACCEPT'   # alle Hosts im lokalen Netz dürfen
                               # auf den Router zugreifen

#
# Zugriff auf das ``Internet''
#
PF_FORWARD_POLICY='REJECT'
PF_FORWARD_ACCEPT_DEF='yes'
PF_FORWARD_LOG='no'

PF_FORWARD_N='2'
PF_FORWARD_1='tmpl:samba DROP' # Samba-Pakete, die das Netz
                               # verlassen wollen, werden verworfen
PF_FORWARD_2='IP_NET_1 ACCEPT' # alle anderen Pakete dürfen das
                               # lokale Netz verlassen

#
# Maskieren des lokalen Netzes
#
PF_POSTROUTING_N='1'
PF_POSTROUTING_1='IP_NET_1 MASQUERADE'  # maskiere Pakete, die das Subnetz
                                        # verlassen

3.10.6.2 Einfacher maskierender Router mit zwei Netzen dahinter

#
# Zugriff auf den Router
#
PF_INPUT_POLICY='REJECT'
PF_INPUT_ACCEPT_DEF='yes'
PF_INPUT_LOG='no'
PF_INPUT_N='2'
PF_INPUT_1='IP_NET_1 ACCEPT'   # alle Hosts im lokalen Netz dürfen
                               # auf den Router zugreifen
PF_INPUT_2='IP_NET_2 ACCEPT'   # alle Hosts im lokalen Netz dürfen
                               # auf den Router zugreifen

#
# Zugriff auf das ``Internet''
#
PF_FORWARD_POLICY='REJECT'
PF_FORWARD_ACCEPT_DEF='yes'
PF_FORWARD_LOG='no'

#
# Freie Kommunikation zwischen den Netzen
#
PF_FORWARD_N='4'
PF_FORWARD_1='IP_NET_1 IP_NET_2 ACCEPT BIDIRECTIONAL'
PF_FORWARD_2='tmpl:samba DROP' # Samba-Pakete, die das Netz
                               # verlassen wollen, werden verworfen
PF_FORWARD_3='IP_NET_1 ACCEPT' # alle anderen Pakete dürfen das
                               # lokale Netz verlassen
PF_FORWARD_4='IP_NET_2 ACCEPT' # alle anderen Pakete dürfen das
                               # lokale Netz verlassen

#
# Maskieren der lokalen Netze, unmaskierte Kommunikation zwischen den
# Netzen
#
PF_POSTROUTING_N='3'
PF_POSTROUTING_1'IP_NET_1 IP_NET_2 ACCEPT BIDIRECTIONAL'
PF_POSTROUTING_2='IP_NET_1 MASQUERADE'  # maskiere Pakete, die das Subnetz
                                        # verlassen
PF_POSTROUTING_3='IP_NET_2 MASQUERADE'  # maskiere Pakete, die das Subnetz
                                        # verlassen

3.10.6.3 Maskierender DSL-Router mit zwei Netzen dahinter und SSH/HTTP-Zugriff aus dem Internet

#
# Zugriff auf den Router
#
PF_INPUT_POLICY='REJECT'
PF_INPUT_ACCEPT_DEF='yes'
PF_INPUT_LOG='no'
PF_INPUT_N='4'
PF_INPUT_1='IP_NET_1 ACCEPT'   # alle Hosts im lokalen Netz dürfen
                               # auf den Router zugreifen
PF_INPUT_2='IP_NET_2 ACCEPT'   # alle Hosts im lokalen Netz dürfen
                               # auf den Router zugreifen
PF_INPUT_3='tmpl:ssh ACCEPT'   # gestatte Zugriff auf SSH-Dienst
                               # von überall her
PF_INPUT_4='tmpl:http 1.2.3.4/24 ACCEPT'  # gestatte Rechner aus
                               # einem bestimmten Subnetz Zugriff
                               # auf HTTP-Dienst


#
# Zugriff auf das ``Internet''
#
PF_FORWARD_POLICY='REJECT'
PF_FORWARD_ACCEPT_DEF='yes'
PF_FORWARD_LOG='no'

#
# Keine Kommunikation zwischen den Netzen, beide Netze dürfen ins
# Internet, Samba-Pakete werden verworfen
#
PF_FORWARD_N='2'
PF_FORWARD_1='tmpl:samba if:any:pppoe DROP' # Samba-Pakete, die das Netz
                               # verlassen wollen, werden verworfen
PF_FORWARD_2='if:any:pppoe ACCEPT' # alle anderen Pakete dürfen das
                               # lokale Netz verlassen

#
# Maskieren der lokalen Netze, unmaskierte Kommunikation zwischen den
# Netzen
#
PF_POSTROUTING_N='1'
PF_POSTROUTING_1='if:any:pppoe MASQUERADE'  # maskiere Pakete, die das Subnetz
                                            # verlassen

3.10.6.4 Portweiterleitung

Portweiterleitungen lassen sich mit den PREROUTING-Regeln wie folgt umsetzen (TARGET bezeichnet die ursprüngliche Zieladresse (optional) und den ursprünglichen Zielport, NEW_TARGET bezeichnet die neue Zieladresse und den neuen Zielport (optional), PROTOCOL bezeichnet das jeweilige Protokoll):

    TARGET='<port>'
    NEW_TARGET='<ip>'
    PROTOCOL='<proto>'
    PF_PREROUTING_x='prot:<proto> dynamic:<port> DNAT:<ip>'

    TARGET='<port1>-<port2>'
    NEW_TARGET='<ip>'
    PROTOCOL='<proto>'
    PF_PREROUTING_x='prot:<proto> dynamic:<port1>-<port2> DNAT:<ip>'

    TARGET='<ip>:<port-a>'
    NEW_TARGET='<ip>:<port-b>'
    PROTOCOL='<proto>'
    PF_PREROUTING_x='prot:<proto> any <ip>:<port-a> DNAT:<ip>:<port-b>'

3.10.6.5 Transparenter Proxy

Will man bestimmte Zugriffe auf das Internet nur über einen lokalen Proxy zulassen, kann man das mit Hilfe der PREROUTING- und POSTROUTING-Ketten erzwingen, ohne dass der Client davon etwas merkt. Prinzipiell sind dazu drei Schritte notwendig:

  1. Anfragen an den HTTP-Port, die nicht vom Proxy kommen, an den Proxy umleiten (PREROUTING).
  2. Die umgeleiteten Pakete so verändern, dass der Proxy denkt, sie kommen vom Router, so dass er sie wieder dorthin zurückschickt (POSTROUTING).
  3. Die Pakete durch die FORWARD-Kette durchlassen, sofern ein Eintrag à la

    PF_FORWARD_x='IP_NET_1 ACCEPT'
    

    nicht existiert (FORWARD).

Beispiel 1: Angenommen, wir haben nur ein Netz IP_NET_1, in dem auf einem Rechner namens proxy ein Squid-Proxy läuft, und wollen den gesamten http-Datenverkehr über ihn leiten. Squid lauscht auf Port 3128. Der Einfachheit halber beziehen wir uns via @proxy auf den eingetragenen Host aus HOST_1_NAME='proxy' (vgl. Domainkonfiguration).

Das Ganze würde wie folgt aussehen:

...
  PF_PREROUTING_x='@proxy ACCEPT'
      # Pakete vom Proxy sollen nicht umgeleitet werden

  PF_PREROUTING_x='prot:tcp IP_NET_1 80 DNAT:@proxy:3128'
      # HTTP-Pakete aus IP_NET_1 mit einem beliebigen Ziel werden
      # umgeleitet nach @proxy, Port 3128

  PF_POSTROUTING_x='any @proxy:3128 SNAT:IP_NET_1_IPADDR'
      # alle Pakete an den Proxy-Port 3128 so umschreiben, als wären sie
      # vom fli4l (IP_NET_1_IPADDR)

  PF_FORWARD_x='prot:tcp @proxy 80 ACCEPT'
      # HTTP-Pakete vom Proxy durch die FORWARD-Kette durchlassen (wenn nötig)
...

Gibt es mehrere Netze oder potentielle Konflikte mit anderen Portweiterleitungen (die ja auch nichts anderes sind als DNAT-Regeln), muss man die Regeln vielleicht noch etwas enger formulieren.

Beispiel 2: Unser Proxy namens proxy steht in IP_NET_1, lauscht auf Port 3128 und soll nur für Clients aus IP_NET_1 wirksam werden. IP_NET_1 ist über IP_NET_1_DEV erreichbar. Pakete aus weiteren Netzen sollen nicht berücksichtigt werden.

...
  PF_PREROUTING_x='if:IP_NET_1_DEV:any !@proxy 80 DNAT:@proxy:3128'
      # Anfragen an den HTTP-Port, die nicht vom Proxy, aber über eine
      # interne Schnittstelle (IP_NET_1_DEV) kommen, an den Proxy-Port umleiten.
      # An dieser Stelle ist es wichtig, mit if:IP_NET_1_DEV:any zu
      # überprüfen, ob die Pakete von innen kommen, da sonst auch Pakete von
      # außen umgeleitet würden (Sicherheitslücke!).

  PF_POSTROUTING_x='prot:tcp IP_NET_1 @proxy:3128 SNAT:IP_NET_1_IPADDR'
      # HTTP-Pakete die aus IP_NET_1 stammen und für den Proxy-Port 3128
      # gedacht sind, so umschreiben, als wären sie vom fli4l (IP_NET_1_IPADDR)

  PF_FORWARD_x='prot:tcp @proxy 80 ACCEPT'
      # HTTP-Pakete vom Proxy durch die FORWARD-Kette durchlassen (wenn nötig)
...

Beispiel 3: Um sich das Leben etwas zu erleichtern und die Regeln kürzer zu gestalten, kann man auch Templates einsetzen (vgl. Templates im Paketfilter). Zweckmäßig ist an dieser Stelle das tmpl:http, das in prot:tcp any any:80 übersetzt wird. So wird z.B. aus tmpl:http IP_NET_1 DNAT:@proxy:3128 dann prot:tcp IP_NET_1 80 DNAT:@proxy:3128.

Sowohl IP_NET_1 als auch IP_NET_2 sollen transparent über den Proxy umgeleitet werden. Damit ließe sich vereinfacht auch schreiben:

...
  PF_PREROUTING_x='tmpl:http @proxy   ACCEPT'
      # HTTP-Pakete vom Proxy sollen nicht umgeleitet werden

  PF_PREROUTING_x='tmpl:http IP_NET_1 DNAT:@proxy:3128'
      # HTTP-Pakete aus IP_NET_1 sollen umgeleitet werden

  PF_PREROUTING_x='tmpl:http IP_NET_2 DNAT:@proxy:3128'
      # HTTP-Pakete aus IP_NET_2 sollen umgeleitet werden

  PF_POSTROUTING_x='IP_NET_1 @proxy:3128 SNAT:IP_NET_1_IPADDR'
  PF_POSTROUTING_x='IP_NET_2 @proxy:3128 SNAT:IP_NET_2_IPADDR'

  PF_FORWARD_x='tmpl:http @proxy ACCEPT'
...

Und so ließe sich das endlos fortsetzen ...


3.10.7 DMZ - Demilitarisierte Zone

fli4l gestattet auch den Aufbau einer DMZ. Hier sei erstmal auf das Wiki verwiesen. https://ssl.nettworks.org/wiki


3.10.8 Conntrack-Helfer

Die Verwendung von IP-Masquerading hat zwar den Vorteil, dass mehrere Rechner im LAN über eine einzige offizielle IP-Adresse geroutet werden kann, es gibt aber auch Nachteile, die man in Kauf nehmen muss.

Ein großes Problem ist zum Beispiel, dass kein Rechner von außen von sich aus eine Verbindung zu einem Rechner aufnehmen kann. Das ist zwar aus Sicherheitsgründen eigentlich durchaus erwünscht, aber bestimmte Protokolle funktionieren nicht mehr, weil sie einen Verbindungsaufbau von außen einfach erfordern.

Ein klassisches Beispiel ist FTP. Neben dem Kommunikationskanal, auf dem Befehle und Antworten ausgetauscht werden, wird ein weiterer Kanal (in Form eines IP-Ports) verwendet, um die eigentlichen Nutzdaten zu versenden. fli4l verwendet dafür bestimmte Conntrack-Helfer, um solche zusätzlichen Ports, die verwendet werden, ad hoc dann freizuschalten und an den internen Rechner weiterzuleiten, wenn sie benötigt werden. Dabei ``horcht'' der Conntrack-Helfer in den Datenstrom, um zu erkennen, wann ein zusätzlicher Port benötigt wird.

Typische Anwendungen für Conntrack-Helfer sind Chat-Protokolle und Spiele im Internet.

Ein solcher Conntrack-Helfer wird über Regeln in zwei speziellen Arrays aktiviert. Das Array PF_PREROUTING_CT_% enthält Helfer-Zuordnungen zu Paketen, die von außen kommen, das Array PF_OUTPUT_CT_% enthält Helfer-Zuordnungen zu Paketen, die auf dem Router generiert werden. Einige Beispiele aus der Praxis sollen dies verdeutlichen.

Beispiel 1: Soll aktives FTP aus dem LAN erlaubt werden, ist das aus der Sicht des Routers eine Verbindung von außerhalb, somit muss ein Eintrag in PF_PREROUTING_CT_% vorgenommen werden:

    PF_PREROUTING_CT_N='1'
    PF_PREROUTING_CT_1='tmpl:ftp IP_NET_1 HELPER:ftp'

Damit wird für alle TCP-Verbindungen aus dem lokalen Netz (IP_NET_1) zu irgendeiner anderen Adresse an Port 21 (dies ist der ftp-Port) das ftp-Hilfsmodul geladen. Dieses Modul erlaubt dann im Laufe der Verbindung, dass der FTP-Server zurück zum Client eine Datenverbindung aufbauen kann, indem temporär ein ``Loch'' in der Firewall aufgemacht wird.

Beispiel 2: Soll passives FTP für einen FTP-Server im LAN ermöglicht werden (dabei wird die Datenverbindung von außen nach innen aufgebaut, so dass auch hier kurzfristig ein Loch in der Firewall geöffnet werden muss), ist dies ebenfalls aus der Sicht des Router eine Verbindung von außerhalb des Routers. Hier sieht die Regel folgendermaßen aus:

    PF_PREROUTING_CT_N='1'
    PF_PREROUTING_CT_1='tmpl:ftp any dynamic HELPER:ftp'

Mit dieser Regel wird ausgedrückt, dass alle FTP-Verbindungen, die an die dynamische Adresse des Routers gesandt werden, mit dem FTP-Conntrack-Helfer assoziiert werden. Hier wurde dynamic verwendet, da angenommen wird, dass der Router für die Einwahl ins Internet verantwortlich ist und somit eine externe IP-Adresse besitzt. Falls der Router eine Einwahl via DSL durchführt, kann man die Regel auch so schreiben:

    PF_PREROUTING_CT_N='1'
    PF_PREROUTING_CT_1='tmpl:ftp if:pppoe:any HELPER:ftp'

Mit dieser Regel wird ausgedrückt, dass alle FTP-Verbindungen, die von der DSL-Schnittstelle (pppoe) kommen, mit dem FTP-Conntrack-Helfer assoziiert werden.

Falls der Router sich nicht einwählt, sondern z.B. hinter einem anderen Router (Fritz!Box, Kabelmodem etc.) hängt, so kann die folgende Regel verwendet werden:

    PF_PREROUTING_CT_N='1'
    PF_PREROUTING_CT_1='tmpl:ftp if:IP_NET_2_DEV:any HELPER:ftp'

Dabei wird im Beispiel angenommen, dass die Verbindung zum anderen Router über die Schnittstelle durchgeführt wird, die dem zweiten Subnetz zugeordnet ist (IP_NET_2_DEV).

Zu beachten ist, dass natürlich zusätzlich eine entsprechende Konfiguration der FORWARD-Kette nötig ist, um die FTP-Pakete auch tatsächlich weiterzuleiten. Eine typische Regel wäre etwa

    PF_PREROUTING_1='tmpl:ftp any dynamic DNAT:@ftpserver'

wobei angenommen wird, dass der Host, auf dem das FTP-Serverprogramm läuft, den Namen ftpserver hat.

Beispiel 3: Schließlich muss auch, wenn man vom fli4l direkt aktives FTP benutzen möchte (etwa mit Hilfe des ftp-Programms aus dem tools-Paket), die Firewall dafür vorbereitet werden, diesmal in der OUTPUT-Kette, die mit Hilfe des Arrays PF_OUTPUT_CT_% konfiguriert wird:

    PF_OUTPUT_CT_N='1'
    PF_OUTPUT_CT_1='tmpl:ftp HELPER:ftp'

Diese Regel ist jedoch unnötig, falls FTP_PF_ENABLE_ACTIVE='yes' benutzt wird - siehe hierzu die Dokumentation des ftp-OPTs im tools-Paket.

Es folgt eine Übersicht über die existierenden Conntrack-Helfer:

Table 3.9: Verfügbare Conntrack-Helfer im Paketfilter
Helfer Erläuterung
   
ftp File Transfer Protocol
h323 H.323 (Voice over IP)
irc Internet Relay Chat
pptp PPTP Masquerading (Mit diesem Modul lässt sich mehr als ein PPTP-Client gleichzeitig hinter einem fli4l-Router betreiben.)
sip Session Initiation Protocol
sane SANE Network Procotol
snmp Simple Network Management Protocol
tftp Trivial File Transfer Protocol
 

Es folgt eine Übersicht der zu konfigurierenden Variablen:

PF_PREROUTING_CT_ACCEPT_DEF
Steht diese Variable auf `yes', werden Standard-Regeln generiert, die für ein korrektes Funktionieren des Routers notwendig sind. Standardmäßig sollte man hier `yes' eintragen.

PF_PREROUTING_CT_N PF_PREROUTING_CT_x PF_PREROUTING_CT_x_COMMENT
Liste der Regeln, die beschreiben, welche eingehenden Pakete vom Router mit Conntrack-Helfern verbunden werden.

PF_OUTPUT_CT_ACCEPT_DEF
Steht diese Variable auf `yes', werden Standard-Regeln generiert, die für ein korrektes Funktionieren des Routers notwendig sind. Standardmäßig sollte man hier `yes' eintragen.

PF_OUTPUT_CT_N PF_OUTPUT_CT_x PF_OUTPUT_CT_x_COMMENT

Liste der Regeln, die beschreiben, welche auf dem Router generierten Pakete vom Router mit Conntrack-Helfern verbunden werden.



Footnotes

... Ports.3.2
Ein Port ist nur bei TCP- und UDP-Paketen vorhanden.
... sein:3.3
siehe http://www.sns.ias.edu/~jns/files/iptables_talk/x38.htm für eine genauere Beschreibung der Zustände
© 2001-2020 Das fli4l-Team - February 2, 2020