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 Container Registry를 만들거나 사용
- Azure Key Vault 만들거나 사용합니다.
- 최신 Azure CLI 설치 및 구성 또는 Azure Cloud Shell에서 명령 실행
참고 항목
인증서 저장 전용으로 새 Azure Key Vault를 만드는 것이 좋습니다.
표기법 CLI 및 AKV 플러그 인 설치
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
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
사용 가능한 플러그 인을 나열하고 버전이
1.2.0
인azure-kv
플러그 인이 목록에 포함되어 있는지 확인합니다.notation plugin ls
환경 변수 구성
참고 항목
이 가이드에서는 AKV 및 ACR을 구성할 때 편의를 위해 환경 변수를 사용합니다. 특정 리소스에 대해 이러한 환경 변수의 값을 업데이트합니다.
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"
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에서 인증서 가져오기
인증서를 가져오려면:
- 전체 인증서 체인이 포함된 CA 공급업체로부터 인증서 파일을 가져옵니다.
- 인증서 가져오기의 지침에 따라 인증서를 Azure Key Vault로 가져옵니다.
참고 항목
인증서를 만들거나 가져온 후 인증서에 인증서 체인이 포함되어 있지 않으면 CA 공급업체로부터 중간 및 루트 인증서를 가져올 수 있습니다. 공급업체에 중간 인증서(있는 경우)와 루트 인증서가 포함된 PEM 파일을 제공하도록 요청할 수 있습니다. 그런 다음 이 파일은 컨테이너 이미지 서명의 5단계에서 사용할 수 있습니다.
Notation CLI 및 AKV 플러그 인을 사용하여 컨테이너 이미지에 서명
ACR 및 AKV를 사용할 때는 안전하고 제어된 액세스를 보장하기 위해 적절한 권한을 부여해야 합니다. 특정 시나리오에 따라 사용자 계정, 서비스 주체 또는 관리 ID와 같은 다양한 엔터티에 대한 액세스 권한을 부여할 수 있습니다. 이 자습서에서는 로그인한 Azure 사용자에게 액세스 권한이 부여됩니다.
ACR에 대한 액세스 작성
ACR에서 컨테이너 이미지를 빌드하고 서명하려면 AcrPull
및 AcrPush
역할이 필요합니다.
ACR 리소스를 포함하는 구독 설정
az account set --subscription $ACR_SUB_ID
역할 할당
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에 푸시
개별 Azure ID를 사용하여 ACR에 인증합니다.
az acr login --name $ACR_NAME
Important
Docker가 시스템에 설치되어 있고 az acr login
또는 docker login
을 사용하여 ACR에 인증하는 경우 자격 증명이 이미 저장되어 notation으로 사용할 수 있습니다. 이 경우 ACR에 인증하기 위해 notation login
을 다시 실행할 필요가 없습니다. notation 인증 옵션에 대한 자세한 내용은 OCI 규격 레지스트리로 인증을 참조하세요.
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에 대한 액세스 승인
Azure RBAC 사용(권장)
AKV 리소스가 포함된 구독 설정
az account set --subscription $AKV_SUB_ID
역할 할당
인증서에 전체 인증서 체인이 포함되어 있는 경우 보안 주체에는 다음 역할이 할당되어야 합니다.
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의 인증서를 사용하여 컨테이너 이미지에 서명
인증서의 키 ID를 가져옵니다. AKV의 인증서에는 여러 버전이 있을 수 있습니다. 다음 명령은
$CERT_NAME
인증서의 최신 버전에 대한 키 ID를 가져옵니다.KEY_ID=$(az keyvault certificate show -n $CERT_NAME --vault-name $AKV_NAME --query 'kid' -o tsv)
키 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_type
을azurecli
로 설정할 수 있습니다.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
서명된 이미지 및 연결된 서명의 그래프를 봅니다.
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로 컨테이너 이미지 확인
서명 확인을 위해 명명된 신뢰 저장소에 루트 인증서를 추가합니다. 루트 인증서가 없으면 CA에서 가져올 수 있습니다. 다음 예에서는 루트 인증서
$ROOT_CERT
를$STORE_NAME
신뢰 저장소에 추가합니다.STORE_TYPE="ca" STORE_NAME="wabbit-networks.io" notation cert add --type $STORE_TYPE --store $STORE_NAME $ROOT_CERT
$ROOT_CERT
가 성공적으로 추가되었는지 확인하려면 루트 인증서를 나열합니다.notation cert ls
확인 전에 신뢰 정책을 구성합니다.
신뢰 정책을 사용하면 사용자가 미세 조정된 확인 정책을 지정할 수 있습니다. 다음 명령을 사용하여 신뢰 정책을 구성합니다.
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를 신뢰한다고 가정합니다. 자세한 내용은 신뢰 저장소 및 신뢰 정책 사양을 참조하세요.notation policy
를 사용하여trustpolicy.json
에서 신뢰 정책 구성을 가져옵니다.notation policy import ./trustpolicy.json
성공적인 가져오기를 확인하기 위해 신뢰 정책 구성을 표시합니다.
notation policy show
이미지의 무결성을 확인하려면
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에서 서명된 이미지 배포의 유효성을 검사하려면: