로컬 네트워크 권한

로컬 영역 네트워크 (LAN)의 기기는 INTERNET 권한이 있는 모든 앱에서 액세스할 수 있습니다. 이렇게 하면 앱이 로컬 기기에 쉽게 연결할 수 있지만 사용자 지문 형성 및 위치 프록시와 같은 개인 정보 보호 영향도 있습니다.

로컬 네트워크 보호 프로젝트는 새로운 런타임 권한 뒤에 로컬 네트워크 액세스를 제한하여 사용자의 개인 정보를 보호하는 것을 목표로 합니다.

영향

Android 16에서는 이 권한이 선택 기능이므로 선택한 앱만 영향을 받습니다. 선택의 목표는 앱 개발자가 앱의 어떤 부분이 암시적 로컬 네트워크 액세스에 의존하는지 파악하여 향후 Android 출시에서 권한을 보호할 수 있도록 준비하는 것입니다.

앱이 다음을 사용하여 사용자의 로컬 네트워크에 액세스하는 경우 영향을 받습니다.

  • 로컬 네트워크 주소에서 원시 소켓을 직접 또는 라이브러리 사용(예: Multicast DNS (mDNS) 또는 Simple Service Discovery Protocol (SSDP))
  • 로컬 네트워크에 액세스하는 프레임워크 수준 클래스 사용(예: NsdManager)

영향 세부정보

로컬 네트워크 주소로의 트래픽에는 로컬 네트워크 액세스 권한이 필요합니다. 다음 표에는 몇 가지 일반적인 사례가 나와 있습니다.

앱 하위 수준 네트워크 작업 로컬 네트워크 권한 필요
아웃바운드 TCP 연결 만들기
인바운드 TCP 연결 수락
UDP 유니캐스트, 멀티캐스트, 브로드캐스트 전송
인바운드 UDP 유니캐스트, 멀티캐스트, 브로드캐스트 수신

이러한 제한사항은 네트워킹 스택에 깊이 구현되므로 모든 네트워킹 API에 적용됩니다. 여기에는 플랫폼 또는 관리 코드에서 생성된 소켓, Cronet 및 OkHttp와 같은 네트워킹 라이브러리, 이러한 라이브러리 위에 구현된 API 가 포함됩니다. 로컬 네트워크에서 서비스를 확인하려면 .local 서픽스가 있는 로컬 네트워크 권한이 필요합니다.

앞의 규칙에 대한 예외는 다음과 같습니다.

  • 기기의 DNS 서버가 로컬 네트워크에 있는 경우 포트 53에서 로컬 네트워크 액세스 권한이 필요하지 않습니다.
  • 출력 전환기를 인앱 선택기로 사용하는 애플리케이션에는 로컬 네트워크 권한이 필요하지 않습니다 (향후 출시에서 추가 가이드 제공 예정).

Android 17 적용

Android 17부터 로컬 네트워크 보호는 Android 17 이상을 타겟팅하는 앱에 필수이며 적용됩니다.

특성 Android 16 Android 17
타겟 SDK 36 37 이상
권한 일시적으로 사용된 NEARBY_WIFI_DEVICES ACCESS_LOCAL_NETWORK
기본 액세스 로컬 네트워크 액세스가 열려 있음 타겟 SDK를 업데이트하는 모든 앱의 로컬 네트워크가 기본적으로 차단됨
권한 그룹 기존 NEARBY_DEVICES 권한 그룹의 일부

적용 후 앱 기능이 중단되지 않았는지 확인하려면 SDK 37 이상을 타겟팅하는 애플리케이션이 다음 경로 중 하나를 채택하여 로컬 네트워크 액세스를 관리해야 합니다.

경로 A: 개인 정보를 보호하는 선택기 사용

시스템 중재 검색 및 연결 작업의 경우 선택기를 사용하여 광범위한 런타임 권한을 완전히 요청하지 마세요. 사용 사례에 따라 다음 선택기를 사용하세요.

  • 미디어 스트리밍: 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: 런타임 권한 요청 (광범위한 액세스)

이 경로는 홈 자동화 또는 로컬 네트워크에 대한 광범위하고 지속적인 액세스가 필요한 IoT 기기 관리와 같은 복잡한 사용 사례에 필요합니다.

  • 매니페스트에서 권한 선언: 개발자는 AndroidManifest.xml에서 ACCESS_LOCAL_NETWORK을(를) 명시적으로 선언해야 합니다.

  • 런타임에 권한 요청: 로컬 네트워크 액세스를 시도하기 전에 애플리케이션은 권한이 부여되었는지 확인해야 합니다. 권한이 부여되지 않은 경우 표준 시스템 메시지를 트리거하려면 Activity.requestPermission()을 호출해야 합니다.

  • 사전 부여 시나리오: ACCESS_LOCAL_NETWORK 권한은 NEARBY_DEVICES 권한 그룹의 일부입니다. 사용자가 이 그룹의 다른 권한 (예: 블루투스 권한)을 이미 부여한 경우 로컬 네트워크 액세스를 다시 요청하지 않습니다.

  • 거부 및 취소 처리: 앱은 사용자가 요청을 거부하거나 나중에 시스템 설정에서 권한을 취소하는 경우를 정상적으로 처리해야 합니다. 이러한 시나리오에서는 로컬 네트워크 트래픽이 차단됩니다.

권한 요청 재설정 카운터 전략

플랫폼은 앱이 NEARBY_DEVICES 권한 그룹 (이제 ACCESS_LOCAL_NETWORK 포함)을 이전에 거부하여 앱이 충분한 근거를 제시한 후 권한을 요청하지 못하도록 하는 시나리오를 해결하는 카운터 재설정 전략을 구현합니다. 이 메커니즘은 앱이 requestPermission() API를 호출할 수 있는 추가 기회를 부여하여 ACCESS_LOCAL_NETWORK 권한의 거부 횟수를 효과적으로 재설정합니다. 이렇게 하면 특히 앱이 핵심 기능에 로컬 네트워크 액세스가 필요함을 전달하기 전에 초기 거부가 발생한 경우 사용자와 더 미묘하게 재참여할 수 있습니다.

분할 권한 모델

로컬 네트워크 권한은 분할 권한 마이그레이션 전략을 활용하여 타겟 SDK에 따라 신규 애플리케이션과 기존 애플리케이션을 다르게 처리합니다.

카테고리 타겟 SDK 수준 로컬 네트워크 액세스 동작 필요한 개발자 작업
신규 앱 / 업데이트된 앱 >= 37 (Android 17) 기본적으로 차단됨 ACCESS_LOCAL_NETWORK 런타임 권한 선언 및 요청
레거시 앱 < 37 인터넷 권한이 있는 앱은 ACCESS_LOCAL_NETWORK에 대한 암시적 권한 부여를 받아 액세스 권한을 유지할 수 있습니다. 이는 일시적이며 앱이 타겟 SDK를 37로 올리면 기본적으로 차단됩니다. 즉각적인 코드 변경이 필요하지 않음

사용 사례별 LNP 전략

  • 전송: 미디어 전송 기능의 경우 가장 적절하고 개인 정보를 보호하는 전략은 출력 전환기를 사용하는 것입니다. 이 방법을 사용하면 시스템에서 사용자를 대신하여 로컬 네트워크 검색 및 연결을 처리할 수 있으므로 앱에서 ACCESS_LOCAL_NETWORK 권한을 요청할 필요가 없습니다.

  • 브라우저: 오류를 처리하려면 프로토콜에 따라 다른 접근 방식이 필요합니다. UDP 오류로 인해 EPERM 오류 코드가 발생합니다. TCP 연결의 경우 브라우저는 NDK API android_getnetworkblockedreason(int sockFd) 를 사용하여 패킷이 LNP에 의해 차단되었는지 확인해야 합니다. 이 API는 ANDROID_NETWORK_BLOCKED_REASON_LNP를 반환합니다.

  • 기타 사용 사례 (예: IoT): mDNS를 사용하여 기기를 찾는 애플리케이션은 권한 없이 기기를 찾을 수 있는 android.net.nsd.DiscoveryRequest#FLAG_SHOW_PICKER와 IP 주소를 가져오는 NsdManager#registerServiceInfoCallback / NsdManager#resolveService를 사용해야 합니다. 이 방법으로 가져온 IP 주소에 대한 연결에는 ACCESS_LOCAL_NETWORK 권한이 필요하지 않습니다.

직접 로컬 네트워크 통신이 필요하고 시스템 중재 선택기를 사용할 수 없는 애플리케이션의 경우 권한 재설정 카운터 전략을 사용하는 것이 좋습니다. 사용자가 ACCESS_LOCAL_NETWORK 권한을 취소하면 이 메커니즘은 앱이 권한을 다시 요청할 수 있는 추가 기회를 제공하여 개발자가 사용자에게 더 명확한 근거를 제시할 수 있도록 합니다.

Android 16 가이드

로컬 네트워크 제한을 선택하려면 다음 단계를 따르세요.

  1. 기기를 Android 16 베타 3 이상이 포함된 빌드로 플래시합니다.
  2. 테스트할 앱을 설치합니다.
  3. adb를 사용하여 Appcompat 구성을 전환합니다.

    adb shell am compat enable RESTRICT_LOCAL_NETWORK <package_name>
    
  4. 기기를 재부팅합니다.

이제 앱의 로컬 네트워크 액세스가 제한되고 로컬 네트워크에 액세스하려는 시도는 소켓 오류로 이어집니다. 앱 프로세스 외부에서 로컬 네트워크 작업을 실행하는 API (예: NsdManager)를 사용하는 경우 선택 중에 영향을 받지 않습니다.

액세스 권한을 복원하려면 앱에 NEARBY_WIFI_DEVICES 권한을 부여해야 합니다.

  • 앱이 NEARBY_WIFI_DEVICES 권한을 manifest에서 선언하는지 확인합니다.
  • 설정 > > [앱 이름] > 권한 > 근처 기기 > 허용으로 이동합니다.

이제 앱의 로컬 네트워크 액세스가 복원되고 모든 시나리오가 앱을 선택하기 전과 같이 작동해야 합니다. 앱 네트워크 트래픽이 미치는 영향은 다음과 같습니다.

권한 아웃바운드 LAN 요청 아웃바운드/인바운드 인터넷 요청 인바운드 LAN 요청
승인됨 작동의 원리 작동의 원리 작동의 원리
허용되지 않음 실패 경험 작동의 원리 실패 경험

다음 명령어를 사용하여 Appcompat 구성을 전환합니다.

adb shell am compat disable RESTRICT_LOCAL_NETWORK <package_name>

오류

권한 누락으로 인해 로컬 네트워크 액세스 요청이 실패하는 경우

  • TCP 연결은 일반적으로 시간 제한 오류 를 일으킵니다.

  • UDP 오류 및 일반적인 권한 거부는 일반적으로 EPERM 오류 코드를 일으킵니다.

버그

버그 및 다음을 위한 의견을 제출하세요.

  • LAN 액세스의 불일치 (특정 액세스가 '로컬 네트워크' 액세스로 간주되어서는 안 된다고 생각하는 경우)
  • LAN 액세스가 차단되어야 하지만 차단되지 않는 버그
  • LAN 액세스가 차단되어서는 안 되지만 차단되는 버그

다음은 이 변경사항의 영향을 받지 않아야 합니다.

  • 인터넷 액세스
  • 모바일 네트워크