10.2 容器安全:Falco 运行时安全监控
预计阅读时间:15 分钟
📖 目录
Falco 是 CNCF 毕业项目,也是事实上的 Kubernetes 运行时安全标准。它通过内核 eBPF 探针或内核模块监控系统调用,检测容器环境中的异常行为。Falco 于 2018 年加入 CNCF 孵化项目,2020 年毕业,目前是 Kubernetes 运行时安全领域的事实标准。它由 Sysdig 团队开发,利用 Linux 内核的系统调用来实时检测安全威胁。
学习目标
- 理解 Falco 的工作原理(系统调用 → eBPF 探针 → 规则匹配 → 告警)
- 能够安装和配置 Falco,包括 Helm 部署和 Docker 单机部署两种方式
- 能够编写自定义 Falco 规则,检测特定的容器异常行为
- 掌握 Falco 告警输出配置,集成 Falcosidekick 转发到 Slack / PagerDuty 等平台
前置知识
- Linux 系统调用基本概念(syscall、文件描述符、进程创建)
- Docker 和 Kubernetes 基础(Pod、Container、Namespace)
- Linux 安全基础(capabilities、seccomp、AppArmor)
- Helm 包管理器基本使用(helm install、helm repo)
- 基础 YAML 语法(编写 Falco 规则和 K8s 配置)
核心原理
Falco 的监控链路:系统调用(syscall)→ eBPF 探针 → Falco 引擎 → 规则匹配 → 告警输出。
工作流程详解
- 系统调用采集:Falco 通过 eBPF 探针(推荐)或内核模块,hook Linux 内核的
sys_enter和sys_exit事件,捕获所有系统调用 - 事件解析:将原始系统调用数据解析为结构化事件,包括进程信息、文件路径、网络连接、容器元数据等
- 规则匹配:使用 Falco 规则语言对事件流进行模式匹配,检测异常行为
- 告警输出:匹配成功时触发告警,支持标准输出、Syslog、HTTP、gRPC 等多种输出方式
相比传统安全方案的差异:
- 不是扫描镜像(那是 Trivy 的工作)
- 不是固定防火墙规则(那是 NetworkPolicy 的工作)
- 而是监控运行时行为——发现"运行时不该出现的行为"
- 不是事后分析(那是 auditd 的工作),而是实时检测
eBPF vs 内核模块
| 特性 | eBPF 探针(推荐) | 内核模块 |
|---|---|---|
| 内核版本要求 | Linux 4.18+ | 任意(支持 DKMS) |
| 安全性 | 沙箱执行,更安全 | 内核级代码,风险较高 |
| 性能 | 接近原生性能 | 略高开销 |
| 兼容性 | 容器化友好 | 需要编译内核模块 |
| 推荐场景 | 生产环境、K8s 集群 | 老旧内核、调试用途 |
1. 安装 Falco
# 方式一:Helm 安装(K8s)
helm repo add falcosecurity https://falcosecurity.github.io/charts
helm repo update
helm install falco falcosecurity/falco \
--namespace falco --create-namespace \
--set tty=true \
--set falco.driver.kind=ebpf
# 方式二:Docker 部署(单机)
docker run -d --name falco \
--privileged \
-v /var/run/docker.sock:/var/run/docker.sock \
-v /proc:/host/proc:ro \
-v /boot:/host/boot:ro \
-v /lib/modules:/host/lib/modules:ro \
-v /usr:/host/usr:ro \
-v /etc:/host/etc:ro \
falcosecurity/falco:latest \
falco --driver=ebpf
# 方式三:直接安装(Ubuntu/Debian)
# 添加 Falco GPG key 和仓库
curl -fsSL https://falco.org/repo/falcosecurity-packages.asc | sudo gpg --dearmor -o /usr/share/keyrings/falco-archive-keyring.gpg
echo "deb [signed-by=/usr/share/keyrings/falco-archive-keyring.gpg] https://download.falco.org/packages/stable/x86_64/ /" | sudo tee /etc/apt/sources.list.d/falco.list
sudo apt-get update && sudo apt-get install -y falco
# 启动 Falco 服务
sudo systemctl enable falco
sudo systemctl start falco
Helm 安装配置详解
# 完整的 Helm values.yaml 示例
falco:
driver:
kind: ebpf # 使用 eBPF 探针(推荐)
ebpf:
leastPrivileged: false # true 则不加载所有 syscall
rules:
- /etc/falco/falco_rules.yaml
- /etc/falco/rules.d/custom.yaml # 自定义规则路径
# 资源限制
resources:
requests:
cpu: 100m
memory: 256Mi
limits:
cpu: 500m
memory: 512Mi
# 告警输出
falco:
jsonOutput: true # JSON 格式输出
httpOutput:
enabled: false
url: ""
syslogOutput:
enabled: false
fileOutput:
enabled: true
keepAlive: true
filename: /var/log/falco/falco-events.log
2. 默认规则(已内置)
Falco 安装后自带 100+ 规则,以下是最关键的一些:
| 规则名 | 检测行为 | 严重性 |
|---|---|---|
| Terminal shell in container | 容器内启动 shell(攻击者后期利用) | Notice |
| Read sensitive file | 读取 /etc/shadow、~/.kube/config 等敏感文件 | Warning |
| Write below binary dir | 向 /usr/bin 等目录写入可执行文件 | Notice |
| Launch Privileged Container | 创建特权容器(--privileged) | Notice |
| Unexpected K8s nodeport | 创建 NodePort 类型 Service | Notice |
| Change thread namespace | nsenter 进入其他容器命名空间 | Critical |
| Outbound connection to known malicious IP | 连接已知恶意 IP | Critical |
规则严重性分级
| 级别 | 含义 | 建议响应 |
|---|---|---|
| Emergency | 系统已遭受攻击 | 立即隔离受影响 Pod,启动应急响应 |
| Critical | 高概率安全事件 | 立即排查,可能需要中断服务 |
| Error | 疑似攻击行为 | 快速确认,准备隔离措施 |
| Warning | 可疑行为 | 记录并分析,判断是否为正常操作 |
| Notice | 值得注意的行为 | 记录日志,定期审查 |
| Informational | 正常但值得记录 | 仅记录 |
3. 自定义规则
# 自定义规则文件 /etc/falco/rules.d/custom.yaml
- rule: Detect curl in container
desc: curl 在容器内被使用(可能是数据外泄)
condition: >
spawned_process and
container and
proc.name = curl
output: >
Curl used in container
(user=%user.name container=%container.id image=%container.image
cmdline=%proc.cmdline)
priority: WARNING
tags: [network, data_exfiltration]
- rule: Block host network access
desc: 容器使用主机网络(hostNetwork)
condition: >
container and
k8s.pod and
not jevt.value[/spec/hostNetwork] is null
output: >
Pod uses hostNetwork (pod=%k8s.pod.name ns=%k8s.ns.name)
priority: WARNING
tags: [network, privilege]
规则语法详解
# Falco 规则由三部分组成:condition(条件)、output(输出)、priority(优先级)
# condition 中常用的宏(macros)
- macro: container
condition: (container.id != host)
- macro: spawned_process
condition: >
evt.type in (clone, clone3, fork, vfork, execve, execveat) and
evt.dir = <
# condition 中常用的字段
# proc.name - 进程名
# proc.cmdline - 完整命令行
# proc.pid - 进程 ID
# container.id - 容器 ID
# container.image - 镜像名
# fd.name - 文件描述符指向的路径
# fd.rip - 远程 IP 地址
# fd.rport - 远程端口
# k8s.pod.name - K8s Pod 名称
# k8s.ns.name - K8s Namespace
# output 中可用的占位符
# %user.name - 触发事件的用户名
# %proc.name - 进程名
# %proc.cmdline - 完整命令行
# %container.id - 容器 ID
# %container.image - 镜像名
# %fd.name - 文件路径或网络连接
# 使用条件组合
- rule: Sensitive file read by non-root
desc: 非 root 用户读取敏感文件
condition: >
open_read and
container and
proc.name != root and
(fd.name startswith /etc/shadow or
fd.name startswith /etc/passwd or
fd.name contains .kube/config)
output: >
Sensitive file read (user=%user.name file=%fd.name
container=%container.id image=%container.image)
priority: WARNING
4. 告警输出配置
# Falco 支持多种告警方式
# 标准输出(默认)
# 直接写入标准输出
# Syslog
falco:
syslog:
enabled: true
# 写入文件
falco:
file_output:
enabled: true
keep_alive: true
filename: /var/log/falco-events.log
# HTTP 端点(集成到告警系统)
falco:
http_output:
enabled: true
url: http://alertmanager:9093/api/v1/alerts
# gRPC 加密输出(Falcosidekick 推荐)
# Falcosidekick 可以转发到 Slack、PagerDuty、S3、Elasticsearch 等
5. 集成 Falcosidekick
# Falcosidekick 将 Falco 告警转发到 40+ 目标
helm install falcosidekick falcosecurity/falcosidekick \
--namespace falco \
--set config.slack.webhookurl=https://hooks.slack.com/services/xxx \
--set config.slack.minimumpriority=warning
# Falcosidekick 支持的输出目标
# - Slack / Microsoft Teams / Discord
# - PagerDuty / OpsGenie
# - Elasticsearch / Loki / Splunk
# - AWS S3 / SQS / Lambda
# - Kafka / NATS / Redis
# - Webhook(自定义 HTTP 端点)
Falcosidekick Web UI
# 安装 Falcosidekick Web UI(可视化告警仪表盘)
helm install falcosidekick-ui falcosecurity/falcosidekick-ui \
--namespace falco \
--set redis.storageClass=standard
# 访问 UI
kubectl port-forward -n falco svc/falcosidekick-ui 2802:2802
# 浏览器访问 http://localhost:2802
6. 实际排错案例
# 查看 Falco 日志
kubectl -n falco logs -l app.kubernetes.io/name=falco --tail=50
# 常见告警分析
# 1. "Notice: A shell was spawned in a container"
# → 检查谁在容器内 exec,是否正常运维操作
# 2. "Warning: Read sensitive file"
# → 检查容器内是否有程序读取 /etc/shadow
# 3. "Critical: Outbound connection to known malicious IP"
# → 立即排查该 Pod!可能是挖矿或 C2 通信
# 临时禁用规则(不要在生产直接禁用,先切换告警)
falco:
rules_file:
- /etc/falco/falco_rules.yaml
# - /etc/falco/rules.d/custom.yaml # 注释掉以禁用自定义规则
7. eBPF 工作原理深入
Falco 的"眼睛"是 eBPF,搞清楚 eBPF 的机制才能理解为什么它快、以及为什么它依赖内核版本:
- 探针挂载:Falco 的 eBPF 程序挂在内核 tracepoint 上(
sys_enter/sys_exit),进程发起系统调用时同步触发 - 验证器检查:程序加载时内核验证器(verifier)逐条检查字节码——确保不越界、不无限循环、终止可控,这是 eBPF 安全性的根本保证
- 事件传输:内核态程序把事件写入 ring buffer(perf_event / BPF ringbuf),用户态 Falco 引擎异步读取,不阻塞业务进程
- 零拷贝优势:数据只在内核态加工、按需输出,相比 auditd 的逐条用户态转发开销低一个数量级
# 查看 Falco 实际加载的 eBPF 程序
sudo bpftool prog list | grep -i falco
# 查看 BPF map(事件缓冲、状态表)
sudo bpftool map list | grep -i falco
# 检查内核是否满足要求(eBPF 依赖的内核配置)
grep -E "CONFIG_BPF|CONFIG_BPF_EVENTS|CONFIG_TRACEPOINTS" /boot/config-$(uname -r)
# 常见报错与内核的对应关系
# "failed to open bpf file" → 内核过老(< 4.18)或 CONFIG_BPF_EVENTS 未开启
# "ring buffer map: ... operation not permitted" → 容器缺少 CAP_BPF/SYS_ADMIN
为什么 eBPF 比内核模块安全 内核模块是自由代码,一旦有 bug 直接崩内核(panic);eBPF 程序受验证器约束 + 沙箱执行,加载失败也只是返回错误。生产环境首选 eBPF 探针不是性能问题,而是可靠性问题。
8. 规则语言详解
Falco 规则由五部分组成,掌握它们的组合方式就能写出精确的检测逻辑:
| 元素 | 作用 | 示例 |
|---|---|---|
| rule | 定义一条检测规则 | - rule: Detect shell |
| macro | 可复用的条件片段(常量宏) | - macro: container |
| list | 字符串集合(进程名/路径清单) | - list: sensitive_files |
| condition | 事件匹配表达式(核心) | evt.type=execve and proc.name in (bash) |
| output | 告警内容模板(支持占位符) | %proc.cmdline |
# 操作符速查
# 比较:=、!=、<、>、<=、>=
# 集合:in (a, b, c)、not in、intersects
# 逻辑:and、or、not
# 字符串:startswith、endswith、contains、glob、regex
# 存在性:exists、is null、is not null
# 字段速查(按事件类型动态可用)
# 文件事件:evt.type=open/openat/creat/unlink, fd.name
# 进程事件:evt.type=execve/clone/fork, proc.name, proc.cmdline, proc.pname
# 网络事件:evt.type=connect/accept, fd.rip, fd.rport, fd.lip, fd.lport
# 容器/K8s:container.id, container.image, k8s.pod.name, k8s.ns.name
# 条件组合技巧:括号改变优先级(and 高于 or)
condition: >
(evt.type in (open, openat) and
fd.name in (sensitive_files)) or
(evt.type = execve and proc.name = nc)
列表与宏的覆盖式扩展
# 覆盖(override)Falco 内置列表——追加自己关心的敏感文件
- list: sensitive_files
append: true
items: [/data/secrets/db_pwd, /app/config/private.key]
# 覆盖宏:在原有基础上收紧/放宽
- macro: user_known_shell_activities
append: true
condition: or proc.name in (kubectl, helm, istioctl)
# 覆盖规则:降低误报(把内置规则优先级调低)
- rule: Terminal shell in container
append: true
priority: INFO
# 完全禁用某条内置规则
- rule: Terminal shell in container
enabled: false
9. 规则定制案例实战
案例一:检测挖矿行为
- list: mining_pools
items: [pool.supportxmr.com, xmr-eu1.nanopool.org, mine.aeon-pool.com]
- rule: Detect Crypto Mining
desc: 容器连接已知挖矿矿池
condition: >
container and
evt.type in (connect, sendto) and
(fd.rip in (mining_pools) or
fd.rport = 3333 or fd.rport = 4444 or fd.rport = 5555)
output: >
Crypto mining detected (container=%container.name image=%container.image
remote=%fd.rip:%fd.rport cmd=%proc.cmdline)
priority: CRITICAL
tags: [crypto, network]
案例二:检测反弹 Shell
# 反弹 shell 的典型特征:容器内进程与外部 IP 建立双向交互 shell
- rule: Reverse Shell
desc: 检测容器内出现可疑的 bash/sh 与外部地址交互
condition: >
container and
evt.type = execve and
proc.name in (bash, sh, zsh, python, python3, perl, nc) and
(proc.cmdline contains "-i" or
proc.cmdline contains "connect-back" or
(proc.cmdline contains "/dev/tcp/" and proc.cmdline contains "0<&1"))
output: >
Possible reverse shell (user=%user.name cmd=%proc.cmdline
container=%container.id image=%container.image)
priority: CRITICAL
tags: [network, process]
案例三:误报治理——白名单宏
# 运维巡检脚本会触发大量 Terminal shell 告警,先确认后豁免
- macro: user_known_shell_activities
append: true
condition: or (proc.name = bash and proc.pname = sshd)
# 健康检查探针频繁读取 /etc/passwd,加入白名单
- macro: user_known_read_sensitive_file_activities
append: true
condition: or (proc.pname in (kubelet, containerd) and fd.name = /etc/passwd)
# 验证规则语法
falco --validate /etc/falco/rules.d/custom.yaml
# 或加载后直接测一条
falco -r /etc/falco/rules.d/custom.yaml -e /dev/null
10. 告警集成与响应闭环
告警的价值在于被响应。Falcosidekick 是社区标准的转发中枢,按严重性路由到不同通道是基本盘:
# 完整 values.yaml:分级路由 + 事件过滤
config:
slack:
webhookurl: "https://hooks.slack.com/services/xxx"
minimumpriority: "warning" # 只转发 warning 及以上
pagerduty:
apikey: "xxx"
minimumpriority: "critical" # critical 直达 PagerDuty 值班
webhook:
address: "http://alertmanager.monitoring:9093/api/v1/alerts"
minimumpriority: "error" # error 以上进 AlertManager
# 字段级过滤(降低噪声)
customfields:
cluster: "prod-a"
team: "platform"
# 用 Helm 部署
helm install falcosidekick falcosecurity/falcosidekick \
--namespace falco \
-f falcosidekick-values.yaml
# 验证链路:手动触发一条测试事件
kubectl -n falco exec deploy/falco -- falco -e "evt.type=execve" --test
告警去重与降噪
- Falco 支持
--disable-cri-async、base_events等性能开关减少重复事件 - Falcosidekick 内置 dedup 窗口(同一规则 + 同一容器 1 分钟内只发一条)
- 规则输出里带上
k8s.ns.name、k8s.pod.name便于机器人自动打标签分组 - 每周回顾告警量 Top 10,为稳定误报写白名单宏(参考第 9 节案例三)
11. 性能与容量规划
Falco 常驻在每个节点上,对宿主机的开销直接决定它能覆盖多少集群。核心指标与规划方法:
| 指标 | 含义 | 健康阈值 |
|---|---|---|
| events/s(每秒事件数) | 节点整体 syscall 事件量 | 数万级正常,超过 50 万/s 需关注 |
| falco_drops_total | 因缓冲区满被丢弃的事件 | 持续增长即告警(漏检风险) |
| falco_evts_queue_perc | 事件队列占用百分比 | < 50% 健康,> 80% 丢事件风险 |
| CPU / 内存 | Falco 进程本身 | 约 0.5-1 核 + 200-500MB(视规则量) |
# 通过 Prometheus 指标观察 Falco 健康(Helm 部署时已暴露)
kubectl -n falco port-forward svc/falco 9376:9376
# 本地查询
curl -s localhost:9376/metrics | grep -E "falco_(drops|evts_queue|events_total)" | head -10
# 关键调优手段
# 1. 关闭不需要的字段解析(减少 CPU):--fields 只留必要字段
# 2. 精简规则:条件里少用 fd.name contains 这类全量字符串匹配
# 3. 按需选择探针:仅 K8s 场景可禁用部分不需要的事件类型
# 4. 调整缓冲区:--bpf-probe-buffer-size 默认 8MB,高吞吐节点可调大
# 告警规则(Prometheus):丢事件即告警
rules:
- alert: FalcoEventDrops
expr: increase(falco_drops_total[5m]) > 0
labels:
severity: warning
annotations:
summary: "Falco 开始丢弃事件,检测覆盖出现缺口"
容量规划经验 单节点事件吞吐与业务负载强相关:IO 密集(数据库、日志采集)节点的事件量是 Web 节点的数倍。上线前在每类节点各做一次 24h 基线采集,按最高值 ×1.5 规划资源,比统一配置更可靠。
常见错误
| 错误现象 | 可能原因 | 解决方案 |
|---|---|---|
error opening device /dev/falco | eBPF 探针未加载或内核版本不支持 | 检查内核版本 ≥ 4.18;尝试切换为内核模块模式 --driver=kernel |
| Falco Pod CrashLoopBackOff | 权限不足或挂载路径错误 | 确保 Pod 以 --privileged 运行,检查 /proc、/sys 等挂载路径 |
规则语法错误(Error loading rules) | YAML 缩进错误或条件语法不正确 | 使用 falco --validate /etc/falco/rules.d/custom.yaml 验证规则语法 |
| 告警过多(告警风暴) | 规则过于宽泛,缺少白名单 | 为已知正常行为添加白名单宏(and not proc.name in (known_binaries)) |
| 性能开销过高 | 系统调用频率过高或规则过于复杂 | 精简规则中的 evt.type 过滤范围;减少不必要的字段提取 |
最佳实践
- 先以 WARNING 级别运行 1-2 周,观察有哪些误报
- 为每个应用定制白名单规则(app-whitelist.yaml)
- CRITICAL 告警直接推送 PagerDuty/钉钉,WARNING 汇总日报
- 结合 K8s Audit Log 做更上层的事件关联
- 每季度审查和调整规则集
- 使用 Falcosidekick Web UI 进行告警可视化和趋势分析
- 在生产环境中同时使用 eBPF 探针和 K8s Audit Log 进行交叉验证
- 为 Falco 配置资源限制,避免在高负载时影响业务
- 定期备份自定义规则文件,纳入 Git 版本管理
练习题
- 规则编写练习:编写一条 Falco 规则,检测容器内使用
wget或curl下载文件的行为。规则需要输出容器名、镜像名、用户和完整命令行。测试规则是否能正确触发告警。 - 告警集成练习:部署 Falcosidekick,将 Falco 的 CRITICAL 级别告警转发到 Slack 频道,WARNING 级别写入本地日志文件。验证告警是否正确路由。
- 误报处理练习:在一个测试集群中运行 Falco 1 周,收集所有告警,找出 Top 5 误报来源,并编写对应的白名单规则来抑制这些误报,同时确保真正的安全威胁仍然能被检测到。
学习检查点
学完本章后,请检验自己是否掌握以下内容:
| 检查项 | 自测问题 | 验证方法 |
|---|---|---|
| 概念理解 | 能用自己的话解释 Falco 的规则引擎和系统调用监控原理 | 尝试向他人讲解 |
| 命令操作 | 能不查文档完成 Falco 安装、规则编写和告警配置 | 在终端实际执行 |
| 原理掌握 | 能说出 Falco 的内核模块/eBPF 探针和事件检测原理 | 画出流程图 |
| 故障排查 | 能独立排查 Falco 规则误报或性能影响过大的问题 | 模拟故障并修复 |
| 最佳实践 | 能说明为什么需要为容器运行时配置运行时安全监控 | 对比不同方案 |
本章总结
Falco 通过 eBPF 在内核层面监控容器行为,是构建时安全(镜像扫描、配置审计)的必要补充,能捕捉到部署前发现不了的运行时异常。默认规则只是起点,必须结合自身业务场景定制白名单宏、调整触发条件,并定期审查规则集。切记:告警不是终点——只有将告警接入 PagerDuty、钉钉等响应流程,形成处置闭环,Falco 才有实际价值,否则未经响应的告警只会沦为噪声。
延伸阅读
- 5.12:eBPF 基础 eBPF 基础——现代 Linux 可观测性
- 6.1:容器底层原理 容器底层原理——Linux namespace 与 cgroups
- 5.13:auditd 审计 auditd 审计系统
- Falco 官方文档:https://falco.org/docs/
- Falco 规则示例库:https://github.com/falcosecurity/rules