没留下的日志,等于没发生过
一句话总结
审计策略不是决定“记录什么”,而是决定“丢弃什么”的文档。规则会从上到下 依次求值,并且只应用第一个匹配项,因此顺序写错后,可能悄无声息地什么都没留下。
为什么需要它
事件响应的第一个问题总是相同:何时、由谁、做了什么。在 Kubernetes 中,唯一能回答 这个问题的资料就是 API 服务器的审计日志。然而,全部记录会使存储成本激增, 随意记录又会在真正需要时一无所获。因此需要审计策略。
日志级别分为四档。
| 级别 | 记录范围 |
|---|---|
None |
不记录 |
Metadata |
只记录请求者、时间、动词、资源等元数据 |
Request |
元数据 + 请求正文 |
RequestResponse |
元数据 + 请求正文 + 响应正文 |
CKS 在这里会反复考查一个陷阱:如果对 Secret 设置 RequestResponse,
Secret 的值会原样写进审计日志文件。审计日志通常会被收集到一个访问权限比应用更宽泛的
位置,因此原本为了保护 Secret 的措施,反而会造成 Secret 扩散。
所以,Secret 和 ConfigMap 通常最多只记录到 Metadata。
工作原理
策略文件是 audit.k8s.io/v1 的 Policy 资源,它从上到下检查 rules 数组,
并应用第一个匹配的规则。因此,顺序本身就有含义。例如,如果想排除 kube-system 中
对 Secret 的 get 请求,对应的 level: None 规则就必须放在 Secret 相关规则之前。
如果放在后面,请求会先匹配上方规则,排除操作完全不会生效。
还会配合使用 omitStages。一个请求可能在 RequestReceived、ResponseStarted、
ResponseComplete、Panic 四个阶段生成事件,而 RequestReceived 几乎总是噪声。
把这个阶段写入顶层 omitStages,可以显著减少日志量。
创建策略文件后,还必须将其连接到 API 服务器。通过 --audit-policy-file 指定策略,
通过 --audit-log-path 指定输出位置,再用 --audit-log-maxage(保留天数)、
--audit-log-maxbackup(文件数量)、--audit-log-maxsize(MB)设定轮转策略。
缺少这三项会使磁盘逐渐写满,而磁盘写满后,API 服务器就会停止工作。
RBAC 中的高风险动词需要特殊处理。escalate、bind、impersonate 本身就是权限提升尝试,
因此应以 RequestResponse 记录,以便保留试图修改什么、如何修改的完整信息。
对于 Pod 变更,Request 是较好的平衡点。保留清单即可在入侵后重建曾部署过什么,
通常不需要连响应正文也记录下来。
现场会遇到的情况
有些领域无法通过审计日志回答,运行时检测会补上这一空缺。Falco 观察内核系统调用,
并对符合规则的行为发出告警。它最知名的内置规则之一,是捕获容器内启动 Shell 的瞬间;
其条件大致是在 evt.type=execve 的基础上,再叠加是否处于容器中,以及进程名称是否
位于 Shell 列表中。没有经过 API 的行为根本不会出现在审计日志里,
所以这两个层面并非替代关系,而是回答不同问题的工具。
可以用 crictl 检查节点上实际运行的内容,但必须守住边界。
crictl 会绕过 API 服务器,因此非常适合诊断,拿来改变状态却很危险。kubelet 会持续监控
自己创建的容器和沙箱;如果人工执行 crictl rm 删除它们,kubelet 的认知与实际状态就会
发生偏差,系统会停留在异常的中间状态。规则可以简单概括为:想知道 Kubernetes 试图做什么,
就使用 kubectl;想知道运行时实际上做了什么,就使用 crictl。两种视角发生偏差的位置,
正是问题所在。
还有一种情况会让整套诊断失去意义:如果 crictl 连接了错误的套接字,它会显示空列表,
从而让人得出“一个容器都没有”的错误结论。第一步应先运行 crictl info 确认当前连接目标,
再核对 /etc/crictl.yaml 中的 runtime-endpoint 是否与 kubelet 的
--container-runtime-endpoint 一致。如果没有明确指定端点,crictl 还会依次尝试已知的
套接字候选项,导致一条命令也可能耗时十几秒。
发现遭入侵的 Pod 后,处置顺序也有明确要求。第一步不是立刻删除,而是保全证据。 先收集日志和状态,再用 NetworkPolicy 切断该 Pod 的通信并实施隔离,确认入侵路径与范围后, 最后替换为已修复漏洞的新镜像。如果先删除,取证证据就会消失。
下一实验要做什么
你将逐条构建 audit.k8s.io/v1 策略文件。从最底部的兜底规则开始,
通过 omitStages 减少噪声;Secret 最多记录到 Metadata,kube-system 中的 Secret get
完全设为 None,RBAC 高风险动词设为 RequestResponse,Pod 变更设为 Request,
并亲自安排这些规则的顺序。最后,还要记录连接 API 服务器所需的审计日志后端标志。