2、Docker守护进程安全:配置daemon.json、TLS认证、限制守护进程权限、审计日志配置
聊到Docker安全,守护进程(dockerd)绝对是第一道防线。我见过太多团队把精力全放在镜像扫描上,结果守护进程裸奔在公网——说白了,门都没锁,墙再高也没用。
这一章,我们聚焦四个核心动作:配置daemon.json、启用TLS认证、限制守护进程权限、审计日志配置。嗯,每一条都是我踩过坑之后才真正重视起来的。
2.1 配置daemon.json:把安全基线写进配置文件
Docker守护进程的默认配置其实挺松的。我个人习惯,拿到一台新机器,第一件事就是检查 /etc/docker/daemon.json 是否存在。如果不存在?说明你正在用默认参数跑,风险不小。
来看一个我常用的安全基线配置:
{
"icc": false,
"log-driver": "json-file",
"log-opts": {
"max-size": "10m",
"max-file": "3"
},
"live-restore": true,
"userland-proxy": false,
"iptables": true,
"ip-forward": true,
"ip-masq": false,
"bridge": "none",
"storage-driver": "overlay2",
"exec-opts": ["native.cgroupdriver=systemd"],
"selinux-enabled": true,
"authorization-plugins": []
}
这里有几个关键点,我重点说一下:
- icc: false —— 禁止容器间通信。除非你明确需要,否则关掉它。我在一个金融项目里遇到过,攻击者通过一个被攻陷的容器横向扩散,就是因为icc没关。
- userland-proxy: false —— 关闭用户态代理,改用iptables DNAT。性能更好,攻击面更小。
- live-restore: true —— 守护进程重启时,容器不挂。这个在生产环境太重要了,我曾经因为升级Docker导致所有容器重启,差点被运维同事拉黑。
- bridge: "none" —— 不创建默认bridge网络。你想想看,默认网络里的容器可以互相通信,这其实是个安全隐患。
systemctl daemon-reload && systemctl restart docker。但重启前,务必确认 live-restore 已开启,否则容器会全部停掉。
2.2 TLS认证:别让你的Docker端口裸奔
Docker默认监听在 /var/run/docker.sock,这是Unix socket,相对安全。但如果你需要远程管理,暴露2375端口——嗯,这就是在给黑客送人头。
我建议的做法:启用TLS双向认证。说白了,客户端和服务端都要验证对方的证书。
生成证书的步骤,我整理成了一张表:
| 步骤 | 命令 | 说明 |
|---|---|---|
| 1. 创建CA私钥 | openssl genrsa -aes256 -out ca-key.pem 4096 |
CA密钥,务必保管好 |
| 2. 生成CA证书 | openssl req -new -x509 -days 365 -key ca-key.pem -sha256 -out ca.pem |
CA自签名证书 |
| 3. 生成服务端密钥 | openssl genrsa -out server-key.pem 4096 |
服务端私钥 |
| 4. 生成服务端CSR | openssl req -subj "/CN=<你的IP>" -new -key server-key.pem -out server.csr |
CN填Docker主机IP |
| 5. 签发服务端证书 | openssl x509 -req -days 365 -in server.csr -CA ca.pem -CAkey ca-key.pem -CAcreateserial -out server-cert.pem |
得到服务端证书 |
| 6. 生成客户端密钥 | openssl genrsa -out key.pem 4096 |
客户端私钥 |
| 7. 生成客户端CSR | openssl req -subj '/CN=client' -new -key key.pem -out client.csr |
CN固定为client |
| 8. 签发客户端证书 | openssl x509 -req -days 365 -in client.csr -CA ca.pem -CAkey ca-key.pem -CAcreateserial -out cert.pem |
得到客户端证书 |
证书生成后,修改daemon.json,加上TLS配置:
{
"tls": true,
"tlsverify": true,
"tlscacert": "/etc/docker/certs/ca.pem",
"tlscert": "/etc/docker/certs/server-cert.pem",
"tlskey": "/etc/docker/certs/server-key.pem",
"hosts": ["tcp://0.0.0.0:2376", "unix:///var/run/docker.sock"]
}
docker --tlsverify --tlscacert=ca.pem --tlscert=cert.pem --tlskey=key.pem -H tcp://你的IP:2376 ps。我习惯把这些参数写进 ~/.docker/config.json,省得每次敲一长串。
2.3 限制守护进程权限:最小权限原则
Docker守护进程默认以root运行,权限非常大。你想想看,如果攻击者控制了dockerd,基本上就等于控制了整台宿主机。
我常用的限制手段有三个:
- 使用非root用户运行dockerd —— 虽然Docker官方不推荐,但你可以通过sudo或systemd的User=指令来降权。不过要注意,降权后有些功能(比如绑定低端口)会受限。
- 启用用户命名空间(userns-remap) —— 这个我强烈推荐。它把容器内的root映射成宿主机上的普通用户,即使容器被攻破,攻击者拿到的也是普通用户权限。
- 限制dockerd可访问的资源 —— 通过systemd的
LimitNOFILE、LimitNPROC等参数,防止dockerd耗尽系统资源。
配置userns-remap的示例:
{
"userns-remap": "default"
}
这个配置会让Docker自动创建一个 dockremap 用户和用户组,并把容器内的UID/GID映射到宿主机的高位UID上。我曾经在一个多租户平台上用过这个功能,效果很好——即使某个容器被提权,它也只能在映射后的命名空间里折腾,影响不了宿主机。
2.4 审计日志配置:出了事得有据可查
安全审计这件事,平时觉得烦,出了事才知道有多重要。我记得有一次排查安全事件,就是因为没有审计日志,花了整整两天才定位到问题源头。
Docker的审计日志,我建议从两个层面入手:
- Docker守护进程自身的日志 —— 通过
--log-driver和--log-opts配置,把日志输出到json-file或syslog。我习惯用json-file,配合日志轮转,防止磁盘写满。 - 系统层面的auditd审计 —— 监控Docker相关的系统调用和文件访问。
配置auditd监控Docker守护进程:
# /etc/audit/rules.d/docker.rules
-w /usr/bin/docker -p wa -k docker
-w /var/lib/docker -p wa -k docker
-w /etc/docker -p wa -k docker
-w /run/docker.sock -p wa -k docker
-w /usr/lib/systemd/system/docker.service -p wa -k docker
这些规则会监控Docker二进制文件、数据目录、配置文件、socket和systemd服务文件的写操作和属性修改。一旦有人动了这些文件,auditd就会记录下来。
查看审计日志的命令:
ausearch -k docker --start today
嗯,这里要注意,auditd的日志量可能会很大。我建议配合 auditd.conf 中的 max_log_file 和 num_logs 参数做轮转,避免日志撑爆磁盘。
核心要点回顾:
- daemon.json是安全基线的起点,别用默认配置
- TLS双向认证是远程管理的唯一安全方式
- userns-remap能有效隔离容器和宿主机权限
- 审计日志是事后追溯的关键,别省这一步
说实话,守护进程安全这部分,我每次给团队培训都会强调:配置再繁琐,也比被攻破后擦屁股强。下一章我们会聊镜像安全,那又是另一个战场了。