DNS-резолвер

Модуль DNS-резолвера обеспечивает защиту пользователей от перехвата DNS и атак с целью изменения конфигурации, а также повышает производительность сети при разрешении DNS. Модуль содержит код, реализующий преобразователь DNS-заглушки, который преобразует имена, например www.google.com, в IP-адреса, например 2001:db8::1. DNS-резолвер-заглушка поддерживает элементы Java API, такие как InetAddress#getAllByName и Network#getAllByName, а также встроенные сетевые функции, и реализует отправку и получение DNS-запросов и кеширование результатов.

Изменения в Android 10

На устройствах с Android 9 и более ранних версий код DNS-резолвера распределен между Bionic и netd. DNS-запросы централизованы в демоне netd, чтобы обеспечить кеширование на уровне системы, а приложения вызывают функции (например, getaddrinfo) в Bionic. Запрос отправляется через сокет UNIX в /dev/socket/dnsproxyd демону netd, который анализирует запрос и снова вызывает getaddrinfo для выполнения DNS-запросов, а затем кеширует результаты, чтобы их могли использовать другие приложения. Реализация DNS-резолвера в основном содержалась в файле bionic/libc/dns/ и частично в файле system/netd/server/dns.

В Android 10 код DNS-резолвера перенесен в system/netd/resolv,, преобразован в C++, а также модернизирован и реорганизован. Код в Bionic по-прежнему существует для совместимости с приложениями, но больше не вызывается системой. Рефакторинг затронет следующие пути к исходным файлам:

  • bionic/libc/dns
  • system/netd/client
  • system/netd/server/dns
  • system/netd/server/DnsProxyListener
  • system/netd/server/ResolverController
  • system/netd/resolv

Формат и зависимости

Модуль DNS-резолвера (com.android.resolv) поставляется в виде файла APEX и динамически связывается с netd. Однако netd не является зависимостью, поскольку модуль напрямую обслуживает локальный сокет /dev/socket/dnsproxyd. Конечная точка Binder для конфигурации преобразователя была перенесена из netd в преобразователь. Это означает, что системный сервис может напрямую вызывать модуль преобразователя, не используя netd.

Модуль DNS-резолвера зависит от libc (Bionic) и статически связывает свои зависимости. Другие библиотеки не требуются.

Разрешение mDNS .local

С ноября 2021 г. в Android-резолвере поддерживается разрешение mDNS .local, в котором реализован раздел "5.1 Одноразовые многоадресные DNS-запросы" из RFC 6762 для отправки стандартных DNS-запросов вслепую на адрес 224.0.0.251:5353 или [FF02::FB]:5353. Разрешение mDNS прозрачно поддерживается при вызове getaddrinfo() с именем хоста, заканчивающимся на *.local.

Разрешение mDNS .local дополняет существующую функцию getaddrinfo(), которая используется для получения адресов. Если устройство поддерживает разрешение mDNS .local, API getaddrinfo() отправляет запросы mDNS на адрес 224.0.0.251:5353 или [FF02::FB]:5353 и возвращает локальные адреса. Если устройство не поддерживает разрешение mDNS .local, метод API getaddrinfo() отправляет DNS-запрос на DNS-сервер.

Код находится в AOSP по адресу packages/modules/DnsResolver. Пользователи могут сохранить текущую конфигурацию mDNS для получения адресов или использовать getaddrinfo(). Эта функция работает как обычный DNS-запрос, отправленный на адреса многоадресной рассылки mDNS. Эта функция не влияет на работоспособность системы.

Пользователи могут использовать команду adb shell ping6 HOSTNAME.local, где HOSTNAME – имя хоста целевого устройства в локальной сети, например adb shell ping6 ipad.local.

VPN и мобильный интернет исключены из разрешения .local.