VPN на Android без root: каму належаць згода, маршруты і блакаванне
Згода, інтэрфейс TUN і палітыка блакавання сістэмы — гэта тры розныя дазволы. Прасачыце, які кампанент валодае кожным з іх, перш чым разглядаць праграму VPN для Android.
Root — не тое, што дазваляе праграме VPN для Android пераносіць трафік, блакаваць уцечкі ці працаваць пасля перазагрузкі. Людзі зводзяць усё гэта да фразы «у праграмы ёсць дазвол VPN», і гэта хавае тры асобныя механізмы: згоду карыстальніка, інтэрфейс пакетаў, які стварае сістэма, і палітыку блакавання платформы, якую не праграме вызначаць. Разгледзець дызайн VPN для Android — значыць спытаць, на які з трох насамрэч абапіраецца сцвярджэнне, бо ў кожнага свой уладальнік і свой рэжым адмовы.
Згода прыходзіць праз сістэмную актыўнасць
VpnService.prepare() нічога не дае. Ён вяртае intent у сістэмную актыўнасць згоды, калі згоды няма, і праграма адкрывае гэты дыялог, каб карыстальнік ухваліў сэрвіс. Запуск уласнага працэсу праграмы, даданне дазволу ў маніфест або паказ уласнага экрана «уключыць VPN» не ствараюць згоды.
Згода таксама абмежаваная. Яна належыць пакету ў профілі карыстальніка, таму асабовая копія і працоўная копія — розныя рашэнні, і ўладальнік прылады можа падрыхтаваць кіраваны профіль інакш, чым асабовы. Калі дыялог не з'яўляецца і prepare() вяртае null, згода ўжо існуе для гэтага пакета ў гэтым профілі; гэта не доказ надзейнасці праграмы, а толькі тое, што згода на месцы.
Інтэрфейс — гэта запыт, які выконвае сістэма
Пасля згоды праграма апісвае, што хоча, з дапамогай VpnService.Builder: адрасы, маршруты, серверы DNS, MTU і, дзе падтрымліваецца, праграмы для ўключэння або выключэння. establish() просіць сістэму стварыць інтэрфейс тунеля і накіраваць адпаведны трафік у яго. Рашэнне аб маршрутызацыі належыць сістэме; праграма атрымлівае дэскрыптар файла і павінна зрабіць з пакетамі нешта карыснае.
| What you observe | Who actually owns it |
|---|---|
| VPN consent dialog | The system, triggered by prepare() |
| Routes, DNS and app lists | The app requests them; the system applies them |
| One active VPN per profile | The platform; a new service replaces the old one |
| Always-on and block-without-VPN | Device policy enforced by the platform |
Гэтая табліца — архітэктура ў адным месцы. Праграма ўдзельнічае ў апрацоўцы пакетаў; яна не валодае інтэрфейсам, табліцай маршрутызацыі ці колькасцю сэрвісаў, якія могуць працаваць.
Сокет тунеля мусіць выйсці з уласнага тунеля
Злучэнне, якое пераносіць зашыфраваны трафік, само з'яўляецца сокетам. Калі яго накіраваць назад у інтэрфейс, які праграма толькі што стварыла, тунель залежыць ад тунеля і спыняецца. VpnService.protect() прывязвае гэты сокет да ніжэйшай сеткі, каб ён абыходзіў перахоп, і таму карэктны кліент абараняе свой знешні сокет перад першым рукапацісканнем.
adb shell dumpsys connectivity | grep -i -A5 vpn
adb shell settings get global always_on_vpn_app
adb shell settings get global always_on_vpn_lockdown
Гэтыя каманды паказваюць усталяваную сетку VPN, пакет заўсёды ўключанага рэжыму і ці ўсталяваны блакіроўка. Гэта назіранні толькі для чытання: калі значэнні не адпавядаюць таму, што сцвярджае дызайн, сцвярджэнне датычыцца інтэрфейсу праграмы, а не стану сістэмы.
Блакаванне можа належаць платформе
Android дакументуе палітыку, якая блакуе злучэнні, што не выкарыстоўваюць VPN. Гэтае прымяненне — кантракт платформы, а не праграма, якая ў цыкле паўтарае спробы злучэння. Перамыкач знаходзіцца ў наладах VPN прылады пад назвай «Блакаваць злучэнні без VPN», і на кіраванай прыладзе ўладальнік можа ўключыць яго для ўсяго профілю. Гэтае адрозненне важнае пры ацэнцы маркетынгавага сцвярджэння: кліент можа паказваць значок замка і агрэсіўна перападключацца, пакуль прамы трафік застаецца магчымым, або ахопленыя праграмы могуць заставацца афлайн, бо сістэма ўжывае блакіроўку.
Значок замка малюе праграма, таму ён даказвае толькі тое, што праграма лічыць сябе злучанай. Ці страціць іншая праграма доступ да сеткі, вырашае платформа, таму карысная праверка — назіраць, як гэтая праграма падае, пакуль тунель уключаны.
Этыкетка «заўсёды ўключана» ў краме праграм таксама не замяняе гэты кантракт. Заўсёды ўключаны рэжым і блакіроўка — гэта налады прылады, часта ўжытыя ўладальнікам, і іх паводзіны для выключаных праграм вызначае платформа. Чытайце наладу, а не значок.
Чатыры пытанні для разгляду дызайну
Па-першае, хто даў згоду: які пакет, які профіль і ці быў гэта карыстальнік, ці палітыка кіраванай прылады? Па-другое, што запытала праграма: якія маршруты, якія сямействы адрасоў, якія ўключаныя або выключаныя праграмы? Па-трэцяе, што адбываецца, калі тунель недаступны: сістэма блакуе ці трафік вяртаецца ў ніжэйшую сетку? Па-чацвёртае, што праграма робіць з атрыманымі пакетамі?
Чацвёртае пытанне — тое, на якое мадэль дазволаў адказаць не можа. Згода і інтэрфейс TUN даказваюць, што праграма можа атрымліваць трафік, а не тое, што яна яго шыфруе, аўтэнтыфікуе суразмоўцу ці чыста аднаўляецца. Гэта ўласцівасці рэалізацыі, і менавіта на іх сумленны разгляд марнуе час.
Непатрэбны запыт root не становіцца законным ад таго, што вынік называюць «забойцам», а дыялог згоды не з'яўляецца аўдытам бяспекі. Трымайце тры дазволы асобна, і кожнае сцвярджэнне становіцца правяраным.