Seccomp 安全

Seccomp 安全

什么是 Seccomp

Seccomp(Secure Computing Mode)是 Linux 内核的安全功能,用于限制进程可以使用的系统调用(syscalls)。Docker 默认使用 seccomp 来限制容器可以调用的系统调用,减少内核攻击面。

系统调用的风险

Linux 内核有 300+ 系统调用,容器通常只需要其中一小部分:

常见容器需要的 syscall
read, write, open, close, stat, mmap, exit, ...

高风险 syscall(容器通常不需要):
mount, umount, kexec_load, open_by_handle_at, ...

攻击者可以利用不必要的系统调用进行逃逸或提权。

Docker 默认的 Seccomp 配置

Docker 内置了一个默认的 seccomp 配置文件,禁用了 44 个危险系统调用(在 amd64 上):

{
  "defaultAction": "SCMP_ACT_ERRNO",
  "architectures": ["SCMP_ARCH_X86_64"],
  "syscalls": [
    {
      "names": [
        "acct",
        "add_key",
        "bpf",
        "clock_adjtime",
        "clock_settime",
        "create_module",
        "delete_module",
        "finit_module",
        "get_kernel_syms",
        "init_module",
        "ioperm",
        "iopl",
        "kcmp",
        "kexec_file_load",
        "kexec_load",
        "keyctl",
        "mount",
        "open_by_handle_at",
        "perf_event_open",
        "personality",
        "pivot_root",
        "process_vm_readv",
        "process_vm_writev",
        "ptrace",
        "query_module",
        "reboot",
        "request_key",
        "setdomainname",
        "sethostname",
        "setns",
        "settimenofreq",
        "stime",
        "swapon",
        "swapoff",
        "sysfs",
        "syslog",
        "umount",
        "umount2",
        "unshare",
        "uselib",
        "userfaultfd",
        "ustat",
        "vm86",
        "vm86old"
      ],
      "action": "SCMP_ACT_ERRNO"
    }
  ]
}

使用默认配置

# Docker 默认启用 seccomp
docker run nginx  # seccomp 已自动启用

# 查看是否启用
docker inspect nginx | grep seccomp
# "SecurityOpt": ["seccomp", "default"]

自定义 Seccomp 配置

创建自定义策略

{
  "defaultAction": "SCMP_ACT_ALLOW",
  "architectures": ["SCMP_ARCH_X86_64"],
  "syscalls": [
    {
      "names": ["mount", "umount2"],
      "action": "SCMP_ACT_ERRNO"
    }
  ]
}

应用自定义策略

# 使用自定义策略
docker run --security-opt seccomp=custom.json nginx

# 禁止 seccomp(❌ 不推荐)
docker run --security-opt seccomp=unconfined nginx

Seccomp Action 类型

Action 说明 使用场景
SCMP_ACT_ALLOW 允许系统调用 白名单模式
SCMP_ACT_ERRNO 返回错误(EPERM) 禁用系统调用
SCMP_ACT_KILL 杀死进程 严格限制
SCMP_ACT_TRACE 跟踪记录 调试

策略模式

白名单模式(推荐)

{
  "defaultAction": "SCMP_ACT_ERRNO",
  "syscalls": [
    {
      "names": ["read", "write", "open", "close", "exit", "exit_group"],
      "action": "SCMP_ACT_ALLOW"
    }
  ]
}

黑名单模式

{
  "defaultAction": "SCMP_ACT_ALLOW",
  "syscalls": [
    {
      "names": ["mount", "umount", "kexec_load"],
      "action": "SCMP_ACT_ERRNO"
    }
  ]
}

调试 Seccomp

查看被阻止的系统调用

# 在容器内测试
docker run --rm alpine sh -c "mount -t tmpfs tmpfs /mnt"
# mount: permission denied (seccomp 阻止)

# 查看审计日志
sudo journalctl | grep seccomp
# 可能看到 seccomp 拒绝的记录

记录系统调用

使用 strace 分析应用所需的系统调用:

# 在容器内运行 strace
docker run --cap-add=SYS_PTRACE alpine strace -c ls

# 输出系统调用统计
% time     seconds  usecs/call     calls    errors syscall
------ ----------- ----------- --------- --------- ----------------
 25.00    0.000100          50         2           write
 20.00    0.000080          20         4           mmap
...

不同应用场景的配置文件

Nginx Web 服务器

{
  "defaultAction": "SCMP_ACT_ERRNO",
  "architectures": ["SCMP_ARCH_X86_64"],
  "syscalls": [
    {
      "names": [
        "accept", "bind", "brk", "chdir", "clone",
        "close", "connect", "dup", "epoll_create",
        "epoll_ctl", "epoll_wait", "exit", "exit_group",
        "fstat", "getsockname", "listen", "mmap",
        "munmap", "nanosleep", "open", "openat",
        "poll", "read", "recvfrom", "sendto",
        "setsockopt", "socket", "stat", "write"
      ],
      "action": "SCMP_ACT_ALLOW"
    }
  ]
}

编译工具

{
  "defaultAction": "SCMP_ACT_ERRNO",
  "syscalls": [
    {
      "names": [
        "clone", "execve", "fork", "open", "read",
        "write", "mmap", "munmap", "brk"
      ],
      "action": "SCMP_ACT_ALLOW"
    }
  ]
}

Compose 中使用 Seccomp

services:
  app:
    image: myapp
    security_opt:
      - seccomp=./seccomp-profile.json
      # 或使用 Docker 默认
      # - seccomp=default

  unconfined:
    image: debug
    security_opt:
      - seccomp=unconfined   # ❌ 不推荐

最佳实践

  1. 保留默认配置:大多数情况下 Docker 默认的 seccomp 配置文件已经足够安全
  2. 使用白名单模式:精确控制容器所需的系统调用
  3. 禁用不必要的工具:不需要 mount、网络调试工具时移除对应 syscall
  4. 配合其他安全机制:seccomp + AppArmor + Capabilities 形成多层防护
  5. 仅对需要大量权限的应用自定义:如 Docker-in-Docker、调试工具

常见问题

# 问题:Nginx 启动失败
docker run nginx
# nginx: [emerg] bind() to 0.0.0.0:80 failed

# 解决:不是 seccomp 问题,是权限问题
# 使用 --cap-add=NET_BIND_SERVICE 或高位端口

# 问题:strace 无法使用
docker run --rm alpine strace ls
# strace: ptrace(PTRACE_TRACEME, ...): Operation not permitted

# 解决:需要 --cap-add=SYS_PTRACE

Seccomp 通过在系统调用层面对容器进行限制,是容器安全纵深防御体系中的重要组成部分。

© 版权声明
THE END
喜欢就支持一下吧
点赞8 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容