cron 在凌晨三点执行了 curl
本实验在 VM 中运行
一台 Ubuntu 24.04 VM 上,Falco 已经以 modern eBPF 驱动运行。系统调用插桩是内核功能,在实验 Pod 中根本无法实现。启动需要 2–3 分钟(因为要安装 Falco)。
目标
亲手编写能抓住标题中事件的规则。拆分列表和宏,把告警保存为 JSON 文件,真正种下一个计划任务,并在文件中确认规则抓到了它。然后再制造一个会命中同一规则的正常作业,只把它作为例外排除,再确认坏的仍然能被抓到。
为什么重要
基于日志的检测有结构性的局限。日志只会留下程序决定要留下的内容。系统调用则不同——无论是创建进程还是打开文件,都必须经过内核,而内核是骗不了的。
但是,如果把系统调用全看一遍,告警就会太多。所以运行时检测的实际工作不是“抓什么”,而是“可以排除什么”。只要一条规则把正常的备份作业也抓进来,几天之内就没人看告警了。这时如果把规则放宽,真正的事件也会一起漏掉。把例外收得窄、并写明理由,这个习惯决定了检测体系的寿命。
步骤
- 把 Falco 的版本、驱动和服务状态保存到
/root/falco/01-engine.txt。 - 在
/etc/falco/rules.d/labhub-cron.yaml中用一个list、一个macro、一个rule编写规则。输出中必须包含%user.name和%proc.cmdline。 - 在
/etc/falco/config.d/labhub-output.yaml中开启 JSON 输出和文件输出(/var/log/falco/events.json),并重启服务。 - 创建
/etc/cron.d/telemetry,让它每分钟向外发出请求。 - 等待 1 分钟以上,把捕获到的一行告警保存到
/root/falco/05-alert.json。 - 创建
/etc/cron.d/backup-sync,再放一个会命中同一规则的正常作业,只把它通过规则的exceptions排除,然后重启服务。 - 清空
events.json,等计划任务运行一次,在/root/falco/07-verify.txt中确认正常作业没有被抓到、坏的被抓到了。 - 把规则的依据写到
/root/falco/08-report.md,分为## 무엇을 잡는가、## 왜 예외를 두었나、## auditd 와 무엇이 다른가、## 다음에 넓힐 곳(韩文,依次意为“抓什么”“为什么设置例外”“与 auditd 有什么不同”“下一步要扩大的地方”)四节。
参考
- 规则验证用
falco --validate /etc/falco/falco_rules.yaml --validate <내 파일>(占位符为自己的规则文件)。必须同时给出默认规则文件——spawned_process之类的宏定义在那边。 - cron 启动 shell,再由 shell 调用命令,所以父进程是 shell。要看祖先,像
proc.aname[2]这样写。 - 服务名是
falco,但实际的单元因驱动而异。用systemctl show -p Id --value falco确认,并以该名称查看 journal。 - 计划任务每分钟运行一次。等待的过程已经拆分成了步骤,所以不要急着评分。
- 常见错误:把例外以
and not …的形式融进condition末尾。六个月后没人知道那一段的理由。 - 常见错误:例外收得太宽,导致整条规则变得安静。第 7 步会抓住这一点。
什么在用什么驱动运行
把 falco --version 的版本号、它以哪个驱动(单元名称)运行、以及服务状态保存到 /root/falco/01-engine.txt。
systemctl show -p Id --value falco 会给出实际的单元名称。falco 是该单元的别名。不知道驱动,就无法找出“为什么抓不到”。
编写一条规则
在 /etc/falco/rules.d/labhub-cron.yaml 中编写一个 list、一个 macro、一个 rule。要抓住计划任务下运行外部请求工具的行为,output 中必须包含 %user.name 和 %proc.cmdline,priority 为 WARNING 以上。
list 和 macro 只能引用定义在自己前面的内容,所以按列表 → 宏 → 规则的顺序书写。cron 会启动 shell,所以要看的不是父进程而是祖先。写完后,连同默认规则文件一起用 --validate 确认。
把告警留在文件里
在 /etc/falco/config.d/labhub-output.yaml 中开启 json_output: true 和文件输出(/var/log/falco/events.json),并重启服务。不要整个修改 falco.yaml。
config.d 下的文件会叠加到默认配置上。重启后查看 journal,会逐行打印出读取了哪些配置文件——这就是“真的生效了”的证据。
种下事件
创建 /etc/cron.d/telemetry,让它每分钟用 curl 向外发出请求。它是 /etc/cron.d 格式,所以在调度时间之后有一栏是执行命令的用户。
每分钟是 * * * * *。请求不需要真的成功——进程被执行了这件事会被系统调用捕获。
在文件中看是否抓到
等计划任务运行一次后,从 /var/log/falco/events.json 中挑出自己规则的一行告警,保存到 /root/falco/05-alert.json。
用 jq -c 'select(.rule == "<규칙 이름>")' /var/log/falco/events.json | tail -1 就会得到一行(占位符为规则名称)。文件里也混有 Falco 内部告警,所以要按规则名称过滤。
窄窄地排除一个正常作业
创建 /etc/cron.d/backup-sync,再放一个会命中同一规则的正常作业,只把它通过规则的 exceptions 排除,然后重启服务。不要在 condition 末尾加 and not …。
exceptions 用 name、fields、comps、values 书写。在 fields 中写要看的事件字段,在 comps 中写比较方式,在 values 中写值的集合,引擎就会把它以 and not (…) 的形式接到条件后面。值收得太宽,会在第 7 步被抓到。
两个都再运行一遍
清空 /var/log/falco/events.json,等计划任务运行一次(最多 1 分钟),确认 telemetry 被抓到而 backup-sync 没有被抓到,并用两行以上写到 /root/falco/07-verify.txt。
服务重新读取规则,例外才会生效(上一步已经重启过了)。旧告警还在会干扰判断,所以请清空文件,只看新收到的。如果例外太宽,该抓的也会变得安静。
留下规则的依据
在 /root/falco/08-report.md 中写四节:## 무엇을 잡는가、## 왜 예외를 두었나、## auditd 와 무엇이 다른가、## 다음에 넓힐 곳(韩文,依次意为“抓什么”“为什么设置例外”“与 auditd 有什么不同”“下一步要扩大的地方”)。正文中必须出现 exceptions、priority、events.json 三个词。
下一个人看到这条规则时,最想先删掉的就是例外。如果没有写明为什么设置它,就真的会被删掉。也请整理一下它与前一个模块中的内核审计有哪些重叠、哪些不同。