4、容器运行时安全基线:容器逃逸防护、只读根文件系统、非root用户运行、Seccomp/AppArmor配置

容器运行时安全基线是云原生安全体系中的最后一道防线。即使镜像扫描、镜像签名和准入控制全部通过,攻击者仍可能利用容器运行时的配置缺陷实现逃逸或权限提升。本章聚焦四个核心控制项:容器逃逸防护、只读根文件系统、非root用户运行以及Seccomp/AppArmor配置。这四个维度共同构成了运行时安全基线的“四象限”,缺一不可。

核心原则:运行时安全基线不是一次性配置,而是需要持续监控和实时告警的动态基线。任何偏离基线的行为都应触发告警并自动阻断。

4.1 容器逃逸防护

容器逃逸是运行时安全中最严重的风险。攻击者一旦逃逸出容器,即可直接访问宿主机内核,进而横向移动至整个集群。逃逸防护的核心在于最小化容器对宿主机内核的暴露面。

逃逸类型 攻击向量 防护措施 监控指标
内核漏洞逃逸 利用内核CVE(如Dirty Pipe、CVE-2022-0847) 及时更新内核、启用内核模块签名、使用安全容器(gVisor/Kata) 内核版本、漏洞扫描结果
挂载逃逸 挂载宿主机敏感目录(/var/run/docker.sock、/proc、/sys) 禁止特权容器、限制hostPath挂载、使用PodSecurityPolicy 挂载点列表、特权模式状态
capability逃逸 赋予SYS_ADMIN、SYS_PTRACE等危险capability 最小capability原则、使用seccomp过滤系统调用 capability白名单、实际capability集合
进程逃逸 通过nsenter、ptrace进入宿主机命名空间 禁止--pid=host、--net=host、--ipc=host 命名空间共享配置
常见误区:很多团队只关注镜像漏洞扫描,却忽略了运行时配置中的逃逸路径。例如,一个无漏洞的镜像如果以特权模式运行并挂载了docker.sock,攻击者可以轻松创建恶意容器实现逃逸。
容器逃逸防护架构图 攻击者(容器内) 逃逸攻击向量 内核漏洞 | 挂载逃逸 | capability逃逸 | 进程逃逸 特权容器 | hostPath | --pid=host 运行时逃逸防护层 最小capability | 只读根文件系统 | 非root用户 | Seccomp/AppArmor 宿主机内核 ✕ 阻断逃逸

4.2 只读根文件系统

将容器的根文件系统设置为只读(readOnlyRootFilesystem: true)是防止恶意写入和持久化攻击的有效手段。攻击者即使获得容器shell,也无法修改二进制文件、写入后门脚本或篡改配置文件。

最佳实践:对于无状态应用(如API服务、前端应用),始终启用只读根文件系统。对于需要临时写入的场景,使用emptyDir卷或单独的持久卷,而非直接写入根文件系统。

只读根文件系统的监控要点:

  • 基线值:所有非特权容器应设置 securityContext.readOnlyRootFilesystem: true
  • 异常检测:监控容器内 /proc/1/exe、/bin、/sbin、/usr/bin 等关键目录的写入操作
  • 告警规则:当检测到容器尝试写入 /etc/passwd、/etc/shadow、/var/spool/cron 等敏感路径时立即告警
  • 绕过检测:注意检查是否通过 mount --bind 或 mount --make-rshared 绕过只读限制
# Kubernetes Pod 配置示例:只读根文件系统 + 临时写入卷
apiVersion: v1
kind: Pod
metadata:
  name: secure-app
spec:
  containers:
  - name: app
    image: myapp:1.0
    securityContext:
      readOnlyRootFilesystem: true
      runAsNonRoot: true
      runAsUser: 1001
    volumeMounts:
    - name: tmp
      mountPath: /tmp
    - name: data
      mountPath: /var/data
  volumes:
  - name: tmp
    emptyDir: {}
  - name: data
    persistentVolumeClaim:
      claimName: app-data-pvc

4.3 非root用户运行

默认情况下,容器以root用户运行(UID=0),这违反了最小权限原则。非root用户运行(runAsNonRoot: true)确保容器内进程使用非零UID,即使攻击者获得容器控制权,也无法获得宿主机的root权限。

配置项 说明 推荐值 监控方式
runAsNonRoot 强制容器以非root用户运行 true 审计Pod securityContext
runAsUser 指定运行UID 1001-65535(非0) 检查UID是否在允许范围
runAsGroup 指定运行GID 与UID一致或非0 检查GID是否在允许范围
fsGroup 卷的组所有权 非0 检查fsGroup配置
supplementalGroups 附加组 非0 检查附加组列表
常见陷阱:即使设置了 runAsNonRoot: true,如果镜像本身以root用户构建且未创建非root用户,Pod将无法启动。建议在Dockerfile中显式创建应用用户:RUN addgroup -S appgroup && adduser -S appuser -G appgroup,并在最后切换用户:USER appuser。

4.4 Seccomp/AppArmor配置

Seccomp(Secure Computing Mode)和AppArmor(Application Armor)是Linux内核提供的强制访问控制机制,用于限制容器可以执行的系统调用和文件访问权限。

4.4.1 Seccomp配置

Seccomp通过白名单或黑名单方式限制容器进程可以调用的系统调用。Kubernetes从v1.19开始支持Seccomp的GA特性。

# Seccomp配置文件示例:仅允许必要系统调用
{
  "defaultAction": "SCMP_ACT_ERRNO",
  "architectures": ["SCMP_ARCH_X86_64"],
  "syscalls": [
    {
      "names": [
        "accept4", "bind", "close", "connect", "dup",
        "epoll_create1", "epoll_ctl", "epoll_wait",
        "exit", "exit_group", "fstat", "ftruncate",
        "getdents64", "getpeername", "getsockname",
        "listen", "lseek", "mkdirat", "mmap", "mprotect",
        "munmap", "newfstatat", "openat", "poll",
        "pread64", "pwrite64", "read", "readlinkat",
        "recvfrom", "recvmsg", "renameat", "sendmsg",
        "sendto", "set_robust_list", "setsockopt",
        "shutdown", "socket", "statx", "sync_file_range",
        "unlinkat", "write"
      ],
      "action": "SCMP_ACT_ALLOW"
    }
  ]
}

4.4.2 AppArmor配置

AppArmor使用基于路径的访问控制,可以限制文件读写、网络访问、capability使用等。Kubernetes通过AppArmor profile注解来启用。

特性 Seccomp AppArmor
控制粒度 系统调用级别 文件路径+capability+网络
配置方式 JSON配置文件 profile文件(类似SELinux策略)
Kubernetes支持 Pod spec中指定seccompProfile 通过annotation指定
默认策略 RuntimeDefault(Docker默认) 未指定时无限制
监控重点 被拒绝的系统调用次数 被拒绝的文件访问次数
Seccomp + AppArmor 双层防护模型 容器进程 Seccomp 系统调用过滤器 白名单模式:仅允许必要系统调用 AppArmor 文件/网络访问控制 路径白名单:仅允许访问指定文件 Linux 内核 ✕ 拒绝非法调用 ✕ 拒绝非法访问

4.5 运行时安全基线的实时监控与告警

以上四个维度的配置需要在运行时持续监控,任何偏离基线的变更都应触发告警。推荐使用Falco作为运行时安全监控引擎,结合Prometheus和Alertmanager实现告警闭环。

监控指标清单:

  • 逃逸检测:敏感挂载点变更、特权模式启用、capability集合变化、命名空间共享配置变更
  • 只读文件系统:readOnlyRootFilesystem配置变更、关键目录写入事件、mount系统调用异常
  • 非root用户:runAsNonRoot配置变更、容器内UID检测、特权用户创建事件
  • Seccomp/AppArmor:seccompProfile配置变更、AppArmor profile变更、系统调用拒绝事件、文件访问拒绝事件
# Falco规则示例:检测容器逃逸尝试
- rule: Container Escape via Mount
  desc: Detect attempts to mount sensitive host paths
  condition: >
    evt.type=mount and
    container.id != host and
    (mount.target startswith "/host" or
     mount.target startswith "/var/run/docker.sock" or
     mount.target startswith "/proc" or
     mount.target startswith "/sys")
  output: >
    Container escape attempt via mount (user=%user.name
    command=%proc.cmdline target=%mount.target)
  priority: CRITICAL
  tags: [container, escape, mount]

- rule: Non-Root User Violation
  desc: Detect containers running as root
  condition: >
    container.id != host and
    proc.uid=0 and
    not proc.name in (systemd, init)
  output: >
    Container running as root (user=%user.name
    container=%container.name image=%container.image)
  priority: WARNING
  tags: [container, security, user]
告警分级建议:
  • CRITICAL:容器逃逸事件、特权容器创建、敏感挂载点变更 → 立即阻断并通知安全团队
  • WARNING:非root用户配置缺失、Seccomp/AppArmor未启用 → 触发自动修复流水线
  • INFO:只读文件系统配置变更、capability集合变化 → 记录审计日志并定期审查

通过将上述四个维度的基线配置与Falco、Prometheus、Alertmanager集成,可以实现容器运行时安全基线的自动化合规检测与实时告警,确保任何偏离基线的行为都能在秒级内被发现和响应。