
用 sysdig Falco 把容器逃逸行为摁在萌芽里我这套规则已经拦下 3 次真实攻击说实话我一直觉得容器安全这事大多数人只做了半套。镜像扫描、CVE 修复、镜像签名这些当然要做。但它们都是事前检查——攻击者一旦进了容器运行时里发生什么你根本看不见。去年我们线上就吃过这个亏一个被攻破的 Pod 先是读了 /proc/self/status接着在容器里挂载了宿主机的 /最后把 cron 写进了宿主机。整个链路只用了 7 分钟。从那以后我把运行时审计补上了。核心就是 Falco sysdig 这套组合目前已经实打实拦下 3 次容器逃逸企图。为什么选 Falco sysdig而不是 EDR 或 AgentFalco 是 CNCF 项目直接挂在宿主机内核里通过 tracepoint 抓系统调用对容器无侵入。sysdig 则更像是命令行版的 Falco适合临时抓现场、验证规则。两者的关系我习惯这样理解Falco7x24 小时值守的规则引擎sysdig突发事件时的取证显微镜市面上很多 EDR 也能做类似事情但它们通常要装重型 Agent、依赖厂商规则库、价格按节点算。对我们这种 K8s 集群几百个节点、业务形态杂的团队来说Falco 的规则开源可审计、部署轻量是更务实的起点。我的 Falco 部署方式DaemonSet 本地规则直接在 K8s 上以 DaemonSet 跑 Falco 是最省事的方案。官方 Helm chart 已经封装得差不多了但我改了两个地方禁用默认规则里的噪音项比如频繁的 shell 启动告警把自定义规则用 ConfigMap 挂进去方便版本化# falco-daemonset.yaml节选apiVersion:apps/v1kind:DaemonSetmetadata:name:falcospec:selector:matchLabels:app:falcotemplate:spec:containers:-name:falcoimage:falcosecurity/falco:0.39.0securityContext:privileged:truevolumeMounts:-mountPath:/etc/falco/rules.dname:falco-rulesvolumes:-name:falco-rulesconfigMap:name:falco-custom-rules# custom-rules.yaml-rule:Container_Escape_Mount_Host_Rootdesc:Detect mounting of host root filesystem inside containercondition:spawned_process and container and (proc.name in (mount, umount) or proc.cmdline contains /host ) and (proc.cmdline contains /proc/1/root or proc.cmdline contains /host)output:Possible container escape via host mount user%user.name command%proc.cmdline container%container.name pod%k8s.pod.name ns%k8s.ns.namepriority:CRITICAL这条规则盯的是最常见的逃逸路径之一在容器里挂载宿主机根目录。只要进程命令行出现/host或/proc/1/root立刻触发 CRITICAL。三条被拦下的真实攻击链第一次挖矿程序尝试挂载宿主机凌晨 2 点一个存在 RCE 漏洞的旧版 Java 应用 Pod 被攻入。攻击者先是curl下载了一个二进制文件随后执行mount/dev/sda1 /hostchroot/host /bin/bashFalco 在第一条 mount 命令出来的瞬间就告警了。我们收到 Prometheus Alertmanager 通知后直接对该节点做了隔离cordon drain然后拉镜像做复盘。第二次特权容器读取宿主机 /etc/shadow开发同学在测试环境启了一个privileged: true的调试容器本来只想临时用一下结果脚本里顺手跑了cat/proc/1/root/etc/shadow这个行为触发了我们的读取宿主机敏感文件规则。虽然这次不是外部攻击但正好暴露了一个坏实践测试环境滥用特权容器。后来我们加了 OPA Gatekeeper 策略直接禁止非白名单命名空间跑 privileged Pod。第三次利用 CAP_SYS_ADMIN 进行 mount 命名空间逃逸有个服务为了做日志采集申请了CAP_SYS_ADMIN。攻击者拿到 shell 后用它执行了unshare -m创建新的 mount 命名空间再尝试把宿主机 cgroup 挂进来。这种攻击比前两次隐蔽因为不是直接 mount 宿主机根目录。我们针对unshare系统调用加了一条规则-rule:Unshare_In_Containerdesc:unshare syscall inside container (possible namespace escape)condition:spawned_process and container and proc.name unshare and not proc.pname in (containerd-shim, runc)output:unshare called in container user%user.name command%proc.cmdline container%container.name pod%k8s.pod.namepriority:WARNING警报出来后我们确认是异常流量触发的立刻把该 Pod 驱逐并重建了密钥。用 sysdig 做现场取证Falco 告警告诉你发生了什么sysdig 帮你回答怎么发生的。举个例子收到一条 mount 告警后我通常会立刻到对应节点执行# 抓取该容器最近 60 秒的系统调用sysdig-pc-M60-S\container.namepod-name\and(evt.typeexecve orevt.typeopenat orevt.typemount)\-w/tmp/incident.scap# 回放分析sysdig-r/tmp/incident.scap-pc-p%evt.time %proc.name %proc.cmdline %fd.name-pc参数会自动把容器名、Pod 名、命名空间打印出来看日志的时候非常清楚。告警接入与响应自动化Falco 的输出我接了两条路stdout / sidecar exporter把 Falco 日志转成 Prometheus 指标按规则名做计数Falcosidekick把事件推到 Slack 调用 Webhook 做自动响应我们的 Webhook 会做这几件事给节点打污点阻止新 Pod 调度对可疑 Pod 做kubectl delete --force --grace-period0把 sysdig 抓包任务作为 Job 派发到同节点自动化响应要慎用尤其是删除 Pod。我们只在 CRITICAL 级别、且规则明确无误的情况下才自动执行避免误伤正常业务。写在最后容器安全不是一个扫描器能解决的。镜像安全负责别让坏人进门运行时安全负责坏人进来后你能看见。Falco sysdig 这套方案成本不高但对运维视野的提升非常明显。它让我们从出事了看日志猜变成行为一异常就立刻知道。如果你也在跑 K8s建议先从三条规则开始容器内 mount 宿主机根目录容器内读取 /proc/1/root/etc 下敏感文件容器内调用 unshare / nsenter 等命名空间操作规则不用多先把最常见的逃逸路径盯住。等这套跑顺了再逐步加业务相关的自定义规则。代码和规则我都放在内部 GitLab 的security/falco-rules仓库里了有需要可以翻出来直接抄。