[Zurück: Authpf: Benutzer-Shell für
authentifizierende Gateways]
[Inhalt]
[Weiter: Firewall für zuhause oder ein kleines
Büro]
PF: Firewallredundanz mit CARP und pfsync
Inhaltsverzeichnis
Einführung in CARP
CARP ist das »Common Address Redundancy«-Protokoll. Sein Hauptzweck
ist es, mehreren Hosts in einem gleichen Netzwerksegment zu ermöglichen,
eine IP-Adresse zu teilen. CARP ist eine sichere und freie
Alternative zum »Virtual
Router Redundancy«-Protokoll (VRRP) und zum
»Hot Standby
Router«-Protokoll (HSRP).
CARP funktioniert, indem es einer Gruppe mehreren Hosts in einem gleichen
Netzwerksegment ermöglicht, sich eine IP-Adresse zu teilen. Eine solche
Gruppe wird als Redundanzgruppe bezeichnet (im Folgenden nur Gruppe
genannt). Dieser Gruppe ist eine IP-Adresse zugeteilt, die
sich die Gruppenmitglieder untereinander teilen. Innerhalb der Gruppe
arbeitet ein Host als Master, die restlichen Hosts in der Gruppe als
Backup. Der Masterhost hält die zugewiesene IP-Adresse; er reagiert
auf den gesamten Netzwerkverkehr und auf ARP-Anfragen, die an ihn bzw.
an die ihm zugewiesene IP gerichtet sind. Jeder Host kann einer oder
mehreren Gruppen zugeteilt sein.
In der Praxis wird CARP häufig dazu genutzt, eine Gruppe von redundanten
Firewalls zu erstellen. Die virtuelle IP, die der Gruppe zugeteilt ist,
wird bei den Netzwerkclients als das standardmäßige Gateway
konfiguriert. Sollte nun der Masterhost der Gruppe ausfallen, so wird
einer der Backuphosts in der Gruppe seine Funktion übernehmen.
CARP unterstützt IPv4 und IPv6.
Funktionsweise von CARP
Der Masterhost sendet in regelmäßigen Zeitintervallen Nachrichten an das
lokale Netzwerk, um den Backuphosts mitzuteilen, dass er im Betrieb
ist. Wenn die Backuphosts nach einer festgelegten Zeitspanne keine
dieser Nachrichten registrieren, wird einer der Backuphosts an dessen
Stelle treten und dessen Dienst übernehmen. Der Backuphost, der die
niedrigsten Werten für advbase und advskew hat,
wird die Aufgabe übernehmen.
Es ist möglich, mehrere CARP-Gruppen in einem gleichen Netzwerksegment
einzurichten. Die CARP-Nachrichten beinhalten eine »Virtual Host ID«,
welche es den Hosts ermöglicht, zwischen den verschiedenen Gruppen zu
unterscheiden.
Um eine Gruppe vor gefälschten CARP-Nachrichten zu schützen, ist es
möglich, jede dieser Gruppen mit Passwortschutz zu versehen. Jedes
gesendete Paket ist durch einen SHA1-HMAC geschützt.
CARP ist ein eigenständiges Protokoll, sodass extra definierte
pass-Regeln im Regelsatz verwendet werden sollten.
pass out on $carp_dev proto carp keep state
$carp_dev sollte das physikalische Interface sein, über welches
CARP kommuniziert.
Konfiguration von CARP
Jede Gruppe wird durch ein virtuelles
carp(4)-Netzwerkinterface dargestellt. Als solches wird es auch
mit
ifconfig(8) konfiguriert.
ifconfig carpN create
ifconfig carpN vhid vhid [pass password]
[carpdev carpdev] \
[advbase advbase] [advskew advskew]
[state state] [group|-group group] \
ipaddress netmask mask
- carpN
- Der Name des virtuellen carp(4)-Interfaces, wobei N die
Interface-Nummer ist (z. B. carp10).
- vhid
- Die »Virtual Host ID«.
Eine eindeutige Nummer, die zur Identifizierung einer Redundanzgruppe innerhalb
eines Netzwerks, und zur Unterscheidung von Gruppen als solche genutzt wird.
Gültige Werte sind 1 bis 255.
Der Wert muss für alle Mitglieder einer Gruppe identisch sein.
- password
- Das Passwort, welches die Mitglieder einer Gruppe nutzen, um sich
untereinander zu authentifizieren. Alle Hosts in einer Gruppe müssen das
gleiche Passwort benutzen.
- carpdev
- Dieser Parameter ist optional. Er gibt das physikalische Interface
an, welches dem Netzwerksegment zugeordnet ist, in dem sich die Gruppe
befindet. Standardmäßig versucht CARP, das richtige Interface selbst zu
finden. Dabei sucht es anhand der Kombination aus Netzwerkmaske
(mask) und IP-Adresse (ipaddress) nach dem Interface, das
in dem gleichen Subnetz ist wie das carp(4)-Interface.
- advbase
- Dieser Parameter ist optional. Er gibt an, in welchen
Zeitintervallen der Host Nachrichten an die Gruppe senden soll, die
signalisieren, dass der Host ein Mitglied der Gruppe ist. Gültige Werte
sind 1 bis 255. Der Standardwert ist 1.
- advskew
- Dieser optionale Parameter gibt an, wie sehr advbase
gestreckt werden soll, wenn CARP-Advertisements gesendet werden. Durch
die Einstellung von advskew kann der Master-CARP-Host
festgelegt werden. Je höher der Wert ist, desto geringer ist
seine Berechtigung, die Rolle vom Masterhost einzunehmen. Gültige
Werte sind 0 bis 254. Der Standardwert ist 0.
- state
- Zwingt das carp(4)-Interface dazu, einen bestimmten Status
anzunehmen. Gültige Werte sind init, backup und
master.
- group, -group
- Fügt eine carp(4)-Schnittstelle zu einer bestimmten Schnittstellengruppe
hinzu, oder entfernt sie von dort.
Standardmäßig werden alle carp(4)-Schnittstellen zu der Gruppe carp
hinzugefügt.
Jede Gruppe besitzt einen carpdemote-Zähler, der alle
carp(4)-Schnittstellen beeinflusst, die zu dieser Schnittstelle gehören.
Wie unten beschrieben wird, kann es nützlich sein,
bestimmte Schnittstellen zum Zwecke der Ausfallsicherung zu Gruppen
zusammenzufassen.
- ipaddress
- Dies ist die IP-Adresse, die der Gruppe zugewiesen wird. Diese
Adresse muss nicht im selben Subnetz sein wie die IP-Adresse, die dem
physikalischen Interface zugeordnet ist (sofern vorhanden). Die
Adresse muss jedem Host in der Gruppe zugewiesen sein.
- mask
- Die Subnetzmaske der gemeinsam genutzten IP.
Weiterhin kann das Verhalten von CARP via
sysctl(8) manipuliert werden.
- net.inet.carp.allow
- Akzeptiert eingehende CARP-Pakete - oder nicht. Standardwert ist 1
(akzeptiert).
- net.inet.carp.preempt
- Erlaubt Hosts innerhalb einer Redundanz-Gruppe, die einen besseren
advbase- und advskew-Wert haben, zum Masterhost zu
werden.
Zusätzlich erlaubt diese Option das Herunterfahren einer Schnittstellengruppe
als Ganzes in dem Fall, dass eine ihrer Schnittstellen ausfällt.
Fällt eine physikalisch vorhandene Schnittstelle mit aktiviertem CARP aus,
so wird der Degradierungszähler, carpdemote, um eins (1) bei all
jenen Schnittstellengruppen erhöht, denen die carp(4)-Schnittstelle angehört,
was effektiv zu einem Ausfall aller Gruppenmitglieder führt.
net.inet.carp.preempt ist standardmäßig 0 (deaktiviert).
- net.inet.carp.log
- Protokolliere Status-Änderungen, fehlerhafte Pakete und andere Fehler.
Kann einen Wert zwischen null (0) und sieben (7) haben, entsprechend der
syslog(3)-Prioritäten.
Der Standard ist zwei (2; nur Status-Änderungen).
CARP-Beispiel
Es folgt eine Beispielkonfiguration für CARP.
# sysctl -w net.inet.carp.allow=1
# ifconfig carp1 create
# ifconfig carp1 vhid 1 pass mekmitasdigoat carpdev em0 \
advskew 100 10.0.0.1 netmask 255.255.255.0
Das bewirkt Folgendes:
- Schaltet den Empfang von CARP-Paketen ein (dies ist die
Standardeinstellung).
- Erzeugt ein carp(4)-Interface: carp1.
- Konfiguriert carp1 für den virtuellen Host Nr. 1, setzt ein
Passwort und konfiguriert das Interface em0 als jenes, das zur
Gruppe gehört. Dazu wird der Host durch Setzen von advskew auf
100 als Backuphost konfiguriert (natürlich nur, wenn der
Master einen kleineren Wert als 100 bei advskew besitzt). Die
virtuelle IP, die der Gruppe zugewiesen ist, ist 10.0.0.1. Die
Subnetzmaske ist 255.255.255.0.
Ein Aufruf von ifconfig für carp1 zeigt den
Status des Interfaces an.
# ifconfig carp1
carp1: flags=8802<UP,BROADCAST,SIMPLEX,MULTICAST> mtu 1500
carp: BACKUP carpdev em0 vhid 1 advbase 1
advskew 100
groups: carp
inet 10.0.0.1 netmask 0xffffff00
broadcast 10.0.0.255
Einführung in pfsync
Das
pfsync(4)-Netzwerkinterface zeigt bestimmte Änderungen des
pf(4)-Zustands (seiner Tabellen) an.
Durch die Nutzung von
tcpdump(8) können diese Änderungen in Echtzeit überwacht werden.
Zusätzlich kann das pfsync(4)-Interface diese Änderungen an andere
Hosts im Netzwerk senden, sodass diese den Zustand ihrer Tabellen
entsprechend angleichen können. Ebenso kann pfsync(4) auf solche
Nachrichten aus dem Netzwerk warten und diese lesen.
Funktionsweise von pfsync
Standardmäßig sendet oder empfängt pfsync(4) keine derartigen Meldungen
über das Netzwerk. Dennoch können die Updates mittels tcpdump(8) oder
anderen Programmen mitverfolgt werden.
Wenn pfsync(4) so konfiguriert ist, diese Nachrichten über das Netzwerk
zu senden und zu empfangen, werden die Nachrichten an alle Teilnehmer
der Gruppe versendet. All diese Updateinformationen werden jedoch ohne
Authentifizierung versendet. Um hier für Sicherheit zu sorgen, gibt es
zwei bewährte Verfahren:
- Verbinde die zwei Maschinen, die ihre Updates untereinander
austauschen sollen, mit einem Crossover-Kabel und konfiguriere das
Interface als syncdev (siehe hier).
- Benutze die ifconfig(8)-Option syncpeer (siehe unten), um eine Unicastverbindung über das
Netzwerk zwischen den Maschinen aufzubauen, über die sie die Nachrichten
austauschen können. Danach konfiguriere
ipsec(4), um die Verbindung abzusichern.
Wenn die Updates über das Netzwerk gesendet und empfangen werden,
sollten diese pfsync-Pakete auch im Regelsatz so berücksichtigt werden,
dass sie auch ihr Ziel erreichen können.
pass on $sync_if proto pfsync
$sync_if sollte das physikalische Interface sein, über das
pfsync(4) kommuniziert.
Konfiguration von pfsync
Da pfsync(4) als virtuelles Netzwerkinterface arbeitet, wird es mit
ifconfig(8) konfiguriert.
ifconfig pfsyncN syncdev syncdev [syncpeer
syncpeer] [defer|-defer]
- pfsyncN
- Der Name des pfsync(4)-Interfaces. pfsync0 ist
standardmäßig benutzbar, wenn der generische Kernel
(GENERIC) verwendet wird.
- syncdev
- Der Name des physikalischen Interfaces, worüber pfsync die Updates
versendet.
- syncpeer
- Dieser Parameter ist optional. Er gibt den Host an, an den Updates
als Unicastnachrichten versendet werden sollen. Standardmäßig werden
die Updatenachrichten als Multicastnachricht an die Gruppe im lokalen
Netzwerk gesendet. Diese Option überschreibt das Verhalten und sendet
stattdessen das Update per Unicastnachricht an den angegebenen
syncpeer.
- defer
- Wenn der Schalter defer benutzt wird, so wird das erste Paket
einer neuen Verbindung, die die Firewall passiert, nicht transmittiert bevor
entweder ein anderes pfsync(4)-System die Statustabellen-Ergänzung anerkannt
hat, oder ein Zeitlimit abgelaufen ist.
Dies verursacht kleine Verzögerungen, erlaubt aber den Fluss des Traffic, wenn
mehr als eine Firewall aktiv Pakete bearbeiten könnte (»active/active«),
zum Beispiel mit bestimmten ospfd(8)-, bgpd(8)- oder carp(4)-Konfigurationen.
pfsync-Beispiel
Es folgt eine pfsync-Beispielkonfiguration.
# ifconfig pfsync0 syncdev em1 up
Dies aktiviert pfsync auf dem em1-Interface. Ausgehender
Verkehr wird via Multicast in das Netzwerk gesendet. Jeder Host mit
aktiviertem pfsync kann die Updates empfangen.
Kombinieren von CARP und pfsync für Ausfallsicherheit und
Redundanz
Durch die Kombination der Fähigkeiten von CARP und pfsync lässt sich
eine Gruppe von zwei oder mehr Hosts zu einem Firewallcluster mit hoher
Verfügbarkeit und Redundanz erstellen.
- CARP:
- Regelt automatisch die Ausfallsicherheit, indem ein anderer Host
seine Aufgabe bei einem Ausfall übernimmt.
- pfsync:
- Synchronisiert die Statustabellen zwischen allen Firewalls in einer
Gruppe. Wenn eine Firewall ausfallen sollte, kann der Netzwerkverkehr
ohne Unterbrechung über den neuen Firewallhost laufen. Der neue
Firewallhost hat stets eine aktuelle Statustabelle und kann sofort
seine Arbeit verrichten.
Ein Beispielszenario. Zwei Firewalls: fw1 und fw2.
+------| WAN/Internet |------+
| |
em2| |em2
+-----+ +-----+
| fw1 |-em1--------------em1-| fw2 |
+-----+ +-----+
em0| |em0
| |
---+--gemeinsam genutztes LAN---+---
Die Firewalls sind über ein Crossover-Kabel miteinander über
em1 verbunden. Beide sind an das LAN mit em0 und an
das WAN (bzw. Internet) an em2 angeschlossen.
Die IP-Adressen wurden folgendermaßen vergeben:
- fw1 em0: 172.16.0.1
- fw1 em1: 10.10.10.1
- fw1 em2: 192.0.2.1
- fw2 em0: 172.16.0.2
- fw2 em1: 10.10.10.2
- fw2 em2: 192.0.2.2
- LAN shared IP: 172.16.0.100
- WAN/Internet shared IP: 192.0.2.100
Als Firewall-Masterhost wird fw1 festgelegt.
Konfiguration von fw1:
! aktiviere Präemptivität und Ausfallsicherheit für Gruppeninterfaces
# sysctl -w net.inet.carp.preempt=1
! pfsync konfigurieren
# ifconfig em1 10.10.10.1 netmask 255.255.255.0
# ifconfig pfsync0 syncdev em1
# ifconfig pfsync0 up
! CARP auf dem LAN-Interface konfigurieren
# ifconfig carp1 create
# ifconfig carp1 vhid 1 carpdev em0 pass lanpasswd \
172.16.0.100 netmask 255.255.255.0
! CARP auf dem WAN/Internet-Interface konfigurieren.
# ifconfig carp2 create
# ifconfig carp2 vhid 2 carpdev em2 pass netpasswd \
192.0.2.100 netmask 255.255.255.0
|
Konfiguration von fw2:
! aktiviere Präemptivität und Ausfallsicherheit für Gruppeninterfaces
# sysctl -w net.inet.carp.preempt=1
! pfsync konfigurieren
# ifconfig em1 10.10.10.2 netmask 255.255.255.0
# ifconfig pfsync0 syncdev em1
# ifconfig pfsync0 up
! CARP auf dem LAN-Interface konfigurieren
# ifconfig carp1 create
# ifconfig carp1 vhid 1 carpdev em0 pass lanpasswd \
advskew 128 172.16.0.100 netmask 255.255.255.0
! CARP auf dem WAN/Internet-Interface konfigurieren.
# ifconfig carp2 create
# ifconfig carp2 vhid 2 carpdev em2 pass netpasswd \
advskew 128 192.0.2.100 netmask 255.255.255.0
|
Weitere technische Möglichkeiten
Weitere technische Möglichkeiten im Umgang mit CARP und pfsync.
CARP und pfsync während des Bootvorgangs konfigurieren
Da carp(4) und pfsync besondere Netzwerkinterfacetypen sind,
lassen sie sich während des Bootvorgangs konfigurieren, indem man für
sie eine
hostname.if(5)-Datei anlegt.
Das Skript
netstart wird während des Bootens dann anhand diesen Dateien die
Konfiguration durchführen.
Beispiele:
- /etc/hostname.carp1
-
inet 172.16.0.100 255.255.255.0 172.16.0.255 vhid 1 carpdev em0 \
pass lanpasswd
- /etc/hostname.pfsync0
-
up syncdev em1
Ausfallsicherheit vom Master-Host testen
Es kann irgendwann die Zeit kommen, in der der Masterhost ausfällt,
bzw. sein Dienst vorübergehend eingestellt werden muss. Dies kann
geschehen, wenn man den Masterhost warten muss oder ein Problem
besteht, welches zu beheben ist. Das Ziel ist es, den Masterhost von
seinem Dienst zu suspendieren, ohne dass der Netzwerkverkehr davon
beeinträchtigt wird. Dazu muss einer der Backuphosts den Dienst des
Masterhosts übernehmen.
Um einen solchen Ausfall für eine bestimmte CARP-Gruppe zu erzwingen,
fahre das carp(4)-Interface auf dem Masterhost herunter. Das führt
dazu, dass der Masterhost sich selber mit »unendlich hohen«
advbase und advskew ankündigen wird. Der Backuphost
(oder einer davon) wird das merken und ab sofort die Rolle vom
Masterhost übernehmen.
# ifconfig carp1 down
Eine Alternative wäre advskew zu vergrößern, sodass der
Wert größer ist als advskew auf dem Backuphost
(bzw. den anderen Backuphosts). Damit wird ein Failover hervorgerufen,
der es dem Master ermöglicht, weiterhin in der CARP-Gruppe verfügbar
zu sein.
Eine andere Möglichkeit, um Ausfallsicherheit zu gewährleisten,
ist die Anpassung des CARP-Demotionzählers. Der Demotionzähler gilt
als Maß dafür, wie »bereit« ein Host ist, der Master der CARP-Gruppe
zu werden. Wenn ein Host zum Beispiel gerade dabei ist hochzufahren,
wäre es eine schlechte Idee, ihn als CARP-Master zu deklarieren, bis
alle Interfaces eingerichtet, alle Netzwerkdaemons gestartet wurden
etc. Hosts, die einen hohen Demotionwert versenden, werden seltener
als Master ausgewählt.
Ein Demotionzähler wird in jeder Interfacegruppe gespeichert, zu der
das CARP-Interface gehört. Standardmäßig sind alle CARP-Interfaces
Mitglied der »carp«-Interfacegruppe. Der aktuelle Wert des
Demotioncounters kann mit ifconfig(8) angezeigt werden:
# ifconfig -g carp
carp: carp demote count 0
In diesem Beispiel wird der Zähler der »carp«-Interfacegruppe angezeigt.
Wenn ein CARP-Host sich selbst im Netzwerk anbietet, so wird die Summe
aller Demotionzähler der Interfacegruppen versendet, zu denen das
carp(4)-Interface gehört. Das heißt, dass der versendete Demotionwert
die Summe aller Zähler darstellt.
Nehmen wir nun folgendes Beispiel an. Zwei Firewalls mit CARP besitzen
folgende CARP-Interfaces:
- carp1 - Buchhaltung
- carp2 - Angestellte
- carp3 - Internet
- carp4 - DMZ
Das Ziel besteht darin, nur die carp1- und carp2-Gruppen im Falle eines
Ausfalls auf die zweite Firewall umzuleiten.
Zuerst müssen beide zuerst zu einer neuen Interfacegruppe hinzugefügt
werden. In diesem Beispiel nennen wir sie »internal«:
# ifconfig carp1 group internal
# ifconfig carp2 group internal
# ifconfig internal
carp1: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> mtu 1500
carp: MASTER carpdev em0 vhid 1 advbase 1
advskew 100
groups: carp internal
inet 10.0.0.1 netmask 0xffffff00 broadcast
10.0.0.255
carp2: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> mtu 1500
carp: MASTER carpdev em1 vhid 2 advbase 1
advskew 100
groups: carp internal
inet 10.0.1.1 netmask 0xffffff00 broadcast
10.0.1.255
Nun erhöhen wir den Demotionzähler für die Gruppe »internal« mittels
ifconfig(8):
# ifconfig -g internal
internal: carp demote count 0
# ifconfig -g internal carpdemote 50
# ifconfig -g internal
internal: carp demote count 50
Die Firewall wird nun im Falle eines Ausfalls die Gruppen carp1 und
carp2 gerne an die andere Firewall im Cluster übergeben, doch weiterhin
Master von carp3 und carp4 bleiben. Wenn die andere Firewall nun selbst
beginnt, sich mit einem Demotionwert über 50 anzubieten, oder die
andere Firewall aufhört, ihren Wert zu übermitteln, so wird diese
Firewall wie zuvor die Gruppen carp1 und carp2 übernehmen.
Um auf die primäre Firewall zurückfallen zu können, mach die Änderungen
wieder rückgängig:
# ifconfig -g internal -carpdemote 50
# ifconfig -g internal
internal: carp demote count 0
Netzwerkdaemons wie zum Beispiel
OpenBGPD und
sasyncd(8) verwenden den Demotioncounter, um sicherzustellen,
dass die Firewall nicht zum Master wird, bevor die BGP-Sitzung
aufgebaut und IPsec-SAs synchronisiert wurden.
Tipps für Regelsätze
Filter das physikalische Interface.
Soweit es PF anbelangt, wird der Netzwerkverkehr vom physikalischen
Interface und nicht vom virtuellen CARP-Interface (d. h.
carp0) empfangen. Schreibe also deine Regelsätze
dementsprechend. Vergiss nicht, dass ein Interfacename in einer
PF-Regel entweder der Name eines physikalischen Interfaces
oder eine dem Interface zugewiesene Adresse sein kann. Zum Beispiel
könnte diese Regel korrekt sein:
pass in on fxp0 inet proto tcp from any to carp0 port 22
Das Ersetzen von fxp0 in carp0 würde aber nicht das
machen, was du erwartest.
Vergiss NIEMALS, proto carp und proto pfsync
zu übergeben!
Weitere Referenzen
Bitte folge den Links für weitere Informationen zu dem Thema.
[Zurück: Authpf: Benutzer-Shell für
authentifizierende Gateways]
[Inhalt]
[Weiter: Firewall für zuhause oder ein kleines
Büro]
www@openbsd.org
$OpenBSD: carp.html,v 1.31 2012/12/21 10:33:10 ajacoutot Exp $