seccomp异常时的维测

遇到 seccomp(Secure Computing Mode)异常 时,通常表现为进程因违反 seccomp 规则而被内核终止(常见信号 SIGSYSSIGKILL),日志中会有相关记录。以下是系统的维测步骤和关键点:


1. 确认异常现象

  • 日志定位

    • 检查系统日志(/var/log/syslog/var/log/messagesjournalctl):
      1
      2
      journalctl -k --grep="seccomp"
      grep -i "seccomp" /var/log/syslog
    • 典型日志示例:
      1
      audit: type=1326 ... syscall=xxx ... seccomp=action=KILL ...
  • 进程信号

    • 若进程崩溃,用 dmesgjournalctl 检查是否因 SIGSYS(非法系统调用)终止。

2. 获取触发的系统调用信息

  • 从日志提取关键字段

    • syscall=:触发的系统调用号(如 231 代表 exit_group)。
    • arch=:CPU 架构(如 x86_64)。
    • exe=:触发进程的路径。
  • 系统调用号转名称

    1
    2
    # 根据架构查询(x86_64 示例)
    ausyscall x86_64 231 # 输出:exit_group

3. 分析 seccomp 策略

  • 定位策略来源

    • 容器环境(如 Docker):

      1
      docker inspect <容器ID> --format='{{.HostConfig.SeccompProfile}}'

      默认策略路径:/etc/docker/seccomp/*.json

    • 自定义应用
      检查代码中加载的 seccomp BPF 策略(如通过 libseccompprctl(PR_SET_SECCOMP))。

  • 策略规则检查

    • 确认触发的系统调用是否被显式禁止(SCMP_ACT_KILLSCMP_ACT_ERRNO)。
    • 检查是否有规则覆盖了该调用(如基于参数过滤)。

4. 动态调试:使用跟踪工具

  • strace 捕获系统调用

    1
    strace -f -e trace=all -s 512 -o strace.log <命令>

    过滤触发前的调用序列,定位非法调用。

  • perf 监控 seccomp 事件

    1
    2
    perf record -e 'syscalls:sys_enter_seccomp' -ag
    perf script
  • auditd 高级跟踪

    1
    auditctl -a always,exit -F arch=b64 -S <syscall>  # 监控特定调用

5. 临时绕过与测试

  • 禁用 seccomp 验证

    • 容器运行时添加参数(临时测试):
      1
      docker run --security-opt seccomp=unconfined ...
    • 注意:仅用于定位问题,生产环境勿用!
  • 修改策略允许调用
    在 seccomp 配置文件中添加规则:

    1
    2
    3
    4
    {
    "names": ["被禁止的系统调用名"],
    "action": "SCMP_ACT_ALLOW"
    }

6. 深入代码分析

  • 反汇编定位调用点

    • 使用 gdb 附加进程,捕获 SIGSYS 信号:
      1
      2
      3
      gdb -p <PID>
      (gdb) catch signal SIGSYS
      (gdb) continue
    • 信号触发时检查寄存器:
      • $RAX:系统调用号。
      • $RIP:调用指令地址。
  • 检查调用栈

    1
    (gdb) bt full

7. 常见陷阱

  • 架构差异:32位/64位调用号不同(如 open vs openat)。
  • 隐式调用glibc 封装函数可能触发非预期调用(如内存分配调用 mmap)。
  • 参数过滤:策略中基于参数过滤规则(如 openO_RDWR 被禁止)。

8. 修复与验证

  • 策略调整

    • 允许必要调用,或放宽参数限制。
    • 使用 SCMP_ACT_LOG 记录调用而不终止进程(调试模式)。
  • 策略热重载

    1
    2
    # 动态更新策略(需程序支持)
    syscallerctl --reload-seccomp <策略文件>

总结排查流程

1
2
3
4
5
6
7
8
9
10
graph TD
A[发现崩溃/日志告警] --> B[确认 seccomp 错误日志]
B --> C{容器 or 原生进程?}
C -->|容器| D[检查容器 seccomp 策略]
C -->|原生| E[检查应用加载的策略]
D --> F[分析触发系统调用]
E --> F
F --> G[strace/perf 动态跟踪]
G --> H[修改策略并测试]
H --> I[问题解决]

通过以上步骤,可高效定位 seccomp 违规根源。关键点:结合内核日志、动态跟踪与策略分析,优先在测试环境复现问题。