概述
Libvirt 被广泛应用于管理 Linux® 上的虚拟化环境。它提供了各种丰富的功能,包括客户机生命周期管理、资源分配、资源管理(使用 cgroups),以及通过 SELinux 实现安全强制 (security enforcement) 等。所有这些操作均是由 libvirt 执行,主要处理被分配给客户机或从客户机释放的主机资源。
从 0.9.0 版本开始,libvirt 就能够与主机上的 Linux 审计子系统通信,发出有关若干操作的记录。这是一项重要特性,允许系统管理员、审计员,甚至其他应用程序访问虚拟化环境中详细的变更历史,包括客户机生命周期操作,以及主机资源到客户机的分配变化。
Linux 审计子系统能够处理来自不同来源的许多种操作,而不仅仅是 libvirt 发出的与虚拟化有关的事件。审计系统常用于跟踪文件变更、来自 SELinux 或 AppAmor 的安全拒绝 (security denial),以及系统调用。这些不同的事件包含对虚拟机审计有用的信息。
例如,SELinux 策略可能禁止访问某个分配给客户机的资源,这将生成一个 AVC (Access Vector Cache) 拒绝记录。尽管该事件不是由 libvirt 发出,但是它与一个客户机关联。类似地,许多事件都可以与客户机关联,其中包含由内核或用户空间内的程序生成的异常事件。
在下一节中,我们将快速了解审计系统如何工作,libvirt 如何与之交互,以及如何从审计日志获取与客户机相关的信息。
审计基础知识
Linux 内核负责生成大部分审计事件,例如系统调用事件、文件监视事件和安全事件。但是用户应用程序也可以生成事件。
Linux 审计系统的核心组件就是内核。由其他组件生成的所有事件首先将被发送给内核。在内核中,将应用一系列规则来决定是否应当丢弃某个事件。图 1 展示了构成 Linux 审计系统的组件。
内核中的审计规则可以通过 auditctl
命令修改。一些具有特殊功能的应用程序,如 libvirt
daemon,被认为是可信任的应用程序,能够向内核发送审计事件。在应用了规则后,内核向 audit
daemon 发送审计事件。然后 audit
daemon 将记录写入到磁盘,并使用 auditspd daemon 分配定制操作。
其他组件(ausearch、aureport、aulast 和 auvirt)均为用户空间工具,用于解析审计日志并以更简单的形式呈现信息。auvirt 工具专门用于呈现与虚拟化有关的事件和关联事件。
需要注意审计事件和审计记录之间的区别。审计事件是由受审计的用户或应用程序所发起的一个操作,例如:文件打开事件就是一个可以受审计的事件。此外,审计记录包含仅与事件的某个方面有关的信息。因此,一个事件可能跨越审计日志中的一个或多个记录。以文件打开为例,该事件可以生成两条记录,一条记录包含与被调用的开放 syscall 有关的信息,另一条记录包含与所访问的文件有关的记录。(参见 清单 1 获得示例)。
type=SYSCALL msg=audit(1328292445.908:40194): arch=c000003e syscall=2 success=yes exit=3 a0=7fffe3d2e85c a1=941 a2=1b6 a3=7fffe3d2c570 items=3 ppid=26377 pid=26677 auid=500 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=pts8 ses=1 comm="touch" exe="/bin/touch" subj=unconfined_u:unconfined_r:unconfined_t:s0 key=(null) type=CWD msg=audit(1328292445.908:40194): cwd="/home/mhcerri" type=PATH msg=audit(1328292445.908:40194): item=0 name="/tmp/file" inode=1196 dev=fd:01 mode=0100775 ouid=500 ogid=501 rdev=00:00 obj=unconfined_u:object_r:user_tmp_t:s0 |
注意,每条记录都有一个不同的类型,所有三条记录都包含 "1328292445.908:40194" 字符串。这是事件标识符。冒号前的头两个数字为事件时间戳,第一个为 UNIX® 事件(单位为秒),第二个为毫秒值。第三个数字是生成的序列号。还需注意,审计记录中使用的格式有些复杂,因此审计系统提供了一些工具帮助您显示审计日志。
回页首
Libvirt 和 Audit
Libvirt 实际上生成三种类型的记录。它们都包含一条通用记录,“uuid” 字段。这是一个 Universal Unique Identifier,标识所有记录中 libvirt 发出的客户机。libvirt 使用的记录类型为:
回页首
Auvirt
auvirt 工具将搜索审计日志,查找由 libvirt 生成的记录,展示虚拟机会话列表。它还查找其他一些事件,如主机宕机、与客户机有关的 AVC 拒绝事件,以及与 QEMU 有关的异常事件。清单 2 展示了一个 auvirt 输出例子。第一个字段为客户机名称。第二个为启动客户机的用户。第三个为客户机运行的时间范围。注意,示例中 “Arch” 的执行已失败,而另一个仍然保持运行。
# auvirt Fedora root Tue Jan 24 16:28 - 16:28 (00:00) Fedora root Wed Jan 25 10:31 - 10:34 (00:02) CentOS root Wed Jan 25 10:34 - 13:50 (03:16) Fedora root Wed Jan 25 13:51 - 13:54 (00:03) Fedora root Wed Jan 25 13:54 - 13:55 (00:00) Arch root Wed Jan 25 13:55 - failed Arch root Wed Jan 25 13:56 |
可以通过下面的选项将输出限制到一个特定的时间范围:
--start <date> [<time>]
:为将要使用的时间期限确定一个开始时间 --end <date> [<time>]
:为将要使用的时间期限确定一个结束时间 如果忽略 <time>
,工具将把开始和结束时间默认设置为 “00:00:00” 和 “23:59:59”。
# auvirt --start 01/25/2012 12:00:00 --end 01/25/2012 Fedora root Wed Jan 25 13:51 - 13:54 (00:03) Fedora root Wed Jan 25 13:54 - 13:55 (00:00) Arch root Wed Jan 25 13:55 - failed Arch root Wed Jan 25 13:56 |
也可以将结果限制到一个客户机。该客户机可以通过客户机名称或客户机的 UUID 指定。默认情况下,为了保持输出简单,工具不会显示 UUID,但是您可以通过 --show-uuid
选项在输出中包含它。
# auvirt --vm Fedora Fedora root Tue Jan 24 16:28 - 16:28 (00:00) Fedora root Wed Jan 25 10:31 - 10:34 (00:02) Fedora root Wed Jan 25 13:51 - 13:54 (00:03) Fedora root Wed Jan 25 13:54 - 13:55 (00:00) # auvirt --show-uuid --uuid cabf9532-99f1-3756-930f-59e8f19d4144 Arch cabf9532-99f1-3756-930f-59e8f19d4144 root Wed Jan 25 13:55 - failed Arch cabf9532-99f1-3756-930f-59e8f19d4144 root Wed Jan 25 13:56 |
默认情况下,auvirt 将显示一个简化的输出。要展示所有与虚拟化有关的事件,可以使用 --all-events
选项。使用该选项后,auvirt 将展示每个起始和结束事件、资源分配和相关事件的记录。清单 5 展示了使用 --all-events
选项的例子。
# auvirt --vm CentOS --all-events down root Wed Jan 25 08:34 res CentOS root Wed Jan 25 10:34 - 13:50 (03:16) cgroup allow major rw pty [...] avc CentOS root Wed Jan 25 10:34 relabelto denied libvirtd CentOS.img system_u:object_r:svirt_image_t:s0:c6,c883 [...] res CentOS root Wed Jan 25 10:34 - 13:50 (03:16) disk start /var/lib/libvirt/images/CentOS.img res CentOS root Wed Jan 25 10:34 - 13:50 (03:16) net start 52:54:00:DB:AE:B4 res CentOS root Wed Jan 25 10:34 - 13:50 (03:16) mem start 1048576 res CentOS root Wed Jan 25 10:34 - 13:50 (03:16) vcpu start 1 start CentOS root Wed Jan 25 10:34 - 13:50 (03:16) [...] stop CentOS root Wed Jan 25 13:50 |
第一个字段表示事件类型,包含以下值:start、stop、res、avc、anom 和 down(表示主机宕机)。
资源分配和 AVC 记录包含额外的字段,提供相关的信息。资源分配中的额外字段包括:
auvirt 报告的 AVC 事件表示客户机执行的访问没有被拒绝,而主机中另一个进程对客户机资源进行的访问被拒绝。AVC 事件包含的额外字段包括:
relabelto
和 relabelfrom
操作,额外又包含了字段,表示相关的安全上下文:relabelto
的目标上下文和 relabelfrom
的源上下文。 回页首
访问原始数据
Auvirt 提供了用户友好的输出,不必包含审计日志中的所有事件信息。有时,这些额外的信息可能有用,需要访问原始数据来获得更详细的信息。Auvirt 包含 --proof
选项,可用于显示审计事件标识符(用于生成输出中的每条记录)。
# auvirt --vm Fedora -ts 01/23/2012 00:00 -te 01/23/2012 17:30 --proof Fedora root Mon Jan 23 17:02 - 17:27 (00:24) Proof: 1327345338.087:41631, 1327346831.548:41702 |
清单 6 显示了 auvirt 示例,显示了用于创建记录的开始和停止事件标识符。通过这些信息,您可以使用 ausearch 工具从审计日志中提取原始记录(参见 清单 7)。
# ausearch -a 41631 --start 01/23/2012 17:02:00 --end 01/23/2012 17:27:59 ---- time->Mon Jan 23 17:02:18 2012 type=VIRT_CONTROL msg=audit(1327345338.087:41631): user pid=2433 uid=0 auid=4294967295 ses=4294967295 subj=system_u:system_r:initrc_t:s0 msg='virt=kvm op=start reason=booted vm="Fedora" uuid=7bcae45c-c179-6cea-a185-c7abe50520c7: exe="/usr/sbin/libvirtd" hostname=? addr=? terminal=? res=success' |
该示例使用了 -a
选项,将输出限制到带有给定序列号的记录,还使用了 --start
和 --end
选项,它们与 auvirt 选项的工作方式相同。注意,原始记录包含了额外的信息,如原因、可执行文件名称和 pid。
回页首
结束语
云计算正在变得越来越普及,虚拟化开始成为一项主流技术。清晰地理解虚拟化环境中发生的变化变得愈加重要。此外,对于某些特定的行业,如政府和金融,审计也成为一项必须满足的要求。本文介绍了可用于过滤与虚拟化相关的主机审计事件的审计工具。通过使用这些事件,您可以了解到主机和客户机上发生的客户机事件,从而获得更加全面的客户机审计跟踪