Files
docker_practice/18_security/18.3_daemon_sec.md
2026-02-25 21:06:21 -08:00

87 lines
4.2 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

## 18.3 服务端防护
Docker 守护进程`dockerd`是容器生命周期的核心驱动力默认情况下Docker 服务的运行需要极高的系统特权root 权限因此其安全性关系到整台宿主机的生死存亡
如果 Docker 守护进程的访问控制没有做好恶意攻击者可以通过 Docker API 轻易地启动一个特权容器并将宿主机的根目录`/`挂载到容器中从而完全接管服务器
为了加强对服务端的保护我们需要从访问控制通信加密和权限最小化三个维度进行加固
### 18.3.1 限制 API 访问
Docker 客户端`docker` 命令通过 REST API 与守护进程进行通信
在早期版本中Docker 有时会绑定在 `127.0.0.1` TCP 套接字上但这容易遭遇跨站脚本跨协议攻击现在的发行版默认使用 Unix Domain Socket`/var/run/docker.sock`并依赖文件系统的权限控制
#### 原则 1决不可将无认证的 TCP 端口暴露在公网
这是最常见的 Docker 被入侵抓去挖矿的原因绝不能在没有任何安全控制的情况下强行开启 `-H tcp://0.0.0.0:2375`
如果业务确实需要远程访问 Docker 守护进程**必须启用 TLS 认证机制**让客户端和服务端互相进行证书校验
#### 开启 TLS 认证双向加密
利用安全机制确保只有经过授权的主机网络并在强证书保护下进行通信
1. 首先使用 `openssl` 或基于本地 CA 工具生成一套客户端与服务器的证书
2. 配置 Docker 守护进程通常是 `daemon.json` `dockerd` 启动参数指定证书路径
```bash
dockerd \
--tlsverify \
--tlscacert=ca.pem \
--tlscert=server-cert.pem \
--tlskey=server-key.pem \
-H=0.0.0.0:2376
```
3. 客户端想要连接时也必须出示客户端证书
> [!TIP]
> 配置 TLS 生成证书的完整步骤可以查阅 [Docker 官方 TLS 文档](https://docs.docker.com/engine/security/protect-access/)。在现代编排系统(如 Kubernetes通常会有自动化方案管理这些凭据。
### 18.3.2 保护本地 Socket 访问
哪怕不开启网络端口本地的 `/var/run/docker.sock` 也需要谨慎对待
任何被授予该 Socket 读写权限的用户通常被加入 `docker` 用户组等同于拥有了对宿主机的零成本提权途径无需密码的免密 `sudo` 权限
> [!CAUTION]
> 永远不要将不可信的普通用户加入到 `docker` 用户组中同样在容器编排时尽量避免将宿主机的 `/var/run/docker.sock` 直接映射给普通容器使用这种模式被称为 Docker-in-Docker (DinD) Docker-out-of-Docker (DooD)存在极高的越权风险
### 18.3.3 Rootless 模式 (非特权运行)
为了从根本上解决拥有 Docker socket 就是 root的问题Docker 在近年推出了 **Rootless 模式**
Rootless 模式允许在完全局限于非 `root` 用户的环境中运行 Docker 守护进程`dockerd`和容器该模式利用了现代 Linux 内核的 User Namespace 技术和非特权网络命名空间实现
#### 配置运行 Rootless Docker
要在非 root 环境中运行 Docker只需要简单几步
1. 安装必要的依赖通常是 `uidmap` 工具包以便系统支持 `newuidmap` `newgidmap`
```bash
$ sudo apt-get install uidmap
```
2. 切换到一个没有任何 `sudo` 权限的普通用户假设用户名为 `testuser`
```bash
$ su - testuser
```
3. 运行 Docker 官方提供的 Rootless 安装脚本
```bash
$ curl -fsSL https://get.docker.com/rootless | sh
```
4. 配置环境变量指向新创建的私有 socket
```bash
$ export DOCKER_HOST=unix:///run/user/1000/docker.sock
$ docker version
```
安装并暴露相应的配置后该用户的环境将能独立启动属于他自己的 Docker Daemon即使由于某些未知 0-Day 漏洞使得攻击者突破了容器他们也只会受限于 `testuser` 这个非特权用户所在的有限系统环境内
### 18.3.4 结语
保障 Docker 服务端的安全主要是做减法关闭不必要的网络监听点严管 Socket 访问权限而一旦基础系统条件允许**毫不犹豫地在生产环境启用 Rootless 模式**将是一项划算的安全加固选择