Voucher로 증명 만들기

이 튜토리얼에서는 Voucher를 설정하고 사용하여 Binary Authorization 증명을 만드는 방법을 설명합니다.

Voucher 개요

Voucher는 이미지의 Binary Authorization 증명을 만들기 전에 컨테이너 이미지에 대한 일련의 검사를 실행하는 오픈소스 도구입니다. Voucher에는 클라이언트와 서버 구성요소가 있습니다. 이미지를 빌드하는 단계 후에 빌드 파이프라인 내에서 추가 단계로 Voucher Client를 실행합니다. Voucher Client 빌드 단계는 실행될 때 이미지를 Voucher Server에 제출하여 검사를 수행합니다. Voucher Server 구성 파일에서 Voucher가 실행하는 검사를 다른 기준과 함께 정의합니다.

이 가이드에서는 Voucher snakeoil 검사를 사용하여 이미지의 취약점을 테스트하는 방법을 보여줍니다. 이 가이드의 뒷부분에 나오는 것처럼 fail-on 옵션을 취약점 기준점으로 설정하여 구성 파일에서 검사를 사용 설정합니다.

snakeoil 검사가 완료된 후 식별된 모든 취약점이 기준점 아래로 떨어지면 Voucher Server가 이미지의 Binary Authorization 증명을 만듭니다. 식별된 취약점이 기준점을 충족하거나 초과하면 Voucher Server가 증명을 만들지 않습니다.

컨테이너 이미지 배포 시 확인된 증명이 없으면 Binary Authorization 시행자가 이미지 배포를 허용하지 않습니다.

목표

이 가이드에서는 다음과 같은 작업을 수행하게 됩니다.

  1. Cloud Run에서 Voucher Server를 설정합니다.
  2. Voucher Client 설정
  3. 예시 빌드 파이프라인에서 Voucher를 사용합니다.

비용

이 가이드에서는 다음 Google Cloud 제품을 사용합니다.

  • Container Registry
  • 컨테이너 분석
  • Cloud Build
  • Cloud Key Management Service
  • Cloud Run

가격 계산기를 사용하면 예상 사용량을 토대로 예상 비용을 산출할 수 있습니다.

시작하기 전에

  1. Google Cloud 계정에 로그인합니다. Google Cloud를 처음 사용하는 경우 계정을 만들고 Google 제품의 실제 성능을 평가해 보세요. 신규 고객에게는 워크로드를 실행, 테스트, 배포하는 데 사용할 수 있는 $300의 무료 크레딧이 제공됩니다.
  2. Google Cloud Console의 프로젝트 선택기 페이지에서 Google Cloud 프로젝트를 선택하거나 만듭니다.

    프로젝트 선택기로 이동

  3. Cloud 프로젝트에 결제가 사용 설정되어 있는지 확인합니다. 프로젝트에 결제가 사용 설정되어 있는지 확인하는 방법을 알아보세요.

  4. Cloud Build, Container Registry, Container Analysis, Cloud KMS, Cloud Run, and Identity and Access Management API를 사용 설정합니다.

    API 사용 설정

  5. Cloud SDK 설치 및 초기화
  6. Google Cloud Console의 프로젝트 선택기 페이지에서 Google Cloud 프로젝트를 선택하거나 만듭니다.

    프로젝트 선택기로 이동

  7. Cloud 프로젝트에 결제가 사용 설정되어 있는지 확인합니다. 프로젝트에 결제가 사용 설정되어 있는지 확인하는 방법을 알아보세요.

  8. Cloud Build, Container Registry, Container Analysis, Cloud KMS, Cloud Run, and Identity and Access Management API를 사용 설정합니다.

    API 사용 설정

  9. Cloud SDK 설치 및 초기화
  10. Google Kubernetes Engine에서 Binary Authorization을 설정하는 것이 좋습니다. 이 튜토리얼에서는 증명을 만드는 방법을 설명합니다. 배포-시간 시행을 사용하여 증명을 확인하고 연결된 이미지를 배포하려면 Binary Authorization을 설정해야 합니다. 증명 필요로 정책을 구성해야 합니다. Google Cloud Console 또는 명령줄에서 정책을 구성할 수 있습니다.
  11. 환경 변수에 Google Cloud 프로젝트를 지정합니다.

      export PROJECT_ID=PROJECT_ID
    

    PROJECT_ID를 프로젝트 ID로 바꿉니다.

  12. gcloud 명령어에 프로젝트 ID를 설정합니다.

    gcloud config set project ${PROJECT_ID}

  13. 다음 단계에서 프로젝트 번호를 환경 변수에 저장합니다.

    export PROJECT_NUMBER=$(gcloud projects describe "${PROJECT_ID}" \
      --format='value(project_number)')

Voucher Server 설정

다음 단계에서는 Voucher Server를 설정합니다.

Cloud Key Management Service 서명 키 만들기

이 섹션에서는 Voucher Server가 Binary Authorization 증명을 만드는 데 사용하는 키를 만듭니다.

  1. 키링 만들기

    gcloud kms keyrings create KEY_RING\
       --location global
    

    KEY_RING을 키링 이름(예: voucher-key-ring)으로 바꿉니다.

  2. 서명 키를 만듭니다.

    gcloud kms keys create KEY_NAME \
      --keyring KEY_RING \
      --location global \
      --purpose "asymmetric-signing" \
      --default-algorithm "rsa-sign-pkcs1-4096-sha512"
    

    KEY_NAME을 키 이름(예: voucher-key)으로 바꿉니다.

  3. Cloud Key Management Service 키 버전 리소스 ID를 저장합니다.

    export KMS_RESOURCE_ID=projects/$PROJECT_ID/locations/global/keyRings/KEY_RING/cryptoKeys/KEY_NAME/cryptoKeyVersions/1
    
  4. Compute Engine 런타임 엔진 서비스 계정cloudkms.signer 역할을 부여합니다.

    이 단계에서는 Voucher Server를 실행하는 서비스 계정에 cloudkms.signer 역할을 부여합니다. 이렇게 하면 Voucher Server가 Cloud Key Management Service 키로 증명에 서명할 수 있습니다. 이렇게 하려면 다음 명령어를 실행하세요.

    gcloud kms keys add-iam-policy-binding\
      KEY_NAME --keyring=KEY_RING\
      --location=global\
      --member=serviceAccount:${PROJECT_NUMBER}-compute@developer.gserviceaccount.com\
      --role=roles/cloudkms.signer
    

컨테이너 분석 메모 만들기

이 섹션에서는 메모를 만듭니다.

  1. 메모 ID를 저장합니다.

    export NOTE_ID=snakeoil
    
  2. 메모 URI를 저장합니다.

    export NOTE_URI=projects/$PROJECT_ID/notes/$NOTE_ID
    
  3. 요청 페이로드를 만듭니다.

    cat > /tmp/note_payload.json << EOM
    {
      "name": "${NOTE_URI}",
      "attestation": {
        "hint": {
          "human_readable_name": "voucher note for snakeoil check"
        }
      }
    }
    EOM
    
  4. 메모를 만듭니다.

    curl -X POST \
      -H "Content-Type: application/json" \
      -H "Authorization: Bearer $(gcloud --project ${PROJECT_ID} auth print-access-token)"  \
      -H "x-goog-user-project: ${PROJECT_ID}" \
      --data-binary @/tmp/note_payload.json  \
    "https://containeranalysis.googleapis.com/v1/projects/${PROJECT_ID}/notes/?noteId=${NOTE_ID}"
    

Voucher Server 빌드 및 구성

이 일회성 설정에서 Voucher Server 이미지를 가져오고, 구성하고, 빌드합니다. 그런 다음 Container Registry에 저장합니다.

  1. Voucher 저장소를 클론합니다.

    git clone https://github.com/grafeas/voucher.git
    cd voucher/
    

    이 저장소에는 다음이 포함됩니다.

    • Voucher Server를 빌드할 소스 코드
    • Voucher Client를 빌드할 소스 코드
    • Voucher 사용 방법을 보여주는 예시
  2. Voucher Server 구성 파일을 업데이트합니다.

    Linux

    템플릿에서 Voucher Server 구성 파일을 만들고 을 위에서 정의한 값으로 바꿉니다. 다음 명령어를 실행하면 됩니다.

     cat tutorials/cloudrun/config.toml.template \
        | sed -e "s?<PROJECT_ID>?${PROJECT_ID}?g" \
        | sed -e "s?<KMS_KEY_NAME>?${KMS_RESOURCE_ID}?g" \
          > tutorials/cloudrun/config.toml
    

    기타 OS

    1. tutorials/cloudrun/config.toml.template 파일을 수정합니다.

      • <PROJECT_ID>${PROJECT_ID}의 값으로 바꿉니다.
      • <KMS_KEY_NAME>${KMS_RESOURCE_ID}의 값으로 바꿉니다.
    2. 파일을 tutorials/cloudrun/config.toml로 저장합니다.

  3. Voucher Server 구성 파일을 확인합니다.

    cat tutorials/cloudrun/config.toml
    

    다음이 포함된 출력이 표시됩니다.

    failon = "high"
    

    구성 파일에서 failon 옵션은 high로 설정됩니다. 이 설정은 이미지에서 취약점 검사를 수행하도록 Voucher Server를 구성합니다. 이미지에 심각도가 HIGH인 취약점이 있으면 검사가 실패하고 Voucher Server가 Binary Authorization 증명을 만들지 않습니다. fail-on 설정에 대한 자세한 내용은 실패 기준: 취약점 발생 시 실패를 참조하세요.

  4. Voucher Server 컨테이너 이미지를 빌드하고 업로드합니다.

    이 섹션에서는 Voucher Server 컨테이너 이미지를 빌드하는 Cloud Build 파이프라인을 실행합니다. 이 빌드는 Voucher Server 이미지를 gcr.io/$PROJECT_ID/voucher-server에 업로드합니다.

    gcloud  builds submit --config ./tutorials/cloudrun/cloudbuild-server.yaml
    

Cloud Run에 Voucher Server 배포

  1. 리전을 선택합니다.

    사용 가능한 리전 목록을 보려면 사용 가능한 리전 목록 보기를 참조하세요. 선택한 리전을 저장할 변수를 만듭니다.

    export REGION=REGION
    

    REGION을 Voucher Server를 배포할 리전의 이름으로 바꿉니다.

  2. Cloud Run에 Voucher Server를 배포합니다.

    gcloud run deploy --image gcr.io/${PROJECT_ID}/voucher-server \
      --platform managed voucher-server \
      --region ${REGION} \
      --no-allow-unauthenticated
    

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

    Service [voucher-server] revision [voucher-server-00001-caw] has been deployed and is serving 100 percent of traffic.
    Service URL: https://voucher-server-4wjtm2amga-uc.a.run.app
    
  3. Voucher Server 서비스 URL을 저장합니다.

    export SERVER_SERVICE_URL=$(gcloud run services describe voucher-server --platform managed --region ${REGION} --format='value(status.url)')
    

Voucher Client 설정

다음 단계에서는 Voucher Client를 설정합니다.

  1. Voucher Client의 호출자 서비스 계정을 만듭니다.

    gcloud iam service-accounts create INVOKER_ACCOUNT_NAME
    

    INVOKER_ACCOUNT_NAME을 호출자 서비스 계정의 이름(예: voucher-invoker)으로 바꿉니다.

  2. 서비스 계정을 지정합니다.

    export INVOKER_SERVICE_ACCOUNT=INVOKER_ACCOUNT_NAME@$PROJECT_ID.iam.gserviceaccount.com
    
  3. 프로젝트의 호출자 서비스 계정에 run.invoker 역할을 부여합니다.

    호출자 서비스 계정에 Cloud Run에서 Voucher Server를 호출할 수 있는 권한을 부여합니다. 이렇게 하려면 다음 명령어를 입력하세요.

    gcloud run services add-iam-policy-binding voucher-server \
      --member serviceAccount:$INVOKER_SERVICE_ACCOUNT \
      --role roles/run.invoker \
      --platform managed \
      --region ${REGION}
    
  4. Cloud Build의 호출자 서비스 계정에 iam.serviceAccountTokenCreator 역할을 부여합니다.

    이 섹션에서는 빌드 중에 Voucher Client가 Voucher Server에 요청을 보낼 수 있는 권한을 갖도록 호출자 서비스 계정을 가장할 수 있는 권한을 Cloud Build 서비스 계정에 부여합니다. 이렇게 하려면 다음 명령어를 입력하세요.

    gcloud iam service-accounts add-iam-policy-binding $INVOKER_SERVICE_ACCOUNT \
      --member=serviceAccount:$PROJECT_NUMBER@cloudbuild.gserviceaccount.com \
      --role=roles/iam.serviceAccountTokenCreator
    

Voucher를 사용하여 이미지의 취약점 확인

이 섹션에서는 두 가지 Cloud Build 파이프라인 예시를 실행합니다. 두 파이프라인 모두에서 이미지를 빌드한 다음 Voucher를 사용하여 취약점을 확인합니다.

실패 사례

이 섹션에서는 예시 빌드 파이프라인이 증명을 만들지 못합니다. Debian 9를 기반으로 빌드된 이미지에는 심각도가 HIGH인 취약점이 하나 이상 포함되어 있습니다. Voucher Server config.tomlfail-on 옵션은 HIGH 심각도 취약점 발생 시 실패하도록 설정됩니다. 이 경우 Voucher Server는 Binary Authorization 증명을 만들지 않습니다.

  1. 빌드 파이프라인을 실행합니다.

    gcloud builds submit \
      --substitutions=_SERVICE_URL=$SERVER_SERVICE_URL,_SERVICE_ACCOUNT=$INVOKER_SERVICE_ACCOUNT \
      --config=tutorials/cloudrun/examples/cloudbuild-bad.yaml tutorials/cloudrun/examples
    
  2. 마지막 빌드의 로그에서 Voucher snakeoil 결과를 검색합니다.

    Console

    1. 마지막 빌드의 빌드 ID를 기록해 둡니다.

    2. Google Cloud Console에서 빌드 기록 페이지로 이동합니다.

      빌드 기록으로 이동

    3. 빌드에서 빌드 ID의 처음 몇 자가 포함된 항목을 클릭합니다.

    4. 원본 보기를 클릭합니다.

    5. 브라우저를 사용하여 snakeoil을 검색합니다.

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

      "name":"snakeoil","error":"vulnerable to 14 vulnerabilities"
      

    gcloud

    1. 빌드의 빌드 ID를 저장합니다.

      export BUILD_ID=$(gcloud builds list --limit=1 --format="value('ID')")
      
    2. 다음 명령어를 입력하여 빌드 로그를 검색합니다.

       gcloud builds log ${BUILD_ID} | grep "snakeoil"
      

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

      "name":"snakeoil","error":"vulnerable to 14 vulnerabilities"
      

성공 사례

이 섹션에서는 예시 빌드 파이프라인이 증명을 만드는 데 성공합니다. 식별된 모든 취약점이 fail-on 기준점보다 낮은 등급이므로 파이프라인이 검사에 통과하고 증명이 생성됩니다.

  1. 파이프라인을 실행합니다.

    gcloud builds submit\
      --substitutions=_SERVICE_URL=$SERVER_SERVICE_URL,_SERVICE_ACCOUNT=$INVOKER_SERVICE_ACCOUNT\
      --config=tutorials/cloudrun/examples/cloudbuild-good.yaml tutorials/cloudrun/examples
    
  2. 마지막 빌드의 로그에서 Voucher snakeoil 결과를 검색합니다.

    Console

    1. 마지막 빌드의 빌드 ID를 기록해 둡니다.

    2. Google Cloud Console에서 빌드 기록 페이지로 이동합니다.

      빌드 기록으로 이동

    3. 빌드에서 빌드 ID의 처음 몇 자가 포함된 항목을 클릭합니다.

    4. 원본 보기를 클릭합니다.

    5. 브라우저를 사용하여 snakeoil을 검색합니다.

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

      "name":"snakeoil","success":true,"attested":true
      

    gcloud

    1. 마지막 빌드의 빌드 ID를 저장합니다.

      export BUILD_ID=$(gcloud builds list --limit=1 --format="value('ID')")
      
    2. 다음 명령어를 입력하여 빌드 로그를 검색합니다.

       gcloud builds log ${BUILD_ID} | grep "snakeoil"
      

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

      "name":"snakeoil","success":true,"attested":true
      

삭제

이 문서에 사용된 리소스를 삭제하려면 다음과 같이 프로젝트를 삭제하면 됩니다.

gcloud projects delete ${PROJECT_ID}

다음 단계