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 引擎 → 规则匹配 → 告警输出。

工作流程详解

  1. 系统调用采集:Falco 通过 eBPF 探针(推荐)或内核模块,hook Linux 内核的 sys_entersys_exit 事件,捕获所有系统调用
  2. 事件解析:将原始系统调用数据解析为结构化事件,包括进程信息、文件路径、网络连接、容器元数据等
  3. 规则匹配:使用 Falco 规则语言对事件流进行模式匹配,检测异常行为
  4. 告警输出:匹配成功时触发告警,支持标准输出、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 类型 ServiceNotice
Change thread namespacensenter 进入其他容器命名空间Critical
Outbound connection to known malicious IP连接已知恶意 IPCritical

规则严重性分级

级别含义建议响应
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 的机制才能理解为什么它快、以及为什么它依赖内核版本:

  1. 探针挂载:Falco 的 eBPF 程序挂在内核 tracepoint 上(sys_enter/sys_exit),进程发起系统调用时同步触发
  2. 验证器检查:程序加载时内核验证器(verifier)逐条检查字节码——确保不越界、不无限循环、终止可控,这是 eBPF 安全性的根本保证
  3. 事件传输:内核态程序把事件写入 ring buffer(perf_event / BPF ringbuf),用户态 Falco 引擎异步读取,不阻塞业务进程
  4. 零拷贝优势:数据只在内核态加工、按需输出,相比 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-asyncbase_events 等性能开关减少重复事件
  • Falcosidekick 内置 dedup 窗口(同一规则 + 同一容器 1 分钟内只发一条)
  • 规则输出里带上 k8s.ns.namek8s.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/falcoeBPF 探针未加载或内核版本不支持检查内核版本 ≥ 4.18;尝试切换为内核模块模式 --driver=kernel
Falco Pod CrashLoopBackOff权限不足或挂载路径错误确保 Pod 以 --privileged 运行,检查 /proc、/sys 等挂载路径
规则语法错误(Error loading rulesYAML 缩进错误或条件语法不正确使用 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 版本管理

练习题

  1. 规则编写练习:编写一条 Falco 规则,检测容器内使用 wgetcurl 下载文件的行为。规则需要输出容器名、镜像名、用户和完整命令行。测试规则是否能正确触发告警。
  2. 告警集成练习:部署 Falcosidekick,将 Falco 的 CRITICAL 级别告警转发到 Slack 频道,WARNING 级别写入本地日志文件。验证告警是否正确路由。
  3. 误报处理练习:在一个测试集群中运行 Falco 1 周,收集所有告警,找出 Top 5 误报来源,并编写对应的白名单规则来抑制这些误报,同时确保真正的安全威胁仍然能被检测到。

学习检查点

学完本章后,请检验自己是否掌握以下内容:

检查项自测问题验证方法
概念理解能用自己的话解释 Falco 的规则引擎和系统调用监控原理尝试向他人讲解
命令操作能不查文档完成 Falco 安装、规则编写和告警配置在终端实际执行
原理掌握能说出 Falco 的内核模块/eBPF 探针和事件检测原理画出流程图
故障排查能独立排查 Falco 规则误报或性能影响过大的问题模拟故障并修复
最佳实践能说明为什么需要为容器运行时配置运行时安全监控对比不同方案

本章总结

Falco 通过 eBPF 在内核层面监控容器行为,是构建时安全(镜像扫描、配置审计)的必要补充,能捕捉到部署前发现不了的运行时异常。默认规则只是起点,必须结合自身业务场景定制白名单宏、调整触发条件,并定期审查规则集。切记:告警不是终点——只有将告警接入 PagerDuty、钉钉等响应流程,形成处置闭环,Falco 才有实际价值,否则未经响应的告警只会沦为噪声。

延伸阅读

↑ 回到顶部