Android VPN ఆపాదన: getConnectionOwnerUid మరియు /proc/net
Android 10 యాప్ల నుండి /proc/netని దాచుతుంది. VPN ఇప్పటికీ ప్యాకెట్లను పొందుతుంది, కానీ ఆపాదన తన సొంత tuple మరియు అనుమతి నియమాలతో getConnectionOwnerUidకి మారుతుంది.
Android 10 మరియు తర్వాత, /proc/net/tcp తెరిచే యాప్కి socket పట్టికకు బదులు యాక్సెస్ నిరాకరణ లభిస్తుంది. VPN ఇంటర్ఫేస్కి అది పట్టదు: ప్యాకెట్లు ఇప్పటికీ వస్తాయి, ఎందుకంటే టన్నెల్ అనేది రూటింగ్ నిర్ణయం, ఫైల్ అనుమతి కాదు. మారినది మరింత సన్నిహిత ప్రశ్నకు సమాధానం: “ఈ కనెక్షన్ ఏ యాప్ సొంతం?” ప్రత్యామ్నాయం ConnectivityManager.getConnectionOwnerUid, ప్రతి కనెక్షన్కు మద్దతు ఉన్న ప్రశ్న, మరియు పాత అలవాటు మరియు కొత్త API మధ్య ఎంపిక మీకు నిజంగా మూడు పనులలో ఏది ఉందనే దానిపై ఆధారపడి ఉంటుంది: ప్యాకెట్లను స్వీకరించడం, ప్రవాహాన్ని ఆపాదించడం, లేదా వినియోగాన్ని కలపడం.
యజమాని ప్రశ్నకు రెండు సమాధానాలు
API 29 కి ముందు, ప్రత్యేక అధికారం ఉన్న లేదా root ప్రక్రియ kernel యొక్క socket పట్టికలను చదివి, నాలుగింటిని సరిపోల్చి, యజమాని UID తెలుసుకోగలిగేది. అది ఒకే ఫైల్లో మొత్తం పరికర జాబితాను ఇచ్చేది. API 29 నుండి ఫైల్ సిస్టమ్ వీక్షణ పరిమితం, మరియు మద్దతు ఉన్న మార్గం ప్రోటోకాల్, స్థానిక చిరునామా మరియు రిమోట్ చిరునామాతో ప్రతి కనెక్షన్కు ప్రశ్న.
| 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 |
పోలిక “పాత వర్సెస్ కొత్త” కాదు. ఇవి గతంలో ఒక చదవగలిగే ఫైల్ తీర్చిన, ఇప్పుడు మూడు వేర్వేరు ఒప్పందాలతో మూడు వేర్వేరు ఇంటర్ఫేస్లు తీర్చే మూడు వేర్వేరు పనులు.
స్థానిక చిరునామాయే యాప్ చివర
పద్ధతి సంతకం ప్రోటోకాల్, స్థానిక socket చిరునామా మరియు రిమోట్ socket చిరునామా తీసుకుంటుంది. “స్థానికం” అంటే కనెక్షన్లో యాప్ వైపు, మీరు పరిశీలించే క్షణంలో ప్యాకెట్ మూలంగా ఉన్న చివర కాదు. రిమోట్ సర్వర్ నుండి యాప్కి తిరిగి వచ్చే ప్యాకెట్ మూలం మరియు గమ్యం ఆ నిర్వచనానికి వ్యతిరేకంగా తిరగబడి ఉంటాయి.
ConnectivityManager cm = getSystemService(ConnectivityManager.class);
int uid = cm.getConnectionOwnerUid(
OsConstants.IPPROTO_TCP, appLocalAddress, appRemoteAddress);ఈ దిశా పొరపాటే పనిచేసే ప్రశ్న తప్పు సమాధానం లేదా ఏదీ ఇవ్వకపోవడానికి అత్యంత సాధారణ కారణం. కాల్కు ముందు రెండు చివరలను లాగ్ చేసి, యాప్ నిజంగా తెరిచిన కనెక్షన్తో జోడిని నిర్ధారించండి. చిరునామా కుటుంబం కూడా ముఖ్యం: IPv4 ద్వారా మ్యాప్ చేసిన చిరునామా మరియు స్థానిక IPv6 చిరునామా వేర్వేరు tuple, అదే పోర్టులపై TCP మరియు UDP ప్రవాహాలు కూడా.
అధికారం మరియు తెలియని ఫలితాలు ఒప్పందంలో భాగం
ప్రశ్న అధికారం ఉన్న కాలర్లకు మాత్రమే పరిమితం, సంబంధిత వినియోగదారు కోసం యాక్టివ్ VPN యాప్ కూడా కలిసి. సంబంధం లేని పర్యవేక్షణ యాప్ మరొక ప్రొఫైల్ కనెక్షన్లను లెక్కించగలదని ఊహించలేదు, మరియు అధికారం లేని కాల్ స్నేహపూర్వక లోపానికి బదులు భద్రతా మినహాయింపును విసరవచ్చు. రెండు ఫలితాలను స్పష్టంగా నిర్వహించండి.
లేని యజమాని ప్యాకేజీ పేరు కాదు. ప్యాకెట్ మరియు ప్రశ్న మధ్య ప్రవాహం మూసివేయబడి ఉండవచ్చు, tuple అసంపూర్ణంగా ఉండవచ్చు, లేదా కాలర్కు తెలుసుకోవడానికి అనుమతి ఉండకపోవచ్చు. మొదటి విజయవంతమైన సమాధానాన్ని కాష్ చేసి తర్వాత మళ్లీ ఉపయోగించడం కొత్త కనెక్షన్ను పాత యాప్కు ఆపాదిస్తుంది, ఇది తెలియదని నివేదించడం కంటే దారుణం.
ఆపాదన విఫలమైనప్పుడు, ట్రాఫిక్కు ఇప్పటికీ నిర్ణయం కావాలి: విధానం కోరిన చోట దాన్ని బ్లాక్ చేయండి, మీకు అర్థమయ్యే పరిధిని మాత్రమే అనుమతించండి, లేదా ఖాళీని చూపండి. ఆ ప్రత్యామ్నాయం రూపకల్పనకు చెందుతుంది, వ్యాఖ్యకు కాదు.
లెక్కింపు మరొక ప్రశ్న
NetworkStatsManager తన సొంత యాక్సెస్ నియమాల ప్రకారం వినియోగాన్ని నివేదిస్తుంది. ఒక UID ఒక కాలంలో ఎంత బదిలీ చేసిందో చెప్పగలదు; ఏదైనా సజీవ ప్యాకెట్ యజమానిని చెప్పలేదు. నెట్వర్క్ సామర్థ్యాలు నెట్వర్క్ లక్షణాలను వివరిస్తాయి, socket జాబితాను కాదు. మూడింటినీ కలపడం స్థిరంగా కనిపించే కానీ కాని డాష్బోర్డులను ఇస్తుంది.
ఏ యాప్లు టన్నెల్ ఉపయోగిస్తాయో నిర్ణయించే సులభ సందర్భానికి, Android యొక్క మద్దతు ఉన్న అనుమతించిన మరియు నిషేధించిన యాప్ జాబితాలు ఎలాంటి స్క్రాపింగ్ లేకుండానే విధానాన్ని వ్యక్తపరుస్తాయి. నిజంగా అవసరమైన సందర్భాలకు ప్రతి-ప్రవాహ ఆపాదనను కేటాయించండి, మరియు దిశ, అనుమతులు మరియు తెలియని స్థితులను కలిసి నిర్వహించే నిర్వహిత అమలుకు బడ్జెట్ పెట్టండి.
పని ప్రకారం సాధనాన్ని ఎంచుకోండి, తర్వాత అంచులను పరీక్షించండి
అవసరం టన్నెల్ ఎంపిక అయితే, ప్లాట్ఫారమ్ జాబితాను ఉపయోగించండి. ప్రత్యక్ష ఆపాదన అయితే, యజమాని ప్రశ్నను ఉపయోగించి సమాధానం రాని ప్రతి tupleని తెలియనిదిగా పరిగణించండి. చారిత్రక మొత్తాలు అయితే, stats API ఉపయోగించండి. తర్వాత సులభ అమలులను విచ్ఛిన్నం చేసే మూడు అంచులను పరీక్షించండి: వ్యతిరేక దిశ ప్యాకెట్, ప్రశ్నకు ముందు మూసుకునే ప్రవాహం, మరియు యాక్టివ్ VPN కాని కాలర్.
వీటిలో ఏదీ SELinux నిలిపివేయడం, ఫోన్ను root చేయడం లేదా kernel పట్టికలను ప్రపంచవ్యాప్తంగా చదవగలిగేలా చేయడం అవసరం లేదు. పరిమితే ముఖ్యం: ప్లాట్ఫారమ్ ఆపాదనను ఒక ఒప్పందం వెనుకకు జరిపింది, తద్వారా సమాధానం చట్టబద్ధంగా అవసరమైన భాగానికి మాత్రమే అందుతుంది, మరెవరికీ కాదు.