Docker的 privileged 选项解析(特权模式:赋予容器几乎与主机相同的权限)

Runtime privilege and Linux capabilities

参考官方文档:Docker run reference

By default, Docker containers are “unprivileged” and cannot, for example, run a Docker daemon inside a Docker container. This is because by default a container is not allowed to access any devices, but a “privileged” container is given access to all devices (see the documentation on cgroups devices).

The –privileged flag gives all capabilities to the container. When the operator executes docker run –privileged, Docker will enable access to all devices on the host as well as set some configuration in AppArmor or SELinux to allow the container nearly all the same access to the host as processes running outside containers on the host. Additional information about running with –privileged is available on the Docker Blog.

Docker 容器的安全性

Linux Namespace 和 Capabilities

Docker使用Linux namespace和capabilities来实现容器隔离和限制权限。

Linux Namespace:Docker利用namespace技术,使得每个容器都有其自己的进程、网络、挂载、用户ID等独立的空间。这保证了容器与容器之间以及容器与主机之间的隔离性。
Capabilities:Linux capabilities允许将传统的root权限分割成多个不同的能力,例如CAP_NET_ADMIN能力允许操作网络配置,CAP_CHOWN能力允许改变文件所有权。Docker默认情况下会赋予容器一些必要的capabilities,但不包括全部的能力,从而降低了被攻击的风险。

Docker 通过 –cap-add 和 –cap-drop 两个参数,可以灵活地添加或删除容器的 capabilities。

docker run --cap-add=SYS_PTRACE --rm -it alpine

上面 --cap-add=SYS_PTRACE 的意思就是:给容器添加 SYS_PTRACE 权限,允许容器内的进程可以 ptrace 和 debug 其他进程。

Docker限制和权限

在默认情况下,Docker对容器的权限进行了严格的限制,只提供了有限的capabilities。此外,许多系统级别的操作(例如挂载文件系统、修改内核参数等)都是被禁止的。这种安全模型使得Docker可以在不牺牲安全性的前提下,实现轻量级的虚拟化。

然而,在某些情况下,我们可能需要赋予容器更多的权限。例如,如果我们需要在容器中运行一些需要特权的服务(如网络设备管理、硬件设备接口等),那么默认的权限可能就不够用了。这时候,--privileged=true 选项就派上了用场。

Docker的–privileged=true选项

当使用–privileged=true选项运行容器时,Docker会赋予容器几乎与主机相同的权限。 具体来说,这个选项做了以下两件事情:

 给容器添加了所有的capabilities
允许容器访问主机的所有设备

–privileged=true的风险

尽管 --privileged=true 选项为容器提供了强大的功能,但它也带来了一些严重的安全隐患。由于privileged容器具有几乎与主机相同的权限,所以如果容器被恶意代码控制,那么攻击者就可以轻易地突破容器的边界,对主机进行任意操作。

因此,我们需要谨慎地使用 --privileged=true 选项,只在真正需要的情况下才启用它。在可能的情况下,我们应该尽量使用其他更细粒度的权限控制手段,例如通过--cap-add--device参数来分别添加必要的capabilities或设备访问权限。

细粒度的权限控制手段

# 添加单个capability
docker run --rm --cap-add NET_ADMIN -it alpine sh

# 添加设备访问权限
docker run --device=/dev/sda:/dev/xvdc -it alpine

docker-compose 参考

version: "3"
services:
 baicai_image:
 image: debian
 container_name: "baicai_image"
 restart: unless-stopped
 command: run -c /app/config.json
 volumes:
 - ./config.json:/app/config.json
 environment:
 TZ: Asia/Shanghai
 ports:
 - "80:80"
 privileged: false
 cap_add:
 - NET_ADMIN
 - SYS_MODULE
 - SYS_PTRACE
 - SYS_ADMIN
 - NET_RAW
 cap_drop:
 - ALL

附注: 在Docker Debian容器中安装ps、top等命令

debian镜像默认没有包括进程管理相关工具,在实际使用时可能有些麻烦,如果需要也可以自己安装,使用如下命令。

apt update && apt install -y procps

文章来源:

Author:白菜
link:https://blog.baicai.me/article/2023/docker_privileged/