引言:当 kubectl 成为一把双刃剑
大家好,在Kubernetes的世界里,kubectl 是我们手中最强大的“瑞士军刀”。它让我们能够轻松地与集群交互,部署应用,排查故障。然而,这把“军刀”中最锋利的两刃——kubectl exec 和 kubectl port-forward,也可能成为最危险的安全后门。
kubectl exec:允许用户在Pod内容器中执行任意命令,相当于一个直通容器内部的Shell。如果被滥用,攻击者可以窃取敏感信息、横向移动或植入恶意软件。kubectl port-forward:能够将本地端口流量转发到Pod的端口,直接暴露了集群内部的网络服务,绕过了Ingress、Service等所有网络策略和安全控制。
对于任何一个生产环境的EKS集群,放任这些操作而不进行监控,无异于“夜不闭户”。幸运的是,AWS EKS提供了强大的控制平面日志(Control Plane Logging)功能,特别是其中的审计日志(Audit Logs),它能记录下对K8s API Server的每一次调用。今天,我们就来一步步了解如何利用它,揪出每一次高危操作,并设置实时告警。
核心原理:让K8s API Server成为我们的“告密者”
要理解如何监控,我们首先要明白kubectl命令的工作原理。其实,每一条kubectl命令,本质上都是向Kubernetes API Server发送的一个HTTP请求。
例如,当我们执行kubectl exec -it my-pod -- /bin/bash时,kubectl客户端实际上是向API Server发起了创建pods/exec子资源的请求。
我们的监控逻辑就是:
- 开启日志:在EKS集群上启用审计日志功能,让API Server把所有请求记录都发送到AWS CloudWatch Logs。
- 分析日志:审计日志是结构化的JSON格式,包含了请求者(
user)、操作(verb)、目标资源(objectRef)等所有关键信息。 - 筛选关键行为:我们在海量的日志中,通过创建**指标筛选器(Metric Filter)**来精确匹配
exec和port-forward这类操作。 - 实时告警:一旦匹配到这些行为,就触发CloudWatch告警(Alarm),通过SNS通知到我们。
整个流程清晰明了,接下来让我们进入实战环节。
实战指南:三步搭建我们的EKS操作“天眼”
前提条件:
- 一个正在运行的EKS集群。
- 安装并配置好AWS CLI,且拥有管理EKS集群的权限。
第一步:启用EKS审计日志
默认情况下,EKS控制平面日志是关闭的。我们需要通过AWS CLI手动开启它。我们只关心审计日志,所以只开启audit类型。
# 将 "your-cluster-name" 替换为我们的EKS集群名称
aws eks update-cluster-config \
--name your-cluster-name \
--logging '{"clusterLogging":[{"types":["audit"],"enabled":true}]}'
执行此命令后,AWS会更新我们的EKS集群配置。这可能需要几分钟时间。更新完成后,EKS会自动在CloudWatch中创建一个名为 /aws/eks/your-cluster-name/cluster 的日志组,所有审计日志都会被发送到这里。
实用建议:除了
audit,EKS还支持api、authenticator等日志类型。api记录了API服务器的请求和响应,但审计日志更侧重于安全审计,信息更精炼。对于此场景,audit是最佳选择。
第二步:分析日志并创建指标筛选器
现在,日志已经开始流入CloudWatch了。随便在一个Pod上执行一次exec操作:
# 确保我们有pod可以操作
kubectl run test-pod --image=nginx
kubectl exec -it test-pod -- echo "hello from exec"
然后去CloudWatch日志组,我们会找到类似下面的日志条目(已精简):
{
"kind": "Event",
"apiVersion": "audit.k8s.io/v1",
"level": "Metadata",
"verb": "create",
"requestURI": "/api/v1/namespaces/default/pods/test-pod/exec?command=echo...&container=test-pod...",
"user": {
"username": "arn:aws:iam::123456789012:user/your-iam-user",
"groups": ["system:masters", "system:authenticated"]
},
"objectRef": {
"resource": "pods",
"namespace": "default",
"name": "test-pod",
"subresource": "exec" // <-- 关键点!
},
...
}
从日志中我们发现了关键信息:
- 操作:
"verb": "create"(exec和port-forward都是通过创建子资源实现的) - 识别符:
"objectRef": { "subresource": "exec" }或"objectRef": { "subresource": "portforward" }
有了这个,我们就可以创建指标筛选器了。
-
导航到 CloudWatch -> 日志组,选择
/aws/eks/your-cluster-name/cluster。 -
点击 “操作” -> “创建指标筛选器”。
-
在 “筛选模式” 中,输入以下表达式。这个表达式会匹配所有
create操作的exec或port-forward事件:{ ($.verb = "create") && (($.objectRef.subresource = "exec") || ($.objectRef.subresource = "portforward")) } -
点击“下一步”,为该筛选器分配一个指标:
- 筛选器名称:
HighRiskKubectlOperations - 指标命名空间:
EKS/Audit(自定义,方便归类) - 指标名称:
HighRiskOperationCount - 指标值:
1(每次匹配到日志,指标值就+1)
- 筛选器名称:
第三步:创建告警
当指标创建成功后,我们就可以基于它来创建告警了。
- 在指标筛选器页面,找到刚创建的
HighRiskKubectlOperations,点击右侧的 “创建警报”。 - 配置告警条件:
- 指标名称:
HighRiskOperationCount - 统计数据:求和 (Sum)
- 周期:1 分钟
- 条件:大于 (>)
- 阈值:0 (意味着只要在1分钟内,发生至少1次高危操作,就告警)
- 指标名称:
- 配置操作:
- 选择 “状态为ALARM” 时。
- 选择一个现有的SNS主题,或创建一个新的。这个SNS主题可以配置为发送邮件、短信、调用Lambda或推送到Slack。
点击创建,大功告成!现在,只要有人在我们的集群上执行kubectl exec或port-forward,我们就会在1分钟内收到告警邮件。邮件中可以包含时间戳等信息,结合CloudWatch日志中的user字段,我们可以快速定位到是谁、在什么时间、对哪个Pod执行了高危操作。
结论与延伸
通过利用EKS审计日志和CloudWatch,我们以一种云原生的方式,为集群中最危险的操作安装了一个灵敏的“防盗铃”。这不仅满足了安全合规的要求,更重要的是,它将潜在的威胁从“暗处”拉到了“明处”,极大地提升了集群的整体安全性。
我们可以更进一步:
- 细化告警:可以基于
user.username或objectRef.namespace创建更精细的筛选器,例如只告警非白名单用户或在生产命名空间中的操作。 - 日志归档与分析:将CloudWatch日志长期归档到S3,或使用Amazon Athena、OpenSearch进行更复杂的历史行为分析和可视化。
- 自动化响应:通过Lambda函数订阅SNS通知,实现自动化响应,例如临时隔离Pod或向安全团队的IM工具发送详细的事件报告。
希望这篇文章能帮助大家更好地守护自己的EKS集群。安全无小事,从监控每一次高危操作开始!