Как подписать образы контейнеров

Предусловия:

  • Развернутый кластер;
  • Установлен и работает "Модуль анализа конфигураций приложений (Kyverno)".

Kyverno, входящий в поставку Комплекса, умеет проверять образы контейнеров, размещенные в docker или registry (подробнее о том, как настроить аутентификацию в приватном registry, см. в п. Аутентификация в приватном registry). Для подписи образов контейнеров и получения публичного ключа чаще всего используется инструмент Cosign от Sigstore.

Как настроить подпись образов

Можно подписывать образы вручную или встроить процесс подписи образов в pipeline. Для подписи образов необходимо:

  1. Иметь установленный Cosign от Sigstore.

Если у вас не установлен Cosign, требуется использовать команду для установки (иначе ‒ следует пропустить этот шаг). Установку необходимо выполнить с устройства, которое будет осуществлять подпись (например, на машине с поднятым registry):

Команда для Linux/macOS:

curl -sSL https://github.com/sigstore/cosign/releases/latest/download/cosign-linux-amd64 -o /usr/local/bin/cosign
chmod +x /usr/local/bin/cosign

Команда для Windows (PowerShell):

Invoke-WebRequest -URI https://github.com/sigstore/cosign/releases/latest/download/cosign-windows-amd64.exe -OutFile cosign.exe
  1. Для каждого образа выполнить команду подписи. По умолчанию cosign регистрирует подпись во внешних сервисах. В закрытом контуре или без необходимости хранения информации о подписи во внешних источниках использовать команду с флагами:
  • --key cosign.key;
  • --tlog-upload=false.

В случае если для registry нет валидного сертификата, можно воспользоваться флагом:

  • --allow-insecure-registry.

Команда для подписи контейнера

cosign sign --key cosign.key --tlog-upload=false $IMAGE

В процессе подписи будет отображаться информация:

Generating ephemeral keys...
Retrieving signed certificate...
By typing 'y', you attest that you grant (or have permission to grant) and agree to have this information stored permanently in transparency logs.
Are you sure you would like to continue? [y/N] y
Your browser will now be opened to:
https://oauth2.sigstore.dev/auth/auth?access_type=online&client_id=sigstore&code_challenge=OrXitVKUZm2lEWHVt1oQWR4HZvn0rSlKhLcltglYxCY&code_challenge_method=S256&nonce=2KvOWeTFxYfxyzHtssvlIXmY6Jk&redirect_uri=http%3A%2F%2Flocalhost%3A57102%2Fauth%2Fcallback&response_type=code&scope=openid+email&state=2KvOWfbQJ1caqScgjwibzK2qJmb
Successfully verified SCT...
tlog entry created with index: 12086900
Pushing signature to: $IMAGE

Подпись образов происходит приватным ключом, а проверка ‒ публичным. Подробнее см. на официальной странице Sigstore.

Как настроить проверку подписи

Для настройки проверки подписи нужно выполнить следующие шаги:

  1. если у вас не установлен Cosign, использовать команду для установки (иначе ‒ пропустить этот шаг). Установку необходимо выполнить на своей рабочей станции:

Команда для Linux/macOS:

curl -sSL https://github.com/sigstore/cosign/releases/latest/download/cosign-linux-amd64 -o /usr/local/bin/cosign
chmod +x /usr/local/bin/cosign

Команда для Windows (PowerShell):

Invoke-WebRequest -URI https://github.com/sigstore/cosign/releases/latest/download/cosign-windows-amd64.exe -OutFile cosign.exe
  1. если у вас не создана ключевая пара для Cosign, создать с помощью команды для генерации ключевой пары (иначе ‒ пропустить этот шаг):
cosign generate-key-pair

Эта команда создаст два файла:

  • cosign.key ‒ приватный ключ;
  • cosign.pub ‒ публичный ключ (используется для проверки).
  1. извлечь публичный ключ с помощью команды:
cat cosign.pub

Результат должен выглядит примерно так:

-----BEGIN PUBLIC KEY-----
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEhUJv5NJ6Y5J5Z6X6X5X5X5X5X5X
5X5X5X5X5X5X5X5X5X5X5X5X5X5X5X5X5X5X5X5X5X5X5X5X5X5X5X5X5X5X5X
-----END PUBLIC KEY-----
  1. в кластере Kubernetes импортировать политику Kyverno, в манифесте политики проверки подписи которой указать значение вашего публичного ключа:

Важно ‒ Нужно обязательно заменить значение публичного ключа.

apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
  annotations:
    policies.kyverno.io/category: infosec
    policies.kyverno.io/description: Проверка подписи образа позволяет
      контролировать его целостность и запускать контейнеры только из
      проверенных и доверенных образов
    policies.kyverno.io/severity: High
    policies.kyverno.io/title: Image Signature Checker
  name: system-image-sign-check
spec:
  admission: true
  background: false
  emitWarning: false
  failurePolicy: Ignore
  rules:
 match:
        any:
 resources:
              kinds:
 Pod
              namespaceSelector:
                matchExpressions:
 key: shturval.tech/system-namespace
                    operator: Exist
      name: image-sign-check
      skipBackgroundRequests: true
      verifyImages:
 attestors:
 count: 1
              entries:
 keys:
                    ctlog:
                      ignoreSCT: true
                    publicKeys: >-
                      -----BEGIN PUBLIC KEY-----
                          MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAECp1Gvey7C3SPSsR4Xdxp3ffM55+j
                          ESzbBYgf71aw0P2ViS54eQ3jNJ7cKqj91hsM9XgowckvxDrRU5PSglg+7g==
                      -----END PUBLIC KEY-----
                    rekor:
                      ignoreTlog: true
                    signatureAlgorithm: sha256
                  signatureAlgorithm: sha256
 keys:
                    ctlog:
                      ignoreSCT: true
                    publicKeys: |-
                      -----BEGIN PUBLIC KEY-----
                      MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE3dNylLLrn1TqigZ5gGGsG2r55pot
                      VnSGcEOsHXOSNwMUiBDal716IfJ1MBWrmeRrOlM0IwfWnXnuitM3Qgd0ew==
                      -----END PUBLIC KEY-----
                    rekor:
                      ignoreTlog: true
                    signatureAlgorithm: sha256
                  signatureAlgorithm: sha256
          imageReferences:
 */*
          mutateDigest: false
          required: true
          useCache: false
          verifyDigest: true
  schemaValidation: true
  validationFailureAction: Audit
  webhookTimeoutSeconds: 10

Загруженная политика будет доступна для просмотра в графическом интерфейсе кластера в разделе "Безопасность/Менеджер политик безопасности". Следует обратить внимание, что политика будет блокировать запуск всех не подписанных этим ключом контейнеров, в том числе системных. В предложенном выше манифесте политики системные образы контейнеров добавлены в исключения.