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 तालिका विश्वव्यापी रूपमा पढ्न मिल्ने बनाउन माग गर्दैन। सीमा नै मुख्य कुरा हो: प्लेटफर्मले एट्रिब्युसनलाई करारपछाडि सार्यो ताकि उत्तर वैध रूपमा आवश्यक पर्ने घटकलाई मात्र उपलब्ध होस्, अरू कसैलाई होइन।