Yerel ağ izni

Yerel ağdaki (LAN) cihazlara, INTERNET iznine sahip tüm uygulamalar erişebilir. Bu sayede uygulamalar yerel cihazlara kolayca bağlanabilir ancak kullanıcının parmak izini oluşturma ve konum için proxy görevi görme gibi gizlilikle ilgili sonuçları da vardır.

Yerel Ağ Korumaları projesi, yerel ağa erişimi yeni bir çalışma zamanında istenen izinle kısıtlayarak kullanıcı gizliliğini korumayı amaçlar.

Etki

Android 17'den (API düzeyi 37) itibaren, Android 17 veya sonraki sürümleri hedefleyen uygulamalar için yerel ağ korumaları uygulanır. Önceki Android 16 etkinleştirme yapılandırması kullanımdan kaldırıldı. Mevcut uygulama şartları için Android 17 Yaptırımı başlıklı makaleyi inceleyin.

Kullanıcının yerel ağına aşağıdaki yöntemlerle erişen uygulamalar etkilenir:

  • Yerel ağ adreslerinde ham soketlerin doğrudan veya kitaplık kullanımı (ör. Multicast DNS (mDNS) veya Simple Service Discovery Protocol (SSDP)).
  • Yerel ağa erişen çerçeve düzeyindeki sınıfların (ör. NsdManager) kullanımı.

Etkiyle ilgili ayrıntılar

Yerel ağ adresine giden ve bu adresten gelen trafik için yerel ağ erişim izni gerekir. Aşağıdaki tabloda bazı yaygın durumlar listelenmiştir:

Uygulama Düşük Seviyeli Ağ İşlemi Yerel Ağ İzni Gerekli
Giden TCP bağlantısı oluşturma evet
Gelen TCP bağlantısını kabul etme evet
UDP tek noktaya yayın, çok noktaya yayın, genel yayın gönderme evet
Gelen UDP tek noktaya yayın, çok noktaya yayın, yayın alma evet

Bu kısıtlamalar ağ yığınının derinliklerinde uygulandığından tüm ağ API'leri için geçerlidir. Buna platformda veya yönetilen kodda oluşturulan soketler, Cronet ve OkHttp gibi ağ kitaplıkları ve bunların üzerine uygulanan tüm API'ler dahildir. Yerel ağda .local son ekine sahip hizmetleri çözmeye çalışmak için yerel ağ izni gerekir.

Yukarıdaki kuralların istisnaları:

  • Bir cihazın DNS sunucusu yerel ağdaysa bu sunucuya giden/sunucudan gelen trafik (53 numaralı bağlantı noktasında) için yerel ağ erişim izni gerekmez.
  • Uygulama içi seçici olarak çıkış değiştiriciyi kullanan uygulamaların yerel ağ izinlerine ihtiyacı olmaz (Daha fazla bilgi sonraki sürümlerde paylaşılacaktır).

Android 17 Yaptırımı

Android 17'den itibaren, Android 17 veya sonraki sürümleri hedefleyen uygulamalar için yerel ağ korumaları zorunlu hale getirilmiştir.

En Boy Oranı Android 16 Android 17
Hedef SDK 36 37 veya daha yüksek
İzin NEARBY_WIFI_DEVICES geçici olarak kullanıldı ACCESS_LOCAL_NETWORK
Varsayılan Erişim Yerel ağ erişimi açık Hedef SDK'larını güncelleyen tüm uygulamalar için yerel ağ varsayılan olarak engellenir.
İzin Grubu Mevcut NEARBY_DEVICES izin grubunun bir parçasıdır.

Uygulama işlevselliğinin yaptırımdan sonra bozulmadığını doğrulamak için SDK 37 veya sonraki sürümleri hedefleyen uygulamaların, yerel ağ erişimini yönetmek için aşağıdaki yollardan birini benimsemesi gerekir:

A yolu: Gizliliği korumaya yönelik seçicileri kullanma

Sistem aracılı keşif ve bağlantı görevleri için seçicileri kullanarak çalışma zamanında istenen geniş kapsamlı izni tamamen istemekten kaçının. Kullanım alanınıza göre aşağıdaki seçicileri kullanın:

  • Medya yayını: Google Cast'i destekleyen uygulamalarda çıkış değiştirici özelliği kullanılabilir. Bu sayede geliştiriciler, uygulamanın geniş kapsamlı ACCESS_LOCAL_NETWORK izni istemesine gerek kalmadan kullanıcıların belirli aktarım cihazlarını seçmesine izin verebilir.
  • Genel Bağlantı: NsdManager, mDNS keşfi için sistem tarafından çalıştırılan bir hizmet seçici içerir. Uygulama tüm ağı taramak yerine, kullanıcının uygulamanın erişebileceği tek bir cihaz seçmesine olanak tanıyan bir iletişim kutusu gösterir.
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 yolu: Çalışma zamanında istenen izin (geniş erişim) isteme

Bu yol, yerel ağa geniş ve kalıcı erişim gerektiren ev otomasyonu veya IoT cihaz yönetimi gibi karmaşık kullanım alanları için gereklidir.

  • İzni manifest dosyasında beyan edin: AndroidManifest.xml içinde ACCESS_LOCAL_NETWORK iznini açıkça beyan edin.

  • Çalışma zamanında izin isteme: Uygulamalar, yerel ağ erişimi denemeden önce iznin verilip verilmediğini kontrol etmelidir. Aksi takdirde, standart sistem istemini tetiklemek için Activity.requestPermission() yöntemini çağırmaları gerekir.

  • Önceden verilmiş izin senaryosu: ACCESS_LOCAL_NETWORK izni, NEARBY_DEVICES izin grubunun bir parçasıdır. Kullanıcı bu grupta başka bir izin (ör. Bluetooth izinleri) verdiyse yerel ağ erişimi için tekrar istem gösterilmez.

  • Reddetme ve İptal Etme İşlemlerini Yönetme: Uygulamalar, kullanıcının isteği reddettiği veya daha sonra sistem ayarlarında izni iptal ettiği durumları kontrollü bir şekilde yönetmelidir. Bu tür senaryolarda yerel ağ trafiği engellenir.

İzin isteği sıfırlama sayacı stratejisi

Platform, bir uygulamanın NEARBY_DEVICES izin grubunu (artık ACCESS_LOCAL_NETWORK iznini de içerir) daha önce reddetmesi nedeniyle, gerekçesini yeterli şekilde sunduktan sonra izin istemesinin engellendiği senaryoları ele alan bir sayaç sıfırlama stratejisi uygular. Bu mekanizma, uygulamanın requestPermission() API'sini çağırması için ek fırsatlar sunarak ACCESS_LOCAL_NETWORK izni için ret sayısını etkili bir şekilde sıfırlar. Bu sayede, özellikle ilk ret işlemi uygulama temel işlevi için yerel ağ erişiminin gerekliliğini iletmeden önce gerçekleştiğinde kullanıcıyla daha ayrıntılı bir şekilde yeniden etkileşim kurulabilir.

Bölünmüş izin modeli

Yerel ağ izni, yeni ve eski uygulamaları hedef SDK'larına göre farklı şekilde işlemek için bölünmüş izin taşıma stratejisi kullanır.

Kategori Hedef SDK düzeyi Yerel ağ erişimi davranışı Geliştiricinin yapması gereken işlem
Yeni Uygulamalar/Güncellenen Uygulamalar >= 37 (Android 17) Varsayılan olarak engellenir ACCESS_LOCAL_NETWORK çalışma zamanında istenen izni beyan edin ve isteyin
Eski Uygulamalar < 37 INTERNET iznine sahip uygulamalar, ACCESS_LOCAL_NETWORK için dolaylı bir izin alır ve bu sayede erişimi sürdürebilir. Bu geçici bir durumdur ve uygulama, hedef SDK'yı 37'ye yükselttiğinde varsayılan olarak engellenir. Şu anda kod değişikliği yapmanız gerekmez. SDK 37'yi hedeflemeden önce çalışma zamanında ACCESS_LOCAL_NETWORK izni istemeyin.

Kullanım Alanına Göre LNP Stratejisi

  • Yayınlama: Medya yayınlama işlevleri için en uygun ve gizliliği korumaya yönelik strateji, çıkış değiştiriciyi kullanmaktır. Bu yöntem, sistemin yerel ağ keşfini ve bağlantısını kullanıcı adına işlemesine olanak tanır. Böylece uygulamanın ACCESS_LOCAL_NETWORK izni istemesine gerek kalmaz.

  • Tarayıcılar: Hataların ele alınması, protokole göre farklı yaklaşımlar gerektirir. UDP hataları EPERM hata koduna neden olur. TCP bağlantıları için tarayıcılar, bir paketin LNP tarafından engellenip engellenmediğini belirlemek üzere NDK API'yi (android_getnetworkblockedreason(int sockFd)) kullanmalıdır. Bu API, ANDROID_NETWORK_BLOCKED_REASON_LNP değerini döndürür.

  • Diğer Kullanım Alanları (ör. IoT): mDNS kullanarak cihazları bulan uygulamalar, izin olmadan cihazların bulunmasına olanak tanıyan android.net.nsd.DiscoveryRequest#FLAG_SHOW_PICKER ve IP adreslerini almak için NsdManager#registerServiceInfoCallback / NsdManager#resolveService kullanmalıdır. Bu şekilde elde edilen IP adreslerine bağlantılar için ACCESS_LOCAL_NETWORK izni gerekmez.

Doğrudan yerel ağ iletişimi gerektiren ve sistem tarafından yönetilen seçicileri kullanamayan uygulamalarda, Android 17 (SDK 37) veya sonraki sürümleri hedeflerken izin sıfırlama sayacı stratejisinin kullanılması önerilir. ACCESS_LOCAL_NETWORK izni kullanıcı tarafından iptal edilirse bu mekanizma, uygulamanın izni yeniden istemesi için ek fırsatlar sunarak geliştiricilerin kullanıcıya daha net bir gerekçe sunmasına olanak tanır.

Android 16 ile ilgili bilgiler (kullanımdan kaldırıldı)

Android 16'da yerel ağ kısıtlamalarını etkinleştirmek için aşağıdakileri yapın:

  1. Cihazınıza Android 16 Beta 3 veya sonraki sürümlerin yüklü olduğu bir derleme yükleyin.
  2. Test edilecek uygulamayı yükleme
  3. ADB kullanarak Appcompat yapılandırmasını açma/kapatma

    adb shell am compat enable RESTRICT_LOCAL_NETWORK <package_name>
    
  4. Cihazı yeniden başlatma

Artık uygulamanızın yerel ağa erişimi kısıtlanmıştır ve yerel ağa erişim girişimleri soket hatalarına yol açar. Uygulama işleminizin dışında yerel ağ işlemleri gerçekleştiren API'ler kullanıyorsanız (ör. NsdManager) bunlar etkinleştirme sırasında etkilenmez.

Erişimi geri yüklemek için uygulamanıza NEARBY_WIFI_DEVICES izni vermeniz gerekir.

  • Uygulamanın, manifest dosyasında NEARBY_WIFI_DEVICES iznini beyan ettiğinden emin olun.
  • Ayarlar > Uygulamalar > [Uygulama Adı] > İzinler > Yakındaki cihazlar > İzin ver'e gidin.

Uygulamanızın yerel ağa erişimi geri yüklenir ve tüm senaryolarınız, uygulamayı etkinleştirmeden önceki gibi çalışır. Uygulama ağı trafiği bu durumdan şu şekilde etkilenir.

İzin Giden LAN İsteği Giden/Gelen İnternet İsteği Gelen LAN İsteği
Verildi Works Works Works
İzin verilmedi Başarısızlar Works Başarısızlar

Appcompat yapılandırmasını devre dışı bırakmak için aşağıdaki komutu kullanın.

adb shell am compat disable RESTRICT_LOCAL_NETWORK <package_name>

Hatalar

Yerel ağ erişimi isteği, eksik izin nedeniyle başarısız olursa:

  • TCP bağlantıları genellikle zaman aşımı hatasına neden olur.

  • UDP hataları ve genel izin retleri genellikle EPERM hata koduyla sonuçlanır.

Hatalar

Şunlarla ilgili hataları ve geri bildirimleri gönderin:

  • LAN erişimindeki tutarsızlıklar (belirli bir erişimin "yerel ağ" erişimi olarak kabul edilmemesi gerektiğini düşünüyorsanız)
  • LAN erişiminin engellenmesi gerekirken engellenmediği hatalar
  • LAN erişiminin engellenmemesi gerekirken engellendiği hatalar

Aşağıdakiler bu değişiklikten etkilenmeyecek:

  • İnternet erişimi
  • Mobil Ağ