pf-kill switch i macOS for OpenVPN: regler som feiler lukket
Et pf-regelsett blokkerer direkte trafikk mens tunnelen er nede. Behold klientens vei til serveren sin, og bevis deretter blokkeringen med tunnelen av.
På macOS er en kill switch bare så god som pakkefilterpolitikken bak den, og pf er delen som håndhever den politikken. Politikken må gjøre to motsatte ting samtidig: la klienten nå serveren sin slik at en tunnel kan finnes, og stoppe alt annet fra å gå direkte ut. De fleste publiserte regelsett får til det andre og glemmer det første, så maskinen mister tilkoblingen i stedet for å vinne beskyttelse. Versjonen som virker navngir endepunktet, resolveren og tunnelen, og ikke noe mer.
Hva et pakkefilter kan avgjøre, og hva det ikke kan
pf ser på grensesnitt, adresser, protokollnumre og porter, og stopper der. Det lærer aldri hvilken prosess som åpnet en socket, så en tillatelse skrevet for ett program blir en tillatelse for hvert program som kan nå samme port. Det er slik et rundhåndet UDP-unntak gjør en kill switch tilbake til et vanlig nettverk. Applikasjonsbevisst blokkering hører til klienten eller en systemutvidelse, ikke til denne filen.
Filteret lager heller ikke ruter. Når klienten faller, kan standardruten fortsatt peke på en død tunnel, og pf gjør det om til blokkerte pakker i stedet for et stille fall tilbake til Wi-Fi. Blokkeringen er det tilsiktede resultatet, ikke en feil man skal rute utenom.
Rekkefølgen avgjør utfallet oftere enn regelteksten. Uten quick fortsetter pf å vurdere etter et treff, og den siste matchende regelen vinner, så en bred passering nederst overstyrer de grundige unntakene over. Å merke passeringene med quick gjør første treff endelig, som er det en politikkforfatter vanligvis mener.
Les fakta om grensesnitt og endepunkt først
Trådløse grensesnitt nummereres ikke likt på hver Mac, og tunneleenheten får et nummer som kan endre seg mellom oppstarter. En regel som navngir en enhet som ikke finnes, feiler ved parsing, noe som er høyt og lett å fange, mens en regel som navngir feil eksisterende enhet parses rent og slipper gjennom trafikk du ville stoppe.
Samle fakta mens klienten er tilkoblet, for tunneleenheten finnes bare da. Du trenger grensesnittet som holder standardruten, enheten klienten laget, og adressen og porten til serveren den ringer. Nettopp den siste verdien er den de fleste regelsett utelater, og å utelate den er grunnen til at et kopiert regelsett blokkerer sin egen tunnel.
route -n get default
ifconfig -l
scutil --nc list
Den første kommandoen navngir grensesnittet som vinner nå, den andre lister hver enhet kjernen kjenner, og den tredje viser VPN-konfigurasjonene systemet kan starte. Skriv ned svarene, og les deretter serveradressen og porten fra klientens egen konfigurasjon.
Skriv regelsettet rundt tunnelens vei
Filen nedenfor avviser som standard og slipper inn fem ting igjen: loopback, tunneleenheten, klientens vei til serveren sin, resolveren som brukes før tunnelen finnes, og de to utvekslingene som holder en trådløs lenke brukbar. Grensesnittnavn og serveradressen kommer fra maskinen din, så bytt ut verdiene du bekreftet. Tunnelnummeret vil heller ikke stemme med ditt.
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
DHCP-linjen finnes fordi en Mac ber om en adresse før den har en, så forespørselen forlater port 68 mot port 67 uten en brukbar kildeadresse. Multicast-linjen lar systemet vurdere om den trådløse lenken er verdt å bruke, og å fjerne den gir en maskin som melder ingen tilkobling på et fungerende nettverk. Endepunktlinjen er det som lar OpenVPN nå serveren sin i det hele tatt; uten den slipper block all det ytre håndtrykket og tunnelen reiser seg aldri. Resolverlinjen er smalere enn en generell DNS-tillatelse, fordi den navngir én adresse og én port i stedet for hver forespørsel maskinen gjør.
De endepunkt- og resolverunntakene er de to som må finnes; alt annet forblir blokkert. Hvis klienten ringer en bokstavelig adresse, fjern resolverlinjen og behold endepunktlinjen. Hvis serveradressen endres, oppdater den linjen før neste tilkobling, eller fyll en pf-tabell fra klientens egen krok og match tabellen i stedet.
Ta tunnelen ned, og start deretter på nytt
Parse før lasting, for en syntaksfeil er billig i en tørrkjøring og dyr i en fjernøkt. Last deretter filen, aktiver filteret hvis det var av, og les tilbake hva som faktisk er i kraft. Tilbakelesingen er ikke seremoni: et annet anker kan legge til regler du ikke skrev, så sammenlign det utskrevne settet med filen din.
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
Med reglene lastet, ta tunnelen ned og prøv å laste en side. Vanlig trafikk skal stoppe, og den skal fortsatt være stoppet etter at maskinen sover og våkner, for det er i den overgangen gammel tilstand siver tilbake. Koble til på nytt og bekreft at trafikken fortsetter uten å røre regelsettet. Hvis en nettleser fortsatt virker med tunnelen nede, er en regel bredere enn du trodde, og tilbakelesingen navngir den vanligvis.
Omstarten er den delen folk hopper over. macOS leser /etc/pf.conf ved oppstart, men å lese filen er ikke det samme som å aktivere filteret, så et regelsett som virker nå kan være inaktivt etter en omstart. Kjør deretter sudo pfctl -s info og bekreft at statuslinjen melder filteret som aktivert.
Hold utgangen og omstartveien ærlig
Et regelsett som blokkerer alt, kan også låse deg ute av en maskin du administrerer eksternt. Rediger fra en lokal økt når du kan, ha den forrige filen ved siden av den nye, og kjenn tilbakeveien før du trenger den. Kommandoene nedenfor deaktiverer filteret og laster inn kopien du beholdt, og det er sekvensen for en konsoll, ikke over tunnelen du nettopp kuttet. En tilbakeføring på fem sekunder slår en smart regel hver gang.
sudo pfctl -d
sudo pfctl -f /etc/pf.conf.previous
sudo pfctl -s rules
Varighet krever en launch daemon som kjører pfctl -e og laster filen din ved oppstart. Behandle den som enhver annen privilegert jobb: absolutte stier, en logg du kan lese etterpå, og en test på en maskin du fysisk kan nå. En daemon som feiler stille, lar maskinen stå ubeskyttet og se normal ut.
Dokumenter hullene, og start med en annen VPN-klient som lager sin egen tunneleenhet. Reglene dine navngir ett tunnelgrensesnitt, så et andre forblir blokkert eller blir fanget av en bred regel som legges til senere. Tethering- og hotspot-grensesnitt dukker bare opp noen ganger og fortjener samme merknad. Ingen av disse hullene er grunn til å hoppe over politikken; de er betingelsene den fortsatt holder under.