이 가이드에서는 Google Kubernetes Engine(GKE)이 컨트롤 플레인 VM에 사용하는 Compute Engine 가상 머신(VM) 이미지의 무결성을 확인하는 방법을 설명합니다. 이 가이드는 컨트롤 플레인 로그를 모니터링하고 다음을 확인하려는 보안팀을 대상으로 합니다.
- 컨트롤 플레인 VM은 보안 부트 및 무결성 모니터링을 통해 암호학적으로 검증된 정품 펌웨어 및 기타 부팅 소프트웨어로 부팅되었습니다.
- 컨트롤 플레인 VM이 정품 GKE OS 이미지에서 부팅되었습니다.
워커 노드의 OS 이미지와 부팅 무결성에 대해서도 이 확인을 수행할 수 있습니다.
이 페이지에서는 컨트롤 플레인 보안 상황을 확인하거나 관리 키를 사용하여 컨트롤 플레인에서 암호화 및 사용자 인증 정보 서명을 구성하는 등의 작업을 수행할 수 있는 GKE의 선택적 컨트롤 플레인 기능 집합 중 한 부분을 설명합니다. 자세한 내용은 GKE control plane authority 정보를 참조하세요.
기본적으로 Trusted Cloud 는 관리형 컨트롤 플레인에 다양한 보안 조치를 적용합니다. 이 페이지에서는 GKE 컨트롤 플레인을 더 잘 파악하거나 제어할 수 있는 선택적 기능을 설명합니다.
VM 무결성 확인 정보
기본적으로 모든 GKE 컨트롤 플레인 인스턴스는 보안 및 측정된 부팅, 가상 신뢰 플랫폼 모듈(vTPM), UEFI 펌웨어와 같은 보안 기능을 사용하는 강화된 VM인 보안 VM입니다. 또한 모든 GKE 노드는 기준 '양호한' 부팅 시퀀스에 대해 각 보안 VM의 부팅 시퀀스를 검증하는 무결성 모니터링을 사용 설정합니다. 이 검사에서는 각 부팅 시퀀스 단계의 통과 또는 실패 결과를 반환하고 이러한 결과를 Cloud Logging에 추가합니다. 무결성 모니터링은 모든 GKE 클러스터에서 기본적으로 사용 설정되며 다음 단계를 검증합니다.
- 초기 부팅 시퀀스: UEFI 펌웨어가 시작되어 부트로더가 제어권을 가져올 때까지입니다.
earlyBootReportEvent
로 VM 로그에 추가됩니다. - 후기 부팅 시퀀스: 부트로더에서 제어권을 가져온 시점부터 운영체제 커널이 제어권을 가져올 때까지입니다.
lateBootReportEvent
로 VM 로그에 추가됩니다.
또한 GKE는 Logging에 컨트롤 플레인 VM 생성 로그를 추가합니다. 이러한 로그에는 머신을 식별하는 메타데이터가 포함되고 VM 이미지와 부팅 시퀀스에 관한 세부정보가 포함되어 있습니다.Trusted Cloud 는 GitHub의 gke-vsa 저장소에 있는 각 GKE 컨트롤 플레인 VM 이미지에 대해 인증 요약 증명(VSA)을 게시합니다. VSA는 증명에 in-toto 프레임워크를 사용합니다. 해당 VSA에 대해 클러스터의 컨트롤 플레인 VM 로그를 검증하여 컨트롤 플레인 노드가 예상대로 부팅되었는지 확인할 수 있습니다.
이러한 검사를 수행하면 다음과 같은 목표를 달성할 수 있습니다.
- 컨트롤 플레인의 소프트웨어가 보안 부팅 및 무결성 모니터링으로 보호되고, 의도한 소스 코드와 일치하며, 다른 Trusted Cloud 고객이 사용하는 이미지와 정확히 같아야 합니다.
- GKE가 컨트롤 플레인을 보호하는 방법에 대한 신뢰도를 높입니다.
가격 책정
이 기능은 GKE에서 추가 비용 없이 제공됩니다.
시작하기 전에
시작하기 전에 다음 태스크를 수행했는지 확인합니다.
- Google Kubernetes Engine API를 사용 설정합니다. Google Kubernetes Engine API 사용 설정
- 이 태스크에 Google Cloud CLI를 사용하려면 gcloud CLI를 설치한 후 초기화하세요. 이전에 gcloud CLI를 설치한 경우
gcloud components update
를 실행하여 최신 버전을 가져옵니다.
-
Enable the Cloud Logging API.
- 버전 1.29 이상을 실행하는 GKE Autopilot 모드 또는 Standard 모드 클러스터가 이미 있는지 확인합니다.
필요한 역할
컨트롤 플레인 VM 무결성을 확인하는 데 필요한 권한을 얻으려면 관리자에게 프로젝트에 대한 다음 IAM 역할을 부여해 달라고 요청하세요.
-
클러스터 생성 및 상호작용:
Kubernetes Engine 클러스터 관리자(
roles/container.clusterAdmin
) -
로그 액세스 및 처리:
로그 뷰어(
roles/logging.viewer
)
역할 부여에 대한 자세한 내용은 프로젝트, 폴더, 조직에 대한 액세스 관리를 참조하세요.
커스텀 역할이나 다른 사전 정의된 역할을 통해 필요한 권한을 얻을 수도 있습니다.
실패한 부팅 시퀀스 단계 확인
무결성 모니터링은 컨트롤 플레인 VM이 실패하거나 부팅 시퀀스의 단계를 성공적으로 완료하는 경우 Logging에 로그를 추가합니다. 실패한 부팅 이벤트를 보려면 다음 명령어를 실행하세요.
Trusted Cloud 콘솔에서 로그 탐색기 페이지로 이동합니다.
쿼리 필드에 다음 쿼리를 지정합니다.
jsonPayload.@type="type.googleapis.com/cloud_integrity.IntegrityEvent" jsonPayload.earlyBootReportEvent.policyEvaluationPassed="false" OR jsonPayload.lateBootReportEvent.policyEvaluationPassed="false" jsonPayload.metadata.isKubernetesControlPlaneVM="true"
이 쿼리에서
false
를true
로 바꿔 부팅 성공 이벤트를 확인할 수도 있습니다.쿼리 실행을 클릭합니다. 결과가 표시되지 않으면 컨트롤 플레인 VM이 모든 무결성 모니터링 검사를 통과한 것입니다. 출력이 표시되면 다음 단계로 진행하여 해당 클러스터를 식별합니다.
실패한 부팅 무결성 로그에서
resource.labels.instance_id
필드의 값을 복사합니다.쿼리 필드에 다음 쿼리를 지정합니다.
protoPayload.@type="type.googleapis.com/google.cloud.audit.AuditLog" protoPayload.metadata.isKubernetesControlPlaneVM="true" resource.labels.instance_id="INSTANCE_ID" protoPayload.methodName="v1.compute.instances.insert"
INSTANCE_ID
를 이전 단계의instance_id
필드 값으로 바꿉니다.쿼리 실행을 클릭합니다.
protoPayload.metadata.parentResource.parentResourceId
필드 값은 GKE 클러스터 ID입니다.GKE 클러스터의 이름입니다.
gcloud asset query \ --organization=ORGANIZATION_ID \ --statement="SELECT name FROM container_googleapis_com_Cluster WHERE resource.data.id='CLUSTER_ID';"
다음을 바꿉니다.
ORGANIZATION_ID
:Trusted Cloud 조직의 숫자 IDCLUSTER_ID
: 이전 단계의protoPayload.metadata.parentResource.parentResourceId
필드 값
출력은 다음과 비슷합니다.
# lines omitted for clarity //container.googleapis.com/projects/PROJECT_ID/locations/LOCATION/clusters/CLUSTER_NAME
이 출력에는 다음 필드가 있습니다.
PROJECT_ID
: Trusted Cloud 프로젝트 ID입니다.LOCATION
: 클러스터의 위치입니다.CLUSTER_NAME
: 클러스터의 이름입니다.
컨트롤 플레인 VM 로그 찾기 및 검사
GKE 클러스터에 해당하는 Compute Engine VM 생성 로그는 _Default
로그 버킷에 저장됩니다.
클러스터 컨트롤 플레인 VM의 생성 로그를 찾고 이 메타데이터를 검색하려면 다음을 수행하세요.
Trusted Cloud 콘솔에서 로그 탐색기 페이지로 이동합니다.
쿼리 필드에 다음 쿼리를 지정합니다.
resource.type="gce_instance" protoPayload.methodName="v1.compute.instances.insert" protoPayload.metadata.isKubernetesControlPlaneVM="true"
쿼리 실행을 클릭합니다. 결과가 표시되지 않으면 시작하기 전에 섹션의 모든 요구사항을 충족하는지 확인하세요.
쿼리 결과에서
metadata
필드를 확인합니다. 출력은 다음과 비슷합니다.# fields omitted for clarity "metadata": { "usedResources": { "attachedDisks": [ { "sourceImageId": "9046093115864736653", "sourceImage": "https://www.googleapis.com/compute/v1/projects/1234567890/global/images/gke-1302-gke1627000-cos-113-18244-85-49-c-pre", "isBootDisk": true } # fields omitted for clarity
metadata
필드에는 다음 정보가 포함됩니다.usedResources
: VM을 만드는 데 사용된 리소스 목록입니다.attachedDisks
: VM의 부팅 디스크입니다.sourceImageId
: VM 이미지의 고유 ID입니다.sourceImage
: 소스 VM 이미지의 URL입니다. 이 필드의 값 구문은https://www.googleapis.com/compute/v1/projects/PROJECT_NUMBER/global/images/IMAGE_NAME
입니다. 여기서PROJECT_NUMBER
는 컨트롤 플레인 VM을 호스팅하는Trusted Cloud소유 프로젝트의 수이고IMAGE_NAME
은 VM을 부팅하는 데 사용된 이미지의 이름입니다.isBootDisk
: 이 디스크가 VM의 부팅 디스크로 사용되었는지 여부를 나타내는 불리언 식별자입니다.
컨트롤 플레인 VM 이미지의 VSA 찾기 및 확인
이 섹션에서는 GitHub의 gke-vsa 저장소에서 컨트롤 플레인 VM 이미지에 해당하는 VSA를 찾습니다. 그런 다음 소프트웨어 아티팩트에 대한 공급망 등급(SLSA) 프레임워크에서 제공하는 slsa-verifier
라는 도구를 사용하여 VSA를 확인합니다. 컨트롤 플레인 VM 생성 로그에서 다음 데이터가 필요합니다.
- VM 이미지 ID
- VM을 호스팅하는 Trusted Cloud소유 프로젝트의 프로젝트 번호
- VM을 부팅하는 데 사용된 OS 이미지 이름
컨트롤 플레인 VM에 해당하는 파일의 파일 이름 형식은 다음과 같습니다.
IMAGE_NAME:IMAGE_ID.intoto.jsonl
다음을 바꿉니다.
IMAGE_NAME
: VM 이미지 이름으로, 이전 섹션의 VM 감사 로그에 있는attachedDisks.sourceImage
필드의/images/
뒤에 오는 문자열입니다. 예를 들면gke-1302-gke1627000-cos-113-18244-85-49-c-pre
입니다.IMAGE_ID
: VM 이미지 ID로, 이전 섹션의 VM 감사 로그에 있는attachedDisks.sourceImageId
필드의 값입니다. 예를 들면9046093115864736653
입니다.
VSA 파일의 파일 이름을 아는 경우 VSA를 찾아 확인하려면 다음 단계를 따르세요.
gke-vsa
GitHub 저장소를 엽니다.- 'gke-master-images' 디렉터리에서 VM 이미지에 해당하는 파일을 찾습니다. 예를 들면
https://github.com/GoogleCloudPlatform/gke-vsa/blob/main/gke-master-images:78064567238/IMAGE_NAME:IMAGE_ID.intoto.jsonl
입니다. - VSA 파일을 다운로드합니다.
slsa-verifier
도구를 설치합니다.VSA 확인을 위한 공개 키를
vsa_signing_public_key
라는 파일에 저장합니다.다음과 같이 VSA를 확인합니다.
slsa-verifier verify-vsa \ --attestation-path=PATH_TO_VSA_FILE \ --resource-uri=gce_image://gke-master-images:IMAGE_NAME \ --subject-digest=gce_image_id:IMAGE_ID\ --verifier-id=https://bcid.corp.google.com/verifier/bcid_package_enforcer/v0.1 \ --verified-level=BCID_L1 \ --verified-level=SLSA_BUILD_LEVEL_2 \ --public-key-path=PATH_TO_PUBLIC_KEY_FILE \ --public-key-id=keystore://76574:prod:vsa_signing_public_key
다음을 바꿉니다.
PATH_TO_VSA_FILE
: 다운로드한 VSA 파일의 경로입니다.IMAGE_NAME
: VM 이미지의 이름입니다(예:gke-1302-gke1627000-cos-113-18244-85-49-c-pre
).IMAGE_ID
: VM 이미지 ID입니다(예:9046093115864736653
).
VSA가 확인 검사를 통과하면 출력은 다음과 같습니다.
Verifying VSA: PASSED PASSED: SLSA verification passed