Jy sit ’n route-opdrag in /etc/ppp/ip-up, verbind die kantoor-tonnel weer, en die lêer loop nooit nie. Niks is verkeerd met die script nie: daardie verbinding gaan glad nie deur PPP nie. Die ingeboude Cisco IPSec- en IKEv2-kliënte begin nooit pppd nie, so die haak-gids word nooit gelees nie, terwyl PPTP en L2TP oor IPSec steeds daardeur gaan. Werk uit watter geval jy het, en aktiveer dan die nie-PPP-een vanuit ’n launchd-wagtaak.

Kyk na die koppelvlak voordat jy enige haak redigeer

Twee opdragte beslis watter meganisme kan werk. Lys die gekonfigureerde dienste, en lys dan die koppelvlakke wat bestaan terwyl die tonnel op is. Die koppelvlaknaam is die bewys; die etiket in Stelselinstellings is nie.

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

’n Diens wat ppp0 lewer, loop die PPP-hake en sal jou lêer uitvoer. ’n Cisco IPSec- of IKEv2-diens lewer eerder ’n utun-toestel, ’n tonnelkoppelvlak sonder ’n PPP-laag, so niks binne /etc/ppp kan dit bereik nie. Wanneer albei soorte opduik, kyk watter diens jy gekoppel het. Mense mors ’n middag op die verkeerde haak deur die kliëntnaam te lees.

Op die PPP-pad moet die lêer aan root behoort en uitvoerbaar wees, want pppd kyk na albei voordat enigiets loop. install stel eienaar en modus in een stap.

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

’n Lêer wat deur Finder of ’n grafiese redigeerder geskep word, behoort dikwels aan jou rekening, of het nie die uitvoerbaarheidsbis nie, en misluk dan net so stil soos die ontbrekende haak. Sit ip-down nou langsaan. root en wheel in die eienaarkolom plus rwxr-xr-x in die moduskolom is wat jy wil hê.

Laat launchd die script afvuur wanneer ’n tonnel verskyn

Vir kliënte wat nooit PPP raak nie, moet die sneller van elders kom, en die stelselkonfigurasiebergplek is die eerlike bron: macOS herskryf dit by elke tonneloorgang. ’n launchd-taak wat daardie gids dophou, word geroep wanneer ’n tonnel verskyn of verdwyn.

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

Installeer dit as ’n launch-daemon, nie as ’n agent per gebruiker nie, want roeteherstel hoort by die masjien. bootstrap vervang die ouer vorm load -w op huidige weergawes. RunAtLoad maak die eerste uitvoering waarneembaar, en ThrottleInterval keer dat ’n reeks Wi-Fi-aansluitings die script herhaaldelik lanseer.

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

Die lokval is dat die dopgehoue gids verander vir gebeurtenisse wat niks met jou VPN te doen het nie: ’n Wi-Fi-aansluiting, ’n DHCP-hernuwing, ’n kabel wat ingeprop word. Die wag hieronder maak van ’n raserige sneller ’n bruikbare haak, en ’n logreël verduidelik ’n roete op ’n vreemde uur.

Eienaarskap dek die plist sowel as die script. ’n Daemon wat ’n lêer uitvoer in ’n gids wat jou eie rekening kan skryf, gee daardie rekening root.

Beskerm die script sodat ’n tweede loop niks verander nie

Die script besluit eers of die tonnel bestaan, en stop stil wanneer dit nie bestaan nie. Alles daarna moet veilig wees om te herhaal, want die sneller vuur baie meer gereeld as ’n enkele verbinding. Los die koppelvlak tydens looptyd op eerder as om ’n indeks hard te kodeer wat by die volgende verbinding verander.

#!/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 stop met ’n nie-nul status wanneer die roete al bestaan, so ’n script wat elke nie-nul status as fout behandel, rapporteer elke keer ’n gebreekte haak wanneer dit die regte ding doen. Die netstat-toets hierbo maak van daardie geval ’n uitdruklike no-op.

Die aanwesigheid van die koppelvlak is swakker bewyse as wat dit lyk, want ander VPN-kliënte en sommige houerruntime skep ook utun-toestelle. Vra die diens self met scutil --nc status "Office VPN" en vereis die gekoppelde toestand voordat jy roetering aanraak. Hou die antwoord in ’n logreël, want ’n week later is daardie rekord die enigste verduideliking wat jy het.

Bring die gateway terug sonder om DNS te breek

Wanneer die tonnel die verstekroete oorneem, verlaat gewone blaai die kantoor en die plaaslike internetpad werk nie meer nie. Vang eers die fisiese koppelvlak se router, en wys dan die verstek terug daarheen. DHCP klop die ontleding van ’n tabel wat al die tonnel se eie verstek bevat.

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

Resolvers is ’n aparte laag met ’n aparte hulpmiddel, en om die roete te herstel herstel hulle nie. Kyk wat in werking is met scutil --dns, en herstel dan wat dit produseer: die diensorde en die DNS-inskrywings op die fisiese diens. Om die kas te spoel diagnoseer ’n opsoek wat ná ’n netwerkwisseling vasgehaak het; dit is nie iets om te skeduleer nie.

’n Tonnel wat ’n Wi-Fi-wisseling oorleef terwyl DNS stol, is ’n derde fout: sudo killall -HUP mDNSResponder laat die resolver sy konfigurasie herlees. Gebruik dit een keer, met die hand.

Bewys dat die taak vanself vuur

Forseer een loop met kickstart -k voordat jy die wagpad vertrou, en lees dan die uittreestatus wat die taak aangeteken het. ’n Skoon uittrede bewys die script werk; dit bewys nie die sneller werk nie. Verbreek dan en verbind weer met die taak gelaai, en kyk vir ’n loop wat jy nie gevra het nie.

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

Kyk na scutil --nc status voor en ná elke poging. ’n Script wat geloop het terwyl die tonnel af was, bewys niks oor die verbindingspad nie.

Die aftakking verdien dieselfde behandeling as die verbindingstakking: verwyder die roete met die hand, laat die taak loop, en bevestig dat dit terugkom. ’n Haak wat ’n roete byvoeg en dit nooit verwyder nie, laat ’n masjien wat ’n week later verkeerd optree, met niks wat die twee gebeurtenisse verbind. Sodra albei gedrag hou, trek sudo launchctl bootout system/net.example.tunnel-watch die taak skoon terug. ’n Wagdaemon wat gelaai gelaat word, is hoe ’n eenmalige herstel maande later ’n onverklaarde roete word.

Verwante artikels