Tutorial

Konfigurieren von Packet Filter (PF) unter FreeBSD 12.1

SecurityFirewallFreeBSD

Der Autor hat den COVID-19 Relief Fund dazu ausgewählt, eine Spende im Rahmen des Programms Write for DOnations zu erhalten.

Einführung

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.

Voraussetzungen

Bevor Sie mit diesem Tutorial beginnen, benötigen Sie Folgendes:

  • Einen 1G FreeBSD 12.1-Server (entweder ZFS oder UFS). Sie können unser Tutorial Erste Schritte mit FreeBSD nutzen, um Ihren Server mit Ihrer bevorzugten Konfiguration einzurichten.
  • Standardmäßig ist bei FreeBSD keine Firewall aktiviert – Anpassung ist ein besonderes Kennzeichen des Ethos von FreeBSD. Wenn Sie Ihren Server zum ersten Mal starten, benötigen Sie also vorübergehend Schutz, während PF konfiguriert wird. Wenn Sie DigitalOcean verwenden, können Sie Ihre Cloud-Firewall sofort nach dem Starten des Servers aktivieren. Konsultieren Sie den Firewall Schnellstart von DigitalOcean, um Anweisungen zur Konfiguration einer Cloud-Firewall zu erhalten. Wenn Sie einen anderen Cloud-Anbieter nutzen, bestimmen Sie den schnellsten Weg, um vor dem Loslegen sofortigen Schutz zu erreichen. Egal welche Methode Sie wählen, darf Ihre temporäre Firewall nur eingehenden SSH-Verkehr zulassen, dafür aber alle Arten von ausgehendem Datenverkehr zulassen.

Schritt 1 — Erstellen Ihres vorläufigen Regelsatzes

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:

/etc/pf.conf
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:

/etc/pf.conf
block all
pass in proto tcp to port 22

Anmerkung: Alternativ können Sie den Namen des Protokolls verwenden:

/etc/pf.conf
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:

/etc/pf.conf
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:

Preliminary Ruleset /etc/pf.conf
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.

Schritt 2 — Testen Ihres vorläufigen Regelsatzes

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:

Output
pf_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):

Output
Status: 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:

Output
PING 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.

Schritt 3 — Vervollständigen Ihres Basisregelsatzes

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.

Integration von Makros und Tabellen

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:

/etc/pf.conf
vtnet0 = "vtnet0"
icmp_types = "{ echoreq }"
. . .

Ändern Sie Ihre vorherigen SSH- und ICMP-Regeln mit Ihren neuen Variablen:

/etc/pf.conf
. . .
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:

/etc/pf.conf
. . .
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:

/etc/pf.conf
. . .
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.

Schützen Ihrer SSH-Ports

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:

/etc/pf.conf
. . .
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:

/etc/pf.conf
. . .
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.

Bereinigen Ihres Datenverkehrs

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:

/etc/pf.conf
. . .
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:

Output
vtnet0: 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:

/etc/pf.conf
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:

/etc/pf.conf
. . .
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.

Schritt 4 — Testen Ihres Basisregelsatzes

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:

Base Ruleset /etc/pf.conf
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:

  • Eine Sammlung von Makros, die wichtige Dienste und Geräte definieren können.
  • Richtlinien zur Netzwerkhygiene für Paketfragmentierung und illogische IP-Adressen.
  • Eine default deny-Filterstruktur, die alles blockiert und nur zulässt, was Sie angeben.
  • Eingehenden SSH-Zugriff mit Begrenzungen der Anzahl der gleichzeitigen Verbindungen, die von einem Host hergestellt werden können.
  • Richtlinien für ausgehenden Datenverkehr, die Ihnen Zugriff auf einige kritische Dienste aus dem Internet erlauben.
  • ICMP-Richtlinien, die Zugriff auf das ping-Dienstprogramm und die MTU-Pfadsuche bieten.

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:

Output
PING 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.

Schritt 5 — Verwalten Ihrer Überladungstabelle

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:

Output
0/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:

/usr/local/bin/clear_overload.sh
#!/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:

crontab
# 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.

Schritt 6 — Hinzufügen von Ankern zu Ihren Regelsätzen

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:

/etc/blocked-hosts-anchor
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:

/etc/pf.conf
. . .
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:

Output
blocked_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:

Output
block 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:

/etc/pf.conf
. . .
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:

Output
blocked_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:

Output
block 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.

Schritt 7 — Protokollieren der Aktivität Ihrer Firewall

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:

Output
reading 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:

Output
tcpdump: 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.

Zugreifen auf Protokolldateien mit pftop

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):

Output
PR 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

Erstellen zusätzlicher Protokollschnittstellen

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:

/etc/hostname.pflog1
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.

Schritt 8 — Zurücksetzen auf Ihren Basisregelsatz

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:

/etc/pf.conf
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.

Simple Web Server Ruleset
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.

Zusammenfassung

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.

0 Comments

Creative Commons License