A téves feltevés az, hogy egy VpnService-alkalmazás átbillent egy rendszerkapcsolót, és onnantól a telefon védett. Ami valójában történik, szűkebb: az alkalmazás hozzájárulást kér, interfészt épít, fájlleírókon keresztül olvas és ír csomagokat, és visszaadja az interfészt, amikor leáll. Egyszerre csak egy ilyen alagút lehet életben, és a rendszer kérdezés nélkül elveheti. A zavaró viselkedés nagy része, amelyet az emberek a protokollnak tulajdonítanak, ebből a tulajdonosi modellből ered.

Kezeljen minden életciklus-átmenetet a tervezés részének, ne szélsőséges esetnek.

Tévhit: az alkalmazás bekapcsolja a telefon VPN-jét

A folyamat a VpnService.prepare()-tal kezdődik, amely egy Intentet ad vissza, amelyet a felhasználónak el kell fogadnia, és a establish()-tal folytatódik, amely utána még meghiúsulhat olyan okokból, amelyeket az alkalmazás nem irányít. Egy második alagút létrehozása deaktiválja az első interfészt és lecseréli a rendszerértesítést. A sorozat egyetlen pontján sem birtokol az alkalmazás eszközszintű kapcsolót; a neki adott leírót és a rá érkező csomagokat birtokolja. Még az állandó értesítés is a rendszerhez tartozik, nem az alkalmazás tervezéséhez.

Mivel az interfészt adják, nem elragadják, egy másik kliens bármikor elfoglalhatja a helyet. Az alkalmazás ezt visszahíváson keresztül tudja meg, nem visszatérési értéken.

Az alkalmazás kényszerített leállítása ugyanezen okból látszik az értesítési panelen: a rendszer azt jelenti, amit adott, nem azt, amit az alkalmazás megjeleníteni választott.

Tévhit: a hozzájárulást egyszer adják meg

Amikor a rendszer átadja az alagutat egy másik kliensnek, visszavonási tranzakciót küld azon a binderen, amelyet az alaposztály a onBind()-ból ad vissza. Az alkalmazásnak, amely ezt a bindert a sajátjával helyettesíti, magának kell továbbítania a visszavonási tranzakciót, különben a VpnService.onRevoke() soha nem indul el, és a szolgáltatás tovább ír egy leíróba, amely már nem létezik. A jóváhagyást a felhasználó is visszavonhatja, és a rendszer leállíthatja a szolgáltatást újraindítás vagy mindig bekapcsolt újracsatlakozás közben.

Ennek kezelése konkrét munka, nem naplósor: hagyja abba a leíró olvasását, zárja be, törölje a csatlakoztatott jelzőt, és mondja meg a felhasználónak, milyen állapotban van. Ezután döntse el, hogy az alkalmazásnak újra kell-e építenie, újra kérdeznie vagy várnia, mert mindig bekapcsolt konfigurációban a rendszer magától is visszahozhatja a szolgáltatást.

Az az alkalmazás, amely a visszavonást kivételként, nem állapotként kezeli, csatlakozottnak fogja jelenteni magát, miközben minden általa írt csomag eldobódik, és ez a lehető legrosszabb hibamód egy adatvédelmi eszköz számára.

Tévhit: az interfész helyetted szűri a forgalmat

Ami érkezik, nyers IP. A rögzítés vagy szűrés az IP-, TCP-, UDP- és IPv6-fejlécek elemzését, a folyamok követését és a válaszok leíróba való visszaírását jelenti, ami egy rögzítő alkalmazást kis hálózati veremmé tesz, nem rendszereszközzé. A protect() azért létezik, hogy az alkalmazás saját átviteli socketje megkerülje az alagútját ahelyett, hogy önmagát rögzítené, és olyan logikai értéket ad vissza, amely minden socketen ellenőrzést érdemel, amelyet az alagút felállása után hoznak létre.

A szerkesztő engedélyezett és tiltott alkalmazáslistái döntik el, kinek a forgalma lép be az interfészre. Nem adnak hozzáférést az interfész által hordozott IP-csomagokon túli adatokhoz, és egyetlen API sem tárja fel egy másik kliens alagútját vagy sorolja fel a rendszer VPN-profiljait. A hálózati képességek megmondhatják, hogy egy hálózat VPN-átvitel, de azt nem, hogy kié az alagút.

Ezért kapnak a más alkalmazások állapotára vonatkozó kérdések ellentmondásos válaszokat: az információ egyszerűen nincs feltárva a folyamatod előtt.

Mit követel valójában az életciklus

Kövesse az általa irányított állapotokat: előkészített, létrehozott, visszavont, leállított. Az újracsatlakozásnak bontásnak, majd létrehozásnak kell lennie, egyetlen tulajdonossal a leíróhoz és az átviteli sockethez, mert két komponens, amely verseng a létrehozásért, harcolni fog az egyetlen szabad helyért. A háttérindítások modern Androidon korlátozottak, ezért az indítási broadcast nem garancia; használjon előtér-szolgáltatást az értesítésével ott, ahol az API-szint engedi.

Naplózza az átmenetet, ne csak a végállapotot, és tartsa az állapotgépet elég kicsinek ahhoz, hogy minden utat teszteljen. Az az állapot, amelyet tesztben nem ér el, olyan állapot, amellyel a terepen napló nélkül találkozik.

Tesztelje az életciklust egy eszközön

Az emulátorok tudnak hamisítani a kapcsolatot, de a hozzájárulás és a visszavonás útját nem meggyőzően, ezért futtassa ezeket valódi eszközön, telepített második VPN-klienssel, amely ellopja a helyet.

adb shell dumpsys connectivity | grep -i -A3 vpn
adb shell dumpsys activity services | grep -i -A2 vpnservice
adb logcat -s VpnService:V AndroidRuntime:E
adb shell am force-stop com.example.vpnapp

Indítsa el az alagutat, erősítse meg az értesítést és az interfészt, majd csatlakoztassa a másik klienst, és figyelje, hogy lefut-e a visszavonási visszahívás, és tisztul-e az állapot. Kényszerítetten állítsa le az alkalmazást, és ellenőrizze, jelent-e még valami élő leírót.

Ismételje meg a sorozatot mindig bekapcsolt újraindítás után, mert ez az út eltér a felhasználó által indított kapcsolattól. Nem zöld ikont keres, hanem bizonyítékot arra, hogy az alkalmazás abbahagyta egy olyan leíró használatát, amely már nem volt a birtokában.

Kapcsolódó cikkek