Android 10:ssä ja uudemmissa sovellus, joka avaa /proc/net/tcp, saa pääsykieltäytymisen socket-taulun sijaan. VPN-rajapintaa se ei haittaa: paketit saapuvat yhä, koska tunneli on reitityspäätös, ei tiedostolupa. Muuttui vastaus kapeampaan kysymykseen: ”mikä sovellus omistaa tämän yhteyden?” Korvaaja on ConnectivityManager.getConnectionOwnerUid, tuettu yhteyskohtainen kysely, ja valinta vanhan tavan ja uuden API:n välillä riippuu siitä, mikä kolmesta tehtävästä sinulla todella on: pakettien vastaanotto, vuon attribuutio vai käytön summaus.

Kaksi tapaa vastata omistajakysymykseen

Ennen API 29:tä etuoikeutettu tai root-prosessi saattoi lukea ytimen socket-tauluja, sovittaa nelikon ja selvittää omistavan UID:n. Se antoi koko laitteen kattavan luettelon yhdessä tiedostossa. API 29:stä lähtien tiedostojärjestelmän näkymä on rajoitettu, ja tuettu reitti on yhteyskohtainen kysely, jossa on protokolla, paikallinen osoite ja etäosoite.

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

Vertailu ei ole ”vanha vastaan uusi”. Kyse on kolmesta eri tehtävästä, jotka ennen hoiti yksi luettava tiedosto ja nyt hoitaa kolme eri rajapintaa kolmella eri sopimuksella.

Paikallinen osoite on sovelluksen pää

Metodin allekirjoitus ottaa protokollan, paikallisen socket-osoitteen ja etä-socket-osoitteen. ”Paikallinen” tarkoittaa yhteyden sovelluksen puolta, ei sitä päätä, joka tarkastushetkellä sattuu olemaan paketin lähde. Etäpalvelimelta takaisin sovellukseen matkaavan paketin lähde ja kohde ovat käänteiset suhteessa tähän määritelmään.

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

Tämä suuntavirhe on yleisin syy siihen, että toimiva kysely palauttaa väärän vastauksen tai ei mitään. Kirjaa molemmat päät ennen kutsua ja varmista pari sitä yhteyttä vasten, jonka sovellus todella avasi. Osoiteperheellä on myös merkitystä: IPv4:n kautta kartoitettu osoite ja natiivi IPv6-osoite ovat eri nelikoita, samoin kuin TCP- ja UDP-vuot samoilla porteilla.

Valtuutus ja tuntemattomat tulokset ovat osa sopimusta

Kysely on rajattu valtuutettuihin kutsujiin, mukaan lukien kyseisen käyttäjän aktiivinen VPN-sovellus. Asiaankuulumaton valvontasovellus ei voi olettaa voivansa luetella toisen profiilin yhteyksiä, ja valtuuttamaton kutsu voi heittää tietoturvapoikkeuksen ystävällisen virheen sijaan. Käsittele molemmat tulokset eksplisiittisesti.

Puuttuva omistaja ei ole paketin nimi. Vuon on voinut sulkeutua paketin ja kyselyn välillä, nelikko voi olla puutteellinen tai kutsujalla ei yksinkertaisesti ole lupaa tietää. Ensimmäisen onnistuneen vastauksen välimuistiin tallentaminen ja myöhempi uudelleenkäyttö kohdistaa uuden yhteyden vanhaan sovellukseen, mikä on pahempaa kuin tuntemattoman ilmoittaminen.

Kun attribuutio epäonnistuu, liikenne tarvitsee silti päätöksen: estä se siellä, missä käytäntö vaatii, salli vain ymmärtämäsi laajuus tai tuo aukko näkyviin. Tämä varareitti kuuluu suunnitteluun, ei kommenttiin.

Kirjanpito on eri kysymys

NetworkStatsManager raportoi käytön omien käyttöoikeussääntöjensä mukaan. Se voi kertoa, paljonko UID siirsi jakson aikana; se ei voi kertoa mielivaltaisen elävän paketin omistajaa. Verkon ominaisuudet kuvaavat verkon piirteitä, eivät socket-luetteloa. Kolmen sekoittaminen tuottaa kojelautoja, jotka näyttävät johdonmukaisilta eivätkä ole.

Yksinkertaisessa tapauksessa, jossa päätetään mitkä sovellukset käyttävät tunnelia, Androidin tuetut sallittujen ja kiellettyjen sovellusten luettelot ilmaisevat käytännön jo ilman mitään scrapingia. Säästä vuokohtainen attribuutio tapauksille, jotka sitä todella tarvitsevat, ja varaa budjetti ylläpidettävälle toteutukselle, joka käsittelee suunnan, käyttöoikeudet ja tuntemattomat tilat yhdessä.

Valitse työkalu tehtävän mukaan ja testaa sitten reunat

Jos vaatimus on tunnelin valinta, käytä alustan luetteloa. Jos kyse on live-attribuutiosta, käytä omistajakyselyä ja kohtele jokaista vastaamatonta nelikkoa tuntemattomana. Jos kyse on historiallisista summista, käytä stats-API:a. Testaa sitten kolme reunaa, jotka rikkovat naiivit toteutukset: vastakkaiseen suuntaan kulkeva paketti, ennen kyselyä sulkeutuva vuo ja kutsuja, joka ei ole aktiivinen VPN.

Mikään tästä ei vaadi SELinuxin poistamista käytöstä, puhelimen roottaamista tai ytimen taulujen tekemistä maailmanlaajuisesti luettaviksi. Rajoitus on koko pointti: alusta siirsi attribuution sopimuksen taakse, jotta vastaus on saatavilla komponentille, joka sitä laillisesti tarvitsee, eikä kenellekään muulle.

Aiheeseen liittyvät artikkelit