Redian新闻
>
容器快了,却不安全了,Rootless 安排上

容器快了,却不安全了,Rootless 安排上

公众号新闻

在以 root 用户身份运行 Docker 会带来一些潜在的危害和安全风险,这些风险包括:

  1. 1. 容器逃逸:如果一个容器以 root 权限运行,并且它包含了漏洞或者被攻击者滥用,那么攻击者可能会成功逃出容器,并在宿主系统上执行恶意操作。这会导致宿主系统的安全性受到威胁。

  2. 2. 特权升级:在以 root 用户身份运行 Docker 的情况下,容器内的进程可能会尝试特权升级,获取宿主系统的 root 权限。这可能会导致严重的安全问题,因为攻击者可能会利用这些权限来控制宿主系统。

  3. 3. 文件系统访问:以 root 用户身份运行的容器可以访问宿主系统上的文件系统,这可能会导致机密文件的泄漏或文件的损坏。

  4. 4. 网络权限:容器以 root 权限运行时,可能会滥用网络权限,例如进行端口扫描、DDoS 攻击等恶意行为。

为了减少这些风险,推荐采取以下做法:

  • • 以非root用户身份运行容器:最佳实践是在容器中以非root用户的身份运行应用程序。这可以通过在容器中指定普通用户来实现,并避免使用 USER 指令将容器进程切换到 root 用户。

  • • 限制容器的权限:使用 Docker 的安全配置选项,如 --security-opt,可以限制容器的能力,例如禁止容器访问宿主系统的特定目录、文件和设备。

  • • 更新和监控容器:定期更新容器的基础镜像和应用程序,以确保安全漏洞得到修复。同时,使用容器监控和审计工具来检测不寻常的活动。

  • • 限制容器能力:使用 Docker 的能力(capabilities)设置来限制容器的权限,仅提供所需的最小权限来运行应用程序。

什么东西看似Rootless ,实则不然

  • • docker run --user foo:它允许你以非 root 身份在容器中执行进程。值得注意的是,你无法执行包安装等特权活动。runc、containerd 等仍以 root 身份运行。

  • • usermod -aG docker foo:允许非root用户连接到docker套接字。相当于允许用户以 root 身份运行。

  • • sudo dockerchmod +s dockerd: 无需解释

  • • dockerd --userns-remap:它允许你以非 root 身份运行容器。runc、containerd 等仍然以 root 身份运行。

Docker Rootless 基本概念

Docker Rootless 是一种在非特权模式下运行 Docker 的方式,允许以非root用户身份来管理 Docker 守护进程和容器,以降低潜在的安全漏洞风险。在这种模式下,即使在 Docker 安装期间,也无需使用root权限。这有助于提高容器的安全性,因为以非特权用户身份运行容器可以限制容器内部的特权操作。对于特权模式的 Docker 容器,攻击者可能会利用宿主机文件读写权限等漏洞来逃逸,因此非特权模式更为安全。

同时,在 Docker 中,容器可以选择是否以特权模式运行,通过设置 --privileged=false 可以将容器切换为非特权模式。总的来说,Docker Rootless 模式提供了一种更加安全的方式来运行 Docker 容器,降低了潜在的安全风险,特别是在多租户环境中或需要更严格的容器隔离时,这种模式非常有用。

Rootless 模式允许以非 root 用户身份运行 Docker 守护进程(dockerd)和容器,以缓解 Docker 守护进程和容器运行时中潜在的漏洞。

Rootless 模式是在 Docker v19.03 版本作为实验性功能引入的,在 Docker v20.10 版本 GA。

Rootless 模式如何运作

Rootless 模式利用 user namespaces 将容器中的 root 用户和 Docker 守护进程(dockerd)用户映射到宿主机的非特权用户范围内。Docker 此前已经提供了 --userns-remap 标志支持了相关能力,提升了容器的安全隔离性。Rootless 模式在此之上,让 Docker 守护进程也运行在重映射的用户名空间中。

用户命名空间自 Linux 内核 v3.8 以来就已存在,因此该功能在 Docker 中已经存在很长时间了 。

img

Rootless 模式在用户名称空间内执行Docker守护程序和容器。这与userns-remapmode非常相似,除了模式之外,userns-remap守护进程本身以root特权运行,而在Rootless 模式下,守护程序和容器都在没有root特权的情况下运行。

Rootless 模式不使用具有SETUID位或文件功能的二进制文件,除了newuidmapnewgidmap,它们是允许在用户名称空间中使用多个UID / GID所必需的。

Rootless 模式已知限制

  • • 仅支持以下存储驱动程序:

    • • overlay2 (仅在以5.11或更高版本的内核,Ubuntu风格的内核或Debian风格的内核运行时)

    • • fuse-overlayfs(仅在与内核4.18或更高版本一起运行且fuse-overlayfs已安装的情况下)

    • • btrfs(仅在使用内核4.18或更高版本运行,或~/.local/share/docker通过user_subvol_rm_allowedmount选项安装时)

    • • vfs

  • • 仅当与cgroup v2和systemd一起运行时,才支持Cgroup。请参阅限制资源

  • • 不支持以下功能:

    • • AppArmor

    • • 检查站

    • • 叠加网络

    • • 暴露SCTP端口

  • • 要使用该ping命令,请参阅路由ping数据包

  • • 要公开特权TCP / UDP端口(<1024),请参阅公开特权端口

  • • IPAddress显示在中,docker inspect并在RootlessKit的网络名称空间中命名。这意味着如果不nsenter进入网络名称空间,则无法从主机访问IP地址。

  • • 主机网络(docker run --net=host)。

Rootless 模式实践

实践环境

本文使用 Centos 7.5 操作系统的虚拟机进行实验。

cat /etc/redhat-release
CentOS Linux release 7.5.1804 (Core)

创建普通用户

$ useradd rootless
echo 123456 | passwd rootless --stdin

安装依赖

Rootless 模式可以在没有 root 权限的情况下运行 Docker 守护进程和容器, 但是需要安装 newuidmapnewgidmap 工具,以便在用户命名空间下创建从属(subordinate)用户和组的映射(remapping)。通过以下命令安装 newuidmap 和 newgidmap 工具。

cat <<EOF | sudo sh -x
curl -o /etc/yum.repos.d/vbatts-shadow-utils-newxidmap-epel-7.repo https://copr.fedorainfracloud.org/coprs/vbatts/shadow-utils-newxidmap/repo/epel-7/vbatts-shadow-utils-newxidmap-epel-7.repo
yum install -y shadow-utils46-newxidmap
cat <<EOT >/etc/sysctl.conf
user.max_user_namespaces = 28633
EOT
sysctl --system
EOF

注意事项

CentOS 7

  • • 添加user.max_user_namespaces=28633/etc/sysctl.conf(或 /etc/sysctl.d)并运行sudo sysctl --system

  • • systemctl --user默认情况下不起作用。dockerd-rootless.sh不使用systemd直接运行。

CentOS 8 / Fedora

  • • fuse-overlayfs建议安装。运行sudo dnf install -y fuse-overlayfs

  • • 你可能需要sudo dnf install -y iptables

  • • 启用SELinux后,你可能会遇到can't open lock file /run/xtables.lock: Permission denied错误。解决此问题的方法是sudo dnf install -y policycoreutils-python-utils && sudo semanage permissive -a iptables_t。此问题已在moby / moby#41230中进行了跟踪。

  • • 已知可在CentOS 8和Fedora 33上工作。

Ubuntu

  • • 无需准备。

  • • overlay2默认情况下启用存储驱动程序(特定于Ubuntu的内核补丁)。

  • • 已知可在Ubuntu 16.04、18.04和20.04上运行

UID/GID 映射配置

从属用户和组的映射由两个配置文件来控制,分别是 /etc/subuid 和 /etc/subgid使用以下命令为 rootless 用户设置 65536 个从属用户和组的映射。

echo "rootless:100000:65536" | tee /etc/subuid
echo "rootless:100000:65536" | tee /etc/subgid

对于 subuid,这一行记录的含义为:用户 rootless,在当前的 user namespace 中具有 65536 个从属用户,用户 ID 为 100000-165535,在一个子 user namespace 中,这些从属用户被映射成 ID 为 0-65535 的用户。subgid 的含义和 subuid 相同。

比如说用户 rootless 在宿主机上只是一个具有普通权限的用户。我们可以把他的一个从属 ID (比如 100000 )分配给容器所属的 user namespace,并把 ID 100000 映射到该 user namespace 中的 uid 0。此时即便容器中的进程具有 root 权限,但也仅仅是在容器所在的 user namespace 中,一旦到了宿主机中,顶多也就有 rootless 用户的权限而已。

安装 Rootless Docker

切换到 rootless 用户。

su - rootless 

执行以下命令安装 Rootless Docker。

curl -fsSL https://get.docker.com/rootless | sh

安装成功后显示如下内容。

$ curl -fsSL https://get.docker.com/rootless | sh
# Installing stable version 24.0.5
# Executing docker rootless install script, commit: b9139c0
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100 66.5M  100 66.5M    0     0  1235k      0  0:00:55  0:00:55 --:--:-- 1373k
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100 19.4M  100 19.4M    0     0  1096k      0  0:00:18  0:00:18 --:--:-- 1233k
+ PATH=/home/rootless/bin:/usr/lib64/qt-3.3/bin:/usr/local/bin:/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/home/rootless/.local/bin:/home/rootless/bin
+ /home/rootless/bin/dockerd-rootless-setuptool.sh install
[INFO] systemd not detected, dockerd-rootless.sh needs to be started manually:

PATH=/home/rootless/bin:/sbin:/usr/sbin:$PATH dockerd-rootless.sh 

[INFO] Creating CLI context "rootless"
Successfully created context "rootless"
[INFO] Using CLI context "rootless"
Current context is now "rootless"

[INFO] Make sure the following environment variable(s) are set (or add them to ~/.bashrc):
# WARNING: systemd not found. You have to remove XDG_RUNTIME_DIR manually on every logout.
export XDG_RUNTIME_DIR=/home/rootless/.docker/run
export PATH=/home/rootless/bin:$PATH

[INFO] Some applications may require the following environment variable too:
export DOCKER_HOST=unix:///home/rootless/.docker/run/docker.sock

将以下内容添加到 ~/.bashrc 文件中,添加完以后使用 source ~/.bashrc 命令使环境变量生效。

export XDG_RUNTIME_DIR=/home/rootless/.docker/run
export PATH=/home/rootless/bin:$PATH
export DOCKER_HOST=unix:///home/rootless/.docker/run/docker.sock

启动 Docker 守护进程

方式1:带systemd(强烈推荐)

systemd文件默认位置为 ~/.config/systemd/user/docker.service

使用systemctl --user管理守护程序的生命周期:

$ systemctl --user start docker

要在系统启动时启动守护程序,请启用systemd服务并持续进行以下操作:

$ systemctl --user enable docker
$ sudo loginctl enable-linger $(whoami)

即使使用User=指令,也不支持将Rootless Docker作为全系统范围的服务(/etc/systemd/system/docker.service)启动。

关于目录路径的说明:

  • • 套接字默认路径为$XDG_RUNTIME_DIR/docker.sock。 $XDG_RUNTIME_DIR通常设置为/run/user/$UID

  • • 数据目录默认设置为~/.local/share/docker。数据目录不应位于NFS上。

  • • 守护程序配置目录默认设置为~/.config/docker。此目录~/.docker与客户端使用的目录不同。

sudo loginctl enable-linger $(whoami)解释

这个命令是用于启用用户的 linger(保持)设置,让用户的会话在用户注销后继续运行。让我详细解释一下这个命令的各个部分:

  1. 1. sudosudo 是一个用于以超级用户权限执行命令的工具。在这里,它用于确保我们有足够的权限来执行后续的命令。

  2. 2. loginctlloginctl 是一个用于管理 Linux 登录会话和用户登录状态的工具。它可以用于查看、控制和管理用户登录会话。

  3. 3. enable-linger: 这是 loginctl 的一个子命令,用于启用用户的 linger 设置。Linger 是一个控制登录会话是否在用户注销后继续运行的机制。启用 linger 后,用户注销后,其登录会话将继续运行,直到手动停止。

  4. 4. $(whoami): 这部分是一个命令替换,它会被当前登录用户的用户名所替代。whoami 命令用于获取当前登录用户的用户名。

因此,整个命令的目的是以超级用户权限启用当前登录用户的 linger 设置,使其登录会话在用户注销后继续运行。这在某些情况下可能会很有用,例如,如果你希望在用户注销后继续运行某些后台任务或服务。请谨慎使用这个命令,因为它可能会导致系统资源被占用,特别是在多用户环境中。

方式2:没有systemd

dockerd-rootless.sh

必须设置以下环境变量:

  • • $HOME:用户目录

  • • $XDG_RUNTIME_DIR:临时目录,只有预期的用户可以访问,例如~/.docker/run。该目录应在每次主机关闭时删除。该目录可以位于tmpfs上,但是不应位于之/tmp下。在此/tmp目录下,可能容易受到TOCTOU攻击。

客户端

需要明确指定套接字路径或CLI上下文。

要指定套接字路径,请使用$DOCKER_HOST

export DOCKER_HOST=unix://$XDG_RUNTIME_DIR/docker.sock
$ docker run -d -p 8080:80 nginx

要指定CLI上下文,请使用docker context

$ docker context use rootless
rootless
Current context is now "rootless"
$ docker run -d -p 8080:80 nginx

运行容器

使用以下命令启动一个 nginx 容器,并将 80 端口映射到宿主机的 8080 端口。

docker run -d -p 8080:80 nginx

查看容器。

[rootless@demo ~]$ docker ps
CONTAINER ID   IMAGE     COMMAND                  CREATED         STATUS         PORTS                                   NAMES
f3b204c97a84   nginx     "/docker-entrypoint.…"   9 minutes ago   Up 9 minutes   0.0.0.0:8080->80/tcp, :::8080->80/tcp   bold_stonebraker

访问容器。

$ curl http://localhost:8080

# 返回结果 Nginx 欢迎界面
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>

Rootless 模式调试技巧

进入dockerd名称空间

dockerd-rootless.sh脚本,会在其自己的user,mount和network 名称空间中执行dockerd

为了进行调试,你可以通过以下明立进入名称空间Rootless 模式

nsenter -U --preserve-credentials -n -m -t $(cat $XDG_RUNTIME_DIR/docker.pid)

Rootless 模式卸载

要删除Docker守护程序的systemd服务,请运行dockerd-rootless-setuptool.sh uninstall

dockerd-rootless-setuptool.sh 默认位置:/home/rootless/bin/dockerd-rootless-setuptool.sh

$ dockerd-rootless-setuptool.sh uninstall
+ systemctl --user stop docker.service
+ systemctl --user disable docker.service
Removed /home/testuser/.config/systemd/user/default.target.wants/docker.service.
[INFO] Uninstalled docker.service
[INFO] This uninstallation tool does NOT remove Docker binaries and data.
[INFO] To remove data, run: `/usr/bin/rootlesskit rm -rf /home/testuser/.local/share/docker`

要删除数据目录,请运行rootlesskit rm -rf ~/.local/share/docker

要删除二进制文件,docker-ce-rootless-extras请在软件包管理器中安装了Docker的情况下删除软件包。如果你使用https://get.docker.com/rootless安装了Docker,请删除以下二进制文件`~/bin`:

cd ~/bin
rm -f containerd containerd-shim containerd-shim-runc-v2 ctr docker docker-init docker-proxy dockerd dockerd-rootless-setuptool.sh dockerd-rootless.sh rootlesskit rootlesskit-docker-proxy runc vpnkit

Rootless Docker 与 Podman

RedHat Inc 的 Podman 是另一种流行的容器引擎,用于运行和管理容器。它被誉为以Rootless 运行是其相对于 docker 引擎的功能之一。通过Rootless Docker ,弥合了差距,现在它们具有几乎相同的功能和几乎相同的性能。他们之间还使用大量相同的代码。

Rootless Docker 不支持指定 docker run --net=host 。但如果你确实需要使用 docker run --net=host,Podman 可能是你更好的选择。

总结

Docker Rootless模式是官方提供的一种安全解决方案,可以让Docker守护进程以普通用户身份运行,从而避免容器应用利用Docker漏洞获得宿主机root权限的风险。

另外,要注意的是因为Docker作为容器本身需要利用很多系统高级特性,因此Docker守护进程以非Root身份运行实际上也会导致一些功能受限。这点可以参与官方文档详细了解。

(版权归原作者所有,侵删)


微信扫码关注该文公众号作者

戳这里提交新闻线索和高质量文章给我们。
相关阅读
教育随笔(118)也谈思维科学中国军事力量在亚洲能排第一吗?快了!快了!锻炼孩子咀嚼力,滑嫩有弹性,一周一次安排上!HRoot:2023HRoot全球人力资源服务机构50强榜单与白皮书OpenTelemetry Protocol (OTLP) 1.0.0 版本发布人在日本,但这件懒人变美神器,我给你们都安排上了麻州一流学区,富豪名流聚居地,本周学区豪宅精选--Newton/Weston/Dover/Wellesley/Brookline新版疫苗加强针不安全?佛罗里达卫生局再唱“反调”,不建议民众接种~真的不安全吗?中Z、中R连爆惊天大雷,有钱人的钱都不安全了?比佛利也不安全了!两名居民下午散步时,遭两歹徒持枪抢劫,2块劳力士手表被撸走...红茶、绿茶、花茶......通通安排上,茶香极速到家!电话手表也不安全了?小心骗子盯上未成年!35岁妈妈第一次做这件事,重新美回20多岁?想要变美显年轻,建议赶紧安排上(不是医美)一口补钙,两口补锌,三口满满DHA!这种早餐给娃安排上,长高长壮身体棒返团|轻松长高5公分!身高弯道超车的秘密武器安排上了!这支自费疫苗强烈建议打!5岁前赶紧给孩子安排上!太不安全了!8大道2男直接入室持枪抢劫!嫌疑人在逃中...记一次容器环境下出现Address not available小心!多伦多Yonge/Finch热门停车场不安全了:多名华人车被偷!蒙特利尔华人夫妇经营饺子店, 无故遭殴打袭击! "这座城市越来越不安全了"…适合孩子用的夏季驱蚊好物!能当发夹的可爱驱蚊夹快安排上~Shanghai FTZ at 10: Businesses Eye Enhanced Policies for Growth预告 | 别催啦!磨了大半年的学习桌,总算给大家安排上了!暑假宅家费爹费妈?怎么会!是不是没把手工活动安排上?Docker的使用案例以及未来发展、Docker Hub 服务、环境安全、容器部署安全澳洲牛羊肉批发价格腰斩,Woolies、Coles却不降价!为啥?团丨抢跑双十一!全家我都安排上了,看到就是赚到!长篇小说连载《此世,此生》第五十二章四加州富人区也不安全了!两名居民下午散步时,遭两歹徒持枪抢劫,2块劳力士手表被撸走...The lessons from Microsoft’s startling comeback | 商论双语15种全谷物搭配,免泡和大米同熟!一口补蛋白,两口补纤维,营养还低脂,快给全家人安排上!周末随笔活着就好坐食有鱼小狸奴(续)仅本周!任意电影院、任意场次票价仅$4!《奥本海默》《芭比》统统安排上!
logo
联系我们隐私协议©2024 redian.news
Redian新闻
Redian.news刊载任何文章,不代表同意其说法或描述,仅为提供更多信息,也不构成任何建议。文章信息的合法性及真实性由其作者负责,与Redian.news及其运营公司无关。欢迎投稿,如发现稿件侵权,或作者不愿在本网发表文章,请版权拥有者通知本网处理。