Der Autor hat den COVID-19 Relief Fund dazu ausgewählt, eine Spende im Rahmen des Programms Write for DOnations zu erhalten.
Die Firewall ist wahrscheinlich eine der wichtigsten Verteidigungslinien gegen Cyberangriffe. Die Fähigkeit zur grundlegenden Konfiguration einer Firewall ist enorm wichtig, da sie es Administratoren ermöglicht, ihre Netzwerke richtig zu kontrollieren.
Packet Filter (PF) ist eine bekannte Firewall-Anwendung, die vom sicherheitsorientierten OpenBSD-Projekt verwaltet wird. Genauer gesagt handelt es sich um um ein Paketfilter-Tool (daher der Name), das für seine einfache Syntax, hohe Benutzerfreundlichkeit und umfangreichen Funktionen geschätzt wird. PF ist standardmäßig eine Stateful-Firewall, die Informationen über Verbindungen in einer Tabelle für Zustandserfassung speichert, auf die für Analysezwecke zugegriffen werden kann. PF ist Teil des FreeBSD-Basissystems und wird von einer starken Entwickler-Community unterstützt. Obwohl es hinsichtlich der Kernel-Architektur Unterschiede zwischen den FreeBSD- und OpenBSD-Versionen von PF gibt, ist ihre Syntax im Allgemeinen ähnlich. Je nach Komplexität können gängige Regelsätze für beide Distributionen mit relativ geringem Aufwand modifiziert werden.
In diesem Tutorial erstellen Sie mit PF von Grund auf eine Firewall auf einem FreeBSD 12.1-Server. Sie werden einen grundlegenden Regelsatz einrichten, der als Vorlage für zukünftige Projekte dienen kann. Außerdem werden Sie einige der fortgeschrittenen Funktionen von PF wie Packet-Hygiene, Abwehr von Brute-Force-Angriffen, Überwachung und Protokollierung sowie Tools anderer Anbieter kennenlernen.
Bevor Sie mit diesem Tutorial beginnen, benötigen Sie Folgendes:
Sie legen mit diesem Tutorial los, indem Sie einen vorläufigen Regelsatz erarbeiten, der grundlegenden Schutz und Zugriff auf kritische Dienste im Internet bietet. An diesem Punkt verfügen Sie über einen ausgeführten FreeBSD 12.1-Server mit einer aktiven Cloud-Firewall.
Es gibt zwei Ansätze zum Erstellen einer Firewall: default deny und default permit. Beim default deny-Ansatz wird der ganze Verkehr blockiert und nur zugelassen, was in einer Regel angegeben ist. Der default permit-Ansatz bewirkt das genaue Gegenteil: Er überträgt den gesamten Datenverkehr und blockiert nur das, was in einer Regel angegeben ist. Sie werden den default deny-Ansatz verwenden.
PF-Regelsätze werden in eine Konfigurationsdatei namens /etc/pf.conf
geschrieben, was auch ihr Standardspeicherort ist. Es ist in Ordnung, diese Datei an einem anderen Ort zu speichern, solange dieser in der Konfigurationsdatei /etc/rc.conf
angegeben wird. In diesem Tutorial verwenden Sie den Standardspeicherort.
Melden Sie sich mit Ihrem non-root user bei Ihrem Server an:
- ssh freebsd@your_server_ip
Als Nächstes erstellen Sie Ihre /etc/pf.conf
-Datei:
- sudo vi /etc/pf.conf
Anmerkung: Wenn Sie an einem beliebigen Punkt im Tutorial den vollständigen Basisregelsatz anzeigen möchten, können Sie die Beispiele in Schritt 4 oder Schritt 8 konsultieren.
PF filtert Pakete anhand von drei zentralen Aktionen: block
, pass
und match
. In Kombination mit anderen Optionen bilden diese Regeln. Eine Maßnahme wird ergriffen, wenn ein Paket die in einer Regel angegebenen Kriterien erfüllt. Wie Sie möglicherweise erwarten, sorgen die Regeln pass
und block
dafür, dass Datenverkehr durchgelassen
bzw. blockiert
wird. Eine match
-Regel führt eine Aktion für ein Paket aus, wenn sie ein übereinstimmendes Kriterium findet, lässt das Paket aber weder zu noch blockiert sie es. Zum Beispiel können Sie die Netzwerkadressenübersetzung (NAT) für ein übereinstimmendes Paket ausführen, ohne es zu übertragen oder zu blockieren; es wird dort bleiben, bis Sie es in einer anderen Regel dazu anweisen, etwas zu tun (z. B. Weiterleitung an ein anderes Gerät oder Gateway).
Fügen Sie anschließend die erste Regel in Ihre /etc/pf.conf
-Datei ein:
block all
Diese Regel blockiert alle Arten von Datenverkehr in jede Richtung. Da keine Richtung angegeben ist, gilt sie standardmäßig für sowohl eingehenden
als auch ausgehenden
Datenverkehr. Diese Regel ist anwendbar auf eine lokale Workstation, die gegenüber dem Rest der Welt isoliert werden soll, ist jedoch weitgehend unpraktisch und wird bei Remoteservern nicht funktionieren, da sie keinen SSH-Verkehr zulässt. Wenn PF aktiviert gewesen wäre, hätten Sie sich sogar aus dem Server ausgesperrt.
Bearbeiten Sie Ihre Datei /etc/pf.conf
mit der folgenden hervorgehobenen Zeile, um SSH-Verkehr zu erlauben:
block all
pass in proto tcp to port 22
Anmerkung: Alternativ können Sie den Namen des Protokolls verwenden:
block all
pass in proto tcp to port ssh
Aus Konsistenzgründen werden wir Portnummern verwenden, es sei denn, es gibt einen triftigen Grund dafür, es nicht zu tun. Es gibt in der Datei /etc/services
eine detaillierte Liste der Protokolle und ihrer jeweiligen Portnummern, die Sie sich ansehen sollten.
PF verarbeitet Regeln sequentiell von oben nach unten; d. h. Ihr aktueller Regelsatz blockiert zunächst den gesamten Datenverkehr, lässt ihn dann aber passieren, wenn die Kriterien in der nächsten Zeile erfüllt werden, was in diesem Fall SSH-Verkehr ist.
Sie können nun SSH-Daten an Ihren Server übertragen, blockieren aber weiterhin alle Formen von ausgehendem Datenverkehr. Das ist ein Problem, da Sie keine kritischen Dienste aus dem Internet aufrufen können, um Pakete zu installieren, die Zeiteinstellungen zu aktualisieren und so weiter.
Fügen Sie darum am Ende Ihrer Datei /etc/pf.conf
die folgende hervorgehobene Regel hinzu:
block all
pass in proto tcp to port { 22 }
pass out proto { tcp udp } to port { 22 53 80 123 443 }
Ihr Regelsatz lässt nun ausgehenden SSH-, DNS-, HTTP-, NTP- und HTTPS-Verkehr zu und blockiert den gesamten eingehenden Datenverkehr (mit Ausnahme von SSH). Sie platzieren die Portnummern und Protokolle in geschweiften Klammern, wodurch in PF-Syntax eine Liste gebildet wird, sodass Sie bei Bedarf mehr Portnummern hinzufügen können. Sie fügen außerdem eine Pass-Out-Regel für das UDP-Protokoll an den Ports 53
und 123
hinzu, da DNS und NTP oft zwischen den TCP- und UDP-Protokollen wechseln. Sie sind mit dem vorläufigen Regelsatz fast fertig und müssen nur noch ein paar Regeln hinzufügen, um grundlegende Funktionalität zu erreichen.
Vervollständigen Sie den vorläufigen Regelsatz mit den hervorgehobenen Regeln:
set skip on lo0
block all
pass in proto tcp to port { 22 }
pass out proto { tcp udp } to port { 22 53 80 123 443 }
pass out inet proto icmp icmp-type { echoreq }
Speichern und schließen Sie die Datei.
Sie erstellen für das Loopbackgerät eine set skip
-Regel, da es Datenverkehr nicht filtern muss und Ihren Server wahrscheinlich spürbar verlangsamen würde. Sie fügen eine pass out inet
-Regel für das ICMP-Protokoll hinzu, was es Ihnen ermöglicht, das Dienstprogramm ping(8) zur Problembehandlung zu verwenden. Die Option inet
repräsentiert die IPv4-Adressfamilie.
ICMP ist ein Mehrzweckprotokoll, das von Netzwerkgeräten für verschiedene Arten von Kommunikation verwendet wird. Das ping-Dienstprogramm zum Beispiel verwendet eine Art von Nachricht, die als Echoanforderung bekannt ist und welche Sie Ihrer icmp_type
-Liste hinzugefügt haben. Vorsorglich lassen Sie nur Nachrichtentypen zu, die Sie brauchen, um zu verhindern, dass unerwünschte Geräte Ihren Server kontaktieren. Wenn sich Ihre Anforderungen erhöhen, können Sie mehr Nachrichtentypen in Ihre Liste aufnehmen.
Sie haben nun einen funktionierenden Regelsatz, der grundlegende Funktionalität für die meisten Rechner bereitstellt. Im nächsten Abschnitt überprüfen wir, ob alles richtig funktioniert, indem wir PF aktivieren und den vorläufigen Regelsatz testen.
In diesem Schritt testen Sie Ihren vorläufigen Regelsatz und stellen von Ihrer Cloud-Firewall auf die PF-Firewall um, damit PF vollständig übernimmt. Sie aktivieren Ihren Regelsatz mit dem Dienstprogramm pfctl
, das das integrierte Befehlszeilentool von PF und die primäre Schnittstellenmethode zu PF ist.
PF-Regelsätze sind nichts weiter als Textdateien, was bedeutet, dass mit dem Laden neuer Regelsätze keine empfindlichen Verfahren verbunden sind. Sie können einen neuen Regelsatz laden und der alte verschwindet. Einen bestehenden Regelsatz müssen Sie nur selten (wenn überhaupt) leeren.
FreeBSD verwendet ein Netz von Shellskripten, das als rc
-System bekannt ist, um zu verwalten, wie Dienste zur Startzeit gestartet werden; wir geben diese Dienste in verschiedenen rc
-Konfigurationsdateien an. Für globale Dienste wie PF verwenden Sie die Datei /etc/rc.conf
. Da rc
-Dateien für das Wohlbefinden eines FreeBSD-Systems kritisch sind, sollten sie nicht direkt bearbeitet werden. Stattdessen bietet FreeBSD ein Befehlszeilenprogramm namens sysrc
, das Ihnen dabei hilft, diese Dateien sicher zu bearbeiten.
Aktivieren wir PF nun unter Verwendung des Befehlszeilenprogramms sysrc
:
- sudo sysrc pf_enable="YES"
- sudo sysrc pflog_enable="YES"
Überprüfen Sie diese Änderungen durch Drucken des Inhalts Ihrer Datei /etc/rc.conf
:
- sudo cat /etc/rc.conf
Sie sehen die folgende Ausgabe:
Outputpf_enable="YES"
pflog_enable="YES"
Außerdem aktivieren Sie den Dienst pflog
, der wiederum den Daemon pflogd
für die Anmeldung bei PF aktiviert. Mit der Anmeldung arbeiten Sie in einem späteren Schritt.
Sie geben zwei globale Dienste in Ihrer Datei /etc/rc.conf
an; sie werden aber erst dann initialisiert, wenn Sie den Server neu starten oder die Dienste manuell starten. Starten Sie den Server neu, damit Sie auch Ihren SSH-Zugriff testen können.
Starten Sie PF, indem Sie den Server neu starten:
- sudo reboot
Die Verbindung wird verworfen. Das Aktualisieren dauert ein paar Minuten.
Stellen Sie nun wieder eine SSH-Verbindung zum Server her:
- ssh freebsd@your_server_ip
Sie haben zwar Ihre PF-Dienste initialisiert, doch haben Sie Ihren Regelsatz /etc/pf.conf
nicht geladen, was bedeutet, dass Ihre Firewall noch nicht aktiv ist.
Laden Sie den Regelsatz mit pfctl
:
- sudo pfctl -f /etc/pf.conf
Wenn keine Fehler oder Nachrichten vorhanden sind, bedeutet dies, dass Ihr Regelsatz keine Fehler aufweist und die Firewall aktiv ist.
Nachdem PF nun ausgeführt wird, können Sie Ihren Server von Ihrer Cloud-Firewall trennen. Dies können Sie im Bedienfeld in Ihrem DigitalOcean-Konto tun, indem Sie Ihr Droplet aus dem Portal Ihrer Cloud-Firewall entfernen. Wenn Sie einen anderen Cloudanbieter verwenden, stellen Sie sicher, dass alles, was Sie als temporären Schutz nutzen, deaktiviert wird. Eine Ausführung von zwei verschiedenen Firewalls auf einem Server wird mit hoher Wahrscheinlichkeit Probleme verursachen.
Starten Sie Ihren Server sicherheitshalber neu:
- sudo reboot
Stellen Sie nach ein paar Minuten erneut eine SSH-Verbindung mit Ihrem Server her:
- ssh freebsd@your_server_ip
PF ist nun Ihre aktive Firewall. Sie können sich vergewissern, dass sie ausgeführt wird, indem Sie mit dem Dienstprogramm pfctl ein paar Daten aufrufen.
Sehen wir uns nun mit pfctl -si
einige Statistiken und Zähler an:
- sudo pfctl -si
Sie übergeben die Flags -si
, die für show info stehen. Dies ist eine der vielen Filterparameterkombinationen, die Sie mit pfctl verwenden können, um Daten über Ihre Firewallaktivitäten zu analysieren.
Sie sehen die folgenden Tabellendaten (die Werte variieren von Gerät zu Gerät):
OutputStatus: Enabled for 0 days 00:01:53 Debug: Urgent
State Table Total Rate
current entries 5
searches 144 1.3/s
inserts 11 0.1/s
removals 6 0.1/s
Counters
match 23 0.2/s
bad-offset 0 0.0/s
fragment 0 0.0/s
short 0 0.0/s
normalize 0 0.0/s
memory 0 0.0/s
bad-timestamp 0 0.0/s
congestion 0 0.0/s
ip-option 0 0.0/s
proto-cksum 0 0.0/s
state-insert 0 0.0/s
state-limit 0 0.0/s
src-limit 0 0.0/s
synproxy 0 0.0/s
map-failed 0 0.0/s
Da Sie Ihren Regelsatz gerade aktiviert haben, gibt es noch nicht sehr viele Informationen. Die Ausgabe zeigt jedoch, dass PF bereits 23 abgeglichene Regeln erfasst hat, was bedeutet, dass die Kriterien Ihres Regelsatzes 23 mal abgeglichen wurden. Die Ausgabe bestätigt auch, dass Ihre Firewall funktioniert.
Außerdem lässt Ihr Regelsatz zu, dass ausgehender Datenverkehr auf einige kritische Dienste aus dem Internet zugreift, einschließlich des ping-Dienstprogramms.
Überprüfen wir nun mit ping über google.com
die Internetverbindung und den DNS-Dienst.
- ping -c 3 google.com
Da Sie das Zähl-Flag -c 3
ausgeführt haben, werden Ihnen drei erfolgreiche Verbindungsantworten angezeigt:
OutputPING google.com (172.217.0.46): 56 data bytes
64 bytes from 172.217.0.46: icmp_seq=0 ttl=56 time=2.088 ms
64 bytes from 172.217.0.46: icmp_seq=1 ttl=56 time=1.469 ms
64 bytes from 172.217.0.46: icmp_seq=2 ttl=56 time=1.466 ms
--- google.com ping statistics ---
3 packets transmitted, 3 packets received, 0.0% packet loss
round-trip min/avg/max/stddev = 1.466/1.674/2.088/0.293 ms
Stellen Sie sicher, dass Sie mit dem folgenden Befehl auf das Repository pkgs zugreifen können:
- sudo pkg upgrade
Wenn Pakete aktualisiert werden müssen, fahren Sie fort und aktualisieren Sie sie.
Wenn beide Dienste funktionieren, bedeutet das, dass Ihre Firewall funktioniert und Sie jetzt fortfahren können. Ihr vorläufiger Regelsatz bietet zwar Schutz und Funktionalität, doch handelt es sich dabei immer noch um einen elementaren Regelsatz, der weiter verbessert werden kann. In den verbleibenden Abschnitten werden Sie Ihren Basisregelsatz vervollständigen und einige der fortgeschrittenen Funktionen von PF verwenden.
In diesem Schritt bauen Sie auf dem vorläufigen Regelsatz auf, um Ihren Basisregelsatz zu vervollständigen. Sie werden einige Ihrer Regeln neu organisieren und mit fortgeschritteneren Konzepten arbeiten.
In Ihrem vorläufigen Regelsatz haben Sie alle Ihre Parameter als vordefinierten Code in jede Regel aufgenommen (d. h. die Portnummern, aus denen die Listen bestehen). Dies kann in Zukunft je nach Art Ihrer Netzwerke unüberschaubar werden. Für organisatorische Zwecke umfasst PF Makros, Listen und Tabellen. Sie haben bereits Listen direkt in Ihre Regeln aufgenommen, Sie können sie aber auch von Ihren Regeln trennen und unter Verwendung von Makros einer Variable zuweisen.
Öffnen Sie Ihre Datei, um einige Ihrer Parameter in Makros zu übertragen:
- sudo vi /etc/pf.conf
Fügen Sie nun ganz oben im Regelsatz den folgenden Inhalt ein:
vtnet0 = "vtnet0"
icmp_types = "{ echoreq }"
. . .
Ändern Sie Ihre vorherigen SSH- und ICMP-Regeln mit Ihren neuen Variablen:
. . .
pass in on $vtnet0 proto tcp to port { 22 }
. . .
pass inet proto icmp icmp-type $icmp_types
. . .
Ihre vorherigen SSH- und ICMP-Regeln verwenden jetzt Makros. Die Variablennamen werden mit der Dollarzeichensyntax von PF bezeichnet. Sie weisen Ihre vtnet0
-Schnittstelle aus Formalitätsgründen einer Variable mit dem gleichen Namen zu, was Ihnen die Option bietet, sie bei Bedarf in Zukunft umzubenennen. Andere gängige Variablennamen für öffentliche Schnittstellen sind unter anderem $pub_if
oder $ext_if
.
Als Nächstes implementieren Sie eine Tabelle, die einem Makro ähnelt, jedoch der Aufnahme von Gruppen von IP-Adressen dient. Erstellen wir nun eine Tabelle für nicht routingfähige IP-Adressen, die oft bei Denial of Service-Angriffen (DOS) eine Rolle spielen. Sie können die in RFC6890 angegebenen IP-Adressen verwenden, in der spezielle IP-Adresseinträge definiert sind. Ihr Server sollte über die öffentliche Schnittstelle keine Pakete an diese Adressen senden oder von diesen Adressen empfangen.
Erstellen Sie diese Tabelle, indem Sie den folgenden Inhalt direkt unter dem Makro icmp_types
hinzufügen:
. . .
table <rfc6890> { 0.0.0.0/8 10.0.0.0/8 100.64.0.0/10 127.0.0.0/8 169.254.0.0/16 \
172.16.0.0/12 192.0.0.0/24 192.0.0.0/29 192.0.2.0/24 192.88.99.0/24 \
192.168.0.0/16 198.18.0.0/15 198.51.100.0/24 203.0.113.0/24 \
240.0.0.0/4 255.255.255.255/32 }
. . .
Fügen Sie nun Ihre Regeln für die Tabelle <rfc6890>
unter der Regel set skip on lo0
hinzu:
. . .
set skip on lo0
block in quick on egress from <rfc6890>
block return out quick on egress to <rfc6890>
. . .
Hier geben Sie die return
-Option ein, die Ihre block out
-Regel ergänzt. Damit werden die Pakete verworfen; zudem wird eine RST-Nachricht an den Host gesendet, der versucht hat, diese Verbindungen herzustellen. Das hilft bei der Analyse der Hostaktivität. Dann fügen Sie das Schlüsselwort egress
hinzu, um automatisch die Standardrouten für die jeweiligen Schnittstellen zu finden. Dies ist in der Regel eine sauberere Methode für die Suche nach Standardrouten, insbesondere bei komplexen Netzwerken. Das Schlüsselwort quick
führt die Regeln sofort aus, ohne den Rest des Regelsatzes zu berücksichtigen. Wenn beispielsweise ein Paket mit unlogischen IP-Adressen versucht, sich mit dem Server zu verbinden, sollte die Verbindung sofort verworfen werden und es gibt keinen Grund dafür, das Paket im Laufe des verbleibenden Regelsatzes auszuführen.
Da Ihr SSH-Port für die Öffentlichkeit geöffnet ist, kann er missbraucht werden. Ein offensichtliches Warnzeichen, das auf einen Angreifer hinweist, ist eine große Zahl von Anmeldeversuchen. Wenn beispielsweise die gleiche IP-Adresse zehnmal in einer Sekunde versucht, sich bei Ihrem Server anzumelden, können Sie davon ausgehen, dass dies nicht durch menschliche Hände geschieht, sondern durch Computersoftware, die versucht hat, Ihr Anmeldepasswort zu knacken. Diese Arten von systematischen Exploits werden oft als Brute Force-Angriffe bezeichnet und sind in der Regel erfolgreich, wenn der Server schwache Passwörter aufweist.
Warnung: Wir empfehlen für alle Server dringend die Verwendung einer Authentifizierung mit öffentlichen Schlüsseln. Konsultieren Sie das Tutorial von DigitalOcean zu schlüsselbasierter Authentifizierung.
PF verfügt über integrierte Funktionen für die Handhabung von Brute Force- und ähnlichen Angriffen. Mit PF können Sie die Anzahl von gleichzeitigen Verbindungsversuchen, die von einem einzelnen Host zulässig sind, einschränken. Wenn ein Host diese Grenzwerte überschreitet, wird die Verbindung verworfen und der Host vom Server verbannt. Dazu verwenden Sie den Überladungsmechanismus von PF, der eine Tabelle mit gesperrten IP-Adressen pflegt.
Ändern Sie Ihre vorherige SSH-Regel, um die Anzahl der gleichzeitigen Verbindungen von einem einzelnen Host wie folgt zu begrenzen:
. . .
pass in on $vtnet0 proto tcp to port { 22 } \
keep state (max-src-conn 15, max-src-conn-rate 3/1, \
overload <bruteforce> flush global)
. . .
Sie fügen die Option keep state
hinzu, mit der Sie die Zustandskriterien für die Überladungstabelle definieren können. Sie übergeben den Parameter max-src-conn
, um die Anzahl der gleichzeitigen Verbindungen anzugeben, die von einem einzelnen Host pro Sekunde erlaubt sind, sowie den Parameter max-src-conn-rate
, um die Anzahl der neuen Verbindungen anzugeben, die von einem einzelnen Host pro Sekunde erlaubt sind. Sie geben 15
Verbindungen für max-src-conn
und 3
Verbindungen für max-src-conn-rate
an. Wenn diese Grenzwerte von einem Host überschritten werden, fügt der Mechanismus für die Überladung
die Quell-IP-Adresse der Tabelle <bruteforce>
hinzu, um diesen Host vom Server zu verbannen. Schließlich sorgt die Option flush global
dafür, dass die Verbindung sofort verworfen wird.
Sie haben in Ihrer SSH-Regel eine Überladungstabelle definiert, die Tabelle jedoch noch nicht in Ihrem Regelsatz deklariert.
Fügen Sie die Tabelle <bruteforce>
unter dem Makro icmp_types
hinzu:
. . .
icmp_types = "{ echoreq }"
table <bruteforce> persist
. . .
Das Schlüsselwort persist
ermöglicht es, dass im Regelsatz eine leere Tabelle existiert. Ohne dieses Schlüsselwort wird sich PF beschweren, dass es in der Tabelle keine IP-Adressen gibt.
Diese Maßnahmen stellen sicher, dass Ihr SSH-Port durch einen leistungsstarken Sicherheitsmechanismus geschützt ist. PF ermöglicht Ihnen eine Konfiguration von schnellen Lösungen, um Sie vor katastrophalen Formen von Exploits zu schützen. In den nächsten Abschnitten ergreifen Sie Schritte zur Bereinigung von Paketen bei ihrer Ankunft am Server.
Anmerkung: In den folgenden Abschnitten werden die Grundlagen der TCP/IP-Protokoll-Suite beschrieben. Wenn Sie das Einrichten von Webanwendungen oder Netzwerken planen, ist es in Ihrem Interesse, diese Konzepte zu beherrschen. Sehen Sie sich das Tutorial von DigitalOcean Einführung in Netzwerkterminologie, -schnittstellen und -protokolle an.
Aufgrund der Komplexität der TCP/IP-Protokoll-Suite und der Hartnäckigkeit von bösartigen Akteuren kommen Pakete oft mit Diskrepanzen und Unklarheiten (wie überlappende IP-Fragmente, falsche IP-Adressen usw.) an. Es ist dringend geboten, Ihren Datenverkehr zu bereinigen, bevor er in das System gelangt. Der technische Begriff für dieses Verfahren ist Normalisierung.
Wenn Daten über das Internet übertragen werden, werden sie in der Regel an ihrer Quelle in kleinere Fragmente zerlegt, um die Übertragungsparameter des Zielhosts zu erfüllen, wo sie wieder zu kompletten Paketen zusammengesetzt werden. Leider können Angreifer diesen Prozess auf verschiedene Arten, die über den Umfang dieses Tutorials hinausgehen, kapern. Dank PF können Sie Fragmentierung jedoch mit einer Regel verwalten. PF enthält ein Schlüsselwort scrub
, das Pakete normalisiert.
Fügen Sie das Schlüsselwort scrub
direkt vor der Regel block all
hinzu:
. . .
set skip on lo0
scrub in all fragment reassemble max-mss 1440
block all
. . .
Diese Regel wendet Bereinigung auf allen eingehenden Datenverkehr an. Sie fügen die Option fragment reassemble
hinzu, die verhindert, dass Fragmente in das System gelangen. Stattdessen werden sie im Arbeitsspeicher zwischengespeichert, bis sie wieder zu kompletten Paketen zusammengesetzt werden; das bedeutet, dass Ihre Filterregeln nur einheitliche Pakete handhaben müssen. Außerdem fügen Sie die Option max-mss 1440
hinzu, die die maximale Segmentgröße von wieder zusammengesetzten TCP-Paketen repräsentiert (auch als Nutzlast bezeichnet). Sie geben einen Wert von 1.440 Byte an, was ein geeignetes Gleichgewicht zwischen Größe und Leistung darstellt, sodass viel Platz für die Header bleibt.
Ein weiterer wichtiger Aspekt der Fragmentierung ist ein Begriff, der als maximale Übertragungseinheit (MTU) bekannt ist. Die TCP/IP-Protokolle erlauben es Geräten, Paketgrößen zur Herstellung von Verbindungen auszuhandeln. Der Zielhost verwendet ICMP-Nachrichten, um die Quell-IP-Adresse seiner MTU zu informieren (ein Prozess, der als MTU-Pfadsuche bezeichnet wird). Der spezifische ICMP-Nachrichtentyp lautet Ziel nicht erreichbar. Sie aktivieren die MTU-Pfadsuche, indem Sie den Nachrichtentyp unreach
in Ihre Liste icmp_types
aufnehmen.
Sie verwenden die Standard-MTU Ihres Servers von 1.500 Byte, die mit dem Befehl ifconfig
festgelegt werden kann:
- ifconfig
Sie sehen die folgende Ausgabe, die Ihre aktuelle MTU enthält:
Outputvtnet0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500 options=6c07bb<RXCSUM,TXCSUM,VLAN_MTU,VLAN_HWTAGGING,JUMBO_MTU,VLAN_HWCSUM,TSO4,TSO6,LRO,VLAN_HWTSO,LINKSTATE,RXCSUM_IPV6,TXCSUM_IPV6>
. . .
Aktualisieren Sie die Liste icmp_types
, um den Nachrichtentyp Ziel nicht erreichbar aufzunehmen:
vtnet0 = "vtnet0"
icmp_types = "{ echoreq unreach}"
. . .
Nachdem Sie nun über Richtlinien zum Umgang mit Fragmentierung verfügen, sind die Pakete, die in Ihr System gelangen, einheitlich und konsistent. Dies ist wünschenswert, da es extrem viele verschiedene Geräte gibt, die Daten über das Internet austauschen.
Sie werden nun daran arbeiten, ein anderes Sicherheitsproblem zu verhindern, das als IP-Spoofing bekannt ist. Angriffe ändern oftmals ihre Quell-IP-Adressen, um so zu tun, als befänden sie sich innerhalb des Unternehmens in einem vertrauenswürdigen Knoten. PF umfasst eine Antispoofing-Direktive für den Umgang mit gespooften Quell-IP-Adressen. Wenn es auf eine bestimmte Schnittstelle angewendet wird, sperrt Antispoofing allen Datenverkehr aus dem Netzwerk an dieser Schnittstelle (es sei denn, er stammt von dieser Schnittstelle). Wenn Sie zum Beispiel Antispoofing auf Schnittstellen anwenden, die sich bei 5.5.5.1/24
befinden, kann der gesamte Datenverkehr vom Netzwerk 5.5.5.0/24
nicht mit dem System kommunizieren, es sei denn, er stammt von diesen Schnittstellen.
Fügen Sie den folgenden hervorgehobenen Inhalt hinzu, um Antispoofing auf Ihre vtnet0
-Schnittstelle anzuwenden:
. . .
set skip on lo0
scrub in
antispoof quick for $vtnet0
block all
. . .
Speichern und schließen Sie die Datei.
Diese Antispoofing-Regel besagt, dass der gesamte Datenverkehr von vtnet0
-Netzwerken nur über die vtnet0
-Schnittstelle übertragen werden darf; andernfalls wird der Datenverkehr mit dem Schlüsselwort quick
sofort verworfen. Bösartige Akteure können sich so nicht im Netzwerk von vtnet0
verstecken und mit anderen Knoten kommunizieren.
Um Ihre Antispoofing-Regel zu testen, drucken Sie Ihren Regelsatz auf dem Bildschirm in ausführlicher Form aus. Regeln in PF sind typischerweise in einer verkürzten Form verfasst, können aber auch in einer ausführlichen Form geschrieben sein. Es ist im Allgemeinen unpraktisch, Regeln ausführlich zu schreiben, kann aber für Testzwecke hilfreich sein.
Drucken Sie den Inhalt von /etc/pf.conf
mit pfctl
und dem folgenden Befehl:
- sudo pfctl -nvf /etc/pf.conf
Der Befehl pfctl
benötigt die Flags -nvf
, die den Regelsatz drucken und testen, ohne dass irgendetwas tatsächlich geladen wird (auch als Probelauf bekannt). Sie sehen nun den gesamten Inhalt von /etc/pf.conf
in seiner ausführlichen Form.
Sie sehen im Antispoofing-Abschnitt etwas, das der folgenden Ausgabe ähnelt:
Output. . .
block drop in quick on ! vtnet0 inet from your_server_ip/20 to any
block drop in quick on ! vtnet0 inet from network_address/16 to any
block drop in quick inet from your_server_ip to any
block drop in quick inet from network_address to any
block drop in quick on vtnet0 inet6 from your_IPv6_address to any
. . .
Ihre Antispoofing-Regel hat erkannt, dass sie Teil des Netzwerks your_server_ip/20
ist. Außerdem hat sie ermittelt, dass der Server (im Beispiel dieses Tutorials) Teil eines network_address/16
-Netzwerks ist und über eine zusätzliche IPv6-Adresse verfügt. Antispoofing hindert alle diese Netzwerke daran, mit dem System zu kommunizieren, es sei denn, ihr Datenverkehr wird über die vtnet0
-Schnittstelle übertragen.
Ihre Antispoofing-Regel ist die letzte Ergänzung zu Ihrem Basisregelsatz. Im nächsten Schritt werden Sie diese Änderungen initiieren und einige Tests durchführen.
In diesem Schritt überprüfen und testen Sie Ihren Basisregelsatz, um sicherzustellen, dass alles richtig funktioniert. Am besten vermeiden Sie es, zu viele Regeln auf einmal zu implementieren, ohne sie getestet zu haben. Eine bewährte Methode besteht darin, mit den Grundlagen zu beginnen, inkrementell zu erweitern und Ergebnisse bei Konfigurationsänderungen zu sichern.
Hier ist Ihr vollständiger Basisregelsatz:
vtnet0 = "vtnet0"
icmp_types = "{ echoreq unreach }"
table <bruteforce> persist
table <rfc6890> { 0.0.0.0/8 10.0.0.0/8 100.64.0.0/10 127.0.0.0/8 169.254.0.0/16 \
172.16.0.0/12 192.0.0.0/24 192.0.0.0/29 192.0.2.0/24 192.88.99.0/24 \
192.168.0.0/16 198.18.0.0/15 198.51.100.0/24 203.0.113.0/24 \
240.0.0.0/4 255.255.255.255/32 }
set skip on lo0
scrub in all fragment reassemble max-mss 1440
antispoof quick for $vtnet0
block in quick on $vtnet0 from <rfc6890>
block return out quick on egress to <rfc6890>
block all
pass in on $vtnet0 proto tcp to port { 22 } \
keep state (max-src-conn 15, max-src-conn-rate 3/1, \
overload <bruteforce> flush global)
pass out proto { tcp udp } to port { 22 53 80 123 443 }
pass inet proto icmp icmp-type $icmp_types
Stellen Sie sicher, dass Ihre Datei /etc/pf.conf
mit diesem vollständigen Basisregelsatz übereinstimmt, bevor Sie fortfahren. Speichern und schließen Sie die Datei dann.
Ihr vollständiger Basisregelsatz bietet Ihnen:
Führen Sie den folgenden pfctl
-Befehl aus, um einen Probelauf vorzunehmen:
- sudo pfctl -nf /etc/pf.conf
Sie übergeben die -nf
-Flags, die pfctl
anweisen, den Regelsatz auszuführen, ohne ihn zu laden. Das führt zur Ausgabe von Fehlern, wenn etwas falsch ist.
Laden Sie nun, da keine Fehler gefunden wurden, den Regelsatz:
- sudo pfctl -f /etc/pf.conf
Wenn keine Fehler vorliegen, bedeutet dies, dass Ihr Basisregelsatz aktiv ist und ordnungsgemäß funktioniert. Wie zuvor in diesem Tutorial führen Sie einige Tests für Ihren Regelsatz aus.
Prüfen Sie zunächst die Internetverbindung und den DNS-Dienst:
- ping -c 3 google.com
Sie sehen die folgende Ausgabe:
OutputPING google.com (172.217.0.46): 56 data bytes
64 bytes from 172.217.0.46: icmp_seq=0 ttl=56 time=2.088 ms
64 bytes from 172.217.0.46: icmp_seq=1 ttl=56 time=1.469 ms
64 bytes from 172.217.0.46: icmp_seq=2 ttl=56 time=1.466 ms
--- google.com ping statistics ---
3 packets transmitted, 3 packets received, 0.0% packet loss
round-trip min/avg/max/stddev = 1.466/1.674/2.088/0.293 ms
Überprüfen Sie dann, ob Sie das Repository pkgs
erreichen können:
- sudo pkg upgrade
Aktualisieren Sie wiederum Pakete, wenn dies benötigt wird.
Starten Sie schließlich Ihren Server neu:
- sudo reboot
Geben Sie Ihrem Server einige Minuten zum Neustart. Sie haben Ihren Basisregelsatz fertig gestellt und implementiert, was ein signifikanter Fortschritt ist. Sie können nun einige der fortgeschrittenen Funktionen von PF erkunden. Im nächsten Schritt verhindern Sie auch Brute Force-Angriffe.
Mit der Zeit füllt sich die Überladungstabelle <bruteforce>
mit bösartigen IP-Adressen; darum müssen Sie sie regelmäßig löschen. Es ist unwahrscheinlich, dass ein Angreifer die gleiche IP-Adresse weiter verwenden wird. Daher ist es wenig sinnvoll, sie für lange Zeiträume in der Überladungstabelle zu speichern.
Sie verwenden pfctl
mit dem folgenden Befehl, um IP-Adressen manuell zu löschen, die in der Überladungstabelle für 48 Stunden oder länger gespeichert waren:
- sudo pfctl -t bruteforce -T expire 172800
Sie werden eine Ausgabe sehen, die der folgenden ähnelt:
Output0/0 addresses expired.
Sie übergeben das Flag -t bruteforce
, das für table bruteforce steht, und das Flag -T
, mit dem sich eine Handvoll von integrierten Befehlen ausführen lässt. In diesem Fall führen Sie den Befehl expire
aus, um alle Einträge aus -t bruteforce
zu löschen, wobei der Zeitwert in Sekunden dargestellt wird. Da Sie mit einem neuen Server arbeiten, gibt es in der Überladungstabelle wahrscheinlich noch keine IP-Adressen.
Diese Regel eignet sich für schnelle Korrekturen, eine robustere Lösung bestünde jedoch darin, den Prozess mit cron, dem Auftragsplaner von FreeBSD, zu automatisieren. Lassen Sie uns stattdessen ein Shell-Skript erstellen, das diese Befehlssequenz ausführt.
Erstellen Sie eine Shell-Skript-Datei im Verzeichnis /usr/local/bin
:
- sudo vi /usr/local/bin/clear_overload.sh
Fügen Sie Ihrem Shell-Skript den folgenden Inhalt hinzu:
#!/bin/sh
pfctl -t bruteforce -T expire 172800
Machen Sie die Datei mit dem folgenden Befehl ausführbar:
- sudo chmod 755 /usr/local/bin/clear_overload.sh
Als Nächstes erstellen Sie einen Cron Job. Das sind Jobs, die anhand einer Zeit, die Sie angeben, wiederholt ausgeführt werden. Sie werden häufig für Backups oder andere Prozesse verwendet, die jeden Tag zur gleichen Zeit ausgeführt werden sollen. Sie erstellen Cron-Jobs mit crontab-Dateien. Konsultieren Sie bitte die Hauptseiten, um mehr über cron(8) und crontab(5) zu erfahren.
Erstellen Sie mit dem folgenden Befehl eine crontab-Datei für einen root user:
- sudo crontab -e
Fügen Sie der Datei crontab nun den folgenden Inhalt hinzu:
# minute hour mday month wday command
* 0 * * * /usr/local/bin/clear_overload.sh
Speichern und schließen Sie die Datei.
Anmerkung: Richten Sie jeden Wert an seinem entsprechenden Tabelleneintrag aus, um die Lesbarkeit zu erhöhen, falls Dinge beim Hinzufügen des Inhalts nicht richtig ausgerichtet sind.
Dieser Cron-Job führt jeden Tag um Mitternacht das Skript clear_overload.sh
aus, um IP-Adressen, die 48 Stunden alt sind, aus der Überladungstabelle <bruteforce>
zu entfernen. Als Nächstes fügen Sie Ihrem Regelsatz Anker hinzu.
In diesem Schritt fügen Sie Anker ein, die zur Einbeziehung von Regeln in den Hauptregelsatz dienen, entweder manuell oder aus einer externen Textdatei. Anker können Regelausschnitte, Tabellen und auch andere Anker enthalten, die als verschachtelte Anker bekannt sind. Wir zeigen Ihnen nun, wie Anker funktionieren, indem wir eine Tabelle zu einer externen Datei hinzufügen und sie in Ihren Basisregelsatz einbinden. Ihre Tabelle wird eine Gruppe von internen Hosts enthalten, bei denen Sie verhindern möchten, dass sie sich mit der Außenwelt verbinden können.
Erstellen Sie eine Datei namens /etc/blocked-hosts-anchor
:
- sudo vi /etc/blocked-hosts-anchor
Fügen Sie der Datei folgende Inhalte hinzu:
table <blocked-hosts> { 192.168.47.1 192.168.47.2 192.168.47.3 }
block return out quick on egress from <blocked-hosts>
Speichern und schließen Sie die Datei.
Diese Regeln deklarieren und definieren die Tabelle <blocked-hosts>
und hindern dann alle IP-Adressen in der Tabelle <blocked-hosts>
daran, auf Dienste aus der Außenwelt zuzugreifen. Sie verwenden das Schlüsselwort egress
als bevorzugte Methode zum Auffinden der Standardroute oder als Weg hinaus in das Internet.
Sie müssen den Anker noch in Ihrer Datei /etc/pf.conf
deklarieren:
- sudo vi /etc/pf.conf
Fügen Sie nun nach der Regel block all
die folgenden Ankerregeln hinzu:
. . .
block all
anchor blocked_hosts
load anchor blocked_hosts from "/etc/blocked-hosts-anchor"
. . .
Speichern und schließen Sie die Datei.
Diese Regeln deklarieren die Tabelle blocked_hosts
und laden die Ankerregeln aus der Datei /etc/blocked-hosts-anchor
in Ihren Hauptregelsatz.
Initiieren Sie nun diese Änderungen durch Neuladen Ihres Regelsatzes mit pfctl
:
- sudo pfctl -f /etc/pf.conf
Wenn keine Fehler vorhanden sind, bedeutet dies, dass es keine Fehler im Regelsatz gibt und Ihre Änderungen aktiv sind.
Verwenden Sie pfctl
, um zu überprüfen, ob Ihr Anker ausgeführt wird:
- sudo pfctl -s Anchors
Das Flag -s Anchors
steht für “show anchors” (Anker anzeigen). Sie sehen die folgende Ausgabe:
Outputblocked_hosts
Das Dienstprogramm pfctl
kann außerdem die spezifischen Regeln Ihres Ankers mit den Flags -a
und -s
parsen:
- sudo pfctl -a blocked_hosts -s rules
Sie sehen die folgende Ausgabe:
Outputblock return out quick on egress from <blocked-hosts> to any
Eine weitere Eigenschaft von Ankern besteht darin, dass sie es erlauben, Regeln bei Bedarf hinzuzufügen, ohne dass der Regelsatz neu geladen werden muss. Dies kann nützlich sein für Tests, schnelle Problembehebungen, Notfälle und so weiter. Wenn sich ein interner Host beispielsweise merkwürdig verhält und Sie ihn daran hindern möchten, ausgehende Verbindungen herzustellen, kann ein Anker eingerichtet werden, der es Ihnen ermöglicht, schnell über die Befehlszeile einzugreifen.
Öffnen Sie die Datei /etc/pf.conf
und fügen Sie einen weiteren Anker hinzu:
- sudo vi /etc/pf.conf
Sie nennen den Anker rogue_hosts
und platzieren ihn in der Regel block all
:
. . .
block all
anchor rogue_hosts
. . .
Speichern und schließen Sie die Datei.
Um diese Änderungen zu initiieren, laden Sie den Regelsatz mit pfctl
neu:
- sudo pfctl -f /etc/pf.conf
Verwenden Sie erneut pfctl
, um zu überprüfen, ob der Anker ausgeführt wird:
- sudo pfctl -s Anchors
Dadurch erhalten Sie folgende Ausgabe:
Outputblocked_hosts
rogue_hosts
Jetzt wo der Anker ausgeführt wird, können Sie jederzeit Regeln hinzufügen. Testen Sie dies durch Hinzufügen der folgenden Regel:
- sudo sh -c 'echo "block return out quick on egress from 192.168.47.4" | pfctl -a rogue_hosts -f -'
Dadurch werden der Befehl echo
und der Inhalt seiner Zeichenfolge aufgerufen, was dann mit dem Symbol |
in das Dienstprogramm pfctl
übertragen und dort zu einer Ankerregel verarbeitet wird. Öffnen Sie mit dem Befehl sh-c
eine weitere Shell-Sitzung. Das liegt daran, dass Sie eine Pipe zwischen zwei Prozessen einrichten, aber sudo
-Berechtigungen benötigen, damit in der gesamten Befehlssequenz Persistenz herrscht. Es gibt verschiedene Möglichkeiten, um dies zu lösen; hier öffnen Sie einen zusätzlichen Shell-Prozess mit sudo-Berechtigungen unter Verwendung von sudo sh -c
.
Verwenden Sie nun erneut pfctl
, um sich zu vergewissern, dass diese Regeln aktiv sind:
- sudo pfctl -a rogue_hosts -s rules
Dadurch erhalten Sie folgende Ausgabe:
Outputblock return out quick on egress inet from 192.168.47.4 to any
Die Verwendung von Ankern ist vollständig situationsabhängig und oftmals subjektiv. Wie bei jeder anderen Funktion ist der Einsatz von Ankern mit Vor-und Nachteilen verbunden. Manche Anwendungen wie z. B. blacklistd verbinden sich absichtlich mit Ankern. Als Nächstes konzentrieren Sie sich auf die Protokollierung mit PF, was ein kritischer Aspekt der Netzwerksicherheit ist. Ihre Firewall nützt wenig, wenn Sie nicht sehen können, was sie tut.
In diesem Schritt arbeiten Sie mit der Protokollierung von PF, die von einer Pseudoschnittstelle namens pflog
verwaltet wird. Das Protokollieren wird zur Startzeit aktiviert, indem Sie pflog_enabled=YES
zur Datei /etc/rc.conf
hinzufügen; das haben Sie in Schritt 2 getan. Dadurch wird der Daemon pflogd aktiviert, der eine Schnittstelle namens pflog0
hervorbringt und Protokolle im Binärformat in eine Datei namens /var/log/pflog
schreibt. Protokolle können von der Schnittstelle in Echtzeit analysiert oder mit dem Dienstprogramm tcpdump(8) aus der Datei /var/log/pflog
gelesen werden.
Greifen Sie zunächst auf einige Protokolle aus der Datei /var/log/pflog
zu:
- sudo tcpdump -ner /var/log/pflog
Sie übergeben die Flags -ner
, die die Ausgabe zur besseren Lesbarkeit formatieren, und geben auch eine Datei an, die ausgelesen werden soll (in Ihrem Fall /var/log/pflog
).
Sie sehen die folgende Ausgabe:
Outputreading from file /var/log/pflog, link-type PFLOG (OpenBSD pflog file)
In dieser frühen Phase sind in der Datei /var/log/pflog
möglicherweise noch keine Daten vorhanden. Innerhalb kurzer Zeit beginnt die Protokolldatei zu wachsen.
Sie können die Protokolle auch in Echtzeit über die pflog0
-Schnittstelle anzeigen, indem Sie den folgenden Befehl verwenden:
- sudo tcpdump -nei pflog0
Sie übergeben die Flags -nei
, die ebenfalls die Ausgabe zur besseren Lesbarkeit formatieren; dieses Mal geben Sie jedoch eine Schnittstelle an (in Ihrem Fall pflog0
).
Sie sehen die folgende Ausgabe:
Outputtcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on pflog0, link-type PFLOG (OpenBSD pflog file), capture size 262144 bytes
Sie sehen nun Verbindungen in Echtzeit. Wenn dies möglich ist, senden Sie von einem Remotecomputer einen Ping an Ihren Server um zu sehen, welche Verbindungen es gibt. Der Server bleibt in diesem Zustand, bis Sie ihn beenden.
Um diesen Zustand zu beenden und zur Befehlszeile zurückzukehren, drücken Sie Strg + Z
.
Über tcpdump(8) gibt es eine Fülle von Informationen im Internet, einschließlich der offiziellen Website.
Das Dienstprogramm pftop
ist ein Tool zur schnellen Betrachtung der Firewall-Aktivitäten in Echtzeit. Sein Name ist vom bekannten Unix-Dienstprogramm top
beeinflusst.
Um das Programm verwenden zu können, müssen Sie das Paket pftop
installieren:
- sudo pkg install pftop
Führen Sie nun die Binärdatei pftop
aus:
- sudo pftop
Dadurch wird die folgende Ausgabe generiert (Ihre IP-Adressen werden sich unterscheiden):
OutputPR DIR SRC DEST STATE AGE EXP PKTS BYTES
tcp In 251.155.237.90:27537 157.225.173.58:22 ESTABLISHED:ESTABLISHED 00:12:35 23:59:55 1890 265K
tcp In 222.186.42.15:25884 157.225.173.58:22 TIME_WAIT:TIME_WAIT 00:01:25 00:00:06 22 3801
udp Out 157.245.171.59:4699 67.203.62.5:53 MULTIPLE:SINGLE 00:00:14 00:00:16 2 227
Wie bei anderen Schnittstellen auch können mehrere Protokollschnittstellen erstellt und mit einer /etc/hostname
-Datei benannt werden. Sie finden dies ggf. nützlich für organisatorische Zwecke, z. B. wenn Sie bestimmte Arten von Aktivitäten getrennt protokollieren möchten.
Erstellen Sie eine zusätzliche Protokollierungsschnittstelle namens pflog1
:
- sudo vi /etc/hostname.pflog1
Fügen Sie der Datei /etc/hostname.pflog1
folgende Inhalte hinzu:
up
Aktivieren Sie nun das Gerät zur Startzeit in Ihrer Datei /etc/rc.conf
:
- sudo sysrc pflog1_enable="YES"
Jetzt können Sie Ihre Firewall überwachen und protokollieren. Dadurch sehen Sie, wer Verbindungen mit Ihrem Server herstellt und welche Arten von Verbindungen hergestellt werden.
In diesem Tutorial haben Sie einige erweiterte Konzepte in Ihren PF-Regelsatz eingefügt. Es ist nur notwendig, erweiterte Funktionen zu implementieren, wenn Sie sie tatsächlich benötigen. In jedem Fall setzen Sie alles im nächsten Schritt wieder auf den Basisregelsatz zurück.
In diesem abschließenden Abschnitt kehren Sie wieder zu Ihrem Basisregelsatz zurück. Dies ist ein schneller Schritt, der Sie wieder in einen minimalen Funktionsstand zurückversetzt.
Öffnen Sie den Basisregelsatz mit dem folgenden Befehl:
- sudo vi /etc/pf.conf
Löschen Sie den aktuellen Regelsatz in Ihrer Datei und ersetzen Sie ihn durch den folgenden Basisregelsatz:
vtnet0 = "vtnet0"
icmp_types = "{ echoreq unreach }"
table <bruteforce> persist
table <rfc6890> { 0.0.0.0/8 10.0.0.0/8 100.64.0.0/10 127.0.0.0/8 169.254.0.0/16 \
172.16.0.0/12 192.0.0.0/24 192.0.0.0/29 192.0.2.0/24 192.88.99.0/24 \
192.168.0.0/16 198.18.0.0/15 198.51.100.0/24 203.0.113.0/24 \
240.0.0.0/4 255.255.255.255/32 }
set skip on lo0
scrub in all fragment reassemble max-mss 1440
antispoof quick for $vtnet0
block in quick on $vtnet0 from <rfc6890>
block return out quick on egress to <rfc6890>
block all
pass in on $vtnet0 proto tcp to port { 22 } \
keep state (max-src-conn 15, max-src-conn-rate 3/1, \
overload <bruteforce> flush global)
pass out proto { tcp udp } to port { 22 53 80 123 443 }
pass inet proto icmp icmp-type $icmp_types
Speichern und schließen Sie die Datei.
Laden Sie den Regelsatz neu:
- sudo pfctl -f /etc/pf.conf
Wenn es keine Fehler durch den Befehl gibt, heißt das, dass es auch keine Fehler in Ihrem Regelsatz gibt und Ihre Firewall ordnungsgemäß funktioniert.
Außerdem müssen Sie die von Ihnen erstellte pflog1
-Schnittstelle deaktivieren. Da Sie ggf. nicht wissen, ob Sie sie noch benötigen, können Sie pflog1
mit dem Dienstprogramm sysrc
deaktivieren:
- sudo sysrc pflog1_enable="NO"
Entfernen Sie nun die Datei /etc/hostname.pflog1
aus dem Verzeichnis /etc
:
- sudo rm /etc/hostname.pflog1
Starten Sie vor der Abmeldung den Server neu, um sicherzustellen, dass alle Ihre Änderungen aktiv und persistent sind:
- sudo reboot
Warten Sie ein paar Minuten, bevor Sie sich wieder bei Ihrem Server anmelden.
Wenn Sie PF optional mit einem Webserver implementieren möchten, stellt Folgendes einen Regelsatz für dieses Szenario dar. Dieser Regelsatz ist ein ausreichender Ausgangspunkt für die meisten Webanwendungen.
vtnet0 = "vtnet0"
icmp_types = "{ echoreq unreach }"
table <bruteforce> persist
table <webcrawlers> persist
table <rfc6890> { 0.0.0.0/8 10.0.0.0/8 100.64.0.0/10 127.0.0.0/8 169.254.0.0/16 \
172.16.0.0/12 192.0.0.0/24 192.0.0.0/29 192.0.2.0/24 192.88.99.0/24 \
192.168.0.0/16 198.18.0.0/15 198.51.100.0/24 203.0.113.0/24 \
240.0.0.0/4 255.255.255.255/32 }
set skip on lo0
scrub in all fragment reassemble max-mss 1440
antispoof quick for $vtnet0
block in quick on $vtnet0 from <rfc6890>
block return out quick on egress to <rfc6890>
block all
pass in on $vtnet0 proto tcp to port { 22 } \
keep state (max-src-conn 15, max-src-conn-rate 3/1, \
overload <bruteforce> flush global)
pass in on $vtnet0 proto tcp to port { 80 443 } \
keep state (max-src-conn 45, max-src-conn-rate 9/1, \
overload <webcrawlers> flush global)
pass out proto { tcp udp } to port { 22 53 80 123 443 }
pass inet proto icmp icmp-type $icmp_types
Damit wird eine Überladungstabelle namens <webcrawlers>
erstellt, die eine liberalere Überladungsrichtlinie aufweist als Ihr SSH-Port – auf Grundlage der Werte von max-src-conn 45
und max-src-conn-rate
. Das liegt daran, dass nicht alle Überladungen von bösartigen Akteuren stammen. Sie können auch von nicht bösartigen Netbots stammen, sodass Sie übermäßige Sicherheitsmaßnahmen an den Ports 80
und 443
vermeiden. Wenn Sie sich entscheiden, den Regelsatz für Webserver zu implementieren, müssen Sie die Tabelle <webcrawlers>
der Datei /etc/pf.conf
hinzufügen und die IP-Adressen regelmäßig aus der Tabelle löschen. Konsultieren Sie diesbezüglich Schritt 5.
In diesem Tutorial haben Sie PF unter FreeBSD 12.1 konfiguriert. Sie verfügen nun über einen Basisregelsatz, der als Ausgangspunkt für alle Ihre FreeBSD-Projekte dienen kann. Weitere Informationen zu PF finden Sie in den man-Seiten zu pf.conf(5).
Besuchen Sie unsere FreeBSD-Themenseite für weitere Tutorials sowie Fragen und Antworten.
Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.
This textbox defaults to using Markdown to format your answer.
You can type !ref in this text area to quickly search our full set of tutorials, documentation & marketplace offerings and insert the link!