اجازه شبکه محلی

هر برنامه‌ای که اجازه INTERNET را داشته باشد می‌تواند به دستگاه‌های موجود در «شبکه محلی» (LAN) دسترسی پیدا کند. این کار اتصال برنامه‌ها به دستگاه‌های محلی را آسان می‌کند، اما پیامدهای حریم خصوصی نیز به‌همراه دارد، مانند تشکیل اثر انگشت کاربر و عمل کردن به‌عنوان پراکسی برای مکان.

هدف پروژه «محافظت از شبکه محلی» محافظت از حریم خصوصی کاربر ازطریق محدود کردن دسترسی به شبکه محلی با یک اجازه زمان اجرای جدید است.

تأثیر

از Android 17 (سطح ای‌پی‌آی ۳۷)، محافظت‌های شبکه محلی برای برنامه‌هایی که Android 17 یا بالاتر را هدف قرار می‌دهند اعمال می‌شود. پیکربندی موافقت کردن قبلی Android 16 منسوخ شده است؛ برای الزامات پیاده‌سازی فعلی، اجرای Android 17 را ببینید.

اگر برنامه‌ها بااستفاده از موارد زیر به شبکه محلی کاربر دسترسی پیدا کنند، تحت‌تأثیر قرار خواهند گرفت:

  • استفاده مستقیم یا کتابخانه‌ای از سوکت‌های خام در نشانی‌های شبکه محلی، برای مثال، Multicast DNS (mDNS) یا Simple Service Discovery Protocol (SSDP).
  • استفاده از کلاس‌های سطح چارچوب که به شبکه محلی دسترسی دارند، برای مثال، NsdManager.

جزئیات تأثیر

ترافیک به و از نشانی شبکه محلی به اجازه دسترسی به شبکه محلی نیاز دارد. جدول زیر برخی‌از موارد رایج را فهرست می‌کند:

عملیات شبکه سطح پایین برنامه اجازه شبکه محلی لازم است
برقراری اتصال TCP خروجی بله
پذیرفتن اتصال TCP ورودی بله
ارسال UDP تک‌پخشی، چندپخشی، همه‌فرستی بله
دریافت کردن تک‌پخش، چندپخش، یا همه‌پخش UDP ورودی بله

این محدودیت‌ها در عمق پشته شبکه پیاده‌سازی شده‌اند و بنابراین بر همه میاناهای برنامه‌سازی کاربردی شبکه اعمال می‌شوند. این شامل سوکت‌های ایجادشده در پلاتفرم یا کد مدیریت‌شده، کتابخانه‌های شبکه‌سازی مانند Cronet و OkHttp، و هر میانای برنامه‌سازی کاربردی پیاده‌سازی‌شده روی آن‌ها می‌شود. تلاش برای حل کردن سرویس‌ها در شبکه محلی که پسوند .local دارند به اجازه شبکه محلی نیاز دارد.

استثنائات قوانین قبلی:

  • اگر سرور DNS دستگاه در شبکه محلی باشد، ترافیک ورودی/خروجی آن (در درگاه ۵۳) به اجازه دسترسی به شبکه محلی نیاز ندارد.
  • برنامه‌هایی که از «تعویض‌کننده خروجی» به‌عنوان انتخاب‌گر درون‌برنامه‌ای استفاده می‌کنند به اجازه‌های شبکه محلی نیاز نخواهند داشت (راهنمایی‌های بیشتر در نسخه‌های بعدی ارائه خواهد شد).

اجرای Android 17

از Android 17، محافظت‌های شبکه محلی برای برنامه‌هایی که Android 17 یا بالاتر را هدف قرار می‌دهند اجباری و الزامی است.

نسبت ابعادی ‫Android 16 ‫Android 17
SDK هدف 36 ۳۷ یا بالاتر
اجازه به‌طور موقت از NEARBY_WIFI_DEVICES استفاده کرد ACCESS_LOCAL_NETWORK
دسترسی پیش‌فرض دسترسی به شبکه محلی باز است شبکه محلی به‌طور پیش‌فرض برای همه برنامه‌هایی که کیت توسعه نرم‌افزار هدفشان را به‌روز می‌کنند مسدود است
گروه اجازه بخشی از گروه اجازه NEARBY_DEVICES موجود

برای تأیید اینکه عملکرد برنامه پس‌از اجرا شدن خط‌مشی مختل نمی‌شود، برنامه‌هایی که کیت توسعه نرم‌افزار ۳۷ یا بالاتر را هدف قرار می‌دهند باید یکی از مسیرهای زیر را برای مدیریت دسترسی به شبکه محلی اتخاذ کنند:

مسیر الف: استفاده از انتخابگرهای حافظ حریم خصوصی

برای کارهای کاوش و اتصال با واسطه سیستم، از انتخاب‌گرها استفاده کنید تا از درخواست اجازه زمان اجرای گسترده به‌طور کامل اجتناب کنید. براساس مورد استفاده‌تان، از انتخابگرهای زیر استفاده کنید:

  • جاری‌سازی رسانه: برای برنامه‌هایی که از 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
    }
})

مسیر ب: درخواست اجازه زمان اجرا (دسترسی گسترده)

این مسیر برای موارد استفاده پیچیده مانند خودکارسازی خانه یا مدیریت دستگاه اینترنت اشیاء که به دسترسی گسترده و مداوم به شبکه محلی نیاز دارند، ضروری است.

  • اعلام اجازه در مانیفست: ACCESS_LOCAL_NETWORK را به‌طور صریح در AndroidManifest.xml اعلام کنید.

  • درخواست اجازه در زمان اجرا: پیش‌از تلاش برای دسترسی به شبکه محلی، برنامه‌ها باید بررسی کنند که آیا اجازه اعطا شده است یا نه. اگر نه، باید با Activity.requestPermission() تماس بگیرند تا پیام‌واره استاندارد سیستم را فعال کنند.

  • سناریو ازپیش اعطاشده: اجازه ACCESS_LOCAL_NETWORK بخشی از گروه اجازه NEARBY_DEVICES است. اگر کاربر قبلاً اجازه دیگری را در این گروه (مثل اجازه‌های بلوتوث) اعطا کرده باشد، دیگر برای دسترسی به شبکه محلی از او درخواست نخواهد شد.

  • رسیدگی به رد کردن و لغو کردن: برنامه‌ها باید به‌درستی مواردی را که کاربر درخواست را رد می‌کند یا بعداً اجازه را در تنظیمات سیستم لغو می‌کند مدیریت کنند. در چنین سناریوهایی، ترافیک شبکه محلی مسدود خواهد شد.

استراتژی شمارنده بازنشانی درخواست اجازه

این پلتفرم استراتژی بازنشانی شمارنده را اجرا می‌کند که به سناریوهایی می‌پردازد که در آن رد قبلی گروه اجازه NEARBY_DEVICES توسط برنامه (که اکنون شامل ACCESS_LOCAL_NETWORK می‌شود) مانع از درخواست برنامه برای اجازه پس‌از ارائه کافی منطق آن شده است. این سازوکار فرصت‌های بیشتری به برنامه می‌دهد تا میانای برنامه‌سازی کاربردی requestPermission() را فراخوانی کند و به‌طور مؤثری تعداد دفعات رد کردن را برای اجازه ACCESS_LOCAL_NETWORK بازنشانی می‌کند. این کار امکان تعامل مجدد دقیق‌تر با کاربر را فراهم می‌کند، به‌ویژه زمانی که رد اولیه قبل‌از اینکه برنامه بتواند ضرورت دسترسی به شبکه محلی را برای عملکرد اصلی خود منتقل کند، رخ داده باشد.

مدل اجازه تقسیم‌شده

«اجازه شبکه محلی» از استراتژی انتقال اجازه تقسیم‌شده استفاده می‌کند تا با برنامه‌های جدید و قدیمی به‌طور متفاوت و براساس کیت توسعه نرم‌افزار هدف آن‌ها رفتار کند

دسته سطح کیت توسعه نرم‌افزار هدف رفتار دسترسی به شبکه محلی اقدام لازم ازسوی توسعه‌دهنده
برنامه‌های جدید / برنامه‌های به‌روزشده >= 37 (Android 17) مسدودشده به‌طور پیش‌فرض اعلام و درخواست اجازه زمان اجرای ACCESS_LOCAL_NETWORK
برنامه‌های قدیمی < ۳۷ برنامه‌هایی که اجازه INTERNET دارند، اجازه ضمنی برای ACCESS_LOCAL_NETWORK دریافت می‌کنند که به آن‌ها امکان می‌دهد دسترسی را حفظ کنند. این موقتی است و وقتی برنامه کیت توسعه نرم‌افزار هدف را به ۳۷ ارتقا دهد، به‌طور پیش‌فرض مسدود خواهد شد نیازی به تغییر فوری کد نیست. پیش‌از هدف‌یابی کیت توسعه نرم‌افزار ۳۷، ACCESS_LOCAL_NETWORK را در زمان اجرا درخواست نکنید.

استراتژی LNP براساس کاربرد

  • ارسال محتوا: برای عملکردهای ارسال محتوا، مناسب‌ترین و حفظ‌کننده‌ترین استراتژی حریم خصوصی استفاده از تعویض‌کننده خروجی است. این روش به سیستم اجازه می‌دهد کاوش و اتصال شبکه محلی را ازطرف کاربر مدیریت کند و نیاز برنامه به درخواست اجازه ACCESS_LOCAL_NETWORK را ازبین می‌برد.

  • مرورگرها: رسیدگی به خطاها براساس پروتکل به رویکردهای متفاوتی نیاز دارد. خطاهای UDP منجر به کد خطای EPERM می‌شود. برای اتصال‌های TCP، مرورگرها باید از NDK API android_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 نیاز ندارد.

برای برنامه‌هایی که به ارتباط مستقیم شبکه محلی نیاز دارند و نمی‌توانند از انتخاب‌گرهای با واسطه سیستم استفاده کنند، رویکرد پیشنهادی این است که هنگام هدف قرار دادن Android 17 (SDK 37) یا بالاتر، از استراتژی شمارنده بازنشانی اجازه استفاده کنند. اگر کاربر اجازه ACCESS_LOCAL_NETWORK را لغو کند، این سازوکار فرصت‌های بیشتری برای برنامه فراهم می‌کند تا دوباره اجازه را درخواست کند، و به توسعه‌دهندگان امکان می‌دهد دلیل واضح‌تری برای کاربر ارائه دهند.

راهنمای Android 16 (منسوخ‌شده)

برای موافقت با محدودیت‌های شبکه محلی در Android 16، کارهای زیر را انجام دهید:

  1. دستگاهتان را به ساخت Android 16 Beta 3 یا جدیدتر فلش کنید
  2. برنامه موردنظر را برای آزمایش نصب کنید
  3. بااستفاده از adb، پیکربندی Appcompat را تغییر دهید

    adb shell am compat enable RESTRICT_LOCAL_NETWORK <package_name>
    
  4. بازراه‌اندازی دستگاه

اکنون دسترسی برنامه‌تان به شبکه محلی محدود شده است و هرگونه تلاش برای دسترسی به شبکه محلی منجر به خطای سوکت می‌شود. اگر از میاناهای برنامه‌سازی کاربردی‌ای استفاده می‌کنید که عملیات شبکه محلی را خارج از فرایند برنامه‌تان انجام می‌دهند (برای مثال، NsdManager)، این میاناهای برنامه‌سازی کاربردی درطول موافقت کردن تحت‌تأثیر قرار نمی‌گیرند.

برای بازیابی دسترسی، باید به برنامه‌تان اجازه دهید به NEARBY_WIFI_DEVICES دسترسی داشته باشد.

  • مطمئن شوید برنامه اجازه NEARBY_WIFI_DEVICES را در manifest خود اعلام کرده باشد.
  • به تنظیمات > برنامه‌ها > [نام برنامه] > اجازه‌ها > دستگاه‌های اطراف > مجاز کردن بروید

اکنون دسترسی برنامه‌تان به شبکه محلی باید بازیابی شده باشد و همه سناریوهایتان باید مثل قبل‌از انتخاب برنامه کار کنند. تأثیر آن بر ترافیک شبکه برنامه در اینجا آمده است.

اجازه درخواست LAN برون‌سو درخواست اینترنت خروجی/ورودی درخواست LAN ورودی
اعطا شد Works Works Works
اعطا نشده است شکست‌ها Works شکست‌ها

از فرمان زیر برای خاموش کردن پیکربندی Appcompat استفاده کنید

adb shell am compat disable RESTRICT_LOCAL_NETWORK <package_name>

خطاها

اگر درخواست دسترسی به شبکه محلی به‌دلیل نداشتن اجازه ناموفق باشد:

  • اتصال‌های TCP معمولاً به خطای اتمام مهلت منجر می‌شوند.

    تعیین کرد
  • خطاهای UDP و رد اجازه‌های عمومی معمولاً منجر به کد خطای EPERM می‌شود

اشکالات

ارسال اشکالات و بازخورد برای:

  • اختلاف در دسترسی به LAN (فکر می‌کنید دسترسی خاصی نباید دسترسی به «شبکه محلی» درنظر گرفته شود)
  • اشکالاتی که در آن‌ها دسترسی به LAN باید مسدود شود اما نمی‌شود
  • اشکالاتی که در آن‌ها دسترسی به LAN نباید مسدود شود اما مسدود می‌شود

موارد زیر نباید تحت تأثیر این تغییر قرار بگیرند:

  • دسترسی به اینترنت
  • شبکه تلفن همراه