तपाईं /etc/ppp/ip-up मा route आदेश राख्नुहुन्छ, कार्यालयको सुरुङ फेरि जोड्नुहुन्छ, र फाइल कहिल्यै चल्दैन। स्क्रिप्टमा केही गल्ती छैन: त्यो जडान PPP बाटै जाँदैन। अन्तर्निहित Cisco IPSec र IKEv2 क्लाइन्टहरू कहिल्यै pppd सुरु गर्दैनन्, त्यसैले हुक डाइरेक्टरी कहिल्यै पढिँदैन, जबकि PPTP र IPSec माथिको L2TP अझै त्यसबाट जान्छन्। तपाईंको कुन अवस्था हो पहिचान गर्नुहोस्, त्यसपछि गैर-PPP अवस्था launchd निगरानी कामबाट सुरु गर्नुहोस्।

कुनै पनि हुक सम्पादन गर्नुअघि इन्टरफेस जाँच्नुहोस्

दुई आदेशले कुन विधि काम गर्न सक्छ भन्ने तय गर्छन्। कन्फिगर गरिएका सेवाहरू सूचीबद्ध गर्नुहोस्, त्यसपछि सुरुङ चालु हुँदा रहेका इन्टरफेसहरू सूचीबद्ध गर्नुहोस्। इन्टरफेसको नाम नै प्रमाण हो; System Settings को लेबल होइन।

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 ले कामलाई सफासँग अवकाश दिन्छ। लोड गरिएको छोडिएको निगरानी डेमन नै एक-पटकको मर्मत महिनौंपछि अस्पष्ट मार्ग बन्ने बाटो हो।

सम्बन्धित लेखहरू