审计策略会检查 Kubernetes 集群中发生的所有请求、响应。本文介绍了在 Kubernetes 中实施审计策略的相关信息和实践。
作者:Vinod Kumar Nair 翻译:Bach (K8sMeetup) 校对:星空下的文仔
如果我们想检查 Kubernetes 生产环境中的以下活动:
那么在 Kubernetes 中执行审计策略(Audit Policy)是非常正确的选择。
K8sMeetup
典型的 Kubernetes 环境
没有审计策略的 Kubernetes
启用后,审计记录将在 kube-apiserver 组件内开始其生命周期。每个请求在其执行的每个阶段都会生成一个审计事件,然后根据特定策略对其进行预处理,并写入后端。该策略确定记录的内容,后端将保留记录。当前的后端实现包括日志文件和 webhooks。
每个请求都可以记录一个关联的阶段(stage)。定义的阶段有:
RequestReceived
- 此阶段对应审计处理器接收到请求后,并且在委托给其余处理器之前生成的事件。ResponseStarted
- 在响应消息的头部发送后,响应消息体发送前生成的事件。只有长时间运行的请求(例如 watch)才会生成这个阶段。ResponseComplete
- 当响应消息体完成并且没有更多数据需要传输的时候。Panic
- 当 panic 发生时生成。K8sMeetup
审计策略规则和级别
审计策略定义了有关应该记录哪些事件以及应包含哪些数据的规则。审核策略对象结构在 audit.k8s.io
API 组中定义。处理事件时,会按顺序将其与规则列表进行比较。第一个匹配规则设置事件的级别(audit levels)。定义的审核级别有:
None
- 符合这条规则的日志将不会记录。Metadata
- 记录请求的元数据(请求的用户、时间戳、资源、动词等等),但是不记录请求或者响应的消息体。Request
- 记录事件的元数据和请求的消息体,但是不记录响应的消息体。这不适用于非资源类型的请求。RequestResponse
- 记录事件的元数据,请求和响应的消息体。这不适用于非资源类型的请求。下面是一个典型的审计策略文件:
# Log all requests at the Metadata level.
apiVersion: audit.k8s.io/v1
kind: Policy
rules:
- level: Metadata
复杂一点就是:
apiVersion: audit.k8s.io/v1
kind: Policy
omitStages:
- "RequestReceived"
rules:
- level: RequestResponse
resources:
- group: ""
resources: ["pods"]
- level: Metadata
resources:
- group: ""
resources: ["pods/log", "pods/status"]
- level: None
resources:
- group: ""
resources: ["configmaps"]
resourceNames: ["controller-leader"]
- level: None
users: ["system:kube-proxy"]
verbs: ["watch"]
resources:
- group: "" # core API group
resources: ["endpoints", "services"]
- level: None
userGroups: ["system:authenticated"]
nonResourceURLs:
- "/api*" # Wildcard matching.
- "/version"
- level: Request
resources:
- group: "" # core API group
resources: ["configmaps"]
namespaces: ["kube-system"]
- level: Metadata
resources:
- group: "" # core API group
resources: ["secrets", "configmaps"]
- level: Request
resources:
- group: "" # core API group
- group: "extensions" # Version of group should NOT be included.
- level: Metadata
omitStages:
- "RequestReceived"
K8sMeetup
架构-Kubernetes 中的审计策略
Kubernetes 启用了审计策略
我们可以使用 Webhooks 将审核日志发送到文件或远程 Web API。
在本文中,我们将强制 kube api-server 将审核日志发送到文件。
K8sMeetup
在 Kubernetes 中启用审计策略(对于审计日志文件)
apiVersion: audit.k8s.io/v1
kind: Policy
rules:
# Log the request body of configmap changes in kube-system.
- level: Request
resources:
- group: "" # core API group
resources: ["configmaps"]
namespaces: ["kube-system"]
# Log configmap and secret changes in all other namespaces at the Metadata level.
- level: Metadata
resources:
- group: "" # core API group
resources: ["secrets", "configmaps"]
# A catch-all rule to log all other requests at the Metadata level.
- level: Metadata
omitStages:
- "RequestReceived"
- kube-apiserver
- --advertise-address=10.156.0.6
- --audit-policy-file=/etc/kubernetes/audit-policy.yaml
- --audit-log-path=/var/log/audit.log
---
- mountPath: /etc/kubernetes/audit-policy.yaml
name: audit
readOnly: true
— mountPath: /var/log/audit.log
name: audit-log
readOnly: false
---
volumes:
- name: audit
hostPath:
path: /etc/kubernetes/audit-policy.yaml
type: File
- name: audit-log
hostPath:
path: /var/log/audit.log
type: FileOrCreate
k8s-api-server —清单文件
k8s-api-server —清单文件
就这样,转到生成的审计日志文件。
在这个案例中,这是 audit.log。我们可以看到在阶段级别捕获的有关 Kubernetes 集群的审计日志信息,如以下示例中所示:
{
"kind":"Event",
"apiVersion":"audit.k8s.io/v1",
"level":"Metadata",
"auditID":"a42fa658-f143–43d8-b5e6–4e101d3e15ea",
"stage":"ResponseComplete",
"requestURI":"/api/v1/namespaces/default/secrets?fieldManager=kubectl-create",
"verb":"create",
"user":{
"username":"kubernetes-admin",
"groups":[
"system:masters",
"system:authenticated"
]
},
"sourceIPs":[
"10.156.0.2"
],
"userAgent":"kubectl/v1.20.2 (linux/amd64) kubernetes/faecb19",
"objectRef":{
"resource":"secrets",
"namespace":"default",
"name":"test-secret",
"apiVersion":"v1"
},
"responseStatus":{
"metadata":{
},
"code":201
},
"requestReceivedTimestamp":"2021–04–03T13:50:37.009656Z",
"stageTimestamp":"2021–04–03T13:50:38.040874Z",
"annotations":{
"authorization.k8s.io/decision":"allow",
"authorization.k8s.io/reason":""
}
}
{
"kind":"Event",
"apiVersion":"audit.k8s.io/v1",
"level":"Metadata",
"auditID":"f1466b01–9b68–45ec-b3bb-b440397f6481",
"stage":"ResponseComplete",
"requestURI":"/api/v1/namespaces/default/secrets/test-secret",
"verb":"get",
"user":{
"username":"kubernetes-admin",
"groups":[
"system:masters",
"system:authenticated"
]
},
"sourceIPs":[
"10.156.0.2"
],
"userAgent":"kubectl/v1.20.2 (linux/amd64) kubernetes/faecb19",
"objectRef":{
"resource":"secrets",
"namespace":"default",
"name":"test-secret",
"apiVersion":"v1"
},
"responseStatus":{
"metadata":{
},
"code":200
},
"requestReceivedTimestamp":"2021–04–03T13:51:08.603724Z",
"stageTimestamp":"2021–04–03T13:51:08.607716Z",
"annotations":{
"authorization.k8s.io/decision":"allow",
"authorization.k8s.io/reason":""
}
}
{
"kind":"Event",
"apiVersion":"audit.k8s.io/v1",
"level":"Metadata",
"auditID":"30be8c70-fda6–44de-8a83–3fe56161d44e",
"stage":"ResponseComplete",
"requestURI":"/api/v1/namespaces/default/secrets/test-secret",
"verb":"get",
"user":{
"username":"kubernetes-admin",
"groups":[
"system:masters",
"system:authenticated"
]
},
"sourceIPs":[
"10.156.0.2"
],
"userAgent":"kubectl/v1.20.2 (linux/amd64) kubernetes/faecb19",
"objectRef":{
"resource":"secrets",
"namespace":"default",
"name":"test-secret",
"apiVersion":"v1"
},
"responseStatus":{
"metadata":{
},
"code":200
},
"requestReceivedTimestamp":"2021–04–03T13:54:57.867317Z",
"stageTimestamp":"2021–04–03T13:54:57.871369Z",
"annotations":{
"authorization.k8s.io/decision":"allow",
"authorization.k8s.io/reason":""
}
}
此外, 我们可以使用以下 kube-apiserver 标志配置 Log 审计后端,来更改审计日志文件的状态:
--audit-log-maxage
定义保留旧审计日志文件的最大天数。--audit-log-maxbackup
定义要保留的审计日志文件的最大数量。--audit-log-maxsize
定义审计日志文件的最大大小(兆字节)。K8sMeetup
总结
审计策略会检查 Kubernetes 集群中发生的所有请求、响应。这是一个最佳实践,应在早期阶段就启用。在本文示例中,和大家展示了如何将审计数据发送到文件。
原文链接:https://levelup.gitconnected.com/enforce-audit-policy-in-kubernetes-k8s-34e504733300