Zum Hauptinhalt springen

FreeBSD-Firewall-Konfiguration mit PF

Veröffentlicht am:
.
25 Minuten Lesezeit
.
Für die Englische Version

Firewalls ermöglichen das Filtern des eingehenden und ausgehenden Datenverkehrs eines Systems. Eine Firewall verwendet ein oder mehrere Sets von "Regeln", um Netzwerkpakete zu bewerten, wenn sie in Netzwerkverbindungen eintreten oder diese verlassen, und entweder den Verkehr zuzulassen oder zu verbieten. Die Regeln einer Firewall überprüfen ein oder mehrere Paketattribute, einschließlich des Protokoltyps, der Quell-/Ziel-Host-Adresse und des Quell-/Ziel-Ports.

Firewalls erhöhen die Sicherheit eines Netzwerks oder Hosts, indem sie die Anwendungen, Dienste und Geräte eines internen Netzwerks vor unerwünschtem Internetverkehr schützen und isolieren. Sie werden verwendet, um den Zugriff von Hosts im internen Netzwerk auf Internetdienste zu begrenzen oder zu deaktivieren. Darüber hinaus unterstützen Firewalls die Netzwerkadressübersetzung (NAT), die es einem internen Netzwerk ermöglicht, private IP-Adressen zu nutzen und eine einzige Verbindung zum öffentlichen Internet über eine einzelne IP-Adresse oder einen Pool automatisch zugewiesener öffentlicher Adressen zu teilen.

In diesem Artikel werden wir behandeln, welche Firewalls FreeBSD verwendet, was der PF, Packet Filter, ist und wie Sie PF-Firewall-Regeln einfach auf Ihrem FreeBSD-Server konfigurieren können.

Welche Firewall verwendet FreeBSD?

Das Basissystem von FreeBSD hat die folgenden drei Firewalls:

  • PF

  • IPFW

  • IPFILTER, auch bekannt als IPF.

FreeBSD unterstützt mehrere Firewalls, um den unterschiedlichen Bedürfnissen und Vorlieben einer großen Anzahl von Benutzern gerecht zu werden. Jede Firewall verwendet Regeln, um den Paketzugriff auf und von einem FreeBSD-System zu steuern, jedoch auf unterschiedliche Weise und mit unterschiedlicher Regel-Syntax. Jeder Benutzer muss wählen, welche Firewall am besten zu seinen Anforderungen passt.

Zusätzlich enthält FreeBSD zwei Traffic Shaper zur Verwaltung der Bandbreitennutzung:

  • ALTQ

  • dummynet

ALTQ hatte historisch gesehen eine enge Beziehung zu PF und dummynet zu IPFW.

Starten Sie noch heute kostenlos mit Zenarmor

Was ist PF?

Packet Filter, auch bekannt als PF oder pf, ist ein BSD-lizenzierter zustandsbehafteter Paketfilter, der verwendet wird, um TCP/IP-Verkehr zu filtern und Network Address Translation durchzuführen. (NAT.) PF wurde von Daniel Hartmeier für OpenBSD erstellt und wird derzeit vom OpenBSD-Team gewartet und weiterentwickelt. PF wurde heute auf mehrere andere Betriebssysteme wie FreeBSD und DragonflyBSD portiert. Seit OpenBSD 3.0 ist PF ein Bestandteil des GENERIC-Kernels.

PF funktioniert hauptsächlich im Kernel-Space, innerhalb des Netzwerkcodes. Basierend auf der Quelle oder dem Ziel eines Pakets sowie dem Protokoll, der Verbindung und dem Port, für den es bestimmt ist, kann PF erkennen, wohin das Paket geleitet werden soll oder ob es durchgelassen werden soll.

Eine der wesentlichsten Funktionen von PF ist, dass es den Datenverkehr erkennen und blockieren kann, den Sie nicht in Ihr lokales Netzwerk lassen oder nach außen weiterleiten möchten. Neben der Normalisierung und Konditionierung des TCP/IP-Verkehrs bietet PF Bandbreitenmanagement und Paketpriorisierung. Der Paketfilter ist ein äußerst flexibles und wertvolles Instrument zur Steuerung der Netzwerkaktivität.

BESTE PRAKTIKEN

Zusätzlich zu seinen effektiven L4-Paketfilter- und Routing-Funktionen bietet FreeBSD auch Next-Generation-Firewall-Funktionen wie Webkontrolle und Anwendungssteuerung. Dies wird durch ein externes Tool namens Zenarmor bereitgestellt.

Zenarmor NGFW Erweiterung ermöglicht es Ihnen, Ihre Firewall in Sekundenschnelle auf eine Next Generation Firewall aufzurüsten. NG Firewalls ermöglichen es Ihnen, modernen Cyberangriffen entgegenzuwirken, die jeden Tag raffinierter werden.

Einige der Funktionen sind Layer-7-Anwendungs-/Benutzer-bewusstes Blockieren, granulare Filterrichtlinien, kommerzielles Webfiltering mit cloudbasierter KI-gestützter Bedrohungserkennung, Kindersicherung und die besten Netzwerk-Analysen und -Berichte der Branche.

Die Zenarmor Free Edition ist für alle FreeBSD-Nutzer kostenlos verfügbar.

Was ist die Geschichte von PF?

Das Paketfilter-Subsystem von OpenBSD, das allgemein mit der Abkürzung 'PF' bezeichnet wird, wurde von Daniel Hartmeier und einer Reihe anderer OpenBSD-Entwickler während der Sommer- und Herbstmonate der Nordhalbkugel im Jahr 2001 geschrieben und wurde im Dezember 2001 als Standardkomponente des OpenBSD 3.0-Basissystems veröffentlicht.

IPFilter von Darren Reed ist seit 1996 Teil der OpenBSD-Basisinstallation. Es wurde entfernt, weil seine Lizenzierung mit OpenBSDs Mission, Software bereitzustellen, die für jeden kostenlos nutzbar, veränderbar und redistributierbar ist, unvereinbar war.

OpenBSD benötigte ein neues Firewall-Software-Subsystem, als Darren Reed die Welt darüber informierte, dass IPFilter, das tief in das Betriebssystem integriert war, tatsächlich nicht BSD-lizenziert war. In Wirklichkeit ist das Gegenteil der Fall. Die Lizenz war fast identisch mit der BSD-Lizenz, mit der Ausnahme der Erlaubnis, den Code zu ändern und die modifizierte Version zu verbreiten. Laut der Lizenz wies die OpenBSD-Version von IPFilter mehrere Modifikationen und Anpassungen auf, die nicht erlaubt waren. IPFilter wurde am 29. Mai 2001 aus dem OpenBSD-Quellbaum gelöscht, und OpenBSD-current fehlte für viele Wochen jegliche Firewall-Software.

Glücklicherweise führte Daniel Hartmeier bereits bescheidene Kernel-Hacking-Tests im Netzwerkcode in der Schweiz durch. Nachdem er eine kleine eigene Funktion an den Netzwerk-Stack angeschlossen und Pakete durch ihn hindurch reisen ließ, begann er schließlich, über Filterung nachzudenken. Dann trat ein Lizenzdilemma auf.

Am 29. Mai wurde IPFilter aus dem Quellbaum entfernt. Der erste Commit des PF-Codes fand am 24. Juni 2001 statt.

Nach einigen Monaten recht aktiver Entwicklung hatte die mit OpenBSD 3.0 veröffentlichte Version von PF eine ziemlich umfassende Implementierung der Paketfilterung, einschließlich der Netzwerkadressübersetzung.

Daniel Hartmeier und die anderen PF-Entwickler scheinen ihr Wissen über den IPFilter-Code effektiv genutzt zu haben. Daniel hielt eine Präsentation auf der USENIX 2002 mit Leistungsexperimenten, die zeigten, dass OpenBSD 3.1 PF unter Stress genauso gut oder besser abschnitt als IPFilter auf derselben Plattform oder iptables auf Linux. Darüber hinaus wurde das ursprüngliche PF von OpenBSD 3.0 getestet. Diese Tests zeigten hauptsächlich, dass der Code zwischen den Versionen 3.0 und 3.1 effizienter geworden war.

OpenBSD verfügte bereits über die ALTQ-Funktionalität zur Verwaltung von Lastenausgleich und Verkehrsformung, bevor PF implementiert wurde. Nach einiger Zeit wurde ALTQ hauptsächlich aus pragmatischen Gründen in PF aufgenommen. Infolgedessen sind all diese Funktionen über eine einzige Konfigurationsdatei, pf.conf, zugänglich, die sich im Verzeichnis /etc/ befindet und praktisch menschenlesbar ist.

Dies ist derzeit Teil des Basissystems von OpenBSD, FreeBSD, NetBSD und DragonflyBSD. Auf FreeBSD ist PF eines von drei Firewall-Systemen, die nach Bedarf geladen werden können.

Wie konfiguriert man die PF-Firewall auf FreeBSD?

Sie können die PF-Firewall auf FreeBSD ganz einfach konfigurieren, um Ihren Server oder Ihr Netzwerk vor Cyberbedrohungen zu schützen, indem Sie die in den folgenden Schritten erläuterten Anweisungen befolgen.

Wie aktiviert man PF?

Bevor PF verwendet werden kann, muss sein Kernel-Modul geladen werden. Sie können PF aktivieren, indem Sie die folgenden Schritte ausführen:

  1. Führen Sie den nächsten Befehl aus, um die Zeile zur Konfigurationsdatei /etc/rc.conf hinzuzufügen.

    echo 'pf_enable="YES"' >> /etc/rc.conf
  2. PF wird nicht gestartet, wenn seine Regeln-Konfigurationsdatei nicht gefunden werden kann. Beispielregeln sind im Verzeichnis /usr/share/examples/pf verfügbar. In unserem Beispiel werden wir unsere Firewall-Regeln zur Datei /etc/pf.conf hinzufügen. Wenn Ihr benutzerdefiniertes Regelset an einem anderen Ort gespeichert wurde, fügen Sie eine Zeile zu /etc/rc.conf hinzu, die den vollständigen Pfad zur Datei angibt:

    echo 'pf_rules="/etc/pf.conf"' >> /etc/rc.conf
  3. Um die Protokollierungsfunktionalität zu aktivieren, fügen Sie pflog enable=yes zu /etc/rc.conf hinzu, indem Sie den folgenden Befehl ausführen:

    echo 'pflog_enable="YES"' >> /etc/rc.conf
  4. Zusätzlich führen Sie die folgenden Befehle aus, um den Standardort der Protokolldatei zu ändern oder um zusätzliche Optionen anzugeben, die pflog beim Start übergeben werden sollen:

    echo 'pflog_logfile="/var/log/pflog"' >> /etc/rc.conf
    echo 'pflog_flags=""' >> /etc/rc.conf
  5. Führen Sie den folgenden Befehl aus, wenn sich hinter der Firewall ein LAN befindet und Pakete an die Maschinen im LAN gesendet werden müssen, oder wenn NAT erforderlich ist:

    echo 'gateway_enable="YES"' >> /etc/rc.conf
  6. Um PF mit Protokollierungsunterstützung zu starten, geben Sie die folgenden Befehle ein:

    service pf start
    service pflog start

    Sie sollten die folgende Ausgabe sehen. Wenn Sie keine Firewall-Regelsatzdatei wie /etc/pf.conf haben, wird eine Warnmeldung angezeigt.

    # service pf start
    pf_enable: NO -> yes
    pf_enable: yes -> yes
    /etc/rc.d/pf: WARNING:/etc/pf.conf is not readable.
    # service pflog start
    pf_enable: yes -> yes
    pf_enable: yes -> yes
    Starting pflog.
  7. Sie können PF mit dem pfctl-Dienstprogramm steuern. Um PF zu aktivieren, können Sie den folgenden Befehl ausführen. Da unser Firewall-Regelsatz noch nicht bereit ist, starten wir die pf-Firewall in diesem Schritt nicht.

    pfctl -e

Wie benutzt man pfctl?

pfctl ist ein Dienstprogramm, das mit dem Paketfiltergerät über die ioctl-Schnittstelle kommuniziert, um das Paketfiltergerät (PF) zu steuern. Es ermöglicht die Konfiguration von Regelsets und Parametern sowie den Abruf von Statusinformationen des Paketfilters. Um die pfctl-Optionen anzuzeigen, führen Sie den folgenden Befehl aus:

pfctl -h

Sie sollten die folgende Ausgabe sehen:

pfctl [-AdeghMmNnOPqRrvz] [-a  anchor] [-D  macro= value] [-F  modifier]
[-f file] [-i interface] [-K host | network] [-k host | network |
label | id | gateway] [-o level] [-p device] [-s modifier] [-t
table -T command [address ...]] [-x level]
  • Um den Paketfilter (PF) zu aktivieren, führen Sie den folgenden Befehl aus:

    pfctl -e
  • Um den Paketfilter (PF) zu deaktivieren, führen Sie den folgenden Befehl aus:

    pfctl -d
  • Um alle NAT-, Filter-, Status- und Tabellenregeln zu leeren und /etc/pf.conf neu zu laden, führen Sie den folgenden Befehl aus:

    pfctl -F all -f /etc/pf.conf
  • Um die derzeit geladenen Filterregeln, NAT-Regeln, die Zustandstabelle oder alle zu sehen, führen Sie den folgenden Befehl aus:

    pfctl -s [ rules | nat | states | all]
  • Überprüfen Sie die Firewall-Regeldatei /etc/pf.conf auf Fehler, ohne die Regeldatei zu laden, führen Sie den folgenden Befehl aus:

    pfctl -vnf /etc/pf.conf

Wie erstellt man PF-Regelsätze?

Beim Start erhält PF seine Konfigurationsregeln aus pf.conf, wie sie von rc-Skripten geladen werden. Beachten Sie, dass pf.conf zwar die Standardkonfigurationsdatei ist und von den System-rc-Skripten importiert wird, es sich jedoch nur um eine Textdatei handelt, die von pfctl geladen und verarbeitet und in pf eingefügt wird. Einige Apps können beim Start zusätzliche Regelsets aus anderen Dateien laden.

Die Datei pf.conf, die Firewall-Regelsatz, hat mehrere Abschnitte:

  • Makros: Vom Benutzer definierte Variablen, die IP-Adressen, Schnittstellennamen usw. enthalten können. Makros können Listen enthalten und müssen vor der Verwendung angegeben werden.

  • Tabellen: eine Struktur zur Speicherung von IP-Adresslisten.

  • Optionen: verschiedene Konfigurationseinstellungen für PF.

  • Filterregeln: ermöglichen das selektive Filtern oder Stoppen von Paketen, während sie eine beliebige Schnittstelle durchlaufen.

Zeilen, die mit # beginnen, werden als Kommentare betrachtet und werden ignoriert, wenn sie leer sind.

Was sind Makros und Listen?

Eine Liste ermöglicht es, zahlreiche vergleichbare Kriterien innerhalb einer Regel anzugeben. Zum Beispiel zahlreiche Protokolle, Portnummern, Adressen usw. Anstatt für jede zu verbietende IP-Adresse eine separate Filterregel festzulegen, kann eine Liste von IP-Adressen in einer einzigen Regel angegeben werden. Klammern, { }, werden verwendet, um Elemente innerhalb einer Liste zu definieren. Wenn pfctl während des Ladens des Regelsets auf eine Liste stößt, generiert es mehrere Regeln, eine für jedes Listenelement. Zum Beispiel:

block out on vtnet0 from { 192.168.0.1, 192.168.0.2 } to any

Dieses pf-Regelsystem mit einer Liste wird auf die folgenden beiden Regeln erweitert:

block out on vtnet0 from 192.168.0.1 to any
block out on vtnet0 from 192.168.0.2 to any

Makros sind benutzerdefinierte Variablen, die unter anderem IP-Adressen, Portnummern und Schnittstellennamen enthalten können. Makros minimieren die Komplexität von PF-Regelsätzen und vereinfachen deren Wartung.

tipp

Die Namen von Makros müssen mit einem Buchstaben beginnen und dürfen Buchstaben, Zahlen und Unterstriche enthalten. Die reservierten Begriffe pass, out und queue dürfen nicht als Makronamen verwendet werden.

tipp

Wenn auf ein Makro verwiesen wird, nachdem es erstellt wurde, wird sein Name mit einem $-Zeichen vorangestellt.

ext_if = "vtnet0"
block in on $ext_if from any to any

Dies erstellt ein Makro mit dem Namen ext_if.

Makros können sich zu Listen erweitern, wie unten angegeben:

web_servers = "{ 192.168.1.1, 192.168.1.2, 192.168.1.3 }"

Dieser Abschnitt zeigt, wie man ein individuelles Regelwerk entwirft. Es beginnt mit dem einfachsten Regelwerk und entwickelt sich anhand mehrerer Beispiele weiter, um die praktische Nutzung der verschiedenen Fähigkeiten von PF zu veranschaulichen.

Das einfachste Regelwerk ist für einen einzelnen Computer, der keine Dienste ausführt und Zugang zu einem einzigen Netzwerk, wie dem Internet, benötigt. Um dieses einfache Regelset zu erstellen, aktualisieren Sie /etc/pf.conf, indem Sie die folgenden Befehle ausführen:

echo 'block in all' >> /etc/pf.conf
echo 'pass out all keep state' >> /etc/pf.conf

Standardmäßig lehnt die erste Regel allen eingehenden Verkehr ab.

Die zweite Regel erlaubt es, dass von diesem System generierte Verbindungen gesendet werden, während ihre Statusinformationen beibehalten werden. Diese Statusinformationen ermöglichen den Rückverkehr für bestimmte Verbindungen und sollten nur auf vertrauenswürdigen Computern verwendet werden.

Was ist eine Tabelle in PF?

Eine Tabelle wird verwendet, um eine Sammlung von IPv4- und/oder IPv6-Adressen zu speichern. Tabellen-Abfragen sind sehr schnell und benötigen weniger Speicher und CPU-Zeit als Listen-Abfragen. Folglich ist eine Tabelle perfekt zum Speichern einer großen Anzahl von Adressen, da die Suchzeit für eine Tabelle mit 50.000 Adressen nur etwas länger ist als die einer Tabelle mit 50 Adressen. Verwendungen für Tabellen umfassen Folgendes:

  • Quell- und/oder Zieladresse in Regel Quelle und/oder Ziel

  • Die Regelalternativen für Übersetzung und Umleitung sind nat-to und rdr-to, jeweils.

  • Die Zieladresse für die Regeloptionen route-to, reply-to und dup-to.

Tabellen können entweder in pf.conf oder pfctl erstellt werden.

Wie fügt man eine Tabelle hinzu?

Sie können Tabellen mit der table-Direktive in Ihrer Regeln-Konfigurationsdatei pf.conf erstellen. Für jede Tabelle können die folgenden Eigenschaften angegeben werden:

  • const: Der Inhalt der Tabelle kann nach der Erstellung der Tabelle nicht mehr geändert werden. Wenn nicht angegeben, kann pfctl verwendet werden, um Adressen jederzeit zur Tabelle hinzuzufügen oder zu löschen, selbst bei Betrieb mit einem Securelevel von zwei oder höher.

  • persist: Weist den Kernel an, die Tabelle im Speicher zu behalten, auch wenn keine Regeln darauf verweisen. Ohne diese Eigenschaft wird der Kernel die Tabelle löschen, wenn die letzte Regel, die sie referenziert, gelöscht wird.

table <goodguys> { 12.1.0.0/24 }
table <rfc1918> const { 192.168.0.0/16, 172.16.0.0/12, 10.0.0.0/8 }
table <spammers> persist
block in on vtnet0 from { <rfc1918>, <spammers> } to any
pass in on vtnet0 from <goodguys> to any

Tabellennamen sind immer in <> spitzen Klammern eingeschlossen.

dateien, die eine Liste von IP-Adressen und Netzwerken enthalten, können ebenfalls verwendet werden, um Tabellen zu füllen.

table <spammers> persist file "/etc/spammers"
block in on vtnet0 from <spammers> to any

Die Datei /etc/spammers würde eine durch Zeilen getrennte Liste von IP-Adressen und/oder CIDR-Netzwerkblöcken enthalten.

Mit pfctl können Tabellen im laufenden Betrieb geändert werden. Zum Beispiel, um Einträge zur oben erstellten <spammers>-Tabelle hinzuzufügen, führen Sie den folgenden Befehl aus:

pfctl -t spammers -T add 23.23.11.0/24

Dies wird die <spammers>-Tabelle erstellen, falls sie noch nicht existiert. Um die Adressen in einer Tabelle anzuzeigen, führen Sie den nächsten Befehl aus:

pfctl -t spammers -T show

Das -v-Argument wird zusammen mit dem -T show-Argument verwendet, um Statistiken für jeden Tabelleneintrag anzuzeigen. Um Adressen aus einer Tabelle zu entfernen, führen Sie den nächsten Befehl aus:

pfctl -t spammers -T delete 23.23.11.0/24

Wie funktioniert die Paketfilterung?

Paketfilterung ist die selektive Übertragung oder Ablehnung von Datenpaketen über eine Netzwerkschnittstelle. Bei der Bewertung von Paketen verwendet pf Kriterien, die auf den Layer 3 (IPv4 und IPv6) und Layer 4 (TCP, UDP, ICMP und ICMPv6) Headern basieren. Quell- und Zieladresse, Quell- und Zielport sowie Protokoll sind die am häufigsten verwendeten Kriterien.

Filterregeln beschreiben die Kriterien, die ein Paket erfüllen muss, und die Aktion, die durchgeführt wird, wenn eine Übereinstimmung festgestellt wird, entweder blockieren oder weiterleiten. Die Bewertung der Filterregeln erfolgt der Reihenfolge nach, von der ersten bis zur letzten. Bevor die endgültige Aktion durchgeführt wird, wird das Paket gegen alle Filterregeln bewertet, es sei denn, es trifft auf eine Regel, die das Schlüsselwort "fast" enthält. Die auf das Paket anzuwendende Aktion wird durch die "gewinnende" Regel bestimmt, die die letzte Regel ist, die übereinstimmt. Es gibt ein implizites "alle durchlassen" zu Beginn eines Filterregelsatzes, was bedeutet, dass, wenn ein Paket keine Filterregel erfüllt, die folgende Aktion das Durchlassen sein wird.

Was ist die Regel-Syntax?

Die vereinfachte allgemeine Syntax für Filterregeln in PF ist unten angegeben:

action [direction] [log] [quick] [on interface] [af] [proto protocol]
[from src_addr [port src_port]] [to dst_addr [port dst_port]]
[flags tcp_flags] [state]
  • Aktion: Die auf übereinstimmende Pakete auszuführende Aktion, entweder zulassen oder blockieren. Die Pass-Aktion gibt das Paket zur weiteren Verarbeitung an den Kernel zurück, während die Block-Aktion je nach Einstellung der Block-Policy-Option reagiert. Sie können die Standardantwort überschreiben, indem Sie entweder blockieren und verwerfen oder blockieren und zurückgeben.

  • direction: Die Bewegung des Pakets auf einer Schnittstelle, entweder hinein oder heraus.

  • log: Gibt an, dass pflogd das Paket protokollieren soll. Wenn die Regel einen Zustand festlegt, wird nur das Paket, das den Zustand festlegt, aufgezeichnet. Verwenden Sie das Protokoll, um alle Pakete unabhängig aufzuzeichnen. (all).

  • quick: Wenn ein Paket einer Regel entspricht, die quick angibt, wird diese Regel als die letzte übereinstimmende Regel betrachtet, und die angegebene Aktion wird ausgeführt.

  • state: Gibt an, ob Pakete, die dieser Regel entsprechen, Zustandsinformationen beibehalten.

    • no state: TCP, UDP und ICMP werden unterstützt. Zustandsmäßig wird PF diese Verbindung nicht verfolgen. Für TCP-Verbindungen ist oft auch das Flag any erforderlich.
    • keep state: kompatibel mit TCP, UDP und ICMP. Dies ist die Standardeinstellung für alle Filterregeln.
    • modulate state: nur von TCP unterstützt. Anfangssequenznummern (ISNs) werden von PF für Pakete generiert, die dieser Regel entsprechen.
    • synproxy state proxyiert eingehende TCP-Verbindungen, um Server vor gefälschten TCP SYN-Floods zu schützen. Diese Option kombiniert die Funktionen von Zustand beibehalten und Zustand ändern.

Was ist die Default-Deny-Regel?

Bei der Konfiguration einer Firewall wird empfohlen, eine "Default Deny"-Richtlinie zu verwenden. Das bedeutet, allen Verkehr abzulehnen und dann selektiv einige durch die Firewall zu lassen. Diese implizite Verweigerung Methode wird empfohlen, da sie auf der Seite der Vorsicht liegt und die Erstellung eines Regelwerks vereinfacht.

Die erste Filterregel für eine Standard-Blockierungsfilterrichtlinie sollte wie folgt lauten:

block all

Dies wird den gesamten Verkehr auf allen Schnittstellen von überall nach überall in beide Richtungen blockieren.

Wie definiert man eine Regel für durchgelassenen Verkehr?

Nachdem eine Default Deny-Regel hinzugefügt wurde, muss der Verkehr nun ausdrücklich über die Firewall zugelassen werden. ansonsten wird die Standardverweigerungspolitik es verwerfen. Hier kommen die Paketmerkmale wie Quell-/Zielport, Quell-/Zieladresse und Protokoll ins Spiel. Wann immer der Datenverkehr die Firewall durchqueren darf, sollten die entsprechenden Regeln so restriktiv wie möglich sein. Dies wird getan, um sicherzustellen, dass nur der gewünschte Datenverkehr passieren darf.

Einige Beispiele:

# Pass traffic on vtnet0 from the local network, 192.168.0.0/24, to the IP address 192.168.0.1 of the FreeBSD computer. Additionally, transmit the return traffic on vtnet0.

pass in on vtnet0 from 192.168.0.0/24 to 192.168.0.1
pass out on vtnet0 from 192.168.0.1 to 192.168.0.0/24

# Allow the web server running on FreeBSD to receive TCP traffic.

pass in on egress proto tcp from any to egress port www

Wie verwendet man das quick-Schlüsselwort?

Wie bereits erwähnt, wird jedes Paket in aufsteigender Reihenfolge gegen das Filter-Regelsatz überprüft. Das Paket ist standardmäßig zum Durchlassen vorgesehen, was durch jede Regel geändert werden kann und mehrmals bis zum Abschluss der Filterregeln geändert werden kann. Eine Ausnahme von der Regel, dass die zuletzt übereinstimmende Regel gewinnt, besteht: Die Schnelloption bei einer Filterregel verhindert, dass die Regel weiterverarbeitet wird, und führt die angegebene Aktion aus. Schauen wir uns ein paar Beispiele an:

block in on egress proto tcp to port ssh
pass in all

In diesem Beispiel kann die Blockzeile bewertet werden, aber sie wird keine Auswirkungen haben, da sie unmittelbar von einer Zeile gefolgt wird, die alles bestehen lässt. Es ist besser, die Regel wie folgt zu schreiben:

block in quick on egress proto tcp to port ssh
pass in all

Diese Regeln werden etwas anders bewertet. Wenn die Blockzeile von der schnellen Option übereinstimmt, wird das Paket blockiert und der Rest des Regelsets wird ignoriert.

Wie man den Zustand beibehält?

"Zustand beibehalten" oder "zustandsbehaftete Inspektion" ist eine wesentliche Fähigkeit des PF. Stateful Inspection bezieht sich auf die Fähigkeit von PF, den Status oder die Entwicklung einer Netzwerkverbindung zu überwachen. Durch das Speichern von Informationen über jede Verbindung in einer Zustands-Tabelle kann PF schnell beurteilen, ob ein Paket, das die Firewall durchläuft, Teil einer bereits bestehenden Verbindung ist. Wenn ja, darf das Paket die Firewall passieren, ohne dass es einer Überprüfung der Regeln unterzogen wird.

Das Beibehalten des Zustands bietet mehrere Vorteile, wie vereinfachte Regelsets und verbesserte Paketfilterleistung. PF kann Pakete in beide Richtungen mit den Einträgen der Zustandstabelle abgleichen, wodurch die Notwendigkeit für Filterregeln entfällt, die den Rückverkehr erlauben. Aufgrund der Tatsache, dass Pakete, die mit zustandsbehafteten Verbindungen übereinstimmen, keine Überprüfung des Regelsets durchlaufen, kann die Zeit, die PF mit der Verarbeitung dieser Pakete verbringt, erheblich verkürzt werden.

Wenn eine Regel einen Zustand festlegt, stellt das erste Paket, das die Regel erfüllt, den "Zustand" zwischen dem Sender und dem Empfänger her. Nun, nicht nur passen Pakete, die vom Sender zum Empfänger reisen, dem Zustandseintrag an und überspringen die Regelnbewertung, sondern auch Antwortpakete, die vom Empfänger zum Sender reisen, tun dies ebenfalls.

Wenn ein Paket auf eine pass-Regel trifft, erstellt jede Regel sofort einen Zustandseintrag. Dies kann direkt mit der no state-Option deaktiviert werden.

pass out on egress proto tcp from any to any

Diese Regel autorisiert ausgehenden TCP-Verkehr auf der Egress-Schnittstelle und ermöglicht es auch, dass Antwortverkehr durch die Firewall fließt. Das Beibehalten des Zustands erhöht die Geschwindigkeit drastisch, da Zustandsabfragen viel schneller sind als das Durchleiten eines Pakets durch die Filterregeln.

Die Option modulate state funktioniert identisch zur Option keep state, aber sie gilt nur für TCP-Pakete. modulate state randomisiert die Anfangssequenznummer (ISN) ausgehender Verbindungen. Dies ist hilfreich, um Verbindungen zu schützen, die von Betriebssystemen gestartet werden, die ISNs unsachgemäß auswählen. Die Option modulate state kann in Regeln verwendet werden, die Protokolle außer TCP spezifizieren, um Regelsets zu vereinfachen. In solchen Fällen wird der Zustand als beibehalten betrachtet.

Um den Zustand ausgehender TCP-, UDP- und ICMP-Pakete zu behalten und TCP-ISNs zu modulieren, können Sie das folgende Regelset verwenden:

pass out on egress proto { tcp, udp, icmp } from any to any modulate state

Zusätzlich ermöglicht das Beibehalten des Zustands, dass relevanter ICMP-Verkehr die Firewall passieren kann. Zum Beispiel, wenn eine TCP-Verbindung, die die Firewall durchquert, zustandsbehaftet überwacht wird und eine ICMP-Source-Quench-Nachricht, die sich auf diese TCP-Verbindung bezieht, eintrifft, wird sie dem entsprechenden Zustandseintrag zugeordnet und durch die Firewall geleitet.

Global bestimmen die state-policy Laufzeitoption und pro Regel die Schlüsselwörter if-bound und floating state die Reichweite eines Zustandseintrags. Diese pro-Regel-Schlüsselwörter haben die gleiche Bedeutung wie bei ihrer Verwendung in Verbindung mit der state-policy-Option. Zum Beispiel:

pass out on egress proto { tcp, udp, icmp } from any to any modulate state (if-bound)

Diese Regel würde vorschreiben, dass Pakete die Ausgangsschnittstelle durchqueren müssen, um dem Status-Eintrag zu entsprechen.

Wie man gefälschte Pakete blockiert?

Adress-Spoofing tritt auf, wenn ein böswilliger Benutzer die Quell-IP-Adresse gesendeter Pakete fälscht, um die tatsächliche Adresse zu verbergen oder einen anderen Netzwerk-Knoten zu imitieren. Sobald die Adresse gefälscht wurde, kann ein Netzwerkangriff durchgeführt werden, ohne den tatsächlichen Ursprung des Angriffs offenzulegen. Zusätzlich könnte ein Angreifer versuchen, auf Netzwerkdienste zuzugreifen, die auf bestimmte IP-Adressen beschränkt sind.

Das Schlüsselwort antispoof bietet einen gewissen Schutz gegen Adress-Spoofing in PF:

antispoof [log] [quick] for interface [af]
  • log: Gibt an, dass Pakete, die den Kriterien entsprechen, von pflogd protokolliert werden sollen. (8).

  • quick: Wenn ein Paket diese Regel erfüllt, wird es als die "gewinnende" Regel betrachtet und die Überprüfung des Regelsets wird eingestellt.

  • Schnittstelle: Die Netzwerkschnittstelle, auf der der Spoofing-Schutz aktiviert werden soll. Dies kann auch eine Liste von Schnittstellen sein.

  • af: Die Adressfamilie, für die Spoofing-Schutz aktiviert werden soll, entweder inet oder inet6 für IPv4 und IPv6, jeweils.

antispoof for vtnet0 inet

Alle Vorkommen des Antispoof-Begriffs in einem geladenen Regelset werden in zwei Filterregeln erweitert. Die oben genannte Antispoof-Regel würde erweitert zu:

block in on ! vtnet0 inet from 10.0.0.0/24 to any
block in inet from 10.0.0.1 to any

Diese Richtlinien erreichen zwei Ziele:

  • Verhindert, dass jeglicher Verkehr aus dem 10.0.0.0/24-Netzwerk über eine andere Schnittstelle als vtnet0 eintritt. Da das 10.0.0.0/24-Netzwerk mit der vtnet0-Schnittstelle verbunden ist, sollten Pakete mit einer Quelladresse in diesem Netzwerkblock niemals auf einer anderen Schnittstelle ankommen.

  • Verhindert allen eingehenden Verkehr von der IP-Adresse 10.0.0.1 auf vtnet0. Alle eingehenden Pakete mit einer Quelladresse, die dem Host-Computer entspricht, sollten als bösartig eingestuft werden.

Die erweiterten Filterregeln für die Antispoof-Regel werden zusätzlich Pakete blockieren, die über die Loopback-Verbindung an lokale Adressen geliefert werden. Es ist eine gute Praxis, die Filterung auf Loopback-Schnittstellen ohnehin zu überspringen, aber Antispoof-Standards benötigen dies.

set skip on lo0
antispoof for vtnet0 inet

Nur IP-zugewiesene Schnittstellen sollten die Verwendung von Antispoof erlauben. Die Verwendung von Antispoof auf einer Schnittstelle ohne IP-Adresse führt zu solchen Filterregeln wie:

block drop in on ! vtnet0 inet all
block drop in inet all

There is a possibility of banning all incoming traffic on all interfaces with these rules.

How to Create PF Ruleset For a Web Server?

PF understands port names as well as port numbers, as long as the names are listed in /etc/services. In this example, all traffic is blocked except for the connections initiated by this system for the specified TCP and UDP services:

int_tcp_services = "{ domain, ntp, smtp, www, https, ftp, ssh }"
int_udp_services = "{ domain, ntp }"
block all
pass out proto tcp to any port $tcp_services keep state
pass proto udp to any port $udp_services keep state

Sie können das folgende PF-Regelsatzbeispiel verwenden, um Ihren Webserver zu schützen:

## Set your public interface ##
ext_if="vtnet0"

## Set your server public IP address ##
ext_if_ip="22.33.44.55"

## Set and drop these IP ranges on public interface ##

private = "{ 127.0.0.0/8, 192.168.0.0/16, 172.16.0.0/12, 10.0.0.0/8, 169.254.0.0/16, 192.0.2.0/24, 0.0.0.0/8, 240.0.0.0/4 }"

## Set http(80)/https (443) port here ##

webports = "{http, https}"

## enable these services ##

int_tcp_services = "{domain, ntp, smtp, www, https, ftp, ssh}"
int_udp_services = "{domain, ntp}"

## Skip loop back interface - Skip all PF processing on interface ##

set skip on lo

## Sets the interface for which PF should gather statistics such as bytes in/out and packets passed/blocked ##

set loginterface $ext_if

## Set default policy ##

block return in log all
block out all

# Deal with attacks based on incorrect handling of packet fragments

scrub in all

# Drop all Non-Routable Addresses

block drop in quick on $ext_if from $private to any
block drop out quick on $ext_if from any to $private

## Blocking spoofed packets

antispoof quick for $ext_if

# Open SSH port which is listening on port 22 from 22.22.33.33 IP only

# We do not allow or accept ssh traffic from ALL for security reasons

pass in quick on $ext_if inet proto tcp from 22.22.33.33 to $ext_if_ip port = ssh flags S/SA keep state label "USER_RULE: Allow SSH from 22.22.33.33"

## Use the following rule to enable ssh for ALL users from any IP address #

## pass in inet proto tcp to $ext_if port ssh

### [ OR ] ###

## pass in inet proto tcp to $ext_if port 22

# Allow Ping

pass inet proto icmp icmp-type echoreq

# All access to our Nginx/Apache/Lighttpd Webserver ports

pass proto tcp from any to $ext_if port $webports

# Allow essential outgoing traffic

pass out quick on $ext_if proto tcp to any port $int_tcp_services

pass out quick on $ext_if proto udp to any port $int_udp_services

# Add custom rules below

Wie konfiguriert man ein Gateway mit NAT?

Dieser Abschnitt erklärt, wie man ein FreeBSD-System mit PF einrichtet, um als Gateway für mindestens ein weiteres System zu dienen. Jede Netzwerkschnittstelle am Gateway muss mit einem anderen Netzwerk verbunden sein. xl0 ist in diesem Fall mit dem Internet verbunden, während xl1 mit dem internen Netzwerk verbunden ist. Um ein einfaches Gateway mit NAT auf Ihrem FreeBSD zu konfigurieren, können Sie die folgenden Schritte befolgen.

  1. Aktivieren Sie das Gateway, damit der Netzwerkverkehr, der an einer Schnittstelle empfangen wird, an eine andere Schnittstelle gesendet werden kann. Führen Sie den folgenden sysctl-Befehl aus, um IPv4-Pakete weiterzuleiten:

    sysctl net.inet.ip.forwarding=1
  2. Um IPv6-Verkehr weiterzuleiten, führen Sie den nächsten Befehl aus:

    sysctl net.inet6.ip6.forwarding=1
  3. Um diese Optionen beim Systemstart zu aktivieren, fügen Sie sie mit sysrc zu /etc/rc.conf hinzu:

    sysrc gateway_enable=yes
    sysrc ipv6_gateway_enable=yes
  4. Erstellen Sie die PF-Regeln, die es dem Gateway ermöglichen, den Datenverkehr zu übertragen. Während die folgende Regel zustandsbehafteten Verkehr von internen Netzwerk-Hosts durch das Gateway erlaubt, gewährleistet das Schlüsselwort "to" nicht den Transit von Quelle zu Ziel:

    pass in on xl1 from xl1:network to xl0:network port $ports keep state
  5. Die obige Regel erlaubt es dem Datenverkehr nur, über die interne Schnittstelle in das Gateway einzutreten. Um den Paketen das Weiterleiten zu ermöglichen, ist eine passende Regel erforderlich:

    pass out on xl0 from xl1:network to xl0:network port $ports keep state
    tipp

    Diese beiden Regeln könnten zu einer zusammengefasst werden:

    pass from xl1:network to any port $ports keep state

    Die $localnet-Makro könnte als das Netzwerk definiert werden, das direkt an die interne Schnittstelle ($xl1:network) angeschlossen ist. $localnet kann auch mit einer IP-Adresse/Netzmaske-Notation definiert werden, wie zum Beispiel 192.168.100.1/24 für ein Subnetz privater Adressen.

    $localnet kann bei Bedarf als Liste von Netzwerken konfiguriert werden. Unabhängig von den genauen Anforderungen könnte die folgende Definition von $localnet in einer Standard-Passregel verwendet werden:

    pass from $localnet to any port $ports keep state

    Das folgende Regelset fügt die NAT-Regel hinzu, die die Netzwerkadressübersetzung von nicht routbaren Adressen im internen Netzwerk zur IP-Adresse der externen Schnittstelle verwaltet. Wenn die IP-Adresse der externen Schnittstelle dynamisch zugewiesen wird, müssen die Klammern, die den letzten Teil der NAT-Regel ($ext if) umschließen, vorhanden sein. Es garantiert, dass der Netzwerkverkehr weiterhin normal funktioniert, selbst wenn sich die externe IP-Adresse ändert.

    ext_if = "xl0"  # macro for external interface
    int_if = "xl1" # macro for internal interface
    localnet = $int_if:network

    # ext_if IP address could be dynamic, hence ($ext_if)

    nat on $ext_if from $localnet to any -> ($ext_if)
    block all
    pass from { lo0, $localnet } to any keep state
    tipp

    Dieses Regelwerk erlaubt wahrscheinlich, dass mehr Datenverkehr das Netzwerk verlässt, als erforderlich ist. Eine solche Konfiguration kann dieses Makro erzeugen:

    client_out = "{ ftp-data, ftp, ssh, domain, pop3, auth, nntp, http, https, cvspserver, 1528, 5999, 8000, 8080 }"

    Verwenden Sie das obige Makro in der Hauptpassregel:

    pass inet proto tcp from $localnet to any port $client_out flags S/SA keep state

    Es könnten mehrere weitere Pass-Regeln erforderlich sein. Das folgende Regelset ermöglicht SSH-Zugriff auf die externe Schnittstelle:

    pass in inet proto tcp to $ext_if port ssh

    Die nächste Makrodefinition und Regel ermöglicht es internen Clients, DNS und NTP zu verwenden:

    udp_services = "{ domain, ntp }"
    pass quick inet proto { tcp, udp } to any port $udp_services keep state

Wie erstelle ich einen FTP-Proxy?

Aufgrund der Natur des FTP-Protokolls kann es schwierig sein, gültige FTP-Regeln festzulegen. FTP ist viele Jahrzehnte älter als Firewalls und wurde unsicher entworfen. Die häufigsten Argumente gegen FTP sind:

  • Passwörter werden im Klartext gesendet.

  • Das Protokoll erfordert mindestens zwei TCP-Verbindungen (Steuer- und Datenverbindung) auf unterschiedlichen Ports.

  • Wenn eine Sitzung gebildet wird, werden die Daten über zufällig gewählte Ports gesendet.

Bevor mögliche Sicherheitslücken in der Client- oder Server-Software untersucht werden, bieten all diese Bereiche Sicherheitsprobleme. Es gibt sicherere Alternativen zu FTP, wie SFTP und SCP, die beide Authentifizierung und Datenübertragung über verschlüsselte Verbindungen bieten.

Wenn FTP notwendig ist, leitet PF den FTP-Verkehr an eine kleine Proxy-Software namens ftp-proxy weiter, die Teil des FreeBSD-Basissystems ist. Mit Hilfe einer Reihe von Ankern ist der Proxy dafür verantwortlich, Regeln dynamisch in das Regelset einzufügen und zu entfernen, um den FTP-Verkehr angemessen zu verwalten.

Um den FTP-Proxy zu aktivieren, fügen Sie die folgende Zeile zu /etc/rc.conf hinzu:

ftpproxy enable="YES"

Dann starten Sie den Proxy, indem Sie ausführen:

service ftp-proxy start

/etc/pf.conf muss für eine grundlegende Einrichtung drei Teile haben.

  1. Zuerst die Anker, die vom Proxy verwendet werden, um die Regeln einzufügen, die er für FTP-Sitzungen erstellt:

    nat-anchor "ftp-proxy/*"
    rdr-anchor "ftp-proxy/*"
  2. Eine Erlaubnisregel ist erforderlich, damit FTP-Verkehr den Proxy erreichen kann.

  3. Umleitungs- und NAT-Regeln müssen vor den Filterregeln festgelegt werden. Fügen Sie diese rdr-Regel direkt nach der nat-Regel ein:

    rdr pass on $int_if proto tcp from any to any port ftp -> 127.0.0.1 port 8021
  4. Lassen Sie den umgeleiteten Verkehr weiterfahren:

    pass out proto tcp from $proxy to any port ftp

    wobei $proxy die gebundene Adresse des Proxy-Daemons ist.

  5. Speichern Sie /etc/pf.conf, laden Sie die aktualisierten Regeln und testen Sie, ob FTP-Verbindungen von einem Client aus funktionieren, indem Sie den folgenden Befehl ausführen:

    pfctl -f /etc/pf.conf

Dieses Beispiel zeigt eine einfache Konfiguration, bei der Clients im lokalen Netzwerk mit entfernten FTP-Servern kommunizieren müssen. Diese Konfiguration sollte mit der Mehrheit der FTP-Client- und Serverkombinationen funktionieren. Das Hinzufügen von Optionen zur Zeile ftpproxy_flags= ändert das Verhalten des Proxys auf verschiedene Weise. Einige Clients oder Server können Eigenheiten aufweisen, die im Setup berücksichtigt werden müssen, oder es kann notwendig sein, den Proxy auf spezifische Weise zu integrieren, wie zum Beispiel die Zuweisung des FTP-Verkehrs zu einer bestimmten Warteschlange.

Konfigurieren Sie einen zweiten FTP-Proxy im Umkehrmodus mit -R auf einem anderen Port mit seiner eigenen Weiterleitungsregel, um einen FTP-Server zu betreiben, der durch PF und ftp-proxy geschützt ist.

Wie verwaltet man ICMP-Verkehr?

Zahlreiche Debugging- und Troubleshooting-Tools für TCP/IP-Netzwerke hängen vom Internet Control Message Protocol (ICMP) ab, das mit dem Ziel der Fehlersuche entwickelt wurde. Das ICMP-Protokoll überträgt und empfängt Steuerungsnachrichten zwischen Hosts und Gateways, hauptsächlich um den Sender über unerwartete oder herausfordernde Umstände auf dem Weg zum Zielhost zu informieren. Router verwenden das Internet Control Message Protocol (ICMP), um Paketgrößen und andere Übertragungseigenschaften auszuhandeln, ein Prozess, der oft als Route MTU Discovery bezeichnet wird.

Aus der Sicht einer Firewall sind einige ICMP-Steuerungsnachrichten anfällig für bekannte Angriffsvektoren. Auch das bedingungslose Zulassen aller Diagnosetrafik hilft beim Debuggen, macht es aber einfacher für andere, Netzwerkinformationen zu sammeln. Aufgrund dieser Überlegungen ist die folgende Regel möglicherweise nicht optimal:

pass inet proto icmp from any to any.

Das Zulassen aller ICMP-Verkehr von dem lokalen Netzwerk, während alle Anfragen von außerhalb des Netzwerks blockiert werden, ist eine Methode.

pass inet proto icmp from $localnet to any keep state
pass inet proto icmp from any to $ext_if keep state

Es gibt weitere Alternativen, die einige der Anpassungsfähigkeit von PF veranschaulichen. Anstatt alle ICMP-Nachrichten zu akzeptieren, könnte man beispielsweise nur die auswählen, die von ping und traceroute verwendet werden. Definieren Sie eine Makro für diese Art von Nachricht, um zu beginnen, und eine Regel:

icmp_types = "echoreq"
pass inet proto icmp all icmp-type $icmp_types keep state

Da Unix traceroute standardmäßig UDP verwendet, ist die folgende Regel erforderlich, um es zu aktivieren:

# allow out the default range for traceroute(8):

pass out on $ext_if inet proto udp from any to any port 33433 >< 33615 keep state

Da TRACERT.EXE auf Microsoft Windows-Computern ICMP-Echoanforderungsnachrichten verwendet, ist nur die erste Regel erforderlich, um Netzwerkverfolgungen von diesen Systemen zuzulassen. Unix traceroute kann so konfiguriert werden, dass es mehr Protokolle verwendet, und wenn -I verwendet wird, wird es ICMP Echo-Anforderungsnachrichten verwenden.

Wie verwaltet man die Pfad-MTU-Erkennung?

Internetprotokolle sollen geräteunabhängig sein, und daher kann die ideale Paketgröße für eine bestimmte Verbindung nicht immer genau vorhergesagt werden. Die Maximum Transmission Unit (MTU), die die höchste Grenze für die Paketgröße eines Interfaces bestimmt, ist die primäre Einschränkung für die Paketgröße. Um die MTUs für die Netzwerkinterfaces eines Systems zu überprüfen, geben Sie ifconfig ein.

Die Path MTU Discovery wird von TCP/IP verwendet, um die optimale Paketgröße für eine Verbindung zu ermitteln. Dieses Verfahren sendet Pakete unterschiedlicher Größen mit dem gesetzten "Do not fragment"-Flag und erwartet ein ICMP-Antwortpaket vom Typ "3, Code 4", wenn die maximale Größe erreicht ist. Typ 3 zeigt ein unerreichbares Ziel an, während Code 4 anzeigt, dass Fragmentierung erforderlich ist, aber das do-not-fragment-Flag gesetzt ist. Fügen Sie den Typ "Destination Unreachable" zur ICMP-Typen-Makro hinzu, um die Pfad-MTU-Erkennung zu aktivieren und Verbindungen zu verschiedenen MTUs zu erleichtern.

icmp_types = "{ echoreq, unreach }"

Da die Pass-Regel dieses Makro bereits verwendet, ist es nicht notwendig, es zu ändern, um den neuen ICMP-Typ zu verarbeiten:

pass inet proto icmp all icmp-type $icmp_types keep state

PF erlaubt das Filtern aller ICMP-Typ- und Codevarianten. Die Menge der verfügbaren Typen und Codes ist in den Spezifikationen icmp und icmp6 angegeben.

Wie man Überlastungstabellen zum Schutz des SSH-Servers verwendet?

Diejenigen, die SSH auf einer externen Schnittstelle verwenden, haben wahrscheinlich Folgendes in ihren Authentifizierungsprotokollen gesehen:

Sep 15 03:12:34 myserver sshd[25771]: Failed password for root from 33.44.55.66 port 40991 ssh2
Sep 15 03:12:34 myserver sshd[5279]: Failed password for root from 33.44.55.66 port 40991 ssh2
Sep 15 03:12:35 myserver sshd[5279]: Received disconnect from 33.44.55.66: 11: Bye Bye
Sep 15 03:12:44 myserver sshd[29635]: Invalid user admin from 33.44.55.66
Sep 15 03:12:44 myserver sshd[24703]: input_userauth_request: invalid user admin
Sep 15 03:12:44 myserver sshd[24703]: Failed password for invalid user admin from 33.44.55.66 port 41485 ssh2

Dies deutet auf einen Brute-Force-Angriff hin, bei dem eine Person oder Software versucht, den Benutzernamen und das Passwort des Systems zu erraten.

Wenn externer SSH-Zugriff für autorisierte Benutzer erforderlich ist, kann die Änderung des Standard-SSH-Ports Schutz bieten. Dennoch bietet PF eine elegantere Methode. Pass-Regeln können Einschränkungen festlegen, was verbundene Hosts tun dürfen, und Verstöße können in eine Datenbank von Adressen aufgenommen werden, denen der Zugang ganz oder teilweise verboten ist. Es ist sogar möglich, alle Verbindungen von Computern zu beenden, die das Limit überschreiten.

  1. Erstellen Sie die folgende Tabelle im Tabellenbereich des Regelsets zur Konfiguration:

    table <bruteforce> persist
  2. Früh im Regelwerk Regeln hinzufügen, um Brute-Force-Zugriffe zu verhindern und gleichzeitig echten Zugriff zu erlauben:

    block quick from <bruteforce>
    pass inet proto tcp from any to $localnet port $tcp_services \
    flags S/SA keep state \
    (max-src-conn 100, max-src-conn-rate 15/5, \
    overload <bruteforce> flush global)

Der in Klammern angegebene Teil spezifiziert die Einschränkungen, und die Werte sollten an die lokalen Vorgaben angepasst werden. Es könnte wie folgt geschrieben werden:

  • max-src-conn: die maximale Anzahl gleichzeitiger Verbindungen, die von einem einzelnen Host erlaubt sind.

  • max-src-conn-rate: die maximale Anzahl neuer Verbindungen, die von einem einzelnen Host pro Sekunde erlaubt sind.

  • overload <bruteforce>: Jeder Host, der diese Einschränkungen überschreitet, wird seiner Adresse zur Brute-Force-Datenbank hinzugefügt, wenn die Überlast aktiviert ist. Das Regelwerk verbietet allen Verkehr aus der Brute-Force-Tabelle.

  • flush global: Diese Option legt fest, dass, wenn ein Host sein Verbindungslimit erreicht, alle globalen Verbindungen für diesen Host beendet werden.

Dieses Beispiel-Regelsatz wird nur zu Illustrationszwecken bereitgestellt. Zum Beispiel, wenn eine große Anzahl von Verbindungen im Allgemeinen gewünscht wird, aber SSH-Beschränkungen gewünscht sind, sollte die obige Regel durch die folgende Regel früh im Regelset ergänzt werden:

pass quick proto { tcp, udp } from any to any port ssh flags S/SA keep state (max-src-conn 15, max-src-conn-rate 5/3, overload <bruteforce> flush global)
tipp

Es ist möglicherweise nicht erforderlich, jeden Überlastungsangreifer zu blockieren.

Insbesondere ist der Überlastmechanismus eine generische Strategie, die nicht einzigartig für SSH ist, und es ist nicht immer optimal, die gesamte Kommunikation von Tätern vollständig zu blockieren.

Zum Beispiel kann eine Überlastregel verwendet werden, um einen Maildienst oder einen Webdienst zu verteidigen, während die Überlasttabelle in einer Regel verwendet werden könnte, um Täter einer Warteschlange mit einer geringen Bandbreitenzuweisung zuzuweisen oder auf eine bestimmte Webseite umzuleiten.

Im Laufe der Zeit werden die Tabellen durch Überlaufregeln gefüllt, und ihre Größe wird allmählich zunehmen, was mehr RAM erfordert. Manchmal ist eine gesperrte IP-Adresse eine dynamisch zugewiesene IP-Adresse, die später einem Host zugewiesen wurde, der einen gültigen Grund hat, sich mit anderen Hosts im lokalen Netzwerk zu verbinden.

pfctl ermöglicht es, Tabellen Einträge in solchen Fällen ablaufen zu lassen. Dieser Befehl wird <bruteforce>-Tabelleneinträge löschen, die seit 86400 Sekunden nicht mehr aufgerufen wurden, zum Beispiel:

pfctl -t bruteforce -T expire 86400

Ähnliche Funktionalität wird durch das Modul security/expiretable angeboten, das Tabellenobjekte entfernt, die innerhalb eines bestimmten Zeitraums nicht besucht wurden.

Nach der Installation kann der Befehl expiretable verwendet werden, um <bruteforce>-Tabelleneinträge zu löschen, die älter als ein bestimmtes Alter sind. Dieses Beispiel löscht alle Einträge, die älter als vierundzwanzig Stunden sind:

/usr/local/sbin/expiretable -v -d -t 24h bruteforce

Wie man SPAM verhindert?

Der spamd-Daemon, der mit Spamassassin geliefert wird, kann so konfiguriert werden, dass er in Kombination mit PF einen äußeren Schutz gegen SPAM bietet. Dieser spamd integriert sich über eine Sammlung von Umleitungen in die PF-Einstellungen.

Der Großteil des Spam stammt aus einer kleinen Anzahl von Spam-freundlichen Netzwerken und einer großen Anzahl von gehackten Arbeitsstationen, die beide sofort an Blocklisten gemeldet werden.

Wenn spamd eine SMTP-Verbindung von einer Adresse auf einer Blockliste erhält, zeigt es sein Banner an und wechselt sofort in einen Modus, in dem es auf SMTP-Verkehr Byte für Byte antwortet. Diese Taktik wird als tarpitting bezeichnet, und ihr Zweck ist es, so viel Zeit wie möglich auf der Seite des Spammers zu verbringen. Die Implementierung, die einbyteige SMTP-Antworten verwendet, wird manchmal als stuttering bezeichnet.

Dieses Beispiel veranschaulicht die grundlegenden Schritte, die erforderlich sind, um spamd mit automatisch aktualisierten Blocklisten zu konfigurieren:

  1. Installieren Sie den mail/spamd Port oder das Paket.

  2. Um die Greylisting-Funktionen von spamd zu nutzen, muss fdescfs unter /dev/fd gemountet werden. Fügen Sie die folgende Zeile zur Datei /etc/fstab hinzu:

    fdescfs /dev/fd fdescfs rw 0 0
  3. Mounten Sie das Dateisystem, indem Sie den nächsten Befehl ausführen:

    mount fdescfs
  4. Fügen Sie die folgenden Zeilen zu Ihrem PF-Regelsatz hinzu:

    table <spamd> persist
    table <spamd-white> persist
    rdr pass on $ext_if inet proto tcp from <spamd> to \
    { $ext_if, $localnet } port smtp -> 127.0.0.1 port 8025
    rdr pass on $ext_if inet proto tcp from !<spamd-white> to \
    { $ext_if, $localnet } port smtp -> 127.0.0.1 port 8025

    Wesentlich sind die Tabellen <spamd> und <spamd-white>. SMTP-Verkehr von Adressen, die in <spamd> aber nicht in <spamd-white> erwähnt sind, wird an den spamd-Daemon gesendet, der auf Port 8025 läuft.

  5. Richten Sie spamd in /usr/local/etc/spamd.conf ein und fügen Sie die rc.conf-Parameter hinzu. Die Installation von mail/spamd stellt eine Beispielkonfigurationsdatei (/usr/local/etc/spamd.conf.sample) zur Verfügung. Eine der ersten Zeilen in der Konfigurationsdatei, die nicht mit # beginnt, enthält den Block, der die all-Liste definiert, die angibt, welche Listen verwendet werden sollen:

    all:\
    :traplist:allowlist:

    Dieser Eintrag fügt die von Ihnen angegebenen Blocklisten hinzu, getrennt durch Doppelpunkte (:). Um eine Allowlist zu verwenden, um Adressen von einer Blockliste zu entfernen, setzen Sie den Namen der Allowlist direkt nach den Namen der Blockliste. Zum Beispiel: blocklist:allowlist:.

    Die Definition der bereitgestellten Blockliste folgt:

    Mounten Sie das Dateisystem, indem Sie den nächsten Befehl ausführen:

    traplist:\
    :black:\
    :msg=SPAM. Ihre Adresse %A hat in den letzten 24 Stunden Spam gesendet":\
    :method=http:\
    :file=www.openbsd.org/spamd/traplist.gz

    wo die erste Zeile den Namen der Sperrliste definiert und die zweite Zeile den Listentyp angibt. Während des SMTP-Gesprächs enthält das msg-Feld die Nachricht, die blockierten Absendern angezeigt wird. Der Parameter "method" bestimmt, wie spamd-setup die Listendaten abruft; verfügbare Methoden sind HTTP, FTP, von einer Datei auf einem gemounteten Dateisystem und exec. Der Datei-Parameter gibt den Namen der Datei an, die spamd voraussichtlich erhalten wird.

    Ähnlich wie die vorherige Definition, aber ohne das msg-Feld, da keine Nachricht erforderlich ist:

    allowlist:\
    :white:\
    :method=file:\
    :file=/var/mail/allowlist.txt
    Wählen Sie Datenquellen mit Bedacht:

    Die Verwendung aller Blocklisten in der Beispielkonfiguration spamd.conf wird den Zugriff auf erhebliche Teile des Internets verhindern. Administratoren müssen die Konfigurationsdatei ändern, um eine geeignete Konfiguration zu erstellen, die geeignete Datenquellen und, falls erforderlich, benutzerdefinierte Listen verwendet.

  6. Fügen Sie den folgenden Eintrag zu /etc/rc.conf hinzu:

    spamd_flags="-v" # use "" and see spamd-setup(8) for flags
  7. Laden Sie das Regelset neu, indem Sie den nächsten Befehl ausführen:

    pfctl -F all -f /etc/pf.conf
  8. Starten Sie spamd, indem Sie den folgenden Befehl eingeben:

    service obspamd start
  9. Vervollständigen Sie die Konfiguration mit spamd-setup.

  10. Schließlich erstellen Sie einen Cron-Job, der spamd-setup aufruft, um die Tabellen in angemessenen Abständen zu aktualisieren.

Wie definiert man eine Greylist?

PF unterstützt auch Greylisting, das temporäre Kommunikationen mit 45n-Codes von unbekannten Hosts blockiert. Nachrichten von grau gelisteten Hosts, die innerhalb eines angemessenen Zeitrahmens erneut versuchen, werden durchgelassen. Der Verkehr von Absendern, die so konfiguriert sind, dass sie sich innerhalb der von RFC 1123 und RFC 2821 festgelegten Parameter verhalten, wird sofort erlaubt.

Der bemerkenswerteste Aspekt des Greylistings, abgesehen von seiner Einfachheit, ist, dass es immer noch funktioniert. Spammer und Virusautoren haben sich sehr langsam angepasst, um diese Strategie zu umgehen.

Die grundlegenden Konfigurationsschritte für Greylisting sind wie folgt:

  1. Stellen Sie sicher, dass fdescfs wie in Schritt 2 des vorhergehenden Verfahrens angegeben, gemountet wurde.

  2. Um den Greylisting-Modus für spamd zu aktivieren, fügen Sie die folgende Zeile zu /etc/rc.conf hinzu:

    spamd grey="YES" # spamd-Greylisting verwenden, wenn JA
  3. Um die Greylisting-Konfiguration abzuschließen, führen Sie die folgenden Befehle aus:

    Dienst neu starten``` obspamd
    Dienst obspamlogd starten

Das Spamdb-Datenbanktool und der Spamlogd-Whitelist-Updater führen im Hintergrund wichtige Greylisting-Aktivitäten durch. Die /var/db/spamdb-Datenbank dient als primäre Schnittstelle für den Administrator zur Verwaltung der Block-, Grau- und Erlauben-Listen.

Wie man Netzwerghygiene gewährleistet?

Dieser Abschnitt veranschaulicht, wie block-policy, scrub und antispoof auf das Regelwerk angewendet werden, um es sinnvoll agieren zu lassen.

Die block-policy ist eine Option, die im Optionsbereich des Regelsets konfiguriert wird, der vor den Weiterleitungs- und Filterregeln kommt. Diese Option legt die Art des Feedbacks fest, falls vorhanden, das PF an Websites gibt, die durch eine Regel gesperrt wurden. Es gibt zwei mögliche Werte für diese Option:

  • drop: verwirft gestoppte Pakete ohne Rückmeldung.

  • return: gibt einen Statuscode wie Connection Refused zurück

Die Standardrichtlinie, wenn nicht festgelegt, ist drop. Um die block-policy zu ändern, geben Sie den neuen Wert ein:

set block-policy return

scrub ist ein Begriff in PF, der die Normalisierung von Netzwerkpaketen ermöglicht. Dieses Verfahren setzt fragmentierte TCP-Pakete wieder zusammen und verwirft solche mit falschen Flag-Kombinationen. Scrub bietet einen gewissen Schutz gegen Angriffe, die auf der unsachgemäßen Verarbeitung von Paketfragmenten basieren, wenn es aktiviert ist. Es gibt viele Optionen, aber die Grundversion ist für die Mehrheit der Konfigurationen ausreichend:

scrub in all

Dieses Beispiel setzt die maximale Segmentgröße auf 1440 Bytes und fügt die Teile wieder zusammen:

scrub in all fragment reassemble no-df max-mss 1440

Das Antispoof-System verteidigt sich gegen Aktivitäten von gefälschten oder gefälschten IP-Adressen, indem es hauptsächlich verhindert, dass Pakete an Schnittstellen ankommen und in logisch unmöglichen Richtungen gesendet werden.

Diese Regeln eliminieren gefälschten Verkehr aus dem Rest der Welt sowie gefälschte Pakete, die aus dem lokalen Netzwerk stammen.

antispoof für $ext_if
antispoof für $int_if

Wie geht man mit nicht routbaren Adressen um?

Selbst mit einem korrekt konfigurierten Gateway zur Handhabung der Netzwerkadressübersetzung kann es notwendig sein, die Fehlkonfigurationen anderer zu berücksichtigen. Ein typischer Konfigurationsfehler besteht darin, nicht routbare Adressen den Zugriff auf das Internet zu erlauben. Da der Verkehr von nicht routbaren Adressen zu einer Vielzahl von DoS-Angriffstaktiken beitragen könnte, ist es ratsam, solchen Verkehr ausdrücklich vom Zugriff auf das Netzwerk über die externe Schnittstelle auszuschließen.

In diesem Beispiel wird ein Makro erstellt, das nicht routbare Adressen enthält, und dann in Sperrregeln verwendet. An der externen Schnittstelle des Gateways wird der Verkehr zu und von diesen Adressen diskret verworfen.

martians = "{ 127.0.0.0/8, 192.168.0.0/16, 172.16.0.0/12, 10.0.0.0/8, 169.254.0.0/16, 192.0.2.0/24, 0.0.0.0/8, 240.0.0.0/4 }"

block drop in quick on $ext_if from $martians to any
block drop out quick on $ext_if from any to $martians

Wie aktiviert man ALTQ oder QoS?

ALTQ kann zusammen mit PF verwendet werden, um Quality of Service auf FreeBSD anzubieten. (QOS). Sobald ALTQ aktiviert ist, können Warteschlangen, die die Verarbeitungspriorität ausgehender Pakete bestimmen, im Regelwerk konfiguriert werden.

ALTQ ist nicht als ladbares Kernel-Modul zugänglich. Erstellen Sie einen benutzerdefinierten Kernel basierend auf den Anweisungen in der Konfiguration des FreeBSD-Kernels, wenn die Schnittstellen des Systems ALTQ unterstützen. Die möglichen Kernel-Optionen sind unten aufgeführt. Das erste ist erforderlich, um ALTQ zu aktivieren. Mindestens eine der anderen Optionen ist erforderlich, um den Algorithmus für den Warteschlangen-Scheduler anzugeben:

optionen ALTQ
Optionen ALTQ_CBQ # Klassenbasierte Warteschlangen (CBQ)
Optionen ALTQ_RED # Random Early Detection (RED)
optionen ALTQ_RIO # RED In/Out
Optionen ALTQ_HFSC # Hierarchischer Paket-Scheduler (HFSC)
Optionen ALTQ_PRIQ # Prioritätswarteschlange (PRIQ)

Die unten aufgeführten Planungsalgorithmen sind verfügbar:

  • CBQ: Class Based Queuing (CBQ) wird verwendet, um die Bandbreite einer Verbindung in verschiedene Klassen oder Warteschlangen aufzuteilen, um den Verkehr gemäß Filterregeln zu priorisieren.

  • RED: Random Early Detection (RED) wird verwendet, um Netzwerküberlastungen zu verhindern, indem die Warteschlangenlänge überwacht und mit den minimalen und maximalen Kriterien der Warteschlange verglichen wird. Wenn die Warteschlange voll ist, werden alle neuen Pakete willkürlich verworfen.

  • RIO: Im Random Early Detection In and Out (RIO) Modus verfolgt RED mehrere durchschnittliche Warteschlangenlängen und Schwellenwerte, jeweils einen für jede QoS-Stufe.

  • HFSC: Der HFSC Hierarchical Fair Service Curve Packet Scheduler wird unter http://www-2.cs.cmu.edu/hzhang/HFSC/main.html erklärt.

  • PRIQ: Priority Queuing (PRIQ) gibt dem Verkehr in einer Warteschlange mit höherer Priorität immer Vorrang.

Wie verwaltet man den PF-Dienst?

Um die PF-Firewall zu starten, können Sie den folgenden Befehl ausführen:

service pf start

Um die PF-Firewall zu stoppen, können Sie den folgenden Befehl ausführen:

service pf stop

Um PF auf Syntaxfehler zu überprüfen, können Sie den folgenden Befehl ausführen:

service pf check

Um die PF-Firewall neu zu starten, können Sie den folgenden Befehl ausführen:

service pf restart

Um den PF-Status anzuzeigen, können Sie den folgenden Befehl ausführen:

service pf status

Um den pflog-Dienst zu starten/stoppen/neustarten, können Sie die folgenden Befehle eingeben:

service pflog starten
service pflog stoppen
service pflog neu starten

Wie man PF-Protokolle anzeigt?

PF-Protokolle sind im Binärformat. Um PF-Protokolle anzuzeigen, können Sie den folgenden Befehl ausführen:

tcpdump -n -e -ttt -r /var/log/pflog

Um Protokolle in Echtzeit vom pflog0-Interface anzuzeigen, führen Sie den folgenden Befehl aus:

tcpdump -n -e -ttt -i pflog0

Sie können auch das pftop-Dienstprogramm verwenden, das ein Werkzeug zum schnellen Anzeigen der Firewall-Aktivität in Echtzeit ist. Sie müssen das pftop-Paket installieren, indem Sie den folgenden Befehl ausführen:

pkg install pftop

Sie können Protokolle in Echtzeit anzeigen, indem Sie den folgenden Befehl ausführen:

pftop