14 10 月 2026

Docker 默认配置是「好用优先」,不是「安全优先」:容器以 root 跑、资源不设上限、宿主机内核共享。这篇把这些坑一个个填上——容器逃逸、资源失控、镜像投毒、敏感信息泄露四类风险各有解法,全部有命令。

需要现成的游戏云服务器,可以看看财富云计算:一键开服面板,NAT 型无独立公网 IP,价格比独立 IP 机型省一半以上,主流游戏都能快速部署,安全基线面板已内置。

一、风险清单:Docker 到底危在哪里

风险场景后果
容器逃逸容器进程拿到 root + 特权模式控制宿主机
资源失控某容器内存泄漏/无限 fork宿主机 OOM,所有服务陪葬
镜像投毒拉到来路不明的镜像,内置挖矿程序CPU 打满、电费/云费飙升
密钥泄露密码写进 Dockerfile 或镜像历史镜像一扩散,秘密全公开
数据卷越权挂载了 / 或敏感目录容器可读写宿主机任意文件
供应链攻击基础镜像被篡改后门直接进入生产

二、运行参数加固:docker run 的安全姿势

2.1 最小权限运行

docker run -d \
  --name myapp \
  --user 1000:1000 \            # 非 root 用户(UID:GID)
  --read-only \                 # 根文件系统只读,临时文件走 tmpfs
  --tmpfs /tmp \                # 需要写的目录挂内存盘
  --cap-drop ALL \              # 丢掉全部 Linux capabilities
  --cap-add NET_BIND_SERVICE \  # 只加回必要的(如绑 80 端口)
  --security-opt no-new-privileges \  # 禁止 setuid 提权
  --memory 512m \               # 内存上限(必须!)
  --cpus 1.0 \                  # CPU 上限
  -p 127.0.0.1:8080:80 \        # 只绑本地回环,由反代对外
  myapp:1.0.0

参数含义逐条说:

参数防什么
--user 1000:1000容器内拿不到 root,逃逸门槛抬高
--read-only + --tmpfs恶意程序没法往磁盘写持久化后门
--cap-drop ALL容器进程没有任何特权能力(默认有 14 项)
--security-opt no-new-privileges阻断 setuid/setgid 提权链
--memory / --cpus单容器故障不拖垮宿主机
-p 127.0.0.1:8080:80服务端口不直接暴露公网

2.2 绝对不要用的参数

--privileged          # 特权模式,几乎等于放弃隔离
--pid host            # 看到宿主机全部进程
--network host        # 共享宿主机网络栈
--ipc host            # 共享进程间通信
-v /:/host            # 挂载宿主机根目录
--cap-add SYS_ADMIN   # 几乎万能提权 capability

游戏服场景常见误区:为了「性能」给容器加 --privileged——绝大多数游戏根本不需要。真需要特定能力,用 --cap-add 精确加一项,比如 SYS_NICE 调优先级。

三、docker-compose 安全模板

services:
  app:
    image: registry.example.com/app:1.2.3   # 锁版本,不用 latest
    user: "1000:1000"
    read_only: true
    tmpfs:
      - /tmp
    cap_drop:
      - ALL
    security_opt:
      - no-new-privileges:true
    mem_limit: 512m
    cpus: 1.0
    pids_limit: 200                    # 进程数上限,防 fork 炸弹
    restart: unless-stopped
    ports:
      - "127.0.0.1:8080:80"            # 对外交给 Nginx 反代
    environment:
      - DB_PASSWORD_FILE=/run/secrets/db_password   # 密钥走文件不落镜像
    secrets:
      - db_password
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost/health"]
      interval: 30s
      timeout: 3s
      retries: 3
    logging:                           # 日志也要限,防写爆磁盘
      driver: json-file
      options:
        max-size: "50m"
        max-file: "3"

secrets:
  db_password:
    file: ./secrets/db_password.txt

mem_limit、pids_limit、日志轮转这三项是救命配置,宿主机被一个容器拖死的案例,90% 是缺这三样。

四、Docker 守护进程加固

只加固容器不够,Docker 本身也要收口。

4.1 不要暴露 2375 端口

# 查看 docker 是否监听在公网
ss -tlnp | grep 2375

2375 是 Docker API 明文端口,暴露公网 = 把宿主机 root 权限送出去(历史上被大量矿工扫描)。正确做法:只监听本地 unix socket,远程管理走 SSH 隧道或 TLS 认证的 2376。

4.2 限制非 root 用户用 docker

能跑 docker 命令 = 有 root 权限(因为 docker 组等价于 root)。生产机器只给必要账号加入 docker 组,或者用 rootless 模式。

4.3 rootless Docker(进阶)

# 官方 rootless 安装脚本
curl -fsSL https://get.docker.com/rootless | bash

# 当前用户免 sudo 跑 docker,守护进程本身以普通用户身份运行
# 即使容器被打穿,拿到的也只是你的普通用户权限

rootless 适合个人服务器/开发机;生产集群用 K8s + PodSecurity 更彻底。

4.4 开启 user namespace remapping

/etc/docker/daemon.json:

{
  "userns-remap": "default"
}

改完 systemctl restart docker。效果:容器里的 root(UID 0)映射到宿主机上的普通用户,逃逸了也不是真 root。

五、镜像安全:从拉取到运行

5.1 只从可信来源拉镜像

# 官方镜像优先:docker pull nginx 而不是某第三方 nginx-optimized
# 验证镜像摘要,防止源被篡改
docker pull nginx@sha256:xxxxxxxx...

5.2 扫描漏洞

# Trivy(开源,免费,最常用)
docker run --rm aquasec/trivy image --severity HIGH,CRITICAL myapp:1.2.3

# Docker 官方扫描
docker scout cves myapp:1.2.3

扫描结果要分级处理:CRITICAL/HIGH 必须修或评估,LOW/MEDIUM 记录跟踪。别被 LOW 级漏洞吓到不敢上线,也别对 CRITICAL 视而不见。

5.3 定期更新基础镜像

# 每季度重建一次镜像,拉取最新基础镜像补丁
docker build --pull --no-cache -t myapp:1.2.4 .

漏洞修在基础镜像里,你不重建就永远打不上补丁。CI 里加一条定时任务自动构建,见Dockerfile 编写与镜像优化。

5.4 私密信息不进镜像

# 错误:Dockerfile 里写密码,任何人 docker history 都能看到
ENV DB_PASSWORD=123456

# 正确一:运行时注入
docker run -e DB_PASSWORD=$(cat /run/secrets/db_pw) myapp

# 正确二:BuildKit secret,构建时用完即焚
docker build --secret id=db_pw,src=./secrets/db_pw .
# Dockerfile 里:
RUN --mount=type=secret,id=db_pw cat /run/secrets/db_pw

已经写进镜像的密码,改代码重新构建是唯一解法,删历史层救不回来。

六、资源限制:为什么必须设

不设限制的容器,一个内存泄漏就能吃光宿主机内存,触发内核 OOM Killer 乱杀进程——杀哪个看内核心情,经常是杀掉你的数据库。

# 查看容器实时资源占用
docker stats

# 单个容器详情(含限制)
docker inspect myapp --format '{{.HostConfig.Memory}} {{.HostConfig.Cpus}}'

三层防护配齐:

层级配置防的场景
单容器--memory --cpus --pids_limit单容器发疯
宿主机总内存留 20% 余量、监控告警多容器集体膨胀
编排层K8s ResourceQuota / LimitRange团队滥用

告警规则照抄:Prometheus 监控里加一条 container_memory_usage_bytes / limit > 0.85 持续 5 分钟即报警,提前干预。

七、应急:怀疑容器被入侵

# 1. 看进程:容器里有没有可疑进程(挖矿通常是 xmrig/kdevtmpfsi)
docker top myapp

# 2. 看网络连接
docker exec myapp ss -tlnp

# 3. 看文件变动:对比镜像内文件(需要镜像里有 shell)
docker exec myapp sh -c "find /app -newer /app/main -type f"

# 4. 看镜像历史有无可疑层
docker history --no-trunc myapp

# 5. 确认沦陷:立即隔离——断网但不删(保留证据)
docker network disconnect bridge myapp
docker exec myapp cat /var/log/nginx/access.log > /tmp/evidence.log

处置顺序:先断网止血 → 导出日志证据 → 分析入口 → 重建容器 → 修补配置。不要一慌了事直接删容器,日志证据没了就查不到入侵路径。更完整的响应流程见数据泄露应急响应。

八、一页清单(打印贴墙)

  • [ ] 所有容器 --user 非 root 运行
  • [ ] --cap-drop ALL,按需加回
  • [ ] --read-only + --tmpfs
  • [ ] --memory / --cpus / --pids_limit 全配上
  • [ ] 日志 max-size + max-file
  • [ ] 镜像锁版本号,禁 latest
  • [ ] 构建走 --pull,每季度重建补丁
  • [ ] Trivy 扫描接入 CI,CRITICAL 不过线
  • [ ] 密钥运行时注入,镜像历史无明文
  • [ ] Docker API 不暴露公网
  • [ ] 端口绑定 127.0.0.1 + 反代对外
  • [ ] daemon.json 开 userns-remap

Docker 安全的核心思想就一句:默认不信任何人,包括容器里的进程。上面十二条配齐,市面上 90% 的容器安全事故都和你无关。

需要自带安全基线的游戏云服务器,可以看看财富云计算:一键开服面板,NAT 型无独立公网 IP,价格比独立 IP 机型省一半以上,主流游戏都能快速部署。延伸阅读:SSH 安全加固进阶、Docker 部署网站实战、端口速查表。

延伸阅读
  1. 网站环境怎么选:LNMP 手动 / 宝塔面板 / Docker / 云开发
  2. 问卷表单系统搭建:SurveyKing / Formbricks,数据自己收
  3. 图床搭建:Lsky Pro / Lychee,自托管图片托管方案
  4. 邮件列表搭建:listmonk 自托管 Newsletter,把读者握在自己手里
  5. 文档站点搭建:MkDocs / VuePress / Docsify,产品文档与技术手册方案
  6. RSS 阅读器搭建:FreshRSS 自托管,把信息流拿回自己手里
  7. 短链接服务搭建:Shlink 自托管,链接数据自己掌握
  8. 网站状态监控页搭建:Uptime Kuma,服务器挂了第一时间知道
更多阅读
  1. 上一篇:Dockerfile 编写与镜像优化实战:镜像缩小 90%
  2. 下一篇:幻兽帕鲁开服教程(Linux 版):从零搭一台 24 小时在线的服务器
发表评论 5

取消回复