Rilevado de aktiva VPN ene de sandboxa Mac-a aplikaĵo
Ne ekzistas publika API por ĉi tiu demando, kaj la artifiko de la interfaca nomo estas nur heŭristiko. Ses kontroloj por decidi, de kio via aplikaĵo vere dependu.
Vi bezonas unu ekranon konduti alie kiam la tunelo estas aktiva, kaj ne ekzistas voko kiu diras al vi tion. Tio estas la limigo de liverado: en macOS neniu publika kadro raportas ĉu arbitra VPN estas konektita, kaj en iOS la stato apartenas al la aplikaĵo kiu instalis la agordon. La subaj kontroloj iras de tiu limo al io, kion vi povas liveri, kaj ĉiu el ili povas fini la serĉadon frue.
Kontrolo 1: ĉu la demando entute respondeblas?
Sandboxado solvas la demandon antaŭ ol iu ajn API faras tion. Tria partio ne povas listigi la etendaĵon de alia vendisto, kaj ĝi ankaŭ ne povas legi la agordon de tiu etendaĵo, do ne ekzistas subtenata objekto por demandi.
Ĉiu ĉirkaŭvojo trafas la saman muron. Interfacaj listoj, scutil --nc list kaj rektaj legadoj de sistema agordo aŭ postulas rajtigojn, kiujn la sandboxo retenas, aŭ dependas de konduto, kiun Apple neniam promesis. Se la plano bezonas unu el tiuj, la plano estas la problemo. Funkcio konstruita sur nedokumentita detalo estas subtena bileto kun livera dato.
Kontrolo 2: ĉu via aplikaĵo mem administras la tunelon?
Se jes, vi havas subtenatan respondon por via propra agordo. Ŝargu la preferojn, traktu la eraron, poste legu la staton kaj abonu al ŝanĝoj anstataŭ enketi:
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
}Estu preciza pri tio, kion ĉi tio redonas: la stato de la tunelo, kiun vi instalis. Uzanto, kiu uzas alian klienton, aperos kiel malkonektita, kaj tio ne estas cimo en via kodo. Decidu, kiun el tiuj du demandoj via funkcio vere starigas, antaŭ ol vi konstruos sur la respondo.
Kontrolo 3: kion heŭristiko vere dirus al vi?
La vaste kopiita aliro demandas al la sistema prokura vortaro pri ĝiaj ampleksaj enskriboj kaj legas la ŝlosilojn, kiuj hazarde estas interfacaj nomoj:
let settings = CFNetworkCopySystemProxySettings()?.takeRetainedValue() as NSDictionary?
let scoped = settings?["__SCOPED__"] as? [String: Any]
let names = scoped?.keys ?? []Ŝlosilo komenciĝanta per tap, tun, ppp, ipsec aŭ utun implicas, ke ĉeestas tunel-ampleksa interfaco. Kongruigi la tutan nomon malsukcesas tuj, ĉar iOS 12 liveris utun1 kaj utun2, kaj iuj profiloj aperas kiel ipsec4, ppp0 aŭ utun0. Komparu prefiksojn anstataŭe.
Tamen, nomo ne identigas posedanton. Sistemaj funkcioj kaj etendaĵoj de aliaj vendistoj ankaŭ kreas utun-interfacojn, kaj unu povas ekzisti dum ĝi portas neniom da via trafiko. Legu ĝin kiel signalon, ke io tunelforma estas proksime, nenion pli fortan. Falsa pozitivo ĉi tie estas malmultekosta se vi baras nur unu funkcion, kaj multekosta se vi baras la ensalutan ekranon.
Kontrolo 4: ĉu vi povas anstataŭe testi la celon?
Se la aplikaĵo nur bezonas scii, ĉu interna servo estas atingebla, testu tiun servon. Mallonga provo kun tempolimo respondas la demandon, de kiu la funkcio vere dependas, kaj ĝi daŭre funkcias kiam la uzanto ŝanĝas klienton aŭ la tunelo ŝanĝas formon.
Atingebleco estas observo pri via vojo. Interfaca nomo estas konkludo pri io apuda al via vojo, kaj tial la heŭristiko produktas disputojn en cimraportoj dum la provo produktas pruvojn. Se la provo malsukcesas dum la uzanto insistas, ke la VPN estas ŝaltita, vi nun havas konkretan vojon por sencimigi: nomrezolucio, itinero aŭ serva permeso.
Kontrolo 5: ĉu la platformo povas devigi tion, kion vi bezonas?
Kiam la postulo estas garantio, ke nenio eskapas el la tunelo, la profilo estas ĝia loko, ne la detektilo. Ŝalti includeAllNetworks en plentunela agordo en iOS 14 aŭ pli nova ŝanĝas la konduton de la platformo anstataŭ peti vian aplikaĵon dedukti ĝin. La flago estas dokumentita en la referenco NEVPNProtocol.
Tio estas alia speco de respondo: devigo anstataŭ observado. Ĝi ankaŭ validas nur por profiloj, kiujn vi kontrolas, do ĝi ne helpas konsuman aplikaĵon, kiu observas la tunelon de iu alia.
Kontrolo 6: faru la malsukceson sekura kaj observebla
Malŝaltu nur la kapablon, kiu bezonas la tunelon, kaj lasu la reston de la aplikaĵo uzebla. Detektilo, kiu kaŝas la tutan interfacon kiam ajn ĝi ne certas, fabrikas interrompon por ĉiu, kies tunelo uzas nomon, kiun vi neniam antaŭvidis. Revenu anstataŭe al la konservativa konduto: lokaj funkcioj daŭre funkcias kaj nur la fora voko, kiu vere bezonas la tunelon, estas malŝaltita. Tiu elekto estas produkta decido, kaj ĝi meritas esti skribita apud la heŭristiko.
Registru, kion vi observis: interfacajn nomojn, platforman version kaj la rezulton de unu provo. Tio transformas la sekvan raporton de disputo al kontrolo. Poste preferu subtenatan deklaron kie vi havas unu, ĉar administrita agordo povas porti la intencon eksplicite kaj forigi la plej grandan parton de la kialo inspekti nomojn entute.
Se kontroloj 1 ĝis 5 lasis vin sen subtenata respondo, liveru la provon kaj nomu la rezulton honeste. Dokumentita signalo de plej bona klopodo estas pli bona produkta decido ol privata API, kiu rompiĝas en la sekva eldono.