На Android 10 и понови апликацијата што отвора /proc/net/tcp добива одбиен пристап наместо табела со socket. VPN интерфејсот не го интересира: пакетите сè уште пристигнуваат, зашто тунелот е одлука за рутирање, а не дозвола за датотека. Она што се смени е одговорот на потесно прашање: „која апликација ја поседува оваа врска?“ Замената е ConnectivityManager.getConnectionOwnerUid, поддржаното барање по врска, а изборот меѓу старата навика и новиот API зависи од тоа која од трите работи всушност ја имате: примање пакети, атрибуција на тек или собирање на користењето.

Два начина да одговорите на прашањето за сопственикот

Пред API 29 привилегиран или root процес можеше да ги чита табелите со socket на јадрото, да ја совпадне четворката и да го дознае UID на сопственикот. Тоа даваше инвентар за цел уред во една датотека. Од API 29 приказот на датотечниот систем е ограничен, а поддржаниот пат е барање по врска со протоколот, локалната адреса и далечната адреса.

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

Споредбата не е „старо наспроти ново“. Тоа се три различни работи што порано ги задоволуваше една читлива датотека, а сега ги задоволуваат три различни интерфејси со три различни договори.

Локалната адреса е крајот на апликацијата

Потписот на методот прима протокол, локална socket адреса и далечна socket адреса. „Локално“ значи страната на апликацијата во врската, а не крајот што во моментот на проверката случајно е извор на пакетот. Пакетот што патува од далечниот сервер назад кон апликацијата има извор и дестинација обратни во однос на таа дефиниција.

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

Оваа грешка во насоката е најчестата причина зошто исправно барање да врати погрешен одговор, или никаков. Запишете ги двата краја пред повикот и потврдете го парот спрема врската што апликацијата навистина ја отворила. Семејството адреси е исто така важно: адреса претставена преку IPv4 и изворна IPv6 адреса се различни четворки, како и TCP и UDP тековите на исти порти.

Овластувањето и непознатите резултати се дел од договорот

Барањето е ограничено на овластени повикувачи, вклучувајќи ја активната VPN апликација за соодветниот корисник. Неповрзана апликација за надзор не може да претпостави дека може да ги наброи врските на друг профил, а неовластен повик може да фрли безбедносен исклучок наместо пријателска грешка. Двата исхода обработете ги експлицитно.

Сопственик што недостасува не е име на пакет. Текот можеби се затворил помеѓу пакетот и барањето, четворката можеби е нецелосна, или на повикувачот едноставно не му е дозволено да знае. Кеширањето на првиот успешен одговор и неговото подоцнежно користење припишува нова врска на стара апликација, што е полошо од пријавување непознато.

Кога атрибуцијата не успее, сообраќајот сепак бара одлука: блокирајте го таму каде што политиката го бара, дозволете само опфат што го разбирате, или покажете ја празнината. Таа резерва им припаѓа на дизајнот, не на коментар.

Сметководството е друго прашање

NetworkStatsManager пријавува користење според сопствените правила за пристап. Може да ви каже колку пренел некој UID во период; не може да ви каже сопственик на произволен жив пакет. Мрежните можности опишуваат својства на мрежа, не именик на socket. Мешањето на трите дава табли што изгледаат усогласени и не се.

За едноставниот случај да одлучите кои апликации го користат тунелот, поддржаните списоци на дозволени и забранети апликации на Android веќе ја изразуваат политиката без никакво scraping. Зачувајте ја атрибуцијата по тек за случаите на кои навистина им треба, и предвидете буџет за одржлива имплементација што заедно ги обработува насоката, дозволите и непознатите состојби.

Изберете алатка според работата, потоа тестирајте ги рабовите

Ако барањето е избор на тунел, користете го списокот на платформата. Ако е жива атрибуција, користете го барањето за сопственик и третирајте ја секоја неодговорена четворка како непозната. Ако се историски збирови, користете stats API. Потоа тестирајте ги трите рабови што ги кршат наивните имплементации: пакет во обратна насока, тек што се затвора пред да го прашате, и повикувач што не е активниот VPN.

Ништо од ова не бара исклучување на SELinux, root на телефонот или глобално читливи табели на јадрото. Ограничувањето е поентата: платформата ја премести атрибуцијата зад договор за одговорот да биде достапен на компонентата што законски му треба, и на никој друг.

Поврзани статии