• Русский
  • Image Signature Verification

    В Tekton Chains можно автоматически подписывать собранный образ и записывать подпись в SLSA Provenance.

    Обзор функции

    Этот метод использует Tekton Chains для автоматической подписи собранного образа, а затем использует cosign или Kyverno для проверки подписи:

    1. Настроить Tekton Chains для автоматической подписи собранного образа.
    2. Использовать задачу buildah Tekton Task для сборки образа.
    3. (Опционально) Использовать CLI cosign для проверки подписи.
    4. Настроить правила Kyverno для разрешения только подписанных образов.
    5. Использовать образ для создания Pod и проверки подписи.
    TIP

    По сравнению с Quick Start: Signed Provenance, этот метод добавляет только дополнительные шаги проверки.

    Сценарии использования

    Следующие сценарии требуют обращения к рекомендациям из этого документа:

    • Реализация проверки подписи образа в кластерах Kubernetes с использованием Kyverno
    • Применение политик безопасности, разрешающих развертывание только подписанных образов
    • Настройка автоматической проверки подписи образов в CI/CD пайплайнах
    • Обеспечение целостности и подлинности образов в продуктивной среде
    • Внедрение мер безопасности цепочки поставок для контейнерных образов

    Предварительные требования

    • Kubernetes кластер с установленными Tekton Pipelines, Tekton Chains и Kyverno
    • Реестр с разрешённой загрузкой образов
    • Установленный и настроенный CLI kubectl для доступа к кластеру
    • Установленный CLI инструмент cosign
    • Установленный CLI инструмент jq

    Обзор процесса

    ШагОперацияОписание
    1Генерация ключей подписиСоздание пары ключей для подписи артефактов с помощью cosign
    2Настройка аутентификацииКонфигурация учётных данных реестра для загрузки образов
    3Настройка Tekton ChainsНастройка Chains для использования OCI хранилища и подписи
    4Создание примерного пайплайнаСоздание определения пайплайна с необходимыми задачами и рабочими областями
    5Запуск примерного пайплайнаСоздание и запуск PipelineRun с правильной конфигурацией
    6Ожидание подписиОжидание, пока PipelineRun будет подписан Chains
    7Получение информации об образеИзвлечение URI образа и дайджеста из PipelineRun
    8Проверка подписей с KyvernoНастройка и проверка подписи образа с помощью политик Kyverno
    9Очистка ресурсовУдаление тестовых Pod и политик

    Пошаговые инструкции

    Шаги 1-7: Базовая настройка

    Эти шаги идентичны руководству Quick Start: Signed Provenance. Пожалуйста, следуйте инструкциям в том руководстве для:

    Шаг 8: Проверка подписи с Kyverno

    В Шаге 8: Проверка образа и аттестации мы используем CLI cosign для проверки подписи. Здесь мы используем Kyverno для проверки подписи.

    Шаг 8.1: Создание политики Kyverno для разрешения развертывания только подписанных образов

    TIP

    Для этого шага требуются права администратора кластера.

    Подробнее о Kyverno ClusterPolicy смотрите в Kyverno ClusterPolicy

    Политика выглядит следующим образом:

    apiVersion: kyverno.io/v1
    kind: ClusterPolicy
    metadata:
      name: only-cosign-image-deploy
    spec:
      webhookConfiguration:
        failurePolicy: Fail
        timeoutSeconds: 30
      background: false
      rules:
        - name: check-image
          match:
            any:
              - resources:
                  kinds:
                    - Pod
                  namespaces:
                    - policy
          verifyImages:
            - imageReferences:
                - "*"
                # - "<registry>/test/*"
              skipImageReferences:
                - "ghcr.io/trusted/*"
              failureAction: Enforce
              verifyDigest: false
              required: false
              useCache: false
              imageRegistryCredentials:
                allowInsecureRegistry: true
                secrets:
                  # Учетные данные должны существовать в namespace, где развернут kyverno
                  - registry-credentials
    
              attestors:
                - count: 1
                  entries:
                    - keys:
                        publicKeys: |- # <- Публичный ключ подписанта
                          -----BEGIN PUBLIC KEY-----
                          MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEFZNGfYwn7+b4uSdEYLKjxWi3xtP3
                          UkR8hQvGrG25r0Ikoq0hI3/tr0m7ecvfM75TKh5jGAlLKSZUJpmCGaTToQ==
                          -----END PUBLIC KEY-----
    
                        ctlog:
                          ignoreSCT: true
    
                        rekor:
                          ignoreTlog: true

    :::details {title="Объяснение полей YAML"}

    • spec.rules[].match.any[].resources: Ресурсы, которые будут сопоставлены и проверены.
      • kinds: Типы ресурсов для сопоставления и проверки.
        • Pod: Ресурсы типа Pod.
      • namespaces: Пространства имён ресурсов для сопоставления и проверки.
        • policy: Ресурсы в пространстве имён policy будут сопоставлены и проверены.
    • spec.rules[].verifyImages: Настройки проверки образов
      • imageReferences: Образы, которые будут проверяться.
        • *: все образы будут проверены.
        • <registry>/test/*: только образы из реестра <registry>/test будут проверены.
      • skipImageReferences: Образы, которые будут пропущены.
        • ghcr.io/trusted/*: образы из реестра ghcr.io/trusted будут пропущены.
      • imageRegistryCredentials:
        • allowInsecureRegistry: Разрешить небезопасный реестр.
        • secrets: Секреты для учётных данных реестра образов.
          • registry-credentials: Имя секрета. Секрет должен существовать в namespace, где развернут kyverno.
      • attestors: Подписанты, используемые для проверки образа.
        • count: Количество подписантов, которые должны совпасть.
        • entries: Записи подписантов.
          • keys: Ключи подписантов.
            • publicKeys: Публичные ключи подписантов.
              • Этот публичный ключ совпадает с публичным ключом cosign.pub в секрете signing-secrets.
            • ctlog: ctlog подписантов.
              • ignoreSCT: Игнорировать SCT.
                • В изолированных сетевых средах сначала игнорируйте SCT.
            • rekor: rekor подписантов.
              • ignoreTlog: Игнорировать Tlog.
                • В изолированных сетевых средах сначала игнорируйте Tlog. :::

    Требуется настроить конфигурацию

    • spec.rules[].attestors[].entries[].keys.publicKeys: Публичный ключ подписанта.
      • Этот публичный ключ совпадает с публичным ключом cosign.pub в секрете signing-secrets.
      • Публичный ключ можно получить из раздела Get the Signing Public Key.

    Сохраните в yaml-файл с именем kyverno.only-cosign-image-deploy.yaml и примените командой:

    $ kubectl apply -f kyverno.only-cosign-image-deploy.yaml
    
    clusterpolicy.kyverno.io/only-cosign-image-deploy configured

    Шаг 8.2: Проверка политики

    В пространстве имён policy, где определена политика, создайте Pod для проверки политики.

    Используйте подписанный образ, созданный пайплайном, для создания Pod.

    $ export NAMESPACE=<policy>
    $ export IMAGE=<<registry>/test/chains/demo-1:latest@sha256:93635f39cb31de5c6988cdf1f10435c41b3fb85570c930d51d41bbadc1a90046>
    
    $ kubectl run -n $NAMESPACE signed --image=${IMAGE} -- sleep 3600
    
    pod/signed created

    Pod будет успешно создан.

    $ export NAMESPACE=<policy>
    $ kubectl get pod -n $NAMESPACE signed
    
    NAME      READY   STATUS    RESTARTS   AGE
    signed   1/1     Running   0          10s

    Используйте неподписанный образ для создания Pod.

    $ export NAMESPACE=<policy>
    $ export IMAGE=<<registry>/test/chains/unsigned:latest>
    
    $ kubectl run -n $NAMESPACE unsigned --image=${IMAGE} -- sleep 3600

    Если вы получите такой вывод, значит Pod заблокирован политикой.

    Error from server: admission webhook "mutate.kyverno.svc-fail" denied the request:
    
    resource Pod/policy/unsigned was blocked due to the following policies
    
    only-cosign-image-deploy:
      check-image: 'failed to verify image ubuntu:latest:
        .attestors[0].entries[0].keys: no signatures found'

    Шаг 9: Очистка ресурсов

    Удалите Pod, созданные на предыдущих шагах.

    $ export NAMESPACE=<policy>
    $ kubectl delete pod -n $NAMESPACE signed
    
    pod "signed" deleted

    Удалите политику.

    $ kubectl delete clusterpolicy only-cosign-image-deploy

    Ожидаемые результаты

    После выполнения этого руководства:

    • У вас настроена работа с Tekton Chains для подписи образов и Kyverno для проверки подписей
    • Ваши контейнерные образы автоматически подписываются в процессе сборки
    • В указанном пространстве имён разрешено развертывание только подписанных образов
    • Неподписанные образы автоматически блокируются политиками Kyverno
    • Вы реализовали базовый контроль безопасности цепочки поставок для контейнерных образов

    Это руководство предоставляет основу для внедрения безопасности цепочки поставок в ваших CI/CD пайплайнах. В продуктивной среде рекомендуется:

    1. Настроить правильную изоляцию пространств имён и контроль доступа
    2. Реализовать безопасное управление ключами подписи
    3. Настроить мониторинг и оповещения о нарушениях политик
    4. Регулярно менять ключи подписи и обновлять политики безопасности
    5. Рассмотреть возможность внедрения дополнительных мер безопасности, таких как сканирование уязвимостей

    Ссылки