Android VPN attiecināšana: getConnectionOwnerUid pret /proc/net
Android 10 slēpj /proc/net no lietotnēm. VPN joprojām saņem paketes, bet attiecināšana pāriet uz getConnectionOwnerUid ar saviem tuple un atļauju noteikumiem.
Android 10 un jaunākās versijās lietotne, kas atver /proc/net/tcp, saņem piekļuves liegumu socket tabulas vietā. VPN saskarnei tas nekas: paketes joprojām ierodas, jo tunelis ir maršrutēšanas lēmums, nevis faila atļauja. Mainījās atbilde uz šaurāku jautājumu: „kura lietotne pārvalda šo savienojumu?“ Aizstājējs ir ConnectivityManager.getConnectionOwnerUid, atbalstītais vaicājums katram savienojumam, un izvēle starp veco ieradumu un jauno API ir atkarīga no tā, kurš no trim darbiem jums patiešām ir: pakešu saņemšana, plūsmas attiecināšana vai lietojuma summēšana.
Divi veidi, kā atbildēt uz īpašnieka jautājumu
Pirms API 29 priviliģēts vai root process varēja lasīt kodola socket tabulas, saskaņot četrinieku un uzzināt īpašnieka UID. Tas deva visai ierīcei kopīgu uzskaiti vienā failā. Kopš API 29 failusistēmas skats ir ierobežots, un atbalstītais ceļš ir vaicājums katram savienojumam ar protokolu, lokālo adresi un attālo adresi.
| Question | Legacy socket tables | getConnectionOwnerUid |
|---|---|---|
| Who owns this flow? | Scan and match the tuple | Ask once per tuple |
| Device-wide inventory? | Yes, when readable | No, one flow at a time |
| Historical usage? | No | No; that is NetworkStatsManager |
| Works without root? | No on modern releases | Yes, for authorized callers |
Salīdzinājums nav „vecais pret jauno“. Tie ir trīs dažādi darbi, ko agrāk apmierināja viens lasāms fails un tagad apmierina trīs dažādas saskarnes ar trim dažādiem līgumiem.
Lokālā adrese ir lietotnes gals
Metodes paraksts ņem protokolu, lokālo socket adresi un attālo socket adresi. „Lokālā“ nozīmē lietotnes pusi savienojumā, nevis to galu, kas pārbaudes brīdī nejauši ir paketes avots. Paketei, kas ceļo no attālā servera atpakaļ uz lietotni, avots un galamērķis attiecībā pret šo definīciju ir apgriezti.
ConnectivityManager cm = getSystemService(ConnectivityManager.class);
int uid = cm.getConnectionOwnerUid(
OsConstants.IPPROTO_TCP, appLocalAddress, appRemoteAddress);Šī virziena kļūda ir visbiežākais iemesls, kāpēc strādājošs vaicājums atgriež nepareizu atbildi vai nevienu. Reģistrējiet abus galus pirms izsaukuma un pārbaudiet pāri pret savienojumu, ko lietotne patiešām atvēra. Adrešu saime arī ir svarīga: IPv4 kartētā adrese un dzimtā IPv6 adrese ir dažādi četrinieki, tāpat kā TCP un UDP plūsmas tajos pašos portos.
Autorizācija un nezināmie rezultāti ir līguma daļa
Vaicājums ir ierobežots ar autorizētiem izsaucējiem, tostarp attiecīgā lietotāja aktīvo VPN lietotni. Nesaistīta uzraudzības lietotne nevar pieņemt, ka tā var uzskaitīt cita profila savienojumus, un neautorizēts izsaukums var izmest drošības izņēmumu, nevis atgriezt draudzīgu kļūdu. Apstrādājiet abus iznākumus skaidri.
Trūkstošs īpašnieks nav paketes nosaukums. Plūsma varēja tikt aizvērta starp paketi un vaicājumu, četrinieks var būt nepilnīgs, vai izsaucējam vienkārši nav atļauts zināt. Pirmās veiksmīgās atbildes kešošana un vēlāka atkārtota izmantošana piešķir jaunu savienojumu vecai lietotnei, kas ir sliktāk nekā ziņot par nezināmo.
Kad attiecināšana neizdodas, trafikam joprojām vajag lēmumu: bloķējiet to tur, kur to prasa politika, atļaujiet tikai jums saprotamu apjomu vai parādiet plaisu. Šī rezerves gaita pieder dizainam, nevis komentāram.
Uzskaite ir cits jautājums
NetworkStatsManager ziņo par lietojumu saskaņā ar saviem piekļuves noteikumiem. Tas var pateikt, cik UID pārraidīja periodā; tas nevar pateikt patvaļīgas dzīvas paketes īpašnieku. Tīkla iespējas apraksta tīkla īpašības, nevis socket katalogu. Trīs sajaukšana rada informācijas paneļus, kas izskatās konsekventi un nav.
Vienkāršajā gadījumā, kad jāizlemj, kuras lietotnes izmanto tuneli, Android atbalstītie atļauto un aizliegto lietotņu saraksti jau izsaka politiku bez jebkādas scrapēšanas. Saglabājiet attiecināšanu pa plūsmai gadījumiem, kuriem tā patiešām vajadzīga, un paredziet budžetu uzturētai ieviešanai, kas kopā apstrādā virzienu, atļaujas un nezināmos stāvokļus.
Izvēlieties rīku pēc darba, tad pārbaudiet malas
Ja prasība ir tuneļa izvēle, izmantojiet platformas sarakstu. Ja tā ir tieša attiecināšana, izmantojiet īpašnieka vaicājumu un katru neatbildēto četrinieku uzskatiet par nezināmu. Ja tās ir vēsturiskas summas, izmantojiet stats API. Pēc tam pārbaudiet trīs malas, kas salauž naivas ieviešanas: pretējā virziena paketi, plūsmu, kas aizveras pirms vaicājuma, un izsaucēju, kas nav aktīvais VPN.
Neviens no tā neprasa izslēgt SELinux, rootot tālruni vai padarīt kodola tabulas globāli lasāmas. Ierobežojums ir jēga: platforma pārcēla attiecināšanu aiz līguma, lai atbilde būtu pieejama komponentam, kuram tā likumīgi vajadzīga, un nevienam citam.