Quyền truy cập mạng cục bộ

Mọi ứng dụng có quyền INTERNET đều có thể truy cập vào các thiết bị trên Mạng cục bộ (LAN). Điều này giúp các ứng dụng dễ dàng kết nối với các thiết bị cục bộ, nhưng cũng gây ra những vấn đề về quyền riêng tư, chẳng hạn như tạo dấu vân tay của người dùng và đóng vai trò là proxy cho vị trí.

Dự án Bảo vệ mạng cục bộ nhằm bảo vệ quyền riêng tư của người dùng bằng cách hạn chế quyền truy cập vào mạng cục bộ thông qua một quyền mới khi bắt đầu chạy.

Tác động

Trong Android 16, quyền này là một tính năng chọn sử dụng, nghĩa là chỉ những ứng dụng chọn sử dụng mới bị ảnh hưởng. Mục tiêu của việc chọn sử dụng là để nhà phát triển ứng dụng hiểu được những phần nào của ứng dụng phụ thuộc vào quyền truy cập ngầm ẩn vào mạng cục bộ để họ có thể chuẩn bị bảo vệ quyền đó trong bản phát hành Android sau này.

Các ứng dụng sẽ bị ảnh hưởng nếu truy cập vào mạng cục bộ của người dùng bằng cách:

  • Sử dụng trực tiếp hoặc sử dụng thư viện các socket thô trên địa chỉ mạng cục bộ, ví dụ: Multicast DNS (mDNS) hoặc Simple Service Discovery Protocol (SSDP).
  • Sử dụng các lớp ở cấp khung truy cập vào mạng cục bộ, ví dụ: NsdManager.

Thông tin chi tiết về tác động

Lưu lượng truy cập đến và đi từ địa chỉ mạng cục bộ yêu cầu quyền truy cập mạng cục bộ. Bảng sau đây liệt kê một số trường hợp phổ biến:

Hoạt động mạng cấp thấp của ứng dụng Quyền truy cập mạng cục bộ bắt buộc
Tạo kết nối TCP đi
Chấp nhận kết nối TCP đến
Gửi một thông báo UDP đơn hướng, đa hướng, truyền phát
Nhận một thông báo UDP đơn hướng, đa hướng, truyền phát đến

Các quy định hạn chế này được triển khai sâu trong ngăn xếp mạng, do đó, chúng áp dụng cho tất cả các API mạng. Điều này bao gồm các socket được tạo trong nền tảng hoặc mã được quản lý, các thư viện mạng như Cronet và OkHttp, cũng như mọi API được triển khai trên các socket đó. Việc cố gắng phân giải các dịch vụ trên mạng cục bộ có hậu tố .local yêu cầu quyền truy cập mạng cục bộ.

Các trường hợp ngoại lệ đối với các quy tắc trước đó:

  • Nếu máy chủ DNS của thiết bị nằm trên mạng cục bộ, thì lưu lượng truy cập đến / từ máy chủ đó (ở cổng 53) không yêu cầu quyền truy cập mạng cục bộ.
  • Các ứng dụng sử dụng Trình chuyển đổi đầu ra làm trình chọn trong ứng dụng sẽ không cần quyền truy cập mạng cục bộ (sẽ có thêm hướng dẫn trong bản phát hành sau này).

Thực thi Android 17

Kể từ Android 17, các biện pháp bảo vệ mạng cục bộ là bắt buộc và được thực thi đối với các ứng dụng nhắm đến Android 17 trở lên.

Tỷ lệ Android 16 Android 17
SDK mục tiêu 36 37 trở lên
Quyền Tạm thời sử dụng NEARBY_WIFI_DEVICES ACCESS_LOCAL_NETWORK
Quyền truy cập mặc định Quyền truy cập mạng cục bộ đang mở Mạng cục bộ bị chặn theo mặc định đối với tất cả các ứng dụng cập nhật SDK mục tiêu
Nhóm quyền Một phần của nhóm quyền NEARBY_DEVICES hiện có

Để xác minh rằng chức năng của ứng dụng không bị hỏng sau khi thực thi, các ứng dụng nhắm đến SDK 37 trở lên phải áp dụng một trong các đường dẫn sau để quản lý quyền truy cập mạng cục bộ:

Đường dẫn A: Sử dụng trình chọn bảo đảm quyền riêng tư

Đối với các tác vụ kết nối và phát hiện do hệ thống điều phối, hãy sử dụng trình chọn để tránh hoàn toàn việc yêu cầu quyền khi bắt đầu chạy. Sử dụng các trình chọn sau đây dựa trên trường hợp sử dụng của bạn:

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
    }
})

Đường dẫn B: Yêu cầu quyền khi bắt đầu chạy (quyền truy cập rộng)

Đường dẫn này là bắt buộc đối với các trường hợp sử dụng phức tạp như tự động hoá nhà ở hoặc quản lý thiết bị IoT cần quyền truy cập rộng và liên tục vào mạng cục bộ.

  • Khai báo quyền trong tệp kê khai: Khai báo rõ ràng ACCESS_LOCAL_NETWORK trong AndroidManifest.xml.

  • Yêu cầu quyền khi bắt đầu chạy: Trước khi cố gắng truy cập vào mạng cục bộ, các ứng dụng phải kiểm tra xem quyền đã được cấp hay chưa. Nếu chưa, các ứng dụng phải gọi Activity.requestPermission() để kích hoạt lời nhắc hệ thống tiêu chuẩn.

  • Trường hợp được cấp trước: Quyền ACCESS_LOCAL_NETWORK là một phần của nhóm quyền NEARBY_DEVICES Nếu người dùng đã cấp một quyền khác trong nhóm này (chẳng hạn như quyền Bluetooth), thì họ sẽ không được nhắc lại về quyền truy cập mạng cục bộ.

  • Xử lý trường hợp từ chối và thu hồi: Các ứng dụng phải xử lý một cách thích hợp các trường hợp người dùng từ chối yêu cầu hoặc sau đó thu hồi quyền trong phần cài đặt hệ thống. Trong những trường hợp như vậy, lưu lượng truy cập mạng cục bộ sẽ bị chặn.

Chiến lược đặt lại bộ đếm yêu cầu quyền

Nền tảng này triển khai một chiến lược đặt lại bộ đếm giải quyết các trường hợp mà việc từ chối trước đó của ứng dụng đối với nhóm quyền NEARBY_DEVICES (hiện bao gồm ACCESS_LOCAL_NETWORK) đã ngăn ứng dụng yêu cầu quyền sau khi trình bày đầy đủ lý do. Cơ chế này cấp thêm cơ hội cho ứng dụng gọi API requestPermission(), đặt lại số lần từ chối đối với quyền ACCESS_LOCAL_NETWORK. Điều này cho phép tương tác lại với người dùng một cách tinh tế hơn, đặc biệt là khi lần từ chối ban đầu xảy ra trước khi ứng dụng có thể truyền đạt sự cần thiết của quyền truy cập mạng cục bộ đối với chức năng cốt lõi của mình.

Mô hình quyền chia tách

Quyền truy cập mạng cục bộ sử dụng chiến lược di chuyển quyền chia tách để xử lý các ứng dụng mới và cũ theo cách khác nhau, dựa trên SDK mục tiêu của chúng

Danh mục Cấp độ SDK mục tiêu Hành vi truy cập mạng cục bộ Hành động bắt buộc đối với nhà phát triển
Ứng dụng mới / Ứng dụng đã cập nhật >= 37 (Android 17) Bị chặn theo mặc định Khai báo và yêu cầu quyền khi bắt đầu chạy ACCESS_LOCAL_NETWORK
Ứng dụng cũ < 37 Các ứng dụng có quyền INTERNET sẽ nhận được quyền ngầm ẩn cho ACCESS_LOCAL_NETWORK, cho phép chúng giữ lại quyền truy cập. Đây là quyền tạm thời và sẽ bị chặn theo mặc định sau khi ứng dụng tăng SDK mục tiêu lên 37 Không cần thay đổi mã ngay. Đừng yêu cầu ACCESS_LOCAL_NETWORK khi bắt đầu chạy trước khi nhắm đến SDK 37.

Chiến lược LNP theo trường hợp sử dụng

  • Truyền: Đối với các chức năng truyền nội dung nghe nhìn, chiến lược phù hợp nhất và bảo đảm quyền riêng tư là sử dụng trình chuyển đổi đầu ra. Phương thức này cho phép hệ thống xử lý việc phát hiện và kết nối mạng cục bộ thay cho người dùng, loại bỏ nhu cầu ứng dụng yêu cầu ACCESS_LOCAL_NETWORK quyền.

  • Trình duyệt: Việc xử lý lỗi yêu cầu các phương pháp khác nhau dựa trên giao thức. Lỗi UDP dẫn đến mã lỗi EPERM. Đối với các kết nối TCP, trình duyệt nên sử dụng NDK API android_getnetworkblockedreason(int sockFd) để xác định xem một gói có bị LNP chặn hay không. API này trả về ANDROID_NETWORK_BLOCKED_REASON_LNP.

  • Các trường hợp sử dụng khác (ví dụ: IoT): Các ứng dụng tìm thiết bị bằng mDNS nên sử dụng android.net.nsd.DiscoveryRequest#FLAG_SHOW_PICKER cho phép tìm thiết bị mà không cần quyền và NsdManager#registerServiceInfoCallback / NsdManager#resolveService để lấy địa chỉ IP. Các kết nối đến địa chỉ IP thu được theo cách này không yêu cầu quyền ACCESS_LOCAL_NETWORK.

Đối với các ứng dụng yêu cầu giao tiếp trực tiếp trên mạng cục bộ và không thể sử dụng trình chọn do hệ thống điều phối, phương pháp được đề xuất là sử dụng chiến lược đặt lại bộ đếm quyền khi nhắm đến Android 17 (SDK 37) trở lên. Nếu người dùng thu hồi quyền ACCESS_LOCAL_NETWORK, cơ chế này sẽ cung cấp thêm cơ hội cho ứng dụng yêu cầu lại quyền, cho phép nhà phát triển trình bày lý do rõ ràng hơn cho người dùng.

Hướng dẫn về Android 16

Để chọn sử dụng các quy định hạn chế về mạng cục bộ, hãy làm như sau:

  1. Cài đặt ROM thiết bị thành bản dựng có Android 16 Beta 3 trở lên
  2. Cài đặt ứng dụng cần kiểm thử
  3. Bật/tắt cấu hình Appcompat bằng adb

    adb shell am compat enable RESTRICT_LOCAL_NETWORK <package_name>
    
  4. Khởi động lại thiết bị

Giờ đây, quyền truy cập của ứng dụng vào mạng cục bộ bị hạn chế và mọi nỗ lực truy cập vào mạng cục bộ đều dẫn đến lỗi socket. Nếu bạn đang sử dụng các API thực hiện các thao tác trên mạng cục bộ bên ngoài quy trình ứng dụng (ví dụ: NsdManager), thì các API đó sẽ không bị ảnh hưởng trong quá trình chọn sử dụng.

Để khôi phục quyền truy cập, bạn phải cấp cho ứng dụng quyền NEARBY_WIFI_DEVICES.

  • Đảm bảo ứng dụng khai báo quyền NEARBY_WIFI_DEVICES trong manifest.
  • Chuyển đến phần Cài đặt > Ứng dụng > [Tên ứng dụng] > Quyền > Thiết bị ở gần > Cho phép

Giờ đây, quyền truy cập của ứng dụng vào mạng cục bộ sẽ được khôi phục và tất cả các trường hợp của bạn sẽ hoạt động như trước khi chọn sử dụng ứng dụng. Dưới đây là cách lưu lượng truy cập mạng của ứng dụng bị ảnh hưởng.

Quyền Yêu cầu LAN đi Yêu cầu Internet đi/đến Yêu cầu LAN đến
Đã cấp Works Works Works
Không được cấp Thất bại Works Thất bại

Sử dụng lệnh sau để bật/tắt cấu hình Appcompat

adb shell am compat disable RESTRICT_LOCAL_NETWORK <package_name>

Lỗi

Nếu yêu cầu truy cập mạng cục bộ không thành công do thiếu quyền:

  • Kết nối TCP thường sẽ dẫn đến lỗi hết thời gian chờ.

  • Lỗi UDP và việc từ chối quyền chung thường sẽ dẫn đến mã lỗi EPERM

Lỗi

Gửi thông tin về lỗi và ý kiến phản hồi cho:

  • Sự khác biệt trong quyền truy cập LAN (bạn không cho rằng một quyền truy cập nhất định nên được coi là quyền truy cập "mạng cục bộ")
  • Lỗi khi quyền truy cập LAN phải bị chặn nhưng không bị chặn
  • Lỗi khi quyền truy cập LAN không được chặn nhưng lại bị chặn

Những nội dung sau đây sẽ không bị ảnh hưởng bởi thay đổi này:

  • Quyền truy cập Internet
  • Mạng di động