Nakakonekta ang VPN sa Mac pero hindi kailanman umandar ang ip-up: magpatakbo ng launchd watch
Hindi kailanman sinisimulan ng mga tunnel na Cisco IPSec at IKEv2 ang pppd, kaya nananatiling tahimik ang /etc/ppp/ip-up. Bantayan ang direktoryo ng configuration at hayaang patunayan ng script ang tunnel.
Naglalagay ka ng utos na route sa /etc/ppp/ip-up, muling ikinokonekta ang tunnel ng opisina, at hindi kailanman tumatakbo ang file. Walang mali sa script: ang koneksiyong iyon ay hindi dumadaan sa PPP. Ang mga built-in na kliyente ng Cisco IPSec at IKEv2 ay hindi kailanman nagsisimula ng pppd, kaya hindi kailanman binabasa ang direktoryo ng hook, samantalang ang PPTP at L2TP sa ibabaw ng IPSec ay dumadaan pa rin dito. Alamin kung aling kaso ang sa iyo, pagkatapos ay i-trigger ang hindi-PPP na kaso mula sa isang trabahong launchd watch.
Suriin ang interface bago mo i-edit ang anumang hook
Dalawang utos ang nagpapasya kung aling mekanismo ang maaaring gumana. Ilista ang mga naka-configure na serbisyo, pagkatapos ay ilista ang mga interface na umiiral habang nakaupo ang tunnel. Ang pangalan ng interface ang ebidensiya; ang label sa System Settings ay hindi.
scutil --nc list
ifconfig -l | tr ' ' '\n' | grep -E '^(utun|ppp)[0-9]+$'
Ang serbisyong gumagawa ng ppp0 ay nagpapatakbo ng mga PPP hook at isasagawa ang iyong file. Ang serbisyong Cisco IPSec o IKEv2 ay gumagawa sa halip ng device na utun, isang interface ng tunnel na walang PPP layer, kaya wala sa loob ng /etc/ppp ang makakaabot dito. Kapag lumitaw ang dalawang uri, suriin kung aling serbisyo ang kinonektahan mo. Nasasayang ng mga tao ang isang hapon sa maling hook dahil binabasa nila ang pangalan ng kliyente.
Sa landas ng PPP ang file ay dapat pag-aari ng root at maipapatupad, dahil sinusuri ng pppd ang dalawa bago magpatakbo ng anuman. Itinatakda ng install ang may-ari at mode sa isang hakbang.
sudo install -o root -g wheel -m 0755 /dev/null /etc/ppp/ip-up
sudo ls -l /etc/ppp/ip-up
Ang file na ginawa sa pamamagitan ng Finder o isang graphical na editor ay madalas na nagiging pag-aari ng iyong account, o walang bit ng pagpapatupad, at pagkatapos ay nabibigo nang kasingtahimik ng nawawalang hook. Ilagay ang ip-down sa tabi nito ngayon. Ang root at wheel sa hanay ng may-ari at ang rwxr-xr-x sa hanay ng mode ang gusto mo.
Hayaang mag-trigger ang launchd ng script kapag lumitaw ang tunnel
Para sa mga kliyenteng hindi kailanman humahawak ng PPP, ang trigger ay dapat magmula sa ibang lugar, at ang imbakan ng configuration ng system ang tapat na pinagmulan: muling isinusulat ito ng macOS sa bawat paglipat ng tunnel. Ang trabahong launchd na nagbabantay sa direktoryong iyon ay tinatawag kapag lumitaw o naglaho ang tunnel.
<?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>
I-install ito bilang launch daemon, hindi bilang ahente ng bawat user, dahil sa makina nakasalalay ang pagkukumpuni ng ruta. Pinapalitan ng bootstrap ang mas lumang anyo ng load -w sa kasalukuyang mga release. Ginagawang napapansin ng RunAtLoad ang unang pagpapatupad, at pinipigilan ng ThrottleInterval ang sunod-sunod na pagbabago ng koneksiyon sa Wi-Fi na paulit-ulit na maglunsad ng script.
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
Ang bitag ay nagbabago ang binabantayang direktoryo para sa mga pangyayaring walang kaugnayan sa iyong VPN: pagkonekta sa Wi-Fi, pag-renew ng DHCP, pagsaksak ng kable. Ang bantay sa ibaba ay ginagawang kapaki-pakinabang na hook ang maingay na trigger, at may linyang log na nagpapaliwanag ng rutang lumitaw sa kakaibang oras.
Saklaw ng pagmamay-ari ang plist pati na ang script. Ang daemon na nagpapatupad ng file sa direktoryong kayang sulatan ng sarili mong account ay nagbibigay ng root sa account na iyon.
Protektahan ang script para walang mabago sa ikalawang pagtakbo
Unang nagpapasya ang script kung umiiral ang tunnel, at tahimik na lumalabas kapag wala. Lahat ng sumunod ay dapat ligtas na ulitin, dahil mas madalas mag-trigger kaysa sa isang koneksiyon. Lutasin ang interface habang tumatakbo sa halip na i-hardcode ang index na magbabago sa susunod na koneksiyon.
#!/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"
Lumabas ang route add na may di-sero na estado kapag umiiral na ang ruta, kaya ang script na itinuturing na kabiguan ang bawat di-sero na estado ay nag-uulat ng sirang hook tuwing ginagawa ang tama. Ang pagsubok na may netstat sa itaas ay ginagawang tahasang no-op ang kasong iyon.
Ang pagkakaroon ng interface ay mas mahinang ebidensiya kaysa sa itsura nito, dahil gumagawa rin ng mga device na utun ang ibang kliyente ng VPN at ilang environment ng container. Tanungin ang serbisyo mismo gamit ang scutil --nc status "Office VPN" at hilingin ang konektadong estado bago hawakan ang routing. Itago ang sagot sa isang linya ng log, dahil makalipas ang isang linggo ang rekord na iyon ang tanging paliwanag na mayroon ka.
Ibalik ang gateway nang hindi sinisira ang DNS
Kapag kinuha ng tunnel ang default na ruta, lumalabas ang ordinaryong pag-browse sa opisina at humihinto ang lokal na landas sa internet. Kunin muna ang router ng pisikal na interface, pagkatapos ay itutok ang default pabalik dito. Nalalamangan ng DHCP ang pag-parse ng talahanayan na mayroon nang sariling default ng tunnel.
PHYS=en0
GW=$(ipconfig getoption "$PHYS" router)
[ -n "$GW" ] && sudo route -n change default "$GW"
Ang mga resolver ay hiwalay na layer na may hiwalay na kasangkapan, at hindi sila inaayos ng pagkumpuni ng ruta. Tingnan gamit ang scutil --dns kung ano ang may bisa, pagkatapos ay ayusin ang gumagawa nito: ang pagkakasunod-sunod ng serbisyo at ang mga entry ng DNS sa pisikal na serbisyo. Ang paglilinis ng cache ay nag-diagnose ng paghahanap na natigil pagkatapos ng paglipat ng network; hindi ito bagay na iskedyul.
Ang tunnel na nakaligtas sa pagbabago ng Wi-Fi habang natigil ang DNS ay ikatlong sira: pinipilit ng sudo killall -HUP mDNSResponder ang resolver na muling basahin ang configuration nito. Gamitin ito isang beses, sa kamay.
Patunayan na kusang nag-trigger ang trabaho
Pilitin ang isang pagtakbo gamit ang kickstart -k bago ka magtiwala sa landas ng pagbabantay, pagkatapos ay basahin ang exit status na naitala ng trabaho. Ang malinis na paglabas ay nagpapatunay na gumagana ang script; hindi nito pinapatunayan na gumagana ang trigger. Pagkatapos ay idiskonekta at ikonekta muli habang nakakarga ang trabaho, at bantayan ang pagtakbong hindi mo hiniling.
sudo launchctl kickstart -k system/net.example.tunnel-watch
sudo launchctl print system/net.example.tunnel-watch | grep -E 'last exit code|state ='
Suriin ang scutil --nc status bago at pagkatapos ng bawat pagtatangka. Ang script na tumakbo habang nakababa ang tunnel ay walang pinapatunayan tungkol sa landas ng koneksiyon.
Ang sanga ng pagtatanggal ay karapat-dapat sa parehong pagtrato ng sanga ng pagkonekta: alisin ang ruta sa kamay, hayaang tumakbo ang trabaho, at tiyakin na bumabalik ito. Ang hook na nagdaragdag ng ruta at hindi kailanman nag-aalis nito ay nag-iiwan ng makina na mali ang kilos makalipas ang isang linggo, na walang nag-uugnay sa dalawang pangyayari. Kapag nanatili ang dalawang pag-uugali, maayos na itinitigil ng sudo launchctl bootout system/net.example.tunnel-watch ang trabaho. Ang daemon ng pagbabantay na iniwang nakakarga ang paraan para maging hindi maipaliwanag na ruta ang isang besesang pagkukumpuni pagkaraan ng mga buwan.