Podman:一个更安全的运行容器的方式
创始人
2024-03-02 03:22:54
0

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 译注:2 32 - 1)。由于容器是 Docker 守护程序的后代,而 Docker 守护程序是 init 系统的子代,所以,我们看到 systemd、Docker 守护程序和容器进程全部具有相同的 loginuid4294967295,审计系统视其为未设置审计 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 文件将没有任何跟踪信息。

现在让我们看看相同的场景在 Podman 下的情况。

$ sudo podman run --privileged -v /:/host fedora touch /host/etc/shadow 
$ sudo ausearch -f /etc/shadow -i type=PROCTITLE msg=audit(10/10/2018 10:23:41.659:4530) : proctitle=/usr/bin/coreutils --coreutils-prog-shebang=touch /usr/bin/touch /host/etc/shadow type=SYSCALL msg=audit(10/10/2018 10:23:41.659:4530) : arch=x86_64 syscall=openat success=yes exit=3 a0=0xffffff9c a1=0x7fffdffd0f34 a2=O_WRONLY|O_CREAT|O_NOCTTY| O_NONBLOCK a3=0x1b6 items=2 ppid=11671 pid=11683 auid=dwalsh uid=root gid=root euid=root suid=root fsuid=root egid=root sgid=root fsgid=root tty=(none) ses=3 comm=touch exe=/usr/bin/coreutils subj=unconfined_u:system_r:spc_t:s0 key=(null)

由于它使用传统的 fork/exec 方式,因此 Podman 正确记录了所有内容。

这只是观察 /etc/shadow 文件的一个简单示例,但审计系统对于观察系统上的进程非常有用。使用 fork/exec 容器运行时(而不是客户端/服务器容器运行时)来启动容器允许你通过审计日志记录保持更好的安全性。

最后的想法

在启动容器时,与客户端/服务器模型相比,fork/exec 模型还有许多其他不错的功能。例如,systemd 功能包括:

  • SD_NOTIFY:如果将 Podman 命令放入 systemd 单元文件中,容器进程可以通过 Podman 返回通知,表明服务已准备好接收任务。这是在客户端/服务器模式下无法完成的事情。
  • 套接字激活:你可以将连接的套接字从 systemd 传递到 Podman,并传递到容器进程以便使用它们。这在客户端/服务器模型中是不可能的。

在我看来,其最好的功能是作为非 root 用户运行 Podman 和容器。这意味着你永远不会在宿主机上授予用户 root 权限,而在客户端/服务器模型中(如 Docker 使用的),你必须打开以 root 身份运行的特权守护程序的套接字来启动容器。在那里,你将受到守护程序中实现的安全机制与宿主机操作系统中实现的安全机制的支配 —— 这是一个危险的主张。


via: https://opensource.com/article/18/10/podman-more-secure-way-run-containers

作者:Daniel J Walsh 选题:lujun9972 译者:wxy 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

相关内容

在CentOS系统中为Do...
理解Docker存储的核心机制:驱动与分层管理 在CentOS系统...
2025-06-16 07:41:58
我的docker随笔39:...
本文介绍在容器中修改时间而不影响宿主机的系统时间。 问题提出 某容...
2025-06-01 18:45:21
容器安全配置
本博客地址:https://security.blo...
2025-06-01 06:33:19
HTML - 容器布局,使...
HTML - 容器布局,使容器充满屏幕高度ÿ...
2025-06-01 02:27:27
docker 容器相互访问...
我们都知道docker是一个个容器,他们相互独立互不...
2025-05-30 11:55:49
Linux运维相关认证有哪...
在 Linux 运维领域,拥有相关认证不仅能证明个人的专业能力,还...
2025-03-01 12:23:35

热门资讯

Helix:高级 Linux ... 说到 基于终端的文本编辑器,通常 Vim、Emacs 和 Nano 受到了关注。这并不意味着没有其他...
使用 KRAWL 扫描 Kub... 用 KRAWL 脚本来识别 Kubernetes Pod 和容器中的错误。当你使用 Kubernet...
JStock:Linux 上不... 如果你在股票市场做投资,那么你可能非常清楚投资组合管理计划有多重要。管理投资组合的目标是依据你能承受...
通过 SaltStack 管理... 我在搜索Puppet的替代品时,偶然间碰到了Salt。我喜欢puppet,但是我又爱上Salt了:)...
Epic 游戏商店现在可在 S... 现在可以在 Steam Deck 上运行 Epic 游戏商店了,几乎无懈可击! 但是,它是非官方的。...
《Apex 英雄》正式可在 S... 《Apex 英雄》现已通过 Steam Deck 验证,这使其成为支持 Linux 的顶级多人游戏之...
如何在 Github 上创建一... 学习如何复刻一个仓库,进行更改,并要求维护人员审查并合并它。你知道如何使用 git 了,你有一个 G...
2024 开年,LLUG 和你... Hi,Linuxer,2024 新年伊始,不知道你是否已经准备好迎接新的一年~ 2024 年,Lin...
什么是 KDE Connect... 什么是 KDE Connect?它的主要特性是什么?它应该如何安装?本文提供了基本的使用指南。科技日...
Opera 浏览器内置的 VP... 昨天我们报道过 Opera 浏览器内置了 VPN 服务,用户打开它可以防止他们的在线活动被窥视。不过...