Paned route-käsu faili /etc/ppp/ip-up, ühendad kontoritunneli uuesti ja fail ei käivitu kunagi. Skriptiga pole midagi valesti: see ühendus ei läbi PPP-d üldse. Sisseehitatud Cisco IPSec ja IKEv2 kliendid ei käivita kunagi pppd, nii et hook-kausta ei loeta kunagi, samal ajal kui PPTP ja L2TP üle IPSec-i käivad endiselt sellest läbi. Tee kindlaks, milline juhtum sinul on, ja käivita seejärel mitte-PPP juhtum launchd-jälgimistööst.

Kontrolli liidest enne, kui muudad ükskõik millist hooki

Kaks käsku otsustavad, milline mehhanism saab töötada. Loetle seadistatud teenused, seejärel loetle liidesed, mis tunnelitöö ajal olemas on. Liidese nimi on tõestus; System Settingsi silt ei ole.

scutil --nc list
ifconfig -l | tr ' ' '\n' | grep -E '^(utun|ppp)[0-9]+$'

Teenus, mis loob ppp0, käivitab PPP-hookid ja täidab sinu faili. Cisco IPSec või IKEv2 teenus loob selle asemel utun seadme, PPP-kihita tunneliliidese, nii et miski /etc/ppp sees ei pääse sellele ligi. Kui mõlemad liigid ilmuvad, kontrolli, millise teenusega ühendusid. Inimesed raiskavad pärastlõuna vale hooki peale, lugedes kliendi nime.

PPP-teel peab fail kuuluma root-ile ja olema täidetav, sest pppd kontrollib mõlemat enne, kui midagi käivitab. install seab omaniku ja režiimi ühe sammuga.

sudo install -o root -g wheel -m 0755 /dev/null /etc/ppp/ip-up
sudo ls -l /etc/ppp/ip-up

Finderi või graafilise redaktori kaudu loodud fail satub sageli sinu konto omandisse või jääb täitmisbitita ning ebaõnnestub siis sama vaikselt kui puuduv hook. Pane ip-down selle kõrvale kohe. root ja wheel omaniku veerus pluss rwxr-xr-x režiimi veerus on see, mida sa tahad.

Lase launchd-il skript käivitada, kui tunnel ilmub

Klientide puhul, kes PPP-d kunagi ei puuduta, peab päästik tulema mujalt, ja süsteemi konfiguratsioonihoidla on aus allikas: macOS kirjutab selle igal tunneli üleminekul üle. Seda kausta jälgiv launchd-töö kutsutakse välja, kui tunnel ilmub või kaob.

<?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>

Paigalda see launch-daemonina, mitte kasutajapõhise agendina, sest marsruudi parandamine kuulub masinale. bootstrap asendab praegustes versioonides vanema vormi load -w. RunAtLoad teeb esimese täitmise jälgitavaks ja ThrottleInterval takistab Wi-Fi ühendumise muudatuste tulval skripti korduvalt käivitada.

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

Lõks on selles, et jälgitud kaust muutub ka sündmuste puhul, millel pole sinu VPN-iga mingit seost: Wi-Fi ühendumine, DHCP uuendamine, sissepistud kaabel. Allpool olev valvur muudab lärmaka päästiku kasutatavaks hookiks ja logirida selgitab kummalisel tunnil tekkinud marsruuti.

Omandiõigus katab plist-i nagu ka skripti. Deemon, mis täidab faili kaustas, kuhu sinu enda konto saab kirjutada, annab sellele kontole root-i.

Kaitse skripti, et teine käivitus ei muudaks midagi

Skript otsustab kõigepealt, kas tunnel on olemas, ja väljub vaikselt, kui pole. Kõik pärast seda peab olema ohutult korratav, sest päästik rakendub palju sagedamini kui üksainus ühendus. Lahenda liides käitusajal, selle asemel et kõvasti kodeerida indeksit, mis järgmisel ühendamisel muutub.

#!/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 väljub nullist erineva olekuga, kui marsruut on juba olemas, nii et skript, mis käsitleb iga nullist erinevat olekut veana, teatab katkisest hookist iga kord, kui teeb õiget asja. Ülal olev netstat test muudab selle juhtumi selgesõnaliseks no-op-iks.

Liidese olemasolu on nõrgem tõestus, kui see paistab, sest ka teised VPN-kliendid ja mõned konteinerikeskkonnad loovad utun seadmeid. Küsi teenuselt endalt scutil --nc status "Office VPN" abil ja nõua ühendatud olekut enne marsruutimise puutumist. Hoia vastust logireal, sest nädala pärast on see kirje ainus selgitus, mis sul on.

Too lüüs tagasi DNS-i rikkumata

Kui tunnel võtab üle vaikemarsruudi, väljub tavaline sirvimine kontori kaudu ja kohalik internetitee lakkab töötamast. Püüa esmalt füüsilise liidese ruuter ja suuna siis vaikemarsruut sellele tagasi. DHCP on parem kui tabeli parsimine, mis sisaldab juba tunneli enda vaikemarsruuti.

PHYS=en0
GW=$(ipconfig getoption "$PHYS" router)
[ -n "$GW" ] && sudo route -n change default "$GW"

Resolverid on eraldi kiht eraldi tööriistaga ja marsruudi parandamine ei paranda neid. Vaata scutil --dns abil, mis kehtib, ja paranda siis see, mis seda tekitab: teenuste järjekord ja DNS-kirjed füüsilisel teenusel. Vahemälu tühjendamine diagnoosib pärast võrguvahetust kinni jäänud päringut; see pole midagi, mida ajastada.

Tunnel, mis elab üle Wi-Fi vahetuse, samal ajal kui DNS tõrkub, on kolmas viga: sudo killall -HUP mDNSResponder paneb resolveri oma konfiguratsiooni uuesti lugema. Kasuta seda üks kord, käsitsi.

Tõesta, et töö käivitub ise

Sunniviisiliselt üks käivitus kickstart -k abil, enne kui usaldad jälgimisteed, ja loe siis väljumisolek, mille töö salvestas. Puhas väljumine tõestab, et skript töötab; see ei tõesta, et päästik töötab. Seejärel ühenda lahti ja uuesti, kui töö on laaditud, ning jälgi käivitust, mida sa ei küsinud.

sudo launchctl kickstart -k system/net.example.tunnel-watch
sudo launchctl print system/net.example.tunnel-watch | grep -E 'last exit code|state ='

Kontrolli scutil --nc status enne ja pärast iga katset. Skript, mis töötas siis, kui tunnel oli maas, ei tõesta ühenduste tee kohta midagi.

Lammutusharu väärib sama kohtlemist kui ühendusharu: eemalda marsruut käsitsi, lase tööl töötada ja kinnita, et see tuleb tagasi. Hook, mis lisab marsruudi ega eemalda seda kunagi, jätab masina, mis käitub nädal hiljem halvasti, ilma et miski need kaks sündmust ühendaks. Kui mõlemad käitumised püsivad, võtab sudo launchctl bootout system/net.example.tunnel-watch töö puhtalt maha. Laadituna jäetud jälgimisdeemon on see, kuidas ühekordne parandus muutub kuude pärast seletamatuks marsruudiks.

Seotud artiklid