Android VPN-útvonalazás: házirend-szabályok a main tábla előtt
Az Android a routing táblát uid- és jelölés-szabályokkal választja ki minden célkeresés előtt, ezért a main táblába felvett útvonalat lehet, hogy soha nem kérdezik meg.
Az Android main táblájába felvett útvonal minden listában helyesnek látszik, mégsem viszi a forgalmat. Az ok az, hogy a main tábla csak egy a több lehetőség közül, és nem azt kérdezik meg először. Az Android hálózati szolgáltatása olyan házirend-szabályokat épít, amelyek a routing táblát olyan információ alapján választják ki, amelyet a célcím nem tartalmaz — az alkalmazás uid-je, a csomagon lévő jelölés, az interfész, amelyen érkezett —, és a cél keresése ezután történik, abban a táblában, amelyet ezek a szabályok választottak.
Három döntés rögzített sorrendben
A kimenő csomag három külön döntést hoz. Először egy házirend-szabály eldönti, melyik routing tábla érvényes. Másodszor a táblán belüli útvonal eldönti a következő ugrást és a kimenő interfészt. Harmadszor a netfilter horgok eldöntik, hogy a csomag túléli-e, módosul-e vagy átirányítják.
A sorrend azért számít, mert minden szakasz csak a saját kérdésére tud válaszolni. A csomagot elfogadó tűzfal-szabály nem választ táblát, és az olyan táblába felvett útvonal, amelyet egyetlen szabály sem választ, hatástalan. Az Android VPN-ek körüli zavar nagy része abból ered, hogy a három közül egyet javítanak és nem látnak változást, mert a hiba egy másikban volt.
| Stage | Selector | What it cannot decide |
|---|---|---|
| Policy rule | uid range, mark, incoming interface | Which route exists inside the table |
| Route lookup | Destination prefix, longest match | Whether the packet is allowed out |
| Netfilter hook | Chain position, match conditions | Which table was selected |
A jelölések csomagolt mező, nem a te címkéd
Az Android több tényt csomagol ugyanabba a jelölésértékbe: melyik hálózatot választották, egy alkalmazás kifejezetten választott-e hálózatot, védett-e egy socket a VPN-től, és az engedélyekhez kapcsolódó bitek. Az AOSP fwmark fejléc határozza meg ezt az elrendezést az aktuális fához, és az elrendezés platformbelső dolog, amely kiadások között változik.
Ezért veszélyes az Androidon egy teljes jelölésértéket a iptables -j MARK --set-mark paranccsal írni. Nem címkét ad hozzá; lecseréli a hálózatválasztást, amelyet a rendszer már elvégzett. A csomag ezután más szabályokra illeszkedik, ami a felülírt bitektől függően úgy tűnhet, hogy a VPN működni kezdett, vagy hogy egy független alkalmazás elvesztette a kapcsolatot.
Ha mégis hozzá kell nyúlnod a jelölésekhez, először olvasd ki az aktuális értéket, és használj maszkot, hogy csak az általad értett bitek változzanak:
ip rule show
ip route show table all | head -40
ip route get 10.20.4.11A kapcsolatjelölés külön objektum a csomagjelöléstől, és egyik sem útvonal. A jelölés visszaállítása a válaszcsomagokon külön lépés a kimeneti táblaválasztástól, ezért az egyirányú javítások olyan kapcsolatokat hoznak létre, amelyek megnyílnak, majd elakadnak.
Ki birtokolja a szabályokat és a táblákat
Az Android hálózati szolgáltatása, a netd hozza létre a szabályokat és a hálózatonkénti táblákat. A AOSP RouteController az a hely, ahol ezeket a szabályokat VPN-ekhez, fizikai hálózatokhoz és uid tartományokhoz összeállítják, és az életciklusa hálózati eseményekhez kötődik, nem konfigurációs fájlhoz.
Két következmény adódik. Először, az egy készüléken talált prioritások és táblaszámok build-belső részletek, nem interfész: egy másik Android-verzión ugyanígy kinéző számok egészen mást jelenthetnek. Másodszor, az állapot a hálózatok változásakor újraépül, így a ma root shellből beszúrt szabály a következő Wi-Fi-váltás után már hiányozhat.
Ezt az eltűnést gyakran úgy jelentik, hogy a rendszer figyelmen kívül hagy egy útvonalat. Valójában az történt, hogy a táblát választó szabály már nem létezik, és a táblán belüli útvonal most elérhetetlen a csomag szempontjából. A szabálylistát nézd, ne az útvonallistát, amikor egy működő konfiguráció újracsatlakozás után felmondja a szolgálatot.
A horgok sorrendjére vonatkozó kérdéseknek nincs általános válasza
Arra a kérdésre, hogy az iptables a VPN-routing előtt fut-e, nem lehet válaszolni a csomag útjának megnevezése nélkül. A helyben előállított csomag az output horgon halad át, ahol a jelölés változása újraútvonalazási ellenőrzést indít — második keresés, nem az első utólagos szerkesztése. A tetherrel csatlakozó ügyféltől érkező csomag a prerouting úton halad és továbbítódik, és az őt látó láncok mások.
Ugyanaz a szabály tehát hatékony lehet egy alkalmazás forgalmára és láthatatlan a tether forgalomra, és a nullán maradó számláló megmondja, melyik utat vette a csomag, nem azt, hogy a szabály hibás-e. Számlálókkal állapítsd meg az utat, mielőtt bármelyik illesztési feltételt megváltoztatod.
Ez az a szakasz is, ahol a házirend-útvonalazás hibája nehezen láthatóvá válik. Egy létező, de a célt nem tartalmazó táblába irányítás hálózat elérhetetlen hibát ad, amely tűzfal-eldobásnak látszik, míg a tűzfal-eldobás időtúllépést ad, amely útvonalazási fekete lyuknak látszik.
A rendszeren belül diagnosztizálj, vagy hagyd békén
Engedélyezett vizsgálathoz négy tényt rögzíts, mielőtt bármihez hozzányúlnál: az alkalmazás uid-jét és profilját, a hálózatot, amelyet az Android neki választott, hogy a VPN egyáltalán tartalmazza-e azt az alkalmazást, és hogy a probléma mindkét címcsaládban fennáll-e. Az alkalmazásonkénti kizárás nagyon sok VPN nem működik jelentést megmagyaráz mindenféle útvonalazási hiba nélkül.
Utána olvasd el a ténylegesen érvényben lévő szabályokat, maszkokat és táblákat, és tartsd a hálózatváltást a megfigyelési ablakon belül. Ha a viselkedés újracsatlakozás során megváltozik, kezelt életciklust látsz, nem hiányzó útvonalat.
Szokásos igényekhez használd a támogatott vezérlőket: alkalmazásonkénti bevonás és kizárás a VPN-alkalmazásban, és a platform saját hálózatválasztását mindenhez, aminek meghatározott útra van szüksége. Ha egy kiemelt integrációnak valóban együtt kell működnie az útvonalazó gépezettel, a pontosan támogatott Android-verzió implementációját célozd, és annak életciklusát a tulajdonos komponensen keresztül tartsd fenn. A platformláncok kiürítése vagy magas prioritású szabály beszúrása második hálózatkezelővé alakítja a diagnózist, és a telefon ennek megfelelően viselkedik.