本文档介绍了设备政策控制器 (DPC) 如何记录网络活动。继续阅读,了解如何向您的 DPC 添加网络日志记录。
概览
记录网络活动有助于企业检测和跟踪恶意软件在其设备上的传播。您的 DPC 可以调用网络日志记录 API,以报告来自系统网络调用的 TCP 连接和 DNS 查找。
通常,DPC 会将日志传送到服务器,以向 IT 管理员呈现。您可能需要在服务器上进一步处理日志,或在设备上本地处理日志。例如,您可以设置 DNS 拒绝名单来检测可疑行为并提醒 IT 管理员。
提供情况
Android 8 及更高版本支持设备所有者进行网络日志记录。启用后,它会收集有关设备的网络活动的数据。对于受管理个人资料的个人资料所有者和具有 DELEGATION_NETWORK_LOGGING 的受托应用,Android 12 及更高版本也支持此功能。当个人资料所有者启用网络日志记录时,网络日志仅包含工作资料的网络活动,不会从个人资料中收集数据。
如需了解详情,请参阅关联的用户。
事件日志
当网络日志记录处于启用状态时,Android 会使用系统网络库记录来自应用的每个事件。网络日志记录会记录两种类型的事件:
- DNS 查询次数
- 网络连接
DNS 查询次数
网络日志记录会记录系统网络请求中的 DNS 查找的事件。日志会捕获每个将主机名解析为 IP 地址的 DNS 请求。系统不会记录其他支持性 DNS 查询,例如域名服务器发现。
网络活动日志记录 API 将每个 DNS 查找显示为 DnsEvent
实例。表 1 介绍了记录到 DnsEvent
中的字段和典型值。
表 1. DNS 事件字段
流量 | 示例 | 说明 |
---|---|---|
主机名 | host.example.com | 在 DNS 查询中发送的主机名。 |
Inet 地址 | 203.0.113.9、198.51.100.25 | DNS 查询为主机名解析的 IPv4 或 IPv6 地址列表。为了使日志大小保持在可管理范围内,结果可能并未包含所有 IP 地址 - 请查看下一行中的地址数。 |
地址数量 | 4 | DNS 查询解析返回的 IP 地址数量。使用此方法可查看所记录的 IP 地址是否为结果的子集。值 0(零)表示主机名无法解析为 IP 地址。 |
软件包名称 | com.android.chrome | 进行 DNS 查询的应用的软件包名称。 |
时间戳 | 1506297600000 | 记录 DNS 查找发生时间的时间戳。该值是 DNS 查询与世界协调时间 (UTC) 1970 年 1 月 1 日午夜之间的毫秒间隔。 |
ID | 25 | 单调递增的数字 ID。适用于 Android 9.0(API 级别 28)或更高版本。 |
虽然 DNS 查找可帮助 IT 管理员跟踪网络连接,但网络日志记录并非通用 DNS 记录解决方案。以下是一些应用可能会执行但不会被记录的 DNS 任务:
- 直接与 DNS 域名服务器通信。
- 调用 Java DNS 库以进行 DNS 查询。
- 通过连接到固定 IP 地址来避免 DNS 查询。
网络连接
网络日志记录会为系统网络请求中的每个尝试连接记录一个事件。日志捕获成功和失败的 TCP 连接 - 系统不会记录 UDP 传输。
网络活动日志记录 API 将每个连接呈现为 ConnectEvent
实例。表 2 介绍了记录到 ConnectEvent
中的字段和典型值。
表 2. 关联事件字段
流量 | 示例 | 说明 |
---|---|---|
Inet 地址 | 2001:db8::2f:abc:0 | 设备连接到的 IP 地址。(可能是 IPv4 或 IPv6 地址)。 |
端口 | 80 | 设备连接的 TCP 端口号。 |
软件包名称 | com.android.chrome | 连接的应用的软件包名称。 |
时间戳 | 1506297600000 | 记录网络连接发生时间的时间戳。该值是连接与世界协调时间 (UTC) 1970 年 1 月 1 日午夜之间的毫秒间隔。 |
ID | 26 | 单调递增的数字 ID。适用于 Android 9.0(API 级别 28)或更高版本。 |
当应用调用标准网络库(例如 Android 的内置 API 或常用的第三方库)以连接到主机时,网络日志记录会记录一个事件。系统不会记录直接发出系统调用以进行通信的应用。请注意,系统不会记录 UDP 网络,因此某些媒体流式传输、即时通讯和游戏应用可能不会出现在日志中。
通知用户
系统会提醒设备用户网络活动日志已启用。用户在界面中会看到以下警告:
- 设备管理对话框中说明您的 DPC 正在监控网络流量的部分。用户可以通过点按“快捷设置”中的受管理设备信息标签来查看对话框。
- 用户刚开始接触网络日志记录时显示的可关闭系统通知。点按通知即会显示设备监控对话框,并在网络监控部分中提供进一步说明。当您的 DPC 停用网络日志记录时,通知会消失。
为 DPC 添加网络日志记录功能
为了帮助 IT 管理员查看网络日志,您的 DPC 需要能够完成以下任务:
- 开启和关闭网络日志记录。
- 在新批次准备就绪后,检索任何记录的日志。
- 将日志中的有用数据发送到服务器。
要求
对于设备所有者,可在 Android 8.0(API 级别 26)或更高版本中使用网络日志记录;对于受管理资料的资料所有者,可在 Android 12(API 级别 31)或更高版本中使用。在记录网络活动之前,DPC 应检查自己是受管理资料的设备所有者还是资料所有者。对于具有工作资料的设备所有者中的网络日志,如果个人资料所有者启用了该资料,则其网络日志不会包含该资料中的网络活动。
启用网络日志记录
如需开始记录网络活动,请调用 DevicePolicyManager
方法 setNetworkLoggingEnabled()
,并将 true
作为 enabled
参数传递。您的 DPC 可以调用 isNetworkLoggingEnabled()
来检查是否记录了网络活动。
在 DPC 启用网络日志记录后,第一批日志可能需要一段时间才能准备就绪。您可能需要在界面中为 IT 管理员设定交付预期。
如需停止记录网络活动,请调用 setNetworkLoggingEnabled()
并传递 false
。IT 管理员关闭网络日志记录时,系统会删除已收集和未报告的所有日志。
检索日志
您的 DPC 可以批量检索日志;网络日志记录 API 不提供对过去的各个条目的随机访问。当有新一批日志可用时,您的 DPC 的 DeviceAdminReceiver
子类会收到 onNetworkLogsAvailable()
回调。该回调包含您的 DPC 可用于检索日志的批处理令牌。您的 DPC 会调用 DevicePolicyManager
方法 retrieveNetworkLogs()
来获取网络事件列表。
以下示例展示了如何在 DeviceAdminReceiver
子类中检索日志:
Kotlin
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 ... }
Java
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 ... }
您的 DPC 应直接检索日志,因为系统会删除日志以便为新批次腾出空间。您可能想要保留日志的本地副本,直到您确定 DPC 已顺利处理所有日志。
处理任何日志
一批日志通常混合包含 DnsEvent
和 ConnectEvent
实例。如需详细了解 DNS 查找和网络连接的数据字段,请参阅事件日志。事件按时间顺序排列,每个批次包含的事件不超过 1200 个。
调用检索日志后,请检查返回值是否不是 null
。如果发生以下任一情况,则值可能为 null
:
- 以批处理令牌表示的批次不再可用。您的 DPC 无法检索该批次,应该等待下一个批次。
- IT 管理员停用了网络日志记录。
以下简化示例展示了 DPC 如何提取已解析的 DNS 主机名。您的 DPC 需要更复杂的处理和报告。
Kotlin
// 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()) } }
Java
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)或更高版本中包含的事件的数字 ID。由于每个事件对应的 ID 会单调递增,因此您可以帮助 IT 管理员发现日志中的数据缺口。每当 DPC 启用日志记录或设备重启时,系统都会重置 ID。
您的 DPC 可以将整个集合发送给服务器,您也可以决定在设备上过滤事件。例如,您可以为 IT 管理员提供已列入许可名单的报告。
开发和测试
在开发和测试期间,您可能希望收到 onNetworkLogsAvailable()
回调,而无需浏览数百个网页。在 Android 9.0(API 级别 28)或更高版本中,您可以发出一些示例网络请求,并强制系统发送日志可用的回调。在终端运行以下 Android 调试桥 (adb) 命令:
adb shell dpm force-network-logs
系统会限制您使用该工具的频率,并在终端输出中报告任何故意减慢速度的情况。如果没有任何日志可检索,您的 DPC 不会收到回调。