Mac VPN bağlı ama ip-up hiç çalışmadı: bir launchd izlemesi kurun
Cisco IPSec ve IKEv2 tünelleri pppd’yi hiç başlatmaz, bu yüzden /etc/ppp/ip-up sessiz kalır. Yapılandırma dizinini izleyin ve betiğin tüneli kanıtlamasını sağlayın.
/etc/ppp/ip-up içine bir route komutu koyuyorsunuz, ofis tüneline yeniden bağlanıyorsunuz ve dosya hiç çalışmıyor. Betikte bir sorun yok: o bağlantı PPP’den hiç geçmiyor. Yerleşik Cisco IPSec ve IKEv2 istemcileri pppd hiç başlatmaz, bu yüzden hook dizini hiç okunmaz, oysa PPTP ve IPSec üzerinden L2TP hâlâ ondan geçer. Hangi durumda olduğunuzu belirleyin, sonra PPP olmayan durumu bir launchd izleme işinden tetikleyin.
Herhangi bir hook’u düzenlemeden önce arayüzü kontrol edin
İki komut hangi mekanizmanın çalışabileceğini belirler. Yapılandırılmış hizmetleri listeleyin, ardından tünel açıkken var olan arayüzleri listeleyin. Arayüz adı kanıttır; Sistem Ayarları’ndaki etiket değil.
scutil --nc list
ifconfig -l | tr ' ' '\n' | grep -E '^(utun|ppp)[0-9]+$'
ppp0 üreten hizmet PPP hook’larını çalıştırır ve dosyanızı yürütür. Cisco IPSec veya IKEv2 hizmeti bunun yerine bir utun aygıtı üretir, PPP katmanı olmayan bir tünel arayüzü, bu yüzden /etc/ppp içindeki hiçbir şey ona ulaşamaz. İki tür de göründüğünde hangi hizmete bağlandığınızı kontrol edin. İnsanlar istemci adını okuyup yanlış hook’ta bir öğleden sonra kaybeder.
PPP yolunda dosya root’a ait ve çalıştırılabilir olmalıdır, çünkü pppd herhangi bir şeyi çalıştırmadan önce ikisini de kontrol eder. install sahibi ve modu tek adımda ayarlar.
sudo install -o root -g wheel -m 0755 /dev/null /etc/ppp/ip-up
sudo ls -l /etc/ppp/ip-up
Finder veya grafik düzenleyici aracılığıyla oluşturulan bir dosya çoğu zaman hesabınıza ait olur ya da çalıştırma bitinden yoksundur ve sonra eksik hook kadar sessizce başarısız olur. Şimdi yanına ip-down koyun. Sahip sütununda root ve wheel, mod sütununda rwxr-xr-x istediğiniz şeydir.
Bir tünel göründüğünde launchd betiği tetiklesin
PPP’ye hiç dokunmayan istemciler için tetikleyici başka bir yerden gelmelidir ve sistem yapılandırma deposu dürüst kaynaktır: macOS onu her tünel geçişinde yeniden yazar. O dizini izleyen bir launchd işi, bir tünel göründüğünde veya kaybolduğunda çağrılır.
<?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>
Bunu kullanıcı başına ajan olarak değil, launch daemon olarak kurun, çünkü rota onarımı makineye aittir. bootstrap güncel sürümlerde eski load -w biçiminin yerini alır. RunAtLoad ilk çalıştırmayı gözlemlenebilir kılar ve ThrottleInterval bir Wi-Fi bağlantı değişikliği dalgasının betiği tekrar tekrar başlatmasını önler.
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
Tuzak şu ki izlenen dizin VPN’inizle ilgisi olmayan olaylarda da değişir: bir Wi-Fi bağlantısı, bir DHCP yenilemesi, takılan bir kablo. Aşağıdaki koruma gürültülü bir tetikleyiciyi kullanışlı bir hook’a dönüştürür ve bir günlük satırı garip bir saatteki rotayı açıklar.
Sahiplik betik kadar plist’i de kapsar. Kendi hesabınızın yazabildiği bir dizinde dosya yürüten bir daemon o hesaba root verir.
İkinci çalıştırma hiçbir şeyi değiştirmesin diye betiği koruyun
Betik önce tünelin var olup olmadığına karar verir ve yoksa sessizce çıkar. Sonrasındaki her şey tekrarlanabilir olmalıdır, çünkü tetikleyici tek bir bağlantıdan çok daha sık ateşlenir. Bir sonraki bağlantıda değişen bir indeksi sabit kodlamak yerine arayüzü çalışma zamanında çözün.
#!/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 rota zaten varsa sıfır olmayan durumla çıkar, bu yüzden her sıfır olmayan durumu başarısızlık sayan bir betik doğru olanı yaptığı her seferinde bozuk hook bildirir. Yukarıdaki netstat testi bu durumu açık bir no-op’a çevirir.
Arayüzün varlığı göründüğünden daha zayıf bir kanıttır, çünkü diğer VPN istemcileri ve bazı konteyner ortamları da utun aygıtları oluşturur. Hizmetin kendisine scutil --nc status "Office VPN" ile sorun ve yönlendirmeye dokunmadan önce bağlı durumu şart koşun. Yanıtı bir günlük satırında tutun, çünkü bir hafta sonra o kayıt elinizdeki tek açıklama olacak.
DNS’i bozmadan ağ geçidini geri getirin
Tünel varsayılan rotayı devraldığında sıradan gezinme ofisten çıkar ve yerel internet yolu çalışmayı durdurur. Önce fiziksel arayüzün yönlendiricisini yakalayın, sonra varsayılanı tekrar ona yönlendirin. DHCP, tünelin kendi varsayılanını zaten içeren bir tabloyu ayrıştırmaktan iyidir.
PHYS=en0
GW=$(ipconfig getoption "$PHYS" router)
[ -n "$GW" ] && sudo route -n change default "$GW"
Çözümleyiciler ayrı bir araçla ayrı bir katmandır ve rotayı onarmak onları onarmaz. scutil --dns ile neyin yürürlükte olduğuna bakın, sonra onu üreten şeyi düzeltin: hizmet sırası ve fiziksel hizmetteki DNS girdileri. Önbelleği boşaltmak, ağ değişiminden sonra takılan bir aramayı teşhis eder; planlanacak bir şey değildir.
Wi-Fi değişimini atlatıp DNS’in takıldığı bir tünel üçüncü arızadır: sudo killall -HUP mDNSResponder çözümleyicinin yapılandırmasını yeniden okumasını sağlar. Bunu bir kez, elle kullanın.
İşin kendi kendine tetiklendiğini kanıtlayın
İzleme yoluna güvenmeden önce kickstart -k ile bir çalıştırmayı zorlayın, sonra işin kaydettiği çıkış durumunu okuyun. Temiz bir çıkış betiğin çalıştığını kanıtlar; tetikleyicinin çalıştığını kanıtlamaz. Ardından iş yüklüyken bağlantıyı kesip yeniden bağlanın ve istemediğiniz bir çalıştırmayı gözleyin.
sudo launchctl kickstart -k system/net.example.tunnel-watch
sudo launchctl print system/net.example.tunnel-watch | grep -E 'last exit code|state ='
Her denemeden önce ve sonra scutil --nc status kontrol edin. Tünel kapalıyken çalışan bir betik bağlantı yolu hakkında hiçbir şey kanıtlamaz.
Sökme dalı bağlanma dalıyla aynı muameleyi hak eder: rotayı elle kaldırın, işin çalışmasına izin verin ve geri geldiğini doğrulayın. Bir rota ekleyip onu hiç kaldırmayan bir hook, bir hafta sonra kötü davranan bir makine bırakır ve iki olayı hiçbir şey birbirine bağlamaz. İki davranış da tutunca sudo launchctl bootout system/net.example.tunnel-watch işi temiz biçimde emekliye ayırır. Yüklü bırakılan bir izleme daemonu, tek seferlik bir onarımın aylar sonra açıklanamayan bir rotaya dönüşme yoludur.