falco ebpf模式下规则必须基于syscall事件,路径匹配需用pmatch或startswith且依赖fd.name解析(v3.2+默认启用),不可混用syscall与k8s等event字段,热加载失败常因未启用syscall插件或rules_file路径错误。

eBPF 规则必须用 syscall 作为事件源,不能直接监听文件路径
Falco 的 eBPF probe 不支持像 Sysdig Inspect 那样用 openat(/etc/shadow) 这种带路径的过滤写法。它只捕获原始系统调用,路径解析在用户态完成,所以规则里得先匹配 syscall 类型,再靠 fd.name 或 proc.cmdline 做二次筛选。
常见错误是照搬 Sysdig 的过滤语法,比如写 evt.type=openat and fd.name contains "/etc/shadow" —— 这在 Falco eBPF 模式下会完全不触发,因为 fd.name 在 syscall 事件中为空(路径还没解析)。
- 正确做法:用
evt.type in (open, openat, openat2)匹配调用,再加fd.name pmatch ("/etc/.*")(注意要用pmatch,不是contains) - 性能影响:
pmatch比contains开销大,高频路径建议用精确前缀匹配,比如fd.name startswith "/etc/shadow" - 兼容性注意:Falco v3.2+ 才默认启用
fd.name解析;旧版本需确认-DENABLE_FD_PATH_RESOLUTION=ON已编译进 probe
syscall 和 event 规则类型不能混用
Falco 规则定义里 condition 字段的上下文取决于 event 类型。eBPF 模式下,syscall 类型规则能访问 evt.arg.*、fd.* 等字段,而 event 类型(如 container、k8s)字段完全不同,强行混用会导致条件永远为 false。
典型现象:规则写了 evt.type=openat and k8s.pod.name="prod-api",但始终不告警——因为 k8s.pod.name 只在 event 类型事件中存在,syscall 事件里这个字段压根没值。
- 判断依据:看
rule定义里的event字段值,syscall表示走内核路径,container或k8s表示走用户态事件源 - 替代方案:需要关联容器上下文时,用
container.id(所有 syscall 事件都带)再查 K8s API,或用macro封装跨层逻辑 - 调试技巧:加
output: "debug: %evt.type %fd.name %container.id"快速验证字段是否可取
用 syscall.openat 替代 sysdig -e 'openat' -p '%proc.cmdline %fd.name'
Sysdig Inspect 常用 -p 格式化输出看行为,但 Falco 是检测引擎,不是交互式工具。要复现类似效果,得靠 output 字段拼接字段,并确保这些字段在当前 event 类型中真实存在。
容易踩的坑是直接把 Sysdig 的格式粘贴过去,比如写 output: "%proc.cmdline %fd.name",结果日志里全是空值——因为 proc.cmdline 在某些 syscall 中未捕获(尤其子进程刚 fork 时)。
- 稳妥写法:
output: "Open attempt: %proc.name (pid:%proc.pid) %fd.name %evt.arg.flags",优先用proc.name(稳定)、proc.pid(必有) - 权限限制:eBPF 默认不捕获完整命令行,需启动 Falco 时加
--enable-external-events并确认/proc/PID/cmdline可读 - 路径脱敏:生产环境避免在 output 里打全路径,可用
%fd.name endswith "/shadow"替代明文
规则热加载失败?检查 rules_file 路径和 syscall 插件状态
Falco 支持 curl -X POST http://localhost:8765/test 测试规则,但 eBPF 模式下热加载常失败,根本原因往往不是语法错,而是 probe 本身没加载 syscall 插件。
现象是 falco --validate-rules 显示 OK,但 systemctl status falco 日志里反复报 Failed to load rules: no event sources enabled,或者规则完全不触发。
- 确认命令:
falco --list-event-sources输出必须含syscall;若只有k8saudit或json,说明 eBPF probe 没启用 - 检查路径:
rules_file在falco.yaml中必须是绝对路径,相对路径在 systemd 下常失效(比如写成rules/falco_rules.yaml) - 内核兼容性:RHEL/CentOS 8.4+ 或 Ubuntu 20.04+ 才默认支持完整 syscall tracepoints;老内核需手动编译 probe 或降级用
modern_bpf插件
真正难调的是 syscall 上下文丢失——比如 fork 后 execve 前的短暂窗口,proc.cmdline 还是父进程的,这时候只能靠 proc.pname 和 evt.arg.pathname 组合判断,没法完全对齐 Sysdig 的实时快照能力。










