GKE 노드에서 Linux 감사 로그 사용 설정


이 페이지에서는 Container-Optimized OS를 실행하는 Google Kubernetes Engine 노드에서 자세한 운영체제 감사 로그를 사용 설정하는 방법을 설명합니다. 이 페이지에서는 Cloud Logging에 로그를 전송하도록 fluent-bit Logging 에이전트를 구성하는 방법도 설명합니다. Google에서 노드 및 기본 가상 머신(VM)을 관리하므로 GKE Autopilot 클러스터에서는 Linux auditd 로깅을 사용 설정할 수 없습니다.

운영체제 감사 로깅은 Cloud 감사 로그Kubernetes 감사 로그와는 다릅니다.

개요

노드의 운영체제 로그는 오류 메시지, 로그인 시도, 바이너리 실행과 같은 클러스터 및 워크로드 상태의 중요한 정보를 제공합니다. 이 정보를 사용하여 문제를 디버깅하거나 보안 이슈를 조사할 수 있습니다.

클러스터의 각 노드에서 로그를 수집하려면 DaemonSet를 예약할 수 있는 각 클러스터 노드에서 정확히 하나의 포드를 실행하는 DaemonSet를 사용하세요. 이 포드는 호스트의 auditd 로깅 데몬을 구성하고, Logging 또는 다른 로그 수집 서비스로 로그를 전송하도록 로깅 에이전트를 구성합니다.

기본적으로 감사는 이벤트 이후에 발생하며 사후 보안 조치입니다. auditd 로그만으로는 클러스터에서 증거를 수집하기에 충분하지 않을 수 있습니다. 전체 보안 전략의 일부로 auditd 로깅을 가장 잘 사용하는 방법을 고려하세요.

제한사항

이 페이지에서 설명하는 로깅 메커니즘은 GKE Standard 클러스터에서 Container-Optimized OS를 실행하는 노드에서만 작동합니다.

로깅 DaemonSet 작동 방식

이 섹션에서는 개발자의 필요에 맞게 구성할 수 있도록 예시 로깅 DaemonSet의 작동 방식을 설명합니다. 다음 섹션에서는 DaemonSet를 배포하는 방법을 설명합니다.

예시 매니페스트는 DaemonSet, ConfigMap과 이를 포함하는 네임스페이스를 정의합니다.

DaemonSet는 클러스터의 각 노드에 포드를 배포합니다. 포드에는 컨테이너가 2개 있습니다. 첫 번째 컨테이너는 Container-Optimized OS 노드에서 사용할 수 있는 cloud-audit-setup systemd 서비스를 시작하는 init 컨테이너입니다. 두 번째 컨테이너인 cos-auditd-fluent-bit는 노드 저널에서 Linux 감사 로그를 수집하고 Cloud Logging으로 내보내도록 구성된 fluent-bit 인스턴스를 포함합니다.

예시 로깅 DaemonSet는 다음 이벤트를 로깅합니다.

  • auditd 시스템 구성 수정
  • AppArmor 권한 검사
  • execve(), socket(), setsockopt(), mmap() 실행
  • 네트워크 연결
  • 사용자 로그인
  • SSH 세션 및 기타 모든 TTY(kubectl exec -t 세션 포함)

로깅 DaemonSet 구성

ConfigMap(cos-auditd-fluent-bit-config)을 사용하여 로깅 DaemonSet를 구성합니다. 제공된 예시는 감사 로그를 Logging으로 전송하지만 다른 대상으로 로그를 전송하도록 구성할 수 있습니다.

auditd에서 생성한 로그의 양은 매우 많을 수 있으며, 이는 시스템 리소스를 소비하고 기본 로깅 구성보다 많은 로그를 전송하므로 추가 비용이 발생할 수 있습니다. 필터를 설정하여 로깅 볼륨을 관리할 수 있습니다.

로깅 DaemonSet 배포

  1. 기존 클러스터를 사용하거나 새 클러스터를 생성할 수 있습니다.

  2. 예시 매니페스트를 다운로드합니다.

    curl https://raw.githubusercontent.com/GoogleCloudPlatform/k8s-node-tools/master/os-audit/cos-auditd-logging.yaml > cos-auditd-logging.yaml
    
  3. 예시 매니페스트를 필요에 맞게 수정합니다. DaemonSet 작동 방식에 대한 자세한 내용은 이전 섹션을 참조하세요.

  4. 공통 변수를 초기화합니다.

    export CLUSTER_NAME=CLUSTER_NAME
    export CLUSTER_LOCATION=COMPUTE_REGION
    

    다음을 바꿉니다.

    • CLUSTER_NAME: 클러스터의 이름입니다.
    • COMPUTE_REGION: 클러스터의 Compute Engine 리전입니다. 영역 클러스터의 경우 해당 영역을 대신 사용합니다.
  5. 로깅 Namespace, DaemonSet, ConfigMap을 배포합니다.

    envsubst '$CLUSTER_NAME,$CLUSTER_LOCATION' < cos-auditd-logging.yaml \
    | kubectl apply -f -
    
  6. 로깅 포드가 시작되었는지 확인합니다. 매니페스트에 다른 네임스페이스를 정의한 경우 사용 중인 네임스페이스의 이름으로 cos-auditd를 바꿉니다.

    kubectl get pods --namespace=cos-auditd
    

    포드가 실행 중이면 출력은 다음과 같습니다.

    NAME                                             READY   STATUS    RESTARTS   AGE
    cos-auditd-logging-g5sbq                         1/1     Running   0          27s
    cos-auditd-logging-l5p8m                         1/1     Running   0          27s
    cos-auditd-logging-tgwz6                         1/1     Running   0          27s
    

    클러스터의 각 노드에 하나의 포드가 배포됩니다. 이 경우 클러스터에는 노드가 3개 있습니다.

  7. 이제 Logging에서 감사 로그에 액세스할 수 있습니다. 로그 탐색기에서 다음 쿼리를 사용하여 결과를 필터링합니다.

    LOG_ID("linux-auditd")
    resource.labels.cluster_name = "CLUSTER_NAME"
    resource.labels.location = "COMPUTE_REGION"
    

    또는 gcloud CLI를 사용할 수도 있습니다. 결과 집합이 매우 클 수 있으므로 --limit를 사용합니다.

    gcloud logging read --limit=100 "LOG_ID("linux-auditd") AND resource.labels.cluster_name = "${CLUSTER_NAME}" AND resource.labels.location = "${CLUSTER_LOCATION}""
    

로그 내보내기

지원되는 대상으로 로그를 라우팅하는 방법은싱크 구성 및 관리를 참조하세요.

삭제

auditd 로깅을 사용 중지하려면 로깅 DaemonSet를 삭제하고 노드를 재부팅합니다. 감사 구성이 사용 설정되면 잠기며 노드를 다시 만들어야만 변경할 수 있습니다.

  1. 클러스터에서 DaemonSet, ConfigMap, 네임스페이스를 삭제합니다.

    kubectl delete -f cos-auditd-logging.yaml
    
  2. 클러스터의 노드를 재부팅합니다. 먼저 이러한 노드가 속한 인스턴스 그룹을 가져옵니다.

    instance_group=$(gcloud compute instance-groups managed list \
                        --format="value(name)" \
                        --filter=${CLUSTER_NAME})
    

    그런 다음 인스턴스를 직접 가져옵니다.

    instances=$(gcloud compute instance-groups managed list-instances ${instance_group} \
                   --format="csv(instance)[no-heading][terminator=',']")
    

    마지막으로 인스턴스를 다시 만듭니다.

    gcloud compute instance-groups managed recreate-instances ${instance_group} \
       --instances=${instances}
    

다음 단계