전공영역 공부 기록

CKS 3편 클러스터 보안 - audit

악분 2022. 2. 2. 16:09
반응형

 

안녕하세요. CKS자격증을 공부했던 내용을 정리한 시리즈입니다.

2편에서는 공부하면서 참고했던 자료를 소개합니다.

 

1. audit 개요

audit은 누가, 언제, 무엇을, 어떻게 등 쿠버네티스 활동을 감시하고 파일로 저장하는 기능입니다.

 

2. audit 정책(Policy)

감시하는 활동은 4가지 타입입니다.

  • RequestReceived: 요청RequestReceived
  • ResponseStarted: 응답 헤더 전달(요청 수신 응답)
  • ResponseComplete: 완료 응답 전달
  • Panic: 오류

 

쿠버네티스는 특정 활동만 필터링하여 저장할 수 있도록 필터기능을 제공합니다. 필터기능을 audit 정책이라고 합니다.관리자는 yaml포맷으로 특정 활동을 필터링할 수 있습니다.

 

정책은 yaml포맷으로 정의됩니다.

apiVersion: audit.k8s.io/v1 # This is required.
kind: Policy
# Don't generate audit events for all requests in RequestReceived stage.
omitStages:
  - "RequestReceived"
rules:
  # Log pod changes at RequestResponse level
  - level: RequestResponse
    resources:
    - group: ""
      # Resource "pods" doesn't match requests to any subresource of pods,
      # which is consistent with the RBAC policy.
      resources: ["pods"]
  # Log "pods/log", "pods/status" at Metadata level
  - level: Metadata
    resources:
    - group: ""
      resources: ["pods/log", "pods/status"]

 

3. audit 활성화 방법

audit은 디폴트로 비활성화 되어 있습니다. kube-apiserver static pod에서 audit인자를 설정하여 auidt을 활성화 활수 있습니다. 설정해야 하는 인자는 공식문서(https://kubernetes.io/docs/tasks/debug-application-cluster/audit/#log-backend)에서 설명되어 있습니다.

vi /etc/kubernetes/manifests/kube-apiserver.yaml

 

주의할 점은 --audit-policy인자에 해당하는 정책파일 설정을 위해 마운트(volumes, volumemount필드) 설정이 필요합니다. 마운트 설정이 되지 않으면 존재하지 않는 파일 에러가 발생하여 kube-apiserver pod가 실행되지 않습니다. 마운트 설정은 공식문서에 친절히 설명되어 있습니다.

 

4. audit 정책 적용 실습

공식문서(https://kubernetes.io/docs/tasks/debug-application-cluster/audit/#audit-policy)에 있는 예제 정책을 사용했습니다.

 

정책파일을 audit-policy.yaml파일로 저장합니다.

vi /etc/kubernetes/audit/audit-policy.yaml
apiVersion: audit.k8s.io/v1 # This is required.
kind: Policy
# Don't generate audit events for all requests in RequestReceived stage.
omitStages:
  - "RequestReceived"
rules:
  # Log pod changes at RequestResponse level
  - level: RequestResponse
    resources:
    - group: ""
      # Resource "pods" doesn't match requests to any subresource of pods,
      # which is consistent with the RBAC policy.
      resources: ["pods"]
  # Log "pods/log", "pods/status" at Metadata level
  - level: Metadata
    resources:
    - group: ""
      resources: ["pods/log", "pods/status"]

  # Don't log requests to a configmap called "controller-leader"
  - level: None
    resources:
    - group: ""
      resources: ["configmaps"]
      resourceNames: ["controller-leader"]

  # Don't log watch requests by the "system:kube-proxy" on endpoints or services
  - level: None
    users: ["system:kube-proxy"]
    verbs: ["watch"]
    resources:
    - group: "" # core API group
      resources: ["endpoints", "services"]

  # Don't log authenticated requests to certain non-resource URL paths.
  - level: None
    userGroups: ["system:authenticated"]
    nonResourceURLs:
    - "/api*" # Wildcard matching.
    - "/version"

  # Log the request body of configmap changes in kube-system.
  - level: Request
    resources:
    - group: "" # core API group
      resources: ["configmaps"]
    # This rule only applies to resources in the "kube-system" namespace.
    # The empty string "" can be used to select non-namespaced resources.
    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"]

  # Log all other resources in core and extensions at the Request level.
  - level: Request
    resources:
    - group: "" # core API group
    - group: "extensions" # Version of group should NOT be included.

  # A catch-all rule to log all other requests at the Metadata level.
  - level: Metadata
    # Long-running requests like watches that fall under this rule will not
    # generate an audit event in RequestReceived.
    omitStages:
      - "RequestReceived"

 

api-server static pod설정을 백업합니다.

 cp /etc/kubernetes/manifests/kube-apiserver.yaml ~/kube-apiserver.yaml.bak

 

그리고, api-server파일을 설정합니다. 마운트 설정이 꼭 필요합니다.

 vi /etc/kubernetes/manifests/kube-apiserver.yaml
 
 ...
 spec:
  containers:
      - command:
        - kube-apiserver
        - --audit-policy-file=/etc/kubernetes/audit-policy.yaml
        - --audit-log-path=/var/log/kubernetes/audit/audit.log
        - --audit-log-maxage=5
        - --audit-log-maxbackup=1
        - --audit-log-maxsize=1024
        ...
        volumeMounts:
          - mountPath: /etc/kubernetes/audit-policy.yaml
            name: audit
            readOnly: true
          - mountPath: /var/log/kubernetes/audit/
            name: audit-log
            readOnly: false
        ...
    ...
    volumes:
    - name: audit
      hostPath:
        path: /etc/kubernetes/audit-policy.yaml
        type: File
    - name: audit-log
      hostPath:
        path: /var/log/kubernetes/audit/
        type: DirectoryOrCreate
    ...

 

vi에디터를 닫으면 kube-apiserver pod가 재실행됩니다. 리눅스 프로세스 명령어로 확인하거나 kubectl 명령어가 잘 실행되는 방법으로 확인할 수 있습니다. 만약 약 5분이 지나도 프로세스가 없거나 kubectl명령어가 없다면, 설정이 잘못된것니다. crictl를 이용하여 컨테이너레벨 로그 분석이 필요합니다.

ps aux | grep api

 

volumes에 설정한 경로로 이동하면 audit.log파일이 보입니다. jq명령어로 예쁘게 출력하면 아래와 같은 결과를 얻을 수 있습니다.

head -1 /var/log/kubernetes/audit/audit.log | jq

 

5. CKS 팁

CKS에서는 어렵게 출제되지 않고 단순히 정책을 활성화하는 문제가 출제됩니다.

 

5.1 백업파일 위치

kube-apiserver.yaml 백업파일 위치는 /etc/kubernetes/manifests디렉터리에서 하면 안됩니다. 오버라이딩되어서 audit설정이 무시됩니다. /tmp 등 다른 위치에 백업하세요!

 

5.2 api-server 설정 수정 후 강제 로딩

kubeapi-server.yaml파일이 수정되면 자동으로 api-server pod가 자동으로 실행됩니다. 하지만, 재실행 안되는 경우도 있어? kubeapi-server.yaml파일을 다른위치로 이동한 후에 다시 원래 위치로 옮기는 것을 추천합니다.

cd /etc/kubernetes/manifests/
mv kube-apiserver.yaml ../
mv ../kube-apiserver.yaml ./

 

참고자료

[1] [공식문서] audit문서: https://kubernetes.io/docs/tasks/debug-application-cluster/audit/

 

반응형