В этом документе объясняется, как контроллер политики устройства (DPC) регистрирует сетевую активность. Продолжайте читать, чтобы узнать, как добавить ведение журнала сети в ваш ЦОД.
Обзор
Регистрация сетевой активности может помочь предприятиям обнаруживать и отслеживать распространение вредоносного ПО на своих устройствах. Ваш ЦОД может вызывать API-интерфейсы сетевого журнала, чтобы сообщать о TCP-соединениях и DNS-поисках из системных сетевых вызовов.
Обычно ваш ЦОД передает журналы на сервер для представления ИТ-администратору. Возможно, вы захотите дополнительно обработать журналы на своем сервере или локально на устройстве. Например, вы можете настроить списки запретов DNS для обнаружения и оповещения ИТ-администраторов о подозрительном поведении.
Доступность
Ведение журнала сети поддерживается в Android 8 и более поздних версиях для владельца устройства. Если включено, он собирает данные о сетевой активности устройства. Он также поддерживается в Android 12 и более поздних версиях для владельца управляемого профиля и делегированного приложения с помощью DELEGATION_NETWORK_LOGGING . Если ведение журнала сети включено владельцем профиля, сетевые журналы включают только сетевую активность рабочего профиля и не собирают данные из личного профиля.
Чтобы узнать больше, прочитайте Аффилированные пользователи .
Журналы событий
Когда ведение журнала сети активно, Android записывает каждое событие из приложений, используя системные сетевые библиотеки. В журнале сети регистрируются два типа событий:
- DNS-запросы
- Сетевые подключения
DNS-запросы
В журнале сети регистрируются события DNS-запросов, которые являются частью системных сетевых запросов. Журналы фиксируют каждый запрос DNS, который преобразует имя хоста в IP-адрес. Другие вспомогательные DNS-запросы, такие как обнаружение сервера имен, не записываются.
API-интерфейсы регистрации сетевой активности представляют каждый запрос DNS как экземпляр DnsEvent
. В таблице 1 описаны поля и типичные значения, записанные в DnsEvent
.
Таблица 1. Поля событий DNS
Данные | Пример | Описание |
---|---|---|
Имя хоста | хост.example.com | Имя хоста, отправленное в DNS-запросе. |
Интернет-адреса | 203.0.113.9 , 198.51.100.25 | Список IPv4 или IPv6 адресует DNS-запрос, разрешенный для имени хоста. Чтобы сохранить управляемый размер журнала, результаты могут включать не все IP-адреса — см. количество адресов в следующей строке. |
Количество адресов | 4 | Число IP-адресов, возвращенных в результате разрешения DNS-запроса. Используйте это, чтобы узнать, являются ли зарегистрированные IP-адреса частью результатов. Значение 0 (ноль) означает, что имя хоста не преобразуется в IP-адрес. |
Имя пакета | com.android.chrome | Имя пакета приложения, выполнившего DNS-запрос. |
Временная метка | 1506297600000 | Запись временной метки, когда произошел поиск DNS. Значением является интервал в миллисекундах между поиском DNS и полуночью 1 января 1970 года по всемирному координированному времени (UTC). |
ИДЕНТИФИКАТОР | 25 | Монотонно увеличивающийся числовой идентификатор. Доступно в Android 9.0 (уровень API 28) или выше. |
Хотя поиск DNS может помочь ИТ-администраторам отслеживать сетевые подключения , ведение журнала сети не является универсальным решением для записи DNS. Вот некоторые задачи DNS, которые приложение может выполнять, но которые не регистрируются:
- Общение напрямую с DNS-сервером имен.
- Вызов библиотеки DNS Java для выполнения DNS-запросов.
- Избегание DNS-запроса путем подключения к фиксированному IP-адресу.
Сетевые подключения
В журнале сети регистрируется событие для каждой попытки подключения, которая является частью системного сетевого запроса. В журналах фиксируются успешные и неудачные TCP-соединения — передачи UDP не записываются.
API-интерфейсы регистрации сетевой активности представляют каждое соединение как экземпляр ConnectEvent
. В таблице 2 описаны поля и типичные значения, записанные в ConnectEvent
.
Таблица 2. Поля событий подключения
Данные | Пример | Описание |
---|---|---|
Интернет-адреса | 2001:db8::2f:abc:0 | IP-адрес, к которому подключено устройство. Это может быть адрес IPv4 или IPv6. |
Порт | 80 | Номер TCP-порта, к которому подключено устройство. |
Имя пакета | com.android.chrome | Имя пакета подключенного приложения. |
Временная метка | 1506297600000 | Запись временной метки, когда произошло сетевое соединение. Значение представляет собой миллисекундный интервал между соединением и полуночью 1 января 1970 года по всемирному координированному времени (UTC). |
ИДЕНТИФИКАТОР | 26 | Монотонно увеличивающийся числовой идентификатор. Доступно в Android 9.0 (уровень API 28) или выше. |
В журнале сети регистрируется событие, когда приложение вызывает стандартные сетевые библиотеки, такие как встроенные API Android или популярные сторонние библиотеки, для подключения к хосту. Приложения, выполняющие системные вызовы напрямую для связи, не регистрируются. Помните, что сеть UDP не регистрируется, поэтому некоторые приложения потоковой передачи мультимедиа, обмена сообщениями и игровые приложения могут не отображаться в журналах.
Информируйте пользователей
Система предупреждает пользователей устройств о том, что ведение журнала сетевой активности активно. Пользователи видят в интерфейсе следующие предупреждения:
- Раздел в диалоговом окне «Управление устройствами» , в котором объясняется, что ваш ЦОД отслеживает сетевой трафик. Пользователи видят это диалоговое окно, коснувшись метки с информацией об управляемом устройстве в быстрых настройках.
- Открываемое системное уведомление, отображаемое, когда пользователь впервые участвует в ведении журнала сети. При нажатии на уведомление отображается диалоговое окно «Мониторинг устройства» с дальнейшими пояснениями в разделе мониторинга сети. Уведомление исчезает, когда ваш ЦОД отключает ведение журнала сети.
Добавьте сетевое журналирование в свой ЦОД
Чтобы помочь ИТ-администраторам просматривать сетевые журналы, ваш ЦОД должен иметь возможность выполнять следующие задачи:
- Включите и выключите ведение журнала сети.
- Получите все записанные журналы, когда будет готова новая партия.
- Отправьте полезные данные из журналов на сервер.
Требования
Ведение журнала сети доступно в Android 8.0 (уровень API 26) или более поздней версии для владельца устройства и в Android 12 (уровень API 31) или более поздней версии для владельца управляемого профиля. Прежде чем регистрировать сетевую активность, ваш ЦОД должен проверить, является ли он владельцем устройства или владельцем управляемого профиля. Сетевые журналы владельца устройства с рабочим профилем не включают сетевую активность в личном профиле, если она включена владельцем профиля.
Включить ведение журнала сети
Чтобы начать регистрацию сетевой активности, вызовите метод DevicePolicyManager
setNetworkLoggingEnabled()
и передайте true
в качестве enabled
аргумента. Ваш ЦОД может вызвать isNetworkLoggingEnabled()
чтобы проверить, регистрируется ли сетевая активность.
После того как ваш ЦОД включит ведение журнала сети, может пройти некоторое время, прежде чем первый пакет журналов будет готов. Возможно, вы захотите установить ожидания доставки для ИТ-администраторов в своем пользовательском интерфейсе.
Чтобы прекратить регистрацию сетевой активности, вызовите setNetworkLoggingEnabled()
и передайте false
. Когда ИТ-администратор отключает ведение журнала сети, система удаляет все собранные и несообщенные журналы.
Получить журналы
Ваш ЦОД может получать журналы пакетно — API-интерфейсы сетевого журналирования не обеспечивают произвольный доступ к прошлым отдельным записям. Когда доступен новый пакет журналов, подкласс DeviceAdminReceiver
вашего ЦОД получает обратный вызов onNetworkLogsAvailable()
. Обратный вызов включает пакетный токен, который ваш ЦОД может использовать для получения журналов. Ваш ЦОД вызывает метод DevicePolicyManager
retrieveNetworkLogs()
чтобы получить список сетевых событий.
В следующем примере показано, что вы можете получить журналы в подклассе DeviceAdminReceiver
:
Котлин
fun onNetworkLogsAvailable( context: Context, intent: Intent, batchToken: Long, networkLogsCount: Int) { val dpm = getManager(context) var logs: List<NetworkEvent>? = null // Fetch the batch of logs with the batch token from the callback's arguments. try { logs = dpm.retrieveNetworkLogs(getWho(context), batchToken) } catch (e: SecurityException) { // Perhaps an unaffiliated user - handle the exception ... } // Process any logs ... }
Ява
public void onNetworkLogsAvailable( Context context, Intent intent, long batchToken, int networkLogsCount) { DevicePolicyManager dpm = getManager(context); List<NetworkEvent> logs = null; // Fetch the next batch of logs using the callback's batch token argument. try { logs = dpm.retrieveNetworkLogs(getWho(context), batchToken); } catch (SecurityException e) { // Perhaps an unaffiliated user - handle the exception ... } // Process any logs ... }
Ваш ЦОД должен немедленно получить журналы, поскольку система удаляет журналы, чтобы освободить место для новых пакетов. Возможно, вы захотите сохранить локальную копию журналов до тех пор, пока не убедитесь, что ваш ЦОД обработал их все без проблем.
Обработка любых журналов
Пакет журналов обычно содержит смесь экземпляров DnsEvent
и ConnectEvent
. Дополнительные сведения о полях данных DNS-запросов и сетевых подключениях см. в разделе Журналы событий . События расположены в хронологическом порядке, каждая партия содержит не более 1200 событий.
После вызова для получения журналов убедитесь, что возвращаемое значение не равно null
. Значение может быть null
, если произойдет одно из следующих событий:
- Пакет, представленный маркером пакета, больше не доступен. Ваш ЦОД не может получить пакет и должен дождаться следующего пакета.
- ИТ-администратор отключил ведение журнала сети.
В следующем упрощенном примере показано, как DPC может извлечь разрешенные имена хостов DNS. Вашему ЦОД требуется более сложная обработка и отчетность.
Котлин
// Here, logs might be null. We can't fix because either the token doesn't match // the current batch or network logging was deactivated. // Confirm with isNetworkLoggingEnabled(). logs?.forEach { // For this example, report the DNS hosts and discard all other data. // Because we use the event ID, this example requires API level 28. if (it is DnsEvent) { reportDnsHostToServer(it.hostname, it.getTimestamp(), it.getId()) } }
Ява
if (logs == null) { // Abandon processing because either the token doesn't match the current batch // or network logging was deactivated - confirm with isNetworkLoggingEnabled(). return; } for (NetworkEvent event : logs) { // For this example, report the DNS hosts and discard all other data. // This example requires API level 28 because we use the event ID. if (event instanceof DnsEvent) { reportDnsHostToServer( ((DnsEvent) event).getHostname(), event.getTimestamp(), event.getId()); } }
В предыдущем примере также показано, как получить числовой идентификатор для событий, включенных в Android 9.0 (уровень API 28) или более поздних версий. Поскольку идентификатор монотонно увеличивается для каждого события, вы можете помочь ИТ-администраторам обнаружить пробелы в их журналах. Система сбрасывает идентификатор всякий раз, когда ЦОД включает ведение журнала или когда устройство перезагружается.
Ваш ЦОД может отправить всю коллекцию на сервер, или вы можете отфильтровать события на устройстве. Например, вы можете предложить ИТ-администраторам отчеты из белого списка.
Разработка и тестирование
Во время разработки и тестирования вы можете захотеть получать обратные вызовы onNetworkLogsAvailable()
без необходимости просматривать сотни веб-страниц. В Android 9.0 (уровень API 28) или выше вы можете выполнить несколько примеров сетевых запросов и заставить систему отправить обратный вызов, доступные для журналов. Запустите следующую команду Android Debug Bridge (adb) в своем терминале:
adb shell dpm force-network-logs
Система ограничивает частоту использования этого инструмента и сообщает о любом преднамеренном замедлении вывода терминала. Если журналов для получения нет, ваш ЦОД не получит обратного вызова.