Freigeben über


Signieren von Containerimages mithilfe von Notation, Azure Key Vault und einem selbstsignierten Zertifikat

Dieser Artikel ist Teil einer Reihe zur Sicherstellung der Integrität und Authentizität von Containerimages und anderen Open Container Initiative (OCI)-Artefakten. Für einen vollständigen Überblick beginnen Sie mit der Übersicht, in der erklärt wird, warum das Signieren wichtig ist und die verschiedenen Szenarien skizziert werden.

Das Signieren von Containerimages ist ein Prozess, der die Authentizität und Integrität gewährleistet. Eine digitale Signatur, die einem Containerimage hinzugefügt wird, wird während der Bereitstellung überprüft. Die Signatur hilft, zu überprüfen, ob das Bild von einem vertrauenswürdigen Herausgeber stammt und nicht geändert wird.

In diesem Artikel werden die folgenden Tools erläutert, die am Signierungsprozess beteiligt sind:

  • Notation ist ein Open-Source-Sicherheitstool für Lieferketten, das von der Notär Project-Community entwickelt und von Microsoft unterstützt wird. Es unterstützt das Signieren und Überprüfen von Containerimages und anderen Artefakten.

    Wenn Sie ein Containerimage mithilfe von Notation in fortlaufenden Integrations- und CI/CD-Pipelines signieren möchten, befolgen Sie die Anleitungen für Azure-Pipelines oder GitHub-Aktionen.

  • Azure Key Vault ist ein Dienst zum Speichern von Zertifikaten mit Signaturschlüsseln. Notation kann diese Schlüssel über das Key Vault-Plug-In (notation-azure-kv) verwenden, um Containerimages und andere Artefakte zu signieren und zu überprüfen.

  • Azure Container Registry ist eine private Registrierung, mit der Sie Signaturen an Containerimages und andere Artefakte anfügen können, und diese Signaturen anzeigen.

In diesem Artikel erfahren Sie, wie Sie:

  • Installieren Sie die Befehlszeilenschnittstelle (Notation Command-Line Interface, CLI) und das Key Vault-Plug-In.
  • Erstellen Sie ein selbstsigniertes Zertifikat im Key Vault.
  • Erstellen und Übertragen eines Containerimages mithilfe von Containerregistrierungsaufgaben.
  • Signieren Sie ein Containerimage mithilfe der Notation CLI und des Key Vault-Plug-Ins.
  • Validieren Sie ein Container-Image gegen die Signatur mithilfe des Notation-CLI.
  • Verwenden Sie Zeitstempel.

Voraussetzungen

Installieren des Notation CLI- und Key Vault-Plug-Ins

  1. Installieren Sie Notation v1.3.2 in einer Linux AMD64-Umgebung. Um das Paket für andere Umgebungen herunterzuladen, befolgen Sie das Notation-Installationshandbuch.

    # 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. Installieren Sie das Key Vault-Plug-In (notation-azure-kv) v1.2.1 in einer Linux AMD64-Umgebung.

    Hinweis

    Sie finden die URL- und SHA256-Prüfsumme für das Plug-In auf der Releaseseite des Plug-Ins.

    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. Auflisten der verfügbaren Plug-Ins und Bestätigen, dass das notation-azure-kv Plug-In mit Version 1.2.1 in der Liste enthalten ist:

    notation plugin ls
    

Konfigurieren von Umgebungsvariablen

Stellen Sie für die einfache Ausführung von Befehlen in diesem Artikel Werte für die Azure-Ressourcen bereit, die mit den vorhandenen Containerregistrierungs- und Key Vault-Ressourcen übereinstimmen.

  1. Konfigurieren von Key Vault-Ressourcennamen:

    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. Konfigurieren von Containerregistrierungs- 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 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
    

Anmelden mithilfe der Azure CLI

az login

Weitere Informationen finden Sie unter Authentifizieren bei Azure mithilfe der Azure CLI.

Gewähren Sie Zugriffsberechtigungen für die Container Registry und den Key Vault

Wenn Sie mit der Containerregistrierung und dem Key Vault arbeiten, 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 Artikel ist der Zugriff für einen angemeldeten Azure-Benutzer autorisiert.

Autorisieren des Zugriffs auf die Containerregistrierung

Für Register, die für die attributbasierte Zugriffssteuerung (ABAC) von Microsoft Entra aktiviert sind, sind die Rollen Container Registry Repository Reader und Container Registry Repository Writer erforderlich, um Containerimages in der Containerregistrierung zu erstellen und zu signieren.

Für Register, die für ABAC nicht aktiviert sind, sind die Rollen AcrPull und AcrPush erforderlich.

Weitere Informationen zu ABAC finden Sie unter Attributbasierte Zugriffssteuerung von Microsoft Entra für Repositoryberechtigungen.

  1. Legen Sie das Abonnement fest, das die Containerregistrierungsressource enthält:

    az account set --subscription $ACR_SUB_ID
    
  2. Weisen Sie die Rollen zu. Die richtige Rolle, die in der Rollenzuweisung verwendet werden soll, hängt davon ab, ob die Registrierung ABAC aktiviert ist oder nicht.

    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"
    

Autorisieren des Zugriffs auf Key Vault

In diesem Abschnitt werden zwei Optionen zum Autorisieren des Zugriffs auf Key Vault beschrieben.

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 Zugriff auf den Azure Key Vault mithilfe der Azure rollenbasierten Zugriffssteuerung (RBAC) finden Sie unter Bereitstellen des Zugriffs auf Key Vault-Schlüssel, Zertifikate und Geheimnisse mithilfe der Azure rollenbasierten Zugriffssteuerung.

  1. Legen Sie das Abonnement fest, das die Key Vault-Ressource enthält:

    az account set --subscription $AKV_SUB_ID
    
  2. Rollen zuweisen:

    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 im Key Vault (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 einer Richtlinie zu einem Prinzipal finden Sie unter Zuweisen einer Key Vault-Zugriffsrichtlinie (Legacy).

  1. Legen Sie das Abonnement fest, das die Key Vault-Ressource enthält:

    az account set --subscription $AKV_SUB_ID
    
  2. Legen Sie die Zugriffsrichtlinie im Key Vault fest:

    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 Sie zum Erstellen eines Zertifikats und zum Signieren eines Containerimages benötigen. Je nach Ihren Anforderungen müssen Sie möglicherweise weitere Berechtigungen erteilen.

Erstellen eines selbstsignierten Zertifikats im Key Vault (Azure CLI)

Die folgenden Schritte zeigen, wie Sie ein selbstsigniertes Zertifikat zu Testzwecken erstellen:

  1. Erstellen einer Zertifikatrichtliniendatei:

    Nachdem die Zertifikatrichtliniendatei über den folgenden Code ausgeführt wurde, erstellt sie ein gültiges Zertifikat, das mit den Zertifikatanforderungen des Notarprojekts im Key Vault kompatibel ist. Der Wert für ekus dient der Codesignatur, wird von Notation jedoch nicht zum Signieren von Artefakten benötigt. Das Subjekt wird später bei der Überprüfung als vertrauenswürdige Identität verwendet.

    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 mithilfe des Notation CLI- und Key Vault-Plug-Ins

  1. Authentifizieren Sie sich bei Ihrer Containerregistrierung 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 verwendet haben, um sich bei Ihrer Containerregistrierung zu authentifizieren, sind Ihre Anmeldeinformationen bereits gespeichert und für Notation verfügbar. In diesem Fall müssen Sie notation login nicht erneut ausführen, um sich bei Ihrer Containerregistrierung zu authentifizieren. Weitere Informationen zu Authentifizierungsoptionen für Notation finden Sie unter Authentifizieren mit OCI-kompatiblen Registrierungen.

  2. Erstellen und übertragen Sie ein neues Image mithilfe von Azure Container Registry-Aufgaben. 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
    

    In diesem Artikel, wenn das Image bereits erstellt und in der Registry gespeichert ist, dient das Tag für dieses Image als Bezeichner zur Vereinfachung.

    IMAGE=$REGISTRY/${REPO}:$TAG
    
  3. Rufen Sie die ID des Signaturschlüssels ab. Ein Zertifikat im Key Vault 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)
    
  4. Signieren Sie das Containerimage mit dem CoSE-Signaturformat (CBOR Object Signing and Encryption), indem Sie die Signaturschlüssel-ID verwenden. Um sich mit einem selbstsignierten Zertifikat zu signieren, müssen Sie den Plug-In-Konfigurationswert self_signed=truefestlegen.

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

    Um sich bei Key Vault zu authentifizieren, werden standardmäßig die folgenden Anmeldeinformationstypen (sofern aktiviert) in der reihenfolge ausprobiert:

    Wenn Sie einen Anmeldeinformationstyp angeben möchten, verwenden Sie eine zusätzliche Plug-In-Konfiguration namens credential_type. Sie können beispielsweise credential_type explizit auf azurecli festlegen, um eine Azure CLI-Anmeldeinformation zu verwenden, wie in diesem Beispiel 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 folgenden Tabelle werden die Werte von credential_type für verschiedene Anmeldedatentypen dargestellt.

    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

    Hinweis

    Seit Notation v1.2.0 verwendet Notation standardmäßig das OCI-Verweisertagschema , um die Signatur in der Containerregistrierung zu speichern. Sie können die OCI Referrers-API auch mithilfe des Flags --force-referrers-tag falseaktivieren, falls erforderlich. Containerregistrierungsfunktionen unterstützen die OCI Referrers-API, mit Ausnahme von Registrierungen, die mit kundengesteuerten Schlüsseln (CMKs) verschlüsselt sind.

  5. Zeigen Sie das Diagramm signierter Bilder und zugehöriger Signaturen an:

    notation ls $IMAGE
    

Überprüfen eines Containerimages mithilfe der Notation CLI

Um das Containerimage zu überprüfen, fügen Sie das Stammzertifikat, das das Blattzertifikat signiert, dem Vertrauensspeicher hinzu und erstellen Sie Vertrauensrichtlinien zur Verifizierung. Für das in diesem Artikel verwendete selbstsignierte Zertifikat ist das Stammzertifikat das selbstsignierte Zertifikat selbst.

  1. Herunterladen eines öffentlichen Zertifikats:

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

    STORE_TYPE="ca"
    STORE_NAME="wabbit-networks.io"
    notation cert add --type $STORE_TYPE --store $STORE_NAME $CERT_PATH
    
  3. Zertifikat zur Bestätigung auflisten:

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

    Mit Vertrauensrichtlinien können Benutzer fein abgestimmte Überprüfungsrichtlinien angeben. Im folgenden Beispiel wird eine Vertrauensrichtlinie mit dem Namen konfiguriert wabbit-networks-images. Diese Richtlinie gilt für alle Artefakte in $REGISTRY/$REPO und verwendet den benannten Vertrauensspeicher $STORE_NAME des Typs $STORE_TYPE. Außerdem wird davon ausgegangen, dass die Benutzenden einer bestimmten Identität mit dem X.509-Thema $CERT_SUBJECT vertrauen. Weitere Informationen finden Sie unter Vertrauensspeicher- und Vertrauenspolitik-Spezifikation.

    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. Dient notation policy zum Importieren der Vertrauensrichtlinienkonfiguration aus der JSON-Datei, die Sie zuvor erstellt haben:

    notation policy import ./trustpolicy.json
    notation policy show
    
  6. Verwenden Sie notation verify, um zu überprüfen, ob das Containerimage nach dem Build-Zeitpunkt nicht geändert wurde.

    notation verify $IMAGE
    

    Nach erfolgreicher Überprüfung des Bilds über die Vertrauensrichtlinie wird der SHA256-Digest des überprüften Bilds in einer erfolgreichen Ausgabemeldung zurückgegeben.

Zeitstempel verwenden

Seit der Notation v1.2.0-Version unterstützt Notation RFC 3161-kompatible Zeitstempel. Diese Erweiterung erweitert die Vertrauensstellung von Signaturen, die innerhalb des Gültigkeitszeitraums des Zertifikats erstellt wurden, indem sie einer Zeitstempelautorität (Time Stamp Authority, TSA) vertrauen. Diese Vertrauensstellung ermöglicht eine erfolgreiche Signaturüberprüfung auch nach Ablauf der Zertifikate.

Als Image signierer sollten Sie sicherstellen, dass Sie Containerimages mit Zeitstempeln signieren, die ein vertrauenswürdiger TSA generiert hat. Als Bildprüfer sollten Sie sicherstellen, dass Sie sowohl dem Bildsignierer als auch dem zugehörigen TSA vertrauen und Vertrauen über Vertrauensspeicher und Vertrauensrichtlinien einrichten.

Die Zeitstempeln reduziert Kosten, da die Notwendigkeit, Bilder aufgrund des Ablaufs von Zertifikaten regelmäßig neu zu signieren, entfällt. Diese Fähigkeit ist besonders wichtig, wenn Sie kurzlebige Zertifikate verwenden. Ausführliche Anweisungen zum Signieren und Überprüfen von Bildern mithilfe von Zeitstempeln finden Sie im Leitfaden zum Zeitstempel von Notarprojekt.

Notation bietet CI/CD-Lösungen für Azure-Pipelines und GitHub-Aktionen:

So stellen Sie sicher, dass nur vertrauenswürdige Containerimages auf Azure Kubernetes Service (AKS) bereitgestellt werden: