Condividi tramite


Firmare immagini del contenitore con notazione e Azure Key Vault usando un certificato autofirmato

La firma delle immagini del contenitore è un processo che garantisce l'autenticità e l'integrità. A tale scopo, è possibile aggiungere una firma digitale all'immagine del contenitore, che può essere convalidata durante la distribuzione. La firma consente di verificare che l'immagine provenga da un autore attendibile e non sia stata modificata. La notazione è uno strumento di sicurezza della catena di approvvigionamento open source sviluppato dalla community Notary Project e supportato da Microsoft che supporta la firma e la verifica delle immagini del contenitore e di altri artefatti. Azure Key Vault (AKV) viene usato per archiviare i certificati con chiavi di firma che possono essere usate dalla notazione con il plug-in Notation AKV (azure-kv) per firmare e verificare le immagini del contenitore e altri artefatti. Registro Azure Container consente di allegare firme alle immagini del contenitore e ad altri artefatti, nonché di visualizzare tali firme.

Contenuto dell'esercitazione:

  • Installare l'interfaccia della riga di comando di notazione e il plug-in AKV
  • Creare un certificato autofirmato in AKV
  • Compilare ed eseguire il push di un'immagine del contenitore con Attività del Registro Azure Container
  • Firmare un'immagine del contenitore con l'interfaccia della riga di comando notazione e il plug-in AKV
  • Convalidare un'immagine del contenitore rispetto alla firma con l'interfaccia della riga di comando notazione
  • Aggiunta del timestamp

Prerequisiti

Installare l'interfaccia della riga di comando di notazione e il plug-in AKV

  1. Installare Notation v1.2.0 in un ambiente Linux amd64. Seguire la guida all'installazione della notazione per scaricare il pacchetto per altri ambienti.

    # 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. Installare il plug-in di notazione di Azure Key Vault azure-kv v1.2.0 in un ambiente Linux amd64.

    Nota

    Il checksum URL e SHA256 per il plug-in di notazione di Azure Key Vault sono disponibili nella pagina della versione del plug-in.

    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. Elencare i plug-in disponibili e verificare che il plug-in azure-kv con versione 1.2.0 sia incluso nell'elenco.

    notation plugin ls
    

Configurare le variabili di ambiente

Nota

Per semplificare l'esecuzione dei comandi nell'esercitazione, fornire valori per le risorse di Azure in modo che corrispondano alle risorse ACR e AKV esistenti.

  1. Configurare i nomi delle risorse AKV.

    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. Configurare il registro Azure Container e i nomi delle risorse immagine.

    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
    

Accedere tramite l'interfaccia della riga di comando di Azure

az login

Per altre informazioni sull'interfaccia della riga di comando di Azure e su come accedervi, vedere Accedere con l'interfaccia della riga di comando di Azure.

Proteggere le autorizzazioni di accesso a Registro Azure Container e AKV

Quando si lavora con Registro Azure Container e AKV, è essenziale concedere le autorizzazioni appropriate per garantire l'accesso sicuro e controllato. È possibile autorizzare l'accesso per entità diverse, ad esempio entità utente, entità servizio o identità gestite, a seconda degli scenari specifici. In questa esercitazione l'accesso è autorizzato a un utente di Azure connesso.

Autorizzare l'accesso a Registro Azure Container

I ruoli AcrPull e AcrPush sono necessari per firmare le immagini del contenitore in Registro Azure Container.

  1. Impostare la sottoscrizione che contiene la risorsa registro Azure Container

    az account set --subscription $ACR_SUB_ID
    
  2. Assegnare i ruoli

    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"
    

Autorizzare l'accesso a AKV

In questa sezione verranno esaminate due opzioni per autorizzare l'accesso ad AKV.

Per la firma con certificati autofirmati sono necessari i ruoli seguenti:

  • Key Vault Certificates Officer per la creazione e la lettura di certificati
  • Key Vault Certificates Userper la lettura dei certificati esistenti
  • Key Vault Crypto User per le operazioni di firma

Per altre informazioni sull'accesso a Key Vault con il controllo degli accessi in base al ruolo di Azure, vedere Usare un controllo degli accessi in base al ruolo di Azure per la gestione dell'accesso.

  1. Impostare la sottoscrizione che contiene la risorsa AKV

    az account set --subscription $AKV_SUB_ID
    
  2. Assegnare i ruoli

    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"
    

Assegnare i criteri di accesso in AKV (legacy)

Per un'identità sono necessarie le autorizzazioni seguenti:

  • Autorizzazioni Create per la creazione di un certificato
  • Autorizzazioni Get per la lettura dei certificati esistenti
  • Autorizzazioni Sign per le operazioni di firma

Per altre informazioni sull'assegnazione di criteri a un'entità di sicurezza, vedere Assegnare criteri di accesso.

  1. Impostare la sottoscrizione contenente la risorsa AKV:

    az account set --subscription $AKV_SUB_ID
    
  2. Impostare i criteri di accesso 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
    

Importante

Questo esempio mostra le autorizzazioni minime necessarie per la creazione di un certificato e la firma di un'immagine del contenitore. A seconda dei requisiti, potrebbe essere necessario concedere autorizzazioni aggiuntive.

Creare un certificato autofirmato in AKV (interfaccia della riga di comando di Azure)

I passaggi seguenti illustrano come creare un certificato autofirmato a scopo di test.

  1. Creare un file di criteri del certificato.

    Una volta eseguito il file dei criteri di certificato come indicato di seguito, crea un certificato valido compatibile con requisito di certificato di Notary Project in AKV. Il valore per ekus è per la firma del codice, ma non è necessario per la notazione firmare gli artefatti. L'oggetto viene usato in un secondo momento come identità attendibile dell'utente durante la verifica.

    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. Creare il certificato.

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

Firmare un'immagine del contenitore con l'interfaccia della riga di comando notazione e il plug-in AKV

  1. Eseguire l'autenticazione nel Registro Azure Container usando la singola identità di Azure.

    az acr login --name $ACR_NAME
    

Importante

Se Docker è installato nel sistema e vengono usati az acr login o docker login per l'autenticazione nel Registro Azure Container, le credenziali sono già archiviate e disponibili per la notazione. In questo caso non è necessario eseguire notation login di nuovo per eseguire l'autenticazione nel Registro Azure Container. Per altre informazioni sulle opzioni di autenticazione per la notazione, vedere Eseguire l'autenticazione con registri conformi a OCI.

  1. Compilare ed eseguire il push di una nuova immagine con Attività del Registro Azure Container. Usare sempre il valore digest per identificare l'immagine per la firma perché i tag sono modificabili e possono essere sovrascritti.

    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 questa esercitazione, se l'immagine è già stata compilata e archiviata nel Registro di sistema, il tag funge da identificatore per tale immagine per praticità.

    IMAGE=$REGISTRY/${REPO}:$TAG
    
  2. Ottenere l'ID chiave della chiave di firma. Un certificato in AKV può avere più versioni, il comando seguente ottiene l'ID chiave della versione più recente.

    KEY_ID=$(az keyvault certificate show -n $CERT_NAME --vault-name $AKV_NAME --query 'kid' -o tsv)
    
  3. Firmare l'immagine del contenitore con il formato di firma COSE usando l'ID chiave di firma. Per firmare con un certificato autofirmato, è necessario impostare il valore di configurazione del plug-in self_signed=true.

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

    Per eseguire l'autenticazione con AKV, per impostazione predefinita, i tipi di credenziali seguenti, se abilitati, verranno provati in ordine:

    Se si vuole specificare un tipo di credenziale, usare una configurazione aggiuntiva del plug-in denominata credential_type. Ad esempio, è possibile impostare in modo esplicito credential_type su azurecli per l'uso delle credenziali dell'interfaccia della riga di comando di Azure, come illustrato di seguito:

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

    Vedere la tabella seguente per i valori di credential_type per vari tipi di credenziali.

    Tipo di credenziali Valore per credential_type
    Credenziali dell'ambiente environment
    Credenziali dell'identità del carico di lavoro workloadid
    Credenziali dell'identità gestita managedid
    Credenziali dell'interfaccia della riga di comando di Azure azurecli
  4. Visualizzare il grafico delle immagini firmate e delle firme associate.

    notation ls $IMAGE
    

Verificare un'immagine del contenitore con l'interfaccia della riga di comando notazione

Per verificare l'immagine del contenitore, aggiungere il certificato radice che firma il certificato foglia all'archivio attendibilità e creare criteri di attendibilità per la verifica. Per il certificato autofirmato usato in questa esercitazione, il certificato radice è il certificato autofirmato stesso.

  1. Scaricare il certificato pubblico.

    az keyvault certificate download --name $CERT_NAME --vault-name $AKV_NAME --file $CERT_PATH
    
  2. Aggiungere il certificato pubblico scaricato all'archivio attendibilità denominato per la verifica della firma.

    STORE_TYPE="ca"
    STORE_NAME="wabbit-networks.io"
    notation cert add --type $STORE_TYPE --store $STORE_NAME $CERT_PATH
    
  3. Elencare il certificato da confermare.

    notation cert ls
    
  4. Configurare i criteri di attendibilità prima della verifica.

    I criteri di attendibilità consentono agli utenti di specificare criteri di verifica ottimizzati. Nell'esempio seguente viene configurato un criterio di attendibilità denominato wabbit-networks-images, che si applica a tutti gli artefatti in $REGISTRY/$REPO e usa l'archivio trust denominato $STORE_NAME di tipo $STORE_TYPE. Presuppone inoltre che l'utente consideri attendibile un'identità specifica con l'oggetto X.509 $CERT_SUBJECT. Per altre informazioni, vedere Archivio attendibilità e specifica dei criteri di attendibilità.

    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. Usare notation policy per importare la configurazione dei criteri di attendibilità da un file JSON creato in precedenza.

    notation policy import ./trustpolicy.json
    notation policy show
    
  6. Usare notation verify per verificare che l'immagine del contenitore non sia stata modificata dal momento della compilazione.

    notation verify $IMAGE
    

    Al termine della verifica dell'immagine usando i criteri di attendibilità, il digest sha256 dell'immagine verificata viene restituito in un messaggio di output riuscito.

Aggiunta del timestamp

A partire dal rilascio di Notation v1.2.0, Notation supporta timestamping con conformità RFC 3161. Questo miglioramento estende l'attendibilità delle firme create all'interno del periodo di validità del certificato considerando attendibile l'Autorità di timestamp (TSA), abilitando la verifica della firma corretta anche dopo la scadenza del certificato. Come firmatario di immagini, è necessario assicurarsi di firmare immagini del contenitore con timestamp generati da una TSA attendibile. Come verificatore di immagini, per verificare i timestamp, è necessario assicurarsi di considerare attendibile sia il firmatario dell'immagine che la TSA associata e stabilire l'attendibilità tramite archivi e criteri di attendibilità. Il timestamping riduce i costi eliminando la necessità di firmare periodicamente le immagini a causa della scadenza del certificato, un aspetto particolarmente critico quando si usano certificati di breve durata. Per istruzioni dettagliate su come firmare e verificare l'uso del timestamping, fare riferimento alla Guida al timestamping di Notary Project.

Passaggi successivi

La notazione fornisce anche soluzioni CI/CD nel flusso di lavoro di Azure Pipeline e GitHub Actions:

Per convalidare la distribuzione di immagini firmate nel servizio Azure Kubernetes o in Kubernetes: