开头语
写在前面:如有问题,以你为准,
目前24年应届生,各位大佬轻喷,部分资料与图片来自网络
内容较长,页面右上角目录方便跳转
在Kubernetes集群中,API Server的审计日志记录了哪些用户、哪些服务请求操作集群资源,并且可以编写不同规则 控制忽略、存储的操作日志。
审计日志采用SON格式输出,每条日志都包含丰富的元数据,例如请求的URL、HTTP方法、客户端来源等,你可以使 用监控服务来分析API流量,以检测趋势或河能存在的安全隐患。
https://kubernetes.io/zh-cn/docs/tasks/debug/debug-cluster/audit/
修改配置后是需要删除apiserver容器,等待自动pod自动进行创建
apiVersion: audit.k8s.io/v1 # 这是必填项。
kind: Policy
# 不要在 RequestReceived 阶段为任何请求生成审计事件。
omitStages:
? - "RequestReceived"
rules:
? # 在日志中用 RequestResponse 级别记录 Pod 变化。
? - level: RequestResponse
??? resources:
??? - group: ""
????? # 资源 "pods" 不匹配对任何 Pod 子资源的请求,
????? # 这与 RBAC 策略一致。
????? resources: ["pods"]
? # 在日志中按 Metadata 级别记录 "pods/log"、"pods/status" 请求
? - level: Metadata
??? resources:
??? - group: ""
????? resources: ["pods/log", "pods/status"]
? # 不要在日志中记录对名为 "controller-leader" 的 configmap 的请求。
? - level: None
??? resources:
??? - group: ""
????? resources: ["configmaps"]
????? resourceNames: ["controller-leader"]
? # 不要在日志中记录由 "system:kube-proxy" 发出的对端点或服务的监测请求。
? - level: None
??? users: ["system:kube-proxy"]
??? verbs: ["watch"]
??? resources:
??? - group: "" # core API 组
????? resources: ["endpoints", "services"]
? # 不要在日志中记录对某些非资源 URL 路径的已认证请求。
? - level: None
??? userGroups: ["system:authenticated"]
??? nonResourceURLs:
??? - "/api*" # 通配符匹配。
??? - "/version"
? # 在日志中记录 kube-system 中 configmap 变更的请求消息体。
? - level: Request
??? resources:
??? - group: "" # core API 组
????? resources: ["configmaps"]
??? # 这个规则仅适用于 "kube-system" 名字空间中的资源。
??? # 空字符串 "" 可用于选择非名字空间作用域的资源。
??? namespaces: ["kube-system"]
? # 在日志中用 Metadata 级别记录所有其他名字空间中的 configmap 和 secret 变更。
? - level: Metadata
??? resources:
??? - group: "" # core API 组
????? resources: ["secrets", "configmaps"]
? # 在日志中以 Request 级别记录所有其他 core 和 extensions 组中的资源操作。
? - level: Request
??? resources:
??? - group: "" # core API 组
??? - group: "extensions" # 不应包括在内的组版本。
? # 一个抓取所有的规则,将在日志中以 Metadata 级别记录所有其他请求。
? - level: Metadata
??? # 符合此规则的 watch 等长时间运行的请求将不会
??? # 在 RequestReceived 阶段生成审计事件。
??? omitStages:
????? - "RequestReceived"
apiVersion: audit.k8s.io/v1
kind: Policy
rules:
- level: Metadata
? # namespaces: ["default"] # 执行命名空间
? verbs: ["create","delete"] # 指定相关操作
? resources: # 执行资源
? - group: ""
??? resources: ["pods"]
??? # resourceNames: ["controller-leader"] 指定资源名
- level: None
[root@master audit]# ps -ef | grep apiserver
root????? 831053? 831034? 0 10:27 ???????
root???? 2791437 2791419 71 21:09 ???????? 00:00:08 kube-apiserver --advertise-address=
[root@master audit]# kill -9 2791437
[root@master audit]# kubectl get pod -A
[root@master ~]# kubectl delete? pod web1666
pod "web1666" deleted
[root@master audit]# tail -f /var/log/audit/k8s_audit.log
{
? "kind": "Event",
? "apiVersion": "audit.k8s.io/v1",
? "level": "Metadata",
? "auditID": "c52213b1-0bd6-4790-80ae-7c5aeb159ab9",
? "stage": "ResponseComplete",
? "requestURI": "/api/v1/namespaces/default/pods/web1666",
? "verb": "delete",
? "user": {
??? "username": "system:node:node1",
??? "groups": [
????? "system:nodes",
????? "system:authenticated"
??? ]
? },
? "sourceIPs": [
??? "192.168.100.51"
? ],
? "userAgent": "kubelet/v1.28.1 (linux/amd64) kubernetes/8dc49c4",
? "objectRef": {
??? "resource": "pods",
??? "namespace": "default",
??? "name": "web1666",
??? "apiVersion": "v1"
? },
? "responseStatus": {
??? "metadata": {},
??? "code": 200
? },
? "requestReceivedTimestamp": "2023-11-21T02:11:53.435596Z",
? "stageTimestamp": "2023-11-21T02:11:53.444542Z",
? "annotations": {
??? "authorization.k8s.io/decision": "allow",
??? "authorization.k8s.io/reason": ""
? }
}
审计日志支持写入本地文件和Vebhook (发送到外部HTTP API) 两种方式。
vi /etc/kubernetes/manifests/kube-apiserver.yaml
---audit-policy-file=/etc/kubernetes/audit/audit-policy.yaml
--audit-log-path=/var/log/audit/k8s_audit.log
---audit-log-maxage=30
---audit-log-maxbackup=10
---audit-log-maxsize=100
注:使用hostpath数据卷将宿主机/etc/kubernetes/,audit目录挂载到容器中
mkdir /etc/kubernetes/audit
touch /var/log/audit/k8s_audit.log
?apiserver.yaml 需要修改内容
????? volumeMounts:
????? - mountPath: /etc/kubernetes/audit
????? name: audit
????? readOnly: true
??? - mountPath: /var/log/audit/k8s_audit.log
????? name: audit-log-file
? volumes:???????????
? - hostPath:
????? path: /etc/kubernetes/audit
????? type: DirectoryOrCreate
??? name: audit
? - hostPath:
????? path: /var/log/audit/k8s_audit.log
????? type: File
??? name: audit-log-file
[root@master kubernetes]# tail -1 /var/log/audit/k8s_audit.log? | jq
{
? "kind": "Event",
? "apiVersion": "audit.k8s.io/v1",
? "level": "Metadata",
? "auditID": "95279099-833a-4a79-b942-9cd5da761cc6",
? "stage": "ResponseComplete", # 在那个阶段处理
? "requestURI": "/healthz",
? "verb": "get",
? "user": {
??? "username": "system:serviceaccount:calico-system:calico-kube-controllers",
??? "uid": "47d3e62f-edcf-4938-b988-ae0b14e40666",
??? "groups": [
????? "system:serviceaccounts",
????? "system:serviceaccounts:calico-system",
????? "system:authenticated"
??? ],
??? "extra": {
????? "authentication.kubernetes.io/pod-name": [
??????? "calico-kube-controllers-6b7b9c649d-xllqh"
????? ],
????? "authentication.kubernetes.io/pod-uid": [
??????? "fbf6ee10-fd48-4e64-bd03-31995dedbe6a"
????? ]
??? }
? },
? "sourceIPs": [
??? "10.244.219.105"
? ],
? "userAgent": "kube-controllers/v0.0.0 (linux/amd64) kubernetes/$Format",
? "responseStatus": {
??? "metadata": {},
??? "code": 200
? },
? "requestReceivedTimestamp": "2023-11-20T09:06:54.725743Z",
? "stageTimestamp": "2023-11-20T09:06:54.727333Z",
? "annotations": {
??? "authorization.k8s.io/decision": "allow",
??? "authorization.k8s.io/reason": "RBAC: allowed by ClusterRoleBinding \"system:public-info-viewer\" of ClusterRole \"system:public-info-viewer\" to Group \"system:authenticated\""
? }
}
[root@master ~]# docker run -d? --name web1666 nginx:1.17.1
[root@master kubernetes]# cat? /var/log/audit/k8s_audit.log? | grep web1666 | jq
文件描述符? ? ? ? ? ? ? ? ? ? ?作用? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 例子(c语言)
0? ? ?(stdin)? ? ? ? ? ? ? ? ?标准输入? ? ? ? ? ? ? ? ? ? ? ? ? ?fscanf(stdin,"%s",str);
1? ? ?(stdout)? ? ? ? ? ? ? ?标准输出? ? ? ? ? ? ? ? ? ? ? ? ? ?fprintf(stdout,"%s\n","hello");
2? ? ? (stderror)? ? ? ? ? ? ??标准错误输出? ? ? ? ? ? ? ? ? ? fprintf(stderr,"%s\n","error");
1. 简单方便,可以直接使用语言自带的标准库,打印出信息(比如c语言的printf, fprintf函数)作为日志的输入源,不用额外的再建立一个文件。
2. 易管理,可以将容器的标准输出stdout, stderr重定向到log-file.log。 比如将上面的test.c文件编译后,执行? ./a.out >> a.log? 2>&1,就会将标准输出存放到a.log里
使用 volumes 中的 emptyDir: {}
yaml 如图