Маршрут, дададзены ў табліцу main на Android, выглядае правільна ў любым спісе і ўсё роўна не пераносіць трафік. Прычына ў тым, што табліца main — гэта адзін варыянт з некалькіх, і да яе не звяртаюцца першай. Сеткавая служба Android будуе правілы палітыкі, якія выбіраюць табліцу маршрутызацыі па інфармацыі, якой няма ў адрасе прызначэння — uid праграмы, метка на пакеце, інтэрфейс, з якога ён прыйшоў — а пошук прызначэння адбываецца пазней, унутры той табліцы, якую абралі гэтыя правілы.

Тры рашэнні ў фіксаваным парадку

Пакет на выхадзе прымае тры асобныя рашэнні. Па-першае, правіла палітыкі вырашае, якая табліца маршрутызацыі прымяняецца. Па-другое, маршрут унутры гэтай табліцы вырашае наступны хоп і зыходны інтэрфейс. Па-трэцяе, кручкі netfilter вырашаюць, ці пакет выжыве, ці будзе зменены або перанакіраваны.

Парадак важны, бо кожная стадыя можа адказаць толькі на сваё пытанне. Правіла міжсеткавага экрана, якое прымае пакет, не выбірае табліцу, а маршрут, дададзены ў табліцу, якую не выбірае ніводнае правіла, бяздзейны. Вялікая частка блытаніны вакол VPN на Android паходзіць з таго, што выпраўляюць адно з трох і не бачаць змен, бо збой быў у іншым.

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

Меткі — гэта спакаванае поле, а не этыкетка, якой вы валодаеце

Android спакоўвае некалькі фактаў у адным значэнні меткі: якая сетка абрана, ці праграма яўна абрала сетку, ці сокет абаронены ад VPN і біты, звязаныя з дазволамі. Загаловак fwmark у AOSP вызначае гэтую разметку для бягучага дрэва, і разметка — гэта ўнутраная дэталь платформы, якая змяняецца паміж выпускамі.

Менавіта таму запіс цэлага значэння меткі праз iptables -j MARK --set-mark небяспечны на Android. Ён не дадае тэг; ён замяняе выбар сеткі, які сістэма ўжо зрабіла. Пасля гэтага пакет супадае з іншымі правіламі, і гэта можа выглядаць так, нібы VPN пачаў працаваць, або нібыта незвязаная праграма страціла злучэнне, у залежнасці ад таго, якія біты былі перазапісаны.

Калі вам давядзецца чапаць меткі, спачатку прачытайце бягучае значэнне і выкарыстайце маску, каб змяняліся толькі тыя біты, якія вы разумееце:

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

Метка злучэння — асобны аб'ект ад меткі пакета, і ні адна з іх не з'яўляецца маршрутам. Аднаўленне меткі на пакетах адказу — асобны крок ад выбару табліцы на выхадзе, таму аднабаковыя выпраўленні даюць злучэнні, якія адкрываюцца і потым завісаюць.

Хто валодае правіламі і табліцамі

Сеткавая служба Android, netd, стварае правілы і табліцы для кожнай сеткі. AOSP RouteController — гэта месца, дзе гэтыя правілы збіраюцца для VPN, фізічных сетак і дыяпазонаў uid, і яго жыццёвы цыкл прывязаны да сеткавых падзей, а не да файла канфігурацыі.

З гэтага вынікаюць дзве рэчы. Па-першае, прыярытэты і нумары табліц, якія вы бачыце на адным тэлефоне, — гэта ўнутраныя дэталі зборкі, а не інтэрфейс: аднолькавыя на выгляд нумары на іншай версіі Android могуць азначаць зусім іншае. Па-другое, стан перабудоўваецца пры змене сетак, таму правіла, устаўленае сёння з root-абалонкі, можа знікнуць пасля наступнага пераходу Wi-Fi.

Гэтае знікненне часта апісваюць як тое, што сістэма ігнаруе маршрут. Насамрэч правіла, якое выбірала табліцу, больш не існуе, і маршрут унутры табліцы цяпер недасягальны з пункту гледжання пакета. Правярайце спіс правіл, а не спіс маршрутаў, калі працоўная канфігурацыя перастае працаваць пасля перападлучэння.

Пытанні пра парадак кручкоў не маюць універсальнага адказу

Пытанне, ці iptables працуе перад маршрутызацыяй VPN, нельга вырашыць, не назваўшы шлях пакета. Пакет, створаны лакальна, праходзіць праз кручок output, дзе змена меткі выклікае праверку перамаршрутызацыі — другі пошук, а не рэтраактыўнае рэдагаванне першага. Пакет, які прыйшоў ад кліента праз tethering, праходзіць шляхам prerouting і замест гэтага перасылаецца, і ланцужкі, якія яго бачаць, іншыя.

Такім чынам, адно і тое ж правіла можа быць эфектыўным для трафіку праграмы і нябачным для трафіку tethering, а лічыльнік, які застаецца на нулі, кажа вам, які шлях прайшоў пакет, а не тое, ці правіла памылковае. Выкарыстоўвайце лічыльнікі, каб устанавіць шлях, перш чым змяняць умову супадзення.

Гэта таксама стадыя, на якой памылка маршрутызацыі палітыкі робіцца цяжка бачнай. Маршрутызацыя ў табліцу, якая існуе, але не змяшчае прызначэння, дае «сетка недасягальная», што выглядае як скід міжсеткавага экрана, а скід экрана дае тайм-аўт, які выглядае як маршрутная чорная дзіра.

Дыягнастуйце ўнутры сістэмы або не чапайце яе

Для аўтарызаванай праверкі ўстанавіце чатыры факты, перш чым не-небудзь чапаць: uid і профіль праграмы, сетку, якую Android абраў для яе, ці ўключае VPN гэтую праграму наогул, і ці існуе праблема для абодвух сямействаў адрасоў. Выключэнне для асобнай праграмы тлумачыць вельмі шмат паведамленняў «VPN не працуе» без якой-небудзь маршрутнай памылкі.

Затым прачытайце правілы, маскі і табліцы, якія фактычна дзейнічаюць, і трымайце пераключэнне сеткі ў межах акна назірання. Калі паводзіны змяняюцца пры перападлучэнні, вы бачыце кіраваны жыццёвы цыкл, а не адсутны маршрут.

Для звычайных патрэб выкарыстоўвайце падтрыманыя сродкі кіравання: уключэнне і выключэнне асобных праграм у праграме VPN і ўласны выбар сеткі платформы для ўсяго, што патрабуе пэўнага шляху. Калі прывілеяваная інтэграцыя сапраўды павінна ўзаемадзейнічаць з механізмам маршрутызацыі, арыентуйцеся на рэалізацыю менавіта той версіі Android, якую вы падтрымліваеце, і падтрымлівайце яе жыццёвы цыкл праз кампанент, які ёю валодае. Ачыстка ланцужкоў платформы ці ўстаўка правіла з высокім прыярытэтам ператварае дыягностыку ў другі кіраўнік сеткі, і тэлефон будзе паводзіць сябе адпаведна.

Падобныя артыкулы