0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

Docker Rootless的基本概念 Rootless模式如何运作

马哥Linux运维 来源:马哥Linux运维 2023-09-15 11:14 次阅读

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

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

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

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

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 docker和chmod +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 中已经存在很长时间了 。

f977a142-5303-11ee-a25d-92fbcf53809c.pngimg

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

Rootless 模式不使用具有SETUID位或文件功能的二进制文件,除了newuidmap和newgidmap,它们是允许在用户名称空间中使用多个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
CentOSLinuxrelease7.5.1804(Core)

创建普通用户

$useraddrootless
$echo123456|passwdrootless--stdin

安装依赖

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

cat</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"rootless65536"|tee/etc/subuid
echo"rootless65536"|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-fsSLhttps://get.docker.com/rootless|sh

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

$curl-fsSLhttps://get.docker.com/rootless|sh
#Installingstableversion24.0.5
#Executingdockerrootlessinstallscript,commit:b9139c0
%Total%Received%XferdAverageSpeedTimeTimeTimeCurrent
DloadUploadTotalSpentLeftSpeed
10066.5M10066.5M001235k0055055----1373k
%Total%Received%XferdAverageSpeedTimeTimeTimeCurrent
DloadUploadTotalSpentLeftSpeed
10019.4M10019.4M001096k0018018----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.shinstall
[INFO]systemdnotdetected,dockerd-rootless.shneedstobestartedmanually:

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

[INFO]CreatingCLIcontext"rootless"
Successfullycreatedcontext"rootless"
[INFO]UsingCLIcontext"rootless"
Currentcontextisnow"rootless"

[INFO]Makesurethefollowingenvironmentvariable(s)areset(oraddthemto~/.bashrc):
#WARNING:systemdnotfound.YouhavetoremoveXDG_RUNTIME_DIRmanuallyoneverylogout.
exportXDG_RUNTIME_DIR=/home/rootless/.docker/run
exportPATH=/home/rootless/bin:$PATH

[INFO]Someapplicationsmayrequirethefollowingenvironmentvariabletoo:
exportDOCKER_HOST=unix:///home/rootless/.docker/run/docker.sock

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

exportXDG_RUNTIME_DIR=/home/rootless/.docker/run
exportPATH=/home/rootless/bin:$PATH
exportDOCKER_HOST=unix:///home/rootless/.docker/run/docker.sock

启动 Docker 守护进程

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

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

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

$systemctl--userstartdocker

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

$systemctl--userenabledocker
$sudologinctlenable-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.sudo:sudo是一个用于以超级用户权限执行命令的工具。在这里,它用于确保我们有足够的权限来执行后续的命令。

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

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

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

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

方式2:没有systemd

dockerd-rootless.sh

必须设置以下环境变量:

•$HOME:用户目录

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

客户端

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

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

$exportDOCKER_HOST=unix://$XDG_RUNTIME_DIR/docker.sock
$dockerrun-d-p8080:80nginx

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

$dockercontextuserootless
rootless
Currentcontextisnow"rootless"
$dockerrun-d-p8080:80nginx

运行容器

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

dockerrun-d-p8080:80nginx

查看容器。

[rootless@demo~]$dockerps
CONTAINERIDIMAGECOMMANDCREATEDSTATUSPORTSNAMES
f3b204c97a84nginx"/docker-entrypoint.…"9minutesagoUp9minutes0.0.0.0:8080->80/tcp,:::8080->80/tcpbold_stonebraker

访问容器。

$curlhttp://localhost:8080

#返回结果Nginx欢迎界面



Welcometonginx!



Welcometonginx!

Ifyouseethispage,thenginxwebserverissuccessfullyinstalledand working.Furtherconfigurationisrequired.

Foronlinedocumentationandsupportpleasereferto nginx.org.
Commercialsupportisavailableat nginx.com.

Thankyouforusingnginx.

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.shuninstall
+systemctl--userstopdocker.service
+systemctl--userdisabledocker.service
Removed/home/testuser/.config/systemd/user/default.target.wants/docker.service.
[INFO]Uninstalleddocker.service
[INFO]ThisuninstallationtooldoesNOTremoveDockerbinariesanddata.
[INFO]Toremovedata,run:`/usr/bin/rootlesskitrm-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-fcontainerdcontainerd-shimcontainerd-shim-runc-v2ctrdockerdocker-initdocker-proxydockerddockerd-rootless-setuptool.shdockerd-rootless.shrootlesskitrootlesskit-docker-proxyruncvpnkit

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身份运行实际上也会导致一些功能受限。这点可以参与官方文档详细了解。

审核编辑:汤梓红

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 内核
    +关注

    关注

    3

    文章

    1309

    浏览量

    39862
  • Linux
    +关注

    关注

    87

    文章

    10992

    浏览量

    206744
  • 容器
    +关注

    关注

    0

    文章

    481

    浏览量

    21884
  • root
    +关注

    关注

    1

    文章

    82

    浏览量

    21236
  • Docker
    +关注

    关注

    0

    文章

    437

    浏览量

    11603

原文标题:容器快了,却不安全了,Rootless 安排上

文章出处:【微信号:magedu-Linux,微信公众号:马哥Linux运维】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    Proteus涉及的基本概念

    Proteus涉及的基本概念
    发表于 08-01 20:58

    电子元件基本概念和原理

    电子元件基本概念和原理
    发表于 08-05 21:25

    Fpga Cpld的基本概念

    Fpga Cpld的基本概念
    发表于 08-20 17:14

    C语言基本概念

    C语言基本概念
    发表于 08-01 02:00

    数据结构的基本概念是什么

    数据结构之基本概念
    发表于 05-27 08:29

    阻抗控制相关的基本概念

    阻抗控制部分包括两部分内容:基本概念及阻抗匹配。本篇主要介绍阻抗控制相关的一些基本概念
    发表于 02-25 08:11

    智能天线的基本概念

    1智能天线的基本概念 智能天线综合了自适应天线和阵列天线的优点,以自适应信号处理算法为基础,并引入了人工智能的处理方法。智能天线不再是一个简单的单元,它已成为一个具有智能的系统。其具体定义为:智能
    发表于 08-05 08:30

    CODESYS的基本概念有哪些

    CODESYS是什么?CODESYS的基本概念有哪些?CODESYS有哪些功能?
    发表于 09-18 06:52

    缺省适配器模式基本概念

    在这一节我们就看一看第一类:缺省适配器模式一、缺省适配器模式基本概念1.1 说明当不需要全部实现接口提供的方法时,可以设计一个适配器抽象类实现接口,并为接口中的每个方法提供默认方法,抽象类的子类
    发表于 11-11 07:53

    对象适配器模式基本概念

    在这一节我们就看一看第一类:对象适配器模式一、对象适配器模式基本概念1.1 说明对象适配器模式在运行时实现target(目标)接口。在这种适配器模式
    发表于 11-11 07:09

    ESP8266 WIFI模块基本概念与工作模式简析

    ESP8266 WIFI模块基本概念工作模式常用AT指令基本概念ATK-ESP8266模块采用串口(LVTTL)与MCU(或其他串口设备)通信,内置TCP/IP协议栈,能够实现串口与WIFI之间
    发表于 01-18 06:16

    Docker不香吗为什么还要用K8s

    Docker 虽好用,但面对强大的集群,成千上万的容器,突然感觉不香了。 这时候就需要我们的主角 Kubernetes 上场了,先来了解一下 K8s 的基本概念,后面再介绍实践,由浅入深步步为营
    的头像 发表于 06-02 11:56 3205次阅读

    时序分析基本概念介绍—花一样的“模式

    今天要介绍的时序基本概念是Mode(模式). 这是Multiple Scenario环境下Sign off的一个重要概念。芯片的设计模式包括最基本的功能function
    的头像 发表于 07-10 17:21 1988次阅读
    时序分析<b class='flag-5'>基本概念</b>介绍—花一样的“<b class='flag-5'>模式</b>”

    线性稳压器和开关模式电源(SMPS)的基本概念

    电子发烧友网站提供《线性稳压器和开关模式电源(SMPS)的基本概念.pdf》资料免费下载
    发表于 11-24 14:47 0次下载
    线性稳压器和开关<b class='flag-5'>模式</b>电源(SMPS)的<b class='flag-5'>基本概念</b>

    Docker网络的基本概念和原理与用法

    桥接网络(Bridge Network):这是 Docker 容器默认使用的网络类型。每个独立的容器都会连接到一个内部网络的私有网桥。 主机网络(Host Network):在这种模式下,容器共享主机的网络命名空间,直接使用主机的网络接口。
    发表于 03-18 12:26 113次阅读
    <b class='flag-5'>Docker</b>网络的<b class='flag-5'>基本概念</b>和原理与用法