Linux sysdig falco 的 rule condition 与 macro 复用编写规范

1次阅读

macro不能直接作布尔值使用,必须显式展开为完整表达式;多macro组合需加括号防优先级错误;不支持参数化调用,依赖evt.arg.*字段配合rule级条件过滤;嵌套层级应≤2层;跨文件复用需统一加载顺序与格式。

Linux sysdig falco 的 rule condition 与 macro 复用编写规范

rule condition 里不能直接用 macro 名字当布尔值

很多人写 condition 时直接写 is_file_write,以为 macro 定义了就自动可当条件用——不行。macro 只是语法糖,必须显式展开成完整表达式,否则 sysdig/falco 解析失败或逻辑错乱。

正确做法是把 macro 当作“模板片段”来拼接,不是函数调用:

  • macro 定义里用 syscall.name = open or syscall.name = openat 这类原始条件,不能含 and/or 外部逻辑
  • 在 rule 的 condition 中,用括号包裹 macro 引用:(is_file_write),而不是 is_file_write
  • 多个 macro 组合必须加括号防优先级问题:(is_file_write) and (user.name != "root"),不加括号可能被解析为 is_file_write and user.name != "root"(非法)

macro 参数化要靠 evt.arg.* + 条件过滤,不是函数传参

sysdig/falco 的 macro 不支持参数,所谓“复用”,其实是靠通用字段(如 evt.arg.filenameevt.arg.pathname)配合 rule 级别的额外约束实现的。

比如想让一个 macro 同时匹配 /etc/passwd 和 /etc/shadow,不能写 is_sensitive_file("/etc/passwd"),而得:

  • macro 定义只写通用模式:evt.arg.filename contains "/etc/" and (evt.arg.filename endswith "passwd" or evt.arg.filename endswith "shadow")
  • rule 中通过 condition 补充上下文限制:(is_sensitive_file) and proc.name = "vim"
  • 注意 evt.arg.* 字段是否实际存在:openatevt.arg.pathnameopenevt.arg.filename,混用会导致漏匹配

rule condition 中嵌套 macro 超过两层容易触发解析错误

sysdig 2.10+ 和 falco 1.20+ 对 macro 展开有深度限制。三层以上嵌套(比如 A → B → C)常报 Error: failed to parse rule condition 或静默忽略部分逻辑。

实操建议:

  • macro 层级控制在两层内:顶层 macro 尽量直接引用基础条件,少套 macro
  • sysdig -c list_macros 检查 macro 是否被正确定义和展开
  • 调试时把 macro 内容直接粘贴进 rule 的 condition,确认逻辑通后再抽成 macro
  • falco 1.22+ 支持 -V 模式输出展开后的 condition,运行 falco -V -r rules.yaml 2>&1 | grep "expanded condition" 可验证

不同版本 falco/sysdig 的 macro 作用域不兼容

sysdig 的 macro 是全局生效的;falco 则按 rules 文件加载顺序解析,后面文件里的 macro 能引用前面文件定义的,但反过来不行。跨文件复用 macro 很容易因加载顺序错乱导致 undefined macro 错误。

稳妥做法:

  • 所有 macro 集中放在单独的 macros.yaml 文件,并确保它在 rules 列表最前加载
  • 避免在 rule 文件里定义 macro,尤其不要和 rule 混写在同一文件
  • sysdig 3.x 开始要求 macro 必须带 macro: 前缀,而 falco 1.18–1.21 允许省略——混用环境时务必统一格式
  • 检查 falco --versionsysdig --version,falco ≥1.22 才支持 macro 的 required_engine_version 字段做版本锁

macro 看似简单,但真正跨团队、跨环境复用时,最麻烦的从来不是写法,而是 macro 展开那一刻——你永远不知道它到底替换成啥了。

text=ZqhQzanResources