Směrování VPN na Androidu: pravidla zásad před tabulkou main
Android vybírá směrovací tabulku pravidly uid a značek ještě před jakýmkoli hledáním cíle, takže trasa přidaná do main nemusí být nikdy použita.
Trasa přidaná do tabulky main na Androidu vypadá správně v každém výpisu a přesto provoz nepřenáší. Důvod je ten, že tabulka main je jedna z několika možností a neprochází se první. Síťová služba Androidu staví pravidla zásad, která vybírají směrovací tabulku podle informací, které cílová adresa neobsahuje — uid aplikace, značka na paketu, rozhraní, kterým přišel — a vyhledání cíle probíhá až potom, uvnitř tabulky, kterou tato pravidla zvolila.
Tři rozhodnutí v pevném pořadí
Odchozí paket činí tři samostatná rozhodnutí. Za prvé, pravidlo zásad rozhoduje, která směrovací tabulka platí. Za druhé, trasa uvnitř této tabulky rozhoduje o dalším hopu a výstupním rozhraní. Za třetí, háčky netfilter rozhodují, zda paket přežije, bude upraven nebo přesměrován.
Pořadí je důležité, protože každá fáze umí odpovědět jen na svou vlastní otázku. Pravidlo firewallu, které paket přijme, nevybírá tabulku, a trasa přidaná do tabulky, kterou žádné pravidlo nevybírá, je nečinná. Velká část zmatku kolem VPN na Androidu vzniká tím, že se opraví jedna ze tří věcí a nepozoruje se žádná změna, protože závada byla v jiné.
| 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 |
Značky jsou zabalené pole, ne štítek, který vlastníte
Android zabaluje několik skutečností do stejné hodnoty značky: která síť byla vybrána, zda aplikace síť výslovně zvolila, zda je socket chráněn před VPN a bity související s oprávněními. Hlavička fwmark v AOSP definuje toto rozložení pro aktuální strom a rozložení je vnitřní záležitost platformy, která se mezi vydáními mění.
Proto je zápis celé hodnoty značky pomocí iptables -j MARK --set-mark na Androidu nebezpečný. Neplní úlohu štítku; nahrazuje volbu sítě, kterou systém už provedl. Paket pak odpovídá jiným pravidlům, což může vypadat, jako by VPN začala fungovat, nebo jako by nesouvisející aplikace ztratila připojení, podle toho, které bity byly přepsány.
Pokud se značek musíte dotknout, přečtěte nejprve aktuální hodnotu a použijte masku, aby se měnily jen bity, kterým rozumíte:
ip rule show
ip route show table all | head -40
ip route get 10.20.4.11Značka spojení je samostatný objekt od značky paketu a ani jedna není trasa. Obnovení značky na odpovědních paketech je jiný krok než volba tabulky na výstupu, proto jednosměrné opravy vytvářejí spojení, která se otevřou a pak visí.
Kdo vlastní pravidla a tabulky
Síťová služba Androidu, netd, vytváří pravidla a tabulky pro jednotlivé sítě. AOSP RouteController je místo, kde se tato pravidla skládají pro VPN, fyzické sítě a rozsahy uid, a jeho životní cyklus je vázán na síťové události, nikoli na konfigurační soubor.
Z toho plynou dva důsledky. Za prvé, priority a čísla tabulek, které najdete na jednom telefonu, jsou vnitřnosti sestavení, nikoli rozhraní: stejně vypadající čísla na jiné verzi Androidu mohou znamenat něco úplně jiného. Za druhé, stav se při změně sítí znovu sestavuje, takže pravidlo vložené dnes z root shellu může po dalším přechodu Wi-Fi zmizet.
Toto zmizení se často hlásí jako to, že systém ignoruje trasu. Ve skutečnosti pravidlo, které tabulku vybíralo, už neexistuje a trasa uvnitř tabulky je nyní z pohledu paketu nedostupná. Kontrolujte seznam pravidel, ne seznam tras, když funkční konfigurace po opětovném připojení přestane fungovat.
Otázky pořadí háčků nemají univerzální odpověď
Otázku, zda iptables běží před směrováním VPN, nelze zodpovědět bez pojmenování cesty paketu. Lokálně vytvořený paket prochází háčkem output, kde změna značky spustí kontrolu opětovného směrování — druhé vyhledání, ne retroaktivní úpravu prvního. Paket přicházející od tethering klienta prochází cestou prerouting a místo toho se předává dál, a řetězce, které ho vidí, jsou jiné.
Stejné pravidlo tedy může být účinné pro provoz aplikace a neviditelné pro tethering provoz, a čítač, který zůstává na nule, vám říká, jakou cestou se paket vydal, ne zda je pravidlo špatné. Než změníte jakoukoli podmínku shody, zjistěte cestu pomocí čítačů.
To je také fáze, ve které je chyba směrování zásad těžko vidět. Směrování do tabulky, která existuje, ale neobsahuje cíl, vytváří síť nedostupnou, což vypadá jako zahazování firewallem, zatímco zahazování firewallem vytváří časový limit, který vypadá jako směrovací černá díra.
Diagnostikujte uvnitř systému, nebo do něj nezasahujte
Pro autorizovanou kontrolu zjistěte čtyři skutečnosti, než se čehokoli dotknete: uid a profil aplikace, síť, kterou pro ni Android vybral, zda VPN tu aplikaci vůbec zahrnuje, a zda problém existuje pro obě rodiny adres. Vyloučení po aplikacích vysvětluje mnoho hlášení VPN nefunguje bez jakékoli směrovací závady.
Potom si přečtěte pravidla, masky a tabulky, které skutečně platí, a udržte přepnutí sítě uvnitř pozorovacího okna. Pokud se chování při opětovném připojení změní, díváte se na řízený životní cyklus, ne na chybějící trasu.
Pro běžné požadavky používejte podporované ovládací prvky: zahrnutí a vyloučení po aplikacích v aplikaci VPN a vlastní volbu sítě platformy pro vše, co potřebuje konkrétní cestu. Pokud privilegovaná integrace opravdu musí spolupracovat se směrovacím strojem, cílte na implementaci přesné verze Androidu, kterou podporujete, a udržujte její životní cyklus přes komponentu, která ji vlastní. Propláchnutí řetězců platformy nebo vložení pravidla s vysokou prioritou promění diagnózu v druhého správce sítě a telefon se bude chovat podle toho.