土法炼钢兴趣小组的算法知识备份

eBPF 安全监控:不改内核也能审计 syscall

目录

上个月,我们的生产集群发生了一件事:一个 Web 容器通过 CAP_SYS_PTRACE + /proc/1/root 组合拳,成功读取了宿主机的 /etc/shadow

Seccomp profile?全绿。openat()read()write()——全是白名单里的调用。Seccomp 看到的是”正常打开文件”,但它看不到 文件路径指向了宿主机的敏感数据

这就是 Seccomp 的根本局限:无状态 syscall 过滤器,不理解上下文。而 eBPF,可以。

如果你还不熟悉 eBPF 基础,建议先读 eBPF:Linux 内核的隐藏武器。本文假设你已理解 Map、verifier、程序类型等基本概念。

一、为什么 Seccomp 不够用

Seccomp-BPF 与 Capabilities:容器安全的两道防线 中我们讲了 Seccomp-BPF 的原理。这里聚焦它在安全监控场景下的 结构性缺陷

Seccomp 的世界观:syscall number + args,仅此而已

Seccomp-BPF 收到的数据结构是 struct seccomp_data

struct seccomp_data {
    int   nr;                    // syscall 编号
    __u32 arch;                  // 架构
    __u64 instruction_pointer;   // 指令地址
    __u64 args[6];               // syscall 参数(原始值)
};

注意 args[6]原始寄存器值——openat()args[1] 是文件路径的指针,不是字符串。经典 BPF 无法解引用用户态指针,Seccomp 根本不知道你在打开哪个文件。

Seccomp 看不到的维度

维度 Seccomp 能看到? eBPF 能看到?
syscall 编号和参数值
文件路径(解引用后) bpf_d_path()
进程树 / 父进程信息 bpf_get_current_task()
网络连接目标 IP:Port struct sock
容器 ID / cgroup bpf_get_current_cgroup_id()
mount namespace 上下文 ✅ 通过 task_struct

经典 BPF vs eBPF:不是同一个物种

Seccomp 用的是 经典 BPF(cBPF),1992 年设计的包过滤 VM,和现代 eBPF 不是同一物种:

特性 经典 BPF (Seccomp) eBPF
寄存器数量 2 (A, X) 11 (r0-r10)
栈大小 16 slot (64B) 512 字节
Map 支持 ✅ 多种类型
Helper 函数 ✅ 数百个
指针解引用 bpf_probe_read_*
循环 ✅ 有界循环 (5.3+)
尾调用 bpf_tail_call

Seccomp-BPF 中的 “BPF” 是历史遗留命名。它和现代 eBPF 的能力差了不止一个数量级。

快速启用检查清单

Seccomp-BPF 快速启用检查清单

项目 要求 验证命令
最低内核版本 3.5(基础),3.17SECCOMP_SET_MODE_FILTER uname -r
内核配置 CONFIG_SECCOMP=yCONFIG_SECCOMP_FILTER=y zgrep CONFIG_SECCOMP /proc/config.gzgrep CONFIG_SECCOMP /boot/config-$(uname -r)
运行时检查 /proc/sys/kernel/seccomp/actions_avail 存在 cat /proc/sys/kernel/seccomp/actions_avail
容器运行时 Docker 默认启用;containerd 需配置 seccomp_profile docker info \| grep -i seccomp
验证生效 查看进程的 seccomp 模式 grep Seccomp /proc/<PID>/status

二、LSM BPF:给 Linux 安全模块加上 eBPF 引擎

LSM(Linux Security Modules)是内核的安全框架,SELinux、AppArmor 都是其实现。LSM hook 在 syscall 入口之后执行——此时内核已完成参数解析,struct file 等对象已就绪。

从 Linux 5.7 开始,BPF_PROG_TYPE_LSM 允许你将 eBPF 程序挂载到任意 LSM hook——不编译内核模块,不重启。

常用 hook 点:

Hook 点 触发时机 典型用途
file_open 打开文件时 阻止敏感文件访问
bprm_check_security 执行新程序前 阻止特定二进制执行
socket_connect 建立网络连接时 限制出站连接
task_alloc 创建新进程时 限制进程创建
sb_mount 挂载文件系统时 防止未授权挂载

SELinux/AppArmor vs BPF LSM

特性 SELinux/AppArmor BPF LSM
策略加载 编译策略文件,重载服务 bpf() syscall 动态加载
策略语言 专用 DSL(m4 宏 / profile) C + eBPF
修改策略需重启? 通常需要 不需要
可编程性 低(规则匹配) 高(图灵完备*)
与 SELinux 共存 互斥(传统) ✅ 可堆叠

*eBPF 的图灵完备性受 verifier 约束:有界循环、有限栈深度、禁止无限递归。

实战:用 BPF LSM 阻止 /etc/shadow 写入

// lsm_block_shadow_write.bpf.c — 阻止对 /etc/shadow 的写入
#include "vmlinux.h"
#include <bpf/bpf_helpers.h>
#include <bpf/bpf_tracing.h>

#define SHADOW_PATH "/etc/shadow"
#define MAX_PATH_LEN 256

struct event { __u32 pid; __u32 uid; char comm[16]; char path[MAX_PATH_LEN]; };

struct {
    __uint(type, BPF_MAP_TYPE_RINGBUF);
    __uint(max_entries, 256 * 1024);
} events SEC(".maps");

// 返回 0 = 允许,负值 = 拒绝
SEC("lsm/file_permission")
int BPF_PROG(block_shadow_write, struct file *file, int mask)
{
    if (!(mask & 2))  // 只关心写操作(MAY_WRITE)
        return 0;

    char path_buf[MAX_PATH_LEN] = {};
    struct path f_path = BPF_CORE_READ(file, f_path);
    if (bpf_d_path(&f_path, path_buf, sizeof(path_buf)) < 0)
        return 0;

    // 逐字节比较目标路径
    const char target[] = SHADOW_PATH;
    for (int i = 0; i < sizeof(target) - 1; i++) {
        if (path_buf[i] != target[i])
            return 0;
    }

    // 匹配!记录事件并阻断
    struct event *e = bpf_ringbuf_reserve(&events, sizeof(*e), 0);
    if (e) {
        e->pid = bpf_get_current_pid_tgid() >> 32;
        e->uid = bpf_get_current_uid_gid() & 0xFFFFFFFF;
        bpf_get_current_comm(&e->comm, sizeof(e->comm));
        __builtin_memcpy(&e->path, path_buf, MAX_PATH_LEN);
        bpf_ringbuf_submit(e, 0);
    }
    return -13;  // -EACCES
}

char LICENSE[] SEC("license") = "GPL";

编译加载:

# 编译 eBPF 程序
clang -O2 -target bpf -D__TARGET_ARCH_x86 \
    -c lsm_block_shadow_write.bpf.c -o lsm_block_shadow_write.bpf.o

# 确认内核支持 BPF LSM
cat /boot/config-$(uname -r) | grep BPF_LSM   # 应输出 CONFIG_BPF_LSM=y
cat /sys/kernel/security/lsm                    # 应包含 bpf

# 加载 eBPF 程序
bpftool prog load restrict_write.o /sys/fs/bpf/restrict_write type lsm

# 查看已加载的 LSM 程序
bpftool prog list | grep lsm

# 注意:使用 libbpf skeleton 自动 attach 更常见
# bpf_object__open_file() → bpf_object__load() → bpf_program__attach_lsm()

⚠️ BPF LSM 需要 CONFIG_BPF_LSM=ylsm= 包含 bpf。Ubuntu 22.04+、Fedora 36+ 已默认启用。

快速启用检查清单

BPF LSM 快速启用检查清单

项目 要求 验证命令
最低内核版本 5.7BPF_PROG_TYPE_LSM 引入) uname -r
内核配置 CONFIG_BPF_LSM=yCONFIG_BPF=yCONFIG_BPF_SYSCALL=y zgrep -E 'CONFIG_BPF_LSM\|CONFIG_BPF_SYSCALL' /proc/config.gz
LSM 启动参数 lsm= 列表中包含 bpf cat /sys/kernel/security/lsm(应包含 bpf
BTF 支持 推荐 CONFIG_DEBUG_INFO_BTF=y(CO-RE 所需) ls /sys/kernel/btf/vmlinux
bpftool 可用 用于加载和调试 eBPF 程序 bpftool prog list \| grep lsm
修改启动参数(若 lsm 缺少 bpf) 编辑 GRUB 添加 lsm=lockdown,capability,landlock,yama,bpf 编辑 /etc/default/grub,执行 update-grub 后重启

三、Falco:基于 syscall 的运行时威胁检测

如果 BPF LSM 是”手写汇编”,那 Falco 就是”高级语言”——开箱即用的安全检测框架。

架构拆解

Linux 安全监控栈

Falco 的架构分三层:内核态驱动(数据采集)→ 用户态引擎(事件丰富化)→ 规则引擎(威胁检测)。

内核态驱动支持三种模式:

驱动模式 原理 性能 安全性
内核模块 (kmod) 传统 .ko 模块,hook syscall 表 ⭐⭐⭐ ⚠️ 内核崩溃风险
eBPF probe tracepoint 挂载 sys_enter/sys_exit ⭐⭐⭐ ✅ verifier 保障
现代 eBPF 用 CO-RE + Ring Buffer 替代 perf buffer ⭐⭐⭐⭐ ✅ 推荐

生产环境推荐”现代 eBPF”模式。内核模块虽性能略好,但一个 bug 就能 panic 整个节点。

用户态引擎 libsinsp 将原始 syscall 事件丰富化——文件描述符→路径、socket→IP:Port、PID→进程树、容器→ID/image/namespace。

规则引擎使用 YAML 格式,语法类似自然语言:

# 检测容器内读取敏感文件
- rule: Read sensitive file in container
  desc: 检测容器内进程读取 /etc/shadow 等敏感文件
  condition: >
    open_read and container and sensitive_files
    and not proc.name in (shadow_allowed_procs)
  output: >
    容器内敏感文件被读取 (user=%user.name cmd=%proc.cmdline
    file=%fd.name container=%container.name)
  priority: WARNING
  tags: [filesystem, container]

# 检测容器内启动交互式 shell(可能的入侵信号)
- rule: Terminal shell in container
  desc: 容器内不应出现交互式 shell
  condition: >
    spawned_process and container
    and proc.name in (bash, sh, zsh, dash)
    and proc.tty != 0
  output: >
    容器内检测到交互式 shell (user=%user.name
    container=%container.name shell=%proc.name
    parent=%proc.pname)
  priority: CRITICAL
  tags: [shell, container, mitre_execution]

性能开销

在 8 核 / 16GB 的 Kubernetes 节点上(syscall 密集型工作负载):

指标 无 Falco Falco (eBPF) 开销
CPU 使用率 基准 +1.5~3% 可接受
内存占用 ~150MB 固定
syscall 延迟 基准 +0.5~2μs 几乎无感
网络吞吐 基准 -0.2% 可忽略

Falco 的局限

快速启用检查清单

Falco 快速启用检查清单

项目 要求 验证命令
最低内核版本 4.14(eBPF 驱动模式),5.8+(推荐,现代 eBPF 模式) uname -r
内核配置 CONFIG_BPF=yCONFIG_BPF_SYSCALL=yCONFIG_BPF_JIT=y zgrep -E 'CONFIG_BPF=\|CONFIG_BPF_SYSCALL\|CONFIG_BPF_JIT' /proc/config.gz
BTF 支持(现代 eBPF) CONFIG_DEBUG_INFO_BTF=y(5.8+ 推荐) ls /sys/kernel/btf/vmlinux
安装方式 Helm(K8s)或 apt/rpm(裸机) helm install falco falcosecurity/falco -n falco
驱动选择 优先 --set driver.kind=modern_ebpf;回退 ebpf;最后 kmod falco --version 后查看 Driver
验证运行 Falco 进程存活且无报错 systemctl status falcokubectl logs -n falco -l app.kubernetes.io/name=falco
规则加载检查 默认规则文件可被解析 falco -L 2>&1 \| head -20(列出所有已加载规则)
  1. 仅能告警,不能阻断:基于 tracepoint 只能观测,检测到攻击时进程可能已完成恶意操作
  2. 用户态瓶颈:syscall 频率 >100K/s 时,内核→用户态传输可能丢事件
  3. 规则局限:复杂关联分析(“5 秒内 A 然后 B”)难以表达
  4. 进程血缘不完整:依赖 /proc 重建进程树,短命进程可能来不及采集

四、Tetragon:Cilium 的安全可观测性引擎

Tetragon 是 Cilium 的安全组件,设计哲学和 Falco 截然不同:把尽可能多的决策下沉到内核态

架构差异

快速启用检查清单

Tetragon 快速启用检查清单

项目 要求 验证命令
最低内核版本 5.4+(基础),5.11+(完整 kprobe multi-attach),5.13+(推荐) uname -r
内核配置 CONFIG_BPF=yCONFIG_BPF_SYSCALL=yCONFIG_BPF_JIT=yCONFIG_DEBUG_INFO_BTF=y zgrep -E 'CONFIG_BPF=\|CONFIG_DEBUG_INFO_BTF' /proc/config.gz
BTF vmlinux Tetragon 依赖 BTF 做 CO-RE ls /sys/kernel/btf/vmlinux
bpftool 验证 检查 BPF 子系统是否可用 bpftool feature probe kernel \| grep -i bpf_prog_type
安装方式 Helm(推荐) helm install tetragon cilium/tetragon -n kube-system
验证运行 DaemonSet 所有 Pod Running kubectl get ds tetragon -n kube-system
事件验证 能收到进程事件 kubectl exec -n kube-system ds/tetragon -c tetragon -- tetra getevents -o compact \| head
TracingPolicy 加载 CRD 已注册 kubectl get tracingpolicies
特性 Falco Tetragon
事件采集点 tracepoint kprobe + LSM + tracepoint
过滤位置 用户态 内核态
实时阻断 ❌ 仅告警 bpf_send_signal(SIGKILL)
进程血缘追踪 用户态重建(有缺口) 内核态维护(完整)
策略定义 YAML 规则 Kubernetes CRD
整体 CPU 开销 1.5~3% 1~2%

TracingPolicy CRD:声明式安全策略

Tetragon 的核心抽象是 TracingPolicy CRD——声明你想在内核中观测什么、在什么条件下采取什么行动:

apiVersion: cilium.io/v1alpha1
kind: TracingPolicy
metadata:
  name: block-shadow-read
spec:
  kprobes:
    - call: "fd_install"              # 文件描述符安装到进程时触发
      syscall: false
      args:
        - index: 0
          type: int
        - index: 1
          type: "file"                # 自动解析文件路径
      selectors:
        - matchArgs:
            - index: 1
              operator: "Equal"
              values:
                - "/etc/shadow"
          matchActions:
            - action: Sigkill         # 内核态直接杀死进程
            - action: Post            # 同时上报事件

进程血缘追踪

Tetragon 在内核态维护一棵进程树,每个事件都附带完整的进程血缘链:

# 查看 Tetragon 的进程事件
kubectl exec -n kube-system ds/tetragon -c tetragon -- \
    tetra getevents -o compact

# 输出示例(每个事件附带完整进程血缘链):
# 🚀 process  default/nginx-7b8d6c /bin/bash
#    └── /usr/sbin/nginx → /usr/bin/containerd-shim → /usr/bin/containerd
# 📝 open     default/nginx-7b8d6c /bin/bash /etc/shadow
# 💀 sigkill  default/nginx-7b8d6c /bin/bash   (blocked by policy)

不需要额外查询就能知道:(哪个容器的哪个进程)→ 从哪来(完整调用链)→ 做了什么结果(是否被阻断)。

内核态进程族谱追踪:task_struct 遍历与 BPF Map 进程树

Tetragon 的进程血缘追踪不是在用户态通过 /proc 拼凑的(Falco 的方式),而是在内核态实时维护一棵进程树。这是它能做到”零缺口”血缘追踪的关键。

原理拆解

Tetragon 在以下内核事件点挂载 eBPF 程序,实时维护一个 BPF Map 形式的进程树:

挂载点 触发时机 动作
sched_process_fork tracepoint 新进程创建 在 Map 中添加子节点,记录 parent_pid
sched_process_exec tracepoint 进程执行新程序 更新节点的 binary 路径、参数
sched_process_exit tracepoint 进程退出 标记节点为已退出(不立即删除,保留血缘链)
task_newtask kprobe 内核创建 task_struct 捕获完整的 namespace 信息

BPF Map 中进程节点的伪代码结构:

// Tetragon 进程树节点(简化)
struct process_node {
    __u32 pid;
    __u32 tgid;
    __u32 parent_pid;       // 父进程 PID
    __u32 parent_tgid;
    __u64 start_time;       // 进程启动时间(nsec,用于 PID 回收消歧)
    __u64 cgroup_id;        // 容器 cgroup ID
    __u32 uid, gid;
    char  comm[16];         // 进程名
    char  binary[256];      // 完整可执行文件路径
    __u32 flags;            // is_container, is_host, exited...
    __u32 depth;            // 在进程树中的深度(用于防止无限回溯)
};

task_struct 遍历:当一个安全事件触发时(比如 fd_install kprobe 检测到敏感文件访问),eBPF 程序需要向上遍历进程树来获取完整血缘链。它通过 bpf_get_current_task() 拿到当前 task_struct,然后沿着 task->real_parent 指针向上走:

// 伪代码:内核态进程血缘回溯
static __always_inline int walk_process_tree(struct trace_event *event)
{
    struct task_struct *task = (struct task_struct *)bpf_get_current_task();
    struct task_struct *parent;

    // 最多回溯 16 层(eBPF verifier 要求有界循环)
    #pragma unroll
    for (int i = 0; i < 16; i++) {
        __u32 pid = BPF_CORE_READ(task, tgid);

        // 从 BPF Map 查找预先维护的进程信息
        struct process_node *node = bpf_map_lookup_elem(&process_map, &pid);
        if (node) {
            // 把这一层的进程信息写入事件的 ancestors 数组
            event->ancestors[i].pid  = node->pid;
            event->ancestors[i].tgid = node->tgid;
            __builtin_memcpy(event->ancestors[i].comm, node->comm, 16);
            __builtin_memcpy(event->ancestors[i].binary, node->binary, 256);
        }

        // 沿 real_parent 向上走
        parent = BPF_CORE_READ(task, real_parent);
        if (!parent || parent == task)
            break;  // 到达 init 进程或自身循环
        task = parent;
    }
    return 0;
}

跨 fork/exec 的事件关联:传统的基于 /proc 的方案有一个致命缺陷——短命进程。一个进程如果在 1ms 内完成 fork → exec → 恶意操作 → exit,用户态轮询 /proc 根本来不及看到它。Tetragon 的内核态方案没有这个问题:sched_process_fork 在进程创建的瞬间就写入 Map,sched_process_exit 在退出时标记但不删除(延迟清理),中间任何事件都能查到完整血缘链。

Tetragon 的进程树 Map 示意(实际运行中的一个容器):

PID   PPID  Binary                      Cgroup
─────────────────────────────────────────────────────
1     0     /sbin/init                  host
3841  1     /usr/bin/containerd         host
4102  3841  /usr/bin/containerd-shim    host
4156  4102  /usr/sbin/nginx             k8s_nginx_default
4201  4156  /usr/sbin/nginx (worker)    k8s_nginx_default
4289  4201  /bin/bash                   k8s_nginx_default  ← 可疑!
4312  4289  /usr/bin/curl               k8s_nginx_default  ← 可疑!
                                        ↓
    完整血缘链:curl → bash → nginx(worker) → nginx → shim → containerd
    一眼就能看出:nginx worker 不应该 fork 出 bash 和 curl

这个设计的代价是内存占用更高(每个进程节点约 300-400 字节,加上 Map 的固定开销),这也是为什么 Tetragon 的内存占用(~200MB)比 Falco(~150MB)略高。但换来的是零缺口的进程血缘追踪——在安全场景下,这个 tradeoff 非常值得。

实时阻断:内核态 vs 用户态的本质差距

Falco(用户态决策):事件传到用户态 → 规则匹配 → 输出告警——攻击可能已完成。Tetragon(内核态决策):eBPF 程序在 hook 点直接检查 → bpf_send_signal(SIGKILL)攻击在内核态就被终止

性能对比

各安全方案在 Kubernetes 集群(16 核 / 64GB 节点,混合工作负载)上的表现:

指标 Auditd Falco (eBPF) Tetragon eBPF-LSM
CPU 开销 3~5% 1.5~3% 1~2% 0.5~1%
内存占用 ~80MB ~150MB ~200MB ~10MB
事件延迟 ~10μs ~3μs <1μs <0.5μs
阻断能力
丢事件风险 极低
部署复杂度

Auditd 的高 CPU 开销来自其同步的日志写入机制。Falco 和 Tetragon 都使用异步 buffer,overhead 更可控。

五、实战:构建容器逃逸检测

以下使用 Tetragon TracingPolicy 构建一套实际的容器逃逸检测方案。

检测 nsenter / unshare 调用

nsenterunshare 是容器逃逸最常见的手段:

# detect-namespace-escape.yaml
apiVersion: cilium.io/v1alpha1
kind: TracingPolicy
metadata:
  name: detect-namespace-escape
spec:
  tracepoints:
    - subsystem: "sched"
      event: "sched_process_exec"
      args:
        - index: 0
          type: "nop"
        - index: 1
          type: "string"          # 执行的程序路径
      selectors:
        - matchArgs:
            - index: 1
              operator: "Postfix"
              values:
                - "/nsenter"
                - "/unshare"
          matchActions:
            - action: Sigkill      # 立即终止
            - action: Post
              rateLimit: "1m"

检测敏感文件访问

# detect-sensitive-file-access.yaml
apiVersion: cilium.io/v1alpha1
kind: TracingPolicy
metadata:
  name: detect-sensitive-file-access
spec:
  kprobes:
    - call: "fd_install"
      syscall: false
      args:
        - index: 0
          type: int
        - index: 1
          type: "file"
      selectors:
        - matchArgs:
            - index: 1
              operator: "Prefix"
              values:
                - "/etc/shadow"
                - "/etc/sudoers"
                - "/proc/sysrq-trigger"
                - "/proc/kcore"
          matchNamespaces:
            - namespace: Pid
              operator: NotIn
              values:
                - "host_ns"
          matchActions:
            - action: Post
              rateLimit: "30s"
        - matchArgs:                       # /proc/*/mem 直接阻断
            - index: 1
              operator: "Postfix"
              values:
                - "/mem"
          matchActions:
            - action: Sigkill
            - action: Post

检测异常网络连接

# detect-suspicious-network.yaml
apiVersion: cilium.io/v1alpha1
kind: TracingPolicy
metadata:
  name: detect-suspicious-network
spec:
  kprobes:
    - call: "tcp_connect"
      syscall: false
      args:
        - index: 0
          type: "sock"
      selectors:
        - matchArgs:                         # SSRF → 直接杀掉
            - index: 0
              operator: "DAddr"
              values:
                - "169.254.169.254"          # 云元数据端点
          matchActions:
            - action: Sigkill
            - action: Post
        - matchArgs:                         # K8s API → 仅告警
            - index: 0
              operator: "DPort"
              values:
                - "6443"
                - "10250"
          matchActions:
            - action: Post
              rateLimit: "1m"

部署完整方案

# 安装 Tetragon 并应用策略
helm repo add cilium https://helm.cilium.io
helm install tetragon cilium/tetragon -n kube-system \
    --set tetragon.btf=/sys/kernel/btf/vmlinux
kubectl apply -f detect-namespace-escape.yaml \
    -f detect-sensitive-file-access.yaml \
    -f detect-suspicious-network.yaml

# 实时查看安全事件
kubectl exec -n kube-system ds/tetragon -c tetragon -- \
    tetra getevents -o compact --process-ancestors 3

# 测试:容器内尝试读取 /etc/shadow
kubectl exec -it test-pod -- cat /etc/shadow
# 预期:command terminated with exit code 137 (SIGKILL)

六、选型指南:Seccomp vs eBPF-LSM vs Falco vs Tetragon

终极对比表

维度 Seccomp-BPF eBPF-LSM (自定义) Falco Tetragon
最低内核版本 3.5 5.7 4.14 (eBPF) 5.4+
挂载点 syscall 入口 LSM hook tracepoint kprobe + LSM
可见上下文 syscall 号 + args 完整内核对象 syscall + 丰富化 完整内核对象
阻断能力 ✅ KILL/ERRNO ✅ 返回错误码 ❌ 仅告警 ✅ SIGKILL
进程血缘 需自行实现 部分(用户态) ✅ 完整
容器感知 需自行实现 ✅ 原生
K8s 集成 securityContext Helm CRD + Helm
学习曲线
适用场景 基础防护 精确控制 检测 + 合规 检测 + 阻断

不同场景的推荐选择

场景 1:基础容器安全加固Seccomp-BPF(必选)+ Falco(推荐)

Seccomp 做最低成本的基础防护,Falco 做运行时检测,覆盖 Seccomp 看不到的上下文。

场景 2:高安全性生产环境Seccomp-BPF + Tetragon

Seccomp 第一层白名单过滤 + Tetragon 第二层上下文感知检测和实时阻断。

场景 3:定制化安全需求(金融、政府)Seccomp-BPF + 自定义 eBPF-LSM + Tetragon

eBPF-LSM 实现细粒度自定义策略,Tetragon 负责全局检测和告警。

场景 4:安全审计和合规Falco

Falco 规则库已覆盖 MITRE ATT&CK 大量 TTP,输出格式适合对接 SIEM。

分层防御模型

最佳实践不是二选一,而是分层防御:

┌─────────────────────────────────────────┐
│          应用层安全(WAF、认证)          │  ← 拦截已知攻击
├─────────────────────────────────────────┤
│         网络策略(Cilium/Calico)         │  ← 限制通信
├─────────────────────────────────────────┤
│      Seccomp-BPF(syscall 白名单)       │  ← 禁止危险调用
├─────────────────────────────────────────┤
│   Tetragon/Falco(运行时行为检测)        │  ← 检测异常
├─────────────────────────────────────────┤
│      eBPF-LSM(自定义安全策略)           │  ← 精确控制
├─────────────────────────────────────────┤
│         Linux 内核(最小权限原则)         │  ← Capabilities、NS
└─────────────────────────────────────────┘

安全是一个 纵深防御 问题。没有银弹,但 eBPF 让我们第一次能在不改内核的前提下,实现接近内核模块级别的安全监控能力。


参考资料:


By .