Mac-ի VPN-ը միացած է, բայց ip-up-ը երբեք չի աշխատել. գործարկեք launchd հսկիչ
Cisco IPSec և IKEv2 թունելները երբեք չեն գործարկում pppd-ն, ուստի /etc/ppp/ip-up-ը լուռ է մնում։ Հսկեք կարգավորման պանակը և թույլ տվեք սկրիպտին ապացուցել թունելը։
Դուք 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-ը մաքուր կերպով թոշակի է ուղարկում աշխատանքը։ Բեռնված թողնված հսկիչ դեմոնն այն ճանապարհն է, որով մեկանգամյա վերանորոգումը ամիսներ անց դառնում է չբացատրված ուղի։