Mac-VPN konektita sed ip-up neniam ekfunkciis: starigu launchd-gvaton
Tuneloj Cisco IPSec kaj IKEv2 neniam lanĉas pppd, do /etc/ppp/ip-up restas silenta. Gvatu la agordan dosierujon kaj igi la skripton pruvi la tunelon.
Vi metas route-komandon en /etc/ppp/ip-up, rekonektas la oficejan tunelon, kaj la dosiero neniam ruliĝas. Nenio malbonas en la skripto: tiu konekto tute ne pasas tra PPP. La enkonstruitaj klientoj Cisco IPSec kaj IKEv2 neniam lanĉas pppd, do la hoka dosierujo neniam legiĝas, dum PPTP kaj L2TP super IPSec ankoraŭ pasas tra ĝi. Determinu, kiun kazon vi havas, kaj poste ekigu la ne-PPP-an el launchd-gvata tasko.
Kontrolu la interfacon antaŭ ol redakti ajnan hokon
Du komandoj decidas, kiu mekanismo povas funkcii. Listigu la agorditajn servojn, poste listigu la interfacojn, kiuj ekzistas dum la tunelo estas aktiva. La nomo de la interfaco estas la pruvo; la etikedo en Sistemaj Agordoj ne estas.
scutil --nc list
ifconfig -l | tr ' ' '\n' | grep -E '^(utun|ppp)[0-9]+$'
Servo, kiu produktas ppp0, rulas la PPP-hokojn kaj rulos vian dosieron. Servo Cisco IPSec aŭ IKEv2 produktas anstataŭe aparaton utun, tunelan interfacon sen PPP-tavolo, do nenio ene de /etc/ppp povas atingi ĝin. Kiam aperas ambaŭ specoj, kontrolu al kiu servo vi konektiĝis. Homoj malŝparas posttagmezon ĉe la malĝusta hoko legante la nomon de la kliento.
Sur la PPP-vojo la dosiero devas aparteni al root kaj esti plenumebla, ĉar pppd kontrolas ambaŭ antaŭ ol ruli ion ajn. install agordas posedanton kaj reĝimon en unu paŝo.
sudo install -o root -g wheel -m 0755 /dev/null /etc/ppp/ip-up
sudo ls -l /etc/ppp/ip-up
Dosiero kreita per Finder aŭ grafika redaktilo ofte finiĝas posedata de via konto aŭ sen la plenum-bito, kaj tiam fiaskas same silente kiel la mankanta hoko. Metu ip-down apud ĝin nun. root kaj wheel en la posedanta kolumno plus rwxr-xr-x en la reĝima kolumno estas tio, kion vi volas.
Lasu launchd ekigi la skripton kiam tunelo aperas
Por klientoj, kiuj neniam tuŝas PPP, la ekigilo devas veni de aliloke, kaj la sistema agorda konservejo estas la honesta fonto: macOS reverkas ĝin ĉe ĉiu tunela transiro. launchd-tasko, kiu gvatas tiun dosierujon, estas vokata kiam tunelo aperas aŭ malaperas.
<?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>
Instalu ĝin kiel launch-daemon, ne kiel agenton por unuopaj uzantoj, ĉar ripari itineron apartenas al la maŝino. bootstrap anstataŭigas la pli malnovan formon load -w en aktualaj eldonoj. RunAtLoad igas la unuan plenumon observebla, kaj ThrottleInterval malhelpas, ke torento da Wi-Fi-aliĝaj ŝanĝoj lanĉu la skripton ree.
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
La kaptilo estas, ke la gvatata dosierujo ŝanĝiĝas ankaŭ pro eventoj tute ne rilataj al via VPN: Wi-Fi-aliĝo, DHCP-renovigo, enŝovita kablo. La gardanto sube transformas bruan ekigilon en uzeblan hokon, kaj log-linio klarigas itineron je stranga horo.
Posedado kovras la plist same kiel la skripton. Daemon, kiu plenumas dosieron en dosierujo, kiun via propra konto povas skribi, donas root al tiu konto.
Gardu la skripton por ke dua rulo ŝanĝu nenion
La skripto unue decidas, ĉu la tunelo ekzistas, kaj eliras silente kiam ĝi ne ekzistas. Ĉio poste devas esti sekura por ripeto, ĉar la ekigilo ekfunkcias multe pli ofte ol unu sola konekto. Solvu la interfacon ĉe rultempo anstataŭ malmole kodi indekson, kiu ŝanĝiĝas ĉe la sekva konekto.
#!/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 eliras kun ne-nula stato kiam la itinero jam ekzistas, do skripto, kiu traktas ĉiun ne-nulan staton kiel malsukceson, raportas rompitan hokon ĉiufoje, kiam ĝi faras la ĝustan aferon. La testo per netstat supre transformas tiun kazon en eksplicitan no-op.
La ĉeesto de la interfaco estas pli malforta pruvo ol ĝi aspektas, ĉar aliaj VPN-klientoj kaj kelkaj ujaj medioj ankaŭ kreas aparatojn utun. Demandu la servon mem per scutil --nc status "Office VPN" kaj postulu la konektitan staton antaŭ ol tuŝi itineradon. Konservu la respondon en log-linio, ĉar semajnon poste tiu rikordo estos la sola klarigo, kiun vi havos.
Revenigu la enirejon sen rompi DNS
Kiam la tunelo transprenas la defaŭltan itineron, ordinara retumirado eliras tra la oficejo kaj la loka interreta vojo ĉesas funkcii. Unue kaptu la itinerilon de la fizika interfaco, poste direktu la defaŭlton reen al ĝi. DHCP superas analizadon de tabelo, kiu jam enhavas la propran defaŭlton de la tunelo.
PHYS=en0
GW=$(ipconfig getoption "$PHYS" router)
[ -n "$GW" ] && sudo route -n change default "$GW"
Solviloj estas aparta tavolo kun aparta ilo, kaj ripari la itineron ne riparas ilin. Rigardu per scutil --dns, kio validas, poste ripari tion, kio produktas ĝin: la servo-ordo kaj la DNS-rikordoj sur la fizika servo. Malplenigi la kaŝmemoron diagnozas serĉon blokitan post reta ŝanĝo; ĝi ne estas io por plani.
Tunelo, kiu postvivas Wi-Fi-ŝanĝon dum DNS haltas, estas tria misfunkcio: sudo killall -HUP mDNSResponder igas la solvilon relegi sian agordon. Uzu ĝin unufoje, permane.
Pruvu, ke la tasko ekfunkcias memstare
Devigu unu rulon per kickstart -k antaŭ ol fidi la gvatan vojon, poste legu la eliran staton, kiun la tasko registris. Pura eliro pruvas, ke la skripto funkcias; ĝi ne pruvas, ke la ekigilo funkcias. Poste malkonektu kaj rekonektu kun la tasko ŝargita, kaj observu rulon, kiun vi ne petis.
sudo launchctl kickstart -k system/net.example.tunnel-watch
sudo launchctl print system/net.example.tunnel-watch | grep -E 'last exit code|state ='
Kontrolu scutil --nc status antaŭ kaj post ĉiu provo. Skripto, kiu ruliĝis dum la tunelo estis malaktiva, pruvas nenion pri la konekta vojo.
La malmuntbranĉo meritas la saman traktadon kiel la konektbranĉo: forigu la itineron permane, lasu la taskon ruliĝi, kaj konfirmu, ke ĝi revenas. Hoko, kiu aldonas itineron kaj neniam forigas ĝin, postlasas maŝinon, kiu kondutas malbone semajnon poste, sen io liganta la du eventojn. Kiam ambaŭ kondutoj teniĝas, sudo launchctl bootout system/net.example.tunnel-watch emeritigas la taskon pure. Gvata daemon lasita ŝargita estas la maniero, kiel unufoja riparo fariĝas neklarigita itinero monatojn poste.