集成 Auditd 记录容器对宿主机文件的异常访问

解读

在国内金融、运营商、政务云等合规场景下,**“容器逃逸”“越权访问宿主机文件”**是等保 2.0 与关基评测的高危项。面试官想知道你能否把 Linux 原生的 Auditd 审计框架与 Docker 的隔离模型打通,在不改容器镜像、不侵入业务进程的前提下,精准记录容器内进程对宿主机敏感路径(如 /etc、/var/run/docker.sock、/root/.ssh)的异常访问,并能在 SIEM/堡垒机侧统一收集、溯源。

知识点

  1. Auditd 三要素:规则(auditctl)、事件(audit.log)、监听(auditd.service)。
  2. Docker 的挂载传播机制:rprivate、rslave、rshared 对审计可见性的影响。
  3. 容器进程在宿主机 PID 命名空间的映射:/proc//ns/pid 与 /proc//root 联合定位真实路径。
  4. cgroup v1/v2 的 freezer 路径:/sys/fs/cgroup/*/docker/,可反向定位容器 ID。
  5. CAP_AUDIT_WRITE、CAP_AUDIT_CONTROL 能力集:容器默认无 AUDIT_CONTROL,防止容器内篡改规则。
  6. auditd 的“容器标签”插件:国内银河麒麟、统信 UOS 已合入的 audit-containerid 补丁,可把 container_id 写进事件上下文。
  7. 日志不落盘方案:rsyslog + imfile 直接转发到 Kafka,避免宿主机磁盘 IO 被容器刷爆。
  8. 与 Docker daemon 解耦:规则写在宿主机 /etc/audit/rules.d/,重启容器不丢失,符合“基础设施即代码”原则。

答案

步骤一:在宿主机固化审计规则

cat >/etc/audit/rules.d/docker-host.rules <<'EOF'
# 监控宿主机敏感目录
-w /etc -p wa -k host_etc
-w /var/run/docker.sock -p wa -k docker_sock
-w /usr/bin/docker -p x -k docker_bin
# 监控容器挂载点父目录,-C 表示“仅当容器进程触发”
-a exit,always -F dir=/data/kubelet/pods/ -F perm=war -F auid>=1000 -F auid!=4294967295 -k pod_vol
EOF
auditctl -R /etc/audit/rules.d/docker-host.rules
systemctl restart auditd

步骤二:让容器进程带上“容器 ID”标签
国内内核 ≥4.18 已合入 audit: add containerid 补丁,Docker 20.10+ 通过 --security-opt systempaths=unconfined 自动把 container_id 写进 audit 上下文;若内核未打补丁,可借助 oci-seccomp-bpf-hook(阿里开源)在 runc 阶段注入 bpf,把 cgroup 路径截断成 container_id 并写入 aux 记录。

步骤三:过滤“正常” vs “异常”
利用 ausearch 做聚合:

ausearch -k host_etc --format csv | \
awk -F, '$10~/container_id/ && $5!~/^dockerd$/ && $5!~/^kubelet$/{print $1,$5,$10}' >异常访问.csv

把结果通过 rsyslog omkafka 推到蓝鲸、ELK 或内部 SIEM,字段包含:宿主机 PID、容器 ID、文件路径、进程名、返回码(success/noacc)。

步骤四:闭环响应

  1. Falco 侧规则联动:
- rule: Unauthorized etc modification in container
  desc: container proc writes host /etc
  condition: >
    container and evt.type=openat and evt.is_open_write=true and
    fd.name startswith /etc and proc.name!=dockerd
  output: "Container %container.id (%container.name) write host %fd.name"
  priority: WARNING
  1. 堡垒机自动下发隔离指令:
docker pause $(docker ps -q -f id=${container_id})
  1. 审计事件保存 180 天,满足《网络安全法》日志留存要求。

拓展思考

  1. rootless Docker 场景下,auditd 规则仍写在宿主机,但容器进程以宿主用户 1001 运行,需加 -F euid=1001 避免误报。
  2. overlayfs 双层路径问题:容器内 /etc/hosts 实际路径是 /var/lib/docker/overlay2/<id>/diff/etc/hosts,规则若只写 -w /etc 会漏报,应 -w /var/lib/docker/overlay2 并配合 -F path 正则。
  3. 大规模集群可用 eBPF + auditd 双轨:eBPF 做高频采样,auditd 做精准取证,二者通过 container_id 关联,既降负载又保合规。