Udostępnij przez


Podpisywanie obrazów kontenerów przy użyciu notacji, usługi Azure Key Vault i certyfikatu z podpisem własnym

Ten artykuł jest częścią serii dotyczącej zapewniania integralności i autentyczności obrazów kontenerów oraz innych artefaktów Open Container Initiative (OCI). Aby uzyskać pełny obraz, zacznij od omówienia, co wyjaśnia, dlaczego podpisywanie ma znaczenie i przedstawia różne scenariusze.

Podpisywanie obrazów kontenerów to proces, który pomaga zapewnić ich autentyczność i integralność. Podpis cyfrowy dodany do obrazu kontenera jest weryfikowany podczas wdrażania. Podpis pomaga sprawdzić, czy obraz pochodzi z zaufanego wydawcy i nie jest modyfikowany.

W tym artykule omówiono następujące narzędzia związane z procesem podpisywania:

  • Notacja to narzędzie zabezpieczeń łańcucha dostaw typu open source opracowane przez społeczność Notary Project i wspierane przez firmę Microsoft. Obsługuje podpisywanie i weryfikowanie obrazów kontenerów oraz innych artefaktów.

    Jeśli chcesz podpisać obraz kontenera przy użyciu notacji w potokach ciągłej integracji i ciągłego dostarczania (CI/CD), postępuj zgodnie ze wskazówkami dotyczącymi usługi Azure Pipelines lub GitHub Actions.

  • Azure Key Vault to usługa do przechowywania certyfikatów z kluczami podpisywania. Notacja może używać tych kluczy za pośrednictwem wtyczki usługi Key Vault (notation-azure-kv), aby podpisać i zweryfikować obrazy kontenerów oraz inne artefakty.

  • Usługa Azure Container Registry to prywatny rejestr, za pomocą którego można dołączać podpisy do obrazów kontenerów i innych artefaktów oraz wyświetlać te podpisy.

W tym artykule dowiesz się, jak:

  • Zainstaluj interfejs wiersza polecenia Notation (CLI) i wtyczkę Key Vault.
  • Utwórz certyfikat z podpisem własnym w usłudze Key Vault.
  • Kompilowanie i wypychanie obrazu kontenera przy użyciu zadań usługi Container Registry.
  • Podpisz obraz kontenera przy użyciu interfejsu wiersza polecenia Notation i wtyczki Key Vault.
  • Zweryfikuj obraz kontenera względem podpisu, używając Notation CLI.
  • Użyj znacznika czasu.

Wymagania wstępne

Zainstaluj wtyczkę Notation CLI i Key Vault

  1. Zainstaluj notację w wersji 1.3.2 w środowisku z systemem Linux AMD64. Aby pobrać pakiet dla innych środowisk, postępuj zgodnie z przewodnikiem instalacji notacji.

    # Download, extract, and install
    curl -Lo notation.tar.gz https://github.com/notaryproject/notation/releases/download/v1.3.2/notation_1.3.2_linux_amd64.tar.gz
    tar xvzf notation.tar.gz
    
    # Copy the Notation binary to the desired bin directory in $PATH, for example
    cp ./notation /usr/local/bin
    
  2. Zainstaluj wtyczkę usługi Key Vault (notation-azure-kv) w wersji 1.2.1 w środowisku systemu Linux AMD64.

    Uwaga / Notatka

    Adres URL i sumę kontrolną SHA256 dla wtyczki można znaleźć na stronie wydania wtyczki.

    notation plugin install --url https://github.com/Azure/notation-azure-kv/releases/download/v1.2.1/notation-azure-kv_1.2.1_linux_amd64.tar.gz --sha256sum 67c5ccaaf28dd44d2b6572684d84e344a02c2258af1d65ead3910b3156d3eaf5
    
  3. Wyświetl listę dostępnych wtyczek i upewnij się, że wtyczka notation-azure-kv z wersją 1.2.1 znajduje się na liście:

    notation plugin ls
    

Skonfiguruj zmienne środowiskowe

Aby ułatwić wykonywanie poleceń w tym artykule, podaj wartości zasobów platformy Azure, aby dopasować je do istniejących zasobów usługi Container Registry i Key Vault.

  1. Konfigurowanie nazw zasobów usługi Key Vault:

    AKV_SUB_ID=myAkvSubscriptionId
    AKV_RG=myAkvResourceGroup
    # Name of the existing key vault used to store the signing keys
    AKV_NAME=myakv
    # Name of the certificate created in the key vault
    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. Skonfiguruj usługę Container Registry i nazwy zasobów obrazów:

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

Logowanie przy użyciu interfejsu wiersza polecenia platformy Azure

az login

Aby uzyskać więcej informacji, zobacz Uwierzytelnianie na platformie Azure przy użyciu interfejsu wiersza polecenia platformy Azure.

Udzielanie uprawnień dostępu do usługi Container Registry i Key Vault

Podczas pracy z usługą Container Registry i Key Vault niezbędne jest przyznanie odpowiednich uprawnień w celu zapewnienia bezpiecznego i kontrolowanego dostępu. W zależności od określonych scenariuszy można autoryzować dostęp do różnych podmiotów, takich jak użytkownicy główni, usługi główne lub tożsamości zarządzane. W tym artykule dostęp jest autoryzowany dla zalogowanego użytkownika platformy Azure.

Autoryzowanie dostępu do usługi Container Registry

Dla rejestrów z włączoną kontrolą dostępu opartą na atrybutach Microsoft Entra (ABAC) wymagane są role Container Registry Repository Reader i Container Registry Repository Writer do tworzenia i podpisywania obrazów kontenerów w Rejestrze kontenerów.

W przypadku rejestrów, które nie są włączone dla usługi ABAC, wymagane są role AcrPull i AcrPush.

Aby uzyskać więcej informacji na temat kontroli dostępu ABAC, zobacz kontrola dostępu oparta na atrybutach Microsoft Entra dla uprawnień repozytorium.

  1. Ustaw subskrypcję zawierającą zasób usługi Container Registry:

    az account set --subscription $ACR_SUB_ID
    
  2. Przypisz role. Prawidłowa rola do użycia w przypisaniu roli zależy od tego, czy rejestr ma włączoną funkcję ABAC, czy nie.

    USER_ID=$(az ad signed-in-user show --query id -o tsv)
    ROLE1="Container Registry Repository Reader" # For ABAC-enabled registries. Otherwise, use "AcrPull" for non-ABAC-enabled registries.
    ROLE2="Container Registry Repository Writer" # For ABAC-enabled registries. Otherwise, use "AcrPush" for non-ABAC-enabled registries.
    az role assignment create --role "$ROLE1" --role "$ROLE2" --assignee $USER_ID --scope "/subscriptions/$ACR_SUB_ID/resourceGroups/$ACR_RG/providers/Microsoft.ContainerRegistry/registries/$ACR_NAME"
    

Autoryzowanie dostępu do usługi Key Vault

W tej sekcji opisano dwie opcje autoryzowania dostępu do usługi Key Vault.

Do podpisywania wymagane są następujące role przy użyciu certyfikatów z podpisem własnym:

  • Key Vault Certificates Officer do tworzenia i odczytywania certyfikatów
  • Key Vault Certificates User do odczytywania istniejących certyfikatów
  • Key Vault Crypto User na potrzeby operacji podpisywania

Aby dowiedzieć się więcej o dostępie do usługi Key Vault za pomocą kontroli dostępu opartej na rolach (RBAC) platformy Azure, zobacz Zapewnianie dostępu do kluczy, certyfikatów i wpisów tajnych usługi Key Vault przy użyciu kontroli dostępu opartej na rolach platformy Azure.

  1. Ustaw subskrypcję zawierającą zasób usługi Key Vault:

    az account set --subscription $AKV_SUB_ID
    
  2. Przypisz role:

    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"
    

Przypisywanie zasad dostępu w usłudze Key Vault (starsza wersja)

Dla tożsamości wymagane są następujące uprawnienia:

  • Create uprawnienia do tworzenia certyfikatu
  • Get uprawnienia do odczytywania istniejących certyfikatów
  • Sign uprawnienia do operacji podpisywania

Aby dowiedzieć się więcej na temat przypisywania zasad dostępu do głównego podmiotu, zobacz Przypisywanie zasad dostępu do Key Vault (starsza wersja).

  1. Ustaw subskrypcję zawierającą zasób usługi Key Vault:

    az account set --subscription $AKV_SUB_ID
    
  2. Ustaw zasady dostępu w usłudze Key Vault:

    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
    

Ważne

W tym przykładzie przedstawiono minimalne uprawnienia potrzebne do utworzenia certyfikatu i podpisania obrazu kontenera. W zależności od wymagań może być konieczne przyznanie większej liczby uprawnień.

Tworzenie certyfikatu z podpisem własnym w usłudze Key Vault (interfejs wiersza polecenia platformy Azure)

W poniższych krokach pokazano, jak utworzyć certyfikat z podpisem własnym na potrzeby testowania:

  1. Utwórz plik zasad certyfikatu.

    Po wykonaniu pliku zasad certyfikatu za pomocą następującego kodu, tworzony jest prawidłowy certyfikat zgodny z wymaganiami dotyczącymi certyfikatów projektu Notary w Key Vault. Wartość parametru ekus dotyczy podpisywania kodu, ale nie jest wymagana do tego, by notacja podpisywała artefakty. Podmiot jest używany później jako zaufana tożsamość podczas weryfikacji.

    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. Utwórz certyfikat:

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

Podpisywanie obrazu kontenera przy użyciu wtyczki Notation CLI i Key Vault

  1. Uwierzytelnianie w rejestrze kontenerów przy użyciu indywidualnej tożsamości platformy Azure:

    az acr login --name $ACR_NAME
    

    Ważne

    Jeśli Docker jest zainstalowany w systemie i użyto az acr login lub docker login do uwierzytelnienia w rejestrze kontenerów, twoje poświadczenia są już przechowywane i dostępne dla Notation. W takim przypadku nie trzeba uruchamiać notation login ponownie, aby uwierzytelnić się w rejestrze kontenerów. Aby dowiedzieć się więcej o opcjach uwierzytelniania dla notacji, zobacz Uwierzytelnianie przy użyciu rejestrów zgodnych z protokołem OCI.

  2. Skompiluj i wypchnij nowy obraz przy użyciu zadań usługi Azure Container Registry. Zawsze używaj wartości skrótu, aby zidentyfikować obraz do podpisywania, ponieważ tagi są modyfikowalne i można je zastąpić.

    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
    

    W tym artykule, jeśli obraz jest już skompilowany i jest przechowywany w rejestrze, tag służy jako identyfikator dla tego obrazu dla wygody:

    IMAGE=$REGISTRY/${REPO}:$TAG
    
  3. Pobierz identyfikator klucza podpisywania. Certyfikat w usłudze Key Vault może mieć wiele wersji. Następująca komenda uzyskuje identyfikator klucza najnowszej wersji.

    KEY_ID=$(az keyvault certificate show -n $CERT_NAME --vault-name $AKV_NAME --query 'kid' -o tsv)
    
  4. Podpisz obraz kontenera za pomocą formatu podpisu podpisywania i szyfrowania obiektów CBOR (COSE), używając identyfikatora klucza podpisującego. Aby podpisać się certyfikatem z podpisem własnym, należy ustawić wartość konfiguracji wtyczki self_signed=true.

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

    Aby uwierzytelnić się w usłudze Key Vault, domyślnie następujące typy poświadczeń (jeśli są włączone) są wypróbowane w następującej kolejności:

    Jeśli chcesz określić typ poświadczeń, użyj dodatkowej konfiguracji wtyczki o nazwie credential_type. Możesz na przykład jawnie ustawić wartość credential_type na azurecli do używania poświadczeń interfejsu wiersza polecenia platformy Azure, jak pokazano w tym przykładzie:

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

    W poniższej tabeli przedstawiono wartości credential_type dla różnych typów poświadczeń.

    Typ poświadczeń Wartość dla credential_type
    Poświadczenie środowiskowe environment
    Poświadczenia tożsamości obciążenia roboczego workloadid
    Poświadczenie zarządzanej tożsamości managedid
    Poświadczenia CLI platformy Azure azurecli

    Uwaga / Notatka

    Od wersji Notation 1.2.0, Notation zapisuje podpis w Container Registry, wykorzystując schemat tagów odwołań OCI domyślnie. Możesz również włączyć API odwołań OCI przy użyciu flagi --force-referrers-tag false, jeśli to konieczne. Funkcje usługi Container Registry obsługują interfejs API odwołań OCI, z wyjątkiem rejestru zaszyfrowanego za pośrednictwem kluczy zarządzanych przez klienta (CMKs).

  5. Wyświetl wykres podpisanych obrazów i skorelowanych podpisów.

    notation ls $IMAGE
    

Weryfikowanie obrazu kontenera przy użyciu interfejsu wiersza polecenia Notacji

Aby zweryfikować obraz kontenera, dodaj certyfikat główny podpisujący certyfikat liścia do magazynu zaufania i utwórz zasady zaufania na potrzeby weryfikacji. W przypadku certyfikatu z podpisem własnym używanego w tym artykule certyfikat główny jest certyfikatem z podpisem własnym.

  1. Pobierz certyfikat publiczny:

    az keyvault certificate download --name $CERT_NAME --vault-name $AKV_NAME --file $CERT_PATH
    
  2. Dodaj pobrany certyfikat publiczny do nazwanego magazynu zaufania na potrzeby weryfikacji podpisu:

    STORE_TYPE="ca"
    STORE_NAME="wabbit-networks.io"
    notation cert add --type $STORE_TYPE --store $STORE_NAME $CERT_PATH
    
  3. Wyświetl listę certyfikatów, aby potwierdzić:

    notation cert ls
    
  4. Skonfiguruj zasady zaufania przed weryfikacją.

    Zasady zaufania umożliwiają użytkownikom określanie dostrojonych zasad weryfikacji. W poniższym przykładzie skonfigurowano zasady zaufania o nazwie wabbit-networks-images. Ta polityka dotyczy wszystkich artefaktów w $REGISTRY/$REPO i używa nazwanego repozytorium zaufania $STORE_NAME typu $STORE_TYPE. Przyjęto również założenie, że użytkownik ufa określonej tożsamości poprzez temat X.509 $CERT_SUBJECT. Aby uzyskać więcej informacji, zobacz Magazyn zaufania i specyfikacje zasad zaufania.

    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. Użyj notation policy polecenia , aby zaimportować konfigurację zasad zaufania z utworzonego wcześniej pliku JSON:

    notation policy import ./trustpolicy.json
    notation policy show
    
  6. Użyj polecenia notation verify , aby sprawdzić, czy obraz kontenera nie został zmieniony po czasie kompilacji:

    notation verify $IMAGE
    

    Po pomyślnej weryfikacji obrazu za pośrednictwem zasad zaufania skrót SHA256 zweryfikowanego obrazu jest zwracany w pomyślnym komunikacie wyjściowym.

Użyj znacznika czasu

Od wersji 1.2.0 Notation obsługuje znaczniki czasu zgodne ze standardem RFC 3161. To ulepszenie rozszerza zaufanie do podpisów utworzonych w okresie ważności certyfikatu przez zaufanie do urzędu sygnatury czasowej (TSA). To zaufanie umożliwia pomyślną weryfikację podpisu nawet po wygaśnięciu certyfikatów.

Jako podpisujący obrazy kontenerowe, należy upewnić się, że podpisujesz je przy użyciu sygnatur czasowych wygenerowanych przez zaufany TSA. Jako weryfikator obrazów należy upewnić się, że ufasz zarówno podpisującemu obraz, jak i skojarzonemu TSA, oraz nawiązać relację zaufania za pośrednictwem magazynów zaufania i zasad zaufania.

Zastosowanie znakowania czasem zmniejsza koszty poprzez eliminację konieczności okresowego ponownego podpisywania obrazów z powodu wygaśnięcia certyfikatu. Ta możliwość jest szczególnie krytyczna w przypadku używania certyfikatów krótkotrwałych. Aby uzyskać szczegółowe instrukcje dotyczące podpisywania i weryfikowania obrazów przy użyciu sygnatury czasowej, zapoznaj się z przewodnikiem projektu Notary dotyczącym sygnatury czasowej.

Notation zapewnia rozwiązania CI/CD za pomocą Azure Pipelines i GitHub Actions.

Aby upewnić się, że w usłudze Azure Kubernetes Service (AKS) są wdrażane tylko zaufane obrazy kontenerów: