Вы кладзяце каманду route у /etc/ppp/ip-up, перападключаеце офісны тунэль, а файл ніколі не выконваецца. Са скрыптам усё ў парадку: гэтае злучэнне зусім не ідзе праз PPP. Убудаваныя кліенты Cisco IPSec і IKEv2 ніколі не запускаюць pppd, таму каталог хукаў не чытаецца, хоць PPTP і L2TP праз IPSec па-ранейшаму ідуць праз яго. Вызначце, які выпадак у вас, і затым запусціце не-PPP выпадак з задання назірання launchd.

Праверце інтэрфейс, перш чым змяняць любы хук

Дзве каманды вырашаюць, які механізм можа працаваць. Пералічыце наладжаныя службы, затым пералічыце інтэрфейсы, якія існуюць, пакуль тунэль уключаны. Імя інтэрфейса — гэта доказ; надпіс у Сістэмных наладах — не.

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

Служба, якая стварае ppp0, выконвае хукі PPP і запусціць ваш файл. Служба Cisco IPSec або IKEv2 стварае замест гэтага прыладу utun, тунельны інтэрфейс без узроўню PPP, таму нішто ўнутры /etc/ppp не можа да яго дабрацца. Калі з’яўляюцца абодва віды, праверце, да якой службы вы падключыліся. Людзі марнуюць палову дня на няправільным хуку, чытаючы імя кліента.

На шляху PPP файл павінен належаць root і быць выканальным, бо pppd правярае абодва пункты перад запускам чаго-небудзь. install задае ўладальніка і рэжым за адзін крок.

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

Файл, створаны праз Finder або графічны рэдактар, часта належыць вашаму ўліковаму запісу або не мае біта выканання, і тады ён падае так жа ціха, як і адсутны хук. Пакладзіце ip-down побач з ім зараз. root і wheel у слупку ўладальніка плюс rwxr-xr-x у слупку рэжыму — гэта тое, што вам трэба.

Дазвольце launchd запусціць скрыпт, калі з’яўляецца тунэль

Для кліентаў, якія ніколі не закранаюць PPP, трыгер павінен прыходзіць з іншага месца, і сховішча сістэмнай канфігурацыі — гэта сумленная крыніца: macOS перазапісвае яго пры кожным пераходзе тунэля. Заданне launchd, якое назірае за гэтым каталогам, выклікаецца, калі тунэль з’яўляецца або знікае.

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

Усталюйце яго як launch daemon, а не як агент для асобнага карыстальніка, бо рамонт маршрутаў належыць машыне. bootstrap замяняе старую форму load -w у бягучых выпусках. RunAtLoad робіць першае выкананне назіральным, а ThrottleInterval не дае шквалу змен падключэння Wi-Fi запусціць скрыпт паўторна.

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

Пастка ў тым, што каталог, за якім назіраюць, змяняецца і для падзей, якія не маюць дачынення да вашага VPN: падключэнне Wi-Fi, абнаўленне DHCP, устаўлены кабель. Вартаўнік ніжэй ператварае шумны трыгер у прыдатны хук, а радок журнала тлумачыць маршрут, які з’явіўся ў незвычайную гадзіну.

Уласнасць ахоплівае plist гэтак жа, як і скрыпт. Дэман, які выконвае файл у каталогу, куды можа пісаць ваш уласны ўліковы запіс, аддае гэтаму запісу root.

Абараніце скрыпт, каб другі запуск нічога не змяніў

Скрыпт спачатку вырашае, ці існуе тунэль, і ціха выходзіць, калі не. Усё пасля гэтага павінна быць бяспечным для паўтору, бо трыгер спрацоўвае нашмат часцей за адно злучэнне. Вызначайце інтэрфейс падчас выканання, а не жорстка кадуйце індэкс, які змяняецца пры наступным падключэнні.

#!/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 выходзіць з ненулявым статусам, калі маршрут ужо ёсць, таму скрыпт, які лічыць кожны ненулявы статус памылкай, кожны раз паведамляе пра зламаны хук, калі робіць правільна. Тэст netstat вышэй ператварае гэты выпадак у яўную no-op.

Наяўнасць інтэрфейса — слабэйшы доказ, чым здаецца, бо іншыя кліенты VPN і некаторыя асяроддзі кантэйнераў таксама ствараюць прылады utun. Спытайце саму службу праз scutil --nc status "Office VPN" і патрабуйце злучанага стану, перш чым кранаць маршрутызацыю. Трымайце адказ у радку журнала, бо праз тыдзень гэты запіс будзе вашым адзіным тлумачэннем.

Вярніце шлюз, не зламаўшы DNS

Калі тунэль забірае маршрут па змаўчанні, звычайны прагляд выходзіць праз офіс, і лакальны шлях у інтэрнэт перастае працаваць. Спачатку захапіце маршрутызатар фізічнага інтэрфейса, затым накіруйце маршрут па змаўчанні назад на яго. DHCP лепш за разбор табліцы, якая ўжо змяшчае ўласны прадвызначаны маршрут тунэля.

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

Рэзальверы — асобны ўзровень з асобным інструментам, і рамонт маршруту іх не рамантуе. Паглядзіце, што дзейнічае, праз scutil --dns, затым выпраўце тое, што гэта стварае: парадак службаў і запісы DNS на фізічнай службе. Ачыстка кэша дыягнастуе запыт, які завіс пасля пераключэння сеткі; гэта не тое, што варта планаваць.

Тунэль, які перажывае змену Wi-Fi, пакуль DNS стаіць, — гэта трэцяя памылка: sudo killall -HUP mDNSResponder прымушае рэзальвер перачытаць сваю канфігурацыю. Скарыстайцеся ім адзін раз, уручную.

Дакажыце, што заданне запускаецца само

Прымусьце адзін запуск праз kickstart -k, перш чым давяраць шляху назірання, затым прачытайце статус выхаду, які запісала заданне. Чысты выхад даказвае, што скрыпт працуе; ён не даказвае, што працуе трыгер. Затым адключыцеся і падключыцеся зноў з загружаным заданнем і чакайце запуску, якога вы не прасілі.

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

Правярайце scutil --nc status да і пасля кожнай спробы. Скрыпт, які працаваў, пакуль тунэль быў выключаны, нічога не даказвае пра шлях падключэння.

Галіна дэмантажу заслугоўвае такой жа ўвагі, як галіна падключэння: выдаліце маршрут уручную, дайце заданню працаваць і пацвердзіце, што ён вяртаецца. Хук, які дадае маршрут і ніколі яго не выдаляе, пакідае машыну, якая праз тыдзень паводзіць сябе няправільна, і нішто не звязвае дзве падзеі. Калі абодва паводзіны трымаюцца, sudo launchctl bootout system/net.example.tunnel-watch чыста згортвае заданне. Пакінуты загружаным дэман назірання — гэта шлях, якім аднаразовы рамонт праз месяцы становіцца невытлумачальным маршрутам.

Падобныя артыкулы