Подписывание образов контейнеров с помощью Нотации и Azure Key Vault с помощью самозаверяющего сертификата

Подписывание образов контейнеров — это процесс, обеспечивающий их подлинность и целостность. Это достигается путем добавления цифровой подписи в образ контейнера, который можно проверить во время развертывания. Сигнатура помогает убедиться, что изображение находится у доверенного издателя и не было изменено. Нотация — это средство безопасности цепочки поставок открытый код, разработанное сообществом нотаричного проекта и поддерживаемое корпорацией Майкрософт, которое поддерживает подписывание и проверку образов контейнеров и других артефактов. Azure Key Vault (AKV) используется для хранения сертификатов с ключами подписывания, которые могут использоваться нотацией с подключаемым модулем Нотации AKV (azure-kv) для подписывания и проверки образов контейнеров и других артефактов. Реестр контейнеров Azure (ACR) позволяет присоединять подписи к образам контейнеров и другим артефактам, а также просматривать эти подписи.

В этом руководстве рассматриваются следующие темы:

  • Установка интерфейса командной строки нотации и подключаемого модуля AKV
  • Создание самозаверяющего сертификата в AKV
  • Создание и отправка образа контейнера с помощью задач ACR
  • Подписывание образа контейнера с помощью интерфейса командной строки нотации и подключаемого модуля AKV
  • Проверка образа контейнера с помощью нотации CLI
  • Установка меток времени

Необходимые компоненты

Установка интерфейса командной строки нотации и подключаемого модуля AKV

  1. Установите нотацию версии 1.2.0 в среде Linux amd64. Следуйте инструкциям по установке нотации, чтобы скачать пакет для других сред.

    # 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. Установите подключаемый модуль azure-kv Нотации Azure Key Vault версии 1.2.0 в среде Linux amd64.

    Примечание.

    Url-адрес и контрольная сумма SHA256 для подключаемого модуля Нотации Azure Key Vault можно найти на странице выпуска подключаемого модуля.

    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. Список доступных подключаемых модулей и убедитесь, что azure-kv подключаемый модуль с версией 1.2.0 включен в список.

    notation plugin ls
    

Настройка переменных среды

Примечание.

Для упрощения выполнения команд из учебника укажите значения для ресурсов Azure, чтобы они соответствовали существующим ресурсам ACR и AKV.

  1. Настройте имена ресурсов 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. Настройте имена ресурсов ACR и изображений.

    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
    

Вход с помощью Azure CLI

az login

Дополнительные сведения о Azure CLI и его входе см. в статье "Вход с помощью Azure CLI".

Безопасный доступ к ACR и AKV

При работе с ACR и AKV необходимо предоставить соответствующие разрешения для обеспечения безопасного и управляемого доступа. Вы можете авторизовать доступ для различных сущностей, таких как субъекты-пользователи, субъекты-службы или управляемые удостоверения в зависимости от конкретных сценариев. В этом руководстве доступ авторизован для пользователя Azure, выполнившего вход.

Авторизация доступа к ACR

AcrPush Для AcrPull подписывания образов контейнеров в ACR требуются роли.

  1. Задайте подписку, содержащую ресурс ACR

    az account set --subscription $ACR_SUB_ID
    
  2. Назначение ролей

    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"
    

Авторизация доступа к AKV

В этом разделе мы рассмотрим два варианта авторизации доступа к AKV.

Для подписывания с помощью самозаверяемых сертификатов требуются следующие роли:

  • Key Vault Certificates Officer для создания и чтения сертификатов
  • Key Vault Certificates Userдля чтения существующих сертификатов
  • Key Vault Crypto User для операций подписывания

Дополнительные сведения о доступе Key Vault с помощью Azure RBAC см. в статье "Использование Azure RBAC" для управления доступом.

  1. Задайте подписку, содержащую ресурс AKV

    az account set --subscription $AKV_SUB_ID
    
  2. Назначение ролей

    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"
    

Назначение политики доступа в AKV (устаревшая версия)

Для удостоверения требуются следующие разрешения:

  • Create разрешения для создания сертификата
  • Get разрешения на чтение существующих сертификатов
  • Sign разрешения для операций подписывания

Дополнительные сведения о назначении политики субъекту см. в статье "Назначение политики доступа".

  1. Задайте подписку, содержащую ресурс AKV:

    az account set --subscription $AKV_SUB_ID
    
  2. Задайте политику доступа в 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
    

Внимание

В этом примере показаны минимальные разрешения, необходимые для создания сертификата и подписывания образа контейнера. В зависимости от ваших требований может потребоваться предоставить дополнительные разрешения.

Создание самозаверяющего сертификата в AKV (Azure CLI)

Ниже показано, как создать самозаверяющий сертификат для тестирования.

  1. Создайте файл политики сертификата.

    После выполнения файла политики сертификата, как показано ниже, он создает допустимый сертификат, совместимый с требованием сертификата нотаричного проекта в AKV. Значение для ekus подписывания кода, но не требуется для нотации для подписывания артефактов. Тема используется позже в качестве удостоверения доверия, которое пользователь доверяет во время проверки.

    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. Создайте сертификат.

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

Подписывание образа контейнера с помощью интерфейса командной строки нотации и подключаемого модуля AKV

  1. Проверка подлинности в ACR с помощью отдельного удостоверения Azure.

    az acr login --name $ACR_NAME
    

Внимание

Если вы установили Docker в системе и использовали или docker login выполнили az acr login проверку подлинности в ACR, ваши учетные данные уже хранятся и доступны для нотации. В этом случае вам не нужно выполнять notation login проверку подлинности в ACR. Дополнительные сведения о параметрах проверки подлинности для нотации см. в статье Аутентификация с помощью реестров, совместимых с OCI.

  1. Создание и отправка нового образа с помощью задач ACR. Всегда используйте значение дайджеста для идентификации изображения для подписывания, так как теги являются изменяемыми и могут быть перезаписаны.

    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
    

    В этом руководстве, если образ уже создан и хранится в реестре, тег служит идентификатором этого образа для удобства.

    IMAGE=$REGISTRY/${REPO}:$TAG
    
  2. Получите идентификатор ключа подписывания. Сертификат в AKV может иметь несколько версий, следующая команда получает идентификатор ключа последней версии.

    KEY_ID=$(az keyvault certificate show -n $CERT_NAME --vault-name $AKV_NAME --query 'kid' -o tsv)
    
  3. Подписывание образа контейнера с помощью формата подписи COSE с помощью идентификатора ключа подписи. Чтобы подписаться с помощью самозаверяющего сертификата, необходимо задать значение self_signed=trueконфигурации подключаемого модуля.

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

    Для проверки подлинности с помощью AKV по умолчанию следующие типы учетных данных, если они включены, будут проверены в порядке:

    Если вы хотите указать тип учетных данных, используйте дополнительную конфигурацию credential_typeподключаемого модуля. Например, вы можете явно задать credential_type для azurecli использования учетных данных Azure CLI, как показано ниже:

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

    В таблице ниже приведены значения различных типов учетных credential_type данных.

    Тип учетных данных Значение для credential_type
    Учетные данные среды environment
    Учетные данные удостоверения рабочей нагрузки workloadid
    Учетные данные управляемого удостоверения managedid
    Учетные данные для входа с помощью Azure CLI azurecli
  4. Просмотрите график подписанных изображений и связанных подписей.

    notation ls $IMAGE
    

Проверка подписи образа контейнера с помощью интерфейса командной строки нотации

Чтобы проверить образ контейнера, добавьте корневой сертификат, который подписывает конечный сертификат в хранилище доверия и создает политики доверия для проверки. Для самозаверяющего сертификата, используемого в этом руководстве, корневой сертификат — самозаверяющий сертификат.

  1. Скачайте общедоступный сертификат.

    az keyvault certificate download --name $CERT_NAME --vault-name $AKV_NAME --file $CERT_PATH
    
  2. Добавьте скачанный общедоступный сертификат в именованное хранилище доверия для проверки подписи.

    STORE_TYPE="ca"
    STORE_NAME="wabbit-networks.io"
    notation cert add --type $STORE_TYPE --store $STORE_NAME $CERT_PATH
    
  3. Список сертификатов для подтверждения.

    notation cert ls
    
  4. Настройте политику доверия перед проверкой.

    Политики доверия позволяют пользователям указывать настроенные политики проверки. В следующем примере настраивается политика доверия с именем wabbit-networks-images, которая применяется ко всем артефактам $REGISTRY/$REPO и использует именованное хранилище $STORE_NAME доверия типа $STORE_TYPE. Кроме того, предполагается, что пользователь доверяет определенному удостоверению с субъектом $CERT_SUBJECTX.509. Дополнительные сведения см . в спецификации политики доверия и хранилища доверия.

    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. Используется notation policy для импорта конфигурации политики доверия из файла JSON, созданного ранее.

    notation policy import ./trustpolicy.json
    notation policy show
    
  6. Используется notation verify для проверки того, что образ контейнера не был изменен с момента сборки.

    notation verify $IMAGE
    

    После успешной проверки изображения с помощью политики доверия возвращается дайджест sha256 проверенного образа в успешном выходном сообщении.

Установка меток времени

Так как выпуск Нотации версии 1.2.0 нотация поддерживает метку времени соответствия RFC 3161 . Это улучшение расширяет доверие подписей, созданных в течение срока действия сертификата, доверяя центру метки времени (TSA), обеспечивая успешную проверку подписи даже после истечения срока действия сертификатов. В качестве подписи образа необходимо убедиться, что вы подписываете образы контейнеров метками времени, созданными доверенным TSA. Чтобы проверить метки времени, убедитесь, что вы доверяете подписывщику изображений и связанному TSA, и установить доверие с помощью хранилищ доверия и политик доверия. Метка времени снижает затраты, устраняя необходимость периодически повторного подписывания образов из-за истечения срока действия сертификата, что особенно важно при использовании краткосрочных сертификатов. Подробные инструкции по подписи и проверке с помощью метки времени см. в руководстве по метке времени нотарии проекта.

Следующие шаги

Нотация также предоставляет решения CI/CD в рабочем процессе Azure Pipeline и GitHub Actions:

Чтобы проверить развертывание подписанных образов в AKS или Kubernetes, выполните приведенные ниже действия.