Docker 容器安全基线:别用 root 跑容器

docker run 一把梭很爽,但默认配置下容器离 root 只差一个漏洞。小够讲 Docker 容器的安全基线:非 root 用户运行、去掉多余 capability、只读文件系统、可信镜像源,几行参数的事,别等出事再补。

我是小够。VPS 上用 Docker 的人越来越多,但很多人的容器都是 docker run 一把梭,安全全靠默认。今天讲容器安全基线——不深,几行参数,但能挡掉一大类风险。

第一条:别用 root 跑容器

默认情况下,容器里的 root 映射到宿主机的 root(除非配了 user namespace)。容器逃逸漏洞虽然少,但一旦发生就是宿主机沦陷。改法很简单:

docker run --user 1000:1000 ...

或者在 Dockerfile 里:

RUN useradd -m appuser
USER appuser

很多官方镜像已经提供了非 root 变体,优先用。改完记得验证应用还能读写它需要的数据卷——权限问题是切换用户后最常见的坑,chown 一下数据目录就行。

第二条:去掉多余的 capability

容器默认带着一堆 Linux capability(比如 NET_ADMIN、SYS_ADMIN),大部分应用根本用不上。用 --cap-drop=ALL 全去掉,再按需加回:

docker run --cap-drop=ALL --cap-add=NET_BIND_SERVICE ...

Web 服务只需要绑定端口的话,加回 NET_BIND_SERVICE 就够了。capability 越少,逃逸后能干的事越少。

第三条:文件系统只读

应用代码不需要在运行时修改,就把容器文件系统设成只读:

docker run --read-only -v /data:/data:rw ...

只读 + 指定可写的数据卷,攻击者就算进了容器,也写不下恶意文件、装不了后门。这是性价比极高的一招。

第四条:镜像来源要可信

  • 优先用官方镜像(nginx、postgres 等官方库)。
  • 第三方镜像看 stars、看 Dockerfile 是否公开、看更新频率。
  • 生产环境 pin 住具体版本号,别用 latest——latest 今天和明天可能不是同一个东西,出问题都不知道从哪查起。
  • 定期 docker pull 更新基础镜像,补已知漏洞。

第五条:别把 Docker socket 挂进容器

docker run -v /var/run/docker.sock:/var/run/docker.sock ...

这行配置等于把宿主机的 Docker 控制权交给了容器,拿到 socket 就等于拿到宿主机 root。除非你在跑 Portainer 这类管理工具且清楚风险,否则永远别挂载它。

第六条:资源限制

docker run --memory=512m --cpus=1 ...

限制内存和 CPU,防止某个容器被打爆后拖垮整台机器。这既是安全(防 DoS 放大),也是稳定。

第七条:user namespace 隔离

前面说容器里的 root 默认映射到宿主机 root,可以用 user namespace remap 改掉:在 /etc/docker/daemon.json 里加:

{
  "userns-remap": "default"
}

重启 Docker 后,容器里的 root 在宿主机上只是一个普通用户。就算发生容器逃逸,攻击者拿到的是普通用户权限,危害小得多。注意:开了之后已有容器的数据卷权限可能要重新 chown,新机器上直接开最省心。

第八条:seccomp profile

seccomp 限制容器能调用的系统调用。Docker 默认带了一个 seccomp profile,已经禁掉了 40 多个危险调用(如 mount、reboot),对大多数应用够用了。别手贱加 --security-opt seccomp=unconfined 关掉它——除非你明确知道应用需要某个被禁的调用,查文档确认后再放行单个。

第九条:扫描镜像漏洞

镜像里的软件也有漏洞,定期扫一扫。截至撰写时,Trivy 是用得较多的开源扫描器:

trivy image nginx:1.27

扫出高危漏洞就升级镜像版本。CI 里可以加一道门:高危漏洞不让发布。个人用户每月手动扫一次在用的镜像就行,养成习惯。

第十条:别忽视 Docker 本身的更新

容器安全的前提是 Docker 引擎本身没漏洞。docker --version 看一眼版本,跟着官方更新走。引擎漏洞虽然少,但一旦出就是大事——毕竟所有容器都跑在它上面。

第十一条:docker bench,一键体检

想快速知道自己的 Docker 配置有多少问题,可以跑官方的检查脚本 docker-bench-security:

git clone https://github.com/docker/docker-bench-security.git
cd docker-bench-security
sudo sh docker-bench-security.sh

它会逐项检查:是不是 root 跑的、有没有开特权模式、文件系统是不是只读等等,最后给 PASS/WARN 列表。截至撰写时这个项目还在维护,跑一遍 1 分钟,对照 WARN 一项项修,是很好的"查漏补缺"工具。注意:有些 WARN 是业务需要的(比如确实需要某个 capability),理解后再决定修不修,别为了全 PASS 把业务搞挂了。

小够的总结:容器安全和 VPS 安全是同一个思路——最小权限。容器里别用 root、能力别多给、文件系统能只读就只读。Docker 的方便不应该以安全为代价,这几行参数加上,容器就从"裸奔"变成了"穿戴整齐"。