Falco 运行时安全:eBPF 与系统调用监控

Falco 运行时安全:eBPF 与系统调用监控

前言

在云原生时代,容器化和微服务架构已成为主流部署方式。然而,传统的安全防护手段往往难以应对容器环境中的动态威胁。Falco 作为云原生运行时安全领域的开源项目,通过 eBPF(extended Berkeley Packet Filter)技术实现了对系统调用的高性能监控,为容器安全提供了革命性的解决方案。

本文将从源码层面深入剖析 Falco 的架构设计,详细讲解 eBPF 技术在系统调用监控中的实现原理,并通过实战案例展示如何构建基于 Falco 的运行时安全防护体系。


一、Falco 架构深度解析

1.1 整体架构概览

Falco 采用了用户态与内核态分离的架构设计,通过 eBPF 程序在内核态捕获系统调用事件,并在用户态进行规则匹配和告警处理。
系统调用
捕获事件
推送数据
规则匹配
触发告警
应用程序
内核态 eBPF 程序
Perf Buffer / Ring Buffer
用户态 Falco 引擎
规则引擎
输出插件
Syslog / Stdout / Webhook

架构说明:

  1. 内核态层(eBPF Programs):加载到内核的 eBPF 程序,通过 kprobes、tracepoints 等机制挂载到关键系统调用路径
  2. 数据传输层(Perf/Ring Buffer):高效的内核态到用户态数据传输通道
  3. 用户态引擎(Falco Engine):核心的事件处理和规则匹配引擎
  4. 输出层(Outputs):支持多种输出方式,包括日志文件、标准输出、Webhook 等

1.2 核心组件源码分析

1.2.1 eBPF 探针加载机制

Falco 的 eBPF 探针源码位于 drivers/ebpf 目录(版本:0.38.1),核心探针加载逻辑:

c 复制代码
// 文件路径:drivers/ebpf/probe.h
// 版本:Falco 0.38.1

#ifndef _PROBE_H
#define _PROBE_H

#include <linux/types.h>

// 探针类型定义,对应不同的系统调用监控点
enum scap_probes {
    PROBE_ENTRY,      // 系统调用入口探针
    PROBE_EXIT,       // 系统调用退出探针
    PROBE_SCHED_SWITCH, // 进程切换探针
    PROBE_SIGNAL_DELIVERY, // 信号投递探针
};

// 系统调用参数提取结构体
struct scap_evtgen {
    __u64 type;        // 事件类型
    __u64 tid;         // 线程 ID
    __u64 pid;         // 进程 ID
    __u64 ptid;        // 父线程 ID
    __u64 uid;         // 用户 ID
    __u64 gid;         // 组 ID
    __u64 retval;      // 返回值
    char comm[16];     // 进程名称
};

// eBPF map 定义,用于存储配置和状态
struct bpf_map_def SEC("maps") evtgen_config = {
    .type = BPF_MAP_TYPE_HASH,
    .key_size = sizeof(__u32),
    .value_size = sizeof(struct scap_evtgen),
    .max_entries = 1024,
};

#endif
1.2.2 系统调用监控实现

通过 SEC 宏将 eBPF 程序挂载到内核 tracepoint:

c 复制代码
// 文件路径:drivers/ebpf/probe.c
// 版本:Falco 0.38.1

#include "probe.h"
#include <linux/ptrace.h>

// 挂载到 sys_enter_execve tracepoint
// SEC("tracepoint/syscalls/sys_enter_execve") 告诉编译器将此函数挂载到
// execve 系统调用的入口点
SEC("tracepoint/syscalls/sys_enter_execve")
int trace_execve_entry(struct trace_event_raw_sys_enter* ctx)
{
    // 从 eBPF map 中查找当前线程的配置
    __u32 tid = bpf_get_current_pid_tgid();
    struct scap_evtgen *gen = bpf_map_lookup_elem(&evtgen_config, &tid);
    
    // 如果未找到配置,说明该线程不在监控范围内,直接返回
    if (!gen) {
        return 0;
    }
    
    // 捕获系统调用参数
    // ctx->args[0] 包含可执行文件路径指针
    const char *filename = (const char *)ctx->args[0];
    char cmd[16];
    
    // 获取当前进程名称(comm)
    bpf_get_current_comm(&cmd, sizeof(cmd));
    
    // 将事件信息写入 perf buffer
    // PERF_EVENT_CTX 宏定义了事件上下文的格式
    struct event_t *event = bpf_map_lookup_elem(&events, &tid);
    if (event) {
        event->type = EXECVE_EVT;  // 事件类型:execve
        event->timestamp = bpf_ktime_get_ns();  // 获取纳秒级时间戳
        __builtin_memcpy(event->comm, cmd, sizeof(cmd));
        // 注意:由于 eBPF 验证器的限制,字符串拷贝需要特殊处理
        bpf_probe_read_user_str(event->filename, sizeof(event->filename), filename);
        
        // 提交事件到 perf buffer
        bpf_perf_event_output(ctx, &perf_buffer, BPF_F_CURRENT_CPU, 
                              event, sizeof(*event));
    }
    
    return 0;
}

// 挂载到 sys_exit_execve tracepoint
SEC("tracepoint/syscalls/sys_exit_execve")
int trace_execve_exit(struct trace_event_raw_sys_exit* ctx)
{
    __u32 tid = bpf_get_current_pid_tgid();
    struct scap_evtgen *gen = bpf_map_lookup_elem(&evtgen_config, &tid);
    
    if (!gen) {
        return 0;
    }
    
    // 记录系统调用返回值
    // ctx->ret 包含 execve 的返回值(0 表示成功,负数表示错误码)
    gen->retval = ctx->ret;
    
    return 0;
}

// 使用的许可证声明,eBPF 程序必须包含 GPL 许可证
char _license[] SEC("license") = "GPL";

代码解析:

  1. Tracepoint 挂载 :使用 SEC("tracepoint/syscalls/sys_enter_execve") 将 eBPF 程序挂载到 execve 系统调用的入口点
  2. 参数提取 :通过 ctx->args[] 访问系统调用参数,ctx->ret 获取返回值
  3. Perf Buffer :使用 bpf_perf_event_output 将事件高效传输到用户态
  4. BPF 验证器限制 :字符串操作需使用 bpf_probe_read_user_str 等辅助函数

二、eBPF 技术深度剖析

2.1 eBPF 技术栈与对比

eBPF 是 Linux 内核的革命性技术,允许在内核中安全地执行沙盒化程序。以下是 eBPF 与传统内核监控技术的对比:

特性 eBPF Kernel Module Strace Auditd
性能开销 极低(<5%) 极高(50%+) 中等(10-20%)
安全性 验证器保证 可导致内核崩溃 安全 安全
灵活性 高(动态加载) 低(需重编译) 中等
上下文信息 完整 完整 完整 有限
部署复杂度 中等
容器支持 原生支持 需特殊处理 困难 困难
编程语言 C/限制性 Rust C 无需编程 无需编程

关键优势:

  • 零拷贝:通过 perf buffer 和 ring buffer 实现高效数据传输
  • JIT 编译:eBPF 字节码被即时编译为本地机器码
  • 沙盒执行:BPF 验证器确保程序安全,不会导致内核崩溃
  • 动态加载:无需重启内核即可加载/卸载程序

2.2 eBPF 程序加载流程

内核 JIT 编译器 BPF 验证器 libbpf 库 用户态 Falco 内核 JIT 编译器 BPF 验证器 libbpf 库 用户态 Falco 1. 加载 eBPF 字节码 2. 提交程序验证 3. 安全性检查 - 内存访问验证 - 循环限制 - 函数调用限制 4. 验证通过 5. 即时编译为机器码 6. 加载到内核 7. 返回程序 FD 8. 挂载到 tracepoint/kprobe 9. 开始接收事件

流程详解:

  1. 字节码加载:Falco 使用 libbpf 库加载编译好的 eBPF 字节码文件(.o 格式)
  2. 验证器检查 :内核 BPF 验证器进行严格的安全性检查:
    • 内存访问必须经过边界检查
    • 不允许无界循环
    • 限制函数调用深度
    • 防止死锁和内存泄漏
  3. JIT 编译:通过验证后,eBPF 字节码被即时编译为 x86_64/ARM64 等本地机器码
  4. 内核挂载 :通过 bpf_prog_attach 系统调用将程序挂载到具体的 hook 点

2.3 Falco 的 eBPF Map 管理

eBPF Map 是内核态与用户态数据交换的关键机制。Falco 使用多种 map 类型:

c 复制代码
// 文件路径:drivers/ebpf/maps.h
// 版本:Falco 0.38.1

// 1. 哈希表 map:存储线程配置信息
struct bpf_map_def SEC("maps") thread_config_map = {
    .type = BPF_MAP_TYPE_HASH,
    .key_size = sizeof(__u32),        // key: thread ID
    .value_size = sizeof(struct thread_config),
    .max_entries = 65536,
};

// 2. Perf Buffer map:高效事件传输
struct bpf_map_def SEC("maps") perf_buffer = {
    .type = BPF_MAP_TYPE_PERF_EVENT_ARRAY,
    .key_size = sizeof(__u32),        // key: CPU ID
    .value_size = sizeof(__u32),      // value: perf event FD
    .max_entries = 128,               // 通常等于 CPU 核心数
};

// 3. 数组 map:全局配置
struct bpf_map_def SEC("maps") global_config = {
    .type = BPF_MAP_TYPE_ARRAY,
    .key_size = sizeof(__u32),        // key: 索引
    .value_size = sizeof(struct global_settings),
    .max_entries = 1,
};

// 4. LRU 哈希表:用于最近最少淘汰的缓存
struct bpf_map_def SEC("maps") container_cache = {
    .type = BPF_MAP_TYPE_LRU_HASH,
    .key_size = sizeof(__u64),        // key: cgroup ID
    .value_size = sizeof(struct container_info),
    .max_entries = 10240,
};

Map 类型选择策略:

Map 类型 使用场景 优势 限制
HASH 线程配置、容器信息 O(1) 查找,灵活更新 内存占用固定
PERF_EVENT_ARRAY 事件传输 零拷贝,低延迟 需要用户态轮询
ARRAY 全局配置 最快访问速度 固定大小
LRU_HASH 容器缓存 自动淘汰旧条目 LRU 策略不可定制
RING_BUFFER 事件传输(新) 单生产者模型,更简单 内核 5.8+

三、规则引擎与事件匹配

3.1 Falco 规则语法深度解析

Falco 规则采用 YAML 格式,支持丰富的过滤条件和操作符。以下是完整的规则示例:

yaml 复制代码
# 文件路径:/etc/falco/falco_rules.yaml
# 版本:Falco 0.38.1

# 规则:检测容器中的异常 shell 启动
- rule: Detect Shell in Container
  desc: 检测到容器内启动交互式 shell,可能是容器逃逸或横向移动
  condition: >
    spawned_process and
    container and
    shell_procs and
    proc.name in (bash, sh, zsh, dash) and
    not proc.pname_exists and  # 不是由父进程启动(直接启动)
    not user_expected_shell_spawned_programs
  output: >
    异常 shell 启动 (user=%user.name container=%container.name container_id=%container.id 
    shell=%proc.name parent=%proc.pname cmdline=%proc.cmdline exe=%proc.exeline)
  priority: WARNING
  tags: [container, shell, mitre_execution]
  
  # 例外规则:排除可信的 shell 启动场景
  exceptions:
    - name: user_expected_shell_spawned_programs
      fields: [user.name, proc.name]
      comps:
        - user: admin
          proc: bash
        - user: root
          proc: sh
      append: false

# 宏定义:复用的过滤条件
- macro: shell_procs
  condition: >
    proc.name in (bash, sh, zsh, dash, ksh, tcsh, csh, fish)

# 列表定义:可复用的值集合
- list: trusted_images
  items: [nginx:latest, alpine:3.18, postgres:15]

# 规则:检测敏感文件访问
- rule: Sensitive File Access
  desc: 检测对敏感系统文件的访问
  condition: >
    open_read and
    fd.filename in (/etc/shadow, /etc/passwd, /etc/sudoers, 
                    /root/.ssh/id_rsa, /root/.ssh/authorized_keys) and
    not proc.name in (sshd, login, systemd-logind)
  output: >
    敏感文件访问 (user=%user.name file=%fd.filename 
    proc=%proc.name cmdline=%proc.cmdline container=%container.name)
  priority: ERROR
  tags: [filesystem, mitre_collection]

# 规则:检测容器网络异常
- rule: Container Network Spoofing
  desc: 检测容器内网络工具的异常使用
  condition: >
    spawned_process and
    container and
    proc.name in (iptables, nft, tcpdump, wireshark, nmap, netcat, nc) and
    not container.image in (trusted_images) and
    not user_allowed_network_tools
  output: >
    网络工具异常使用 (user=%user.name container=%container.name 
    tool=%proc.name cmdline=%proc.cmdline)
  priority: WARNING
  tags: [network, container, mitre_discovery]

规则语法核心要素:

  1. condition(条件) :支持布尔运算符、比较运算符、集合操作
    • and, or, not:逻辑运算符
    • =, !=, in, contains:比较和匹配运算符
    • proc.name exists:存在性检查
  2. output(输出) :支持丰富的字段占位符
    • %user.name:用户名
    • %container.name:容器名称
    • %proc.cmdline:完整命令行
    • %fd.filename:文件名
  3. priority(优先级):EMERGENCY > ALERT > CRITICAL > ERROR > WARNING > NOTICE > INFO > DEBUG
  4. exceptions(例外):支持基于字段的复杂例外规则

3.2 规则引擎实现原理

Falco 规则引擎基于libsinsp(版本:0.38.1)实现,使用过滤表达式解析器构建高效的匹配树:

cpp 复制代码
// 文件路径:userspace/libsinsp/filter_checker.cpp
// 版本:Falco 0.38.1

// 过滤器 AST(抽象语法树)节点类型
class ast_expr {
public:
    enum expr_type {
        ET_BOOL,           // 布尔表达式
        ET_VALUE,          // 值表达式
        ET_COMPARE,        // 比较表达式
        ET_AND,            // 逻辑与
       ET_OR,             // 逻辑或
        ET_NOT,            // 逻辑非
        ET_LIST,           // 列表表达式
        ET_EXISTS          // 存在性检查
    };

    virtual bool eval(sinsp_evt* evt) = 0;  // 纯虚函数:评估事件是否匹配
};

// 比较表达式节点:处理 proc.name = "bash" 这类条件
class compare_expr : public ast_expr {
private:
    std::string m_field;      // 字段名,如 "proc.name"
    cmpop m_op;               // 比较运算符
    std::string m_value;      // 比较值

public:
    bool eval(sinsp_evt* evt) override {
        // 从事件中提取字段值
        std::string field_value = extract_field(evt, m_field);
        
        // 根据运算符类型执行比较
        switch(m_op) {
            case CO_EQ:
                return field_value == m_value;
            case CO_NE:
                return field_value != m_value;
            case CO_CONTAINS:
                return field_value.find(m_value) != std::string::npos;
            case CO_IN:
                // m_value 是逗号分隔的列表
                return is_in_list(field_value, m_value);
            default:
                return false;
        }
    }
};

// 逻辑与表达式节点
class and_expr : public ast_expr {
private:
    std::vector<std::unique_ptr<ast_expr>> m_children;

public:
    bool eval(sinsp_evt* evt) override {
        // 所有子表达式都必须为 true
        for (auto& child : m_children) {
            if (!child->eval(evt)) {
                return false;
            }
        }
        return true;
    }
};

// 过滤器检查器:负责构建 AST 并评估事件
class filter_checker {
private:
    std::unique_ptr<ast_expr> m_ast;  // 规则的抽象语法树

public:
    // 从字符串表达式构建 AST
    // 例如:parse("spawned_process and container and shell_procs")
    void parse(const std::string& filter) {
        m_parser = new filter_parser(filter);
        m_ast = m_parser->parse();  // 解析为 AST
    }
    
    // 评估事件是否匹配规则
    bool run(sinsp_evt* evt) {
        return m_ast->eval(evt);
    }
};

规则匹配优化技术:

  1. AST 缓存:规则解析后的 AST 会被缓存,避免重复解析
  2. 短路求值:逻辑表达式采用短路求值,提高性能
  3. 字段提取优化:字段提取器使用哈希表实现 O(1) 查找
  4. 索引技术:对高频字段(如 proc.namecontainer.id)建立索引

四、实战场景与最佳实践

4.1 场景一:容器逃逸检测

容器逃逸是容器安全的核心威胁之一。通过监控特权操作和敏感系统调用,Falco 能够有效检测多种逃逸技术。

bash 复制代码
#!/bin/bash
# 文件路径:/opt/falco/scripts/detect_container_escape.sh
# 版本:1.0
# 功能:部署 Falco 规则以检测容器逃逸行为

# 1. 安装 Falco(如果尚未安装)
install_falco() {
    echo "[*] 检查 Falco 安装状态..."
    if ! command -v falco &> /dev/null; then
        echo "[+] 安装 Falco..."
        # 添加 Falco 官方 GPG 密钥
        curl -fsSL https://falco.org/repo/falco-release.asc | gpg --dearmor -o /usr/share/keyrings/falco-archive-keyring.gpg
        
        # 添加 Falco 仓库
        echo "deb [signed-by=/usr/share/keyrings/falco-archive-keyring.gpg] https://download.falco.org/packages/deb stable main" | \
            tee /etc/apt/sources.list.d/falco.list
        
        # 更新并安装
        apt-get update -qq
        apt-get install -y falco
    else
        echo "[+] Falco 已安装"
    fi
}

# 2. 创建容器逃逸检测规则
create_escape_rules() {
    echo "[*] 创建容器逃逸检测规则..."
    cat > /etc/falco/falco_rules_escape.yaml << 'EOF'
# Falco 容器逃逸检测规则集
# 版本:1.0
# 作者:Falco 安全团队

- macro: container_escape_tools
  condition: >
    proc.name in (chroot, pivot_root, mount, umount, 
                  nsenter, unshare, strace, ldconfig)

# 规则1:检测特权容器创建
- rule: Privileged Container Created
  desc: 检测到特权容器的创建,特权容器可能导致容器逃逸
  condition: >
    spawn_process and
    container and
    container.privileged=true and
    container.id != host
  output: >
    特权容器创建 (user=%user.name container=%container.name 
    image=%container.image.image id=%container.id)
  priority: CRITICAL
  tags: [container, escape, privileged]

# 规则2:检测敏感路径挂载
- rule: Sensitive Path Mount in Container
  desc: 容器内挂载了宿主机敏感路径
  condition: >
    mount and
    container and
    container.mount.src in (/, /proc, /sys, /var/run/docker.sock, 
                            /var/lib/kubelet, /etc, /root/.ssh)
  output: >
    敏感路径挂载 (user=%user.name container=%container.name 
    mount_src=%fd.name mount_dest=%fd.directory)
  priority: CRITICAL
  tags: [container, mount, escape]

# 规则3:检测容器内访问 Docker socket
- rule: Docker Socket Access from Container
  desc: 容器内进程访问 Docker socket,可能导致容器逃逸
  condition: >
    open_read and
    container and
    fd.name in (/var/run/docker.sock, /var/run/crio/crio.sock, 
                /var/run/containerd/containerd.sock)
  output: >
    Docker Socket 访问 (user=%user.name container=%container.name 
    proc=%proc.name cmdline=%proc.cmdline)
  priority: CRITICAL
  tags: [container, docker, escape]

# 规则4:检测容器内核模块加载
- rule: Kernel Module Load in Container
  desc: 容器内尝试加载内核模块,严重的逃逸迹象
  condition: >
    spawn_process and
    container and
    proc.name in (insmod, modprobe, rmmod) and
    not proc.pname in (systemd-udevd, kmod)
  output: >
    内核模块加载 (user=%user.name container=%container.name 
    module=%proc.args proc=%proc.name)
  priority: CRITICAL
  tags: [container, kernel, escape]

# 规则5:检测容器内使用 nsenter
- rule: Namespace Enter in Container
  desc: 容器内使用 nsenter 进入其他命名空间,横向移动迹象
  condition: >
    spawn_process and
    container and
    proc.name = nsenter and
    not nsenter_allowed
  output: >
    Namespace 进入 (user=%user.name container=%container.name 
    cmdline=%proc.cmdline pid=%proc.pid)
  priority: WARNING
  tags: [container, namespace, lateral_movement]
EOF
    echo "[+] 规则文件创建完成:/etc/falco/falco_rules_escape.yaml"
}

# 3. 配置 Falco 输出插件(Webhook)
configure_webhook_output() {
    echo "[*] 配置 Webhook 输出..."
    cat >> /etc/falco/falco.yaml << 'EOF'

# Webhook 输出配置
webhook_output:
  enabled: true
  url: "http://alert-manager:8080/falco"
  http_headers:
    - "Content-Type: application/json"
    - "Authorization: Bearer YOUR_TOKEN"
EOF
}

# 4. 启动 Falco 服务
start_falco() {
    echo "[*] 启动 Falco 服务..."
    systemctl daemon-reload
    systemctl enable falco
    systemctl restart falco
    sleep 3
    
    # 检查服务状态
    if systemctl is-active --quiet falco; then
        echo "[+] Falco 服务启动成功"
    else
        echo "[-] Falco 服务启动失败,查看日志:"
        journalctl -u falco -n 50 --no-pager
        exit 1
    fi
}

# 5. 验证规则加载
verify_rules() {
    echo "[*] 验证规则加载..."
    falco --list | grep -E "(Privileged Container Created|Sensitive Path Mount)" && \
        echo "[+] 规则加载成功" || echo "[-] 规则加载失败"
}

# 主函数
main() {
    install_falco
    create_escape_rules
    configure_webhook_output
    start_falco
    verify_rules
    echo ""
    echo "[==================================================]"
    echo "[+] Falco 容器逃逸检测部署完成!"
    echo "[==================================================]"
    echo "[*] 查看实时告警:journalctl -u falco -f"
    echo "[*] 测试规则:docker run --privileged alpine sh"
}

main "$@"

容器逃逸技术覆盖:

逃逸技术 检测原理 Falco 规则 误报率
特权模式逃逸 监控 privileged=true 标志 Privileged Container Created
Docker Socket 挂载 检测 /var/run/docker.sock 访问 Docker Socket Access 极低
敏感路径挂载 监控 mount 系统调用的源路径 Sensitive Path Mount
内核模块加载 监控 insmod/modprobe 执行 Kernel Module Load
cgroup 逃逸 监控 release_agent 文件写入 File Write to Release Agent
Namespace 滥用 监控 nsenter/unshare 执行 Namespace Enter

4.2 场景二:Kubernetes 环境下的 Falco 部署

在 Kubernetes 环境中,Falco 通常以 DaemonSet 方式部署,确保在每个节点上运行监控实例。

yaml 复制代码
# 文件路径:k8s/falco-daemonset.yaml
# 版本:Falco 0.38.1
# 功能:在 Kubernetes 集群中部署 Falco DaemonSet

apiVersion: v1
kind: ServiceAccount
metadata:
  name: falco
  namespace: falco
---
# RBAC:授予 Falco 读取 Pod 信息的权限
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: falco
rules:
  - apiGroups:
      - ""
    resources:
      - pods
      - replicasets
      - services
      - namespaces
      - nodes
    verbs:
      - get
      - list
      - watch
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: falco
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: falco
subjects:
  - kind: ServiceAccount
    name: falco
    namespace: falco
---
# DaemonSet:在每个节点上部署 Falco
apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: falco
  namespace: falco
  labels:
    app: falco
spec:
  selector:
    matchLabels:
      app: falco
  template:
    metadata:
      labels:
        app: falco
    spec:
      serviceAccountName: falco
      hostNetwork: true  # 使用宿主机网络以获取完整事件上下文
      hostPID: true      # 进入宿主机 PID 命名空间
      containers:
        - name: falco
          image: falcosecurity/falco:0.38.1
          imagePullPolicy: Always
          securityContext:
            privileged: true  # Falco 需要特权模式以加载 eBPF 程序
          args:
            - /usr/bin/falco
            - --crio/sock=/var/run/crio/crio.sock      # CRI-O socket 路径
            - --crio/enable-crio-support               # 启用 CRI-O 支持
            - --k8s-api-cert=/var/run/secrets/kubernetes.io/serviceaccount/ca.crt
            - --k8s-api-client-cert=/var/run/secrets/kubernetes.io/serviceaccount/token
            - -o              # 输出到标准输出(由 Fluentd 采集)
            - stdout
            - -T              # 禁用颜色输出
            - -k              # 启用 Kubernetes 元数据丰富
            - -K              # Kubernetes API 服务器地址
            - https://kubernetes.default.svc:443
          env:
            - name: HOST_ROOT
              value: /host
          volumeMounts:
            # 挂载宿主机根目录
            - name: host-root
              mountPath: /host
              readOnly: true
            # 挂载宿主机 proc 文件系统
            - name: proc
              mountPath: /host/proc
              readOnly: true
            # 挂载宿主机 cgroup
            - name: cgroup
              mountPath: /host/sys/fs/cgroup
              readOnly: true
            # 挂载 Falco 配置文件
            - name: falco-config
              mountPath: /etc/falco
              readOnly: true
            # 挂载自定义规则文件
            - name: falco-rules
              mountPath: /etc/falco/rules.d
              readOnly: true
      volumes:
        # 宿主机根目录卷
        - name: host-root
          hostPath:
            path: /
        # proc 文件系统卷
        - name: proc
          hostPath:
            path: /proc
        # cgroup 卷
        - name: cgroup
          hostPath:
            path: /sys/fs/cgroup
        # ConfigMap:Falco 配置
        - name: falco-config
          configMap:
            name: falco-config
        # ConfigMap:自定义规则
        - name: falco-rules
          configMap:
            name: falco-rules
---
# ConfigMap:Falco 配置文件
apiVersion: v1
kind: ConfigMap
metadata:
  name: falco-config
  namespace: falco
data:
  falco.yaml: |-
    base_config:
      priority: notice
    plugins:
      - name: k8saudit
        library_path: libk8saudit.so
        init_config: ""
        open_params: ""
      - name: cloudtrail
        library_path: libcloudtrail.so
        init_config: ""
    load_plugins: [k8saudit, cloudtrail]
    syslog_output:
      enabled: true
    stdout_output:
      enabled: true
---
# ConfigMap:自定义规则
apiVersion: v1
kind: ConfigMap
metadata:
  name: falco-rules
  namespace: falco
data:
  k8s_rules.yaml: |-
    # Kubernetes 特定规则
    
    - rule: Terminal in Container
      desc: 检测到容器内启动终端 shell
      condition: >
        spawned_process and
        container and
        shell_procs and
        not k8s.pod.name in (falco-*, monitoring-*)
      output: >
        Terminal shell in container (user=%user.name container=%container.name 
        pod=%k8s.pod.name namespace=%k8s.ns.name shell=%proc.name)
      priority: WARNING
      tags: [kubernetes, shell]
    
    - rule: K8s ConfigMap Modified
      desc: 检测到 ConfigMap 修改操作
      condition: >
        ka.req.action in (update, delete, create) and
        ka.req.resource = configmaps and
        ka.target.resource.namespace != kube-system
      output: >
        ConfigMap modified (user=%ka.user.name verb=%ka.req.action 
        ns=%ka.target.resource.namespace configmap=%ka.target.resource.name)
      priority: NOTICE
      tags: [kubernetes, audit]

部署命令:

bash 复制代码
#!/bin/bash
# 文件路径:k8s/deploy_falco.sh
# 版本:1.0

# 1. 创建命名空间
kubectl create namespace falco

# 2. 部署 Falco DaemonSet
kubectl apply -f k8s/falco-daemonset.yaml

# 3. 验证部署状态
kubectl wait --for=condition=ready pod -l app=falco -n falco --timeout=60s

# 4. 查看 Falco 日志
kubectl logs -l app=falco -n falco -f --tail=50

# 5. 创建告警输出 ConfigMap(集成 Prometheus)
kubectl apply -f - <<EOF
apiVersion: v1
kind: ConfigMap
metadata:
  name: falco-metrics
  namespace: falco
data:
  metrics.yaml: |-
    # Falco Prometheus 指标导出配置
    metrics:
      enabled: true
      exporter_port: 8765
      rule_stats: true
      event_stats: true
---
apiVersion: v1
kind: Service
metadata:
  name: falco-metrics
  namespace: falco
  labels:
    app: falco
spec:
  selector:
    app: falco
  ports:
    - name: metrics
      port: 8765
      targetPort: 8765
  type: ClusterIP
EOF

4.3 场景三:Falco 告警集成与自动化响应

通过 Falco 的输出插件,可以实现与 SIEM 系统的集成和自动化响应。

python 复制代码
#!/usr/bin/env python3
# 文件路径:/opt/falco/integrations/falco_webhook_server.py
# 版本:1.0
# 功能:接收 Falco Webhook 告警并执行自动化响应

from flask import Flask, request, jsonify
import requests
import json
import logging
from datetime import datetime
from typing import Dict, List
import subprocess
import os

# 配置日志
logging.basicConfig(
    level=logging.INFO,
    format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
    handlers=[
        logging.FileHandler('/var/log/falco-webhook.log'),
        logging.StreamHandler()
    ]
)
logger = logging.getLogger(__name__)

app = Flask(__name__)

# 配置:外部系统集成
CONFIG = {
    'slack_webhook': os.environ.get('SLACK_WEBHOOK_URL', ''),
    'pagerduty_key': os.environ.get('PAGERDUTY_ROUTING_KEY', ''),
    'elasticsearch_url': os.environ.get('ES_URL', 'http://localhost:9200'),
    'auto_containment': os.environ.get('AUTO_CONTAINMENT', 'false').lower() == 'true'
}

class AlertProcessor:
    """Falco 告警处理器"""
    
    def __init__(self, alert: Dict):
        self.alert = alert
        self.priority = alert.get('priority', '')
        self.rule = alert.get('rule', '')
        self.output = alert.get('output', '')
        self.tags = alert.get('tags', [])
        self.timestamp = datetime.utcnow().isoformat()
    
    def should_contain(self) -> bool:
        """判断是否需要自动隔离"""
        # 仅对高危告警执行自动隔离
        critical_rules = [
            'Privileged Container Created',
            'Kernel Module Load in Container',
            'Docker Socket Access from Container'
        ]
        return self.rule in critical_rules and CONFIG['auto_containment']
    
    def contain_container(self):
        """自动隔离容器"""
        try:
            container_id = self.alert.get('output_fields', {}).get('container.id')
            if not container_id:
                logger.warning("无法获取容器 ID,跳过隔离")
                return
            
            logger.warning(f"[自动隔离] 正在隔离容器: {container_id}")
            
            # 停止容器
            subprocess.run(
                ['docker', 'stop', container_id],
                timeout=30,
                capture_output=True
            )
            
            # 记录隔离操作
            self.log_containment_action(container_id)
            
            logger.info(f"[自动隔离] 容器 {container_id} 已成功隔离")
            
        except Exception as e:
            logger.error(f"[自动隔离] 失败: {str(e)}")
    
    def log_containment_action(self, container_id: str):
        """记录隔离操作到 Elasticsearch"""
        try:
            doc = {
                '@timestamp': self.timestamp,
                'action': 'container_containment',
                'container_id': container_id,
                'rule': self.rule,
                'priority': self.priority,
                'original_alert': self.alert
            }
            
            response = requests.post(
                f"{CONFIG['elasticsearch_url']}/falco-containment/_doc",
                json=doc,
                timeout=5
            )
            
            if response.status_code in (200, 201):
                logger.info("隔离操作已记录到 Elasticsearch")
            else:
                logger.warning(f"Elasticsearch 写入失败: {response.status_code}")
                
        except Exception as e:
            logger.error(f"记录隔离操作失败: {str(e)}")
    
    def send_to_slack(self):
        """发送告警到 Slack"""
        if not CONFIG['slack_webhook']:
            return
        
        # 根据优先级设置颜色
        color_map = {
            'EMERGENCY': 'danger',
            'ALERT': 'danger',
            'CRITICAL': 'danger',
            'ERROR': 'warning',
            'WARNING': 'warning'
        }
        color = color_map.get(self.priority, 'good')
        
        attachment = {
            'color': color,
            'title': f"Falco 告警: {self.rule}",
            'text': self.output,
            'fields': [
                {'title': '优先级', 'value': self.priority, 'short': True},
                {'title': '时间', 'value': self.timestamp, 'short': True},
                {'title': '标签', 'value': ', '.join(self.tags), 'short': False}
            ],
            'footer': 'Falco Security',
            'ts': int(datetime.utcnow().timestamp())
        }
        
        try:
            response = requests.post(
                CONFIG['slack_webhook'],
                json={'attachments': [attachment]},
                timeout=5
            )
            if response.status_code == 200:
                logger.info("告警已发送到 Slack")
            else:
                logger.warning(f"Slack 发送失败: {response.status_code}")
        except Exception as e:
            logger.error(f"Slack 发送异常: {str(e)}")
    
    def send_to_pagerduty(self):
        """发送告警到 PagerDuty(仅 CRITICAL 及以上)"""
        if self.priority not in ('EMERGENCY', 'ALERT', 'CRITICAL'):
            return
        
        if not CONFIG['pagerduty_key']:
            return
        
        try:
            response = requests.post(
                'https://events.pagerduty.com/v2/enqueue',
                json={
                    'routing_key': CONFIG['pagerduty_key'],
                    'event_action': 'trigger',
                    'payload': {
                        'summary': f"Falco: {self.rule}",
                        'severity': 'critical',
                        'source': 'falco',
                        'custom_details': self.alert
                    }
                },
                timeout=5
            )
            
            if response.status_code == 202:
                logger.info("告警已发送到 PagerDuty")
            else:
                logger.warning(f"PagerDuty 发送失败: {response.status_code}")
                
        except Exception as e:
            logger.error(f"PagerDuty 发送异常: {str(e)}")

@app.route('/falco', methods=['POST'])
def receive_falco_alert():
    """接收 Falco Webhook 告警"""
    try:
        alert_data = request.json
        logger.info(f"收到 Falco 告警: {alert_data.get('rule')}")
        
        # 处理告警
        processor = AlertProcessor(alert_data)
        
        # 1. 发送到 Slack
        processor.send_to_slack()
        
        # 2. 发送到 PagerDuty(高危告警)
        processor.send_to_pagerduty()
        
        # 3. 自动隔离(如果启用且满足条件)
        if processor.should_contain():
            processor.contain_container()
        
        # 4. 存储到 Elasticsearch(用于后续分析)
        # (此处省略 ES 存储代码)
        
        return jsonify({'status': 'success'}), 200
        
    except Exception as e:
        logger.error(f"处理告警失败: {str(e)}")
        return jsonify({'status': 'error', 'message': str(e)}), 500

@app.route('/health', methods=['GET'])
def health_check():
    """健康检查端点"""
    return jsonify({'status': 'healthy'}), 200

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=8080)

自动化响应流程:
CRITICAL+
WARNING+
启用
禁用
Falco 告警
优先级判断
PagerDuty 告警
Slack 通知
自动隔离?
停止容器
仅记录
Elasticsearch 存储


五、性能优化与最佳实践

5.1 eBPF 程序优化策略

1. 减少 Map 查找次数

c 复制代码
// ❌ 低效实现:多次查找 map
SEC("tracepoint/syscalls/sys_enter_execve")
int trace_execve_bad(struct trace_event_raw_sys_enter* ctx)
{
    __u32 tid = bpf_get_current_pid_tgid();
    
    // 第一次查找
    struct config *cfg1 = bpf_map_lookup_elem(&config_map, &tid);
    if (!cfg1) return 0;
    
    // 第二次查找(重复!)
    struct config *cfg2 = bpf_map_lookup_elem(&config_map, &tid);
    
    return 0;
}

// ✅ 优化实现:只查找一次
SEC("tracepoint/syscalls/sys_enter_execve")
int trace_execve_good(struct trace_event_raw_sys_enter* ctx)
{
    __u32 tid = bpf_get_current_pid_tgid();
    
    // 只查找一次,缓存指针
    struct config *cfg = bpf_map_lookup_elem(&config_map, &tid);
    if (!cfg) return 0;
    
    // 复用 cfg 指针
    __u64 value1 = cfg->field1;
    __u64 value2 = cfg->field2;
    
    return 0;
}

2. 使用 Array Map 替代 Hash Map

c 复制代码
// ❌ Hash Map:O(1) 但常数较大
struct bpf_map_def SEC("maps") cpu_stats_hash = {
    .type = BPF_MAP_TYPE_HASH,
    .key_size = sizeof(__u32),
    .value_size = sizeof(struct cpu_stat),
    .max_entries = 128,
};

// ✅ Array Map:直接索引,更快
struct bpf_map_def SEC("maps") cpu_stats_array = {
    .type = BPF_MAP_TYPE_ARRAY,
    .key_size = sizeof(__u32),
    .value_size = sizeof(struct cpu_stat),
    .max_entries = 128,
};

SEC("perf_event")
int perf_event_handler(struct bpf_perf_event_data* ctx)
{
    __u32 cpu = bpf_get_smp_processor_id();  // 获取当前 CPU ID
    
    // Array Map 可以直接使用 CPU ID 作为索引
    struct cpu_stat *stat = bpf_map_lookup_elem(&cpu_stats_array, &cpu);
    if (stat) {
        __sync_fetch_and_add(&stat->events, 1);  // 原子递增
    }
    
    return 0;
}

5.2 Falco 性能调优参数

参数 默认值 推荐值 说明
syslog_output.enabled true false 生产环境建议关闭,改用文件输出
stdout_output.enabled true false 日志轮转更可靠
file_output.filename - /var/log/falco/falco.log 启用文件输出
file_output.keep_alive false true 保持文件句柄打开
buffered_outputs false true 启用输出缓冲,提升性能
syscall_event_drops 0 1000 允许的每秒事件丢弃数
syscall_events_rate_limit 0 10000 事件速率限制(每秒)

配置文件示例:

yaml 复制代码
# 文件路径:/etc/falco/falco.yaml
# 版本:Falco 0.38.1

# 基础配置
base_config:
  priority: notice          # 最低告警优先级
  syslog_output:
    enabled: false          # 关闭 syslog
  stdout_output:
    enabled: false          # 关闭标准输出
  file_output:
    enabled: true
    filename: /var/log/falco/falco.log
    keep_alive: true
  buffered_outputs: true    # 启用缓冲
  
# 性能调优
syscall_event_drops:
  threshold: 1000           # 每秒 1000 次丢弃后告警
  actions:
    - log
    - alert

syscall_events_rate_limit: 10000  # 每秒最多处理 10000 个事件

# 线程配置
threads: 4                  # 用户态处理线程数

# 元数据丰富
enable_sources:
  - syscall                 # 启用系统调用事件
  - k8s_audit               # 启用 Kubernetes 审计日志

# 输出格式
json_output: true           # JSON 格式输出(便于解析)
json_include_output_property: true

5.3 规则优化技巧

1. 使用宏减少重复

yaml 复制代码
# ❌ 规则冗余
- rule: Web Server Detection
  condition: >
    container and
    proc.name in (nginx, apache, httpd) and
    container.image regexp (nginx:.*|httpd:.*)

# ✅ 使用宏
- macro: web_server_procs
  condition: proc.name in (nginx, apache, httpd)

- macro: web_server_images
  condition: container.image regexp (nginx:.*|httpd:.*)

- rule: Web Server Detection
  condition: >
    container and
    web_server_procs and
    web_server_images

2. 利用例外规则简化条件

yaml 复制代码
# ❌ 复杂的排除条件
- rule: Network Scan Detection
  condition: >
    spawned_process and
    proc.name in (nmap, netcat, nc) and
    not user.name in (security_team, admin) and
    not container.image in (security-tools:latest) and
    not proc.cmdline contains "authorized-scan"

# ✅ 使用例外规则
- rule: Network Scan Detection
  condition: >
    spawned_process and
    proc.name in (nmap, netcat, nc) and
    not network_scan_whitelist

- list: network_scan_whitelist
  items: [security_team, admin, security-tools:latest]

六、高级特性与扩展

6.1 自定义 eBPF 程序

Falco 支持加载自定义 eBPF 程序以扩展监控能力:

c 复制代码
// 文件路径:custom_ebpf_probes/socket_monitor.c
// 功能:监控异常 socket 连接

#include <linux/bpf.h>
#include <bpf/bpf_helpers.h>
#include <linux/socket.h>
#include <linux/in.h>

struct socket_event {
    __u64 timestamp;
    __u32 saddr;
    __u32 daddr;
    __u16 dport;
    __u8 protocol;
    char comm[16];
};

struct bpf_map_def SEC("maps") socket_events = {
    .type = BPF_MAP_TYPE_PERF_EVENT_ARRAY,
    .key_size = sizeof(__u32),
    .value_size = sizeof(__u32),
};

// 已知可信端口列表
struct bpf_map_def SEC("maps") trusted_ports = {
    .type = BPF_MAP_TYPE_HASH,
    .key_size = sizeof(__u16),
    .value_size = sizeof(__u8),
    .max_entries = 256,
};

SEC("kprobe/tcp_v4_connect")
int trace_tcp_connect(struct pt_regs *ctx, struct sock *sk)
{
    __u16 dport = 0;
    __u32 daddr = 0;
    
    // 读取目标端口和地址
    bpf_probe_read_kernel(&dport, sizeof(dport), &sk->__sk_common.skc_dport);
    bpf_probe_read_kernel(&daddr, sizeof(daddr), &sk->__sk_common.skc_daddr);
    
    // 转换字节序
    dport = ntohs(dport);
    
    // 检查是否为可信端口
    __u8 *trusted = bpf_map_lookup_elem(&trusted_ports, &dport);
    if (trusted && *trusted) {
        return 0;  // 可信端口,跳过
    }
    
    // 构造事件
    struct socket_event event = {
        .timestamp = bpf_ktime_get_ns(),
        .dport = dport,
        .daddr = daddr,
        .protocol = IPPROTO_TCP
    };
    
    // 获取进程名称
    bpf_get_current_comm(&event.comm, sizeof(event.comm));
    
    // 发送事件到用户态
    __u32 cpu = bpf_get_smp_processor_id();
    bpf_perf_event_output(ctx, &socket_events, BPF_F_CURRENT_CPU, 
                          &event, sizeof(event));
    
    return 0;
}

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

编译与加载:

bash 复制代码
#!/bin/bash
# 文件路径:custom_ebpf_probes/build_and_load.sh

# 1. 编译 eBPF 程序
clang -O2 -g -target bpf -c socket_monitor.c -o socket_monitor.o

# 2. 加载 eBPF 程序
bpftool prog load socket_monitor.o /sys/fs/bpf/socket_monitor

# 3. 挂载到 Falco
falco --bpf-probe /sys/fs/bpf/socket_monitor

6.2 Falco 插件开发

Falco 0.30+ 支持插件框架,允许扩展数据源和功能:

cpp 复制代码
// 文件路径:falco_plugins/custom_source/plugin.cpp
// 功能:自定义数据源插件

#include <falco/plugin.h>

class CustomSourcePlugin : public falco_plugin::IPlugin {
public:
    std::string get_name() override {
        return "custom_source";
    }
    
    std::string get_version() override {
        return "1.0.0";
    }
    
    // 插件初始化
    void init(const std::string& config) override {
        // 解析配置
        m_config = parse_config(config);
        
        // 初始化数据源
        setup_data_source();
    }
    
    // 获取事件
    bool next_event(falco_plugin::plugin_event& evt) override {
        // 从自定义数据源获取事件
        return fetch_event(evt);
    }
    
    // 字段提取器
    std::shared_ptr<falco_plugin::IFieldExtractor> 
    get_field_extractor() override {
        return std::make_shared<CustomFieldExtractor>();
    }
    
private:
    struct {
        std::string source_name;
        int sample_rate;
    } m_config;
    
    void setup_data_source() {
        // 设置数据采集逻辑
    }
    
    bool fetch_event(falco_plugin::plugin_event& evt) {
        // 实现事件采集
        return true;
    }
};

// 插件工厂函数
extern "C" {
    falco_plugin::IPlugin* create_plugin() {
        return new CustomSourcePlugin();
    }
    
    void destroy_plugin(falco_plugin::IPlugin* plugin) {
        delete plugin;
    }
}

七、故障排查与调试

7.1 常见问题诊断

问题 原因 解决方案
Failed to load eBPF program 内核版本过低(<4.14) 升级内核或使用 module 探针
Too many open files 文件描述符限制 增加 fs.file-max
Event drops detected 事件速率过高 启用速率限制或增加线程数
Cannot find Kubernetes pods RBAC 权限不足 授予 Pod 列表权限
Container metadata missing CRI 不兼容 配置正确的 CRI socket

7.2 调试技巧

bash 复制代码
#!/bin/bash
# 文件路径:/opt/falco/scripts/debug_falco.sh

# 1. 检查 eBPF 程序加载状态
echo "[*] 检查已加载的 eBPF 程序..."
bpftool prog list | grep falco

# 2. 查看 eBPF map 状态
echo "[*] 检查 eBPF map..."
bpftool map list | grep falco

# 3. 实时查看 Falco 事件(调试模式)
echo "[*] 启动 Falco 调试模式..."
falco \
  --disable-ky \
  -D /var/run/falco/falco.sock \
  -l debug \
  -o log_level=debug \
  -o json_output=false \
  -o buffered_outputs=false

# 4. 检查系统调用跟踪
echo "[*] 使用 strace 跟踪 Falco 进程..."
strace -p $(pgrep falco) -e trace=bpf -s 256

# 5. 验证规则语法
echo "[*] 验证规则文件..."
falco --validate -r /etc/falco/falco_rules.yaml

# 6. 查看 Perf Buffer 统计
echo "[*] Perf Buffer 统计..."
cat /sys/kernel/debug/tracing/perf/cpu/cpu0/stats

八、生产环境部署建议

8.1 高可用架构

Kubernetes Cluster
Node 3
Node 2
Node 1
Falco Pod
Fluentd
Falco Pod
Fluentd
Falco Pod
Fluentd
Kafka Cluster
Falco Webhook Server
SIEM System
Slack
PagerDuty

架构说明:

  1. Falco DaemonSet:每个节点运行一个 Falco Pod,确保全覆盖
  2. Fluentd Sidecar:采集 Falco 日志并转发到 Kafka
  3. Kafka Cluster:作为事件缓冲和消息队列,提供高吞吐量
  4. Webhook Server:消费 Kafka 消息,执行告警路由和自动化响应
  5. SIEM 集成:将告警推送到 SIEM 系统进行关联分析

8.2 资源配置建议

组件 CPU 请求 CPU 限制 内存请求 内存限制
Falco Pod 200m 1000m 256Mi 512Mi
Fluentd Sidecar 100m 500m 128Mi 256Mi
Webhook Server 500m 2000m 512Mi 1Gi

Pod 示例:

yaml 复制代码
apiVersion: v1
kind: Pod
metadata:
  name: falco-with-resources
  namespace: falco
spec:
  containers:
    - name: falco
      image: falcosecurity/falco:0.38.1
      resources:
        requests:
          cpu: 200m
          memory: 256Mi
        limits:
          cpu: 1000m
          memory: 512Mi
      securityContext:
        privileged: true

九、总结与展望

9.1 核心要点回顾

  1. eBPF 技术优势:通过内核态探针实现低开销、高性能的系统调用监控
  2. Falco 架构:用户态与内核态分离,支持灵活的规则引擎和多种输出方式
  3. 规则设计:基于 YAML 的声明式规则,支持复杂的过滤条件和例外管理
  4. 生产部署:DaemonSet 方式部署,配合 Fluentd、Kafka 构建高可用架构
  5. 自动化响应:通过 Webhook 集成实现告警路由、容器隔离等自动化操作

9.2 技术演进方向

方向 当前状态 未来展望
eBPF 技术演进 CO-RE(Compile Once, Run Everywhere) 更简单的探针分发和跨内核版本兼容
性能优化 Ring Buffer(内核 5.8+) 更高的吞吐量和更低的延迟
AI 驱动 基于规则的静态检测 机器学习异常检测和行为建模
云原生集成 Kubernetes、Containerd 扩展到 CNI、CSI 等更多云原生组件
标准化 Falco 社区规则集 CNCF 安全规范和行业标准

9.3 最佳实践清单

  • 生产环境:使用 Ring Buffer(内核 5.8+)或 Perf Buffer
  • 性能调优 :启用 buffered_outputs 和事件速率限制
  • 规则管理:使用宏和列表减少冗余,定期审计规则
  • 高可用:DaemonSet 部署 + Kafka 缓冲 + 多副本 Webhook Server
  • 安全加固:限制 Falco 进程权限,使用 RBAC 最小权限原则
  • 监控告警:监控 Falco 自身健康状态(事件丢弃率、CPU/内存使用)
  • 日志管理:使用 Elasticsearch/Splunk 长期存储告警日志
  • 自动化响应:对高危告警启用容器隔离,构建自动化响应链

参考资料


版权声明:本文内容遵循 CC BY-NC-SA 4.0 协议,转载请注明出处。


💡 提示:本文所有代码示例均基于 Falco 0.38.1 版本,实际使用时请根据部署环境的内核版本和 Falco 版本进行调整。

相关推荐
m0_738120722 小时前
网络安全编程——Python编写Python编写基于UDP的主机发现工具(完结:解码ICMP头)
python·网络协议·安全·web安全·udp
胡楚昊2 小时前
openClaw CVE-2026-25253复现与简单分析
安全
哇哦9822 小时前
渗透安全(渗透防御)③
安全·https·渗透·dns·渗透防御
信创DevOps先锋2 小时前
企业级开源治理新选择:Gitee CodePecker SCA如何重塑软件供应链安全
安全·gitee·开源
csdn_aspnet2 小时前
如何保护您的 .NET Web API 免受常见安全威胁
安全·xss·csrf·.net core·cors
CV-杨帆3 小时前
EACL 2026 大模型安全相关论文整理
安全
曼岛_3 小时前
[网络安全] Linux权限维持-隐藏篇
linux·安全·web安全·安全威胁分析
恋恋风尘hhh3 小时前
文字点选验证码前端安全研究:以网易易盾(dun.163)为例
前端·安全
honest_gg3 小时前
潜影【TraceHarvest】:自动化“一键”钓鱼工具
安全·hw·社会工程学·hvv·钓鱼·攻防演练·护网