背景

容器的安全性依赖

  • 命名空间
  • cgroups
  • Linux 权限控制 Capabilities

eBPF 可以做的

  • 安全监控
  • 安全控制

业界的容器安全解决方案

开源项目

Falco

  • 开发者 / 维护者:由 Sysdig 发起,现由 CNCF(Cloud Native Computing Foundation)托管。
  • 核心功能:开源的运行时安全监控工具,专注于检测系统和容器中的异常行为(如未授权文件访问、特权升级、异常网络连接等)。通过实时分析系统调用、进程行为等事件,结合预定义规则(或自定义规则)触发告警。
  • eBPF 使用情况:支持 eBPF 作为事件收集的核心方式。早期依赖 Sysdig 内核模块,后期为减少内核兼容性问题,引入 eBPF 探针作为更优方案(无需手动加载内核模块,适配更多内核版本),目前 eBPF 是其推荐的事件源。

Tracee

  • 开发者 / 维护者:由 Aqua Security 开发并开源。
  • 核心功能:基于 eBPF 的系统行为追踪与威胁检测工具,专注于捕获进程、容器的细粒度行为(如系统调用、文件操作、网络交互、内核事件等),通过内置规则引擎识别可疑行为(如恶意代码执行、容器逃逸尝试等)。
  • eBPF 使用情况:完全基于 eBPF 实现。通过 eBPF 程序附着到内核钩子(如系统调用、kprobes、uprobes 等),直接从内核层收集事件,无需依赖传统内核模块,是其核心技术支柱

AppArmor

  • 开发者 / 维护者:起源于 SUSE,现由 Linux 社区维护,是 Linux 内核官方支持的安全模块。
  • 核心功能:强制访问控制(MAC)工具,通过配置文件(Profile)定义进程的访问权限(如允许访问的文件、网络端口、系统调用等),限制程序的 “越权行为”,属于预防性安全机制。
  • eBPF 使用情况:不使用 eBPF。基于 Linux 内核的 LSM(Linux Security Modules)框架实现,通过内核内置的访问控制钩子生效,与 eBPF 技术无关
对比维度 Falco Tracee AppArmor
核心定位 运行时安全监控与异常检测 基于 eBPF 的系统行为追踪与威胁检测 强制访问控制(预防性安全)
是否使用 eBPF 是(支持 eBPF 作为事件收集方式,替代传统内核模块) 是(完全基于 eBPF 实现事件捕获) 否(基于 LSM 框架)
技术依赖 可选择 eBPF 或 Sysdig 内核模块;依赖规则引擎 依赖 eBPF 内核支持(需内核版本≥4.15);规则引擎 依赖 Linux 内核 LSM 框架(内核≥2.6.36)
核心功能 检测违反规则的异常行为(如特权升级、异常文件访问) 细粒度追踪进程 / 容器行为,检测可疑操作(如恶意系统调用) 限制进程访问权限(如文件、网络、系统调用)
应用场景 容器 / 主机运行时安全监控、入侵检测(IDS) 容器安全审计、威胁狩猎、行为分析 进程权限限制、减少攻击面(如 Web 服务加固)
优势 规则生态丰富,支持多数据源,CNCF 背书 完全基于 eBPF,轻量、低侵入,适合容器环境 配置简单,内核原生支持,性能开销低
典型用户 云原生环境(K8s 集群)、企业安全监控 容器平台(Docker、K8s)、安全研究 服务器加固、嵌入式系统安全

对比

  • eBPF 相关性:Falco 和 Tracee 均依赖 eBPF(Tracee 完全基于 eBPF,Falco 可选 eBPF),而 AppArmor 不涉及 eBPF,依赖传统内核 LSM 机制。
  • 功能差异:Falco 和 Tracee 偏向 “检测”(发现已发生的异常),AppArmor 偏向 “预防”(限制可能的危险行为)。
  • 技术选型:若需轻量、低侵入的容器行为追踪,优先 Tracee;若需成熟的多场景安全监控,选 Falco;若需限制进程权限以减少风险,选 AppArmor。

分析和诊断

  • 通过实时监控内核的行为,再根据不断丰富的特征库做检查匹配,就能找到安全问题
  • Tracee 项目

事件监测

安全策略执行

  • 安全计算(seccomp)、Linux 安全模块(LSM)等已有的安全机制,可通过 eBPF 进行安全审计和决策执行
  • 可以通过辅助函数 kill 非法进程
  • 可以在网络协议栈处理之前,实时监控网络行为,实现丢包处理,效率非常高
  • 如下,KubeArmor 限制容器中进程执行、文件访问、网络连接等各种违反安全策略的操作

Introduction to LSM:​​
Linux Security Modules (LSM) is a framework in the Linux kernel that enables ​​mandatory access control (MAC)​​. Unlike discretionary access control (DAC), LSM allows system-wide security policies that enforce rules regardless of user permissions. Key features:

  • Hook-based Architecture​​: Places security hooks at critical kernel operations
  • ​​Module-based​​: Supports multiple security modules (SELinux, AppArmor, Smack)
  • ​​Policy Enforcement​​: Centralized enforcement of security rules
  • ​​System-wide Protection​​: Protects against privilege escalation and resource abuse

LSM inserts security checks at over 200 critical points including:

  • File operations (open, execve)
  • Network operations (socket, bind)
  • Process control (fork, kill)
  • Module loading (init_module)
graph TD
    A[System Call] --> B[Kernel Operation]
    B --> C[LSM Hook]
    C --> D{Policy Check}
    D -->|Allowed| E[Operation Proceeds]
    D -->|Denied| F[Permission Error]

LSM vs eBPF Security

graph LR
    LSM[Traditional LSM] -->|Built-in| K[Kernel]
    eBPF[eBPF Security] -->|Dynamic| H[Hooks]
    
    K --> A[Static Policies]
    H --> B[Dynamic Programs]
    
    style LSM stroke:#f90
    style eBPF stroke:#09f

Why eBPF Excels in Security​​
​​1. Kernel-Level Visibility​​

  • eBPF programs run directly in the Linux kernel, enabling deep inspection of system calls, network packets, file operations, and process behavior without requiring kernel modifications.
  • This provides ​​unprecedented visibility​​ into low-level activities, including container escapes, privilege escalations, and malicious payload execution. ​​
  1. Minimal Performance Overhead​​
  • Unlike traditional security agents that operate in userspace, eBPF reduces context-switching and data-copying overhead.
  • For example, eBPF-based network filtering (XDP) processes packets at ​​line-rate speeds​​ (100Gbps+), making it viable for high-traffic environments. ​​
  1. Dynamic Programmability​​
  • Security policies can be ​​hot-reloaded​​ into production systems.
  • This allows real-time responses to threats, such as blocking malicious IPs or patching zero-day vulnerabilities by intercepting vulnerable system calls. ​​
  1. Context-Aware Enforcement​​
  • eBPF correlates kernel events with user/container identities.
  • For instance:
  • Link network traffic to specific Kubernetes pods.
  • Associate file access with containerized processes.
  • This context is critical for auditing and blocking attacks in microservices environments. ​​
  1. Bypass Kernel Bypass Attacks​​
  • Malware that evades userspace monitoring (e.g., rootkits) can be detected via eBPF’s kernel hooks,
  • as it operates ​​beneath​​ traditional security layers.

实验

参考

监控主机、容器内执行的命令:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
#!/usr/bin/env bpftrace

#include <linux/sched.h>
#include <linux/nsproxy.h>
#include <linux/utsname.h>
#include <linux/pid_namespace.h>

BEGIN {
  printf("%-12s %-8s %-6s %-6s %-8s %s\n", "PIDNS", "CONTAINER", "PPID", "PID", "COMM", "ARGS");
}

tracepoint:syscalls:sys_enter_execve,
tracepoint:syscalls:sys_enter_execveat {
  $task = (struct task_struct *)curtask;
  $pidns = $task->nsproxy->pid_ns_for_children->ns.inum;
  $cname = $task->nsproxy->uts_ns->name.nodename;
  printf("%-12ld %-8s %-6d %-6d %-8s", (uint64)$pidns, $cname, curtask->parent->pid, pid, comm); join(args->argv);
}

在 宿主机、容器中 分别执行 curl

  • 095c4b4fcc2e,就是容器的 hostname
  • test-VMware-Virtual-Platform,主机的 hostname
1
2
3
4
5
./execsnoop-container.bt
Attaching 3 probes...
PIDNS        CONTAINER PPID   PID    COMM     ARGS
4026532610   095c4b4fcc2e 3835   3881   sh      curl baidu.com
4026531836   test-VMware-Virtual-Platform 3808   3882   bash    curl baidu.com

跟踪用户态

  • 容器文件系统在不同的 mount 命令空间中
  • 对于每个进程来说,Linux 都在 /proc/[pid]/root 处创建了一个链接
  • proc 文档

在容器内执行

1
2
3
lsns -t pid
        NS TYPE NPROCS PID USER COMMAND
4026532610 pid       3   1 root /bin/sh

之后 写一个脚本,模拟kill 行为,杀掉容器中执行的命令:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
#!/usr/bin/env bpftrace

#include <linux/sched.h>
#include <linux/nsproxy.h>
#include <linux/utsname.h>
#include <linux/pid_namespace.h>

tracepoint:syscalls:sys_enter_execve,
tracepoint:syscalls:sys_enter_execveat
/comm == "bash" || comm == "sh"/ {
  $task = (struct task_struct *)curtask;
  $pidns = $task->nsproxy->pid_ns_for_children->ns.inum;
  $cname = $task->nsproxy->uts_ns->name.nodename;
  if ($pidns != 4026531836) {
    printf("Killing shell command in container %s (pidns: %ld): %s ", $cname, $pidns, comm); join(args->argv);
    signal(9);
  }
}

执行

1
2
3
4
bpftrace --unsafe xx.bt
Attaching 2 probes...
Killing shell command in container 095c4b4fcc2e (pidns: 4026532610): sh ls
Killing shell command in container 095c4b4fcc2e (pidns: 4026532610): sh curl baidu.com

参考