eBPF 实战:利用 Tetragon 实时监控并阻断 K8s 集群异常网络外联
在 Kubernetes 集群的安全治理中,网络层面的防御通常依赖于 Network Policy。然而,传统的 Network Policy 只能在 L3/L4 层进行粗粒度的访问控制,且往往难以应对“已感染容器试图通过非常规手段外联”这种深度威胁。
由 Cilium 团队开发的 Tetragon 基于 eBPF 技术,能够深入内核空间监控进程行为、文件访问以及网络连接。本文将演示如何利用 Tetragon 编写 TracingPolicy,精准捕获并审计集群中异常的网络外联行为。
1. 为什么选择 Tetragon?
与传统的日志审计(如 Auditd)或侧车(Sidecar)模式不同,Tetragon 拥有以下优势:
- 内核级观测:直接在内核中运行 eBPF 程序,性能损耗极低。
- 实时阻断能力:不仅仅是记录,还可以在系统调用发生时直接进行内核级阻断(SIGKILL)。
- 上下文关联:自动关联 K8s 的 Metadata(Pod 名称、Namespace、标签等),无需手动对齐日志。
2. 环境准备
首先,确保你的 K8s 集群内核版本在 5.4 及以上(以支持 eBPF BTF)。
使用 Helm 快速安装 Tetragon:
helm repo add cilium https://helm.cilium.io
helm repo update
helm install tetragon cilium/tetragon -n kube-system
安装完成后,可以通过 kubectl get pods -n kube-system -l app.kubernetes.io/name=tetragon 确认 Agent 是否运行正常。
3. 实战场景:监控异常的外部 IP 访问
假设我们有一个生产命名空间 prod-app,其中的服务理论上只允许访问内部数据库和特定的 API 域名。如果该服务突然尝试连接外部的非法 IP(例如 1.1.1.1),我们需要实时感知。
3.1 编写 TracingPolicy
Tetragon 使用 CRD(Custom Resource Definition)来定义监控策略。我们创建一个 TracingPolicy,重点监控 tcp_connect 系统调用。
apiVersion: cilium.io/v1alpha1
kind: TracingPolicy
metadata:
name: monitor-outbound-traffic
spec:
kprobes:
- call: "tcp_v4_connect"
syscall: false
args:
- index: 0
type: "sock"
selectors:
- matchPIDs:
- operator: NotIn
values:
- 1
- 2
matchArgs:
- index: 0
operator: "DPort"
values:
- "80"
- "443"
# 这里可以根据需要排除内网网段
matchActions:
- action: Post
3.2 进阶:限制特定 Pod 的敏感外联
如果我们需要针对性地监控某个带有 app: high-risk 标签的 Pod,并捕获其所有非 53 端口(DNS)的 UDP/TCP 请求,可以使用以下配置:
apiVersion: cilium.io/v1alpha1
kind: TracingPolicy
metadata:
name: restrict-sensitive-pod-network
spec:
podSelector:
matchLabels:
app: high-risk
kprobes:
- call: "tcp_connect"
syscall: true
args:
- index: 0
type: "sock"
selectors:
- matchArgs:
- index: 0
operator: "DPort"
values:
- "22"
- "3389"
- "23"
matchActions:
- action: Sigkill # 发现连接敏感端口直接 Kill 掉进程
4. 验证与日志分析
部署一个测试 Pod 并执行外联操作:
kubectl run test-pod --image=alpine --labels="app=high-risk" -- /bin/sh -c "sleep 3600"
kubectl exec -it test-pod -- apk add curl
kubectl exec -it test-pod -- curl 1.1.1.1:22
此时,由于触发了 Sigkill 动作,curl 进程会被内核直接强杀。
5. 查看观测结果
Tetragon 提供了专门的 CLI 工具 tetra 来解析其输出的 JSON 日志。
# 从 tetragon pod 中实时观察日志
kubectl logs -n kube-system -l app.kubernetes.io/name=tetragon -c export-stdout -f | tetra getevents -o compact
你将看到类似如下的输出,清晰地展示了进程名、Pod 信息、目标 IP 及端口、以及被执行的操作(Action):
🚀 process default/test-pod /usr/bin/curl 1.1.1.1:22 binary /usr/bin/curl
💥 exit default/test-pod /usr/bin/curl 1.1.1.1:22 SIGKILL
6. 生产环境最佳实践
- 分阶段部署:先使用默认的观察模式(不加
Sigkill),通过日志审计确定业务正常的流量特征。 - 精细化过滤:利用
matchPIDs排除系统级组件(如 kubelet、sidecar 注入器),减少日志噪音。 - 日志外接:将 Tetragon 输出的 JSON 日志接入 ELK 或 Grafana Loki,针对
action: Sigkill或tcp_connect异常事件配置告警。 - 性能考量:虽然 eBPF 性能优秀,但过多的 Kprobes 钩子依然会产生开销。建议只在关键应用或高风险命名空间开启深度监控。
总结
Tetragon 通过将安全策略下沉到内核级别,为 Kubernetes 提供了前所未有的可见性。在应对反弹 Shell、敏感数据脱库、内网横向移动等场景时,它不仅是一个高效的监控工具,更是集群最后一道强有力的防线。