실습 설정 안내 및 요구사항
계정과 진행 상황을 보호하세요. 이 실습을 실행하려면 항상 시크릿 브라우저 창과 실습 사용자 인증 정보를 사용하세요.

Binary Authorization으로 배포 통제

실습 35분 universal_currency_alt 크레딧 5개 show_chart 중급
info 이 실습에는 학습을 지원하는 AI 도구가 통합되어 있을 수 있습니다.
이 콘텐츠는 아직 휴대기기에 최적화되지 않음
최상의 경험을 위해 데스크톱 컴퓨터에서 이메일로 전송된 링크를 사용하여 방문하세요.

GSP1183

Google Cloud 사용자 주도형 실습

개요

Binary Authorization은 배포 시점의 보안 제어를 제공하여 Google Kubernetes Engine(GKE) 또는 Cloud Run에 신뢰할 수 있는 컨테이너 이미지만 배포되도록 합니다. Binary Authorization을 사용하면 개발 프로세스 중에 신뢰할 수 있는 기관으로부터 이미지에 서명을 받도록 요구하고 이후 배포 시 서명 검증을 실시할 수 있습니다. 검증을 시행하면 확인된 이미지만 빌드 및 배포 프로세스에 통합되어 컨테이너 환경을 보다 확실하게 제어할 수 있습니다.

다음 다이어그램은 Binary Authorization/Cloud Build 설정에 사용되는 구성요소를 보여줍니다.

Cloud Build Binary Authorization 증명 파이프라인Binary Authorization 증명을 만드는 Cloud Build 파이프라인

이 파이프라인에 대한 설명은 다음과 같습니다.

  1. 컨테이너 이미지를 빌드하는 코드가 Cloud Source Repositories와 같은 소스 저장소로 푸시됩니다.
  2. 지속적 통합(CI) 도구인 Cloud Build가 컨테이너를 빌드하고 테스트합니다.
  3. 이 빌드는 컨테이너 이미지를 Container Registry 또는 빌드된 이미지를 저장하는 다른 레지스트리로 푸시합니다.
  4. 암호화 키 쌍용 키 관리를 제공하는 Cloud Key Management Service가 컨테이너 이미지에 서명합니다. 그러면 결과 서명이 새로 생성된 증명에 저장됩니다.
  5. 배포 시 증명자가 키 쌍의 공개 키를 사용하여 증명을 확인합니다. Binary Authorization에서 서명된 증명에 컨테이너 이미지를 배포하도록 요구하여 정책을 적용합니다.

이 실습에서는 배포된 아티팩트를 보호하는 도구와 기법을 알아봅니다. 이 실습에서는 생성되었지만 특정 환경에 배포되지 않은 아티팩트(컨테이너)에 중점을 둡니다.

학습할 내용

  • 이미지 서명
  • 어드미션 컨트롤 정책
  • 스캔된 이미지 서명
  • 서명된 이미지 승인
  • 서명되지 않은 이미지 차단

설정 및 요건

실습 시작 버튼을 클릭하기 전에

다음 안내를 확인하세요. 실습에는 시간 제한이 있으며 일시중지할 수 없습니다. 실습 시작을 클릭하면 타이머가 시작됩니다. 이 타이머는 Google Cloud 리소스를 사용할 수 있는 시간이 얼마나 남았는지를 표시합니다.

실무형 실습을 통해 시뮬레이션이나 데모 환경이 아닌 실제 클라우드 환경에서 직접 실습 활동을 진행할 수 있습니다. 실습 시간 동안 Google Cloud에 로그인하고 액세스하는 데 사용할 수 있는 새로운 임시 사용자 인증 정보가 제공됩니다.

이 실습을 완료하려면 다음을 준비해야 합니다.

  • 표준 인터넷 브라우저 액세스 권한(Chrome 브라우저 권장)
참고: 이 실습을 실행하려면 시크릿 모드 또는 시크릿 브라우저 창을 사용하세요. 개인 계정과 학습자 계정 간의 충돌로 개인 계정에 추가 요금이 발생하는 일을 방지해 줍니다.
  • 실습을 완료하기에 충분한 시간(실습을 시작하고 나면 일시중지할 수 없음)
참고: 계정에 추가 요금이 발생하지 않도록 하려면 개인용 Google Cloud 계정이나 프로젝트가 이미 있어도 이 실습에서는 사용하지 마세요.

실습을 시작하고 Google Cloud 콘솔에 로그인하는 방법

  1. 실습 시작 버튼을 클릭합니다. 실습 비용을 결제해야 하는 경우 결제 수단을 선택할 수 있는 팝업이 열립니다. 왼쪽에는 다음과 같은 항목이 포함된 실습 세부정보 패널이 있습니다.

    • Google Cloud 콘솔 열기 버튼
    • 남은 시간
    • 이 실습에 사용해야 하는 임시 사용자 인증 정보
    • 필요한 경우 실습 진행을 위한 기타 정보
  2. Google Cloud 콘솔 열기를 클릭합니다(Chrome 브라우저를 실행 중인 경우 마우스 오른쪽 버튼으로 클릭하고 시크릿 창에서 링크 열기를 선택합니다).

    실습에서 리소스가 가동되면 다른 탭이 열리고 로그인 페이지가 표시됩니다.

    팁: 두 개의 탭을 각각 별도의 창으로 나란히 정렬하세요.

    참고: 계정 선택 대화상자가 표시되면 다른 계정 사용을 클릭합니다.
  3. 필요한 경우 아래의 사용자 이름을 복사하여 로그인 대화상자에 붙여넣습니다.

    {{{user_0.username | "Username"}}}

    실습 세부정보 패널에서도 사용자 이름을 확인할 수 있습니다.

  4. 다음을 클릭합니다.

  5. 아래의 비밀번호를 복사하여 시작하기 대화상자에 붙여넣습니다.

    {{{user_0.password | "Password"}}}

    실습 세부정보 패널에서도 비밀번호를 확인할 수 있습니다.

  6. 다음을 클릭합니다.

    중요: 실습에서 제공하는 사용자 인증 정보를 사용해야 합니다. Google Cloud 계정 사용자 인증 정보를 사용하지 마세요. 참고: 이 실습에 자신의 Google Cloud 계정을 사용하면 추가 요금이 발생할 수 있습니다.
  7. 이후에 표시되는 페이지를 클릭하여 넘깁니다.

    • 이용약관에 동의하세요.
    • 임시 계정이므로 복구 옵션이나 2단계 인증을 추가하지 마세요.
    • 무료 체험판을 신청하지 마세요.

잠시 후 Google Cloud 콘솔이 이 탭에서 열립니다.

참고: Google Cloud 제품 및 서비스 목록이 있는 메뉴를 보려면 왼쪽 상단의 탐색 메뉴를 클릭합니다. 탐색 메뉴 아이콘

Cloud Shell 활성화

Cloud Shell은 다양한 개발 도구가 탑재된 가상 머신으로, 5GB의 영구 홈 디렉터리를 제공하며 Google Cloud에서 실행됩니다. Cloud Shell을 사용하면 명령줄을 통해 Google Cloud 리소스에 액세스할 수 있습니다.

  1. Google Cloud 콘솔 상단에서 Cloud Shell 활성화 Cloud Shell 활성화 아이콘를 클릭합니다.

연결되면 사용자 인증이 이미 처리된 것이며 프로젝트가 학습자의 PROJECT_ID, (으)로 설정됩니다. 출력에 이 세션의 PROJECT_ID를 선언하는 줄이 포함됩니다.

Your Cloud Platform project in this session is set to {{{project_0.project_id | "PROJECT_ID"}}}

gcloud는 Google Cloud의 명령줄 도구입니다. Cloud Shell에 사전 설치되어 있으며 명령줄 자동 완성을 지원합니다.

  1. (선택사항) 다음 명령어를 사용하여 활성 계정 이름 목록을 표시할 수 있습니다.
gcloud auth list
  1. 승인을 클릭합니다.

출력:

ACTIVE: * ACCOUNT: {{{user_0.username | "ACCOUNT"}}} To set the active account, run: $ gcloud config set account `ACCOUNT`
  1. (선택사항) 다음 명령어를 사용하여 프로젝트 ID 목록을 표시할 수 있습니다.
gcloud config list project

출력:

[core] project = {{{project_0.project_id | "PROJECT_ID"}}} 참고: gcloud 전체 문서는 Google Cloud에서 gcloud CLI 개요 가이드를 참고하세요.

환경 설정

Cloud Shell에서 프로젝트 ID와 프로젝트의 프로젝트 번호를 설정합니다. PROJECT_IDPROJECT_NUMBER 변수로 저장합니다.

export PROJECT_ID=$(gcloud config get-value project) export PROJECT_NUMBER=$(gcloud projects describe $PROJECT_ID \ --format='value(projectNumber)')

서비스 사용 설정

필요한 모든 서비스를 사용 설정합니다.

gcloud services enable \ cloudkms.googleapis.com \ cloudbuild.googleapis.com \ container.googleapis.com \ containerregistry.googleapis.com \ artifactregistry.googleapis.com \ containerscanning.googleapis.com \ ondemandscanning.googleapis.com \ binaryauthorization.googleapis.com

작업 1. Artifact Registry 저장소 만들기

이 실습에서는 Artifact Registry를 사용하여 이미지를 저장하고 스캔합니다.

  1. 다음 명령어를 사용하여 저장소를 만듭니다.
gcloud artifacts repositories create artifact-scanning-repo \ --repository-format=docker \ --location={{{ project_0.default_region | "REGION" }}} \ --description="Docker repository"
  1. Artifact Registry에 액세스할 때 gcloud 사용자 인증 정보를 활용하도록 Docker를 구성합니다.
gcloud auth configure-docker {{{ project_0.default_region | "REGION" }}}-docker.pkg.dev
  1. 작업 디렉터리를 만들고 해당 디렉터리로 변경합니다.
mkdir vuln-scan && cd vuln-scan
  1. 다음으로 샘플 이미지를 정의합니다. 다음 콘텐츠로 Dockerfile이라는 파일을 만듭니다.
cat > ./Dockerfile << EOF FROM python:3.8-alpine # App WORKDIR /app COPY . ./ RUN pip3 install Flask==2.1.0 RUN pip3 install gunicorn==20.1.0 RUN pip3 install Werkzeug==2.2.2 CMD exec gunicorn --bind :\$PORT --workers 1 --threads 8 main:app EOF
  1. 다음 콘텐츠로 main.py라는 파일을 만듭니다.
cat > ./main.py << EOF import os from flask import Flask app = Flask(__name__) @app.route("/") def hello_world(): name = os.environ.get("NAME", "Worlds") return "Hello {}!".format(name) if __name__ == "__main__": app.run(debug=True, host="0.0.0.0", port=int(os.environ.get("PORT", 8080))) EOF
  1. Cloud Build를 사용하여 컨테이너를 빌드하고 Artifact Registry에 자동으로 푸시합니다.
gcloud builds submit . -t {{{ project_0.default_region | "REGION" }}}-docker.pkg.dev/${PROJECT_ID}/artifact-scanning-repo/sample-image

내 진행 상황 확인하기를 클릭하여 목표를 확인합니다. Artifact Registry 저장소를 만듭니다.

작업 2. 이미지 서명

증명자란 무엇인가요?

  • 증명자는 시스템의 신뢰 체인에서 하나의 링크를 담당하는 사람 또는 프로세스로서
  • 암호화 키를 보유하고 승인 절차를 통과한 이미지에 서명합니다.
  • 정책 생성자는 추상적인 방식으로 상위 수준에서 정책을 결정하는 반면 증명자는 정책의 일부 측면을 구체적으로 시행합니다.
  • 증명자는 QA 테스터나 관리자와 같은 실제 사람일 수도 있고 CI 시스템의 봇일 수도 있습니다.
  • 시스템의 보안은 신뢰성에 따라 달라지므로 비공개 키를 안전하게 보관하는 것이 중요합니다.

각 역할은 조직의 개인 또는 팀을 나타낼 수 있습니다. 프로덕션 환경에서는 이러한 역할이 별도의 Google Cloud Platform 프로젝트에서 관리되고 리소스에 대한 액세스 권한이 Cloud IAM을 사용하여 제한된 방식으로 공유될 것입니다.

증명자 계층 구조 작동 방식

Binary Authorization의 증명자는 Cloud Container Analysis API를 기반으로 구현되므로 계속하기 전에 작동 방식을 설명하는 것이 중요합니다. Container Analysis API는 메타데이터를 특정 컨테이너 이미지와 연결할 수 있도록 설계되었습니다.

예를 들어 Heartbleed 취약점을 추적하기 위해 노트를 만들 수 있습니다. 그러면 보안 공급업체는 컨테이너 이미지에서 취약점을 테스트하는 스캐너를 만들고 손상된 각 컨테이너와 연결된 발생 항목을 만듭니다.

208aa5ebc53ff2b3.png

취약점 추적과 함께 컨테이너 분석은 일반 메타데이터 API로 설계되었습니다. Binary Authorization은 컨테이너 분석을 활용하여 확인 중인 컨테이너 이미지와 서명을 연결합니다. 컨테이너 분석 노트는 단일 증명자를 대표하는 데 사용되며, 발생 항목은 증명자가 승인한 각 컨테이너에 대해 생성되고 연결됩니다.

Binary Authorization API는 '증명자' 및 '증명' 개념을 사용하지만 이러한 개념은 Container Analysis API에서 해당 노트 및 발생 항목을 사용하여 구현됩니다.

컨테이너 분석 플로우 차트

증명자 노트 만들기

증명자 노트는 적용되는 서명 유형의 라벨 역할을 하는 작은 데이터입니다. 예를 들어 한 노트는 취약점 검사를 나타내고 다른 노트는 QA 승인에 사용될 수 있습니다. 노트는 서명 프로세스 중에 참조됩니다.

Container Analysis API 및 Binary Authorization 관계 플로우 차트
  1. 노트를 만듭니다.
cat > ./vulnz_note.json << EOM { "attestation": { "hint": { "human_readable_name": "Container Vulnerabilities attestation authority" } } } EOM
  1. 노트를 저장합니다.
NOTE_ID=vulnz_note curl -vvv -X POST \ -H "Content-Type: application/json" \ -H "Authorization: Bearer $(gcloud auth print-access-token)" \ --data-binary @./vulnz_note.json \ "https://containeranalysis.googleapis.com/v1/projects/${PROJECT_ID}/notes/?noteId=${NOTE_ID}"
  1. 노트를 검증합니다.
curl -vvv \ -H "Authorization: Bearer $(gcloud auth print-access-token)" \ "https://containeranalysis.googleapis.com/v1/projects/${PROJECT_ID}/notes/${NOTE_ID}"

이제 노트가 Container Analysis API 내에 저장됩니다.

  1. 증명자를 만듭니다.

증명자는 실제 이미지 서명 프로세스를 실행하는 데 사용되며 나중에 확인할 수 있도록 노트의 발생 항목을 이미지에 연결합니다. 증명자를 사용하려면 Binary Authorization에 노트도 등록해야 합니다.

증명자가 노트의 발생 항목과 연결됨
  1. 증명자를 만듭니다.
ATTESTOR_ID=vulnz-attestor gcloud container binauthz attestors create $ATTESTOR_ID \ --attestation-authority-note=$NOTE_ID \ --attestation-authority-note-project=${PROJECT_ID}
  1. 증명자를 검증합니다.
gcloud container binauthz attestors list

마지막 줄은 NUM_PUBLIC_KEYS: 0을 나타내며, 이후 단계에서 키를 제공합니다.

Cloud Build는 이미지를 생성하는 빌드를 실행할 때 프로젝트에 built-by-cloud-build 증명자를 자동으로 만듭니다. 따라서 위의 명령어는 vulnz-attestorbuilt-by-cloud-build라는 두 개의 증명자를 반환합니다. 이미지가 성공적으로 빌드되면 Cloud Build가 자동으로 이미지에 대해 서명하고 증명을 만듭니다.

  1. Binary Authorization 서비스 계정에는 증명 노트를 볼 권한이 필요합니다. 다음 API 호출을 사용하여 IAM 역할에 대한 액세스 권한을 제공합니다.
PROJECT_NUMBER=$(gcloud projects describe "${PROJECT_ID}" --format="value(projectNumber)") BINAUTHZ_SA_EMAIL="service-${PROJECT_NUMBER}@gcp-sa-binaryauthorization.iam.gserviceaccount.com" cat > ./iam_request.json << EOM { 'resource': 'projects/${PROJECT_ID}/notes/${NOTE_ID}', 'policy': { 'bindings': [ { 'role': 'roles/containeranalysis.notes.occurrences.viewer', 'members': [ 'serviceAccount:${BINAUTHZ_SA_EMAIL}' ] } ] } } EOM
  1. 파일을 사용하여 IAM 정책을 만듭니다.
curl -X POST \ -H "Content-Type: application/json" \ -H "Authorization: Bearer $(gcloud auth print-access-token)" \ --data-binary @./iam_request.json \ "https://containeranalysis.googleapis.com/v1/projects/${PROJECT_ID}/notes/${NOTE_ID}:setIamPolicy"

내 진행 상황 확인하기를 클릭하여 목표를 확인합니다. 증명자를 만듭니다.

작업 3. KMS 키 추가

이 증명자를 사용하려면 기관에서 컨테이너 이미지에 서명하는 데 사용할 수 있는 암호화 키 쌍을 만들어야 합니다. 이는 Google Cloud Key Management Service(KMS)를 통해 수행할 수 있습니다.

Google Cloud Key Management Service(KMS) 다이어그램
  1. 먼저 새 키를 설명하는 환경 변수를 추가합니다.
KEY_LOCATION=global KEYRING=binauthz-keys KEY_NAME=codelab-key KEY_VERSION=1
  1. 키 집합을 보관할 키링을 만듭니다.
gcloud kms keyrings create "${KEYRING}" --location="${KEY_LOCATION}"
  1. 증명자를 위한 새 비대칭 서명 키 쌍을 만듭니다.
gcloud kms keys create "${KEY_NAME}" \ --keyring="${KEYRING}" --location="${KEY_LOCATION}" \ --purpose asymmetric-signing \ --default-algorithm="ec-sign-p256-sha256"

Cloud 콘솔의 KMS 페이지에 키가 표시됩니다.

  1. 이제 gcloud binauthz 명령어를 통해 키를 증명자와 연결합니다.
gcloud beta container binauthz attestors public-keys add \ --attestor="${ATTESTOR_ID}" \ --keyversion-project="${PROJECT_ID}" \ --keyversion-location="${KEY_LOCATION}" \ --keyversion-keyring="${KEYRING}" \ --keyversion-key="${KEY_NAME}" \ --keyversion="${KEY_VERSION}"
  1. 권한 목록을 다시 출력하면 이제 등록된 키가 표시됩니다.
gcloud container binauthz attestors list

내 진행 상황 확인하기를 클릭하여 목표를 확인합니다. KMS 키를 추가합니다.

작업 4. 서명된 증명 만들기

이제 이미지를 서명할 수 있는 기능이 구성되었습니다. 이전에 만든 증명자를 사용하여 작업 중인 컨테이너 이미지에 서명합니다.

증명과 발생 항목 연결을 보여주는 KMS 다이어그램

증명에는 증명자가 특정 컨테이너 이미지를 확인했으며 클러스터에서 실행해도 안전하다고 명시하는 암호화 서명이 포함되어야 합니다.

  1. 증명할 컨테이너 이미지를 지정하려면 다음을 실행하여 다이제스트를 확인하세요.
CONTAINER_PATH={{{ project_0.default_region | "REGION" }}}-docker.pkg.dev/${PROJECT_ID}/artifact-scanning-repo/sample-image DIGEST=$(gcloud container images describe ${CONTAINER_PATH}:latest \ --format='get(image_summary.digest)')
  1. 이제 gcloud를 사용하여 증명을 만들 수 있습니다. 이 명령어는 서명에 사용할 키의 세부정보와 승인할 특정 컨테이너 이미지를 입력받습니다.
gcloud beta container binauthz attestations sign-and-create \ --artifact-url="${CONTAINER_PATH}@${DIGEST}" \ --attestor="${ATTESTOR_ID}" \ --attestor-project="${PROJECT_ID}" \ --keyversion-project="${PROJECT_ID}" \ --keyversion-location="${KEY_LOCATION}" \ --keyversion-keyring="${KEYRING}" \ --keyversion-key="${KEY_NAME}" \ --keyversion="${KEY_VERSION}"

컨테이너 분석 용어로 말하자면, 새 발생 항목이 생성되어 증명자의 노트에 연결됩니다.

  1. 모든 항목이 예상대로 작동하는지 확인하려면 다음을 실행하여 증명을 나열하세요.
gcloud container binauthz attestations list \ --attestor=$ATTESTOR_ID --attestor-project=${PROJECT_ID}

작업 5. 어드미션 컨트롤 정책

Binary Authorization은 컨테이너 이미지가 실행되기 전에 규칙을 검증할 수 있는 기능을 제공하는 GKE 및 Cloud Run의 기능입니다. 유효성 검사는 신뢰할 수 있는 CI/CD 파이프라인에서든 사용자가 이미지를 수동으로 배포하려고 시도하든 이미지를 실행하려는 모든 요청에 대해 실행됩니다. 이 기능을 사용하면 CI/CD 파이프라인 검사만으로는 불가능한 런타임 환경을 더 효과적으로 보호할 수 있습니다.

이 기능을 이해하기 위해 엄격한 승인 규칙을 적용하도록 기본 GKE 정책을 수정하겠습니다.

  1. Binary Authorization이 사용 설정된 GKE 클러스터를 만듭니다.
gcloud beta container clusters create binauthz \ --zone {{{ project_0.default_zone | "ZONE" }}} \ --binauthz-evaluation-mode=PROJECT_SINGLETON_POLICY_ENFORCE
  1. Cloud Build가 이 클러스터에 배포하도록 허용합니다.
gcloud projects add-iam-policy-binding ${PROJECT_ID} \ --member="serviceAccount:${PROJECT_NUMBER}@cloudbuild.gserviceaccount.com" \ --role="roles/container.developer"

모두 허용 정책

먼저 기본 정책 상태와 이미지를 배포할 수 있는지 확인합니다.

  1. 기존 정책을 검토합니다.
gcloud container binauthz policy export
  1. 시행 정책이 ALWAYS_ALLOW로 설정되어 있습니다.

evaluationMode: ALWAYS_ALLOW

  1. 샘플을 배포하여 모든 항목을 배포할 수 있는지 확인합니다.
kubectl run hello-server --image gcr.io/google-samples/hello-app:1.0 --port 8080
  1. 배포가 작동하는지 확인합니다.
kubectl get pods

다음과 같은 출력이 표시됩니다.

hello-server의 Running 상태
  1. 배포를 삭제합니다.
kubectl delete pod hello-server

모두 거부 정책

이제 모든 이미지를 허용하지 않도록 정책을 업데이트합니다.

  1. 현재 정책을 수정 가능한 파일로 내보냅니다.
gcloud container binauthz policy export > policy.yaml
  1. 텍스트 편집기에서 policy.yaml' 파일을 열고 evaluationMode를 `ALWAYS_ALLOW에서 ALWAYS_DENY로 변경합니다.
edit policy.yaml

수정된 정책 YAML 파일이 다음과 같이 표시되는지 확인합니다.

globalPolicyEvaluationMode: ENABLE defaultAdmissionRule: evaluationMode: ALWAYS_DENY enforcementMode: ENFORCED_BLOCK_AND_AUDIT_LOG name: projects/PROJECT_ID/policy

이 정책은 비교적 간단합니다. globalPolicyEvaluationMode 줄은 이 정책이 Google에서 정의한 전역 정책을 확장한다고 선언합니다. 이렇게 하면 모든 공식 GKE 컨테이너가 기본적으로 실행될 수 있습니다. 또한 이 정책은 다른 모든 포드가 거부됨을 명시하는 defaultAdmissionRule을 선언합니다. 어드미션 규칙에는 이 규칙을 준수하지 않는 모든 포드가 클러스터에서 실행되지 않도록 차단해야 한다고 명시하는 enforcementMode 줄이 포함되어 있습니다.

더 복잡한 정책을 빌드하는 방법은 Binary Authorization 문서를 참고하세요.

지정된 컨테이너만 허용하는 Binary Authorization 정책의 플로우 차트
  1. Cloud Shell에서 다음을 실행하여 새 정책을 적용합니다.
gcloud container binauthz policy import policy.yaml

변경사항이 전파될 때까지 몇 초간 기다립니다.

  1. 샘플 워크로드 배포를 시도합니다.
kubectl run hello-server --image gcr.io/google-samples/hello-app:1.0 --port 8080
  1. 다음 메시지와 함께 배포가 실패합니다.
Error from server (VIOLATES_POLICY): admission webhook "imagepolicywebhook.image-policy.k8s.io" denied the request: Image gcr.io/google-samples/hello-app:1.0 denied by Binary Authorization default admission rule. always_deny 어드미션 규칙에 의해 거부됨

모두 허용하도록 정책 되돌리기

다음 섹션으로 넘어가기 전에 정책 변경사항을 되돌리세요.

  1. 텍스트 편집기에서 evaluationModeALWAYS_DENY에서 ALWAYS_ALLOW로 변경합니다.
edit policy.yaml

수정된 정책 YAML 파일은 다음과 같이 표시됩니다.

globalPolicyEvaluationMode: ENABLE defaultAdmissionRule: evaluationMode: ALWAYS_ALLOW enforcementMode: ENFORCED_BLOCK_AND_AUDIT_LOG name: projects/PROJECT_ID/policy
  1. 되돌린 정책을 적용합니다.
gcloud container binauthz policy import policy.yaml

내 진행 상황 확인하기를 클릭하여 목표를 확인합니다. GKE 클러스터를 만들고 정책을 업데이트합니다.

작업 6. 이미지 자동 서명

이미지 서명을 사용 설정하고 증명자를 수동으로 사용하여 샘플 이미지에 서명했습니다. 실무에서는 CI/CD 파이프라인과 같은 자동화된 프로세스 중에 증명서를 적용하는 것이 좋습니다.

이 섹션에서는 이미지를 자동으로 증명하도록 Cloud Build를 구성합니다.

필요한 역할

  1. Cloud Build 서비스 계정에 Binary Authorization 증명자 뷰어 역할을 추가합니다.
gcloud projects add-iam-policy-binding ${PROJECT_ID} \ --member serviceAccount:${PROJECT_NUMBER}@cloudbuild.gserviceaccount.com \ --role roles/binaryauthorization.attestorsViewer
  1. Cloud Build 서비스 계정(KMS 기반 서명)에 Cloud KMS CryptoKey 서명자/확인자 역할을 추가합니다.
gcloud projects add-iam-policy-binding ${PROJECT_ID} \ --member serviceAccount:${PROJECT_NUMBER}@cloudbuild.gserviceaccount.com \ --role roles/cloudkms.signerVerifier gcloud projects add-iam-policy-binding ${PROJECT_ID} \ --member serviceAccount:${PROJECT_NUMBER}-compute@developer.gserviceaccount.com \ --role roles/cloudkms.signerVerifier
  1. Cloud Build 서비스 계정에 컨테이너 분석 메모 첨부자 역할을 추가합니다.
gcloud projects add-iam-policy-binding ${PROJECT_ID} \ --member serviceAccount:${PROJECT_NUMBER}@cloudbuild.gserviceaccount.com \ --role roles/containeranalysis.notes.attacher

Cloud Build 서비스 계정에 대한 액세스 권한 제공

Cloud Build에는 주문형 스캔 API에 액세스할 권한이 필요합니다.

  • 다음 명령어를 사용하여 액세스 권한을 제공합니다.
gcloud projects add-iam-policy-binding ${PROJECT_ID} \ --member="serviceAccount:${PROJECT_NUMBER}@cloudbuild.gserviceaccount.com" \ --role="roles/iam.serviceAccountUser" gcloud projects add-iam-policy-binding ${PROJECT_ID} \ --member="serviceAccount:${PROJECT_NUMBER}@cloudbuild.gserviceaccount.com" \ --role="roles/ondemandscanning.admin"

커스텀 빌드 Cloud Build 단계 준비

Cloud Build의 커스텀 빌드 단계를 사용하여 증명 프로세스를 간소화합니다. Google은 프로세스를 간소화하기 위해 도우미 함수가 포함된 커스텀 빌드 단계를 제공합니다. 사용하려면 먼저 컨테이너에 커스텀 빌드 단계의 코드를 빌드하고 Cloud Build로 푸시해야 합니다.

  • 이를 위해 다음 명령어를 실행하세요.
git clone https://github.com/GoogleCloudPlatform/cloud-builders-community.git cd cloud-builders-community/binauthz-attestation gcloud builds submit . --config cloudbuild.yaml cd ../.. rm -rf cloud-builders-community

cloudbuild.yaml에 서명 단계 추가

Cloud Build 파이프라인에 증명 단계를 추가합니다.

  1. 아래 서명 단계를 검토합니다.

검토만 가능합니다. 복사 금지

#Sign the image only if the previous severity check passes - id: 'create-attestation' name: 'gcr.io/${PROJECT_ID}/binauthz-attestation:latest' args: - '--artifact-url' - '{{{ project_0.default_region | "REGION" }}}-docker.pkg.dev/${PROJECT_ID}/artifact-scanning-repo/sample-image' - '--attestor' - 'projects/${PROJECT_ID}/attestors/$ATTESTOR_ID' - '--keyversion' - 'projects/${PROJECT_ID}/locations/$KEY_LOCATION/keyRings/$KEYRING/cryptoKeys/$KEY_NAME/cryptoKeyVersions/$KEY_VERSION'
  1. 아래의 전체 파이프라인을 사용하여 cloudbuild.yaml 파일을 작성합니다.
cat > ./cloudbuild.yaml << EOF steps: # build - id: "build" name: 'gcr.io/cloud-builders/docker' args: ['build', '-t', '{{{ project_0.default_region | "REGION" }}}-docker.pkg.dev/${PROJECT_ID}/artifact-scanning-repo/sample-image', '.'] waitFor: ['-'] # additional CICD checks (not shown) #Retag - id: "retag" name: 'gcr.io/cloud-builders/docker' args: ['tag', '{{{ project_0.default_region | "REGION" }}}-docker.pkg.dev/${PROJECT_ID}/artifact-scanning-repo/sample-image', '{{{ project_0.default_region | "REGION" }}}-docker.pkg.dev/${PROJECT_ID}/artifact-scanning-repo/sample-image:good'] #pushing to artifact registry - id: "push" name: 'gcr.io/cloud-builders/docker' args: ['push', '{{{ project_0.default_region | "REGION" }}}-docker.pkg.dev/${PROJECT_ID}/artifact-scanning-repo/sample-image:good'] #Sign the image only if the previous severity check passes - id: 'create-attestation' name: 'gcr.io/${PROJECT_ID}/binauthz-attestation:latest' args: - '--artifact-url' - '{{{ project_0.default_region | "REGION" }}}-docker.pkg.dev/${PROJECT_ID}/artifact-scanning-repo/sample-image:good' - '--attestor' - 'projects/${PROJECT_ID}/attestors/$ATTESTOR_ID' - '--keyversion' - 'projects/${PROJECT_ID}/locations/$KEY_LOCATION/keyRings/$KEYRING/cryptoKeys/$KEY_NAME/cryptoKeyVersions/$KEY_VERSION' images: - {{{ project_0.default_region | "REGION" }}}-docker.pkg.dev/${PROJECT_ID}/artifact-scanning-repo/sample-image:good EOF
  1. 빌드를 실행합니다.
gcloud builds submit

Cloud Build 기록에서 빌드 검토

Cloud 콘솔에서 Cloud Build > 빌드 기록 페이지로 이동하여 최신 빌드와 빌드 단계의 성공적인 실행을 검토합니다.

내 진행 상황 확인하기를 클릭하여 목표를 확인합니다. 서명 단계를 추가합니다.

작업 7. 서명된 이미지 승인

이제 이미지를 실행하기 전에, Binary Authorization을 사용하여 취약점 스캔 후 서명을 받은 이미지인지 검사하도록 GKE를 업데이트합니다.

Binary Authorization은 신뢰할 수 있는 이미지와 신뢰할 수 없는 이미지를 검증합니다.

증명을 요구하도록 GKE 정책 업데이트

GKE BinAuth 정책에 clusterAdmissionRules를 추가하여 증명자가 이미지에 서명하도록 요구

현재 클러스터는 공식 저장소의 컨테이너는 허용하고 다른 모든 컨테이너는 거부하는 규칙이 하나인 정책을 실행하고 있습니다.

  1. 아래 명령어를 사용하여 업데이트된 구성으로 정책을 덮어씁니다.
COMPUTE_ZONE={{{ project_0.default_region | "REGION" }}} cat > binauth_policy.yaml << EOM defaultAdmissionRule: enforcementMode: ENFORCED_BLOCK_AND_AUDIT_LOG evaluationMode: REQUIRE_ATTESTATION requireAttestationsBy: - projects/${PROJECT_ID}/attestors/vulnz-attestor globalPolicyEvaluationMode: ENABLE clusterAdmissionRules: ${COMPUTE_ZONE}.binauthz: evaluationMode: REQUIRE_ATTESTATION enforcementMode: ENFORCED_BLOCK_AND_AUDIT_LOG requireAttestationsBy: - projects/${PROJECT_ID}/attestors/vulnz-attestor EOM
  1. 이제 디스크에 updated_policy.yaml이라는 새 파일이 있어야 합니다. 이제 기본 규칙에서 모든 이미지를 거부하는 대신 먼저 증명자에게 확인을 요청합니다.
허용된 컨테이너와 증명자가 서명한 컨테이너가 허용됨
  1. 새 정책을 Binary Authorization에 업로드합니다.
gcloud beta container binauthz policy import binauth_policy.yaml

서명된 이미지 배포

  1. 바람직한 이미지의 이미지 다이제스트를 가져옵니다.
CONTAINER_PATH={{{ project_0.default_region | "REGION" }}}-docker.pkg.dev/${PROJECT_ID}/artifact-scanning-repo/sample-image DIGEST=$(gcloud container images describe ${CONTAINER_PATH}:good \ --format='get(image_summary.digest)')
  1. Kubernetes 구성에서 다이제스트를 사용합니다.
cat > deploy.yaml << EOM apiVersion: v1 kind: Service metadata: name: deb-httpd spec: selector: app: deb-httpd ports: - protocol: TCP port: 80 targetPort: 8080 --- apiVersion: apps/v1 kind: Deployment metadata: name: deb-httpd spec: replicas: 1 selector: matchLabels: app: deb-httpd template: metadata: labels: app: deb-httpd spec: containers: - name: deb-httpd image: ${CONTAINER_PATH}@${DIGEST} ports: - containerPort: 8080 env: - name: PORT value: "8080" EOM
  1. 앱을 GKE에 배포합니다.
kubectl apply -f deploy.yaml

Cloud 콘솔에서 Kubernetes Engine > 워크로드로 이동하여 이미지가 성공적으로 배포되었는지 확인합니다.

내 진행 상황 확인하기를 클릭하여 목표를 확인합니다. 서명된 이미지를 배포합니다.

작업 8. 서명되지 않은 이미지 차단

이미지 빌드

  1. 로컬 Docker를 사용하여 이미지를 로컬 캐시에 빌드합니다.
docker build -t {{{ project_0.default_region | "REGION" }}}-docker.pkg.dev/${PROJECT_ID}/artifact-scanning-repo/sample-image:bad .
  1. 이미지를 저장소에 푸시합니다.
docker push {{{ project_0.default_region | "REGION" }}}-docker.pkg.dev/${PROJECT_ID}/artifact-scanning-repo/sample-image:bad
  1. 악성 이미지의 이미지 다이제스트를 가져옵니다.
CONTAINER_PATH={{{ project_0.default_region | "REGION" }}}-docker.pkg.dev/${PROJECT_ID}/artifact-scanning-repo/sample-image DIGEST=$(gcloud container images describe ${CONTAINER_PATH}:bad \ --format='get(image_summary.digest)')
  1. Kubernetes 구성에서 다이제스트를 사용합니다.
cat > deploy.yaml << EOM apiVersion: v1 kind: Service metadata: name: deb-httpd spec: selector: app: deb-httpd ports: - protocol: TCP port: 80 targetPort: 8080 --- apiVersion: apps/v1 kind: Deployment metadata: name: deb-httpd spec: replicas: 1 selector: matchLabels: app: deb-httpd template: metadata: labels: app: deb-httpd spec: containers: - name: deb-httpd image: ${CONTAINER_PATH}@${DIGEST} ports: - containerPort: 8080 env: - name: PORT value: "8080" EOM
  1. GKE에 앱 배포 시도
kubectl apply -f deploy.yaml

콘솔에서 워크로드를 검토하고 배포가 거부되었다는 오류를 확인합니다.

증명자가 신뢰하는 키로 서명된 유효한 증명이 없습니다.

내 진행 상황 확인하기를 클릭하여 목표를 확인합니다. 서명되지 않은 이미지를 배포합니다.

수고하셨습니다

컨테이너 이미지가 실행되기 전에 규칙을 검증하기 위해 이미지에 서명하는 증명자를 만드는 방법을 알아봤습니다. Cloud Build에 GKE 클러스터에 대한 액세스를 허용하거나 거부하도록 알리는 정책을 작성하는 방법을 알아보고, Google Cloud KMS와 함께 Binary Authorization을 사용하여 이미지 서명을 검증하고 서명되지 않은 이미지가 Kubernetes 클러스터에 액세스하지 못하도록 했습니다.

다음 단계/더 학습하기

Google Cloud 교육 및 인증

Google Cloud 기술을 최대한 활용하는 데 도움이 됩니다. Google 강의에는 빠른 습득과 지속적인 학습을 지원하는 기술적인 지식과 권장사항이 포함되어 있습니다. 기초에서 고급까지 수준별 학습을 제공하며 바쁜 일정에 알맞은 주문형, 실시간, 가상 옵션이 포함되어 있습니다. 인증은 Google Cloud 기술에 대한 역량과 전문성을 검증하고 입증하는 데 도움이 됩니다.

설명서 최종 업데이트: 2024년 9월 10일

실습 최종 테스트: 2024년 7월 11일

Copyright 2024 Google LLC All rights reserved. Google 및 Google 로고는 Google LLC의 상표입니다. 기타 모든 회사명 및 제품명은 해당 업체의 상표일 수 있습니다.

시작하기 전에

  1. 실습에서는 정해진 기간 동안 Google Cloud 프로젝트와 리소스를 만듭니다.
  2. 실습에는 시간 제한이 있으며 일시중지 기능이 없습니다. 실습을 종료하면 처음부터 다시 시작해야 합니다.
  3. 화면 왼쪽 상단에서 실습 시작을 클릭하여 시작합니다.

시크릿 브라우징 사용

  1. 실습에 입력한 사용자 이름비밀번호를 복사합니다.
  2. 비공개 모드에서 콘솔 열기를 클릭합니다.

콘솔에 로그인

    실습 사용자 인증 정보를 사용하여
  1. 로그인합니다. 다른 사용자 인증 정보를 사용하면 오류가 발생하거나 요금이 부과될 수 있습니다.
  2. 약관에 동의하고 리소스 복구 페이지를 건너뜁니다.
  3. 실습을 완료했거나 다시 시작하려고 하는 경우가 아니면 실습 종료를 클릭하지 마세요. 이 버튼을 클릭하면 작업 내용이 지워지고 프로젝트가 삭제됩니다.

현재 이 콘텐츠를 이용할 수 없습니다

이용할 수 있게 되면 이메일로 알려드리겠습니다.

감사합니다

이용할 수 있게 되면 이메일로 알려드리겠습니다.

한 번에 실습 1개만 가능

모든 기존 실습을 종료하고 이 실습을 시작할지 확인하세요.

시크릿 브라우징을 사용하여 실습 실행하기

Using an Incognito or private browser window is the best way to run this lab. This prevents any conflicts between your personal account and the Student account, which may cause extra charges incurred to your personal account.