Kubernetes

Audit Log Policy

라온클 2023. 6. 8. 09:09

Audit Log 요약

쿠버네티스에서 누가, 언제, 무엇을, 어떻게 활동했는지 감사(audit)하고 파일로 저장하는 기능

정책 파일에 rules 를 정의하여 어떤 로그를 생성할 지 필터링을 걸 수 잇다.

Audit Logging기능을 활성화하려면, 정책 파일을 정의하고, 외부 저장소에 백엔드를 정의해야 한다.

Audit Log 만드는 법

이하 내용은 공식 문서의 '이벤트를 파일 시스템에 기록하는 로그 백엔드'항목을 정리한 것이다.

https://kubernetes.io/docs/tasks/debug/debug-cluster/audit/#log-backend

1단계: Audit Policy 정의하기

Audit Policy의 rules 필드는 필수로 지정되어야 한다.

vi /etc/kubernetes/audit/audit-policy.yaml

예시1 - level: None

None - 이 규칙에 해당되는 이벤트는 로깅하지 않는다.

apiVersion: audit.k8s.io/v1
kind: Policy
rules:
  # "controller-leader" 라는 이름의 configmap에 request를 기록하지 않음.
  - level: None
    resources:
    - group: ""
      resources: ["configmaps"]
      resourceNames: ["controller-leader"]
apiVersion: audit.k8s.io/v1
kind: Policy
rules:
  # endpoint 또는 service에서 "system:kube-proxy"에 의한 감시 request들은 기록하지 않음.
  - level: None
    users: ["system:kube-proxy"]
    verbs: ["watch"]
    resources:
    - group: "" # 핵심 API 그룹
      resources: ["endpoints", "services"]
apiVersion: audit.k8s.io/v1 # 필수
kind: Policy
rules:
  # 리소스가 아닌 특정 URL 경로에 대한 인증된 request들은 기록하지 않음.
  - level: None
    userGroups: ["system:authenticated"]
    nonResourceURLs:
    - "/api*" # /api 경로의 전체 최종 단계에만 해당
    - "/version"

<참고>

'NonResourceURLs'는 감사해야 하는 URL 경로 집합이다.

'level: None'이므로 "/api*"와 "/version" 경로에 대해서는 기록하지 말라는 정책을 의미한다.

참고: https://kubernetes.io/docs/reference/config-api/apiserver-audit.v1/#audit-k8s-io-v1-PolicyRule

예시2 - level: Metadata

Metadata - 요청 메타데이터(요청하는 사용자, 타임스탬프, 리소스, 동사(verb) 등)는 로깅하지만 요청/응답 본문은 로깅하지 않는다.

apiVersion: audit.k8s.io/v1
kind: Policy
rules:
  # 메타데이터 수준에서 "pods/log", "pods/status"를 기록함.
  - level: Metadata
    resources:
    - group: ""
      resources: ["pods/log", "pods/status"]
apiVersion: audit.k8s.io/v1
kind: Policy
rules:
  # 메타데이터 감사 수준(audit level)에서 다른 모든 네임스페이스의 컨피그맵과 시크릿 변경사항을 기록함.
  - level: Metadata
    resources:
    - group: "" # 핵심 API 그룹
      resources: ["secrets", "configmaps"]

메타데이터 감사 수준(audit level)에서 모든 것을 기록하기

apiVersion: audit.k8s.io/v1
kind: Policy
rules:
# 메타데이터 감사 수준(audit level)에서 모든 것을 기록하기
- level: Metadata

예시3 - level: Request

Request - 이벤트 메타데이터 및 요청 본문을 로깅하지만 응답 본문은 로깅하지 않는다. 리소스 외의 요청에는 적용되지 않는다.

apiVersion: audit.k8s.io/v1
kind: Policy
rules:
  # kube-system에 컨피그맵 변경 사항의 요청 본문을 기록함.
  - level: Request
    resources:
    - group: "" # 핵심 API 그룹
      resources: ["configmaps"]
    # 이 정책은 "kube-system" 네임스페이스의 리소스에만 적용됨.
    # 빈 문자열 "" 은 네임스페이스가 없는 리소스를 선택하는데 사용할 수 있음.
    namespaces: ["kube-system"]
apiVersion: audit.k8s.io/v1
kind: Policy
rules:
  # 요청 수준에서 코어 및 확장에 있는 다른 모든 리소스를 기록함.
  - level: Request
    resources:
    - group: "" # 핵심 API 그룹
    - group: "extensions" # 그룹의 버전을 기재하면 안 된다.

예시4 - level: RequestResponse

RequestResponse - 이벤트 메타데이터 및 요청/응답 본문을 로깅한다. 리소스 외의 요청에는 적용되지 않는다.

apiVersion: audit.k8s.io/v1
kind: Policy
rules:
  # RequestResponse 감사 수준(audit level)에서 Pod 변경사항 기록함.
  - level: RequestResponse
    resources:
    - group: ""
      # 리소스 "Pod"가 RBAC 정책과 부합하는 Pod의 하위 리소스에 대한 요청과 일치하지 않음.
      resources: ["pods"]

2단계: 기존 API server 백업하기

먼저 기존 kube-apiserver.yaml Static Pod를 백업해둔다.

# 기존 kube-apiserver.yaml Static Pod를 다른 위치에 백업해두기
cp /etc/kubernetes/manifests/kube-apiserver.yaml ~/kube-apiserver.yaml.bak

다른 위치에 백업해야 하는 이유: 동일한 디렉토리(/etc/kubernetes/manifests)에서 하면 overriding 되어서 Audit 설정이 무시된다.

3단계: API server 파일 설정하기

vim /etc/kubernetes/manifests/kube-apiserver.yaml
apiVersion: v1
kind: Pod
...
  name: kube-apiserver
  namespace: kube-system
spec:
  containers:
  - command:
# 정책  
    - kube-apiserver
    - --audit-policy-file=/etc/kubernetes/audit-policy.yaml # policy
    - --audit-log-path=/var/log/kubernetes/audit/audit.log # policy
    - --audit-log-maxsize=5 # policy
    - --audit-log-maxbackup=1                                    

...

# 볼륨 마운트 경로
volumeMounts:
  - mountPath: /etc/kubernetes/audit-policy.yaml
    name: audit
    readOnly: true
  - mountPath: /var/log/kubernetes/audit/
    name: audit-log
    readOnly: false

...

# 볼륨 hostpath
volumes:
- name: audit
  hostPath:
    path: /etc/kubernetes/audit-policy.yaml
    type: File
- name: audit-log
  hostPath:
    path: /var/log/kubernetes/audit/
    type: DirectoryOrCreate

4단계: API server를재시작하기

일반적으로 '3단계: API server 파일 설정하기' 에서 vi 편집기를 종료하면 바로 API server가 재시작된다.

재시작되는 과정은 아래 명령어를 통해 확인할 수 있다.

# 현재 컨테이너 상태 확인하기
watch crictl ps

# "api-server" 문자열이 들어간 로그 찾기
journalctl | grep api-server 

# api 문자열이 들어간 프로세스 찾기
ps aux | grep api

몇분이 지나도 API server 가 재시작하지 않으면(=kubectl 명령어가 작동하지 않는다면) 다음 방법을 시도한다.

방법1: kubeapi-server.yaml파일을 다른 위치로 이동한 후에 다시 원래 위치로 옮기기

# kubeapi-server.yaml 가 있는 디렉토리로 이동하기
cd /etc/kubernetes/manifests/

# kube-apiserver.yaml를 바로 위 디렉토리로 옮기기
mv kube-apiserver.yaml ../

# 다시 kube-apiserver.yaml를 다시 원래 있던 디렉토리로 옮기기
mv ../kube-apiserver.yaml ./

방법2: systemctl 명령어로 재시작하기

systemctl restart kubelet.service

<참고 링크>

공식 문서

https://kubernetes.io/docs/tasks/debug/debug-cluster/audit/

https://kubernetes.io/docs/reference/config-api/apiserver-audit.v1

제타위키

https://zetawiki.com/wiki/%EC%BF%A0%EB%B2%84%EB%84%A4%ED%8B%B0%EC%8A%A4_audit_log_%EC%84%A4%EC%A0%95%ED%95%98%EA%B8%B0

How to Make Changes to kube-apiserver

https://www.lullabot.com/articles/how-make-changes-kube-apiserver

crictl

https://github.com/kubernetes-sigs/cri-tools/blob/master/docs/crictl.md

토고미님 블로그

https://togomi.tistory.com/26

악분일상님 블로그

https://malwareanalysis.tistory.com/262?category=1067405