Freigeben über


Signieren von Containerimages mit Notation und Azure Key Vault mithilfe eines selbstsignierten Zertifikats

Das Signieren von Containerimages ist ein Prozess, der ihre Authentizität und Integrität sicherstellt. Dies wird erreicht, indem dem Containerimage eine digitale Signatur hinzugefügt wird, die während der Bereitstellung überprüft werden kann. Die Signatur hilft zu überprüfen, ob das Image von einem vertrauenswürdigen Herausgeber stammt und nicht geändert wurde. Notation ist ein von der Notary Project-Community entwickeltes und von Microsoft unterstütztes Open Source Supply Chain-Tool, das das Signieren und Überprüfen von Containerimages und anderen Artefakten unterstützt. Azure Key Vault (AKV) wird verwendet, um Zertifikate mit Signaturschlüsseln zu speichern, der von Notation mit dem AKV-Notation-Plug-In (azure-kv) verwendet werden kann, um Containerimages und andere Artefakte zu signieren und zu überprüfen. Mit dem Azure Container Registry (ACR) können Sie Signaturen an Containerimages und andere Artefakte anfügen und diese Signaturen anzeigen.

In diesem Tutorial wird Folgendes durchgeführt:

  • Installieren des Notation-Plug-Ins für CLI und AKV
  • Erstellen eines selbstsignierten Zertifikats in AKV
  • Erstellen und Pushen eines Containerimages mit ACR Tasks
  • Signieren eines Containerimages mit Notation-Plug-Ins für CLI und AKV
  • Überprüfen eines Containerimages anhand der Signatur mit der Notation-CLI
  • Verwendung von Zeitstempeln

Voraussetzungen

Installieren des Notation-Plug-Ins für CLI und AKV

  1. Installieren von Notation v1.2.0 in einer Linux amd64-Umgebung Befolgen Sie die Notation-Installationsanleitung, um das Paket für andere Umgebungen herunterzuladen.

    # 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. Installieren Sie das Notation-Plug-In für Azure Key Vault (azure-kv) V1.2.0 in einer Linux-amd64-Umgebung.

    Hinweis

    Die URL und die SHA-256-Prüfsumme für das Notation-Plug-In für Azure Key Vault finden Sie auf der Releaseseite des Plug-Ins.

    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. Listen Sie die verfügbaren Plug-Ins auf, und vergewissern Sie sich, dass das Plug-In azure-kv mit der Version 1.2.0 in der Liste enthalten ist.

    notation plugin ls
    

Konfigurieren von Umgebungsvariablen

Hinweis

Stellen Sie für die einfache Ausführung von Befehlen im Tutorial Werte für die Azure-Ressourcen bereit, die den vorhandenen ACR- und AKV-Ressourcen entsprechen.

  1. Konfigurieren von AKV-Ressourcennamen:

    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. Konfigurieren von ACR- und Imageressourcennamen:

    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
    

Anmelden mit der Azure CLI

az login

Weitere Informationen zur Azure CLI und zur Anmeldung mit der Azure CLI finden Sie unter Anmelden mit der Azure CLI.

Sichere Zugriffsberechtigungen für ACR und AKV

Bei der Arbeit mit ACR und AKV ist es wichtig, die entsprechenden Berechtigungen zu erteilen, um einen sicheren und kontrollierten Zugriff zu gewährleisten. Sie können den Zugriff für verschiedene Entitäten autorisieren, z. B. Benutzerprinzipale, Dienstprinzipale oder verwaltete Identitäten, je nach Ihren spezifischen Szenarien. In diesem Tutorial wird der Zugriff für einen angemeldeten Azure-Benutzer autorisiert.

Autorisieren des Zugriffs auf ACR

Die Rollen AcrPull und AcrPush sind für das Signieren von Containerimages in ACR erforderlich.

  1. Festlegen des Abonnements, das die ACR-Ressource enthält

    az account set --subscription $ACR_SUB_ID
    
  2. Zuweisen der Rollen

    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"
    

Autorisieren des Zugriffs auf AKV

In diesem Abschnitt werden wir zwei Optionen für die Autorisierung des Zugriffs auf AKV untersuchen.

Für die Signierung mithilfe von selbstsignierten Zertifikaten sind die folgenden Rollen erforderlich:

  • Key Vault Certificates Officer zum Erstellen und Lesen von Zertifikaten
  • Key Vault Certificates User zum Lesen vorhandener Zertifikate
  • Key Vault Crypto User für Signaturvorgänge

Weitere Informationen zum Key Vault-Zugriff mit Azure RBAC finden Sie unter Verwenden einer Azure RBAC zum Verwalten des Zugriffs.

  1. Legt das Abonnement fest, das die AKV-Ressource enthält.

    az account set --subscription $AKV_SUB_ID
    
  2. Zuweisen der Rollen

    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"
    

Zuweisen einer Zugriffsrichtlinie in AKV (Legacy)

Für eine Identität sind die folgenden Berechtigungen erforderlich:

  • Create-Berechtigungen zum Erstellen eines Zertifikats
  • Get-Berechtigungen zum Lesen vorhandener Zertifikate
  • Sign-Berechtigungen für Signaturvorgänge

Weitere Informationen zum Zuweisen von Richtlinien zu einem Prinzipal finden Sie unter Zuweisen einer Zugriffsrichtlinie.

  1. Festlegen des Abonnements, das die AKV-Ressource enthält:

    az account set --subscription $AKV_SUB_ID
    
  2. Festlegen der Zugriffsrichtlinie in 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
    

Wichtig

Dieses Beispiel zeigt die Mindestberechtigungen, die zum Erstellen eines Zertifikats und zum Signieren eines Containerimages erforderlich sind. Abhängig von Ihren Anforderungen müssen Sie möglicherweise zusätzliche Berechtigungen erteilen.

Erstellen eines selbstsignierten Zertifikats in AKV (Azure CLI)

In den folgenden Schritten wird das Erstellen eines selbstsignierten Zertifikats zu Testzwecken beschrieben.

  1. Erstellen einer Zertifikatrichtliniendatei:

    Sobald die Zertifikatrichtliniendatei wie unten ausgeführt wird, erstellt sie ein gültiges Zertifikat, das mit der Notary Project-Zertifikatanforderung in AKV kompatibel ist. Der Wert für ekus dient der Codesignatur, wird von Notation jedoch nicht zum Signieren von Artefakten benötigt. Der Antragsteller wird später als Vertrauensidentität verwendet, die Benutzer*innen während der Überprüfung angeben.

    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. Erstellen Sie das Zertifikat.

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

Signieren eines Containerimages mit Notation-Plug-Ins für CLI und AKV

  1. Authentifizieren Sie sich bei Ihrer ACR-Instanz mithilfe Ihrer individuellen Azure-Identität.

    az acr login --name $ACR_NAME
    

Wichtig

Wenn Sie Docker auf Ihrem System installiert haben und az acr login oder docker login zur Authentifizierung bei Ihrem ACR verwendet haben, sind Ihre Anmeldeinformationen bereits gespeichert und für die Notation verfügbar. In diesem Fall müssen Sie notation login nicht erneut ausführen, um sich bei Ihrem ACR zu authentifizieren. Weitere Informationen zu Authentifizierungsoptionen für Notation finden Sie unter Authentifizieren mit OCI-konformen Registrierungen.

  1. Erstellen und Pushen eines neuen Images mit ACR Tasks: Verwenden Sie immer den Digestwert, um das Image für die Signatur zu identifizieren, da Tags veränderlich sind und überschrieben werden können.

    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
    

    Wenn das Image in diesem Tutorial bereits erstellt wurde und in der Registrierung gespeichert ist, dient das Tag der Einfachheit halber als Bezeichner für dieses Image.

    IMAGE=$REGISTRY/${REPO}:$TAG
    
  2. Rufen Sie die Schlüssel-ID des Signaturschlüssels ab. Ein Zertifikat in AKV kann mehrere Versionen aufweisen. Der folgende Befehl ruft die Schlüssel-ID der neuesten Version ab.

    KEY_ID=$(az keyvault certificate show -n $CERT_NAME --vault-name $AKV_NAME --query 'kid' -o tsv)
    
  3. Signieren Sie das Containerimage mit dem COSE-Signaturformat mit der Signaturschlüssel-ID. Um mit einem selbstsignierten Zertifikat zu signieren, müssen Sie den Plug-In-Konfigurationswert self_signed=true festlegen.

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

    Um sich bei AKV zu authentifizieren, werden standardmäßig die folgenden Anmeldeinformationstypen in der angegebenen Reihenfolge versucht, sofern sie aktiviert sind:

    Wenn Sie einen Anmeldeinformationstyp angeben möchten, verwenden Sie eine zusätzliche Plug-In-Konfiguration mit dem Namen credential_type. Sie können z. B. credential_type explizit auf azurecli festlegen, um die Azure CLI-Anmeldeinformationen zu verwenden, wie weiter unten gezeigt:

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

    In der nachstehenden Tabelle finden Sie die Werte von credential_type für verschiedene Anmeldeinformationstypen.

    Anmeldeinformationstyp Wert für credential_type
    Umgebungsanmeldeinformationen environment
    Anmeldeinformationen für Workloadidentität workloadid
    Anmeldeinformationen für verwaltete Identität managedid
    Azure CLI-Anmeldeinformationen azurecli
  4. Zeigen Sie das Diagramm der signierten Images und der zugehörigen Signaturen an.

    notation ls $IMAGE
    

Überprüfen eines Containerimages mit Notation-CLI

Um das Containerimage zu überprüfen, fügen Sie das Stammzertifikat, das das Blattzertifikat signiert, dem Vertrauensspeicher hinzu, und erstellen Sie Vertrauensrichtlinien für die Überprüfung. Für das selbstsignierte Zertifikat, das in diesem Tutorial verwendet wird, ist das Stammzertifikat das selbstsignierte Zertifikat selbst.

  1. Herunterladen des öffentlichen Zertifikats:

    az keyvault certificate download --name $CERT_NAME --vault-name $AKV_NAME --file $CERT_PATH
    
  2. Fügen Sie das heruntergeladene öffentliche Zertifikat dem benannten Vertrauensspeicher zur Signaturüberprüfung hinzu.

    STORE_TYPE="ca"
    STORE_NAME="wabbit-networks.io"
    notation cert add --type $STORE_TYPE --store $STORE_NAME $CERT_PATH
    
  3. Listen Sie das Zertifikat für die Bestätigung auf.

    notation cert ls
    
  4. Konfigurieren Sie die Vertrauensrichtlinie vor der Überprüfung.

    Vertrauensrichtlinien ermöglichen es Benutzern, präzise abgestimmte Überprüfungsrichtlinien anzugeben. Im folgenden Beispiel wird eine Vertrauensstellungsrichtlinie mit dem Namen wabbit-networks-images konfiguriert, die für alle Artefakte in $REGISTRY/$REPO gilt und den benannten Vertrauensspeicher $STORE_NAME vom Typ $STORE_TYPE verwendet. Außerdem wird davon ausgegangen, dass der Benutzer einer bestimmten Identität mit dem X.509-Thema $CERT_SUBJECT vertraut. Weitere Informationen finden Sie in der Spezifikation des Vertrauensspeichers und der Vertrauensrichtlinie.

    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. Verwenden Sie notation policy, um die Vertrauensrichtlinienkonfiguration aus einer zuvor erstellten JSON-Datei zu importieren.

    notation policy import ./trustpolicy.json
    notation policy show
    
  6. Verwenden Sie notation verify, um zu überprüfen, ob das Containerimage seit der Buildzeit nicht geändert wurde.

    notation verify $IMAGE
    

    Nach erfolgreicher Überprüfung des Images mithilfe der Vertrauensrichtlinie wird der SHA-256-Digest des überprüften Images in einer Ausgabemeldung zum Erfolg zurückgegeben.

Verwendung von Zeitstempeln

Seit Notation v1.2.0 unterstützt Notation RFC 3161-konforme Zeitstempel. Diese Erweiterung erweitert die Vertrauensstellung von Signaturen, die innerhalb der Gültigkeit von Zertifikaten durch eine Vertrauensstellung mit einer TSA (Timestamping Authority) erstellt wurden, und ermöglicht eine erfolgreiche Signaturüberprüfung auch nach Ablauf von Zertifikaten. Als Imagesignierer sollten Sie sicherstellen, dass Sie Containerimages mit Zeitstempeln signieren, die von einer vertrauenswürdigen TSA generiert wurden. Als Imageprüfer sollten Sie zum Überprüfen von Zeitstempeln sicherstellen, dass Sie sowohl dem Imagesignierer als auch der zugehörigen TSA vertrauen und die Vertrauensstellung über Vertrauensspeicher und Vertrauensrichtlinien einrichten. Durch Zeitstempel werden die Kosten reduziert, da aufgrund des Ablaufs von Zertifikaten regelmäßig Bilder neu signiert werden müssen, was besonders bei der Verwendung von kurzlebigen Zertifikaten von entscheidender Bedeutung ist. Ausführliche Anweisungen zum Signieren und Überprüfen der Verwendung von Zeitstempeln finden Sie im Zeitstempelleitfaden für Notary Project.

Nächste Schritte

Notation bietet auch CI/CD-Lösungen für Azure Pipeline und GitHub Actions-Workflows:

So überprüfen Sie die signierte Imagebereitstellung in AKS oder Kubernetes: