Falco 是 CNCF 毕业的 Kubernetes 运行时安全检测工具:它借助 eBPF 在内核层捕获系统调用,实时判断”容器里正在发生什么异常”,一旦发现违规(比如有人在生产容器里开了 shell、读取了敏感文件、发起了异常网络连接),立刻产生安全告警。如果说 Kubernetes 准入控制 是在”门禁”处拦截非法请求,那么 Falco 就是在”屋内”持续巡检,两者互补构成纵深防御。
一、为什么需要运行时入侵检测
Kubernetes 的安全往往止步于”准入”与”网络”两层:准入控制负责拦截不合规的 YAML,网络策略负责限制 Pod 之间的流量。但即便两者都配齐,攻击者仍可能通过合法入口(如被拿下的业务容器)在运行时干坏事——下载挖矿木马、读取挂载的 Secret、横向移动到宿主机。传统防火墙看不见容器内部的系统调用,而这正是运行时检测要补的盲区。
Falco 的价值在于:它不关心你的镜像是否通过扫描,也不关心你的 YAML 是否合规,它只盯着”此刻容器到底执行了什么”。这种”行为基线”视角,能抓住很多静态检查抓不到的 0day 利用与误用。
二、架构与原理:eBPF 是怎么”看见”容器的
Falco 由内核探针(driver)和用户态引擎两部分组成。探针负责从内核采集系统调用事件,早期使用内核模块,现在主流方案是 eBPF 数据面 同款的 eBPF 技术,无需编译内核模块即可挂载。用户态引擎收到原始事件后,用规则引擎逐条匹配,命中即产生告警。
两种探针各有取舍:内核模块兼容性最好,但每次内核升级都可能需要重新编译,在频繁滚动升级的托管集群里很麻烦;eBPF 探针随内核自带、无需编译,但对内核版本有下限要求(通常 4.x 以上)。生产选型时,建议优先 eBPF,遇到老内核再回退到内核模块,并用 DaemonSet 的节点亲和性分而治之。

三、快速部署(Helm 一行搞定)
官方推荐用 Helm 安装,它会自动选择可用的 eBPF 探针并部署 Falco 守护进程到每个节点:
# 添加仓库并安装
helm repo add falcosecurity https://falcosecurity.github.io/charts
helm repo update
helm install falco falcosecurity/falco \
--namespace falco --create-namespace \
--set driver.kind=ebpf
# 查看各节点 Falco 是否 Ready
kubectl get pods -n falco -o wide
如果集群是 Docker Compose 编排的单机环境,也可以直接以容器方式运行 Falco,挂载 /var/run/docker.sock 与宿主机 /proc 即可。
四、规则引擎:规则、宏、列表三件套
Falco 的规则文件由三类对象构成:列表(lists) 是常量集合,宏(macros) 是可复用的条件片段,规则(rules) 把宏与条件组合成最终判定。理解这三件套,才能写出可维护的检测逻辑。
# 列表:常见敏感目录
list: sensitive_dirs
items: [/etc, /var/run/secrets, /root/.ssh]
# 宏:是否写向敏感目录
macro: write_sensitive
condition: (evt.type in (open,openat,rename) and evt.is_open_write=true and fd.name in sensitive_dirs)
# 规则:检测对敏感目录的写入
rule: Write to sensitive directory
desc: 检测到进程向敏感目录写入文件
condition: write_sensitive and not container.image startswith "trusted/"
output: "敏感目录写入 (user=%user.name file=%fd.name container=%container.name)"
priority: WARNING
4.1 内置规则开箱即用
Falco 自带一套成熟的规则集,覆盖”容器内启动 shell””读 Secret””可疑外联””提权”等高频风险。生产环境通常先全量开启内置规则,再按业务噪声逐步裁剪,而不是从零写起。
五、编写你的第一条自定义规则
最常见、也最实用的自定义规则是”检测有人在容器里开交互式 shell”。攻击者拿到 webshell 后第一件事往往是起 bash,这条规则能第一时间报警:
rule: Terminal shell in container
desc: 容器内启动了交互式 shell
condition: >
spawned_process and container.id != host
and proc.name in (bash, sh, zsh, ksh)
and proc.tty != 0
output: "容器内启动 shell (user=%user.name command=%proc.cmdline container=%container.id)"
priority: NOTICE
tags: [shell, container]
把这段保存为 /etc/falco/rules.d/custom.yaml 后,Falco 会自动热加载,无需重启。我们可以立刻验证:
# 随便进一个运行中的 Pod 里执行 shell
kubectl exec -it my-app-7d9f -- /bin/sh
# 几秒内 Falco 日志即出现:Terminal shell in container
六、告警输出与集成:让安全事件”叫出声”
默认 Falco 只把告警写到 stdout(被容器运行时收集为日志)。要真正发挥作用,需要把告警转发到你的观测体系。Falco 支持 Falcoctl、webhook、gRPC 等多种输出,最典型的组合是:Falco → 文件/stdout → 采集器 → Prometheus 告警 或 SIEM。
# falco 的 webhook 输出配置示例(outputs 段)
json_output: true
outputs:
webhook:
url: "https://alerts.internal/falco"
custom_headers:
Authorization: "Bearer <token>"
# 仅转发 WARNING 及以上
minimum_priority: "WARNING"
收到 webhook 后,你可以用一小段代码做去重与分级,再推送到企业微信、Slack 或值班系统,实现真正的”运行时入侵告警闭环”。
当告警量上来后,建议在 Falco 与最终通道之间加一层 falcosidekick:它负责把原始告警做富化(补全 Pod、Namespace、镜像、集群名等上下文)、按标签路由到不同目的地(Slack、Elasticsearch、Prometheus、Kafka),还能做简单的去重与抑制,避免一次批量异常把值班群刷爆。对于已经接入 Prometheus 告警 的团队,falcosidekick 直接把 Falco 事件转成指标,复用既有 Alertmanager 路由即可,几乎零额外成本。
七、把运行时检测接进 CI/CD 安全门禁
安全不是上线后的事。可以在 GitHub Actions 流水线里加入”镜像扫描 + 策略校验”环节,再配合 Falco 的离线规则校验,保证合并到主干的镜像不会引入高危行为。例如用 falco 的 falco --validate 在 PR 阶段校验自定义规则语法,避免一条错误规则让整个集群静默。
# .github/workflows/security.yml 片段
- name: Validate Falco rules
run: |
docker run --rm -v $PWD/rules:/rules \
falcosecurity/falco:latest falco --validate /rules/custom.yaml
八、生产落地检查清单
| 检查项 | 建议 |
| 探针类型 | 优先 eBPF,避免内核模块编译失败 |
| 规则来源 | 内置全集 + 业务裁剪,切勿从零造轮子 |
| 告警通道 | webhook 接 SIEM,按 priority 分级 |
| 噪声治理 | 用 macro 排除可信镜像与运维操作 |
| 规则校验 | CI 阶段 –validate,防止静默失效 |
| 资源占用 | 观察 eBPF 探针 CPU,节点级限流 |
九、常见坑与排查
| 现象 | 原因与对策 |
| Pod 一直 CrashLoop | 内核不支持 eBPF,改用 driver.kind=module 或升级内核 |
| 告警刷屏 | 规则过宽,用 macro 排除可信容器与 CI 账户 |
| 规则改了不生效 | 确认放在 rules.d 且格式正确,看 falco 启动日志 |
| 漏报 | 检查 events 采样率与 priority 阈值是否过高 |
十、小结
Falco 把”运行时入侵检测”这件事做到了足够轻量:eBPF 探针零侵入、规则三件套易上手、告警可无缝接入现有观测栈。它与准入控制、网络策略形成纵深防御,是每一个生产级 Kubernetes 集群都该默认装上的”屋内摄像头”。从内置规则起步,按业务裁剪,再把告警接进值班体系,你就能在攻击者真正得手之前收到那一声警报。




