Cosign для Docker-образов: подписываем сборку и проверяем её перед установкой
Тег production выглядит убедительно. Он обещает, что внутри находится правильная версия приложения, но технически остаётся изменяемым указателем. Если тег перезаписали или доступ к реестру оказался у постороннего, команда развёртывания может получить совсем другой образ.
Cosign позволяет подписать конкретное содержимое образа и проверить подпись перед запуском. Сервер получает дополнительное основание доверять артефакту: его подписал известный ключ или определённая подтверждённая идентичность сборки. Для небольшого проекта начнём с понятной схемы с отдельной парой ключей.
Подпись не доказывает отсутствие уязвимостей и не исправляет скомпрометированную сборку. Она связывает образ с выбранным источником доверия. Именно эту связь мы и будем проверять.
Содержание
- Digest важнее красивого тега
- Разделяем сборку и сервер приложения
- Создаём ключи и определяем владельца
- Подписываем опубликованный образ
- Проверка должна управлять развёртыванием
- Нужен тест с неправильным образом
- Проверка после копирования между реестрами
- Что делать при смене ключа
- От подписи к понятной цепочке выпуска
Развёртывайте только проверенные сборки
На VPS MAATRIX можно настроить проверку подписей перед запуском контейнера. Ресурсы выбирайте по приложению, а ключ подписи держите вне рабочего сервера.
ВЫБРАТЬ VPSDigest важнее красивого тега
У контейнерного образа есть digest — контрольная сумма манифеста. Ссылка вида registry.example.com/team/app@sha256:... указывает на конкретный артефакт. Тег вроде latest или release может со временем указывать на другой digest.
Подписывайте и развёртывайте образ по digest. Иначе между проверкой тега и загрузкой его значение может измениться. В журнале выпуска сохраняйте digest, версию приложения, идентификатор сборки и результат проверки.
Для образов с несколькими архитектурами уточните, что именно подписывается: общий индекс манифестов или отдельный платформенный манифест. Сервер должен проверять тот уровень, на который ссылается процедура развёртывания. Не смешивайте результаты проверки разных объектов только потому, что у них одинаковое название.
Документация Cosign для контейнеров описывает подпись и хранение связанных артефактов в реестре. Перед внедрением проверьте совместимость вашего registry и его правила очистки.
Разделяем сборку и сервер приложения
Закрытый ключ подписи должен находиться в доверенной системе сборки или защищённом сервисе управления ключами. На рабочем VPS достаточно публичного ключа для проверки. Если разместить закрытый ключ рядом с приложением, компрометация сервера позволит подписывать новые вредоносные образы тем же доверенным ключом.
Для пилота подойдёт отдельный MAATRIX Uab Start с 2 vCPU и 4 GB памяти, если на нём запускается небольшое тестовое приложение. Ресурсы выбирают прежде всего по самому приложению: проверка подписи обычно не определяет размер сервера.
Используйте поддерживаемую Ubuntu или Debian, Docker и Cosign из проверенного официального выпуска. При установке самого Cosign проверьте происхождение бинарного файла по инструкции проекта. Цепочка доверия плохо начинается со случайного исполняемого файла из непонятной ссылки.
Для первого опыта выделите тестовый репозиторий образов. Учётная запись сборки должна иметь право публиковать образ и подпись, а сервер развёртывания — читать необходимые объекты. Полный административный доступ к registry для чтения не нужен.
Создаём ключи и определяем владельца
На доверенной машине выполните:
cosign generate-key-pair
Команда создаёт закрытый и публичный ключи. Защитите закрытый ключ парольной фразой и сохраните его по принятой процедуре. Не добавляйте файл cosign.key в репозиторий, контейнерный образ или публичный артефакт CI.
Публичный ключ можно распространять, но его подлинность важна. Передайте его на сервер через доверенный административный канал и установите в каталог, который обычное приложение не может изменять, например /etc/deploy/cosign.pub с владельцем root.
Запишите назначение ключа, владельца, дату ввода и порядок замены. Один ключ для всех проектов упрощает первую настройку, но увеличивает область последствий при компрометации. Разделяйте ключи там, где различаются команды и уровни доверия.
Варианты локальных ключей и внешних хранилищ описаны в руководстве Cosign по управлению ключами. Для постоянного CI полезно оценить управляемый KMS или иной защищённый механизм, соответствующий вашей инфраструктуре.
Подписываем опубликованный образ
Сначала соберите образ и отправьте его в тестовый registry. Получите точный digest опубликованного артефакта из результата сборки или через инструмент реестра. Не используйте контрольную сумму Dockerfile: это другой объект.
Сохраните полную ссылку в переменной IMAGE_REF. В ней должен быть настоящий адрес вашего образа с @sha256: и полным digest. Затем выполните:
cosign sign --key cosign.key "$IMAGE_REF"
Для обращения к реестру нужны соответствующие учётные данные. Команда может запросить пароль ключа и подтверждение действий, связанных с журналом прозрачности. Прочитайте сообщение, прежде чем включать автоматические ответы в CI.
Если используете публичную инфраструктуру прозрачности, учитывайте, какие метаданные становятся доступны. Не включайте в имена образов и подписи секреты или личные данные. Для закрытых требований изучите подходящую поддерживаемую схему, не отключая проверки наугад.
После подписи выполните проверку на отдельной машине с одним публичным ключом. Это подтверждает, что результат доступен потребителю, а не только локальной среде автора.
Нужен сервер под эту задачу?
Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США и РФ. Оплата картой РФ и по СБП.
АРЕНДОВАТЬ СЕРВЕРПроверка должна управлять развёртыванием
На VPS выполните:
cosign verify --key /etc/deploy/cosign.pub "$IMAGE_REF"
При успехе Cosign проверяет подпись относительно переданного ключа. Дополнительные требования и варианты проверки описаны в документации verify. Не подменяйте проверку поиском слова «success» в произвольном журнале: используйте код завершения команды.
Процедура установки должна останавливаться при неуспешной проверке. После успеха передавайте Docker или Compose ту же ссылку по digest, которую проверили. Если дальше запускается изменяемый тег, смысл защиты теряется на последнем шаге.
Сохраняйте результат проверки и идентификатор выпуска в журнале без секретов. Нужна возможность объяснить, какой образ был установлен и почему процедура сочла его доверенным.
Не добавляйте аварийный флаг «пропустить подпись» в обычный интерфейс выпуска. Если действительно нужен особый восстановительный процесс, он должен быть отдельным, ограниченным и оставлять явный след.
Нужен тест с неправильным образом
Проверка правильного образа мало говорит о защите. Попробуйте другой образ без подписи, образ с подписью другого ключа и недоступный registry. Во всех случаях развёртывание должно остановиться до изменения работающего приложения.
Затем подпишите новую учебную версию и убедитесь, что она проходит. Проверьте, что старая версия остаётся доступной для запланированного отката. Если политика очистки registry удаляет подписи или связанные объекты, это нужно обнаружить до первого аварийного выпуска.
Отдельно испытайте несовпадение архитектуры. Успешная проверка происхождения не означает, что бинарный файл подходит конкретному серверу. Подпись и совместимость платформы — разные проверки, и обе должны входить в процедуру.
Для команды полезно хранить небольшой набор контрольных случаев и выполнять его после изменения CI, обновления Cosign или переноса реестра. Один отрицательный тест часто показывает больше, чем длинный отчёт о правильно подписанной демонстрации.
Проверка после копирования между реестрами
Образ нередко проходит через промежуточный реестр: сборка публикуется в одном месте, а сервер получает её из внутреннего зеркала. Проверьте этот путь целиком. Вместе с самим образом должны быть доступны необходимые материалы подписи, а команда проверки должна относиться к тому объекту, который затем запускается. Успешная проверка исходного реестра не доказывает, что зеркало содержит тот же выпуск.
Для приёмки возьмите один небольшой тестовый образ, подпишите его, перенесите штатным способом и выполните проверку из сети сервера. Затем повторите опыт после очистки старых артефактов в тестовом реестре. Это обнаружит правила хранения, которые сохраняют контейнер, но удаляют связанные подписи. Владелец реестра должен знать, что эти файлы участвуют в разрешении на выпуск, а не являются необязательным украшением рядом с тегом.
Если зеркало недоступно, не добавляйте временное исключение «разрешить любой образ». Лучше остановить новый выпуск и оставить работающую проверенную версию: аварийная кнопка обхода быстро становится самым популярным способом развёртывания.
Что делать при смене ключа
Плановая ротация начинается с нового ключа и распространения его публичной части. На переходный период политика может принимать согласованные старый и новый ключи, если ваша процедура проверки это явно поддерживает. Не полагайтесь на то, что два файла в одном каталоге автоматически означают доверие обоим.
Подпишите тестовый выпуск новым ключом и проверьте серверы. После завершения перехода уберите старое доверие в согласованный срок. Сохраните сведения о том, какими ключами подписывались прежние версии, чтобы план отката не стал неожиданным отказом проверки.
При компрометации ситуация другая: подпись старого ключа уже не является достаточным основанием. Нужно пересмотреть доверенные артефакты и происхождение сборок, заменить ключ и обновить правила серверов. Простая повторная подпись неизвестного образа новым ключом не делает его безопасным.
Откат также должен проходить проверку. При этом технически корректно подписанный старый выпуск может содержать известную уязвимость. Политика допустимых версий должна учитывать это отдельно от криптографической подписи.
От подписи к понятной цепочке выпуска
Дальнейший шаг — подписанные сведения о происхождении сборки и составе зависимостей. Они помогают ответить, из какого исходного состояния получен образ и что находится внутри. Но такие документы полезны только при проверке доверенного автора и привязки к тому же digest.
Не считайте Cosign заменой тестов, сканирования зависимостей или защиты CI. Если злоумышленник может изменить доверенный workflow и получить доступ к ключу, он способен подписать вредоносную сборку вполне корректно.
Для небольшого проекта уже полезна простая цепочка: известная сборка публикует образ, отдельный доверенный ключ подписывает digest, VPS проверяет подпись и запускает именно этот digest. Теперь тег перестаёт быть обещанием на честном слове, а установка получает проверяемое основание.
Нужен сервер под эту задачу?
Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США и РФ. Оплата картой РФ и по СБП.
АРЕНДОВАТЬ СЕРВЕРОбсудить статью, задать вопрос или начать новую тему
Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.
Перейти в сообщество →