Zapobiegaj ruchowi wychodzącemu, chyba że połączenie OpenVPN jest aktywne przy użyciu pf.conf w Mac OS X.

19

Byłem w stanie odmówić wszystkich połączeń z sieciami zewnętrznymi, chyba że moje połączenie OpenVPN jest aktywne przy użyciu pf.conf. Jednak tracę łączność Wi-Fi, jeśli połączenie zostanie zerwane przez zamknięcie i otwarcie pokrywy laptopa lub wyłączenie i ponowne włączenie Wi-Fi.

  • Jestem w systemie Mac OS 10.8.1.
  • Łączę się z Internetem przez Wi-Fi (z różnych lokalizacji, w tym z publicznej sieci Wi-Fi).
  • Połączenie OpenVPN jest konfigurowane za pomocą Viscosity.

Mam skonfigurowane następujące reguły filtrowania pakietów /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

Uruchamiam usługę filtrowania pakietów za pomocą sudo pfctl -ei ładuję nowe reguły za pomocą sudo pfctl -f /etc/pf.conf.

Zredagowałem również /System/Library/LaunchDaemons/com.apple.pfctl.plisti zmieniłem wiersz <string>-f</string>do odczytu, <string>-ef</string>aby filtr pakietów uruchamiał się przy uruchomieniu systemu.

Na początku wszystko wydaje się działać świetnie: aplikacje mogą łączyć się z Internetem tylko wtedy, gdy aktywne jest połączenie OpenVPN, więc nigdy nie wyciekam danych przez niepewne połączenie.

Ale jeśli zamknę i ponownie otworzę pokrywę laptopa lub wyłączę i ponownie włączę Wi-Fi, połączenie Wi-Fi zostanie utracone, a na pasku stanu zobaczysz wykrzyknik na ikonie Wi-Fi. Kliknięcie ikony Wi-Fi powoduje wyświetlenie komunikatu „Alert: Brak połączenia z Internetem”:

Brak komunikatu o połączeniu z Internetem

Aby odzyskać połączenie, muszę rozłączyć i ponownie połączyć Wi-Fi, czasami pięć lub sześć razy, zanim zniknie komunikat „Ostrzeżenie: brak połączenia z Internetem” i będę mógł ponownie otworzyć połączenie VPN. Innym razem alert Wi-Fi znika z własnej woli, wykrzyknik jest usuwany i mogę się połączyć ponownie. Tak czy inaczej, ponowne nawiązanie połączenia może potrwać pięć minut lub dłużej, co może być frustrujące.

Usunięcie linii block allrozwiązuje problem (ale pozwala na niebezpieczne połączenia), więc wydaje się, że blokuję usługę wymaganą przez Apple w celu odzyskania i potwierdzenia połączenia Wi-Fi. Próbowałem:

  • Włączanie icmp przez dodanie pass on $wifi proto icmp alldo pf.conf
  • Włączanie rozpoznawania DNS poprzez dodanie pass on $wifi proto udp from $wifi to any port 53
  • Próbuję dowiedzieć się więcej, logując zablokowane pakiety (zmieniając block allna block log all), ale rejestracja wydaje się być wyłączona w OS X, ponieważ zrobienie tego, sudo tcpdump -n -e -ttt -i pflog0aby zobaczyć dziennik, powoduje „tcpdump: pflog0: Nie ma takiego urządzenia”.

Nic z tego nie pomaga szybciej nawiązać połączenia Wi-Fi.

Co jeszcze mogę zrobić, aby określić, która usługa musi być dostępna, aby odzyskać łączność Wi-Fi, lub jaką zasadę należy dodać do pliku pf.conf, aby połączenia były bardziej niezawodne?

Nacięcie
źródło
1
może to być istotne dla tych, którzy przyjdą po: sparklabs.com/support/preventing_network_and_dns_traffic_leaks
ptim

Odpowiedzi:

14

Monitorując połączenia sieciowe za pomocą Little Snitch, zauważyłem, że Apple używa aplikacji mDNSResponder w tle, aby sprawdzić, czy połączenie Wi-Fi jest dostępne. mDNSResponder wysyła pakiety UDP do serwerów nazw w celu sprawdzenia łączności i rozpoznania nazw hostów na adresy IP.

Zmiana reguły UDP, którą wcześniej musiałem zezwalać na wszystkie pakiety UDP przez Wi-Fi, pozwala mDNSResponder na połączenie, co oznacza, że ​​Wi-Fi ponownie łączy się po raz pierwszy po rozłączeniu. Na wypadek, gdyby pomógł innym w przyszłości, moja ostatnia strona pf.conf, w tym domyślne reguły Apple dla Mountain Lion, wygląda następująco:

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

Oznacza to, że dane mogą być teraz wyciekane przez Wi-Fi przez małą liczbę aplikacji korzystających z protokołu UDP, niestety, takich jak ntpd (do synchronizacji czasu) i mDNSResponder. Ale nadal wydaje się to lepsze niż zezwalanie na przesyłanie danych bez ochrony przez TCP, z czego korzysta większość aplikacji. Jeśli ktoś ma jakieś sugestie dotyczące ulepszenia tej konfiguracji, mile widziane są komentarze lub dalsze odpowiedzi.

Nacięcie
źródło
Jest to coś, co od niechcenia mnie interesuje, ponieważ twoje wyniki zainspirowały mnie do powrotu do domu i wypróbowania go! dzięki!
jakev
@SixSlayer Wygląda na to, że działa całkiem dobrze! Mam skonfigurowaną Viscosity do automatycznego łączenia podczas uruchamiania i po zerwanych połączeniach, co sprawia, że ​​całość jest prawie bezproblemowa. Najważniejszą rzeczą do odnotowania jest to, że pf.conf i com.apple.pfctl.plist resetują się do domyślnych po aktualizacjach systemu operacyjnego, najwyraźniej więc warto zachować kopię zapasową obu.
Nick
IMHO sprawa z UDP jest trochę kłopotliwa. Nie jestem facetem od sieci, ale to coś pomaga mi się uczyć i fascynuje mnie kontrola nad takimi szczegółami. Poświęcę trochę czasu na poszukiwanie pracy, ale jeśli ktoś mnie w tym uderzy, to równie dobrze.
jakev
to jest niesamowite - dokładnie to, czego szukałem. Dziękuję Ci!
keo
Czy zdarzyło Ci się mieć wiele otwartych połączeń OpenVPN jednocześnie i przekierowywać je równolegle? (w celu zwiększenia i
zsumowania
11

Nie musisz zezwalać na wszystkie UDP. „M” w mDNS oznacza „multiemisję” i używa określonego docelowego adresu IP multiemisji zwanego „łączem lokalnego adresu multiemisji” i UDPnumeru portu 5353.

Oznacza to, że w powyższym rozwiązaniu niepotrzebnie zezwalasz na ruch do wszystkich portów UDP 65535 do wszystkich 3,7 miliardów routowalnych adresów IP na świecie w celu ominięcia sieci VPN. Zdziwiłbyś się, ile aplikacji korzysta z UDP, więc znacznie pokonujesz cel swojego oryginalnego pomysłu, aby zapobiec wychodzącym ruchom, gdy VPN jest wyłączony.

Dlaczego zamiast tego nie użyć tej reguły:

pass on $wifi proto udp to 224.0.0.251 port 5353

Bardzo ważna zasada przy konfiguracji zapory ogniowej - robiąc wyjątki przez zaporę ogniową, zawsze staraj się stosować najbardziej szczegółową regułę. Ta specyficzność czasami odbywa się kosztem wygody i łatwości użytkowania, tzn. Może się okazać, że istnieje jakiś inny protokół lokalny dla łącza, który należy przepuścić, i dodać jeszcze jedną konkretną regułę.

Jeśli zamienisz powyższą regułę i okaże się, że powraca pierwotny problem z Wi-Fi, Twój PF może blokować DHCP, protokół używany do autokonfiguracji adresów IP urządzeń sieciowych. (w sieci domowej zwykle router szerokopasmowy byłby serwerem DHCP). Reguła, którą musisz zezwolić na DHCP, to:

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

* Uwaga: może trzeba zastąpić 0.0.0.0za any. DHCPREQUESTPakiet komputer najpierw wysyła, ma adresu źródłowego 0.0.0.0, ponieważ na tym etapie, komputer nie ma jeszcze adresu IP.
Szczerze mówiąc, skłaniałbym się bardziej ku użyciu any. Inną opcją jest wykasowanie dowolnej specyfikacji źródłowej, tj. pass on $wifi proto udp to 255.255.255.255 port 67Ale oznacza to, że utracimy część reguły port źródłowy, a bycie tak dokładnym, jak to możliwe, jest zawsze najbezpieczniejszą opcją.

Mam nadzieję, że to pomaga. Oto kilka przydatnych linków:

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

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

miażdżąco
źródło
1

To dało mi wystarczające informacje w tle, aby dokonać dużego skoku i użyć pf.conf. Oto, czego używam na moim 10.8, aby połączyć się ponownie po zerwaniu połączenia VPN:

(Używam tylko Ethernetu, ale możesz zmienić $ lan na $ wifi i powinno to działać)

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
źródło
1

Aby stworzyć reguły PF w „łatwy” sposób, identyfikując istniejące aktywne interfejsy, w tym interfejsy bieżące (VPN), można użyć tego małego programu Killswitch ,

Wciąż trwa, ale może być dobrym początkiem do identyfikacji zewnętrznego adresu IP i aktywnych interfejsów w celu prawidłowego tworzenia reguł zapory.

przykład lub dane wyjściowe przy użyciu opcji -i(informacje):

$ 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

Przekazywanie adresu IP serwera -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

Jest daleki od ideału, ale praca jest w toku. Więcej informacji / kod można znaleźć tutaj: https://github.com/vpn-kill-switch/killswitch

nbari
źródło
0

- Jako dodatek -

Możesz dodać tę linię:

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

aby umożliwić mDNS działanie na ipv6

użytkownik263367
źródło