다음을 통해 공유


CA 발급 인증서를 사용하여 표기법 및 Azure Key Vault로 컨테이너 이미지에 서명합니다.

신뢰할 수 있는 CA(인증 기관)에서 발급한 인증서로 컨테이너 이미지에 서명하고 확인하는 것은 중요한 보안 사례입니다. 이 보안 조치는 컨테이너 이미지 게시자와 컨테이너 이미지 자체의 ID를 책임감 있게 식별, 권한 부여 및 유효성 검사하는 데 도움이 됩니다. GlobalSign, DigiCert 등과 같은 신뢰할 수 있는 CA(인증 기관)는 사용자 또는 조직의 ID의 유효성을 검사하고 디지털 인증서의 보안을 유지하며 위험이나 오용이 발생할 경우 즉시 인증서를 취소하는 데 중요한 역할을 합니다.

신뢰할 수 있는 CA에서 발급한 인증서로 컨테이너 이미지를 서명하고 확인하는 데 도움이 되는 몇 가지 필수 구성 요소는 다음과 같습니다.

  • Notation은 컨테이너 이미지 및 기타 아티팩트 서명 및 확인을 지원하는 Microsoft에서 지원하는 Notary Project 커뮤니티에서 개발한 오픈 소스 공급망 보안 도구입니다.
  • 암호화 키, 비밀 및 인증서를 관리하기 위한 클라우드 기반 서비스인 AKV(Azure Key Vault)는 서명 키를 사용하여 인증서를 안전하게 저장하고 관리하는 데 도움이 됩니다.
  • 표기법의 확장인 표기법 AKV 플러그 인 azure-kv는 Azure Key Vault에 저장된 키를 사용하여 컨테이너 이미지와 아티팩트의 디지털 서명을 서명하고 확인합니다.
  • ACR(Azure Container Registry)을 사용하면 이러한 서명을 서명된 이미지에 연결할 수 있으며 이러한 컨테이너 이미지를 저장하고 관리하는 데 도움이 됩니다.

이미지의 유효성을 검사할 때 서명은 이미지의 무결성과 서명자의 ID의 유효성을 검사하는 데 사용됩니다. 이는 컨테이너 이미지가 변조되지 않았으며 신뢰할 수 있는 원본에서 가져온 것인지 확인하는 데 도움이 됩니다.

문서 내용:

  • 표기법 CLI 및 AKV 플러그 인 설치
  • AKV에서 CA가 발급한 인증서 만들기 또는 가져오기
  • ACR 작업을 사용하여 컨테이너 이미지 빌드 및 푸시
  • Notation CLI 및 AKV 플러그 인을 사용하여 컨테이너 이미지에 서명
  • 표기법 CLI로 컨테이너 이미지 서명 확인
  • 타임스탬프 처리

필수 조건

참고 항목

인증서 저장 전용으로 새 Azure Key Vault를 만드는 것이 좋습니다.

표기법 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 cli 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
    

환경 변수 구성

참고 항목

이 가이드에서는 AKV 및 ACR을 구성할 때 편의를 위해 환경 변수를 사용합니다. 특정 리소스에 대해 이러한 환경 변수의 값을 업데이트합니다.

  1. AKV 및 인증서에 대한 환경 변수 구성

    AKV_SUB_ID=myAkvSubscriptionId
    AKV_RG=myAkvResourceGroup
    AKV_NAME=myakv 
    
    # Name of the certificate created or imported in AKV 
    CERT_NAME=wabbit-networks-io 
    
    # X.509 certificate subject
    CERT_SUBJECT="CN=wabbit-networks.io,O=Notation,L=Seattle,ST=WA,C=US"
    
  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 
    # 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로 로그인을 참조하세요.

AKV에서 CA가 발급한 인증서 만들기 또는 가져오기

인증서 요구 사항

서명 및 확인을 위한 인증서를 만들 때 인증서는 공증 프로젝트 인증서 요구 사항을 충족해야 합니다.

루트 및 중간 인증서에 대한 요구 사항은 다음과 같습니다.

  • basicConstraints 확장이 존재하고 중요로 표시되어야 합니다. CA 필드는 true로 설정되어야 합니다.
  • keyUsage 확장이 존재하고 critical로 표시되어야 합니다. keyCertSign의 비트 위치를 설정해야 합니다.

CA에서 발급한 인증서에 대한 요구 사항은 다음과 같습니다.

  • X.509 인증서 속성:
    • 제목에는 일반 이름(CN), 국가(C), 시/도(ST) 및 조직(O)이 포함되어야 합니다. 이 자습서에서는 $CERT_SUBJECT가 주체로 사용됩니다.
    • X.509 키 사용 플래그는 DigitalSignature여야 합니다.
    • EKU(확장 키 사용)는 비어 있거나 1.3.6.1.5.5.7.3.3(공동 디자인의 경우)이어야 합니다.
  • 키 속성:
    • exportable 속성을 false(으)로 설정해야 합니다.
    • 공증 프로젝트 사양에서 지원되는 키 형식과 크기를 선택합니다.

Important

이미지 무결성과 성공적으로 통합하려면 인증서의 콘텐츠 형식을 PEM으로 설정해야 합니다.

참고 항목

이 가이드에서는 AKV 플러그 인 버전 1.0.1을 사용합니다. 이전 버전의 플러그 인에는 인증서 체인에서 특정 인증서 주문이 필요한 제한 사항이 있었습니다. 플러그 인 버전 1.0.1에는 이러한 제한 사항이 없으므로 버전 1.0.1 이상을 사용하는 것이 좋습니다.

CA에서 발급한 인증서 만들기

인증서 서명 요청 만들기의 지침에 따라 CSR(인증서 서명 요청)을 만듭니다.

Important

CSR을 병합할 때 CA 공급업체에서 가져온 전체 체인을 병합해야 합니다.

AKV에서 인증서 가져오기

인증서를 가져오려면:

  1. 전체 인증서 체인이 포함된 CA 공급업체로부터 인증서 파일을 가져옵니다.
  2. 인증서 가져오기의 지침에 따라 인증서를 Azure Key Vault로 가져옵니다.

참고 항목

인증서를 만들거나 가져온 후 인증서에 인증서 체인이 포함되어 있지 않으면 CA 공급업체로부터 중간 및 루트 인증서를 가져올 수 있습니다. 공급업체에 중간 인증서(있는 경우)와 루트 인증서가 포함된 PEM 파일을 제공하도록 요청할 수 있습니다. 그런 다음 이 파일은 컨테이너 이미지 서명의 5단계에서 사용할 수 있습니다.

Notation CLI 및 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"
    

컨테이너 이미지를 빌드하고 ACR에 푸시

  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를 사용하여 서명할 이미지를 식별합니다.

    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

AKV에 대한 액세스 승인

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

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

    인증서에 전체 인증서 체인이 포함되어 있는 경우 보안 주체에는 다음 역할이 할당되어야 합니다.

    • Key Vault Secrets User - 비밀 읽기
    • Key Vault Certificates User - 인증서 읽기
    • Key Vault Crypto User - 작업에 서명
    USER_ID=$(az ad signed-in-user show --query id -o tsv)
    az role assignment create --role "Key Vault Secrets User" --role "Key Vault Certificates User" --role "Key Vault Crypto User" --assignee $USER_ID --scope "/subscriptions/$AKV_SUB_ID/resourceGroups/$AKV_RG/providers/Microsoft.KeyVault/vaults/$AKV_NAME"
    

    인증서에 체인이 포함되어 있지 않으면 보안 주체에 다음 역할을 할당해야 합니다.

    • Key Vault Certificates User - 인증서 읽기
    • Key Vault Crypto User - 작업에 서명
    USER_ID=$(az ad signed-in-user show --query id -o tsv)
    az role assignment create --role "Key Vault Certificates User" --role "Key Vault Crypto User" --assignee $USER_ID --scope "/subscriptions/$AKV_SUB_ID/resourceGroups/$AKV_RG/providers/Microsoft.KeyVault/vaults/$AKV_NAME"
    

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

액세스 정책 사용(레거시)

AKV 리소스가 포함된 구독을 설정하려면 다음 명령을 실행합니다.

az account set --subscription $AKV_SUB_ID

인증서에 전체 인증서 체인이 포함되어 있는 경우 주체에게 키 권한 Sign, 비밀 권한 Get 및 인증서 권한 Get을 부여해야 합니다. 보안 주체에게 이러한 권한을 부여하려면 다음 안내를 따릅니다.

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

인증서에 체인이 포함되어 있지 않으면 주체에게 키 권한 Sign 및 인증서 권한 Get을 부여해야 합니다. 보안 주체에게 이러한 권한을 부여하려면 다음 안내를 따릅니다.

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

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

AKV의 인증서를 사용하여 컨테이너 이미지에 서명

  1. 인증서의 키 ID를 가져옵니다. AKV의 인증서에는 여러 버전이 있을 수 있습니다. 다음 명령은 $CERT_NAME 인증서의 최신 버전에 대한 키 ID를 가져옵니다.

    KEY_ID=$(az keyvault certificate show -n $CERT_NAME --vault-name $AKV_NAME --query 'kid' -o tsv) 
    
  2. 키 ID를 사용하여 CODE 서명 형식으로 컨테이너 이미지에 서명합니다.

    인증서에 전체 인증서 체인이 포함되어 있는 경우 다음 명령을 실행합니다.

    notation sign --signature-format cose $IMAGE --id $KEY_ID --plugin azure-kv 
    

    인증서에 체인이 포함되어 있지 않으면 --plugin-config ca_certs=<ca_bundle_file> 매개 변수를 사용하여 PEM 파일의 CA 인증서를 AKV 플러그 인에 전달하고 다음 명령을 실행합니다.

    notation sign --signature-format cose $IMAGE --id $KEY_ID --plugin azure-kv --plugin-config ca_certs=<ca_bundle_file> 
    

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

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

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

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

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

    notation ls $IMAGE
    

    다음 출력 예에서는 다이제스트 sha256:d7258166ca820f5ab7190247663464f2dcb149df4d1b6c4943dcaac59157de8e로 식별된 application/vnd.cncf.notary.signature 형식의 서명이 $IMAGE에 연결됩니다.

    myregistry.azurecr.io/net-monitor@sha256:17cc5dd7dfb8739e19e33e43680e43071f07497ed716814f3ac80bd4aac1b58f
    └── application/vnd.cncf.notary.signature
        └── sha256:d7258166ca820f5ab7190247663464f2dcb149df4d1b6c4943dcaac59157de8e
    

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

  1. 서명 확인을 위해 명명된 신뢰 저장소에 루트 인증서를 추가합니다. 루트 인증서가 없으면 CA에서 가져올 수 있습니다. 다음 예에서는 루트 인증서 $ROOT_CERT$STORE_NAME 신뢰 저장소에 추가합니다.

    STORE_TYPE="ca" 
    STORE_NAME="wabbit-networks.io" 
    notation cert add --type $STORE_TYPE --store $STORE_NAME $ROOT_CERT  
    
  2. $ROOT_CERT가 성공적으로 추가되었는지 확인하려면 루트 인증서를 나열합니다.

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

    신뢰 정책을 사용하면 사용자가 미세 조정된 확인 정책을 지정할 수 있습니다. 다음 명령을 사용하여 신뢰 정책을 구성합니다.

    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
    

    위의 trustpolicy.json 파일은 wabbit-networks-images라는 하나의 신뢰 정책을 정의합니다. 이 신뢰 정책은 $REGISTRY/$REPO 리포지토리에 저장된 모든 아티팩트에 적용됩니다. $STORE_TYPE 형식의 명명된 신뢰 저장소 $STORE_NAME에는 루트 인증서가 포함되어 있습니다. 또한 사용자가 X.509 주체 $CERT_SUBJECT가 있는 특정 ID를 신뢰한다고 가정합니다. 자세한 내용은 신뢰 저장소 및 신뢰 정책 사양을 참조하세요.

  4. notation policy를 사용하여 trustpolicy.json에서 신뢰 정책 구성을 가져옵니다.

    notation policy import ./trustpolicy.json
    
  5. 성공적인 가져오기를 확인하기 위해 신뢰 정책 구성을 표시합니다.

    notation policy show
    
  6. 이미지의 무결성을 확인하려면 notation verify를 사용합니다.

    notation verify $IMAGE
    

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

    Successfully verified signature for myregistry.azurecr.io/net-monitor@sha256:17cc5dd7dfb8739e19e33e43680e43071f07497ed716814f3ac80bd4aac1b58f

타임스탬프 처리

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

FAQ

  • 인증서가 만료된 경우 어떻게 해야 하나요?

    인증서가 만료된 경우 신뢰할 수 있는 CA 공급업체에서 새 인증서와 새 프라이빗 키를 가져와야 합니다. 만료된 인증서는 컨테이너 이미지에 서명하는 데 사용할 수 없습니다. 인증서가 만료되기 전에 서명된 이미지의 경우 타임스탬프로 서명되면 여전히 성공적으로 유효성을 검사할 수 있습니다. 타임스탬프가 없으면 서명 검증이 실패하며, 성공적인 검증을 위해 새 인증서로 해당 이미지에 다시 서명해야 합니다.

  • 인증서가 철회된 경우 어떻게 해야 하나요?

    인증서가 폐지되면 서명도 무효화됩니다. 이는 프라이빗 키가 손상되거나 인증서 보유자의 소속이 변경되는 등 여러 가지 이유로 발생할 수 있습니다. 이 문제를 해결하려면 먼저 소스 코드와 빌드 환경이 최신이고 안전한지 확인해야 합니다. 그런 다음 이 가이드에 따라 소스 코드에서 컨테이너 이미지를 빌드하고, 신뢰할 수 있는 CA 공급업체에서 새 인증서와 새 프라이빗 키를 가져오고, 새 인증서로 새 컨테이너 이미지에 서명합니다.

다음 단계

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

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