다음을 통해 공유


자체 서명된 인증서를 사용하여 Notation 및 Azure Key Vault로 컨테이너 이미지에 서명합니다.

컨테이너 이미지 서명은 신뢰성과 무결성을 보장하는 프로세스입니다. 이는 배포 중에 유효성을 검사할 수 있는 컨테이너 이미지에 디지털 서명을 추가하여 수행됩니다. 서명은 이미지가 신뢰할 수 있는 게시자의 이미지이며 수정되지 않았는지 확인하는 데 도움이 됩니다. Notation은 컨테이너 이미지 및 기타 아티팩트 서명 및 확인을 지원하는 Microsoft에서 지원하는 Notary Project 커뮤니티에서 개발한 오픈 소스 공급망 보안 도구입니다. AKV(Azure Key Vault)는 Notation AKV 플러그 인(azure-kv)으로 Notation에서 컨테이너 이미지 및 기타 아티팩트에 서명하고 확인하는 데 사용할 수 있는 서명 키와 함께 인증서를 저장하는 데 사용됩니다. ACR(Azure Container Registry)을 사용하면 컨테이너 이미지 및 기타 아티팩트에 서명을 첨부하고 해당 서명을 볼 수 있습니다.

이 자습서에서:

  • Notation CLI 및 AKV 플러그 인 설치
  • AKV에서 자체 서명된 인증서 만들기
  • ACR 작업을 사용하여 컨테이너 이미지 빌드 및 푸시
  • Notation CLI 및 AKV 플러그 인을 사용하여 컨테이너 이미지에 서명
  • Notation CLI를 사용하여 서명에 대해 컨테이너 이미지 유효성 검사
  • 타임스탬프 처리

필수 조건

Notation CLI 및 AKV 플러그 인 설치

  1. Linux amd64 환경에 표기법 v1.2.0을 설치합니다. 다른 환경용 패키지를 다운로드하려면 표기법 설치 가이드를 따릅니다.

    # Download, extract and install
    curl -Lo notation.tar.gz https://github.com/notaryproject/notation/releases/download/v1.2.0/notation_1.2.0_linux_amd64.tar.gz
    tar xvzf notation.tar.gz
    
    # Copy the Notation binary to the desired bin directory in your $PATH, for example
    cp ./notation /usr/local/bin
    
  2. Linux amd64 환경에 Notation Azure Key Vault 플러그 인 azure-kv v1.2.0을 설치합니다.

    참고 항목

    Notation Azure Key Vault 플러그 인의 URL 및 SHA256 체크섬은 플러그 인의 릴리스 페이지에서 확인할 수 있습니다.

    notation plugin install --url https://github.com/Azure/notation-azure-kv/releases/download/v1.2.0/notation-azure-kv_1.2.0_linux_amd64.tar.gz --sha256sum 06bb5198af31ce11b08c4557ae4c2cbfb09878dfa6b637b7407ebc2d57b87b34
    
  3. 사용 가능한 플러그 인을 나열하고 버전이 1.2.0azure-kv 플러그 인이 목록에 포함되어 있는지 확인합니다.

    notation plugin ls
    

환경 변수 구성

참고 항목

자습서에서 명령을 쉽게 실행하려면 기존 ACR 및 AKV 리소스와 일치하도록 Azure 리소스에 대한 값을 제공합니다.

  1. AKV 리소스 이름 구성

    AKV_SUB_ID=myAkvSubscriptionId
    AKV_RG=myAkvResourceGroup
    # Name of the existing AKV used to store the signing keys
    AKV_NAME=myakv
    # Name of the certificate created in AKV
    CERT_NAME=wabbit-networks-io
    CERT_SUBJECT="CN=wabbit-networks.io,O=Notation,L=Seattle,ST=WA,C=US"
    CERT_PATH=./${CERT_NAME}.pem
    
  2. ACR 및 이미지 리소스 이름 구성

    ACR_SUB_ID=myAcrSubscriptionId
    ACR_RG=myAcrResourceGroup
    # Name of the existing registry example: myregistry.azurecr.io
    ACR_NAME=myregistry
    # Existing full domain of the ACR
    REGISTRY=$ACR_NAME.azurecr.io
    # Container name inside ACR where image will be stored
    REPO=net-monitor
    TAG=v1
    IMAGE=$REGISTRY/${REPO}:$TAG
    # Source code directory containing Dockerfile to build
    IMAGE_SOURCE=https://github.com/wabbit-networks/net-monitor.git#main
    

Azure CLI로 로그인

az login

Azure CLI 및 로그인 방법에 대한 자세한 내용은 Azure CLI로 로그인을 참조하세요.

ACR 및 AKV에 대한 액세스 권한 보호

ACR 및 AKV를 사용할 때는 안전하고 제어된 액세스를 보장하기 위해 적절한 권한을 부여해야 합니다. 특정 시나리오에 따라 사용자 보안 주체, 서비스 주체 또는 관리 ID와 같은 다양한 엔터티에 대한 액세스 권한을 부여할 수 있습니다. 이 자습서에서는 로그인한 Azure 사용자에게 액세스 권한이 부여됩니다.

ACR에 대한 액세스 권한 부여

ACR에서 컨테이너 이미지에 서명하려면 AcrPullAcrPush 역할이 필요합니다.

  1. ACR 리소스를 포함하는 구독 설정

    az account set --subscription $ACR_SUB_ID
    
  2. 역할 할당

    USER_ID=$(az ad signed-in-user show --query id -o tsv)
    az role assignment create --role "AcrPull" --role "AcrPush" --assignee $USER_ID --scope "/subscriptions/$ACR_SUB_ID/resourceGroups/$ACR_RG/providers/Microsoft.ContainerRegistry/registries/$ACR_NAME"
    

AKV에 대한 액세스 권한 부여

이 섹션에서는 AKV에 대한 액세스 권한을 부여하기 위한 두 가지 옵션을 살펴보겠습니다.

자체 서명된 인증서를 사용하여 서명하려면 다음 역할이 필요합니다.

  • 인증서를 만들고 읽기 위한 Key Vault Certificates Officer
  • 기존 인증서를 읽기 위한 Key Vault Certificates User
  • 작업에 서명하기 위한 Key Vault Crypto User

Azure RBAC를 사용한 Key Vault 액세스에 대한 자세한 내용은 액세스를 관리하기 위해 Azure RBAC 사용을 참조하세요.

  1. AKV 리소스가 포함된 구독 설정

    az account set --subscription $AKV_SUB_ID
    
  2. 역할 할당

    USER_ID=$(az ad signed-in-user show --query id -o tsv)
    az role assignment create --role "Key Vault Certificates Officer" --role "Key Vault Crypto User" --assignee $USER_ID --scope "/subscriptions/$AKV_SUB_ID/resourceGroups/$AKV_RG/providers/Microsoft.KeyVault/vaults/$AKV_NAME"
    

AKV에서 액세스 정책 할당(레거시)

ID에는 다음 권한이 필요합니다.

  • 인증서를 만들기 위한 Create 권한
  • 기존 인증서를 읽기 위한 Get 권한
  • 작업에 서명하기 위한 Sign 권한

보안 주체에 정책을 할당하는 방법에 대한 자세한 내용은 액세스 정책 할당을 참조하세요.

  1. AKV 리소스가 포함된 구독을 설정합니다.

    az account set --subscription $AKV_SUB_ID
    
  2. AKV에서 액세스 정책을 설정합니다.

    USER_ID=$(az ad signed-in-user show --query id -o tsv)
    az keyvault set-policy -n $AKV_NAME --certificate-permissions create get --key-permissions sign --object-id $USER_ID
    

Important

이 예제에서는 인증서를 만들고 컨테이너 이미지에 서명하는 데 필요한 최소 권한을 보여 줍니다. 요구 사항에 따라 추가 권한을 부여해야 할 수 있습니다.

AKV에서 자체 서명된 인증서 만들기(Azure CLI)

다음 단계에서는 테스트 목적으로 자체 서명된 인증서를 만드는 방법을 보여줍니다.

  1. 인증서 정책 파일 만들기

    아래와 같이 인증서 정책 파일이 실행되면 AKV의 공증 프로젝트 인증서 요구 사항과 호환되는 유효한 인증서가 생성됩니다. ekus 값은 코드 서명용이지만 아티팩트에 서명하기 위한 notation에는 필요하지 않습니다. 주체는 나중에 확인 중에 사용자가 신뢰하는 신뢰 ID로 사용됩니다.

    cat <<EOF > ./my_policy.json
    {
        "issuerParameters": {
        "certificateTransparency": null,
        "name": "Self"
        },
        "keyProperties": {
          "exportable": false,
          "keySize": 2048,
          "keyType": "RSA",
          "reuseKey": true
        },
        "secretProperties": {
          "contentType": "application/x-pem-file"
        },
        "x509CertificateProperties": {
        "ekus": [
            "1.3.6.1.5.5.7.3.3"
        ],
        "keyUsage": [
            "digitalSignature"
        ],
        "subject": "$CERT_SUBJECT",
        "validityInMonths": 12
        }
    }
    EOF
    
  2. 인증서 만들기

    az keyvault certificate create -n $CERT_NAME --vault-name $AKV_NAME -p @my_policy.json
    

Notation CLI 및 AKV 플러그 인을 사용하여 컨테이너 이미지에 서명

  1. 개별 Azure ID를 사용하여 ACR에 인증합니다.

    az acr login --name $ACR_NAME
    

Important

Docker가 시스템에 설치되어 있고 az acr login 또는 docker login을 사용하여 ACR에 인증하는 경우 자격 증명이 이미 저장되어 notation으로 사용할 수 있습니다. 이 경우 ACR에 인증하기 위해 notation login을 다시 실행할 필요가 없습니다. notation 인증 옵션에 대한 자세한 내용은 OCI 규격 레지스트리로 인증을 참조하세요.

  1. ACR 작업을 사용하여 새 이미지 빌드 및 푸시 태그는 변경 가능하고 덮어쓸 수 있으므로 항상 다이제스트 값을 사용하여 서명할 이미지를 식별합니다.

    DIGEST=$(az acr build -r $ACR_NAME -t $REGISTRY/${REPO}:$TAG $IMAGE_SOURCE --no-logs --query "outputImages[0].digest" -o tsv)
    IMAGE=$REGISTRY/${REPO}@$DIGEST
    

    이 자습서에서 이미지가 이미 빌드되어 레지스트리에 저장된 경우 태그는 편의를 위해 해당 이미지의 식별자로 사용됩니다.

    IMAGE=$REGISTRY/${REPO}:$TAG
    
  2. 서명 키의 키 ID를 가져옵니다. AKV의 인증서에는 여러 버전이 있을 수 있습니다. 다음 명령은 최신 버전의 키 ID를 가져옵니다.

    KEY_ID=$(az keyvault certificate show -n $CERT_NAME --vault-name $AKV_NAME --query 'kid' -o tsv)
    
  3. 서명 키 ID를 사용하여 COSE 서명 형식으로 컨테이너 이미지에 서명합니다. 자체 서명된 인증서로 서명하려면 플러그 인 구성 값 self_signed=true를 설정해야 합니다.

    notation sign --signature-format cose --id $KEY_ID --plugin azure-kv --plugin-config self_signed=true $IMAGE
    

    AKV로 인증하려면 기본적으로 다음 자격 증명 유형이 사용하도록 설정된 경우 순서대로 시도됩니다.

    자격 증명 유형을 지정하려면 credential_type이라는 추가 플러그 인 구성을 사용합니다. 예를 들어, 아래 설명된 것처럼 Azure CLI 자격 증명을 사용하기 위해 명시적으로 credential_typeazurecli로 설정할 수 있습니다.

    notation sign --signature-format cose --id $KEY_ID --plugin azure-kv --plugin-config self_signed=true --plugin-config credential_type=azurecli $IMAGE
    

    다양한 자격 증명 유형에 대한 credential_type 값은 아래 표를 참조하세요.

    자격 증명 유형 credential_type에 대한 값
    환경 자격 증명 environment
    워크로드 ID 자격 증명 workloadid
    관리 ID 자격 증명 managedid
    Azure CLI 자격 증명 azurecli
  4. 서명된 이미지 및 연결된 서명의 그래프를 봅니다.

    notation ls $IMAGE
    

Notation CLI로 컨테이너 이미지 확인

컨테이너 이미지를 확인하려면 리프 인증서에 서명하는 루트 인증서를 트러스트 저장소에 추가하고 확인을 위한 신뢰 정책을 만듭니다. 이 자습서에서 사용되는 자체 서명된 인증서의 경우 루트 인증서는 자체 서명된 인증서 자체입니다.

  1. 공용 인증서 다운로드

    az keyvault certificate download --name $CERT_NAME --vault-name $AKV_NAME --file $CERT_PATH
    
  2. 서명 확인을 위해 다운로드한 공용 인증서를 명명된 신뢰 저장소에 추가합니다.

    STORE_TYPE="ca"
    STORE_NAME="wabbit-networks.io"
    notation cert add --type $STORE_TYPE --store $STORE_NAME $CERT_PATH
    
  3. 확인할 인증서를 나열합니다.

    notation cert ls
    
  4. 확인 전에 신뢰 정책을 구성합니다.

    신뢰 정책을 사용하면 사용자가 미세 조정된 확인 정책을 지정할 수 있습니다. 다음 예제에서는 $REGISTRY/$REPO의 모든 아티팩트에 적용되고 형식 $STORE_TYPE의 명명된 신뢰 저장소 $STORE_NAME을 사용하는 wabbit-networks-images라는 트러스트 정책을 구성합니다. 또한 사용자가 X.509 주체 $CERT_SUBJECT가 있는 특정 ID를 신뢰한다고 가정합니다. 자세한 내용은 신뢰 저장소 및 신뢰 정책 사양을 참조하세요.

    cat <<EOF > ./trustpolicy.json
    {
        "version": "1.0",
        "trustPolicies": [
            {
                "name": "wabbit-networks-images",
                "registryScopes": [ "$REGISTRY/$REPO" ],
                "signatureVerification": {
                    "level" : "strict" 
                },
                "trustStores": [ "$STORE_TYPE:$STORE_NAME" ],
                "trustedIdentities": [
                    "x509.subject: $CERT_SUBJECT"
                ]
            }
        ]
    }
    EOF
    
  5. notation policy를 사용하여 이전에 만든 JSON 파일에서 신뢰 정책 구성을 가져옵니다.

    notation policy import ./trustpolicy.json
    notation policy show
    
  6. notation verify를 사용하여 빌드 시간 이후 컨테이너 이미지가 변경되지 않았는지 확인합니다.

    notation verify $IMAGE
    

    신뢰 정책을 사용하여 이미지를 성공적으로 확인하면 확인된 이미지의 sha256 다이제스트가 성공적인 출력 메시지에 반환됩니다.

타임스탬프 처리

Notation v1.2.0 릴리스 이후 Notation은 RFC 3161 호환 타임스탬핑을 지원합니다. 이 향상된 기능은 TSA(타임스탬프 기관)를 신뢰하여 인증서의 유효 기간 내에 만들어진 서명의 신뢰를 확장하고, 인증서가 만료된 후에도 성공적인 서명 검증이 가능하도록 합니다. 이미지 서명자는 신뢰할 수 있는 TSA에서 생성한 타임스탬프로 컨테이너 이미지에 서명해야 합니다. 이미지 검증 도구의 경우 타임스탬프를 검증하려면 이미지 서명자와 관련 TSA를 모두 신뢰해야 하며, 신뢰 저장소와 신뢰 정책을 통해 신뢰를 구축해야 합니다. 타임스탬프를 사용하면 인증서 만료로 인해 주기적으로 이미지에 다시 서명할 필요성이 없어져 비용이 절감되는데, 이는 특히 유효 기간이 짧은 인증서를 사용할 때 매우 중요합니다. 타임스탬프를 사용하여 서명하고 확인하는 방법에 대한 자세한 지침은 공증 프로젝트 타임스탬프 가이드를 참조하세요.

다음 단계

또한 Notation은 Azure Pipeline 및 GitHub Actions 워크플로에서 CI/CD 솔루션을 제공합니다.

AKS 또는 Kubernetes에서 서명된 이미지 배포의 유효성을 검사하려면: