Falco 运行时规则与告警链路
一个集群完成节点镜像滚动后,Falco DaemonSet 的 desired、current、ready 全部相等,安全平台却再也收不到“容器内启动 shell”的告警。值班人员重启转发组件、检查网络策略,仍没有结果。真正的断点在节点内核:BTF 文件不可读,集群安全策略同时阻断 bpf(),modern eBPF 探针没有成功加载。Pod Ready 证明进程活着,却没有证明 syscall 事件进入了 Falco。
另一个团队升级默认规则后遭遇告警洪峰。某条规则新增了容器构建工具常见的文件动作,数千条事件挤满输出链;工程师匆忙写了按 namespace 放行的 exception,噪声消失了,真正的交互式 shell 也一起被隐藏。规则、字段、例外、Rules 版本和输出容量没有作为一个变更事务管理,导致“减少误报”演变成不可见的漏报。
Falco 判断的是运行行为,不是配置合规
Falco 从内核或插件事件源接收事实,用规则判断行为是否可疑,再把命中结果交给输出通道。它适合发现容器内 shell、敏感文件访问、异常进程、权限提升等运行行为。它不会替 kube-apiserver 拒绝一个不合规 Deployment,也不会因为镜像签名有效就降低运行时风险。规则命中默认产生告警,不会自动终止进程或删除 Pod。
一次 syscall 检测依次经过 driver、libscap、libsinsp、rule engine 和 output。driver 从内核取得事件;libscap 负责采集与统一编码;libsinsp 解析事件并维护进程、容器等状态,补充 Kubernetes 上下文;规则引擎按 condition 求值;命中后产生带 rule、priority、tags、output 与 output fields 的事件。Kernel Events 架构给出了这些组件的职责关系。
事件源之间相互隔离。syscall、Kubernetes Audit、CloudTrail 等插件源各有线程和规则,Falco 不做跨事件源时序关联。需要把一次进程执行与云 API 操作串成攻击路径时,应把带稳定资产键的事件送往 SIEM 或流处理平台,而不是在 Falco condition 中假设存在全局事件历史。
先用能力探测决定驱动
Falco 0.44.1 的驱动主线是 modern_ebpf 与 kmod。modern eBPF 使用嵌入 Falco 用户态二进制的 CO-RE 探针,不需要在节点下载或现场编译独立 probe,是现代 Linux 的优先选择。它依赖 BTF、BPF ring buffer 与 tracing program 等内核能力;发行版可能向较旧内核回移这些能力,所以版本号只是线索,能力探测才是安装依据。Kernel Events 文档可用于核对目标 release 的驱动要求。
uname -a
test -r /sys/kernel/btf/vmlinux && echo BTF_OK || echo BTF_MISSING
sudo bpftool feature probe kernel | grep 'map_type ringbuf is available'
sudo bpftool feature probe kernel | grep 'program_type tracing is available'
kubectl get nodes -o wide预期证据不是四条命令都“看起来正常”,而是每类生产节点都有记录:内核发行线、架构、BTF 可读、ring buffer 与 tracing program 可用。modern eBPF 的细粒度权限涉及 CAP_BPF、CAP_PERFMON、CAP_SYS_RESOURCE 和 CAP_SYS_PTRACE;不支持细分能力的环境可能需要 CAP_SYS_ADMIN。SELinux、AppArmor、seccomp 或托管平台策略仍可能阻断加载,即使 capability 已写入 Pod spec。
kmod 适合无法提供 modern eBPF 能力、但允许团队管理内核模块的 Linux 节点。它需要匹配运行内核的 headers、DKMS 与编译工具,Secure Boot 还可能要求模块签名和 MOK 注册。节点内核升级会让模块与 headers 的组合改变;容器化 driver loader 下载不到预编译模块时,可能转入现场构建。安装或加载内核模块需要完整特权,不能包装成“加几项 capability 就是最小权限”;模块已经由节点侧安装后,Falco 用户态容器可改用设备映射、host PID 与 CAP_SYS_PTRACE 等更小运行权限,具体挂载和安全策略仍须按目标 Chart 渲染结果验证。
当托管节点既禁止 BPF 又禁止加载模块时,syscall 检测链无法成立。可以运行插件事件源,但那只提供插件对应的审计事实,不会恢复节点 syscall 可见性。此时应更换节点能力、采用平台提供的运行时传感器,或明确接受该检测缺口,而不是留下一个无效 DaemonSet。
在一次性集群固定安装组合
Kubernetes 安装需要 Helm、可创建 namespace、DaemonSet、ServiceAccount、RBAC 与相关安全上下文的集群权限。先确认当前 context,避免把特权传感器装进错误集群;再查询仓库并固定 Chart。下面以 Chart 9.1.0、Falco 0.44.1 为示例组合;校准时的稳定规则版本是 Falco Rules 5.1.0,但该 Chart 默认引用 falco-rules:5 主版本通道并启用 falcoctl follow,下面的命令并没有把 Rules 固定在 5.1.0。生产环境应固定或归档批准的 Rules artifact,并记录实际解析出的版本与摘要。团队采用其他组合时也要同步验证 Chart values、appVersion、Rules artifact 与内核矩阵。
kubectl config current-context
kubectl auth can-i create daemonsets.apps -n falco
kubectl auth can-i create clusterroles.rbac.authorization.k8s.io
helm repo add falcosecurity https://falcosecurity.github.io/charts
helm repo update
helm show chart falcosecurity/falco --version 9.1.0
helm show values falcosecurity/falco --version 9.1.0 > falco-values-reference.yaml
helm upgrade --install falco falcosecurity/falco \
--namespace falco \
--create-namespace \
--version 9.1.0 \
--set driver.kind=modern_ebpf \
--set tty=true \
--wait安装者需要集群级 RBAC,运行中的 Falco ServiceAccount 则应限于采集和元数据富化所需权限。driver.kind=modern_ebpf 选择采集引擎;tty=true 让容器日志在常见 Kubernetes 日志路径中保持可读,是 Chart 场景中的输出适配项,不是驱动开关。生产 values 应进入版本库,通过 Secret 引用输出凭证,避免把 webhook token 放进命令历史。
官方也提供 Falco Operator,用 CRD 管理 Falco、Rulesfile、Plugin、Config 与 Component,适合需要集中管理多实例和组件生命周期的平台。Falco Operator 安装文档将其作为 Kubernetes 推荐路径,同时其 API 仍是 v1alpha1。初次落地可先用 Chart 看清资源与故障链;采用 Operator 后,要把 CRD 兼容、controller 可用性、finalizer 和卸载顺序纳入治理。
安装成功要有四层证据
第一层是调度覆盖:目标 Linux 节点是否都有 Falco Pod,污点节点、arm64 节点和专用节点池是否被 selector 或 toleration 漏掉。第二层是进程状态:容器是否 Ready、是否频繁重启。第三层是探针状态:启动日志是否明确显示 syscall source 与 modern BPF probe 初始化成功。第四层是规则与输出:目标 Rules 是否加载,受控事件是否命中并到达预期出口。
kubectl get nodes -o name
kubectl get daemonset,pods -n falco -o wide
kubectl rollout status daemonset/falco -n falco --timeout=180s
kubectl logs -n falco -l app.kubernetes.io/name=falco --tail=200 \
| grep -Ei 'modern|BPF|syscall|rules|error|warning|drop'健康判据应写成“目标节点有实例且探针、规则和输出均有效”,而不是 DESIRED=CURRENT=READY。若日志出现 BTF、ringbuf、verifier、permission 或 operation not permitted,先回到节点能力和安全策略;若探针成功但没有目标规则,检查 rules 文件、加载顺序与事件源;若本地日志有命中而 SIEM 没有,再查输出链。
规则由 condition、字段和例外共同决定
一条 Falco rule 通常包含 rule、desc、condition、output、priority 和 tags。macro 把可复用条件命名,list 保存值集合,exception 对特定环境噪声做窄化排除。规则不是字符串搜索:condition 在指定事件源的字段模型上求值,对 syscall 规则应明确事件类型,避免让条件在大量无关事件上重复计算。Rules 基本元素说明了 rule、macro、list 与 exception 的结构。
下面是一条教学规则,检测实验 namespace 中容器启动 shell 进程。它不能仅凭这些字段证明 shell 具有交互终端,适合在隔离环境理解字段和输出,不应代替官方规则集的生产规则。先把规则装入 Chart 的 customRules:
customRules:
runtime-lab.yaml: |-
- rule: Lab shell started in container
desc: Detect a shell process in the isolated runtime lab
condition: >
spawned_process and container and
k8s.ns.name = "runtime-lab" and
proc.name in (bash, sh, zsh)
output: >
Lab shell started
(user=%user.name proc=%proc.name command=%proc.cmdline
container=%container.id pod=%k8s.pod.name ns=%k8s.ns.name)
priority: NOTICE
tags: [process, container, runtime-lab]将这段覆盖值作为 runtime-lab-values.yaml 交给现有 release,并在变更前记下 Helm revision。升级日志必须出现 runtime-lab.yaml 已加载且没有规则解析错误,才能开始产生事件:
helm history falco -n falco
helm upgrade falco falcosecurity/falco \
--namespace falco --version 9.1.0 \
--reuse-values --values runtime-lab-values.yaml --wait
kubectl logs -n falco -l app.kubernetes.io/name=falco --tail=200 \
| grep -Ei 'runtime-lab.yaml|error|warning'spawned_process 通常由 macro 展开为进程创建相关事件;container 限定容器上下文;namespace 条件把实验故障半径收窄;proc.name 是可执行名,不等同于完整路径;output fields 决定调查人员收到哪些上下文。路径与参数字段可能受内核、事件模型和截断限制,任何单一字段都不应被视为完整取证记录。
字段能力应从目标二进制确认:falco --list=syscall 可以列出当前 syscall source 可用字段。规则评审要把“字段不存在”“字段存在但当前事件无值”和“值被截断”分开。直接开启 -A 采集全部事件会放大 CPU、buffer 与输出成本,不是修复规则不命中的默认动作。
用受控 shell 跑通正向实验
先创建隔离 namespace,加载教学规则,再用受控 Pod 启动一次 shell。官方 Event Generator 能生成更多样例事件,但部分 action 会修改 /bin、/etc、/dev 等路径,应限制为明确动作并放在一次性节点或隔离容器。Falco sample events给出了官方生成入口与安全提醒。
kubectl create namespace runtime-lab
kubectl run shell-check -n runtime-lab \
--image=alpine@sha256:<approved-digest> \
--restart=Never --command -- sh -c 'id; sleep 2'
kubectl logs -n falco -l app.kubernetes.io/name=falco --since=5m \
| grep 'Lab shell started in container'
kubectl delete pod shell-check -n runtime-lab --ignore-not-found预期日志包含规则名、NOTICE priority、namespace、Pod、container ID、进程名和命令字段。若 Pod 已完成但无事件,按顺序核对它落在哪个节点、该节点 Falco 探针是否有效、规则是否加载、condition 的 namespace 与事件类型是否匹配,以及日志时间窗是否覆盖动作。不要为了“让它命中”立刻删除所有限定条件,那会把调试变成告警洪峰。
实验结束要删除 Pod、namespace 中的临时对象和教学规则,并确认默认规则仍能加载。上述 Chart 路径应执行 helm rollback falco <pre-lab-revision> -n falco --wait,再逐个实例确认 runtime-lab.yaml 不再加载、批准的 Rules artifact 仍在且受控正例仍可命中;不能只删除测试 Pod 就宣称回滚完成。若使用 Operator 管理 Rulesfile,删除实验 Rulesfile 后等待目标资源状态收敛。清理结果应包含“实验规则不再存在”和“生产规则仍然有效”两项证据。
反向实验一:让驱动明确失败
在一次性节点池复制生产 values,移除必要 BPF capability,或使用阻止 BPF syscall 的测试安全策略。不要在承载业务的节点上卸载探针或更改内核安全配置。部署候选 release 后同时观察 Pod 状态与启动日志:
kubectl get pods -n falco -o wide
kubectl logs -n falco -l app.kubernetes.io/name=falco --tail=200 \
| grep -Ei 'BTF|ringbuf|verifier|permission|operation not permitted|driver'预期失败证据是驱动初始化、eBPF load/attach、BTF 或 capability 的明确错误。若 Pod 仍报告 Ready,说明 readiness 没有覆盖探针有效性,平台应增加基于启动状态、指标或受控事件的外部健康门禁。恢复 capability 或测试节点配置后,重新看到探针成功日志并再次运行 shell 正例,才算完成回滚。
反向实验二:证明 exception 没有吞掉真告警
规则调优应使用固定事件集比较旧 Rules 与候选 Rules。先保留一条应命中的稳定事件、一条应被豁免的已知自动化事件和一条字段缺失事件;分别运行旧规则和候选规则,比较新增命中、消失命中、exception 命中与字段变化。总告警数减少不是成功标准,差分必须能定位到 rule、condition、exception、字段和 Rules 版本。
namespace 级 exception 往往过宽,因为同一 namespace 可能同时运行部署器、应用和临时调试 Pod。更稳妥的豁免组合通常包含明确镜像 digest、ServiceAccount、进程祖先、可执行路径或受控标签,并验证租户不能自行伪造这些身份。候选规则一旦让稳定恶意 fixture 消失,升级就应停止;不能用“整体噪声降低”抵消无法解释的漏报。
Falcosidekick 把告警送出去但不保存世界
Falco 可输出 stdout、文件、syslog 与 HTTP(S) 等通道。启用 json_output: true 后,单行 JSON 通常包含 time、rule、priority、output、hostname、tags 与 output_fields,便于日志平台解析。输出通道文档应与目标 release 的配置一起核对。HTTPS 端点需要有效证书,网络策略、认证与凭证轮换也属于输出路径。
Falcosidekick 是稳定的生态组件,接收 Falco HTTP 告警,按优先级过滤、补充自定义字段、暴露 Prometheus 指标,并扇出到聊天、日志、对象存储、消息队列、SIEM 或 OpenTelemetry 等目的地。它不采集 syscall、不执行 Falco rules,也不是耐久消息队列。Chart 可以把它作为依赖启用:
helm upgrade --install falco falcosecurity/falco \
--namespace falco \
--version 9.1.0 \
--set driver.kind=modern_ebpf \
--set falcosidekick.enabled=true \
--set tty=true输出 token、webhook secret、SMTP 密码和云凭证应通过 Kubernetes Secret 或外部密钥系统注入,不能写进 values 仓库。多目标 fan-out 要逐个验证超时、重试、429/500、重复与顺序语义。需要抵抗长时间下游故障时,在 Falcosidekick 与分析平台之间增加团队能运维的耐久队列或持久日志,不要假定转发器内存会无限保存事件。
反向实验三:隔离下游故障
在测试环境把一个 webhook 指向可控的不可达端点,或让接收器短时返回 429/500,同时生成有限数量受控事件。观察 Falco 本地 JSON、Falcosidekick 错误与重试指标、队列或日志后端,以及目标恢复后的重复事件。实验要有数量上限和恢复时间,避免转发重试反过来压垮测试集群。
判定重点是故障隔离:下游失败时 Falco 采集与规则引擎仍运行,本地或耐久层保留可接受的证据;恢复后重复可按事件键处理;凭证与错误响应不会进入公开日志。若事件在内存耗尽后永久丢失,应缩短链路、降低事件率或增加持久层,并把实际交付语义写入运行手册。
dropped events 是正确性指标
syscall buffer 满会产生 dropped events。丢失的不只是某条告警候选事件,libsinsp 用于维护进程、文件和容器状态的事件也可能缺失,后续字段富化因此变得不完整。dropped event 不能被归类为普通性能噪声,它直接影响规则判断与调查可信度。Dropped Events 文档说明了检测与动作配置入口。
容量基线应在代表性节点记录事件率、CPU、内存、buffer drop、规则命中率、输出字节、转发队列和下游延迟。容器批量启动、编译节点 fork/exec 高峰、事件全开和宽规则都会抬高压力。优化顺序通常是确认是否采集无用事件、收窄事件类型与字段、修正规则条件、调整 buffer 与资源,再扩容输出链;单纯降低日志级别不会找回丢失的内核事件。
阈值应来自业务峰值与检测 SLO,而不是复制一个通用百分比。可验证的不变量是:在目标峰值下 dropped events 不持续增长,Falco 资源不挤压业务节点,告警延迟保持在响应预算内,事件洪峰时仍能区分采集丢失与下游积压。
敏感字段和凭证要分层治理
命令行、文件路径、容器标签、namespace、镜像、用户和网络字段可能暴露令牌、客户标识、内部地址或部署拓扑。output 模板应按用例最小化字段;聊天通知只发送事件 ID、规则、priority 和脱敏摘要,完整 output_fields 进入受控证据库。调试日志与安全事件使用不同索引和访问角色,防止运维诊断被误当告警,也防止普通告警查看者读取探针内部信息。
HTTP 输出与 Falcosidekick 凭证按目的地拆分,配置轮换、吊销和审计。接收器必须限制 body 大小、校验证书与身份,并避免把错误响应中的敏感内容回写 Falco 日志。规则仓库同样是安全资产:macro、list 和 exception 的变更需要评审、签名或受控发布,租户不能通过可修改标签轻易绕过全局检测。
Falco Talon 让告警进入高风险响应面
Falco Talon 接收 Falco 或 Falcosidekick 事件,读取 Kubernetes 上下文,并按规则执行 Kubernetes、云、通知或证据输出动作。项目将 Talon 标记为 Incubating;它不是 Falco 检测正确性的组成部分,也不应把一次 rule 命中直接转换为无条件删除、隔离或修改工作负载。
采用自动响应时,先从通知或证据保存动作开始,再引入 namespace 与标签白名单、最小 RBAC、速率限制、超时、熔断、幂等键和人工接管。删除 Pod 可能触发控制器立即重建,隔离网络可能切断取证出口,错误标签可能跨租户命中。每个动作都要有恢复命令、最大影响数量和“检测证据不足时不动作”的停止条件。
高可用分成节点采集和集中交付
syscall 模式下,每个节点 Falco 实例独立检测。节点覆盖率、tolerations、架构镜像、资源压力和 DaemonSet 更新策略决定观测空洞;在同一节点运行两个 Falco Pod 通常不会补回升级期间丢失的历史事件,反而会重复采集。关键健康指标是目标节点是否有已加载探针和规则的实例。
Falcosidekick、队列与 SIEM 属于集中交付层,可以通过多副本、负载均衡、持久化和去重提升可用性。传感器故障与交付故障要分开告警:前者意味着事件未被观察,后者意味着事件已经产生但尚未安全到达目的地。两个层级共用一个“安全平台正常”状态会掩盖真正的恢复动作。
升级把四个版本和输出 schema 绑在一起
Falco 升级至少绑定应用版本、Chart 版本、Falco Rules 版本和 driver/schema API。先在与生产内核一致的 canary 节点池部署候选组合,运行受控正例、驱动反例、规则差分和下游故障实验;比较事件字段、命中、资源、drop 与延迟。Chart breaking changes、appVersion、values 字段和 Rules 兼容要一起评审,不能只看到镜像能启动就滚动全集群。
DaemonSet 滚动期间,每个正在替换的节点都有检测空窗,应限制并发不可用节点并记录实际持续时间。规则更新既可以自动也可以受控发布;高风险环境通常先固定 Rules artifact,在 CI 中用历史事件与 fixture 做差分,再逐批加载。回滚应同时恢复 Chart values、Falco、Rules、输出模板和下游字段映射,否则旧二进制可能继续发送新 schema,或旧规则在新字段模型上求值。
卸载要清掉集群对象、节点状态与外部入口
传统 Chart 先停止规则和输出变更,再保存必要配置与证据,随后卸载 release 并检查残留:
helm uninstall falco -n falco
kubectl get all,configmap,secret,serviceaccount,role,rolebinding -n falco
kubectl get clusterrole,clusterrolebinding | grep -i falco || true
kubectl get pods -A -o wide | grep -i falco || true
kubectl delete namespace runtime-lab --ignore-not-foundkmod 模式还要在每类节点检查模块、DKMS 产物、driver loader 与 systemd 服务;删除 namespace 不能证明内核侧已恢复。Operator 路径应先删除 Rulesfile、Plugin 与 Config,再删除 Falco 与 Component,最后卸载 Operator,避免控制器先消失而 finalizer 残留;Helm 也不会自动替团队删除所有 CRD。
外部清理包括 Falcosidekick 目标、队列、SIEM parser、dashboard、告警规则、Secret、网络策略和云端凭证。日志索引按审计保留策略处理,不能为了“卸载干净”提前销毁事件,也不能让无人负责的索引无限计费。最终证据应表明目标节点没有探针、集群没有悬空权限、下游不再接受旧凭证,同时保留可审计的历史事件。
选型结论来自团队能维护的检测链
Falco 的价值不只是一组默认规则,而是把内核和插件事件、字段富化、规则、结构化输出与生态转发器组织成可治理链路。团队需要成熟规则生态、标准告警和多目的地转发时,它是很强的起点;需要跨事件源关联、长期取证、预防式准入或内核级执行约束时,还需要 SIEM、证据存储或其他执行工具协作。
落地决策最终要回答:目标节点能否稳定加载驱动,关键行为是否有足够字段,规则与 exception 是否有回归数据,dropped events 是否在容量预算内,下游故障是否隔离,敏感数据是否受控,升级空窗与回滚是否可接受。只有这些不变量持续成立,绿色 DaemonSet 和安静的告警面板才真正有意义。
