دستگاههای موجود در یک شبکه محلی (LAN) میتوانند توسط هر برنامهای که مجوز INTERNET دارد، قابل دسترسی باشند. این امر اتصال برنامهها به دستگاههای محلی را آسان میکند، اما پیامدهای حریم خصوصی مانند تشکیل اثر انگشت کاربر و تبدیل شدن به یک پروکسی برای موقعیت مکانی را نیز به همراه دارد.
پروژه حفاظت از شبکههای محلی (Local Network Protections) با هدف محافظت از حریم خصوصی کاربر، دسترسی به شبکه محلی را با مجوز زمان اجرا (runtime permission) جدیدی مسدود میکند.
تأثیر
در اندروید ۱۶، این مجوز یک ویژگی اختیاری است، به این معنی که فقط برنامههایی که این ویژگی را انتخاب کردهاند تحت تأثیر قرار میگیرند. هدف از این قابلیت این است که توسعهدهندگان برنامه بفهمند کدام بخشهای برنامهشان به دسترسی ضمنی به شبکه محلی نیاز دارد تا بتوانند برای محافظت از دسترسیها در نسخههای بعدی اندروید آماده شوند.
اگر برنامهها با استفاده از روشهای زیر به شبکه محلی کاربر دسترسی پیدا کنند، تحت تأثیر قرار خواهند گرفت:
- استفاده مستقیم یا کتابخانهای از سوکتهای خام روی آدرسهای شبکه محلی، برای مثال،
Multicast DNS (mDNS)یاSimple Service Discovery Protocol (SSDP). - استفاده از کلاسهای سطح چارچوب که به شبکه محلی دسترسی دارند، برای مثال،
NsdManager.
جزئیات تأثیر
ترافیک ورودی و خروجی از یک آدرس شبکه محلی نیاز به مجوز دسترسی به شبکه محلی دارد. جدول زیر برخی از موارد رایج را فهرست میکند:
| عملیات شبکه سطح پایین برنامه | مجوز شبکه محلی مورد نیاز است |
|---|---|
| ایجاد یک اتصال TCP خروجی | بله |
| پذیرش یک اتصال TCP ورودی | بله |
| ارسال UDP به صورت تک پخشی، چندپخشی، پخش همگانی | بله |
| دریافت یک UDP ورودی به صورت تک پخشی، چندپخشی، پخش همگانی | بله |
این محدودیتها در اعماق پشته شبکه پیادهسازی شدهاند و بنابراین بر همه APIهای شبکه اعمال میشوند. این شامل سوکتهای ایجاد شده در پلتفرم یا کد مدیریتشده، کتابخانههای شبکه مانند Cronet و OkHttp و هر API پیادهسازی شده بر روی آنها میشود. تلاش برای حل سرویسهایی در شبکه محلی که پسوند .local دارند، نیاز به مجوز شبکه محلی دارد.
استثنائات قوانین قبلی:
- اگر سرور DNS یک دستگاه در یک شبکه محلی باشد، ترافیک به/از آن (در پورت ۵۳) نیازی به مجوز دسترسی به شبکه محلی ندارد.
- برنامههایی که از Output Switcher به عنوان انتخابگر درونبرنامهای خود استفاده میکنند، به مجوزهای شبکه محلی نیاز نخواهند داشت (راهنمایی بیشتر در نسخه بعدی ارائه خواهد شد).
اجرای اندروید ۱۷
از اندروید ۱۷ به بعد، محافظت از شبکههای محلی برای برنامههایی که اندروید ۱۷ یا بالاتر را هدف قرار میدهند، اجباری و الزامی است.
| جنبه | اندروید ۱۶ | اندروید ۱۷ |
|---|---|---|
| کیت توسعه نرمافزاری هدف | ۳۶ | ۳۷ یا بالاتر |
| اجازه | موقتاً استفاده شده NEARBY_WIFI_DEVICES | شبکه محلی دسترسی |
| دسترسی پیشفرض | دسترسی به شبکه محلی باز است | شبکه محلی به طور پیشفرض برای همه برنامههایی که SDK هدف خود را بهروزرسانی میکنند، مسدود شده است. |
| گروه مجوزها | بخشی از گروه مجوز NEARBY_DEVICES موجود |
برای تأیید اینکه عملکرد برنامه پس از اعمال محدودیتها مختل نشده است، برنامههایی که SDK 37 یا بالاتر را هدف قرار میدهند باید یکی از مسیرهای زیر را برای مدیریت دسترسی به شبکه محلی اتخاذ کنند:
مسیر الف: استفاده از انتخابگرهای حافظ حریم خصوصی
برای وظایف کشف و اتصال با واسطه سیستم، از انتخابگرها استفاده کنید تا از درخواست کامل مجوزهای گسترده زمان اجرا جلوگیری شود. از انتخابگرهای زیر بر اساس مورد استفاده خود استفاده کنید:
- پخش رسانه: برنامههایی که از Google Cast پشتیبانی میکنند، میتوانند از ویژگی سوئیچر خروجی استفاده کنند. این قابلیت به توسعهدهندگان امکان میدهد تا به کاربران اجازه دهند دستگاههای پخش خاص را انتخاب کنند، بدون اینکه برنامه نیاز به درخواست مجوز گسترده
ACCESS_LOCAL_NETWORKداشته باشد. - اتصال عمومی:
NsdManagerشامل یک انتخابگر سرویس سیستمی برای کشف mDNS است. به جای اینکه برنامه کل شبکه را اسکن کند، سیستم یک پنجره محاورهای نمایش میدهد که به کاربر اجازه میدهد یک دستگاه واحد را برای دسترسی برنامه انتخاب کند.
val discoveryRequest = DiscoveryRequest.Builder("_http._tcp")
.setFlags(DiscoveryRequest.FLAG_SHOW_PICKER)
.build()
nsdManager.registerServiceInfoCallback(discoveryRequest, executor, object : NsdManager.ServiceInfoCallback {
override fun onServiceUpdated(serviceInfo: NsdServiceInfo) {
// Handle the user-selected and discovered service
// NsdServiceInfo.getHostAddresses() can now be connected to
// without ACCESS_LOCAL_NETWORK permission
}
})
مسیر B: درخواست مجوز زمان اجرا (دسترسی گسترده)
این مسیر برای موارد استفاده پیچیده مانند اتوماسیون خانگی یا مدیریت دستگاههای اینترنت اشیا که نیاز به دسترسی گسترده و مداوم به شبکه محلی دارند، مورد نیاز است.
اعلام مجوز در Manifest: توسعهدهندگان باید صراحتاً
ACCESS_LOCAL_NETWORKدرAndroidManifest.xmlاعلام کنند.درخواست مجوز در زمان اجرا: قبل از هرگونه تلاش برای دسترسی به شبکه محلی، برنامهها باید بررسی کنند که آیا مجوز اعطا شده است یا خیر. در غیر این صورت، آنها باید
Activity.requestPermission()را برای فعال کردن اعلان استاندارد سیستم فراخوانی کنند.سناریوی از پیش اعطا شده: مجوز
ACCESS_LOCAL_NETWORKبخشی از گروه مجوزهایNEARBY_DEVICESاست. اگر کاربری قبلاً مجوز دیگری را در این گروه اعطا کرده باشد (مانند مجوزهای بلوتوث)، برای دسترسی به شبکه محلی مجدداً از او درخواست نخواهد شد.مدیریت رد درخواست و لغو آن: برنامهها باید مواردی را که کاربر درخواست را رد میکند یا بعداً در تنظیمات سیستم مجوز را لغو میکند، به درستی مدیریت کنند. در چنین سناریوهایی، ترافیک شبکه محلی مسدود خواهد شد.
درخواست مجوز، استراتژی شمارندهی بازنشانی
این پلتفرم یک استراتژی تنظیم مجدد شمارنده را پیادهسازی میکند که به سناریوهایی میپردازد که در آنها رد قبلی گروه مجوز NEARBY_DEVICES توسط یک برنامه (که اکنون شامل ACCESS_LOCAL_NETWORK میشود) مانع از درخواست مجوز توسط برنامه پس از ارائه منطقی آن شده است. این مکانیسم فرصتهای بیشتری را برای برنامه فراهم میکند تا API requestPermission() را فراخوانی کند و به طور مؤثر تعداد رد مجوز برای مجوز ACCESS_LOCAL_NETWORK را بازنشانی کند. این امر امکان تعامل مجدد ظریفتری را با کاربر فراهم میکند، به خصوص زمانی که رد اولیه قبل از اینکه برنامه بتواند ضرورت دسترسی به شبکه محلی را برای عملکرد اصلی خود بیان کند، رخ داده است.
مدل مجوز تقسیمشده
مجوزهای شبکه محلی از یک استراتژی مهاجرت مجوزهای تقسیمشده برای مدیریت متفاوت برنامههای جدید و قدیمی، بر اساس SDK هدف آنها، استفاده میکند.
| دسته بندی | سطح SDK هدف | رفتار دسترسی به شبکه محلی | اقدام مورد نیاز توسعهدهنده |
|---|---|---|---|
| برنامههای جدید / برنامههای بهروز شده | >= 37 (اندروید 17) | مسدود شده به طور پیشفرض | اعلام و درخواست مجوز زمان اجرای ACCESS_LOCAL_NETWORK |
| برنامههای قدیمی | < 37 | برنامههایی که دارای مجوز اینترنت هستند، یک مجوز ضمنی برای ACCESS_LOCAL_NETWORK دریافت میکنند که به آنها اجازه میدهد دسترسی خود را حفظ کنند. این مجوز موقتی است و به محض اینکه SDK هدف برنامه به ۳۷ برسد، به طور پیشفرض مسدود خواهد شد. | بدون نیاز به تغییر فوری کد |
استراتژی LNP بر اساس مورد استفاده
پخش: برای قابلیتهای پخش رسانه، مناسبترین و با حفظ حریم خصوصیترین استراتژی، استفاده از سوئیچر خروجی است. این روش به سیستم اجازه میدهد تا کشف و اتصال شبکه محلی را از طرف کاربر مدیریت کند و نیاز به درخواست مجوز
ACCESS_LOCAL_NETWORKتوسط برنامه را از بین میبرد.مرورگرها: مدیریت خطاها بسته به پروتکل، رویکردهای متفاوتی را میطلبد. خطاهای UDP منجر به کد خطای
EPERMمیشوند. برای اتصالات TCP، مرورگرها باید از API NDKandroid_getnetworkblockedreason(int sockFd)استفاده کنند تا مشخص شود که آیا یک بسته توسط LNP مسدود شده است یا خیر. این API مقدارANDROID_NETWORK_BLOCKED_REASON_LNPرا برمیگرداند.موارد استفاده دیگر (برای مثال، اینترنت اشیا): برنامههایی که دستگاههایی را با استفاده از mDNS پیدا میکنند، باید از
android.net.nsd.DiscoveryRequest#FLAG_SHOW_PICKERکه امکان یافتن دستگاهها بدون مجوز را فراهم میکند، وNsdManager#registerServiceInfoCallback/NsdManager#resolveServiceبرای دریافت آدرسهای IP استفاده کنند. اتصال به آدرسهای IP که از این طریق به دست میآیند، نیازی به مجوزACCESS_LOCAL_NETWORKندارند.
برای برنامههایی که نیاز به ارتباط مستقیم شبکه محلی دارند و نمیتوانند از انتخابگرهای سیستمی استفاده کنند، رویکرد پیشنهادی استفاده از استراتژی شمارنده تنظیم مجدد مجوز است. اگر مجوز ACCESS_LOCAL_NETWORK توسط کاربر لغو شود، این مکانیسم فرصتهای بیشتری را برای برنامه فراهم میکند تا دوباره درخواست مجوز کند و به توسعهدهندگان اجازه میدهد تا دلیل واضحتری را برای کاربر ارائه دهند.
راهنمایی اندروید ۱۶
برای اعمال محدودیتهای شبکه محلی، موارد زیر را انجام دهید:
- دستگاه خود را به نسخهای با اندروید ۱۶ بتا ۳ یا بالاتر فلش کنید.
- برنامه را برای آزمایش نصب کنید
با استفاده از adb، تنظیمات Appcompat را تغییر دهید.
adb shell am compat enable RESTRICT_LOCAL_NETWORK <package_name>دستگاه را دوباره راه اندازی کنید
اکنون دسترسی برنامه شما به شبکه محلی محدود شده است و هرگونه تلاشی برای دسترسی به شبکه محلی منجر به خطاهای سوکت میشود. اگر از APIهایی استفاده میکنید که عملیات شبکه محلی را خارج از فرآیند برنامه شما انجام میدهند (به عنوان مثال، NsdManager )، در طول فرآیند opt-in تحت تأثیر قرار نمیگیرند.
برای بازیابی دسترسی، باید به برنامه خود اجازه دسترسی به NEARBY_WIFI_DEVICES را بدهید.
- مطمئن شوید که برنامه مجوز
NEARBY_WIFI_DEVICESرا درmanifestخود اعلام کرده است. - به تنظیمات > برنامهها > [نام برنامه] > مجوزها > دستگاههای نزدیک > اجازه دادن بروید
اکنون دسترسی برنامه شما به شبکه محلی باید بازیابی شده باشد و تمام سناریوهای شما باید مانند قبل از انتخاب برنامه کار کنند. در اینجا نحوه تأثیر ترافیک شبکه برنامه آمده است.
| اجازه | درخواست شبکه محلی خروجی | درخواست اینترنت خروجی/ورودی | درخواست شبکه محلی ورودی |
|---|---|---|---|
| اعطا شده | آثار | آثار | آثار |
| اعطا نشده | شکستها | آثار | شکستها |
برای غیرفعال کردن پیکربندی Appcompat از دستور زیر استفاده کنید.
adb shell am compat disable RESTRICT_LOCAL_NETWORK <package_name>
خطاها
اگر درخواست دسترسی به شبکه محلی به دلیل عدم دسترسی رد شد:
اتصالات TCP معمولاً منجر به خطای timeout میشوند.
خطاهای UDP و رد مجوزهای عمومی معمولاً منجر به کد خطای EPERM میشوند.
اشکالات
ارسال اشکالات و بازخورد برای:
- اختلاف در دسترسی به شبکه محلی (فکر نمیکنید که یک دسترسی خاص باید به عنوان دسترسی به "شبکه محلی" در نظر گرفته شود)
- اشکالاتی که در آنها دسترسی به شبکه محلی باید مسدود شود اما این کار را نمیکند
- اشکالاتی که در آنها دسترسی به شبکه محلی نباید مسدود شود، اما مسدود شده است
موارد زیر نباید تحت تأثیر این تغییر قرار گیرند:
- دسترسی به اینترنت
- شبکه تلفن همراه