[Zurück: Firewal-Redundanz mit CARP und pfsync] [Inhalt]
[ COMP1 ] [ COMP3 ]
| |
---+------+-----+------- xl0 [ OpenBSD ] fxp0 -------- ( Internet )
|
[ COMP2 ]
In diesem internen Netzwerk befinden sich einige Computer. Das Diagramm zeigt drei, aber die tatsächliche Anzahl ist unbedeutend. Diese Computer sind reguläre Arbeitsplätze, die fürs Websurfen, E-Mail, Chatten etc. verwendet werden. COMP3 ist eine Ausnahme, da er als kleiner Webserver läuft. Das interne Netzwerk verwendet den Netzwerkblock 192.168.0.0/255.255.255.0.
Die OpenBSD-Firewall ist ein Celeron 300 mit zwei Netzwerkkarten: eine 3com 3c509B (xl0) und eine Intel EtherExpress Pro/100 (fxp0). Die Firewall hat eine Kabelverbindung zum Internet und verwendet NAT, um diese Verbindung mit dem internen Netzwerk zu teilen. Die IP-Adresse des externen Interfaces wird vom Internetprovider dynamisch zugewiesen.
ext_if="fxp0"
int_if="xl0"
tcp_services="{ 22, 113 }"
icmp_types="echoreq"
comp3="192.168.0.3"
Die ersten beiden Zeilen definieren die Netzwerkinterfaces, auf denen gefiltert wird. Da wir sie hier definieren, können wir den Regelsatz bei einer Hardwareumstellung so belassen wie er ist und müssen lediglich diese zwei Zeilen abändern. Die dritte und vierte Zeile listen die TCP-Portnummern der Dienste auf, die dem Internet gegenüber offengelegt werden (SSH und ident/auth) und den ICMP-Pakettyp, dem erlaubt wird, die Firewallmaschine zu erreichen. Zum Schluss definiert die letzte Zeile die IP-Adresse von COMP3.
Hinweis: Wenn die Internetverbindung PPPoE benötigt, werden Filter und NAT auf dem tun0-Interface stattfinden und nicht auf fxp0.
set block-policy return
set loginterface $ext_if
Jedes Unix-System hat ein sogenanntes Loopbackinterface. Hierbei handelt es sich um ein virtuelles Netzwerkinterface, das von Applikationen genutzt wird, um mit anderen auf dem gleichen System zu kommunizieren. Unter OpenBSD ist das Loopbackinterface lo(4). Es ist allgemein gute Praxis, jegliches Filtern auf den Loopbackinterfaces zu unterbinden. Die Verwendung von set skip bewerkstelligt dies.
set skip on loBeachte, dass wir die gesamte Interfacegruppe lo überspringen. Auf diese Weise können wir später noch Loopbackinterfaces hinzufügen, ohne dass wir uns Gedanken darüber machen müssten, diesen Teil unseres Regelsatzes anzupassen.
scrub in
nat on $ext_if from !($ext_if) to any -> ($ext_if)
»!($ext_if)« könnte in diesem Fall ganz einfach gegen »$int_if« ausgetauscht werden, doch wenn du weitere interne Interfaces hinzufügst, müsstest du ebenfalls zusätzliche NAT-Regeln einfügen, wobei mit dieser Struktur NAT sofort auf allen geschützten Interfaces funktioniert.
Da die IP-Adresse des externen Interfaces dynamisch zugewiesen wird, werden Klammern um das Übersetzungsinterface herum gesetzt. Auf diese Weise wird PF bemerken, wenn sich die Adresse ändert.
Wir wollen ebenfalls, dass der FTP-Proxy funktioniert. Das erreichen wir dadurch, indem wir ebenfalls den NAT-Anker> einbinden:
nat-anchor "ftp-proxy/*"
rdr-anchor "ftp-proxy/*"
rdr on $int_if proto tcp from any to any port 21 -> 127.0.0.1 port 8021
Bedenke, dass diese Regel nur FTP-Verbindungen auf Port 21 erfassen wird. Wenn sich Benutzer auf regulärer Basis mit FTP-Servern auf anderen Ports verbinden, sollte eine Liste verwendet werden, die die Zielports angibt - zum Beispiel: from any to any port { 21, 2121 }.
Die letzte Umleitungsregel erfasst alle Versuche von Personen im Internet, die auf den TCP-Port 80 der Firewall verbinden wollen. Berechtigte Versuche, diesen Port zu erreichen, werden von Benutzern sein, die versuchen, den Webserver vom Netzwerk zu erreichen. Dieser Verbindungsversuch muss auf COMP3 weitergeleitet werden:
rdr on $ext_if proto tcp from any to any port 80 -> $comp3
block in
Zu diesem Zeitpunkt wird der gesamte Verkehr, der in ein Interface gelangen will, abgeblockt - sogar vom internen Netzwerk. Die nächsten Regeln werden die Firewall den oben genannten Zielen entsprechend öffnen, so wie alle benötigten virtuellen Interfaces.
Bedenke, dass PF sowohl den eingehenden als auch den ausgehenden Netzwerkverkehr eines Interfaces blocken kann. Du kannst dir die Konfiguration vereinfachen, indem du den Verkehr nur in eine Richtung filterst, statt sowohl eingehenden als auch ausgehenden. In unserem Fall haben wir uns entschieden, den eingehenden Verkehr zu filtern. Doch sobald der Netzwerkverkehr in ein Interface hineingelassen wurde, werden wir nicht versuchen, ihn am Verlassen zu hintern. Das ganze sieht dann wie folgt aus:
pass out keep state
Des Weiteren benötigen wir einen Anker für ftp-proxy(8):
anchor "ftp-proxy/*"Sinnvoll ist auch der Einsatz eines Schutzes gegen gefälschte Adressen:
antispoof quick for { lo $int_if }
Nun öffne die Ports, die von den Netzwerkdiensten genutzt werden, die für das Internet verfügbar sein sollen. Zuerst der Verkehr, der für die Firewall selbst bestimmt ist:
pass in on $ext_if inet proto tcp from any to ($ext_if) \
port $tcp_services flags S/SA keep state
Die Netzwerkports in dem Makro $tcp_services anzugeben macht es simpel, zusätzliche Dienste dem Internet anzubieten. Neue Ports müssen nur in das Makro eingetragen und der Regelsatz neugeladen werden. UDP-Dienste können ebenfalls geöffnet werden, indem ein $udp_services-Makro erstellt wird und eine Filterregel so wie oben angegeben hinzugefügt wird (mit proto udp).
Zusätzlich zur rdr-Regel, die den Webserververkehr zu COMP3 weiterleitet, MÜSSEN wir ebenfalls diesen Verkehr durch die Firewall leiten:
pass in on $ext_if inet proto tcp from any to $comp3 port 80 \
flags S/SA synproxy state
Für ein bisschen mehr Sicherheit werden wir den TCP-SYN-Proxy verwenden, um den Webserver noch besser zu beschützen.
ICMP-Verkehr muss durchgelassen werden:
pass in inet proto icmp all icmp-type $icmp_types keep state
Dem $tcp_services-Makro ähnelnd kann das $icmp_types-Makro einfach editiert werden, um die Typen der ICMP-Pakete zu ändern, denen erlaubt wird, die Firewall zu erreichen. Bedenke, dass diese Regel für alle Netzwerkinterfaces gilt.
Nun muss der Verkehr zu und vom internen Netzwerk zugelassen werden. Wir nehmen an, dass die Benutzer im internen Netzwerk wissen, was sie tun und keinen Ärger verursachen werden. Dies ist nicht notwendigerweise eine gültige Annahme; ein sehr viel restriktiverer Regelsatz wäre für viele Umgebungen angebrachter.
pass in quick on $int_if
TCP-, UDP- und ICMP-Verkehr darf die Firewall in Richtung Internet verlassen. Das ist auf Grund der vorher genannten Zeile »pass out keep state« notwendig. Zustandsinformationen werden aufbewahrt, sodass die wiederkommenden Pakete durch die Firewall gelassen werden.
# makros
ext_if="fxp0"
int_if="xl0"
tcp_services="{ 22, 113 }"
icmp_types="echoreq"
comp3="192.168.0.3"
# optionen
set block-policy return
set loginterface $ext_if
set skip on lo
# scrub
scrub in
# nat/rdr
nat on $ext_if from !($ext_if) -> ($ext_if:0)
nat-anchor "ftp-proxy/*"
rdr-anchor "ftp-proxy/*"
rdr pass on $int_if proto tcp to port ftp -> 127.0.0.1 port 8021
rdr on $ext_if proto tcp from any to any port 80 -> $comp3
# filterregeln
block in
pass out keep state
anchor "ftp-proxy/*"
antispoof quick for { lo $int_if }
pass in on $ext_if inet proto tcp from any to ($ext_if) \
port $tcp_services flags S/SA keep state
pass in on $ext_if inet proto tcp from any to $comp3 port 80 \
flags S/SA synproxy state
pass in inet proto icmp all icmp-type $icmp_types keep state
pass in quick on $int_if
|
[Zurück: Firewal-Redundanz mit CARP und pfsync] [Inhalt]