Kell egy képernyő, amely másképp viselkedik, amikor az alagút aktív, és nincs olyan hívás, amely ezt megmondaná. Ez a szállítási korlát: macOS-en egyetlen nyilvános keretrendszer sem jelenti, hogy egy tetszőleges VPN csatlakoztatva van-e, iOS-en pedig az állapot ahhoz az alkalmazáshoz tartozik, amely a konfigurációt telepítette. Az alábbi ellenőrzések ettől a korláttól visznek el valami szállíthatóig, és bármelyikük korán véget vethet a keresésnek.

1. ellenőrzés: egyáltalán megválaszolható a kérdés?

A sandbox minden API előtt eldönti a kérdést. Egy harmadik fél folyamata nem tudja felsorolni egy másik szállító kiterjesztését, és nem tudja elolvasni annak a kiterjesztésnek a konfigurációját sem, így nincs támogatott objektum, amit kérdezni lehetne.

Minden megkerülés ugyanabba a falba ütközik. Az interfészlisták, scutil --nc list és a rendszerkonfiguráció közvetlen olvasása vagy a sandbox által visszatartott jogosultságokat igényel, vagy olyan viselkedéstől függ, amit az Apple soha nem ígért meg. Ha a tervnek ezek közül kell valamelyik, a terv a probléma. Egy nem dokumentált részletre épített funkció szállítási dátummal ellátott támogatási jegy.

2. ellenőrzés: az alkalmazásod maga kezeli az alagutat?

Ha igen, van támogatott válaszod a saját konfigurációdra. Töltsd be a beállításokat, kezeld a hibát, majd olvasd ki az állapotot, és iratkozz fel a változásokra a lekérdezgetés helyett:

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
}

Légy pontos abban, mit ad vissza ez: a telepített alagút állapotát. Egy másik klienst futtató felhasználó kapcsolat nélküliként jelenik meg, és ez nem hiba a kódodban. Döntsd el, melyik a két kérdés közül az, amit a funkciód valójában feltesz, mielőtt a válaszra építenél.

3. ellenőrzés: mit mondana el neked valójában egy heurisztika?

A széles körben másolt megközelítés a rendszer proxy szótárától kéri a hatókörrel rendelkező bejegyzéseket, és kiolvassa a kulcsokat, amelyek véletlenül interfésznevek:

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

Egy kulcs, amely tap, tun, ppp, ipsec vagy utun előtaggal kezdődik, arra utal, hogy jelen van egy alagút-hatókörű interfész. A teljes név egyeztetése azonnal meghiúsul, mert az iOS 12 az utun1 és utun2 interfészekkel érkezett, és egyes profilok ipsec4, ppp0 vagy utun0 néven jelennek meg. Hasonlítsd össze inkább az előtagokat.

Ennek ellenére egy név nem azonosít tulajdonost. A rendszerfunkciók és más szállítók kiterjesztései is hoznak létre utun interfészeket, és létezhet olyan, amely semmit sem visz át a forgalmadból. Olvasd ezt annak jelzéseként, hogy van a közelben valami alagút alakú, semmi erősebbet. A téves riasztás itt olcsó, ha csak egy funkciót kapuzol, és drága, ha a bejelentkező képernyőt kapuzolod.

4. ellenőrzés: meg tudod inkább a célt tesztelni?

Ha az alkalmazásnak csak azt kell tudnia, elérhető-e egy belső szolgáltatás, teszteld azt a szolgáltatást. Egy rövid, időtúllépéssel ellátott próba megválaszolja a kérdést, amelytől a funkció valójában függ, és működik tovább, amikor a felhasználó klienst vált vagy az alagút alakot változtat.

Az elérhetőség az útvonaladra vonatkozó megfigyelés. Az interfésznév az útvonalad mellett lévő valamire vonatkozó következtetés, ezért a heurisztika vitákat szül a hibajegyekben, a próba pedig bizonyítékot. Ha a próba meghiúsul, miközben a felhasználó azt állítja, hogy a VPN be van kapcsolva, most már konkrét útvonalad van a hibakereséshez: névfeloldás, útvonal vagy szolgáltatásengedély.

5. ellenőrzés: kikényszerítheti a platform, amire szükséged van?

Amikor a követelmény az a garancia, hogy semmi sem szökik ki az alagútból, a profil a helye, nem a detektor. A includeAllNetworks bekapcsolása teljes alagút konfigurációban iOS 14 vagy újabb rendszeren megváltoztatja a platform viselkedését ahelyett, hogy az alkalmazásodnak kellene kikövetkeztetnie. A jelző dokumentálva van a NEVPNProtocol-referenciában.

Ez másfajta válasz: kikényszerítés megfigyelés helyett. Ráadásul csak az általad vezérelt profilokra vonatkozik, így nem segít egy fogyasztói alkalmazásnak, amely valaki más alagútját figyeli.

6. ellenőrzés: tedd biztonságossá és megfigyelhetővé a hibát

Csak azt a képességet kapcsold ki, amelynek az alagút kell, és hagyd az alkalmazás többi részét használhatónak. Az a detektor, amely bizonytalanság esetén elrejti a teljes felületet, kiesést gyárt mindenkinek, akinek az alagútja olyan nevet használ, amire soha nem számítottál. Térj inkább vissza a konzervatív viselkedésre: a helyi funkciók tovább működnek, és csak az a távoli hívás tiltódik le, amelynek valóban kell az alagút. Ez a választás termékdöntés, és megérdemli, hogy a heurisztika mellé leírják.

Naplózd, amit megfigyeltél: interfésznevek, platformverzió és egy próba eredménye. Ez a következő jelentést vitából ellenőrzéssé alakítja. Utána részesítsd előnyben a támogatott nyilatkozatot, ahol van ilyened, mert egy kezelt konfiguráció kifejezetten hordozhatja a szándékot, és eltávolíthatja a nevek vizsgálatának legtöbb okát.

Ha az 1–5. ellenőrzés támogatott válasz nélkül hagyott, szállítsd a próbát, és nevezd meg őszintén az eredményt. Egy dokumentált legjobb igyekezet jelzés jobb termékdöntés, mint egy privát API, amely a következő kiadásban eltörik.

Kapcsolódó cikkek