Статья Signed Commits и Artifact Signing: защита цепочки поставок кода

1768945319136.webp

Представь себе ситуацию: ты сидишь в своем уютном офисе, работая над важным проектом, и вдруг приходит уведомление - твоя система скомпрометирована. Как? Через код, который ты только что развернул в продакшн. Никаких тревожных знаков не было, но кто-то сумел внедрить вредоносный код через цепочку поставок. Как это возможно? Ведь все выглядит чисто - твой код подписан, контейнеры проверены, зависимости актуальны. Но даже при таких мерах безопасности атака всё же могла пройти. Как это произошло?

Ответ на этот вопрос прост, как и проблема, с которой мы сталкиваемся: цепочка поставок кода - это не просто набор библиотек и контейнеров. Это путь, по которому движется каждая строка кода от разработчика до продакшн-системы, и если в этот путь проникнет злоумышленник, последствия могут быть катастрофическими. От typosquatting до dependency confusion и компрометированных CI/CD пайплайнов - рисков масса. Но что если я скажу, что ты можешь сделать всё возможное, чтобы обезопасить свою цепочку поставок? Мы поговорим о том, как это можно сделать с помощью криптографических подписей, от GPG до Sigstore, и как это помогает избежать атак. Готов ли ты обезопасить свою инфраструктуру на всех уровнях?

Проблема supply chain атак: как мы вообще до такого докатились?​

Появление supply chain атак - это то, о чем невозможно не слышать в последние несколько лет. Такие атаки направлены не на то, чтобы пробиться в систему через обычный вход, а на то, чтобы тихо проникнуть через те механизмы, которые обеспечивают поставку всего необходимого для работы нашей инфраструктуры: от кода до контейнеров и зависимостей. Почему это проблема? Да потому что сегодня, когда все зависимы от внешних библиотек, сервисов и контейнерных образов, атакующие могут заложить вредоносный код прямо в эти поставки, а мы даже не заметим. И да, эти атаки могут привести к серьезным последствиям, от компрометации данных до потери репутации.

Типы атак: typosquatting, dependency confusion и прочее​

Если говорить о видах атак на цепочку поставок, то можно назвать следующие:

Typosquatting - дефолтная атака, основанная на типографических ошибках. Например, создатель вредоносного пакета может зарегистрировать библиотеку с именем, очень похожим на популярное, но с ошибкой в одном символе. Кто-то случайно установит его, думая, что это оригинал, и привет, зловредный код на борту.

Dependency confusion - здесь злоумышленник подменяет легитимные зависимости на свои. Он уже знает, какие библиотеки и зависимости обычно используются в вашем проекте, и создает вредоносные версии, которые попадут в систему, если не настроены правильно при сборке проекта.

Compromised CI/CD - эта угроза не такая очевидная, но куда более коварная. Злоумышленники могут внедриться в систему CI/CD (инструменты автоматической сборки и тестирования), чтобы на этапе сборки и деплоя внедрить вредоносный код в ваши контейнеры или пакеты.

Реальные инциденты: SolarWinds и CodeCov​

Никто не мог пройти мимо самых громких атак последних лет, вроде SolarWinds и CodeCov.

SolarWinds - это один из самых громких инцидентов, когда хакеры проникли в систему обновлений и на несколько месяцев внедрили backdoor в обновления системы управления ИТ-инфраструктурой. Атака была настолько тщательной, что выявить её удалось лишь спустя месяцы. Она затронула тысячи организаций по всему миру, включая государственные структуры.

CodeCov - этот случай стал настоящим кошмаром для разработчиков. Злоумышленники получили доступ к CI/CD системе компании, что позволило им манипулировать кодом, который проходил через систему тестирования и деплоя. Это означало, что злоумышленники могли внедрить зловредный код в любые проекты, использующие их инструменты.

В статье: "Безопасность цепочки поставок (Supply Chain Security): Защита от атак через сторонних вендоров" мы рассказали, что атаки через компрометацию сторонних компонентов и служб не только становятся всё умнее, но и затрагивают инфраструктуру на каждом уровне, от обновлений до зависимостей.

SLSA Framework Overview​

Если бы не было проблем, не было бы и решений, да? Вот тут на помощь приходит SLSA (Supply Chain Levels for Software Artifacts) - фреймворк, который помогает как раз-таки обеспечить безопасность цепочек поставок. SLSA предлагает несколько уровней защиты, которые помогают минимизировать риски от подобных атак. Основные моменты, на которые стоит обратить внимание:

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

Подпись артефактов. Каждый артефакт (будь то библиотека, контейнерный образ или коммит) должен быть подписан, чтобы вы могли удостовериться в его подлинности.

Аудит и проверка. От использования CI/CD до интеграции с Kubernetes - важно все, от первых строк кода до финальной проверки в продакшн.

GPG-подпись коммитов: защита от фальшивок и прокачка безопасности​

Теперь, когда мы разобрались с угрозами, давай перейдем к тому, как защитить свою цепочку поставок на уровне исходного кода. Один из самых простых, но эффективных способов - это GPG-подпись коммитов. Это позволяет подтвердить, что код был изменен именно тем человеком, кто заявляет, что его изменил. Вдобавок, если кто-то решит подменить ваши коммиты в репозитории, это сразу станет очевидно.

Генерация GPG ключей​

Первым шагом будет генерация GPG ключа. Это несложно, и с этим сталкивался почти каждый, кто более-менее серьезно работает с Git. Всё, что нам нужно - это создать пару ключей: публичный и приватный.

Запускаешь команду:

Bash:
gpg --full-generate-key
Следующий шаг - это выбор типа ключа и его длины. Обычно для коммитов хватает RSA с длиной 4096 бит, так что можно идти по умолчанию. После этого выбери лимит действия ключа, если хочешь, чтобы он был ограничен, или установи бессрочный.

Не забудь про идентификацию: укажи имя и email, которые будут использоваться для подписания коммитов. Это важный момент, потому что потом именно эти данные будут проверяться при верификации.

Настройка Git​

Когда ключ сгенерирован, его нужно настроить в Git. Для этого нужно указать Git, какой ключ использовать для подписи. Делается это командой:

Bash:
git config --global user.signingkey <ID вашего ключа>
Где ID вашего ключа; - это идентификатор GPG ключа, который ты только что создал.

А чтобы каждый коммит автоматически подписывался, добавляешь еще одну настройку:

Bash:
git config --global commit.gpgSign true
Теперь все твои коммиты будут подписаны по умолчанию, и в случае атаки на репозиторий это сразу будет видно.

GitHub/GitLab верификация​

Если ты используешь GitHub или GitLab, то настройка GPG-подписей для них - это уже не просто вопрос безопасности, а и вопрос удобства. На этих платформах есть встроенная система верификации подписей. Подписанный коммит будет автоматически отображаться как "Verified" в интерфейсе.
verified-commit.webp

Чтобы привязать свой GPG ключ к аккаунту на GitHub или GitLab, нужно экспортировать свой публичный ключ и добавить его в настройки профиля. На GitHub это можно сделать через раздел "GPG Keys" в настройках безопасности. В GitLab аналогично, есть пункт для добавления GPG-ключа в настройки.

Enforcement: protected branches​

Теперь, когда коммиты подписаны, давай поговорим про защищенные ветки. Если ты хочешь убедиться, что только проверенные коммиты с GPG-подписью могут попадать в основную ветку (например, main или master), тебе нужно настроить защиту ветки.

На GitHub или GitLab можно настроить политику, что коммиты в защищенные ветки должны быть подписаны GPG ключом. Это добавляет ещё один слой защиты, предотвращая попадание в репозиторий неподписанных или фальшивых изменений.
1768944392367.webp


Sigstore Ecosystem: Полный контроль над поставками​

Если GPG-подпись коммитов - это первый шаг на пути к защите цепочки поставок, то Sigstore - это следующая ступень, которая помогает безопасно подписывать артефакты на более высоком уровне, включая контейнерные образы, зависимости и даже документацию. Sigstore предоставляет набор инструментов, которые позволяют сгенерировать подписи без необходимости управлять ключами вручную. Тут уже можно говорить о более глубокой интеграции в DevSecOps процесс.

Если взглянуть на актуальные материалы по защите контейнеров, становится очевидно: современные инструменты вроде Cosign и Sigstore - это не просто нишевые дополнения, а ответ на эволюцию атак, когда вредоносный слой внедряется прямо в контейнеры и образы. В одном из наших
обзоров мы подробно объяснили, как экосистема прозрачных подписей стала критичной частью DevSecOps-практик.

Архитектура: Cosign, Fulcio, Rekor​

Sigstore - это не просто один инструмент, а целая экосистема, в которой ключевые компоненты выполняют свою роль:

Cosign - инструмент для подписания контейнерных образов. Он позволяет подписывать как образы Docker, так и другие артефакты, такие как архивы или бинарники, с использованием криптографических подписей.

Fulcio - сервис, который работает с OIDC (OpenID Connect), чтобы предоставить идентификацию на основе удостоверений. В отличие от традиционного подхода с длинными ключами и их безопасным хранением, Fulcio позволяет подписывать без необходимости управления постоянными секретами. То есть ты можешь использовать свою учетную запись в Kubernetes или другой OIDC-платформе для аутентификации, а затем генерировать подписи для артефактов.

Rekor - сервис для хранения подписанных артефактов в прозрачных журналах. Он используется для записи всей информации о подписи (например, кто подписал и когда), что позволяет позже проверить не только саму подпись, но и всю историю изменений. Это повышает прозрачность и защищенность.

Transparency logs​

Одним из важных элементов в экосистеме Sigstore являются прозрачные журналы (Transparency logs). Это позволяет создавать цепочку доказательств для подписанных артефактов. Представь, что ты подписываешь контейнерный образ с помощью Cosign, и эта информация фиксируется в публичном журнале. В таком случае даже если кто-то попытается изменить подпись или удалить её, ты можешь сразу увидеть это в журнале.

Журналы обеспечивают независимую верификацию того, что с подписью всё в порядке, и что артефакт действительно был подписан именно тобой, а не кем-то другим.

Keyless signing с OIDC​

Теперь давай разберемся с keyless signing, который в контексте Sigstore выглядит как настоящая революция. Обычно при подписи артефактов с помощью GPG или других инструментов тебе нужно управлять ключами, которые могут быть скомпрометированы или утеряны. С помощью OIDC-based signing, в случае с Fulcio, тебе не нужно управлять ключами вообще.

OIDC (OpenID Connect) - это протокол для аутентификации, который широко используется для интеграции с различными сервисами, включая облачные платформы. Это позволяет тебе подписывать артефакты, используя свою учетную запись на платформе, и ключи больше не нужно хранить.

Представь, что ты интегрируешь свою систему с Kubernetes, и на основе этой интеграции автоматизируешь процесс подписания контейнерных образов. В этом случае нет необходимости в ручном управлении ключами - вся аутентификация происходит через OIDC, и ты получаешь все плюсы безопасности при минимальном управлении.
1768944416630.webp


Подпись контейнерных образов. Почему это важно?​

Контейнеры стали стандартом в современных системах, и их безопасность - это не шутки. Как защитить контейнерные образы и убедиться, что они не были подделаны? Ответ прост - подписывать их. Cosign - это инструмент, который позволяет подписывать контейнеры, и благодаря Sigstore это делается не только безопасно, но и удобно.

Cosign sign workflow​

Процесс подписания контейнерных образов с помощью Cosign прост. Давай разберем его пошагово.
  1. Устанавливаешь Cosign через менеджер пакетов или компиляцию из исходников.
  2. Генерируешь ключ или используешь keyless signing с помощью Fulcio для подписания образа.
  3. Выполняешь команду для подписания образа:
Bash:
cosign sign --key <your-key> <image-uri>
Эта команда создаст подпись, которую можно будет прикрепить к контейнерному образу. Всё это можно делать на этапе CI/CD, автоматически подписывая новые версии контейнеров, как только они проходят сборку.

Registry support​

Контейнерные образы можно хранить в различных регистрах, и важно, чтобы эти регистры поддерживали возможность хранения подписанных образов. Большинство популярных контейнерных регистров, включая Docker Hub, GCR и GitHub Container Registry, поддерживают хранение подписанных образов.

Когда образ подписан с помощью Cosign, его можно передавать в любой из этих регистров, и в дальнейшем можно будет проверять его подлинность перед тем, как развернуть его в продакшн.

Key management options​

Что касается управления ключами, то тут у тебя есть несколько вариантов. Ты можешь:
  • Использовать облачные хранилища ключей, такие как Google Cloud KMS или AWS KMS, для безопасного хранения приватных ключей.
  • Использовать keyless signing, что устраняет необходимость в управлении ключами вообще.

Attestations: дополнительный слой безопасности​

Когда речь идет о безопасности в цепочке поставок, важным элементом являются attestations - это не просто подписи, а полные доказательства того, что артефакт, такой как контейнерный образ или зависимость, был создан и подписан с соблюдением всех необходимых стандартов и требований безопасности.

Attestations могут быть использованы для различных целей, от подтверждения происхождения (provenance) до создания SBOM (Software Bill of Materials) и других документов, подтверждающих соответствие безопасности. Это позволяет нам не только проверять подпись, но и убедиться, что артефакт был создан в соответствии с политиками безопасности и требованиями compliance.

SLSA Provenance​

В рамках фреймворка SLSA (Supply Chain Levels for Software Artifacts), который мы уже упоминали, provenance - это информация о происхождении артефакта. Это своего рода доказательство того, что процесс сборки и создания артефакта был выполнен в соответствии с определенными требованиями безопасности и стандартами.

Когда мы говорим о SLSA provenance, то это фактически аттестация того, что контейнерный образ или библиотека прошли через все необходимые этапы проверки, были собраны из безопасных исходных кодов и подписаны корректным образом. Provenance предоставляет полную цепочку доказательств о том, что исходный код был собран и подписан именно теми, кто имеет к этому доступ и кто действовал в рамках установленных процессов.

Таким образом, если кто-то попытается вмешаться в процесс, это будет легко выявить, поскольку вся информация о происхождении артефакта будет в открытом доступе, зафиксирована в журнале и может быть проверена любым заинтересованным лицом.

SBOM Attestations​

SBOM (Software Bill of Materials) - это список всех компонентов, из которых состоит программное обеспечение. Он включает в себя не только библиотеки и их версии, но и всю информацию о зависимости между ними. Этот список имеет большое значение в контексте безопасности, поскольку помогает быстро определить, какие уязвимости могут быть у системы, если в каких-то зависимостях обнаружены новые уязвимости.

Attestations в контексте SBOM означают, что можно гарантировать, что все компоненты в SBOM были проверены, подписаны и прошли верификацию. С помощью таких attestations можно будет понять, что контейнер или программный пакет действительно собран из проверенных зависимостей, и исключить риски использования небезопасных или устаревших версий.

Когда ты подписываешь свой SBOM, ты как бы говоришь: "Этот список компонентов является актуальным и безопасным, и на момент сборки не было найдено никаких уязвимостей". Это даёт дополнительные гарантии безопасности для твоей цепочки поставок.

Custom Attestations​

Custom attestations - это индивидуализированные attestations, которые ты можешь настроить под свои требования безопасности и бизнес-логики. Например, если твой проект использует специфичные библиотеки или сервисы, ты можешь создать свою систему attestations, чтобы гарантировать, что в процессе сборки использовались только проверенные компоненты и что они соответствуют твоим внутренним стандартам безопасности.

Custom attestations могут включать информацию о том, какие шаги были предприняты для проверки безопасности, какие тесты были выполнены или какие методы защиты использовались. Это может быть полезно, если ты работаешь в строго регулируемой отрасли, где важен каждый аспект безопасности.
1768944437963.webp


Verification: как убедиться, что всё подписано правильно​

Теперь, когда мы наладили подписи и attestations, давай поговорим о том, как все это проверять на практике, особенно в рамках CI/CD пайплайнов и Kubernetes.

CI/CD Verification​

Это процесс проверки подписей и attestations прямо в процессе сборки и деплоя. Это важно, чтобы автоматизировать процесс проверки безопасности на каждом этапе работы с кодом и контейнерами.

Предположим, у тебя есть CI/CD пайплайн, который собирает контейнеры. После того как контейнер собран и подписан, в пайплайне можно настроить проверку подписи с помощью Cosign или других инструментов. Это будет выглядеть так:

  1. После того как контейнер собран, ты проверяешь подпись, используя команду типа:
Bash:
cosign verify --key <key> <image-uri>
  1. Если подпись действительна и соответствует ожиданиям, пайплайн продолжит выполнение. Если же подпись недействительна или отсутствует, пайплайн может автоматически отклонить сборку или деплой.
Подобная проверка дает уверенность, что в продакшн попадет только тот код, который был подписан и проверен на всех этапах.

Kubernetes Admission​

Admission controllers в Kubernetes - это механизмы, которые могут вмешиваться в процесс развертывания контейнеров и проверять их перед тем, как они попадут в кластер. Например, ты можешь настроить admission controller, который будет проверять, что каждый контейнер, который ты собираешься развернуть, подписан и соответствует стандартам безопасности.

Можно настроить такие проверки, используя инструменты вроде Kyverno. Это позволит интегрировать проверку подписей непосредственно в процесс деплоя Kubernetes, и если контейнер не пройдет проверку (например, подпись отсутствует или она неправильная), то деплой будет заблокирован.

Пример политики Kyverno для проверки контейнерных подписей:

YAML:
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
  name: verify-image-signature
spec:
  rules:
    - name: check-image-signature
      match:
        resources:
          kinds:
            - Pod
      validate:
        message: "The container image is not signed or has an invalid signature."
        pattern:
          spec:
            containers:
              - image: "*"
                imagePullPolicy: IfNotPresent
Таким образом, Kubernetes сам не даст контейнеру попасть в кластер, если он не подписан или подпись нарушена.
1768944455768.webp


Policy Enforcement: как всё это контролировать​

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

Kyverno image verification​

Kyverno позволяет создать политики для защиты цепочки поставок прямо в Kubernetes. Например, ты можешь настроить политику, которая требует, чтобы каждый контейнер, развернутый в Kubernetes, был подписан и проверен. Это важный шаг, чтобы не полагаться только на людей, а автоматизировать контроль безопасности.

Если мы говорим про enforce политики для верификации образов, то, как я показал в примере выше, можно настроить Kyverno на проверку подписей контейнеров, обеспечив защиту всего процесса с момента сборки и до деплоя в продакшн.

В материале по DevSecOps мы раскрыли важность не только автоматизации подписей и проверок, но и общего подхода к безопасности в SDLC. Речь идёт о том, что построение надежных политик доступа, непрерывный мониторинг и грамотное управление ключами - это части единой культуры, без которой современные механизмы подписи и enforcement теряют часть своей эффективности.

Так как же защитить свою цепочку поставок?​

Мы прошли долгий путь - от теории до практических инструментов, и теперь у нас есть четкая картина того, как можно защитить цепочку поставок с помощью криптографических подписей и attestations. Начав с GPG-подписей для коммитов, мы обеспечили базовую защиту от подмены кода, а с помощью Sigstore и Cosign мы вывели безопасность на новый уровень, интегрируя подписи и attestations в процесс CI/CD и Kubernetes. Использование SLSA provenance и SBOM attestations дает дополнительные гарантии того, что наши артефакты были созданы и подписаны в рамках строгих стандартов безопасности.

Но это только начало. Настройка Kyverno для верификации контейнеров и контроль подписей на каждом уровне инфраструктуры помогают нам создать более защищенную систему, в которой злоумышленникам будет сложнее пройти незамеченными. Всё это - не просто набор инструментов, а целый подход к защите цепочки поставок, который повышает безопасность, снижает риски и повышает доверие к твоей системе.

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

Вложения

  • verified-commit.webp
    verified-commit.webp
    10,2 КБ · Просмотры: 10
Мы в соцсетях:

Взломай свой первый сервер и прокачай скилл — Начни игру на HackerLab