Dela via


Signera containeravbildningar med hjälp av Notation, Azure Key Vault och ett självsignerat certifikat

Den här artikeln är en del av en serie om att säkerställa integritet och äkthet för containeravbildningar och andra OCI-artefakter (Open Container Initiative). För den fullständiga bilden börjar du med översikten, som förklarar varför signering är viktigt och beskriver de olika scenarierna.

Signering av containeravbildningar är en process som hjälper till att säkerställa deras äkthet och integritet. En digital signatur som läggs till i en containeravbildning verifieras under distributionen. Signaturen hjälper till att verifiera att avbildningen kommer från en betrodd utgivare och inte ändras.

I den här artikeln beskrivs följande verktyg som ingår i signeringsprocessen:

  • Notation är ett säkerhetsverktyg med öppen källkod som utvecklats av Notary Project-communityn och som stöds av Microsoft. Den stöder signering och verifiering av containeravbildningar och andra artefakter.

    Om du vill signera en containeravbildning med hjälp av Notation i CI/CD-pipelines (kontinuerlig integrering och kontinuerlig leverans) följer du riktlinjerna för Azure Pipelines eller GitHub Actions.

  • Azure Key Vault är en tjänst för att lagra certifikat med signeringsnycklar. Notation kan använda dessa nycklar via Key Vault-plugin-programmet (notation-azure-kv) för att signera och verifiera containeravbildningar och andra artefakter.

  • Azure Container Registry är ett privat register som du kan använda för att bifoga signaturer till containeravbildningar och andra artefakter, tillsammans med att visa dessa signaturer.

I den här artikeln lär du dig att:

  • Installera kommandoradsgränssnittet Notation (CLI) och Key Vault-plugin-programmet.
  • Skapa ett självsignerat certifikat i Key Vault.
  • Skapa och pusha en containerbild med hjälp av Container Registry-tasker.
  • Signera en containeravbildning med hjälp av Notation CLI och Key Vault-plugin.
  • Verifiera en containeravbildning mot signaturen med hjälp av Notation CLI.
  • Använd tidsstämpling.

Förutsättningar

Installera plugin-programmet Notation CLI och Key Vault

  1. Installera Notation v1.3.2 i en Linux AMD64-miljö. Om du vill ladda ned paketet för andra miljöer följer du installationsguiden för Notation.

    # 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. Installera Key Vault-plugin-programmet (notation-azure-kv) v1.2.1 i en Linux AMD64-miljö.

    Anmärkning

    Du hittar URL:en och SHA256-kontrollsumman för plugin-programmet på plugin-programmets versionssida.

    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. Visa en lista över tillgängliga plugin-program och bekräfta att notation-azure-kv plugin-programmet med versionen 1.2.1 ingår i listan:

    notation plugin ls
    

Konfigurera miljövariabler

För enkel körning av kommandon i den här artikeln anger du värden för De Azure-resurser som ska matcha befintliga Container Registry- och Key Vault-resurser.

  1. Konfigurera Key Vault-resursnamn:

    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. Konfigurera namn på containerregister och avbildningsresurser:

    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
    

Logga in med hjälp av Azure CLI

az login

Mer information finns i Autentisera till Azure med hjälp av Azure CLI.

Bevilja åtkomstbehörigheter till Container Registry och Key Vault

När du arbetar med Container Registry och Key Vault är det viktigt att bevilja lämpliga behörigheter för att säkerställa säker och kontrollerad åtkomst. Du kan auktorisera åtkomst för olika entiteter, till exempel användarhuvudnamn, tjänstens huvudnamn eller hanterade identiteter, beroende på dina specifika scenarier. I den här artikeln är åtkomsten auktoriserad för en inloggad Azure-användare.

Auktorisera åtkomst till Container Registry

För register som är aktiverade för Microsoft Entra-attributbaserad åtkomstkontroll (ABAC) krävs rollerna Container Registry Repository Reader och Container Registry Repository Writer för att skapa och signera containeravbildningar i Container Registry.

För register som inte är aktiverade för ABAC krävs rollerna AcrPull och AcrPush .

Mer information om ABAC finns i Microsoft Entra-attributbaserad åtkomstkontroll för lagringsplatsbehörigheter.

  1. Ange den prenumeration som innehåller Container Registry-resursen:

    az account set --subscription $ACR_SUB_ID
    
  2. Tilldela rollerna. Vilken roll som ska användas i rolltilldelningen beror på om registret är ABAC aktiverat eller inte.

    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"
    

Auktorisera åtkomst till Key Vault

I det här avsnittet beskrivs två alternativ för att auktorisera åtkomst till Key Vault.

Följande roller krävs för signering med hjälp av självsignerade certifikat:

  • Key Vault Certificates Officer för att skapa och läsa certifikat
  • Key Vault Certificates User för att läsa befintliga certifikat
  • Key Vault Crypto User för signeringsåtgärder

Mer information om Key Vault-åtkomst med rollbaserad åtkomstkontroll i Azure (RBAC) finns i Ge åtkomst till Key Vault-nycklar, certifikat och hemligheter med hjälp av rollbaserad åtkomstkontroll i Azure.

  1. Ange den prenumeration som innehåller Key Vault-resursen:

    az account set --subscription $AKV_SUB_ID
    
  2. Tilldela rollerna:

    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"
    

Tilldela en åtkomstprincip i Key Vault (äldre)

Följande behörigheter krävs för en identitet:

  • Create behörigheter för att skapa ett certifikat
  • Get behörigheter för att läsa befintliga certifikat
  • Sign behörigheter för signeringsåtgärder

Mer information om hur du tilldelar en princip till ett användare finns i Tilldela en Key Vault-åtkomstprincip (äldre).

  1. Ange den prenumeration som innehåller Key Vault-resursen:

    az account set --subscription $AKV_SUB_ID
    
  2. Ange åtkomstprincipen i 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
    

Viktigt!

Det här exemplet visar de minsta behörigheter som du behöver för att skapa ett certifikat och signera en containeravbildning. Beroende på dina krav kan du behöva bevilja fler behörigheter.

Skapa ett självsignerat certifikat i Key Vault (Azure CLI)

Följande steg visar hur du skapar ett självsignerat certifikat i testsyfte:

  1. Skapa en certifikatprincipfil.

    När certifikatprincipfilen har körts via följande kod skapar den ett giltigt certifikat som är kompatibelt med certifikatkraven för Notary Project i Key Vault. Värdet för ekus är för kodsignering, men det krävs inte för att Notation ska signera artefakter. Ämnet används senare som en betrodd identitet under verifieringen.

    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. Skapa certifikatet:

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

Signera en containeravbildning med hjälp av Notation CLI och Key Vault plug-in

  1. Autentisera till containerregistret med hjälp av din enskilda Azure-identitet:

    az acr login --name $ACR_NAME
    

    Viktigt!

    Om du har Docker installerat på systemet och du använde az acr login eller docker login för att autentisera till containerregistret lagras dina autentiseringsuppgifter redan och är tillgängliga för Notation. I det här fallet behöver du inte köra notation login igen för att autentisera till containerregistret. Mer information om autentiseringsalternativ för Notation finns i Autentisera med OCI-kompatibla register.

  2. Skapa och pusha en ny avbildning med hjälp av Azure Container Registry-tjänster. Använd alltid digestvärdet för att identifiera bilden som ska signeras, eftersom taggar är föränderliga och kan skrivas över.

    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
    

    I den här artikeln, om avbildningen redan har skapats och lagras i registret, fungerar taggen som en identifierare för avbildningen för enkelhetens skull:

    IMAGE=$REGISTRY/${REPO}:$TAG
    
  3. Hämta ID:t för signeringsnyckeln. Ett certifikat i Key Vault kan ha flera versioner. Följande kommando hämtar nyckel-ID:t för den senaste versionen:

    KEY_ID=$(az keyvault certificate show -n $CERT_NAME --vault-name $AKV_NAME --query 'kid' -o tsv)
    
  4. Signera containeravbildningen med COSE-signaturformatet (CBOR Object Signing and Encryption) med hjälp av signeringsnyckelns ID. Om du vill logga in med ett självsignerat certifikat måste du ange plugin-konfigurationsvärdet self_signed=true.

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

    För att autentisera med Key Vault provas som standard följande typer av autentiseringsuppgifter (om aktiverade) i ordning:

    Om du vill ange en typ av autentiseringsuppgifter använder du ytterligare en plugin-konfiguration med namnet credential_type. Du kan till exempel uttryckligen ange credential_type till azurecli för att använda en Azure CLI-autentiseringsuppgift, vilket visas i det här exemplet:

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

    I följande tabell visas värdena för för olika typer av credential_type autentiseringsuppgifter.

    Typ av autentiseringsuppgifter Värde för credential_type
    Miljöreferenser environment
    Autentiseringsuppgifter för arbetsbelastningsidentitet workloadid
    Autentiseringsuppgifter för hanterad identitet managedid
    Azure CLI-autentiseringsuppgifter azurecli

    Anmärkning

    Sedan Notation v1.2.0 använder Notation taggschemat OCI-refererare för att lagra signaturen i Container Registry som standard. Du kan också aktivera OCI-referens-API :et med hjälp av flaggan --force-referrers-tag false, om det behövs. Funktionerna i Container Registry stöder OCI-referens-API:et, förutom registret som krypteras via kundhanterade nycklar (CMK:er).

  5. Visa grafen över signerade bilder och associerade signaturer:

    notation ls $IMAGE
    

Verifiera en avbildning av en container genom att använda Notations-CLI

Om du vill verifiera containeravbildningen lägger du till rotcertifikatet som signerar lövcertifikatet i certifikatlager och skapar tillitspolicyer för verifiering. För det självsignerade certifikat som används i den här artikeln är rotcertifikatet själva det självsignerade certifikatet.

  1. Ladda ned ett offentligt certifikat:

    az keyvault certificate download --name $CERT_NAME --vault-name $AKV_NAME --file $CERT_PATH
    
  2. Lägg till det nedladdade offentliga certifikatet i den betrodda lagringen för verifiering av signaturer.

    STORE_TYPE="ca"
    STORE_NAME="wabbit-networks.io"
    notation cert add --type $STORE_TYPE --store $STORE_NAME $CERT_PATH
    
  3. Ange certifikatet för att bekräfta:

    notation cert ls
    
  4. Konfigurera en förtroendeprincip före verifiering.

    Med förtroendeprinciper kan användarna ange finjusterade verifieringsprinciper. I följande exempel konfigureras en förtroendeprincip med namnet wabbit-networks-images. Den här principen gäller för alla artefakter i $REGISTRY/$REPO och använder det namngivna förtroendearkivet $STORE_NAME av typen $STORE_TYPE. Det förutsätter också att användaren litar på en specifik identitet med X.509-ämnet $CERT_SUBJECT. För mer information, se Specifikation för betrodd lagring och tillitsprincip.

    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. Använd notation policy för att importera konfigurationen av förtroendeprincipen från JSON-filen som du skapade tidigare:

    notation policy import ./trustpolicy.json
    notation policy show
    
  6. Använd notation verify för att kontrollera att containeravbildningen inte har ändrats efter byggtiden:

    notation verify $IMAGE
    

    När avbildningen har verifierats via förtroendeprincipen returneras SHA256-sammanfattningen av den verifierade avbildningen i ett lyckat utdatameddelande.

Använda tidsstämpling

Sedan notation v1.2.0-versionen har Notation stöd för RFC 3161-kompatibel tidsstämpling. Den här förbättringen utökar förtroendet för signaturer som skapats inom certifikatets giltighetsperiod genom att lita på en tidsstämpelutfärdare (TSA). Det här förtroendet möjliggör lyckad signaturverifiering även efter att certifikaten har upphört att gälla.

Som bildsignerare bör du se till att du signerar containeravbildningar med tidsstämplar som en betrodd TSA genererade. Som bildverifierare bör du se till att du litar på både bildsigneraren och tillhörande TSA och upprättar förtroende via förtroendelager och förtroendeprinciper.

Tidsstämpling minskar kostnaderna genom att eliminera behovet av att regelbundet signera om bilder på grund av att certifikatet upphör att gälla. Den här möjligheten är särskilt viktig när du använder kortlivade certifikat. Detaljerade anvisningar om hur du signerar och verifierar bilder med hjälp av tidsstämpling finns i tidsstämplingsguiden för Notary Project.

Notation tillhandahåller CI/CD-lösningar på Azure Pipelines och GitHub Actions:

För att säkerställa att endast betrodda containeravbildningar distribueras i Azure Kubernetes Service (AKS):