Potreban vam je jedan zaslon koji se ponaša drukčije kad je tunel aktivan, a nema poziva koji vam to kaže. To je ograničenje pri isporuci: na macOS-u nijedan javni okvir ne izvješćuje je li proizvoljan VPN povezan, a na iOS-u status pripada aplikaciji koja je instalirala konfiguraciju. Provjere u nastavku vode od te granice do nečega što možete isporučiti, i svaka od njih može rano završiti pretragu.

Provjera 1: može li se na pitanje uopće odgovoriti?

Sandbox rješava pitanje prije bilo kojeg API-ja. Proces treće strane ne može nabrojiti proširenje drugog dobavljača niti može pročitati konfiguraciju tog proširenja, pa nema podržanog objekta kojeg se može pitati.

Svaki zaobilazni put udara u isti zid. Popisi sučelja, scutil --nc list i izravna čitanja konfiguracije sustava ili zahtijevaju ovlasti koje sandbox uskraćuje ili ovise o ponašanju koje Apple nikada nije obećao. Ako planu treba nešto od toga, problem je u planu. Značajka izgrađena na nedokumentiranom detalju je zahtjev za podršku s datumom isporuke.

Provjera 2: upravlja li vaša aplikacija tunelom sama?

Ako upravlja, imate podržan odgovor za vlastitu konfiguraciju. Učitajte postavke, obradite pogrešku, zatim pročitajte status i pretplatite se na promjene umjesto anketiranja:

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
}

Budite precizni oko toga što ovo vraća: stanje tunela koji ste instalirali. Korisnik koji pokreće drugi klijent prikazat će se kao nepovezan, i to nije pogreška u vašem kodu. Odlučite koje od tih dvaju pitanja vaša značajka zaista postavlja prije nego što gradite na odgovoru.

Provjera 3: što bi vam heuristika zapravo rekla?

Široko kopiran pristup pita sistemski rječnik proxyja za njegove obuhvaćene unose i čita ključeve, koji su slučajno imena sučelja:

let settings = CFNetworkCopySystemProxySettings()?.takeRetainedValue() as NSDictionary?
let scoped = settings?["__SCOPED__"] as? [String: Any]
let names = scoped?.keys ?? []

Ključ koji počinje s tap, tun, ppp, ipsec ili utun implicira da je prisutno sučelje obuhvaćeno tunelom. Podudaranje cijelog imena odmah pada, jer je iOS 12 isporučen s utun1 i utun2, a neki se profili pojavljuju kao ipsec4, ppp0 ili utun0. Umjesto toga usporedite prefikse.

Ipak, ime ne identificira vlasnika. Sistemske značajke i proširenja drugih dobavljača također stvaraju utun sučelja, a jedno može postojati dok ne nosi ništa od vašeg prometa. Čitajte to kao nagovještaj da je u blizini nešto u obliku tunela, ništa više. Lažno pozitivan rezultat ovdje je jeftin ako ograničavate samo jednu značajku, a skup ako ograničavate zaslon za prijavu.

Provjera 4: možete li umjesto toga testirati odredište?

Ako aplikacija samo treba znati je li interna usluga dostupna, testirajte tu uslugu. Kratka sonda s vremenskim ograničenjem odgovara na pitanje o kojem značajka zaista ovisi, i nastavlja raditi kad korisnik promijeni klijenta ili tunel promijeni oblik.

Dostupnost je zapažanje o vašem putu. Ime sučelja je zaključak o nečemu što graniči s vašim putem, zato heuristika stvara rasprave u izvješćima o pogreškama, a sonda stvara dokaze. Ako sonda ne uspije dok korisnik tvrdi da je VPN uključen, sada imate konkretan put za otklanjanje pogrešaka: razrješavanje imena, rutu ili dopuštenje usluge.

Provjera 5: može li platforma nametnuti ono što vam treba?

Kad je zahtjev jamstvo da ništa ne izlazi iz tunela, profil je pravo mjesto za to, a ne detektor. Uključivanje includeAllNetworks u konfiguraciji punog tunela na iOS 14 ili novijem mijenja ponašanje platforme umjesto da traži od vaše aplikacije da to zaključi. Zastavica je dokumentirana u referenci NEVPNProtocol.

To je druga vrsta odgovora: nametanje umjesto promatranja. Također se primjenjuje samo na profile koje kontrolirate, pa ne pomaže potrošačkoj aplikaciji koja gleda tuđi tunel.

Provjera 6: učinite neuspjeh sigurnim i vidljivim

Isključite samo sposobnost kojoj treba tunel i ostavite ostatak aplikacije upotrebljivim. Detektor koji sakrije cijelo sučelje kad god nije siguran stvara prekid rada za svakoga čiji tunel koristi ime koje nikada niste predvidjeli. Umjesto toga vratite se na konzervativno ponašanje: lokalne značajke nastavljaju raditi i onemogućen je samo udaljeni poziv kojem tunel zaista treba. Taj izbor je odluka o proizvodu i zaslužuje da bude zapisan pokraj heuristike.

Zabilježite što ste primijetili: imena sučelja, verziju platforme i rezultat jedne sonde. To sljedeće izvješće pretvara iz rasprave u provjeru. Zatim dajte prednost podržanoj deklaraciji gdje je imate, jer upravljana konfiguracija može eksplicitno nositi namjeru i ukloniti većinu razloga za provjeru imena uopće.

Ako su vas provjere od 1 do 5 ostavile bez podržanog odgovora, isporučite sondu i iskreno označite rezultat. Dokumentiran signal najboljeg napora bolja je odluka o proizvodu od privatnog API-ja koji se kvari u sljedećem izdanju.

Povezani članci