Sandbox'lı bir Mac uygulamasında etkin VPN'i algılamak
Bu soru için genel bir API yok ve arayüz adı numarası yalnızca bir buluşsal yöntem. Uygulamanızın gerçekte neye dayanması gerektiğine karar vermek için altı kontrol.
Tünel açıkken farklı davranan bir ekrana ihtiyacınız var ve bunu size söyleyen bir çağrı yok. Yayınlama kısıtı budur: macOS'ta hiçbir genel çerçeve rastgele bir VPN'in bağlı olup olmadığını bildirmez, iOS'ta ise durum yapılandırmayı kuran uygulamaya aittir. Aşağıdaki kontroller bu sınırdan yayınlayabileceğiniz bir şeye uzanır ve herhangi biri aramayı erken bitirebilir.
Kontrol 1: soruya hiç cevap verilebilir mi?
Sandbox, soruyu herhangi bir API'den önce çözer. Üçüncü taraf bir süreç başka bir satıcının uzantısını listeleyemez ve o uzantının yapılandırmasını da okuyamaz, dolayısıyla sorulacak desteklenen bir nesne yoktur.
Her atlatma aynı duvara çarpar. Arayüz listeleri, scutil --nc list ve doğrudan sistem yapılandırması okumaları ya sandbox'ın sakladığı yetkileri gerektirir ya da Apple'ın hiç vaat etmediği davranışlara bağlıdır. Plan bunlardan birine ihtiyaç duyuyorsa sorun plandır. Belgelenmemiş bir ayrıntıya dayanan özellik, teslim tarihi olan bir destek talebidir.
Kontrol 2: uygulamanız tüneli kendisi mi yönetiyor?
Öyleyse kendi yapılandırmanız için desteklenen bir cevabınız var. Tercihleri yükleyin, hatayı işleyin, sonra durumu okuyun ve anket yapmak yerine değişikliklere abone olun:
vpnManager.loadFromPreferences { error in
// handle a load failure before reading status
}
NotificationCenter.default.addObserver(
forName: .NEVPNStatusDidChange,
object: nil,
queue: nil
) { note in
let status = (note.object as? NEVPNConnection)?.status
}Bunun ne döndürdüğü konusunda kesin olun: kurduğunuz tünelin durumu. Farklı bir istemci çalıştıran kullanıcı bağlantısız görünecek ve bu kodunuzdaki bir hata değil. Cevabın üzerine inşa etmeden önce özelliğinizin gerçekte bu iki sorudan hangisini sorduğuna karar verin.
Kontrol 3: bir buluşsal yöntem size gerçekte ne söyler?
Yaygın olarak kopyalanan yaklaşım, sistem proxy sözlüğünden kapsamlı girdilerini ister ve anahtarları okur, ki bunlar tesadüfen arayüz adlarıdır:
let settings = CFNetworkCopySystemProxySettings()?.takeRetainedValue() as NSDictionary?
let scoped = settings?["__SCOPED__"] as? [String: Any]
let names = scoped?.keys ?? []Anahtar tap, tun, ppp, ipsec veya utun ile başlıyorsa, tünel kapsamlı bir arayüzün var olduğunu ima eder. Tam adı eşleştirmek anında başarısız olur, çünkü iOS 12 utun1 ve utun2 ile geldi ve bazı profiller ipsec4, ppp0 veya utun0 olarak görünür. Bunun yerine önekleri karşılaştırın.
Yine de bir ad hiçbir sahibi tanımlamaz. Sistem özellikleri ve diğer satıcıların uzantıları da utun arayüzleri oluşturur ve biri trafiğinizin hiçbirini taşımadan var olabilir. Bunu çevrede tünel biçimli bir şey olduğuna dair bir ipucu olarak okuyun, daha fazlası değil. Buradaki yanlış pozitif, yalnızca bir özelliği kapılıyorsanız ucuz, oturum açma ekranını kapılıyorsanız pahalıdır.
Kontrol 4: bunun yerine hedefi test edebilir misiniz?
Uygulamanın yalnızca dahili bir hizmete ulaşılıp ulaşılamadığını bilmesi gerekiyorsa o hizmeti test edin. Zaman aşımı olan kısa bir sonda, özelliğin gerçekte bağlı olduğu soruyu yanıtlar ve kullanıcı istemci değiştirdiğinde veya tünel şekil değiştirdiğinde çalışmaya devam eder.
Erişilebilirlik, yolunuz hakkında bir gözlemdir. Arayüz adı, yolunuza komşu bir şey hakkında bir çıkarımdır, bu yüzden buluşsal yöntem hata raporlarında tartışma üretirken sonda kanıt üretir. Kullanıcı VPN'in açık olduğunda ısrar ederken sonda başarısız olursa, artık hata ayıklamak için somut bir yolunuz var: ad çözümleme, rota veya hizmet izni.
Kontrol 5: platform ihtiyacınız olanı zorlayabilir mi?
Gereksinim, tünelden hiçbir şeyin kaçmaması garantisiyse, profilin yeri orasıdır, dedektör değil. includeAllNetworks ayarını iOS 14 veya daha yenisinde tam tünel yapılandırmasında açmak, uygulamanızdan bunu çıkarmasını istemek yerine platform davranışını değiştirir. Bayrak NEVPNProtocol başvurusunda belgelenmiştir.
Bu farklı türde bir cevaptır: gözlem yerine zorlama. Ayrıca yalnızca kontrol ettiğiniz profiller için geçerlidir, bu yüzden başkasının tünelini izleyen bir tüketici uygulamasına yardımcı olmaz.
Kontrol 6: başarısızlığı güvenli ve gözlemlenebilir yapın
Yalnızca tünele ihtiyaç duyan yeteneği kapatın ve uygulamanın geri kalanını kullanılabilir bırakın. Emin olmadığında tüm arayüzü gizleyen bir dedektör, tüneli hiç öngörmediğiniz bir ad kullanan herkes için kesinti üretir. Bunun yerine muhafazakâr davranışa dönün: yerel özellikler çalışmaya devam eder ve yalnızca tünele gerçekten ihtiyaç duyan uzak çağrı devre dışı bırakılır. Bu seçim bir ürün kararıdır ve buluşsal yöntemin yanına yazılmayı hak eder.
Gözlemlediklerinizi kaydedin: arayüz adları, platform sürümü ve bir sondanın sonucu. Bu, sonraki raporu tartışmadan kontrole dönüştürür. Ardından desteklenen bir bildiriminiz varsa onu tercih edin, çünkü yönetilen bir yapılandırma niyeti açıkça taşıyabilir ve adları denetleme nedeninin çoğunu ortadan kaldırabilir.
Kontroller 1 ile 5 sizi desteklenen bir cevaptan yoksun bıraktıysa sondanızı yayınlayın ve sonucu dürüstçe etiketleyin. Belgelenmiş en iyi çaba sinyali, bir sonraki sürümde bozulan özel bir API'den daha iyi bir ürün kararıdır.