技术博客

Docker 合规与审计:等保 2.0 要求、daemon 审计日志与容器安全基线

系统讲解 Docker 生产环境的合规与审计要求:等保 2.0 三级对容器平台的具体要求(身份鉴别、访问控制、安全审计、入侵防范)、Docker daemon 的 auditd 审计配置(记录谁在何时做了什么操作)、CIS Docker Benchmark 安全基线检查(docker-bench-security 工具)、容器安全基线的自动化评估、合规扫描报告生成,以及持续合规监控方案。

Docker安全合规等保2.0审计CIS基线docker-bench-security安全运维

容器化系统面临与传统系统同等甚至更高的合规要求。等保 2.0 三级(现在叫网络安全等级保护制度)要求对系统运行状态进行全面审计,而容器的短暂性(容器重启日志消失)和动态性(大量容器频繁创建销毁)给合规带来了新挑战。本文讲解 Docker 合规审计的完整方案。

等保 2.0 与容器的关系

等保 2.0 三级(GB/T 22239-2019)核心要求与容器对应:

安全通信网络
  要求:网络传输加密
  容器:Docker daemon TLS、容器网络 overlay 加密

安全区域边界
  要求:访问控制、入侵检测
  容器:网络隔离(internal network)、iptables 规则、Falco 入侵检测

安全计算环境
  要求:身份鉴别、访问控制、安全审计、入侵防范、资源控制
  容器:非 root 运行、RBAC(Harbor)、auditd 审计、Seccomp/AppArmor、资源限制

安全管理中心
  要求:系统管理、安全管理、审计管理
  容器:Harbor RBAC、操作审计日志、集中日志(Loki/ELK)

一、Docker daemon 审计配置(auditd)

1.1 安装和配置 auditd

# 安装
apt-get install auditd    # Debian/Ubuntu
yum install audit         # RHEL/CentOS

# 启动
systemctl enable auditd
systemctl start auditd

1.2 Docker 相关审计规则

# /etc/audit/rules.d/docker.rules
# 等保要求:记录对 Docker 关键文件和目录的所有访问

# Docker daemon 可执行文件
-w /usr/bin/docker -p rwxa -k docker
-w /usr/bin/dockerd -p rwxa -k docker

# Docker daemon 配置文件
-w /etc/docker -p rwxa -k docker-config
-w /etc/docker/daemon.json -p rwxa -k docker-config

# Docker Socket(谁访问了 Docker API)
-w /var/run/docker.sock -p rwxa -k docker-socket

# 容器数据目录
-w /var/lib/docker -p rwxa -k docker-data

# Docker service 文件
-w /usr/lib/systemd/system/docker.service -p rwxa -k docker-service
-w /etc/systemd/system/docker.service.d -p rwxa -k docker-service

# containerd(底层运行时)
-w /usr/bin/containerd -p rwxa -k container-runtime
-w /usr/bin/containerd-shim -p rwxa -k container-runtime
-w /usr/bin/runc -p rwxa -k container-runtime

# 网络相关(容器网络操作)
-a exit,always -F arch=b64 -S sethostname -k docker-network
-a exit,always -F arch=b64 -S mount -k docker-mount

# 装载内核模块(容器逃逸常用)
-w /sbin/insmod -p x -k kernel-module
-w /sbin/rmmod -p x -k kernel-module
-w /sbin/modprobe -p x -k kernel-module
-a always,exit -F arch=b64 -S init_module -k kernel-module
# 应用审计规则
auditctl -R /etc/audit/rules.d/docker.rules

# 重启 auditd 使规则永久生效
service auditd restart

# 验证规则已加载
auditctl -l | grep docker

1.3 查询审计日志

# 查询 Docker Socket 访问记录(谁访问了 Docker API)
ausearch -k docker-socket --start today | aureport -f -i

# 查询特定时间范围内的 Docker 操作
ausearch -k docker \
    --start 2026-03-08 00:00:00 \
    --end 2026-03-08 23:59:59 \
    | aureport -x -i

# 查询是否有异常的模块加载(可能的提权操作)
ausearch -k kernel-module --start today | tail -20

# 生成审计报告(每日)
aureport --start today --tty-report    # TTY 相关操作报告
aureport --start today --auth-report   # 认证报告
aureport --start today --file-report   # 文件访问报告

二、CIS Docker Benchmark 安全基线

2.1 docker-bench-security 工具

# 运行 CIS Docker Benchmark 检查
docker run --rm \
    -v /var/run/docker.sock:/var/run/docker.sock \
    -v /var/lib:/var/lib:ro \
    -v /var/run/docker:/var/run/docker:ro \
    -v /usr/lib/systemd:/usr/lib/systemd:ro \
    -v /etc:/etc:ro \
    --label docker_bench_security \
    docker/docker-bench-security

# 输出示例(节选):
# [INFO] 1 - Host Configuration
# [WARN] 1.1.1 - Ensure a separate partition for containers has been created
# [PASS] 1.1.2 - Ensure only trusted users are allowed to control Docker daemon
# [WARN] 1.1.3 - Ensure auditing is configured for the Docker daemon
# [PASS] 1.1.4 - Ensure auditing is configured for Docker files and directories
# ...
# [INFO] 2 - Docker daemon configuration
# [PASS] 2.1 - Ensure network traffic is restricted between containers on the default bridge
# [WARN] 2.2 - Ensure the logging level is set to 'info'
# [PASS] 2.3 - Ensure Docker is allowed to make changes to iptables
# ...
# [INFO] 4 - Container Images and Build Files
# [WARN] 4.1 - Ensure that a user for the container has been created
# [PASS] 4.2 - Ensure that containers use only trusted base images

2.2 CIS Benchmark 关键检查项

# 手动检查关键项目(无法运行工具时)

# 检查1:确认独立分区存储容器数据
df -h /var/lib/docker
# /dev/sdb1   100G   35G   65G  35% /var/lib/docker  ← 独立分区 ✓

# 检查2:审计规则
auditctl -l | grep docker | wc -l
# 应该 > 0

# 检查3:ICC 禁用状态
docker network inspect bridge --format '{{.Options}}' | grep icc
# map[com.docker.network.bridge.enable_icc:false ...]  ← ✓

# 检查4:Content Trust
echo $DOCKER_CONTENT_TRUST
# 1   ← 已开启

# 检查5:非 root 容器比例
docker ps -q | xargs docker inspect --format '{{.Name}} {{.Config.User}}' | \
    awk '{print $2}' | sort | uniq -c
# 数量较多的空值("")代表以 root 运行,需要关注

# 检查6:特权容器
docker ps -q | xargs docker inspect --format '{{.Name}} {{.HostConfig.Privileged}}' | \
    grep true
# 有输出则说明存在特权容器,需要评估是否必要

# 检查7:共享命名空间
docker ps -q | xargs docker inspect --format \
    '{{.Name}} PID:{{.HostConfig.PidMode}} NET:{{.HostConfig.NetworkMode}} IPC:{{.HostConfig.IpcMode}}' | \
    grep -E 'host'
# 列出使用 host 命名空间的容器

# 检查8:内存限制
docker ps -q | xargs docker inspect --format '{{.Name}} {{.HostConfig.Memory}}' | \
    awk '$2=="0"{print $1" 未设置内存限制"}'

三、等保 2.0 专项合规检查

3.1 身份鉴别

# 要求:对操作 Docker 的用户进行身份鉴别

# 检查1:docker 组成员控制
getent group docker
# 确认只有授权人员在 docker 组

# 检查2:Harbor 用户认证
# Harbor → 管理员 → 认证模式
# 推荐:LDAP/AD 集成(统一身份)

# 检查3:登录失败锁定
# 配置 pam_faillock(系统账户)
cat /etc/pam.d/system-auth | grep faillock

# 检查4:密码策略
# Harbor 的密码策略(Harbor UI 中设置)
# 最小长度 8,包含大小写+数字+特殊字符

3.2 访问控制

# 要求:最小权限,拒绝未授权访问

# Docker daemon 访问控制清单
echo "Docker 组成员(每人的必要性需评估):"
getent group docker

echo "Harbor 用户与角色:"
curl -s -u admin:Harbor12345 \
    https://harbor.company.com/api/v2.0/projects/backend/members \
    | jq '.[] | {username: .entity_name, role: .role_name}'

# 容器安全配置合规检查
docker ps -q | while read ID; do
    NAME=$(docker inspect $ID --format '{{.Name}}')
    USER=$(docker inspect $ID --format '{{.Config.User}}')
    PRIV=$(docker inspect $ID --format '{{.HostConfig.Privileged}}')
    CAP=$(docker inspect $ID --format '{{.HostConfig.CapAdd}}')
    
    echo "${NAME}:"
    [ -z "$USER" ] && echo "  ⚠️  以 root 运行"
    [ "$PRIV" = "true" ] && echo "  ❌ 特权模式!"
    [ "$CAP" != "[]" ] && echo "  ⚠️  额外 capabilities: $CAP"
done

3.3 安全审计

# 要求:记录用户行为,日志保留 6 个月以上

# Docker 操作日志(通过 auditd)
# 已配置(见第一节)

# 容器内应用日志(Loki 保留 30 天,需要延长到 180 天)
# loki-config.yml
# limits_config:
#   retention_period: 4320h   # 180 天

# Harbor 操作审计日志
curl -s -u admin:Harbor12345 \
    "https://harbor.company.com/api/v2.0/audit-logs?page_size=20" \
    | jq '.[] | {operation: .operation, resource: .resource, username: .username, op_time: .op_time}'

# 生成每日安全审计报告
cat > /usr/local/bin/daily-docker-audit.sh << 'SCRIPT'
#!/bin/bash
DATE=$(date +%Y-%m-%d)
REPORT="/var/log/docker-audit/${DATE}.txt"
mkdir -p /var/log/docker-audit

echo "=== Docker 安全审计报告 ${DATE} ===" > $REPORT
echo "" >> $REPORT

echo "# Docker Socket 访问记录" >> $REPORT
ausearch -k docker-socket --start yesterday --end today 2>/dev/null | \
    grep -E "auid|comm|exe" | head -50 >> $REPORT

echo "" >> $REPORT
echo "# Docker 配置文件变更" >> $REPORT
ausearch -k docker-config --start yesterday --end today 2>/dev/null | \
    grep -E "auid|name|type=PATH" | head -20 >> $REPORT

echo "" >> $REPORT
echo "# 特权操作统计" >> $REPORT
echo "特权容器数量:$(docker ps -q | xargs docker inspect --format '{{.HostConfig.Privileged}}' | grep -c true)" >> $REPORT
echo "Root 用户容器数量:$(docker ps -q | xargs docker inspect --format '{{.Config.User}}' | grep -c '^$')" >> $REPORT

echo "" >> $REPORT
echo "# 容器运行状态" >> $REPORT
docker ps --format "table {{.Names}}\t{{.Image}}\t{{.Status}}" >> $REPORT

echo "报告生成完毕:${REPORT}"
SCRIPT

chmod +x /usr/local/bin/daily-docker-audit.sh
echo "0 6 * * * root /usr/local/bin/daily-docker-audit.sh" > /etc/cron.d/docker-audit

四、入侵检测(Falco)

# Falco:容器运行时安全监控(CNCF 项目)
# 监控系统调用,实时检测可疑行为

# docker-compose.falco.yml
services:
  falco:
    image: falcosecurity/falco:latest
    container_name: falco
    restart: unless-stopped
    privileged: true      # Falco 需要特权访问内核
    volumes:
      - /var/run/docker.sock:/host/var/run/docker.sock:ro
      - /dev:/host/dev:ro
      - /proc:/host/proc:ro
      - /boot:/host/boot:ro
      - /lib/modules:/host/lib/modules:ro
      - /usr:/host/usr:ro
      - ./falco/falco.yaml:/etc/falco/falco.yaml:ro
      - ./falco/rules:/etc/falco/rules.d:ro
    command: /usr/bin/falco --cri /run/containerd/containerd.sock
# falco/rules/docker.yaml — 检测可疑容器行为
- rule: Shell Spawned in Container
  desc: 在容器内启动 shell(可能是攻击者获得 shell 访问)
  condition: spawned_process and container and shell_procs and not ci_allow
  output: |
    容器内启动 shell(user=%user.name container=%container.name
    image=%container.image.repository proc=%proc.name parent=%proc.pname)
  priority: WARNING
  tags: [container, shell, mitre_execution]

- rule: Write to Sensitive Files
  desc: 写入敏感系统文件(可能是提权尝试)
  condition: >
    open_write and container
    and (fd.name startswith /etc or fd.name startswith /bin or fd.name startswith /sbin)
    and not nginx_allow and not container.image.repository contains "chainguard"
  output: |
    写入敏感文件(user=%user.name file=%fd.name container=%container.name)
  priority: ERROR

- rule: Container Escape Attempt
  desc: 可能的容器逃逸尝试
  condition: >
    spawned_process and container
    and proc.name in (nsenter, unshare, pivot_root)
  output: 可能的容器逃逸尝试(proc=%proc.name container=%container.name)
  priority: CRITICAL

五、合规基线自动化评估

# 生成合规评估报告(综合检查)
cat > /usr/local/bin/compliance-check.sh << 'SCRIPT'
#!/bin/bash

PASS=0; FAIL=0; WARN=0

check() {
    local desc=$1; local cmd=$2; local expect=$3
    result=$(eval "$cmd" 2>/dev/null)
    if echo "$result" | grep -q "$expect"; then
        echo "✅ PASS: $desc"; ((PASS++))
    else
        echo "❌ FAIL: $desc (got: $result)"; ((FAIL++))
    fi
}

warn_check() {
    local desc=$1; local cmd=$2; local expect=$3
    result=$(eval "$cmd" 2>/dev/null)
    if echo "$result" | grep -q "$expect"; then
        echo "✅ PASS: $desc"; ((PASS++))
    else
        echo "⚠️  WARN: $desc"; ((WARN++))
    fi
}

echo "=== Docker 合规基线检查 $(date) ==="
echo ""

echo "--- 宿主机配置 ---"
check "Docker 数据目录在独立分区" "df /var/lib/docker" "/var/lib/docker"
check "auditd 已安装并运行" "systemctl is-active auditd" "active"
check "Docker 审计规则已配置" "auditctl -l" "docker"

echo ""
echo "--- Docker daemon 配置 ---"
check "ICC 已禁用" "docker network inspect bridge --format '{{.Options}}'" "enable_icc:false"
check "用户命名空间重映射" "docker info" "userns"
warn_check "内容信任已启用" "echo \$DOCKER_CONTENT_TRUST" "1"
check "daemon TLS 或仅 Unix socket" \
    "docker info --format '{{.SecurityOptions}}'" "seccomp"

echo ""
echo "--- 容器运行时 ---"
PRIV_COUNT=$(docker ps -q | xargs docker inspect --format '{{.HostConfig.Privileged}}' 2>/dev/null | grep -c true)
ROOT_COUNT=$(docker ps -q | xargs docker inspect --format '{{.Config.User}}' 2>/dev/null | grep -c '^$')
echo "特权容器数:${PRIV_COUNT}(应为 0 或经审批)"
echo "Root 运行容器数:${ROOT_COUNT}(应最小化)"

echo ""
echo "=== 合规检查结果 ==="
echo "通过:$PASS  失败:$FAIL  警告:$WARN"
SCRIPT

chmod +x /usr/local/bin/compliance-check.sh

小结

Docker 合规与审计的核心是可见性与可追溯性:任何对容器环境的操作都应该有记录,记录应该能够追溯到具体的人和时间,记录应该保留足够长的时间。

等保 2.0 三级对容器环境的要求,可以通过以下四层覆盖:auditd 审计宿主机级别的操作(谁运行了 docker 命令)、Harbor RBAC 控制镜像的访问权限、集中日志系统(Loki)保存容器内应用日志 180 天以上、Falco 提供实时运行时入侵检测。

docker-bench-security 是快速评估安全基线的最佳工具,建议纳入定期合规扫描流程(每月至少一次),并将检查结果作为安全改进的量化依据。