Sa Android 10 at mas bago, ang app na nagbubukas ng /proc/net/tcp ay tumatanggap ng pagtanggi sa access sa halip na socket table. Walang pakialam ang VPN interface: dumarating pa rin ang mga packet, dahil ang tunnel ay desisyon sa routing, hindi pahintulot sa file. Ang nagbago ay ang sagot sa isang mas makitid na tanong: «alíng app ang nagmamay-ari ng koneksyong ito?» Ang kapalit ay ConnectivityManager.getConnectionOwnerUid, ang sinusuportahang query sa bawat koneksyon, at ang pagpili sa pagitan ng lumang ugali at ng bagong API ay nakadepende sa kung alin sa tatlong trabaho ang tunay na mayroon ka: pagtanggap ng packet, pag-attribute ng daloy, o pagbubuo ng paggamit.

Dalawang paraan ng pagsagot sa tanong ng may-ari

Bago ang API 29, ang isang privileged o root na proseso ay makakabasa ng socket table ng kernel, maitutugma ang apat, at malalaman ang UID ng may-ari. Nagbibigay iyon ng imbentaryo ng buong device sa isang file. Mula sa API 29, limitado ang tanaw sa filesystem, at ang sinusuportahang landas ay query sa bawat koneksyon kasama ang protocol, lokal na address, at malayong address.

QuestionLegacy socket tablesgetConnectionOwnerUid
Who owns this flow?Scan and match the tupleAsk once per tuple
Device-wide inventory?Yes, when readableNo, one flow at a time
Historical usage?NoNo; that is NetworkStatsManager
Works without root?No on modern releasesYes, for authorized callers

Hindi «luma kumpara sa bago» ang paghahambing. Tatlong magkaibang trabaho ito na dating sinasagot ng isang nababasang file at ngayon ay sinasagot ng tatlong magkaibang interface na may tatlong magkaibang kontrata.

Ang lokal na address ang dulo ng app

Ang lagda ng method ay tumatanggap ng protocol, lokal na socket address, at malayong socket address. Ang «lokal» ay ang panig ng app sa koneksyon, hindi ang dulo na nagkataong pinagmulan ng packet sa sandaling sinusuri mo ito. Ang packet na naglalakbay mula sa malayong server pabalik sa app ay baligtad ang pinagmulan at destinasyon kaugnay ng depinisyong iyon.

ConnectivityManager cm = getSystemService(ConnectivityManager.class);
int uid = cm.getConnectionOwnerUid(
    OsConstants.IPPROTO_TCP, appLocalAddress, appRemoteAddress);

Ang pagkakamaling ito sa direksyon ang pinakakaraniwang dahilan kung bakit ang gumaganang query ay nagbabalik ng maling sagot, o wala. I-log ang dalawang dulo bago ang tawag at tiyakin ang pares laban sa koneksyong aktwal na binuksan ng app. Mahalaga rin ang pamilya ng address: ang address na naka-map sa IPv4 at ang native na IPv6 address ay magkaibang tuple, gayundin ang mga daloy ng TCP at UDP sa parehong port.

Ang awtorisasyon at hindi alam na resulta ay bahagi ng kontrata

Ang query ay limitado sa mga awtorisadong tumatawag, kasama ang aktibong VPN app para sa kaugnay na user. Ang walang kaugnayang monitoring app ay hindi maaaring ipagpalagay na mabibilang nito ang mga koneksyon ng ibang profile, at ang hindi awtorisadong tawag ay maaaring maghagis ng security exception sa halip na magbalik ng magiliw na error. Pangasiwaan ang dalawang kinalabasan nang tahasan.

Ang nawawalang may-ari ay hindi pangalan ng package. Maaaring nagsara ang daloy sa pagitan ng packet at ng query, maaaring hindi kumpleto ang tuple, o maaaring hindi pinapayagang malaman ng tumatawag. Ang pag-cache ng unang matagumpay na sagot at muling paggamit nito sa ibang pagkakataon ay nag-uugnay ng bagong koneksyon sa lumang app, na mas masahol pa kaysa sa pag-uulat ng hindi alam.

Kapag nabigo ang pag-attribute, kailangan pa rin ng desisyon ang trapiko: harangin ito kung saan hinihingi ng patakaran, payagan lamang ang saklaw na naiintindihan mo, o ilantad ang puwang. Ang fallback na iyon ay bahagi ng disenyo, hindi ng komento.

Ang accounting ay ibang tanong

Ang NetworkStatsManager ay nag-uulat ng paggamit sa ilalim ng sarili nitong patakaran sa access. Masasabi nito kung gaano kalaki ang inilipat ng isang UID sa isang panahon; hindi nito masasabi ang may-ari ng isang arbitrary na buhay na packet. Inilalarawan ng mga kakayahan ng network ang mga katangian ng network, hindi direktoryo ng socket. Ang paghahalo ng tatlo ay gumagawa ng mga dashboard na mukhang pare-pareho at hindi naman.

Para sa simpleng kaso ng pagpapasya kung aling app ang gumagamit ng tunnel, ang sinusuportahang listahan ng pinapayagan at ipinagbabawal na app ng Android ay nagpapahayag na ng patakaran nang walang anumang scraping. Itabi ang pag-attribute sa bawat daloy para sa mga kasong tunay na nangangailangan nito, at maglaan ng badyet para sa isang pinapanatiling implementasyon na sabay na humahawak ng direksyon, pahintulot, at hindi alam na estado.

Piliin ang tool ayon sa trabaho, pagkatapos ay subukan ang mga gilid

Kung ang pangangailangan ay pagpili ng tunnel, gamitin ang listahan ng platform. Kung ito ay live na pag-attribute, gamitin ang query ng may-ari at ituring na hindi alam ang bawat tuple na hindi masagot. Kung ito ay makasaysayang kabuuan, gamitin ang stats API. Pagkatapos ay subukan ang tatlong gilid na sumisira sa mga simpleng implementasyon: packet sa kabaligtarang direksyon, daloy na nagsasara bago mo tanungin, at tumatawag na hindi ang aktibong VPN.

Wala sa mga ito ang nangangailangan ng pag-disable ng SELinux, pag-root ng telepono, o paggawa ng kernel table na nababasa sa buong mundo. Ang paghihigpit ang punto: inilipat ng platform ang pag-attribute sa likod ng isang kontrata upang ang sagot ay makarating lamang sa component na lehitimong nangangailangan nito, at wala nang iba.

Kaugnay na mga artikulo