跳轉到內容

Docker 安全加固與容器安全最佳實踐 2026 | 從零構建安全容器環境

Docker 安全加固與容器安全

容器化帶來了部署效率的巨大提升,但也引入了新的安全挑戰。從鏡像漏洞到容器逃逸,從網絡隔離到權限控制,容器安全是一個系統性工程。本文將從鏡像安全、運行時安全、網絡安全等多個維度,全面講解 Docker 安全加固實踐。


一、容器安全概述

1.1 容器安全威脅模型

┌─────────────────────────────────────────────────────────────┐
│                   Docker 安全威脅層                         │
├─────────────────────────────────────────────────────────────┤
│  1. 鏡像層:漏洞鏡像、惡意軟件、敏感信息洩露                  │
│  2. 運行時層:容器逃逸、權限提升、資源濫用                    │
│  3. 網絡層:橫向移動、未授權訪問、數據洩露                    │
│  4. 宿主機層:內核漏洞、文件系統隔離失敗                      │
│  5. 供應鏈層:第三方鏡像、依賴漏洞、CI/CD 入侵                │
└─────────────────────────────────────────────────────────────┘

1.2 安全原則

  1. 最小權限原則:只授予必要的權限
  2. 最小攻擊面:減少不必要的組件和端口
  3. 縱深防禦:多層安全防護
  4. 默認安全:開箱即用的安全配置
  5. 持續監控:實時檢測和響應

二、鏡像安全

2.1 選擇安全的基礎鏡像

dockerfile
# ❌ 不安全:使用 latest 標籤,來源不明
FROM ubuntu:latest

# ✅ 安全:指定具體版本,使用官方鏡像
FROM ubuntu:22.04

# ✅ 更好:使用輕量級發行版
FROM alpine:3.19

# ✅ 最好:使用 distroless 鏡像(無 shell、無包管理器)
FROM gcr.io/distroless/nodejs20-debian12

2.2 多階段構建減少攻擊面

dockerfile
# 構建階段
FROM node:20-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY . .
RUN npm run build

# 運行階段(只包含運行時必要文件)
FROM node:20-alpine
WORKDIR /app
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/node_modules ./node_modules
COPY package.json ./

# 非 root 用戶運行
RUN addgroup -S appgroup && adduser -S appuser -G appgroup
USER appuser

EXPOSE 3000
CMD ["node", "dist/server.js"]

2.3 鏡像漏洞掃描

bash
# 使用 Trivy 掃描鏡像漏洞
trivy image myapp:latest

# 只顯示高危漏洞
trivy image --severity HIGH,CRITICAL myapp:latest

# 生成報告
trivy image --format json --output report.json myapp:latest

# CI/CD 集成(失敗條件:存在 CRITICAL 漏洞)
trivy image --exit-code 1 --severity CRITICAL myapp:latest

2.4 移除敏感信息

dockerfile
# ❌ 錯誤:在鏡像中硬編碼密鑰
ENV API_KEY=secret123
COPY .env .

# ✅ 正確:構建參數(不會保留在最終鏡像中)
ARG BUILD_ENV=production
RUN npm run build -- --mode=$BUILD_ENV

# ✅ 運行時注入環境變量
# docker run -e API_KEY=secret123 myapp

# 檢查鏡像中的敏感文件
trivy fs --security-checks secret ./

2.5 .dockerignore 最佳實踐

# .dockerignore
node_modules
npm-debug.log
.git
.gitignore
.env
.env.*
*.pem
*.key
*.crt
Dockerfile
.dockerignore
README.md
tests/
coverage/
.vscode/
.idea/

三、容器運行時安全

3.1 以非 root 用戶運行

dockerfile
# 創建非 root 用戶
RUN groupadd -r appuser && useradd -r -g appuser appuser

# 設置文件權限
COPY --chown=appuser:appuser app /app

# 切換用戶
USER appuser
bash
# 運行時指定用戶
docker run --user 1000:1000 myapp

# 驗證用戶
docker exec mycontainer whoami

3.2 只讀文件系統

bash
# 只讀根文件系統
docker run --read-only myapp

# 需要寫入的目錄用 tmpfs
docker run --read-only --tmpfs /tmp --tmpfs /var/run myapp
yaml
# docker-compose.yml
services:
  web:
    image: myapp
    read_only: true
    tmpfs:
      - /tmp
      - /var/run

3.3 限制資源使用

bash
# 內存限制
docker run -m 512m --memory-swap 1g myapp

# CPU 限制
docker run --cpus="1.5" myapp
docker run --cpu-shares 512 myapp  # 相對權重

# 限制進程數(防止 fork bomb)
docker run --pids-limit 100 myapp
yaml
services:
  web:
    image: myapp
    deploy:
      resources:
        limits:
          cpus: '2.0'
          memory: 1G
          pids: 100

3.4 禁用特權模式

bash
# ❌ 危險:特權模式(幾乎擁有宿主機所有權限)
docker run --privileged myapp

# ✅ 安全:只授予必要的能力
docker run --cap-drop=ALL --cap-add=NET_BIND_SERVICE myapp
yaml
services:
  web:
    image: myapp
    cap_drop:
      - ALL
    cap_add:
      - NET_BIND_SERVICE

3.5 安全選項

bash
# 禁用 seccomp(不推薦)
docker run --security-opt seccomp=unconfined myapp

# 使用自定義 seccomp 配置
docker run --security-opt seccomp=./seccomp-profile.json myapp

# 禁用 AppArmor(不推薦)
docker run --security-opt apparmor=unconfined myapp

# 禁止容器獲取新權限
docker run --security-opt no-new-privileges myapp

四、網絡安全

4.1 網絡隔離

yaml
services:
  frontend:
    image: nginx
    networks:
      - frontend
      - backend

  api:
    image: myapi
    networks:
      - backend
      - database

  db:
    image: postgres
    networks:
      - database

networks:
  frontend:
    driver: bridge
  backend:
    driver: bridge
  database:
    driver: bridge
    internal: true  # 內部網絡,無法訪問外網

4.2 端口安全

bash
# ❌ 危險:綁定到所有接口
docker run -p 5432:5432 postgres

# ✅ 安全:只綁定到 localhost
docker run -p 127.0.0.1:5432:5432 postgres

# ✅ 更好:不暴露端口,使用內部網絡通信

4.3 網絡策略

bash
# 查看容器網絡
docker network inspect mynetwork

# 限制容器間通信(使用自定義網絡 + iptables)

五、Docker 守護進程安全

5.1 配置 Docker daemon.json

json
// /etc/docker/daemon.json
{
  "icc": false,
  "live-restore": true,
  "no-new-privileges": true,
  "userland-proxy": false,
  "default-ulimits": {
    "nofile": {
      "Name": "nofile",
      "Hard": 64000,
      "Soft": 64000
    }
  },
  "log-driver": "json-file",
  "log-opts": {
    "max-size": "10m",
    "max-file": "3"
  },
  "storage-driver": "overlay2",
  "default-network-opt": {
    "bridge": {
      "com.docker.network.bridge.enable_icc": "false"
    }
  }
}

5.2 限制 Docker 守護進程權限

bash
# 不要以 root 運行 docker daemon(使用 systemd 管理)
systemctl status docker

# 查看 Docker 守護進程配置
cat /usr/lib/systemd/system/docker.service

5.3 Docker API 安全

bash
# ❌ 危險:暴露 Docker API 到公網
dockerd -H tcp://0.0.0.0:2375

# ✅ 安全:使用 TLS 加密
dockerd \
  --tlsverify \
  --tlscacert=ca.pem \
  --tlscert=server-cert.pem \
  --tlskey=server-key.pem \
  -H=0.0.0.0:2376

六、CIS Docker Benchmark

6.1 運行 CIS 基準測試

bash
# 使用 Docker Bench for Security
git clone https://github.com/docker/docker-bench-security.git
cd docker-bench-security
sh docker-bench-security.sh

6.2 CIS 基準核心檢查項

類別檢查項推薦配置
主機配置/etc/docker 目錄權限755
docker.sock 權限660
守護進程配置限制容器間通信icc: false
禁止獲取新權限no-new-privileges: true
日誌配置啟用日誌輪轉
容器配置非 root 用戶運行USER 指令
只讀根文件系統read_only: true
限制 capabilitiescap_drop: ALL
資源限制memory, cpus, pids
鏡像安全使用可信鏡像官方鏡像 + 簽名驗證
漏洞掃描定期掃描
移除敏感信息.dockerignore

七、漏洞掃描與監控

7.1 鏡像掃描工具

bash
# Trivy - 最流行的開源漏洞掃描器
trivy image myapp:latest

# 掃描文件系統
trivy fs ./

# 掃描 Git 倉庫
trivy repo https://github.com/example/repo

# 生成 HTML 報告
trivy image --format template --template "@contrib/html.tpl" -o report.html myapp

7.2 運行時安全監控

bash
# Falco - 容器運行時安全監控
# 安裝
curl -s https://falco.org/repo/falcosecurity-3672BA8F2BE0E017.key | apt-key add -
echo "deb https://download.falco.org/packages/deb stable main" > /etc/apt/sources.list.d/falcosecurity.list
apt-get update && apt-get install -y falco

# 啟動
systemctl start falco

# 查看告警
tail -f /var/log/falco.log

7.3 安全基線檢查

bash
# Docker Bench for Security
docker run -it \
  --net host \
  --pid host \
  --userns host \
  --cap-add audit_control \
  -e DOCKER_CONTENT_TRUST=$DOCKER_CONTENT_TRUST \
  -v /var/lib:/var/lib \
  -v /var/run/docker.sock:/var/run/docker.sock \
  -v /usr/lib/systemd:/usr/lib/systemd \
  -v /etc:/etc \
  --label docker_bench_security \
  docker/docker-bench-security

八、Docker Compose 安全配置

8.1 完整安全配置示例

yaml
version: '3.8'

services:
  web:
    image: myapp:latest
    user: "1000:1000"
    read_only: true
    security_opt:
      - no-new-privileges:true
    cap_drop:
      - ALL
    cap_add:
      - NET_BIND_SERVICE
    deploy:
      resources:
        limits:
          cpus: '2.0'
          memory: 1G
          pids: 100
    tmpfs:
      - /tmp
      - /var/run
    networks:
      - frontend
      - backend
    logging:
      driver: json-file
      options:
        max-size: "10m"
        max-file: "3"

  api:
    image: myapi:latest
    user: "1000:1000"
    read_only: true
    security_opt:
      - no-new-privileges:true
    cap_drop:
      - ALL
    deploy:
      resources:
        limits:
          cpus: '1.0'
          memory: 512M
          pids: 50
    tmpfs:
      - /tmp
    networks:
      - backend
      - database
    environment:
      - DB_HOST=db
      - DB_PASSWORD_FILE=/run/secrets/db_password
    secrets:
      - db_password

  db:
    image: postgres:15-alpine
    user: "999:999"
    read_only: true
    security_opt:
      - no-new-privileges:true
    cap_drop:
      - ALL
    volumes:
      - postgres_data:/var/lib/postgresql/data
    tmpfs:
      - /tmp
      - /var/run/postgresql
    networks:
      - database
    environment:
      - POSTGRES_PASSWORD_FILE=/run/secrets/db_password
    secrets:
      - db_password

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

volumes:
  postgres_data:

networks:
  frontend:
    name: frontend-net
  backend:
    name: backend-net
  database:
    name: database-net
    internal: true

九、最佳實踐總結

9.1 鏡像安全清單

9.2 運行時安全清單

9.3 運維安全清單


十、總結

  • ✅ 理解容器安全威脅模型與安全原則
  • ✅ 鏡像安全:選擇基礎鏡像、多階段構建、漏洞掃描
  • ✅ 運行時安全:非 root 用戶、只讀文件系統、資源限制、capabilities
  • ✅ 網絡安全:網絡隔離、端口安全、內部網絡
  • ✅ Docker 守護進程安全配置
  • ✅ CIS Docker Benchmark 合規檢查
  • ✅ 漏洞掃描與運行時監控
  • ✅ Docker Compose 安全配置完整示例

容器安全是一個持續的過程,需要在開發、部署、運行各個階段都加以重視。遵循最小權限原則和縱深防禦策略,才能構建真正安全的容器環境。


相關閱讀:

最後更新於: