På Android ser en rute som legges inn i tabellen main riktig ut i alle lister, men den fører likevel ikke trafikken. Grunnen er at tabellen main bare er ett av flere alternativer, og den blir ikke undersøkt først. Androids nettverkstjeneste bygger policyregler som velger rutetabell ved hjelp av opplysninger som destinasjonsadressen ikke inneholder — appens uid, en markering på pakken, grensesnittet den kom inn på — og destinasjonsoppslaget skjer etterpå, inne i tabellen som reglene pekte ut.

Tre valg i bestemt rekkefølge

En pakke som skal ut gjør tre atskilte valg. Først bestemmer en policyregel hvilken rutetabell som er aktiv. Så bestemmer en rute i den tabellen neste hopp og grensesnittet ut. Til sist bestemmer netfilter-krokene om pakken slipper gjennom, blir endret eller blir omdirigert.

Rekkefølgen er viktig fordi hvert ledd bare svarer på sitt eget spørsmål. En brannmurregel som tillater en pakke velger ingen tabell, og en rute i en tabell som ingen regel peker på, gjør ingen nytte. Mye forvirring rundt Android-VPN skyldes at man fikser ett av de tre leddene og ikke ser endring, fordi feilen satt i et annet.

StageSelectorWhat it cannot decide
Policy ruleuid range, mark, incoming interfaceWhich route exists inside the table
Route lookupDestination prefix, longest matchWhether the packet is allowed out
Netfilter hookChain position, match conditionsWhich table was selected

Markeringer er et sammensatt felt, ikke en etikett du rår over

Android samler flere opplysninger i samme merkeverdi: hvilket nett som ble valgt, om appen selv valgte nett, om en socket er skjermet mot VPN, og biter for tillatelser. fwmark-hodet i AOSP angir denne innretningen for gjeldende tre, og innretningen er en plattformintern sak som endres fra versjon til versjon.

Derfor er det risikabelt på Android å skrive en komplett merkeverdi med iptables -j MARK --set-mark. Det setter ikke på en tag; det overstyrer nettvalget systemet allerede har gjort. Pakken treffer da andre regler, og det kan se ut som VPN begynte å virke, eller som at en helt annen app mistet nettet, alt etter hvilke biter som ble skrevet over.

Må du først justere markeringer, les av dagens verdi og bruk en maske, slik at bare de bitene du kjenner blir forandret:

ip rule show
ip route show table all | head -40
ip route get 10.20.4.11

En tilkoblingsmarkering er et eget objekt fra en pakkemarkering, og ingen av dem er en rute. Å gjenopprette markeringen på svarpakker er et annet steg enn å velge tabell på vei ut, og derfor gir enveis fikser tilkoblinger som åpner og så henger.

Hvem rår over reglene og tabellene

Android sin nettverkstjeneste, netd, oppretter reglene og tabellene for hvert nett. AOSP RouteController er stedet der reglene settes sammen for VPN, fysiske nett og uid-intervaller, og levetiden styres av nettverkshendelser og ikke av en konfigurasjonsfil.

Det gir to følger. For det første er prioriteter og tabellnumre du ser på én telefon interne byggedetaljer, ikke et grensesnitt: numre som ser like ut på en annen Android-versjon kan bety noe helt annet. For det andre bygges tilstanden på nytt når nett endres, så en regel som legges inn i dag fra et root-skall kan være borte etter neste Wi-Fi-bytte.

Slik forsvinning rapporteres ofte som at systemet overser en rute. Det som egentlig skjedde, er at regelen som valgte tabellen er borte, og ruten i tabellen nå er utilgjengelig sett fra pakken. Sjekk regellisten, ikke rutelisten, når en oppsett som virket slutter å virke etter ny tilkobling.

Spørsmål om rekkefølgen på krokene har ikke noe allment svar

Spørsmålet om iptables kjører før VPN-ruting kan ikke besvares uten å si hvilken vei pakken tar. En lokalt laget pakke går gjennom output-kroken, der en merkingsendring utløser ny rutekontroll — et nytt oppslag, ikke en etterpåklok retting av det første. En pakke fra en tether-klient går via prerouting og videresendes i stedet, og kjedene som ser den er andre.

Samme regel kan altså virke for en apps trafikk og være usynlig for tether-trafikk, og en teller som står på null sier hvilken vei pakken gikk, ikke om regelen er feil. Bruk tellere for å fastslå veien før du endrer en matchbetingelse.

Dette er også trinnet der en policyrutingsfeil blir vanskelig å oppdage. Ruting til en tabell som finnes, men mangler destinasjonen, gir nett utilgjengelig som ser ut som et brannmurslipp, mens et brannmurslipp gir tidsavbrudd som ser ut som et rutingssort hull.

Diagnostiser inni systemet, eller la det være

Ved en autorisert gjennomgang bør du fastslå fire ting før du tar i noe: appens uid og profil, nettet Android valgte for den, om VPN i det hele tatt omfatter appen, og om problemet gjelder begge adressefamilier. En utestengning per app forklarer svært mange meldinger om at VPN ikke virker uten noen rutingsfeil.

Les så reglene, maskene og tabellene som faktisk gjelder, og hold et nettbytte inne i observasjonsvinduet. Endrer oppførselen seg over en ny tilkobling, ser du på en styrt levetid, ikke en manglende rute.

For vanlige behov, bruk de støttede kontrollene: inkludering og utestengning per app i VPN-programmet, og plattformens eget nettvalg for alt som trenger en bestemt vei. Skal en privilegert integrasjon virkelig samarbeide med rutingsmaskineriet, målrett mot implementasjonen av nøyaktig den Android-versjonen du støtter, og vedlikehold levetiden gjennom komponenten som eier den. Å tømme plattformkjeder eller legge inn en regel med høy prioritet gjør en diagnose om til en ekstra nettverksbehandler, og telefonen vil oppføre seg tilsvarende.

Relaterte artikler