Mac VPN pripojené, ale ip-up sa nikdy nespustil: nastavte launchd sledovanie
Tunely Cisco IPSec a IKEv2 nikdy nespúšťajú pppd, takže /etc/ppp/ip-up zostáva ticho. Sledujte konfiguračný adresár a donúťte skript tunel preukázať.
Dáte príkaz route do /etc/ppp/ip-up, znova pripojíte kancelársky tunel a súbor sa nikdy nespustí. So skriptom nie je nič zlé: toto pripojenie vôbec nejde cez PPP. Vstavané klienty Cisco IPSec a IKEv2 nikdy nespúšťajú pppd, takže adresár hookov sa nikdy nečíta, zatiaľ čo PPTP a L2TP cez IPSec ním stále prechádzajú. Zistite, ktorý prípad máte, a potom ten ne-PPP spustite z úlohy launchd sledovania.
Skôr než upravíte akýkoľvek hook, skontrolujte rozhranie
Dva príkazy rozhodnú, ktorý mechanizmus môže fungovať. Vypíšte nakonfigurované služby, potom vypíšte rozhrania, ktoré existujú, kým je tunel aktívny. Názov rozhrania je dôkaz; popis v Nastaveniach systému nie je.
scutil --nc list
ifconfig -l | tr ' ' '\n' | grep -E '^(utun|ppp)[0-9]+$'
Služba, ktorá vytvára ppp0, spúšťa PPP hooky a spustí váš súbor. Služba Cisco IPSec alebo IKEv2 namiesto toho vytvára zariadenie utun, tunelové rozhranie bez PPP vrstvy, takže nič vnútri /etc/ppp sa k nemu nedostane. Keď sa objavia oba druhy, overte, ku ktorej službe ste sa pripojili. Ľudia stratia popoludnie na nesprávnom hooku, pretože čítajú názov klienta.
Na ceste PPP musí súbor patriť rootovi a byť spustiteľný, pretože pppd kontroluje oboje, skôr než čokoľvek spustí. install nastaví vlastníka aj režim v jednom kroku.
sudo install -o root -g wheel -m 0755 /dev/null /etc/ppp/ip-up
sudo ls -l /etc/ppp/ip-up
Súbor vytvorený cez Finder alebo grafický editor často skončí vo vlastníctve vášho účtu alebo bez práva spustenia a potom zlyhá rovnako ticho ako chýbajúci hook. Umiestnite vedľa neho hneď ip-down. root a wheel v stĺpci vlastníka plus rwxr-xr-x v stĺpci režimu je to, čo chcete.
Nechajte launchd spustiť skript, keď sa objaví tunel
Pre klientov, ktorí sa PPP nikdy nedotknú, musí spúšťač prísť odinakiaľ, a úložisko systémovej konfigurácie je poctivý zdroj: macOS ho prepisuje pri každom prechode tunela. Úloha launchd, ktorá tento adresár sleduje, sa zavolá, keď sa tunel objaví alebo zmizne.
<?xml version="1.0" encoding="UTF-8"?>
<plist version="1.0">
<dict>
<key>WatchPaths</key>
<array><string>/Library/Preferences/SystemConfiguration</string></array>
<key>Label</key><string>net.example.tunnel-watch</string>
<key>ProgramArguments</key>
<array><string>/bin/sh</string><string>/usr/local/sbin/tunnel-hook</string></array>
<key>RunAtLoad</key><true/>
<key>ThrottleInterval</key><integer>20</integer>
</dict>
</plist>
Nainštalujte ho ako launch daemon, nie ako agenta pre jednotlivého používateľa, pretože oprava trás patrí stroju. bootstrap nahrádza v aktuálnych verziách staršiu formu load -w. RunAtLoad robí prvé spustenie pozorovateľným a ThrottleInterval bráni tomu, aby séria zmien pri pripájaní k Wi-Fi spúšťala skript opakovane.
sudo install -o root -g wheel -m 0644 tunnel-watch.plist \
/Library/LaunchDaemons/net.example.tunnel-watch.plist
sudo launchctl bootstrap system \
/Library/LaunchDaemons/net.example.tunnel-watch.plist
Pasca je v tom, že sledovaný adresár sa mení aj pri udalostiach, ktoré s vašou VPN nemajú nič spoločné: pripojenie k Wi-Fi, obnova DHCP, zapojený kábel. Strážca nižšie mení hlučný spúšťač na použiteľný hook a riadok v logu vysvetlí trasu v nezvyčajnej hodine.
Vlastníctvo zahŕňa plist rovnako ako skript. Daemon, ktorý spúšťa súbor v adresári, kam váš účet môže zapisovať, dáva tomu účtu root.
Chráňte skript, aby druhé spustenie nič nezmenilo
Skript najprv rozhodne, či tunel existuje, a keď nie, ticho skončí. Všetko po tom musí byť bezpečné opakovať, pretože spúšťač sa aktivuje oveľa častejšie než jediné pripojenie. Rozhranie zisťujte za behu, namiesto toho, aby ste natvrdo kódovali index, ktorý sa pri ďalšom pripojení zmení.
#!/bin/sh
set -u
TUN=$(ifconfig -l | tr ' ' '\n' | grep -m1 '^utun[0-9]' || true)
[ -n "$TUN" ] || exit 0
netstat -rn -f inet | grep -q '^10\.42' && exit 0
route -n add -net 10.42.0.0/16 -interface "$TUN"
route add skončí s nenulovým stavom, keď trasa už existuje, takže skript, ktorý každý nenulový stav berie ako chybu, hlási rozbitý hook vždy, keď robí správnu vec. Test s netstat vyššie mení tento prípad na výslovný no-op.
Prítomnosť rozhrania je slabší dôkaz, než to vyzerá, pretože iní klienti VPN a niektoré kontajnerové prostredia tiež vytvárajú zariadenia utun. Spýtajte sa samotnej služby pomocou scutil --nc status "Office VPN" a pred zásahom do smerovania vyžadujte pripojený stav. Odpoveď držte v riadku logu, pretože o týždeň bude ten záznam jediné vysvetlenie, ktoré budete mať.
Vráťte bránu späť bez rozbitia DNS
Keď tunel prevezme predvolenú trasu, bežné prehliadanie vychádza cez kanceláriu a miestna internetová cesta prestane fungovať. Najprv zachyťte router fyzického rozhrania, potom predvolenú trasu nasmerujte späť naň. DHCP je lepší než parsovanie tabuľky, ktorá už obsahuje vlastnú predvolenú trasu tunela.
PHYS=en0
GW=$(ipconfig getoption "$PHYS" router)
[ -n "$GW" ] && sudo route -n change default "$GW"
Resolvery sú samostatná vrstva so samostatným nástrojom a oprava trasy ich neopraví. Pozrite sa pomocou scutil --dns, čo platí, a potom opravte to, čo to vytvára: poradie služieb a DNS záznamy na fyzickej službe. Vyprázdnenie cache diagnostikuje dopyt zaseknutý po zmene siete; nie je to niečo, čo sa má plánovať.
Tunel, ktorý prežije zmenu Wi-Fi, ale DNS zamrzne, je tretia závada: sudo killall -HUP mDNSResponder prinúti resolver znova načítať konfiguráciu. Použite to raz, ručne.
Dokážte, že sa úloha spúšťa sama
Vynúťte jedno spustenie pomocou kickstart -k, kým uveríte ceste sledovania, a potom prečítajte návratový stav, ktorý úloha zaznamenala. Čistý návrat dokazuje, že skript funguje; nedokazuje, že funguje spúšťač. Potom sa odpojte a znova pripojte s načítanou úlohou a sledujte spustenie, o ktoré ste nežiadali.
sudo launchctl kickstart -k system/net.example.tunnel-watch
sudo launchctl print system/net.example.tunnel-watch | grep -E 'last exit code|state ='
Pred každým pokusom a po ňom skontrolujte scutil --nc status. Skript, ktorý bežal, keď bol tunel dole, o ceste pripojenia nič nedokazuje.
Vetva demontáže si zaslúži rovnaké zaobchádzanie ako vetva pripojenia: odstráňte trasu ručne, nechajte úlohu bežať a potvrďte, že sa vráti. Hook, ktorý pridá trasu a nikdy ju neodstráni, zanechá stroj, ktorý sa o týždeň správa zle, a nič tie dve udalosti nespája. Keď obe správania obstoja, sudo launchctl bootout system/net.example.tunnel-watch úlohu čisto vyradí. Ponechaný načítaný sledovací démon je spôsob, akým sa jednorazová oprava po mesiacoch stane nevysvetlenou trasou.