클러스터 메타데이터 보호

개요

GKE는 인스턴스 메타데이터를 사용하여 노드 VM을 구성하지만, 이 메타데이터 중 일부는 잠재적으로 민감한 데이터를 포함하며, 클러스터에서 실행되는 작업 부하로부터 보호되어야 합니다.

시작하기 전에

이 작업을 준비하려면 다음 단계를 수행하세요.

  • Google Kubernetes Engine API가 사용 설정되었는지 확인합니다.
  • Google Kubernetes Engine API 사용 설정
  • Cloud SDK가 설치되었는지 확인합니다.
  • 기본 프로젝트 ID를 설정합니다.
    gcloud config set project [PROJECT_ID]
  • 영역 클러스터를 사용하는 경우 기본 컴퓨팅 영역을 설정합니다.
    gcloud config set compute/zone [COMPUTE_ZONE]
  • 지역 클러스터를 사용하는 경우 기본 컴퓨팅 지역을 설정합니다.
    gcloud config set compute/region [COMPUTE_REGION]
  • gcloud를 최신 버전으로 업데이트합니다.
    gcloud components update

노드 서비스 계정 구성

각 노드의 서비스 계정 사용자 인증 정보가 작업 부하에 계속 노출되기 때문에, 필요한 최소 권한으로 서비스 계정을 구성했는지 확인해야 합니다. 그런 후 서비스 계정을 노드에 연결하여, 공격자가 Compute Engine API를 사용해서 노드 인스턴스에 직접 액세스하여 GKE의 메타데이터 보호를 우회할 수 없도록 해야 합니다.

compute.instances.get 권한, 컴퓨팅 인스턴스 관리자 역할 또는 기타 유사한 권한이 있는 서비스 계정은 사용하지 마세요. 이러한 계정을 사용하면 공격자가 Compute Engine API를 사용해서 인스턴스 메타데이터를 획득할 수 있습니다. 권장사항은 액세스 범위가 아니라 서비스 계정 권한을 사용해서 노드 VM의 권한을 제한하는 것입니다. 자세한 내용은 Compute Engine의 서비스 계정 문서를 참조하세요.

gcloud

노드 서비스 계정이 없으면 다음 명령어를 사용해서 만들 수 있습니다.

export NODE_SA_NAME=gke-node-sa
gcloud iam service-accounts create $NODE_SA_NAME \
  --display-name "Node Service Account"
export NODE_SA_EMAIL=$(gcloud iam service-accounts list --format='value(email)' \
  --filter='displayName:Node Service Account')

필요한 역할 및 권한으로 서비스 계정을 구성하려면 다음 명령어를 실행하세요. PROJECT프로젝트 ID입니다.

export PROJECT=$(gcloud config get-value project)

gcloud projects add-iam-policy-binding $PROJECT \
  --member serviceAccount:$NODE_SA_EMAIL \
  --role roles/monitoring.metricWriter
gcloud projects add-iam-policy-binding $PROJECT \
  --member serviceAccount:$NODE_SA_EMAIL \
  --role roles/monitoring.viewer
gcloud projects add-iam-policy-binding $PROJECT \
  --member serviceAccount:$NODE_SA_EMAIL \
  --role roles/logging.logWriter

또한 클러스터가 Container Registry에서 비공개 이미지를 가져올 경우, storage.objectViewer 역할을 추가합니다.

gcloud projects add-iam-policy-binding $PROJECT \
  --member serviceAccount:$NODE_SA_EMAIL \
  --role roles/storage.objectViewer

이전 메타데이터 API 사용 중지

Compute Engine의 인스턴스 메타데이터 서버는 메타데이터 쿼리 헤더를 적용하지 않는 이전 /0.1//v1beta1/ 엔드포인트를 노출합니다. 이 기능은 잠재적인 공격자가 인스턴스 메타데이터를 검색하기 어렵게 만드는 /v1/ API의 기능입니다. 특별히 필요하지 않은 한 이러한 이전 API를 사용 중지하는 것이 좋습니다.

이전 메타데이터 API가 사용 중지된 상태로 새 노드 풀 만들기

서비스 계정을 만든 후에는 gcloud 명령줄 도구를 사용해서 이전 메타데이터 API가 사용 중지된 상태로 새 노드 풀(또는 새 클러스터의 기본 노드 풀)을 만들 수 있습니다.

gcloud

이전 메타데이터 API가 사용 중지된 상태로 새 노드 풀을 만들려면 --metadata disable-legacy-endpoints=true 플래그를 사용합니다. 예를 들면 다음과 같습니다.

gcloud container node-pools create [POOL_NAME] \
  --service-account=$NODE_SA_EMAIL \
  --metadata disable-legacy-endpoints=true

동일한 플래그를 사용해서 기본 노드 풀에 이전 메타데이터 API가 사용 중지된 상태로 새 클러스터를 만들 수 있습니다. 예를 들면 다음과 같습니다.

gcloud container clusters create [CLUSTER_NAME] \
  --service-account=$NODE_SA_EMAIL \
  --metadata disable-legacy-endpoints=true

이전 메타데이터 API를 사용 중지하도록 기존 클러스터 업데이트

이전 메타데이터 API가 사용 중지된 상태로 새 노드 풀을 만든 후에는 노드 풀 이전 가이드에 따라 이를 사용하도록 기존 클러스터를 업데이트할 수 있습니다.

이전 메타데이터 API가 사용 중지되었는지 확인

이전 인스턴스 메타데이터 API가 사용 중지되었을 때 /0.1//v1beta1/ 메타데이터 서버 엔드포인트를 요청하면 403 Forbidden이 반환됩니다.

이전 메타데이터 API가 사용 중지되었는지 확인하려면 포드 내에서 curl 명령어를 실행하면 됩니다.

cURL

root@pod-name# curl -H 'Metadata-Flavor: Google' \
'http://metadata.google.internal/computeMetadata/v1/instance/attributes/disable-legacy-endpoints'
true
root@pod-name# curl 'http://metadata.google.internal/computeMetadata/v1beta1/instance/id'
... Error 403 (Forbidden) ... Legacy metadata endpoint accessed: /computeMetadata/v1beta1/instance/id Legacy metadata endpoints are disabled. Please use the /v1/ endpoint. ...

메타데이터 숨김

GKE의 메타데이터 숨김은 클러스터에서 실행되는 사용자 작업 부하에서 잠재적으로 민감한 시스템 메타데이터를 보호합니다.

Kubernetes v1.9.3 이상에서는 메타데이터 숨김을 사용 설정하여 사용자 포드가 Kubelet 사용자 인증 정보 및 VM 인스턴스 정보와 같은 클러스터 노드에 대한 특정 VM 메타데이터에 액세스하는 것을 방지할 수 있습니다. 특히 메타데이터 숨김은 kube-env(Kubelet 사용자 인증 정보 포함) 및 VM의 인스턴스 ID 토큰에 대한 액세스를 보호합니다.

메타데이터 숨김은 사용자 포드(HostNetwork에서 실행되지 않는 포드)에서 클러스터 메타데이터 서버로의 트래픽을 방화벽으로 차단하고, 안전한 쿼리만 허용합니다. 이 방화벽은 사용자 포드의 권한 승격 공격을 위한 Kubelet 사용자 인증 정보 사용 또는 인스턴스 승격 공격을 위한 VM ID 사용을 방해합니다.

제한사항

  • 메타데이터 숨김은 kube-env 및 노드의 인스턴스 ID 토큰에 대한 액세스만 보호합니다.
  • 메타데이터 숨김은 노드의 서비스 계정에 대한 액세스를 제한하지 않습니다.
  • 메타데이터 숨김은 다른 관련 인스턴스 메타데이터에 대한 액세스를 제한하지 않습니다.
  • 메타데이터 숨김은 다른 이전 메타데이터 API에 대한 액세스를 제한하지 않습니다.

메타데이터 숨김으로 새 클러스터 또는 노드 풀 만들기

서비스 계정을 만든 후에는 gcloud 명령줄 도구를 사용해서 메타데이터 숨김이 사용 설정된 상태로 새 클러스터를 만들 수 있습니다.

gcloud

To create a cluster with metadata concealment enabled, run the following
command in your shell or terminal window:

gcloud beta container clusters create [CLUSTER_NAME] \
  --workload-metadata-from-node=SECURE \
  --service-account=$NODE_SA_EMAIL \
  --metadata disable-legacy-endpoints=true \
  --cluster-version=1.9
  [additional parameters and flags omitted]

각 항목의 의미는 다음과 같습니다.

  • [CLUSTER_NAME]은 생성할 클러스터의 이름입니다.
  • --workload-metadata-from-nodeSECURE로 설정됩니다. 플래그를 EXPOSED 또는 UNSPECIFIED로 설정하면 메타데이터 숨김이 사용 중지됩니다.

클러스터 작업 부하에서 숨겨진 ID 토큰 메타데이터 확인

메타데이터를 숨길 때는 노드의 인스턴스 ID 토큰을 통해 서명을 요청할 수 없습니다. 해당 요청이 숨겨진 메타데이터를 사용자에게 명시적으로 알리는지 확인하려면 포드 내에서 curl 명령어를 실행하면 됩니다.

cURL

root@pod-name# curl -H "Metadata-Flavor: Google" \
'http://metadata/computeMetadata/v1/instance/service-accounts/default/identity?audience=https://www.example.com'
This metadata endpoint is concealed.
이 페이지가 도움이 되었나요? 평가를 부탁드립니다.

다음에 대한 의견 보내기...

Kubernetes Engine