Настройка проверки подписи образов

1. Предварительные условия

  1. Установлена утилита для подписи образов Cosign

  2. Установлен сервис NeuVector

  3. Создано пространство имён (в котором будет разрешен запуск только подписанных образов).
    Откройте в браузере веб-интерфейс Nova Console, перейдите на страницу HomeNamespaces и нажмите "Create Namespace"
    В открывшемся окне введите имя для неймспейса, например nova-cosign и нажмите "Create".

    Примечание: Если вы выберете другое имя, которое не начинается с "nova-", то создание пода будет неуспешным из-за более раннего условия NeuVector (№1002).

2. Настройка

  1. Сгенерируйте пару ключей выполнив следующую команду (в данном примере ключи будут сохранены в рабочую директорию, их так же можно сохранить в Vault или в секрет K8S, подробнее https://docs.sigstore.dev/key_management/overview/):

    cosign generate-key-pair

  2. В браузере откройте веб-интерфейс Neuvector и перейдите на страницу AssetsSigstore Verifiers.

  3. Для начала необходимо добавить корневой доверенный сертификат (Sigstore Root of Trust). Можно использовать свой сертификат или публичный (в данном примере будет использован публичный).
    Для добавления сертификата нажмите кнопку "+ Add" в правом-верхнем углу. В открывшемся окне выберите public и в поле Name введите root, после чего нажмите "Add"

    check image signature 1
  4. Теперь необходимо добавить ключ, сгенерированный в п.1 в качестве верификатора. Для этого, нажмите "+ Add" в разделе Verifiers. В открывшемся окне введите имя (например test), вставьте публичный ключ cosign.pub, сгенерированный в п.1 и нажмите "Add".

    check image signature 2
  5. Подготовим несколько образов для теста:

    • скачаем любой публичный образ, например nginx:
      docker pull nginx

    • добавим для данного образа тэг, чтобы потом загрузить его в свой реестр:
      docker tag nginx pstepanov90/nginx-signed:latest

    • загрузим новый тэг в свой репозиторий:
      docker push pstepanov90/nginx-signed:latest

    • подпишем тэг, используя ключ из п.1:
      cosign sign --key cosign.key pstepanov90/nginx-signed:latest
      Теперь у нас в реестре есть подписанный образ nginx.

  6. Для того, чтобы Neuvector мог контролировать подписанные образы, необходимо добавить свой Registry. Для этого перейдите на страницу AssetsRegistries и нажмите кнопку "Add".

  7. В открывшемся окне выберите тип реестра (в данном примере это Docker registry), задайте имя, введите адрес реестра, пользователя, пароль, фильтр (позволяет добавить только определённые образы) и настройки сканирования. Затем нажмите "Submit".

    check image signature 3
  8. После добавления реестра необходимо его просканировать нажав кнопку "Start scan".

  9. Теперь создадим правило, запрещающее запуск неподписанных образов. Для этого перейдите на страницу PolicyAdmission Control и нажмите кнопку "Add".

    • В открывшемся окне введите в поле Comment описание для правила, например "Проверка подписи".

    • Добавьте критерий проверки, для чего в поле Criterion выберите "Image Sigstore Verifiers", в качестве оператора выберите "does NOT contain ANY of", в поле Value выберите значение из п.4 (root\test) и нажмите "+".

    • Добавьте еще один критерий проверки, для чего в поле Criterion выберите "Namespace", в качестве оператора выберите "contains one of", а в качестве Value выберите имя из п.3 (Предварительные условия), после чего нажмите "+".

    • Убедитесь что режим Mode выбран "Protect" и Status переключен в состояние "Enabled", после чего нажмите Add.

      check image signature 4

      Примечание: Если правило не подействует. то нужно добавить ещё одно условие в правило. В поле Criterion выберите "Image signed", в поле Value выберите "false" и нажмите "+".

      check image signature 5
  10. Теперь проверим работу данного правила. Для этого откройте в браузере веб-интерфейс Nova Console и нажмите на кнопку "+" в правом-верхнем углу.

  11. В открывшемся окне введите следующий манифест и нажмите "Create":

    Примечание: тут мы пытаемся создать под используя официальный репозиторий.

    apiVersion: v1
    kind: Pod
    metadata:
      name: nginx
      namespace: nova-cosign
    spec:
      containers:
        - name: nginx
          image: 'nginx:latest'
  12. Убедитесь, что создание пода из неподписанного образа было заблокировано и на экран выведена соответствующая ошибка:

    check image signature 6
  13. Проверьте в консоли Neuvector какое правило заблокировало создание пода.

    check image signature 7
  14. Исправьте в манифесте имя образа на nginx-signed и нажмите "Create":

apiVersion: v1
kind: Pod
metadata:
  name: nginx
  namespace: nova-cosign
spec:
  containers:
    - name: nginx
      image: 'pstepanov90/nginx-signed:latest'