route ბრძანებას დებთ /etc/ppp/ip-up-ში, ხელახლა აკავშირებთ ოფისის გვირაბს და ფაილი არასდროს სრულდება. სკრიპტში ბრალი არ არის: ეს კავშირი საერთოდ არ გადის PPP-ზე. ჩაშენებული Cisco IPSec და IKEv2 კლიენტები არასდროს უშვებენ pppd-ს, ამიტომ hook-ების საქაღალდე არასდროს იკითხება, მაშინ როცა PPTP და IPSec-ზე მდებარე L2TP კვლავ გადიან მასში. დაადგინეთ რომელი შემთხვევაა თქვენი, შემდეგ არა-PPP შემთხვევა გაუშვით launchd მეთვალყურე დავალებიდან.

შეამოწმეთ ინტერფეისი, სანამ რომელიმე hook-ს დაარედაქტირებთ

ორი ბრძანება წყვეტს, რომელი მექანიზმი შეიძლება მუშაობდეს. ჩამოთვალეთ კონფიგურირებული სერვისები, შემდეგ ჩამოთვალეთ ინტერფეისები, რომლებიც არსებობს გვირაბის ჩართული ყოფნისას. ინტერფეისის სახელია მტკიცებულება; System Settings-ის წარწერა არა.

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

სერვისი, რომელიც ქმნის ppp0-ს, უშვებს PPP hook-ებს და შეასრულებს თქვენს ფაილს. Cisco IPSec ან IKEv2 სერვისი სამაგიეროდ ქმნის utun მოწყობილობას, გვირაბის ინტერფეისს PPP ფენის გარეშე, ამიტომ /etc/ppp-ის შიგნით ვერაფერი ვერ მიაღწევს მას. როცა ორივე სახე ჩნდება, შეამოწმეთ რომელ სერვისს დაუკავშირდით. ადამიანები ნახევარ დღეს კარგავენ არასწორ hook-ზე კლიენტის სახელის წაკითხვით.

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-ით ან გრაფიკული რედაქტორით შექმნილი ფაილი ხშირად თქვენი ანგარიშის საკუთრებაში რჩება ან შესრულების ბიტის გარეშე, და შემდეგ ისევე ჩუმად ვარდება, როგორც დაკარგული hook. ახლავე დადეთ 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-ის განახლება, კაბელის ჩართვა. ქვემოთ მოცემული მცველი ხმაურიან ტრიგერს გამოსადეგ hook-ად აქცევს, და ჟურნალის ერთი სტრიქონი უცნაურ საათზე გაჩენილ მარშრუტს ხსნის.

საკუთრება მოიცავს 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 არანულოვანი სტატუსით გადის, როცა მარშრუტი უკვე არსებობს, ამიტომ სკრიპტი, რომელიც ყველა არანულოვან სტატუსს წარუმატებლობად თვლის, ყოველ ჯერზე, როცა სწორს აკეთებს, გატეხილ hook-ზე იუწყება. ზემოთ მოცემული 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 ყოველ ცდამდე და მის შემდეგ. სკრიპტი, რომელიც გაშუქდა გვირაბის გამორთულ ყოფნისას, კავშირის გზაზე არაფერს ამტკიცებს.

დაშლის შტო იმავე მოპყრობის ღირსია, რაც კავშირის შტო: ხელით მოხსენით მარშრუტი, მიეცით დავალებას გაშვების საშუალება და დაადასტურეთ, რომ ბრუნდება. hook, რომელიც მარშრუტს ამატებს და არასდროს შლის, ტოვებს მანქანას, რომელიც ერთი კვირის შემდეგ ცუდად იქცევა, და ვერაფერი აკავშირებს ორ მოვლენას. როცა ორივე ქცევა ძლებს, sudo launchctl bootout system/net.example.tunnel-watch სუფთად გააპენსიორებს დავალებას. ჩატვირთული დატოვებული მეთვალყურე დემონი ის გზაა, რომლითაც ერთჯერადი შეკეთება თვეების შემდეგ აუხსნელ მარშრუტად იქცევა.

დაკავშირებული სტატიები