【问题标题】:Docker root access to host systemDocker root 访问主机系统
【发布时间】:2017-02-02 23:28:14
【问题描述】:

当我以普通用户身份运行容器时,我可以在我的主机文件系统上映射 和修改 root 拥有的目录。这似乎是一个很大的安全漏洞。例如,我可以执行以下操作:

$ docker run -it --rm -v /bin:/tmp/a debian
root@14da9657acc7:/# cd /tmp/a
root@f2547c755c14:/tmp/a# mv df df.orig
root@f2547c755c14:/tmp/a# cp ls df
root@f2547c755c14:/tmp/a# exit

现在我的 host 文件系统将在输入df 时执行ls 命令(大部分是无害的示例)。我不敢相信这是理想的行为,但它正在我的系统中发生(debian 拉伸)。 docker 命令具有正常权限(755,不是 setuid)。

我错过了什么?

也许再澄清一点是件好事。目前我对容器本身的功能或功能不感兴趣,也不关心容器内的根访问权限。

相反,我注意到我系统上任何可以运行 docker 容器的人都可以使用它来获得对我的 主机 系统的 root 访问权限,并以 root 身份读/写他们想要的任何内容:有效地为所有用户提供 root使用权。这显然不是我想要的。如何预防?

【问题讨论】:

    标签: docker


    【解决方案1】:

    有许多 Docker 安全功能可用于帮助解决 Docker 安全问题。对您有帮助的具体方法是用户命名空间。

    基本上,您需要在预先停止 Docker 守护程序的主机上启用用户命名空间:

    dockerd --userns-remap=default &
    

    请注意,这将禁止容器在特权模式下运行(从安全角度来看这是一件好事)并重新启动 Docker 守护程序(在执行此命令之前应该停止它)。进入 Docker 容器时,可以将其限制为当前非特权用户:

    docker run -it --rm -v /bin:/tmp/a --user UID:GID debian
    

    不管怎样,之后尝试使用你的默认命令进入 Docker 容器

    docker run -it --rm -v /bin:/tmp/a debian
    

    如果您尝试操作映射到 Docker 卷(在本例中为 /bin)的主机文件系统,其中文件和目录由 root 拥有,那么您将收到 Permission denied 错误。这证明用户命名空间提供了您正在寻找的安全功能。

    我建议在https://github.com/docker/labs/tree/master/security/userns 上通过 Docker 实验室了解此安全功能。我已经完成了所有的实验室,并在那里打开了问题和 PR,以确保那里的实验室的完整性,并可以为他们担保。

    【讨论】:

    • 但是作为我主机系统上的普通用户,我可以运行(例如)标准 debian 映像,并且 授予我 root 访问权限主机。该实验室表示:“但是,它也存在潜在的安全风险。”这是相当轻描淡写的说法。它不应该说:永远不要以这种方式运行 docker,因为它为您的所有用户提供了对主机系统的 root 访问权限。
    • 谢谢。现在很清楚,我不应该允许任何普通用户运行 docker,而是为他们这样做。实验室指针也很有用。
    • 非管理员用户是否可以轻松覆盖此设置,或者您认为这是一种确保安装安全的相当安全的方式?
    • @BSUK 它需要是具有 root 权限的人,或者是对主机上的 Docker 和服务具有提升权限的人。
    • 是否可以阻止用户在主机上没有的访问权限(例如写入绑定挂载的 /bin)并仍然允许用户在主机上拥有的访问权限(例如写入绑定-挂载的主目录)?
    【解决方案2】:

    在主机上运行 docker 命令的访问权限是对该主机上的 root 的访问权限。这是该工具的设计,因为挂载文件系统和隔离应用程序的功能需要 Linux 上的根功能。这里的安全漏洞是任何授予用户访问权限以运行 docker 命令的系统管理员,否则他们不会信任该主机上的 root 访问权限。因此,应该小心地将用户添加到 docker 组。

    如果使用得当,我仍然认为 Docker 是一种安全改进,因为在容器内运行的应用程序受到限制,无法对主机执行任何操作。造成损坏的能力是通过运行容器的显式选项给出的,例如将根文件系统安装为 rw 卷、直接访问设备或向根添加允许转义命名空间的功能。除非显式创建这些安全漏洞,否则在容器内运行的应用程序的访问权限要比在容器外运行时少得多。

    如果您仍想尝试锁定有权访问 docker 的用户,还有一些额外的安全功能。用户命名空间是阻止容器内部的 root 在主机上具有 root 访问权限的其中之一。还有interlock,它允许您限制每个用户可用的命令。

    【讨论】:

    • 这显然是我对这个概念的误解。谢谢。
    • 但是如果我被允许创建和运行 docker 容器,因为我的工作需要我这样做,我可以使用 docker 用户 root 运行它们,并将 /etc 之类的文件夹挂载到容器中。然后我可以使用主机的root 权限访问该文件夹中的文件。我刚刚尝试过,在主机上编辑/etc 中的文件,而不使用sudo。有用。我可以直接从 docker 容器中编辑文件,或者更改权限并在主机上仅使用普通用户权限进行编辑。我的误解在哪里?
    • @HendrikWiese dockerd 以 root 身份运行,因此如果您以用户身份直接 API 访问以 root 身份运行的守护程序,则您具有 root 访问权限。该 API 访问权限不是普通用户权限。
    • @HendrikWiese 要求您在主机上运行 docker 容器的情况需要 root 访问权限。 Docker 不是一个虚拟化平台,它是一个进程容器。 docker 命令也不是用户空间,它(默认情况下)需要 sudo。
    【解决方案3】:

    您缺少默认情况下在内部以 uid 0 运行的容器。所以这是意料之中的。如果您想在容器内更多地限制权限,请在 Dockerfile 中使用 USER 语句构建它。这将在运行时将 setuid 设置为指定用户,而不是以 root 身份运行。

    请注意,此用户的 uid 不一定是可预测的,因为它是在您构建的映像内部分配的,并且不一定映射到外部系统上的任何内容。但是,关键是,它不会是 root。

    请参阅Dockerfile reference 了解更多信息。

    【讨论】:

    • 我知道在容器内我以 uid 0 运行。没关系。但是,如果我将 /bin(甚至 /)从主机系统映射到容器中的某个目录,我就可以访问主机文件系统,并且可以访问和修改任何内容。所以我在容器内的命令将外部文件系统修改为 root。
    • @SjaakDalens 我不确定您的目标是什么,但您有多种选择。将卷映射为只读,构建映像以使用非特权用户...
    猜你喜欢
    • 1970-01-01
    • 2019-09-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-01-24
    • 2016-09-13
    相关资源
    最近更新 更多