Unter macOS ist ein Kill-Switch nur so gut wie die Paketfilterrichtlinie dahinter, und pf ist das Teil, das diese Richtlinie durchsetzt. Die Richtlinie muss zwei entgegengesetzte Dinge zugleich tun: den Client zu seinem Server lassen, damit ein Tunnel existieren kann, und alles andere davon abhalten, direkt hinauszugehen. Die meisten veröffentlichten Regelsätze schaffen das Zweite und vergessen das Erste, sodass die Maschine die Verbindung verliert statt Schutz zu gewinnen. Die funktionierende Fassung benennt den Endpunkt, den Resolver und den Tunnel, und sonst nichts.

Was ein Paketfilter entscheiden kann und was nicht

pf betrachtet Schnittstellen, Adressen, Protokollnummern und Ports, und dort hört es auf. Es erfährt nie, welcher Prozess einen Socket geöffnet hat, deshalb wird eine für ein Programm geschriebene Erlaubnis zu einer Erlaubnis für jedes Programm, das denselben Port erreichen kann. So verwandelt eine großzügige UDP-Ausnahme einen Kill-Switch wieder in ein gewöhnliches Netzwerk. Anwendungsbewusstes Blockieren gehört zum Client oder zu einer Systemerweiterung, nicht zu dieser Datei.

Der Filter legt auch keine Routen an. Wenn der Client ausfällt, kann die Standardroute weiter auf einen toten Tunnel zeigen, und pf macht daraus blockierte Pakete statt eines stillen Rückfalls auf WLAN. Die Blockade ist das beabsichtigte Ergebnis, keine Fehlfunktion, um die man herumrouten müsste.

Die Reihenfolge entscheidet das Ergebnis häufiger als der Regeltext. Ohne quick wertet pf nach einem Treffer weiter aus, und die letzte passende Regel gewinnt, sodass ein breiter Durchlass unten die sorgfältigen Ausnahmen darüber überstimmt. Wer die Durchlässe mit quick markiert, macht den ersten Treffer endgültig, was ein Richtlinienautor meist meint.

Lesen Sie zuerst die Fakten zu Schnittstelle und Endpunkt

Drahtlosschnittstellen werden nicht auf jedem Mac gleich nummeriert, und das Tunnelgerät bekommt eine Nummer, die sich zwischen Neustarts ändern kann. Eine Regel, die ein nicht vorhandenes Gerät nennt, scheitert beim Parsen, was laut und leicht zu fangen ist, während eine Regel, die das falsche vorhandene Gerät nennt, sauber parst und Verkehr zulässt, den Sie stoppen wollten.

Sammeln Sie die Fakten, solange der Client verbunden ist, denn das Tunnelgerät existiert nur dann. Sie brauchen die Schnittstelle mit der Standardroute, das vom Client erzeugte Gerät sowie Adresse und Port des Servers, den er anwählt. Genau dieser letzte Wert fehlt in den meisten Regelsätzen, und deshalb blockiert ein kopierter Regelsatz seinen eigenen Tunnel.

route -n get default
ifconfig -l
scutil --nc list

Der erste Befehl nennt die derzeit gewinnende Schnittstelle, der zweite listet jedes Gerät, das der Kernel kennt, und der dritte zeigt die VPN-Konfigurationen, die das System starten kann. Schreiben Sie diese Antworten auf und lesen Sie dann Serveradresse und Port aus der eigenen Konfiguration des Clients.

Schreiben Sie den Regelsatz um den Tunnelpfad

Die Datei unten verweigert standardmäßig und lässt fünf Dinge wieder zu: Loopback, das Tunnelgerät, den Pfad des Clients zu seinem Server, den Resolver, der vor dem Tunnel genutzt wird, und die beiden Austausche, die eine Drahtlosverbindung nutzbar halten. Schnittstellennamen und Serveradresse stammen von Ihrer Maschine, ersetzen Sie also die bestätigten Werte. Auch die Tunnelnummer wird nicht zu Ihrer passen.

set skip on lo0
block all
pass out quick on utun0
# maintain this line when the server address changes
pass out quick on en1 inet proto udp to 203.0.113.10 port 1194
# only the resolver the client uses before the tunnel exists
pass out quick on en1 inet proto udp to 192.0.2.53 port 53
pass out quick on en1 inet proto udp from any port 68 to any port 67
pass out quick on en1 inet proto udp to 224.0.0.251 port 5353

Die DHCP-Zeile existiert, weil ein Mac eine Adresse anfordert, bevor er eine hat, sodass die Anfrage Port 68 Richtung Port 67 ohne brauchbare Quelladresse verlässt. Die Multicast-Zeile lässt das System beurteilen, ob die Drahtlosverbindung es wert ist, und ihr Entfernen erzeugt eine Maschine, die in einem funktionierenden Netz keine Verbindung meldet. Die Endpunktzeile ist das, was OpenVPN überhaupt erst seinen Server erreichen lässt; ohne sie verwirft block all den äußeren Handshake, und der Tunnel kommt nie hoch. Die Resolverzeile ist enger als eine allgemeine DNS-Erlaubnis, weil sie eine Adresse und einen Port nennt statt jeder Abfrage, die die Maschine macht.

Diese Endpunkt- und Resolver-Ausnahmen sind die beiden, die es geben muss; alles andere bleibt blockiert. Wählt der Client eine wörtliche Adresse, streichen Sie die Resolverzeile und behalten Sie die Endpunktzeile. Ändert sich die Serveradresse, aktualisieren Sie diese Zeile vor der nächsten Verbindung, oder füllen Sie eine pf-Tabelle aus dem eigenen Hook des Clients und gleichen Sie stattdessen die Tabelle ab.

Nehmen Sie den Tunnel herunter und starten Sie dann neu

Parsen Sie vor dem Laden, denn ein Syntaxfehler ist billig in einem Probelauf und teuer in einer Remote-Sitzung. Laden Sie dann die Datei, aktivieren Sie den Filter, falls er aus war, und lesen Sie zurück, was tatsächlich in Kraft ist. Das Zurücklesen ist keine Zeremonie: ein anderer Anker kann Regeln hinzufügen, die Sie nicht geschrieben haben, also vergleichen Sie den ausgegebenen Satz mit Ihrer Datei.

sudo pfctl -n -v -f /etc/pf.conf
sudo pfctl -f /etc/pf.conf
sudo pfctl -e
sudo pfctl -s rules
sudo pfctl -s Anchors
sudo pfctl -a <anchor> -s rules
sudo pfctl -s info

Nehmen Sie mit geladenen Regeln den Tunnel herunter und versuchen Sie, eine Seite zu laden. Gewöhnlicher Verkehr sollte stoppen, und er sollte auch nach Schlafen und Aufwachen der Maschine gestoppt bleiben, denn genau bei diesem Übergang kriecht veralteter Zustand zurück. Verbinden Sie neu und bestätigen Sie, dass der Verkehr ohne Eingriff in den Regelsatz wieder läuft. Funktioniert ein Browser bei heruntergefahrenem Tunnel noch, ist eine Regel breiter als gedacht, und das Zurücklesen benennt sie meist.

Der Neustart ist der Teil, den Leute überspringen. macOS liest /etc/pf.conf beim Booten, aber die Datei zu lesen ist nicht dasselbe wie den Filter zu aktivieren, also kann ein Regelsatz, der jetzt funktioniert, nach einem Neustart inaktiv sein. Führen Sie danach sudo pfctl -s info aus und bestätigen Sie, dass die Statuszeile den Filter als aktiviert meldet.

Halten Sie den Ausstieg und den Neustartpfad ehrlich

Ein Regelsatz, der alles blockiert, kann Sie auch aus einer Maschine aussperren, die Sie remote administrieren. Bearbeiten Sie aus einer lokalen Sitzung, wenn Sie können, halten Sie die vorherige Datei neben der neuen bereit und kennen Sie den Rückweg, bevor Sie ihn brauchen. Die Befehle unten deaktivieren den Filter und laden die aufbewahrte Kopie neu, und das ist die Reihenfolge für eine Konsole, nicht über den Tunnel, den Sie gerade gekappt haben. Ein Rückweg in fünf Sekunden schlägt jedes Mal eine kluge Regel.

sudo pfctl -d
sudo pfctl -f /etc/pf.conf.previous
sudo pfctl -s rules

Für Dauerhaftigkeit braucht es einen Launch-Daemon, der pfctl -e ausführt und Ihre Datei beim Booten lädt. Behandeln Sie ihn wie jeden anderen privilegierten Job: absolute Pfade, ein Protokoll, das Sie danach lesen können, und ein Test auf einer Maschine, die Sie physisch erreichen. Ein Daemon, der still scheitert, lässt die Maschine ungeschützt und normal aussehen.

Dokumentieren Sie die Lücken, beginnend mit einem zweiten VPN-Client, der sein eigenes Tunnelgerät anlegt. Ihre Regeln benennen eine Tunnelschnittstelle, also bleibt eine zweite blockiert oder wird von einer später hinzugefügten breiten Regel erfasst. Tethering- und Hotspot-Schnittstellen erscheinen nur manchmal und verdienen dieselbe Notiz. Keine dieser Lücken ist ein Grund, die Richtlinie zu überspringen; sie sind die Bedingungen, unter denen sie weiter gilt.

Ähnliche Artikel