O rută adăugată în tabelul main pe Android arată corect în orice listare și totuși nu transportă traficul. Motivul este că tabelul main este doar una dintre mai multe opțiuni și nu este consultat primul. Serviciul de rețea al Android construiește reguli de politică ce aleg un tabel de rutare pe baza unor informații pe care adresa de destinație nu le conține — uid-ul aplicației, o marcă pe pachet, interfața pe care a sosit — iar căutarea destinației are loc după aceea, în interiorul tabelului pe care acele reguli l-au ales.

Trei decizii într-o ordine fixă

Un pachet care iese ia trei decizii separate. Întâi, o regulă de politică stabilește ce tabel de rutare se aplică. Apoi, o rută din acel tabel stabilește următorul salt și interfața de ieșire. În final, cârligele netfilter decid dacă pachetul supraviețuiește, este modificat sau este redirecționat.

Ordinea contează pentru că fiecare etapă poate răspunde doar la propria întrebare. O regulă de firewall care acceptă un pachet nu selectează un tabel, iar o rută adăugată într-un tabel pe care nicio regulă nu îl selectează este inertă. Multă confuzie în jurul VPN-urilor pe Android vine din repararea uneia dintre cele trei și lipsa oricărei schimbări, pentru că defecțiunea era în alta.

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

Mărcile sunt un câmp împachetat, nu o etichetă pe care o deții

Android împachetează mai multe fapte în aceeași valoare de marcă: ce rețea a fost aleasă, dacă o aplicație a ales explicit o rețea, dacă un socket este protejat de VPN și biți legați de permisiuni. Antetul fwmark din AOSP definește acea dispunere pentru arborele curent, iar dispunerea este un detaliu intern al platformei care se schimbă între versiuni.

De aceea scrierea unei valori de marcă întregi cu iptables -j MARK --set-mark este periculoasă pe Android. Nu adaugă o etichetă; înlocuiește selecția de rețea pe care sistemul a făcut-o deja. Pachetul se potrivește apoi cu alte reguli, ceea ce poate arăta ca și cum VPN-ul a început să funcționeze sau ca și cum o aplicație fără legătură a pierdut conectivitatea, în funcție de biții suprascriși.

Dacă trebuie să atingi mărcile, citește mai întâi valoarea curentă și folosește o mască astfel încât să se modifice doar biții pe care îi înțelegi:

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

O marcă de conexiune este un obiect separat de o marcă de pachet, iar niciuna nu este o rută. Restaurarea mărcii pe pachetele de răspuns este un pas diferit de alegerea unui tabel la ieșire, de aceea remedierile unidirecționale produc conexiuni care se deschid și apoi se blochează.

Cine deține regulile și tabelele

Serviciul de rețea al Android, netd, creează regulile și tabelele pe fiecare rețea. AOSP RouteController este locul unde acele reguli sunt asamblate pentru VPN-uri, rețele fizice și intervale de uid, iar ciclul său de viață este legat de evenimente de rețea, nu de un fișier de configurare.

Rezultă două consecințe. Întâi, prioritățile și numerele de tabel pe care le găsești pe un telefon sunt detalii interne ale compilării, nu o interfață: numere identice ca aspect pe altă versiune de Android pot însemna cu totul altceva. Apoi, starea este reconstruită când rețelele se schimbă, așa că o regulă inserată astăzi dintr-un shell root poate dispărea după următoarea tranziție Wi-Fi.

Acea dispariție este adesea raportată ca sistemul ignorând o rută. Ce s-a întâmplat de fapt este că regula care selecta tabelul nu mai există, iar ruta din tabel este acum inaccesibilă din perspectiva pachetului. Verifică lista de reguli, nu lista de rute, când o configurație funcțională încetează să funcționeze după o reconectare.

Întrebările despre ordinea cârligelor nu au un răspuns universal

Întrebarea dacă iptables rulează înaintea rutării VPN nu poate fi răspunsă fără a numi calea pachetului. Un pachet generat local trece prin cârligul output, unde o schimbare de marcă declanșează o verificare de rerutare — o a doua căutare, nu o editare retroactivă a primeia. Un pachet care sosește de la un client în tethering trece pe calea prerouting și este redirecționat mai departe în schimb, iar lanțurile care îl văd sunt altele.

Astfel, aceeași regulă poate fi eficientă pentru traficul unei aplicații și invizibilă pentru traficul în tethering, iar un contor care rămâne la zero îți spune ce cale a luat pachetul, nu dacă regula este greșită. Folosește contoare pentru a stabili calea înainte de a schimba orice condiție de potrivire.

Acesta este și stadiul în care o eroare de rutare pe politică devine greu de văzut. Rutarea către un tabel care există dar nu conține destinația produce o rețea inaccesibilă care arată ca o respingere de firewall, în timp ce o respingere de firewall produce un timeout care arată ca o gaură neagră de rutare.

Diagnostichează în interiorul sistemului sau lasă-l în pace

Pentru o examinare autorizată, stabilește patru fapte înainte de a atinge ceva: uid-ul și profilul aplicației, rețeaua pe care Android a ales-o pentru ea, dacă VPN-ul include acea aplicație și dacă problema există pentru ambele familii de adrese. O excludere pe aplicație explică foarte multe rapoarte de VPN nu funcționează fără nicio defecțiune de rutare.

Apoi citește regulile, măștile și tabelele care sunt efectiv în vigoare și ține o schimbare de rețea în fereastra de observare. Dacă comportamentul se schimbă pe parcursul unei reconectări, te uiți la un ciclu de viață gestionat, nu la o rută lipsă.

Pentru cerințe obișnuite, folosește controalele acceptate: includerea și excluderea pe aplicație în aplicația VPN, și selecția de rețea proprie a platformei pentru tot ce are nevoie de o cale anume. Dacă o integrare privilegiată trebuie într-adevăr să coopereze cu mecanismul de rutare, țintește implementarea exactă a versiunii de Android pe care o suporți și menține-i ciclul de viață prin componenta care o deține. Golirea lanțurilor platformei sau inserarea unei reguli cu prioritate mare transformă un diagnostic într-un al doilea manager de rețea, iar telefonul se va comporta în consecință.

Articole similare