Androidis tabelisse main lisatud marsruut näeb igas loendis õige välja ja ei kanna ikkagi liiklust. Põhjus on see, et tabel main on üks mitmest valikust ja seda ei küsitleta esimesena. Androidi võrguteenus ehitab poliitikareeglid, mis valivad marsruutimistabeli info põhjal, mida sihtkoha aadress ei sisalda — rakenduse uid, paketil olev märge, liides, millelt see saabus — ja sihtkoha otsing toimub hiljem, selle tabeli sees, mille need reeglid valisid.

Kolm otsust kindlas järjekorras

Väljuv pakett teeb kolm eraldi otsust. Esiteks otsustab poliitikareegel, milline marsruutimistabel kehtib. Teiseks otsustab selle tabeli sees olev marsruut järgmise hüppe ja väljuva liidese. Kolmandaks otsustavad netfilteri konksud, kas pakett jääb ellu, seda muudetakse või suunatakse ümber.

Järjekord on oluline, sest iga etapp saab vastata ainult oma küsimusele. Tulemüürireegel, mis paketi vastu võtab, ei vali tabelit, ja marsruut, mis on lisatud tabelisse, mida ükski reegel ei vali, on tegevusetu. Suur osa Androidi VPN-ide ümber olevast segadusest tuleb sellest, et parandatakse ühte kolmest ja ei nähta muutust, sest viga oli teises.

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ärked on pakitud väli, mitte silt, mille omanik sa oled

Android pakib mitu fakti samasse märkeväärtusesse: milline võrk valiti, kas rakendus valis võrgu selgesõnaliselt, kas socket on VPN-i eest kaitstud ja õigustega seotud bitid. AOSP fwmark päis määratleb selle paigutuse praeguse puu jaoks ja paigutus on platvormi sisemine asi, mis versioonide vahel muutub.

Seepärast on Androidis ohtlik kirjutada tervet märkeväärtust käsuga iptables -j MARK --set-mark. See ei lisa silti; see asendab võrguvaliku, mille süsteem on juba teinud. Seejärel sobib pakett teiste reeglitega, mis võib tunduda nii, nagu VPN hakkas tööle, või nagu seotud rakendus kaotas ühenduse, sõltuvalt sellest, millised bitid üle kirjutati.

Kui pead märkeid puudutama, loe esmalt praegune väärtus ja kasuta maski, et muutuksid ainult need bitid, millest aru saad:

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

Ühenduse märge on paketi märkmest eraldi objekt ja kumbki neist ei ole marsruut. Märke taastamine vastusepakettidel on eraldi samm tabeli valimisest väljumisel, mistõttu ühesuunalised parandused tekitavad ühendusi, mis avanevad ja jäävad seejärel rippuma.

Kellele kuuluvad reeglid ja tabelid

Androidi võrguteenus netd loob reeglid ja võrgupõhised tabelid. AOSP RouteController on koht, kus need reeglid pannakse kokku VPN-ide, füüsiliste võrkude ja uid-vahemike jaoks, ja selle elutsükkel on seotud võrgusündmustega, mitte konfiguratsioonifailiga.

Sellest järeldub kaks asja. Esiteks on prioriteedid ja tabelinumbrid, mida ühes telefonis leiad, build'i sisemised detailid, mitte liides: teises Androidi versioonis samasugusena näivad numbrid võivad tähendada hoopis midagi muud. Teiseks ehitatakse olek võrkude muutumisel uuesti üles, seega täna root-shellist lisatud reegel võib pärast järgmist Wi-Fi üleminekut kadunud olla.

Seda kadumist kirjeldatakse sageli nii, nagu süsteem eiraks marsruuti. Tegelikult ei ole reeglit, mis tabeli valis, enam olemas ja tabelis olev marsruut on nüüd paketi vaatepunktist kättesaamatu. Kontrolli reeglite loendit, mitte marsruutide loendit, kui töötav konfiguratsioon lakkab pärast taasühendamist töötamast.

Konksude järjekorra kohta ei ole universaalset vastust

Küsimusele, kas iptables töötab enne VPN-i marsruutimist, ei saa vastata paketi teed nimetamata. Kohapeal genereeritud pakett läbib output-konksu, kus märke muutus käivitab ümbermarsruutimise kontrolli — teine otsing, mitte esimese tagasiulatuv muutmine. Tethering-kliendilt saabuv pakett läbib prerouting-tee ja edastatakse selle asemel edasi, ning ahelad, mis seda näevad, on teised.

Seega võib sama reegel olla tõhus rakenduse liikluse jaoks ja nähtamatu tethering-liikluse jaoks, ning loendur, mis jääb nulli, ütleb sulle, millise tee pakett valis, mitte seda, kas reegel on vale. Kasuta loendureid tee kindlakstegemiseks enne mis tahes sobivustingimuse muutmist.

See on ka etapp, kus poliitikamarsruutimise viga muutub raskesti nähtavaks. Marsruutimine tabelisse, mis on olemas, kuid ei sisalda sihtkohta, tekitab võrgu kättesaamatu, mis näeb välja nagu tulemüüri drop, samas kui tulemüüri drop tekitab ajalõpu, mis näeb välja nagu marsruutimise must auk.

Diagnoosi süsteemi sees või jäta see rahule

Volitatud ülevaatuse jaoks tee enne millegi puudutamist kindlaks neli fakti: rakenduse uid ja profiil, võrk, mille Android selle jaoks valis, kas VPN üldse seda rakendust hõlmab ja kas probleem esineb mõlema aadressiperekonna puhul. Rakendusepõhine välistus seletab väga paljusid teateid VPN ei tööta ilma igasuguse marsruutimisveata.

Seejärel loe reegleid, maske ja tabeleid, mis tegelikult kehtivad, ja hoia võrguvahetust vaatlusakna sees. Kui käitumine muutub üle taasühenduse, vaatad haldatud elutsüklit, mitte puuduvat marsruuti.

Tavaliste nõuete jaoks kasuta toetatud juhtimisvahendeid: rakendusepõhine kaasamine ja välistamine VPN-rakenduses ja platvormi enda võrguvalikut kõige jaoks, mis vajab kindlat teed. Kui privilegeeritud integratsioon peab tõesti marsruutimismasinaga koostööd tegema, sihitle täpselt selle Androidi versiooni teostust, mida toetad, ja hoia selle elutsüklit selle omanikust komponendi kaudu. Platvormi ahelate tühjendamine või kõrge prioriteediga reegli sisestamine muudab diagnoosi teiseks võrguhalduriks ja telefon käitub vastavalt.

Seotud artiklid