Verhindern Sie ausgehenden Datenverkehr, es sei denn, die OpenVPN-Verbindung ist mit pf.conf unter Mac OS X aktiv

19

Ich konnte alle Verbindungen zu externen Netzwerken verweigern, es sei denn, meine OpenVPN-Verbindung ist mit pf.conf aktiv. Ich verliere jedoch die Wi-Fi-Verbindung, wenn die Verbindung durch Schließen und Öffnen des Laptop-Deckels oder erneutes Ein- und Ausschalten von Wi-Fi unterbrochen wird.

  • Ich verwende Mac OS 10.8.1.
  • Ich verbinde mich über WLAN mit dem Internet (von verschiedenen Standorten aus, einschließlich öffentlichem WLAN).
  • Die OpenVPN-Verbindung wird mit Viscosity eingerichtet.

Ich habe die folgenden Paketfilterregeln in /etc/pf.conf

# Deny all packets unless they pass through the OpenVPN connection
wifi=en1
vpn=tun0

block all

set skip on lo
pass on $wifi proto udp to [OpenVPN server IP address] port 443
pass on $vpn

Ich starte den Paketfilterdienst mit sudo pfctl -eund lade die neuen Regeln mit sudo pfctl -f /etc/pf.conf.

Ich habe auch /System/Library/LaunchDaemons/com.apple.pfctl.plistdie Zeile bearbeitet und geändert, um <string>-f</string>zu lesen, <string>-ef</string>damit der Paketfilter beim Systemstart startet.

Das alles scheint auf den ersten Blick sehr gut zu funktionieren: Anwendungen können nur dann eine Verbindung zum Web herstellen, wenn die OpenVPN-Verbindung aktiv ist, sodass ich niemals Daten über eine unsichere Verbindung verliere.

Wenn ich jedoch den Laptopdeckel schließe und wieder öffne oder WLAN aus- und wieder einschalte, geht die WLAN-Verbindung verloren und in der Statusleiste wird ein Ausrufezeichen im WLAN-Symbol angezeigt. Wenn Sie auf das WLAN-Symbol klicken, wird die Meldung "Warnung: Keine Internetverbindung" angezeigt:

Keine Internetverbindungsmeldung

Um die Verbindung wiederherzustellen, muss ich das WLAN manchmal fünf- oder sechsmal trennen und erneut verbinden, bevor die Meldung "Warnung: Keine Internetverbindung" verschwindet und ich die VPN-Verbindung erneut öffnen kann. In anderen Fällen verschwindet die WLAN-Warnung von selbst, das Ausrufezeichen wird gelöscht und ich kann erneut eine Verbindung herstellen. In beiden Fällen kann es fünf Minuten oder länger dauern, bis die Verbindung wiederhergestellt ist, was frustrierend sein kann.

Durch das Entfernen der Leitung wird block alldas Problem behoben (es werden jedoch unsichere Verbindungen zugelassen), sodass anscheinend ein Dienst blockiert wird, den Apple benötigt, um eine Wi-Fi-Verbindung wiederherzustellen und zu bestätigen. Ich habe versucht:

  • Aktivierung von icmp durch Hinzufügen pass on $wifi proto icmp allzu pf.conf
  • Aktivieren der DNS-Auflösung durch Hinzufügen pass on $wifi proto udp from $wifi to any port 53
  • Der Versuch , mehr zu lernen , durch die Protokollierung Pakete blockiert (durch Ändern block allzu block log all), aber die Protokollierung scheint unter OS X deaktiviert werden, da dabei sudo tcpdump -n -e -ttt -i pflog0die Log - Ergebnisse in sehen „tcpdump: pflog0: Kein solches Gerät vorhanden ist “.

Nichts davon hilft dabei, eine Wi-Fi-Verbindung schneller wiederherzustellen.

Was kann ich noch tun, um zu bestimmen, welcher Dienst verfügbar sein muss, um die Wi-Fi-Konnektivität wiederherzustellen, oder welche Regel sollte ich pf.conf hinzufügen, um die Zuverlässigkeit der Wi-Fi-Wiederverbindungen zu erhöhen?

Nick
quelle
1
Dies kann für diejenigen relevant sein, die später kommen: sparklabs.com/support/preventing_network_and_dns_traffic_leaks
ptim

Antworten:

14

Bei der Überwachung von Netzwerkverbindungen mit Little Snitch habe ich festgestellt, dass Apple die mDNSResponder-App im Hintergrund verwendet, um zu überprüfen, ob die Wi-Fi-Verbindung verfügbar ist. mDNSResponder sendet UDP-Pakete an Nameserver, um die Konnektivität zu überprüfen und Hostnamen in IPs aufzulösen.

Das Ändern der UDP-Regel, die ich zuvor hatte, um alle UDP-Pakete über Wi-Fi zuzulassen, ermöglicht mDNSResponder, eine Verbindung herzustellen. Falls es anderen in Zukunft hilft, sieht meine endgültige pf.conf mit Apples Standardregeln für Mountain Lion so aus:

#
# com.apple anchor point
#
scrub-anchor "com.apple/*"
nat-anchor "com.apple/*"
rdr-anchor "com.apple/*"as
dummynet-anchor "com.apple/*"
anchor "com.apple/*"
load anchor "com.apple" from "/etc/pf.anchors/com.apple"

#
# Allow connection via Viscosity only
#
wifi=en1 #change this to en0 on MacBook Airs and other Macs without ethernet ports
vpn=tun0
vpn2=tap0

block all

set skip on lo          # allow local traffic

pass on p2p0            #allow AirDrop
pass on p2p1            #allow AirDrop
pass on p2p2            #allow AirDrop
pass quick proto tcp to any port 631    #allow AirPrint

pass on $wifi proto udp # allow only UDP packets over unprotected Wi-Fi
pass on $vpn            # allow everything else through the VPN (tun interface)
pass on $vpn2           # allow everything else through the VPN (tap interface)

Dies bedeutet, dass die wenigen Anwendungen, die das UDP-Protokoll verwenden, wie z. B. ntpd (für die Zeitsynchronisation) und mDNSResponder, jetzt Daten über WLAN übertragen können. Dies scheint jedoch immer noch besser zu sein, als zuzulassen, dass Daten ungeschützt über TCP übertragen werden. Dies wird von den meisten Anwendungen verwendet. Wenn jemand Vorschläge zur Verbesserung dieses Setups hat, sind Kommentare oder weitere Antworten willkommen.

Nick
quelle
Dies ist etwas, an dem ich mich gelegentlich interessiert habe. Ihre Ergebnisse haben mich dazu inspiriert, nach Hause zu gehen und es zu versuchen! Vielen Dank!
Jakev
@SixSlayer Es scheint ziemlich gut zu funktionieren! Ich habe Viscosity so eingerichtet, dass es beim Start und bei Verbindungsabbrüchen automatisch eine Verbindung herstellt, was das Ganze ziemlich nahtlos macht. Zu beachten ist vor allem, dass pf.conf und com.apple.pfctl.plist anscheinend nach Betriebssystemaktualisierungen auf die Standardeinstellungen zurückgesetzt werden. Es lohnt sich also, eine Sicherungskopie von beiden zu erstellen.
Nick
IMHO ist die UDP-Sache eine Art Patzer. Ich bin kein Netzwerktyp, aber das hilft mir beim Lernen und ich habe eine Faszination für die Kontrolle über diese Art von Details. Ich werde einige Zeit damit verbringen, nach einer Arbeit zu suchen, aber wenn mich jemand schlägt, dann auch.
Jakev
Das ist großartig - genau das, wonach ich gesucht habe. Vielen Dank!
Keo
Haben Sie es vielleicht geschafft, viele OpenVPN-Verbindungen gleichzeitig zu öffnen und parallel zu routen? (um Bandbreite zu gewinnen und zu addieren)
keo
11

Sie müssen nicht alle UDP zulassen . Das "m" in mDNS bedeutet "Multicast" und verwendet eine bestimmte Multicast-Ziel-IP-Adresse, die als "Link Local Multicast Address" bezeichnet wird, und eine UDPPortnummer 5353.

Dies bedeutet, dass Sie in Ihrer obigen Lösung unnötigerweise zulassen, dass Datenverkehr zu allen 65535 UDP-Ports zu allen 3,7 Milliarden routingfähigen IP-Adressen auf der Welt übertragen wird, um Ihr VPN zu umgehen. Sie wären überrascht, wie viele Anwendungen UDP verwenden, und würden den Zweck Ihrer ursprünglichen Idee, ausgehenden Datenverkehr zu verhindern, wenn das VPN ausfällt, deutlich verfehlen.

Warum nicht stattdessen diese Regel verwenden:

pass on $wifi proto udp to 224.0.0.251 port 5353

Eine sehr wichtige Faustregel bei der Firewall-Konfiguration: Versuchen Sie immer, die spezifischste Regel zu verwenden, wenn Sie Ausnahmen durch Ihre Firewall machen. Die Spezifität geht manchmal zu Lasten der Benutzerfreundlichkeit, dh Sie müssen möglicherweise ein anderes verbindungslokales Protokoll durchlassen und eine weitere spezifische Regel hinzufügen.

Wenn Sie die obige Regel eintauschen und feststellen, dass das ursprüngliche WLAN-Problem erneut auftritt, blockiert Ihr PF möglicherweise DHCP, das Protokoll, mit dem die IP-Adressen Ihrer Netzwerkgeräte automatisch konfiguriert werden. (In einem Heimnetzwerk ist normalerweise Ihr Breitbandrouter Ihr DHCP-Server.) Die Regel, die Sie benötigen, um DHCP zuzulassen, lautet:

pass on $wifi proto udp from 0.0.0.0 port 68 to 255.255.255.255 port 67

* Hinweis: Sie können als Ersatz benötigen 0.0.0.0für any. Das DHCPREQUESTPaket, das Ihr Computer zuerst sendet, hat eine Quelladresse, 0.0.0.0da Ihr Computer zu diesem Zeitpunkt noch keine IP-Adresse hat.
Um ehrlich zu sein, würde ich eher auf die Verwendung von neigen any. Eine andere Möglichkeit besteht darin, eine Quellspezifikation herauszureißen, das heißt pass on $wifi proto udp to 255.255.255.255 port 67, wir verlieren den Quellport-Teil der Regel, und es ist immer die sicherste Möglichkeit, so spezifisch wie möglich zu sein.

Hoffentlich hilft das. Hier sind einige nützliche Links:

mDNS: http://en.wikipedia.org/wiki/Multicast_DNS#Packet_structure

DHSP: http://en.wikipedia.org/wiki/Dynamic_Host_Configuration_Protocol#DHCP_discovery

zerschmetternd
quelle
1

Dies gab mir genügend Hintergrundinformationen, um den großen Sprung zu machen und pf.conf zu verwenden. Folgendes verwende ich auf meinem 10.8, um die Verbindung wiederherzustellen, nachdem die VPN-Verbindung unterbrochen wurde:

(Ich benutze nur Ethernet, aber Sie können $ lan für $ wifi ändern und es sollte funktionieren)

lan=en0
wifi=en1
vpn=tun0
block all
set skip on lo
pass on $lan proto { udp,tcp } to 8.8.8.8
pass on $lan proto tcp to vpn.btguard.com port 1194
pass on $vpn
Cedric
quelle
1

Mit dem Ziel, die PF-Regeln auf "einfache" Weise zu erstellen und vorhandene aktive Schnittstellen einschließlich der aktuellen (vpn-) Schnittstellen zu identifizieren, kann dieses kleine Killswitch- Programm verwendet werden.

Ist noch in Arbeit, könnte jedoch ein guter Anfang für die Identifizierung externer IP-Adressen und aktiver Schnittstellen sein, um die Firewall-Regeln ordnungsgemäß zu erstellen.

Beispiel oder Ausgabe mit der -iOption (info):

$ killswitch -i
Interface  MAC address         IP
en1        bc:57:36:d1:82:ba   192.168.1.7
ppp0                           10.10.1.3

public IP address: 93.117.82.123

Server-IP übergeben -ip:

# --------------------------------------------------------------
# Sat, 19 Nov 2016 12:37:24 +0100
# sudo pfctl -Fa -f ~/.killswitch.pf.conf -e
# --------------------------------------------------------------
int_en1 = "en1"
vpn_ppp0 = "ppp0"
vpn_ip = "93.117.82.123"
set block-policy drop
set ruleset-optimization basic
set skip on lo0
block all
pass on $int_en1 proto udp to 224.0.0.251 port 5353
pass on $int_en1 proto udp from any port 67 to any port 68
pass on $int_en1 inet proto icmp all icmp-type 8 code 0
pass on $int_en1 proto {tcp, udp} from any to $vpn_ip
pass on $vpn_ppp0 all

Ist alles andere als perfekt, aber es wird noch gearbeitet. Weitere Informationen / Code finden Sie hier: https://github.com/vpn-kill-switch/killswitch

nbari
quelle
0

- Als Ergänzung -

Vielleicht möchten Sie diese Zeile hinzufügen:

pass on $wifi inet6 proto udp from any to FF02:0000:0000:0000:0000:0000:0000:00FB port 5353

damit mDNS auf ipv6 betrieben werden kann

user263367
quelle