Podman 使用传统的 fork/exec 模型(相对于客户端/服务器模型)来运行容器。
在进入本文的主要主题 Podman 和容器之前,我需要了解一点 Linux 审计功能的技术。
什么是审计?
Linux 内核有一个有趣的安全功能,叫做审计。它允许管理员在系统上监视安全事件,并将它们记录到audit.log 中,该文件可以本地存储或远程存储在另一台机器上,以防止黑客试图掩盖他的踪迹。
/etc/shadow 文件是一个经常要监控的安全文件,因为向其添加记录可能允许攻击者获得对系统的访问权限。管理员想知道是否有任何进程修改了该文件,你可以通过执行以下命令来执行此操作:
# auditctl -w /etc/shadow
现在让我们看看当我修改了 /etc/shadow 文件会发生什么:
# touch /etc/shadow # ausearch -f /etc/shadow -i -ts recent -
type=PROCTITLE msg=audit(10/10/2018 09:46:03.042:4108) : proctitle=touch /etc/shadow type=SYSCALL msg=audit(10/10/2018 09:46:03.042:4108) : arch=x86_64 syscall=openat success=yes exit=3 a0=0xffffff9c a1=0x7ffdb17f6704 a2=O_WRONLY|O_CREAT|O_NOCTTY| O_NONBLOCK a3=0x1b6 items=2 ppid=2712 pid=3727 auid=dwalsh uid=root gid=root euid=root suid=root fsuid=root egid=root sgid=root fsgid=root tty=pts1 ses=3 comm=touch exe=/usr/bin/touch subj=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 key=(null)`
审计记录中有很多信息,但我重点注意到它记录了 root 修改了 /etc/shadow 文件,并且该进程的审计 UID(auid )的所有者是 dwalsh 。
内核修改了这个文件了么?
跟踪登录 UID
登录 UID(loginuid ),存储在 /proc/self/loginuid 中,它是系统上每个进程的 proc 结构的一部分。该字段只能设置一次;设置后,内核将不允许任何进程重置它。
当我登录系统时,登录程序会为我的登录过程设置 loginuid 字段。
我(dwalsh )的 UID 是 3267。
$ cat /proc/self/loginuid 3267
现在,即使我变成了 root,我的登录 UID 仍将保持不变。
$ sudo cat /proc/self/loginuid 3267
请注意,从初始登录过程 fork 并 exec 的每个进程都会自动继承 loginuid 。这就是内核知道登录的人是 dwalsh 的方式。
容器
现在让我们来看看容器。
sudo podman run fedora cat /proc/self/loginuid 3267
甚至容器进程也保留了我的 loginuid 。 现在让我们用 Docker 试试。
sudo docker run fedora cat /proc/self/loginuid 4294967295
为什么不一样?
Podman 对于容器使用传统的 fork/exec 模型,因此容器进程是 Podman 进程的后代。Docker 使用客户端/服务器模型。我执行的 docker 命令是 Docker 客户端工具,它通过客户端/服务器操作与 Docker 守护进程通信。然后 Docker 守护程序创建容器并处理 stdin/stdout 与 Docker 客户端工具的通信。
进程的默认 loginuid (在设置 loginuid 之前)是 4294967295 (LCTT 译注:232 - 1)。由于容器是 Docker 守护程序的后代,而 Docker 守护程序是 init 系统的子代,所以,我们看到 systemd、Docker 守护程序和容器进程全部具有相同的 loginuid :4294967295 ,审计系统视其为未设置审计 UID。
cat /proc/1/loginuid 4294967295
怎么会被滥用?
让我们来看看如果 Docker 启动的容器进程修改 /etc/shadow 文件会发生什么。
$ sudo docker run --privileged -v /:/host fedora touch /host/etc/shadow $ sudo ausearch -f /etc/shadow -i type=PROCTITLE msg=audit(10/10/2018 10:27:20.055:4569) : proctitle=/usr/bin/coreutils --coreutils-prog-shebang=touch /usr/bin/touch /host/etc/shadow type=SYSCALL msg=audit(10/10/2018 10:27:20.055:4569) : arch=x86_64 syscall=openat success=yes exit=3 a0=0xffffff9c a1=0x7ffdb6973f50 a2=O_WRONLY|O_CREAT|O_NOCTTY| O_NONBLOCK a3=0x1b6 items=2 ppid=11863 pid=11882 auid=unset uid=root gid=root euid=root suid=root fsuid=root egid=root sgid=root fsgid=root tty=(none) ses=unset comm=touch exe=/usr/bin/coreutils subj=system_u:system_r:spc_t:s0 key=(null)
在 Docker 情形中,auid 是未设置的(4294967295 );这意味着安全人员可能知道有进程修改了 /etc/shadow 文件但身份丢失了。
如果该攻击者随后删除了 Docker 容器,那么在系统上谁修改 /etc/shadow 文件将没有任何跟踪信息。
(编辑:ASP站长网)
|