Tracee eBPF 运行时检测
一个集群换了新的节点镜像后,Tracee DaemonSet 仍然全部 Ready,常规 execve 事件也能看到,hidden_kernel_module 和 hooked_syscall 等检测却突然消失。探针并没有整体宕机:新镜像限制了 /proc/kallsyms,依赖内核符号的安全事件失去输入,而基础 syscall 仍可采集。团队只按 Pod 存活做健康检查,把“部分能力退化”误判成完整可用。
另一个团队为了提高可见性,把 Policy scope 设为 global,并同时开启环境变量、文件 hash 和宽泛事件。编译节点的进程洪峰很快塞满日志出口,kubectl logs 几乎无法检索,CI token 还随着 exec environment 进入普通告警索引。事件更多没有带来更可靠的检测,反而让敏感数据、CPU、IO、延迟和丢失风险一起扩大。
Tracee 先采集事实事件再派生安全语义
Tracee 是 Aqua Security 的开源 Linux eBPF 运行时观测、检测与取证工具。它采集 syscall、进程、文件、网络和内核事件,再把部分底层事件组合或解释成 security event,并为输出补充进程树、容器、Kubernetes、参数与 threat 上下文。Tracee 项目文档是能力和配置入口,稳定部署则应同时锁定 release 与 Chart 源。
三层对象不能混写。event 是 execve、文件打开、网络动作等事实;security event 是由检测逻辑派生出的可疑行为,例如 fileless execution;旧资料常说的 signature 是实现这些检测语义的一类逻辑,在 v0.24.1 输出中通常表现为 security/detection event 与 threat 字段。不能把每个 syscall 都叫 signature,也不能沿用早期独立 tracee-rules 进程的架构图描述当前稳定版。
Policy 决定“在哪些 workload 上追踪哪些 event”。scope 选择工作负载,rules 选择事件,filters 再约束 context 或 data。它不是 OPA/Rego 风格的通用业务授权语言,也不会默认阻止系统调用;准入、业务授权和网络隔离仍应由各自控制面承担。
节点能力矩阵决定能看见什么
Tracee 只运行在 Linux,支持 x86_64 和 arm64。BTF、kernel symbols、cgroup、runtime socket、网络 capability 与可选 BPF LSM 分别影响不同能力。缺少某一项时,Tracee 可能继续产生基础事件,因此“进程在运行”与“目标检测可用”必须拆开验证。安装前提文档应按目标 release 复核。
安装前在每类节点执行:
uname -a
test -r /sys/kernel/btf/vmlinux && echo BTF_OK || echo BTF_MISSING
test -r /proc/kallsyms && echo KALLSYMS_OK || echo KALLSYMS_MISSING
test -r /etc/os-release && echo OS_RELEASE_OK || echo OS_RELEASE_MISSING
cat /proc/sys/kernel/perf_event_paranoid
grep -E 'CONFIG_(BPF|BPF_SYSCALL|DEBUG_INFO_BTF|BPF_LSM)=' \
/boot/config-"$(uname -r)" 2>/dev/null || trueBTF 支持 CO-RE 程序适配目标内核。/proc/kallsyms 影响 dirty_pipe_splice、hooked_syscall、hidden_kernel_module、hooked_proc_fops、hooked_seq_ops 等事件;它不可读时,基础追踪可能仍存在。/etc/os-release 与内核配置路径用于环境探测。BPF LSM 是部分高级能力的可选依赖,缺失不能笼统写成 Tracee 完全不可用,也不能继续宣称高级事件完整。
权限按功能组合。现代内核且 perf_event_paranoid <= 2 时,常见入口包括 CAP_BPF、CAP_PERFMON 和 CAP_SYS_RESOURCE;进程信息可能需要 CAP_SYS_PTRACE,网络包能力需要 CAP_NET_ADMIN,内核符号可能需要 CAP_SYSLOG。不支持细分 capability 的内核、cgroup v1 或安全策略可能仍要求 CAP_SYS_ADMIN。最简 privileged 入口适合隔离验证,生产最小权限必须按启用能力逐项削减并做反向实验。
先用 Docker 看清宿主观测边界
在 Linux 测试主机上,Docker 是理解 host PID、cgroup 和 runtime enrichment 的最快入口。下面固定镜像 aquasec/tracee:0.24.1,对应稳定 release v0.24.1;Docker 安装文档可用于核对挂载和参数。
docker run --name tracee -it --rm \
--pid=host \
--cgroupns=host \
--privileged \
-v /etc/os-release:/etc/os-release-host:ro \
-v /var/run:/var/run:ro \
aquasec/tracee:0.24.1--pid=host 让容器看到宿主进程,--cgroupns=host 用于关联 cgroup,/var/run 可提供容器 runtime enrichment。这个挂载也可能暴露高价值 socket,即使只读 socket 仍可被连接;生产环境应只挂载实际 runtime 所需路径,并限制 Tracee 容器中的客户端能力。macOS 或 Windows 上的 Docker Desktop 观察的是 Linux VM,不是宿主系统行为,不能用来证明生产 Linux 节点兼容。
快速实验退出时 --rm 会删除容器,却不会替团队删除已导出的日志、webhook 凭证或下游索引。Docker 路径适合验证事件模型和输出,不是 Kubernetes 节点覆盖、高可用或最小 RBAC 的替代品。
Kubernetes 安装要固定 Chart 和运行权限
在 Kubernetes 中,Tracee 以 DaemonSet 覆盖目标节点。安装者需要创建 namespace、DaemonSet、ServiceAccount、RBAC、ConfigMap 以及可能的 Policy CRD;运行中的 ServiceAccount 应只持有元数据富化与策略读取所需 API 权限,节点级 capability 由 Pod securityContext 单独表达。Kubernetes 安装文档与 v0.24.1 Chart 源提供可复核入口。
kubectl config current-context
kubectl auth can-i create daemonsets.apps -n tracee
kubectl auth can-i create clusterroles.rbac.authorization.k8s.io
helm repo add aqua https://aquasecurity.github.io/helm-charts/
helm repo update aqua
helm search repo aqua/tracee --versions | head
helm show values aqua/tracee --version 0.24.1 > tracee-values-reference.yaml
helm upgrade --install tracee aqua/tracee \
--namespace tracee \
--create-namespace \
--version 0.24.1 \
--values tracee-values.yaml \
--waittracee-values.yaml 要显式评审 host PID/cgroup、host mounts、privileged 或 capabilities、ServiceAccount、RBAC、nodeSelector、tolerations、resources、Policy 来源和输出。禁止把 webhook token、Forward 凭证或 SIEM 认证写入 values 仓库或命令历史;通过 Secret 或外部密钥系统注入,并让每个目的地使用独立身份。
安装成功要证明节点、BPF、Policy 和字段都有效
先比较可调度 Linux 节点与 Tracee Pod,再看启动日志中的 BPF、BTF、capability、runtime enrichment 和 Policy。最后触发受控事件确认输出字段。DaemonSet Ready 只是四层证据中的一层。
kubectl get nodes -o name
kubectl get daemonset,pods,configmap -n tracee -o wide
kubectl rollout status daemonset/tracee -n tracee --timeout=180s
kubectl logs -n tracee daemonset/tracee --tail=200 \
| grep -Ei 'started|initialized|BTF|kallsyms|policy|error|warning'预期证据是每个目标节点有实例,eBPF load/attach 没有致命错误,目标 Policy 已加载,所需 enrichment 字段存在。若 execve 正常而特定 security event 不见,回到该事件的依赖矩阵;若事件存在但没有容器信息,检查 runtime socket、cgroup 和权限;若本地 JSON 有记录而平台没有,问题位于输出和消费链。
健康检查应为关键事件建立 capability 状态,例如 basic-events=ready、kernel-symbol-events=degraded、runtime-enrichment=missing,避免用一个布尔值掩盖部分能力退化。
Policy 用 scope、rules 和 filters 控制事件面
稳定基线的 Kubernetes Policy API 为 tracee.aquasec.com/v1beta1。下面策略观察 /tmp 路径上的 security_file_open:
apiVersion: tracee.aquasec.com/v1beta1
kind: Policy
metadata:
name: tmp-file-watch
annotations:
description: watch file opens under tmp
spec:
scope:
- global
rules:
- event: security_file_open
filters:
- data.pathname=/tmp/*scope 先决定哪些 workload 进入候选集,rules.event 决定采集或匹配哪类事件,filters 再按数据字段缩小范围。Policy 总览与 Kubernetes Policy 教程可用于确认目标版本支持的 scope 和 filter 语法。global scope 便于最初理解,但不适合直接覆盖繁忙生产集群。
稳定基线最多加载 64 个 Policy,每个 event type 在同一 Policy 中只能定义一次。不要为每个应用和每条路径机械复制 Policy,这会制造组合爆炸、重启频率和难以解释的重复命中。平台应按租户、节点池和事件语义合并,保留 owner、Policy digest、目标 workload、字段预算和失效时间。
通过 ConfigMap 添加 Policy 后通常需要滚动重启 DaemonSet;采用 Operator/CRD 路径时,控制器可能因 Policy 变化触发滚动。每次变更都可能制造节点级观测空窗,因此 Policy 不是“改一份 YAML 立即无损生效”的轻量对象。
event、security event 和 signature 要分别治理
事实事件适合取证和构建检测输入,security event 适合告警。一个 execve 只说明进程执行;fileless_execution 则由检测逻辑对底层行为和上下文作出安全解释。v0.24.1 的 signatures 源码目录可以帮助安全工程师审查派生逻辑,但应用团队不应通过阅读名字猜测保证。
YAML Policy 负责选择 workload、event 和 filter;自定义 Go event/signature 属于扩展开发,需要编译 Tracee、跟踪接口兼容、测试底层事件依赖并管理制品。两者不能放进同一个无差别“规则仓库”。前者可以由平台策略流水线发布,后者应按探针代码变更进行供应链、性能和升级评审。
告警调查至少保留 event name/ID、matched policy、threat、node、Pod UID、container ID、process、parent、时间和关键 data 字段。security event 没有完整输入上下文时应标记证据不足,不能因名字高危就直接执行破坏性响应。
用官方测试事件跑通正向检测
先确认集群中已经加载包含 fileless_execution 的 security event Policy,再在隔离环境运行官方 tester 的 TRC-105。tester 镜像和事件可随版本变化,正式执行前应在 release 说明中确认匹配版本。
kubectl run tracee-tester \
--image=aquasec/tracee-tester \
--restart=Never -- TRC-105
kubectl logs -n tracee daemonset/tracee --since=5m \
| grep fileless_execution
kubectl get pod tracee-tester -o wide
kubectl delete pod tracee-tester --ignore-not-found预期输出包含 fileless_execution、节点、进程或容器、matched policy 和 threat 上下文。若没有命中,依次检查 Policy 是否包含事件、tester 所在节点的 Tracee 是否有效、日志时间窗、输出过滤和该安全事件的能力依赖;不要先扩大到所有 event。
清理包括删除 tester、恢复临时 Policy、等待 DaemonSet 滚动完成,并确认原有 Policy 仍加载。若事件已经进入持久平台,测试记录应带实验标签和过期策略,避免污染真实事件统计。
反向实验一:移除 capability 识别假健康
在一次性节点池克隆生产 values,移除 CAP_BPF、CAP_PERFMON 或阻止 bpf(),然后部署候选 release。不要在业务节点直接更改内核安全配置。
kubectl get pods -n tracee -o wide
kubectl logs -n tracee daemonset/tracee --tail=200 \
| grep -Ei 'operation not permitted|permission|eBPF|load|attach|capability'预期失败证据是 operation not permitted、eBPF load/attach 或 capability 错误。Pod 若仍 Ready,说明 readiness 没有覆盖探针有效性。恢复 capability 后,要重新看到初始化成功、Policy 加载并再次命中 TRC-105,才算完成回滚。
反向实验二:区分部分退化和整体宕机
在限制 /proc/kallsyms 或没有匹配 BTF 的测试节点运行相同版本,先触发基础 execve,再触发依赖内核符号的测试事件。预期现象可能是基础事件仍存在,而 hooked_syscall、hidden_kernel_module 等不可用或报告初始化错误。
这个实验的价值是建立能力矩阵:basic-event、kernel-symbol-event、runtime-enrichment 和 BPF-LSM-event 分别记录 ready/degraded/unsupported。修复应恢复精确节点配置或选择不依赖该能力的检测,不得把“换一个更宽 Policy”当成内核依赖的替代品。
输出链决定事件能否成为证据
交互排障可使用 table,生产应优先使用结构化 JSON,并送入持久日志或 SIEM。稳定 v0.24.1 还支持 table-verbose、Go template、Fluent Forward、webhook 和 none;latest 或 dev 文档中的 destinations/formats/streams 模型可能属于后续演进,不能直接套到锁定版本。输出文档应与 release 和实际 --help 交叉确认。
事件流与 Tracee 自身诊断日志应分离。前者进入安全事件 schema,后者进入组件运维索引;否则 BPF 初始化错误可能被误当安全事件,普通告警查看者也可能读到探针内部信息。Webhook 或 Forward 目标需要 TLS、认证、请求大小、超时、429/500、背压、失败队列和重复语义。Tracee 不是耐久消息总线,下游长期不可用时必须有团队能维护的持久层。
事件跨 CPU 和节点并不天然全序。取证需要保留 node、CPU、单调时间、墙钟时间和事件 ID,并验证 NTP、Tracee 排序参数和日志管道重排。只按 SIEM 接收时间排序,可能把父子进程和网络动作颠倒。
敏感字段按用途最小化
exec-env 可能采集 token、数据库口令、云凭证、代理地址和内部域名,默认不应全局开启。file hash、stack address、decoded data 和 argument parsing 也会增加 CPU、IO、数据体积与隐私面。每种 enrichment 都应绑定具体调查用例、namespace、时间窗、字段白名单、读取角色和保留期。
聊天通知只发送事件 ID、级别、Policy 和脱敏摘要;完整 process、args、env、路径和 threat 上下文进入受控证据库。输出 token 由 Secret 或外部密钥系统注入,禁止出现在 ConfigMap、values、命令历史和错误响应中。接收端应限制 body 大小并清理可能回显敏感数据的错误页面。
容量预算从 Policy 宽度推导
事件成本由节点 syscall 率、scope 覆盖、event 数量、filter 选择性、enrichment、hash/stack、输出字节、重试和下游索引共同决定。编译、批量启动和短进程密集节点与普通服务节点不能共用一个平均值。宽 Policy 可能让 kubectl logs 失去实用性,也可能让探针与业务争抢 CPU、内存和 IO。
基线至少记录每节点事件率、Tracee CPU/内存、BPF 丢失或错误、输出字节、日志延迟、429/500、队列深度、重复率和索引成本。先收窄 scope、event 和 filter,再按需启用 enrichment,最后才调整资源与下游容量。没有通用阈值可复制,停止条件应来自业务节点抖动预算、检测延迟 SLO、敏感字段边界和可接受丢失率。
反向容量实验可以在限定节点和时间窗启用宽 Policy,让测试 webhook 返回 429/500,观察事件延迟、重复、丢失与资源。到达预算立即恢复窄 Policy。若事件永久丢失、业务资源明显受压或敏感字段进入非授权下游,候选配置不能上线。
高可用是节点覆盖加持久交付
Tracee 的节点采集层由 DaemonSet 提供。可用性指标是可调度目标节点中有多少实例真正加载 eBPF 并加载目标 Policy,不是 Pod Ready 比例。同节点双实例通常造成重复采集和资源竞争;跨节点聚合、持久化、查询和去重由外部日志管道承担。
节点镜像和内核升级会改变 BTF、kallsyms、capability 与 LSM 条件。先在新节点池 canary 部署,运行基础事件、TRC-105、能力缺失反例和输出故障实验,再逐步迁移工作负载。Policy 或 ConfigMap 更新可能要求重启 DaemonSet,滚动期间存在观测空窗,应限制并发不可用节点并保留空窗记录。
升级前同时比较 release notes、镜像、Chart values、Policy CRD、event name/ID、security event、JSON/protobuf schema、capabilities 和内核支持。回滚必须恢复镜像、values、Policy、输出解析器、告警规则和 SIEM 字段映射;只换回镜像可能让旧进程向新 schema 的消费端发送不兼容数据。
卸载要保留证据并核销外部资产
退出前导出 Policy 与必要事件,停止新增策略,撤销输出凭证,再卸载 release。随后检查 namespace 对象、集群级 RBAC、CRD 和残留 Pod:
kubectl get policies.tracee.aquasec.com -A -o yaml \
> tracee-policies-before-uninstall.yaml
helm uninstall tracee -n tracee
kubectl get daemonset,pods,configmap,secret,serviceaccount,role,rolebinding -n tracee
kubectl get clusterrole,clusterrolebinding | grep -i tracee || true
kubectl get crd | grep 'tracee.aquasec.com' || true
kubectl get pods -A -o wide | grep -i tracee || true删除 CRD 前先确认实例已经导出,避免级联丢失策略证据。Helm 不会自动清理所有集群权限、外部 webhook、Forward 目标、日志 parser、dashboard、告警规则和索引。历史事件按审计策略保留,旧凭证应吊销,长期索引要转交明确 owner 或按审批到期删除。
选择 Tracee 的理由应是团队需要深层 Linux/eBPF 事件、内置安全检测和细粒度 workload scope,并愿意维护内核能力矩阵、Policy 发布和证据管道。需要成熟多事件源规则生态时可比较 Falco;需要内核级执行约束时应评估 Tetragon 或 KubeArmor;需要准入阻断则交给准入策略。并行部署多个传感器会重复采集同一内核行为,必须先比较资源、字段增益和告警重复,不能把“双装”默认等同于更安全。
