1. Введение
Container Analysis обеспечивает сканирование уязвимостей и хранение метаданных для контейнеров. Служба сканирования выполняет сканирование уязвимостей в изображениях в реестре артефактов и реестре контейнеров, затем сохраняет полученные метаданные и делает их доступными для использования через API. Хранилище метаданных позволяет хранить информацию из разных источников, включая сканирование уязвимостей, облачные сервисы Google и сторонних поставщиков.
Сканирование уязвимостей может происходить автоматически или по требованию:
- Если автоматическое сканирование включено, сканирование запускается автоматически каждый раз, когда вы отправляете новое изображение в реестр артефактов или реестр контейнеров. Информация об уязвимостях постоянно обновляется при обнаружении новых уязвимостей.
- Если сканирование по требованию включено, необходимо запустить команду для сканирования локального образа или изображения в реестре артефактов или реестре контейнеров. Сканирование по требованию обеспечивает гибкость при сканировании контейнеров. Например, вы можете отсканировать локально созданный образ и устранить уязвимости перед сохранением его в реестре. Результаты сканирования доступны в течение 48 часов после завершения сканирования, а информация об уязвимостях не обновляется после сканирования.
Благодаря Container Analysis, интегрированному в ваш конвейер CI/CD, вы можете принимать решения на основе этих метаданных. Например, вы можете использовать двоичную авторизацию для создания политик развертывания, которые разрешают развертывание только совместимых образов из доверенных реестров.
Что вы узнаете
- Как включить автоматическое сканирование
- Как выполнить сканирование по требованию
- Как интегрировать сканирование в конвейер сборки
- Как подписать утвержденные изображения
- Как использовать контроллеры допуска GKE для блокировки изображений
- Как настроить GKE, чтобы разрешать только подписанные утвержденные изображения
2. Настройка и требования
Самостоятельная настройка среды
- Войдите в Google Cloud Console и создайте новый проект или повторно используйте существующий. Если у вас еще нет учетной записи Gmail или Google Workspace, вам необходимо ее создать .
- Имя проекта — это отображаемое имя для участников этого проекта. Это строка символов, не используемая API Google. Вы можете обновить его в любое время.
- Идентификатор проекта уникален для всех проектов Google Cloud и является неизменяемым (невозможно изменить после его установки). Cloud Console автоматически генерирует уникальную строку; обычно тебя не волнует, что это такое. В большинстве лабораторий кода вам потребуется указать идентификатор проекта (обычно он обозначается как
PROJECT_ID
). Если вам не нравится сгенерированный идентификатор, вы можете создать другой случайный идентификатор. Кроме того, вы можете попробовать свой собственный и посмотреть, доступен ли он. Его нельзя изменить после этого шага, и он останется в силе на протяжении всего проекта. - К вашему сведению, есть третье значение — номер проекта , который используют некоторые API. Подробнее обо всех трех этих значениях читайте в документации .
- Затем вам необходимо включить выставление счетов в Cloud Console, чтобы использовать облачные ресурсы/API. Прохождение этой лаборатории кода не должно стоить много, если вообще стоит. Чтобы отключить ресурсы и избежать выставления счетов за пределами этого руководства, вы можете удалить созданные вами ресурсы или удалить весь проект. Новые пользователи Google Cloud имеют право на участие в программе бесплатной пробной версии стоимостью 300 долларов США .
Запустить редактор Cloudshell
Эта лабораторная работа была разработана и протестирована для использования с редактором Google Cloud Shell. Чтобы получить доступ к редактору,
- получите доступ к своему проекту Google по адресу https://console.cloud.google.com .
- В правом верхнем углу нажмите на значок редактора облачной оболочки.
- В нижней части окна откроется новая панель.
Настройка среды
В Cloud Shell укажите идентификатор и номер вашего проекта. Сохраните их как переменные PROJECT_ID
и PROJECT_ID
.
export PROJECT_ID=$(gcloud config get-value project)
export PROJECT_NUMBER=$(gcloud projects describe $PROJECT_ID \
--format='value(projectNumber)')
Включить службы
Включите все необходимые службы:
gcloud services enable \
cloudkms.googleapis.com \
cloudbuild.googleapis.com \
container.googleapis.com \
containerregistry.googleapis.com \
artifactregistry.googleapis.com \
containerscanning.googleapis.com \
ondemandscanning.googleapis.com \
binaryauthorization.googleapis.com
Создать репозиторий реестра артефактов
В ходе этой лабораторной работы вы будете использовать реестр артефактов для хранения и сканирования изображений. Создайте репозиторий с помощью следующей команды.
gcloud artifacts repositories create artifact-scanning-repo \
--repository-format=docker \
--location=us-central1 \
--description="Docker repository"
Настройте docker для использования ваших учетных данных gcloud при доступе к реестру артефактов.
gcloud auth configure-docker us-central1-docker.pkg.dev
3. Автоматическое сканирование
Сканирование артефактов запускается автоматически каждый раз, когда вы отправляете новое изображение в реестр артефактов или реестр контейнеров. Информация об уязвимостях постоянно обновляется при обнаружении новых уязвимостей. В этом разделе вы отправите изображение в реестр артефактов и изучите результаты.
Создать и перейти в рабочий каталог
mkdir vuln-scan && cd vuln-scan
Определите образец изображения
Создайте файл Dockerfile со следующим содержимым.
cat > ./Dockerfile << EOF
FROM gcr.io/google-appengine/debian9@sha256:ebffcf0df9aa33f342c4e1d4c8428b784fc571cdf6fbab0b31330347ca8af97a
# System
RUN apt update && apt install python3-pip -y
# App
WORKDIR /app
COPY . ./
RUN pip3 install Flask==1.1.4
RUN pip3 install gunicorn==20.1.0
CMD exec gunicorn --bind :$PORT --workers 1 --threads 8 --timeout 0 main:app
EOF
Создайте файл main.py со следующим содержимым.
cat > ./main.py << EOF
import os
from flask import Flask
app = Flask(__name__)
@app.route("/")
def hello_world():
name = os.environ.get("NAME", "Worlds")
return "Hello {}!".format(name)
if __name__ == "__main__":
app.run(debug=True, host="0.0.0.0", port=int(os.environ.get("PORT", 8080)))
EOF
Создайте и отправьте изображение в AR
Используйте Cloud Build, чтобы создать и автоматически отправить контейнер в реестр артефактов. Обратите внимание на тег bad
на изображении. Это поможет вам идентифицировать его для последующих шагов.
gcloud builds submit . -t us-central1-docker.pkg.dev/${PROJECT_ID}/artifact-scanning-repo/sample-image:bad
Просмотр сведений об изображении
После завершения процесса сборки просмотрите образ и результаты поиска уязвимостей на панели мониторинга реестра артефактов.
- Откройте реестр артефактов в облачной консоли.
- Нажмите на репозиторий сканирования артефактов, чтобы просмотреть его содержимое.
- Нажмите на детали изображения
- Нажмите на последний дайджест вашего изображения.
- После завершения сканирования щелкните вкладку уязвимостей для изображения.
На вкладке уязвимостей вы увидите результаты автоматического сканирования только что созданного образа.
Автоматическое сканирование включено по умолчанию. Изучите настройки реестра артефактов, чтобы узнать, как отключить или включить автоматическое сканирование.
4. Сканирование по требованию
Существуют различные сценарии, когда вам может потребоваться запустить сканирование перед отправкой образа в репозиторий. Например, разработчик контейнера может отсканировать изображение и исправить проблемы, прежде чем отправить код в систему управления версиями. В приведенном ниже примере вы создадите и проанализируете изображение локально, прежде чем действовать на основе результатов.
Создайте изображение
На этом этапе вы будете использовать локальный докер для создания образа в локальном кеше.
docker build -t us-central1-docker.pkg.dev/${PROJECT_ID}/artifact-scanning-repo/sample-image .
Сканируйте изображение
После создания изображения запросите его сканирование. Результаты сканирования сохраняются на сервере метаданных. Задание завершается размещением результатов на сервере метаданных.
gcloud artifacts docker images scan \
us-central1-docker.pkg.dev/${PROJECT_ID}/artifact-scanning-repo/sample-image \
--format="value(response.scan)" > scan_id.txt
Просмотр выходного файла
Найдите минутку и просмотрите выходные данные предыдущего шага, которые были сохранены в файле scan_id.txt. Обратите внимание на расположение отчета о результатах сканирования на сервере метаданных.
cat scan_id.txt
Просмотр подробных результатов сканирования
Чтобы просмотреть фактические результаты сканирования, используйте команду list-vulnerabilities
в месте отчета, указанном в выходном файле.
gcloud artifacts docker images list-vulnerabilities $(cat scan_id.txt)
Вывод содержит значительный объем данных обо всех уязвимостях в образе.
Пометить Критические проблемы
Люди редко используют данные, хранящиеся в отчете, напрямую. Обычно результаты используются автоматизированным процессом. Используйте команды ниже, чтобы прочитать детали отчета и зарегистрировать, если были обнаружены какие-либо КРИТИЧЕСКИЕ уязвимости.
export SEVERITY=CRITICAL
gcloud artifacts docker images list-vulnerabilities $(cat scan_id.txt) --format="value(vulnerability.effectiveSeverity)" | if grep -Fxq ${SEVERITY}; then echo "Failed vulnerability check for ${SEVERITY} level"; else echo "No ${SEVERITY} Vulnerabilities found"; fi
Результатом этой команды будет
Failed vulnerability check for CRITICAL level
5. Создание конвейерного сканирования
В этом разделе вы создадите автоматизированный конвейер сборки, который будет создавать образ контейнера, сканировать его и оценивать результаты. Если КРИТИЧЕСКИХ уязвимостей не обнаружено, образ будет отправлен в репозиторий. Если будут обнаружены КРИТИЧЕСКИЕ уязвимости, сборка завершится неудачно и будет завершена.
Предоставить доступ к учетной записи Cloud Build Service.
Cloud Build потребуются права для доступа к API сканирования по требованию. Обеспечьте доступ с помощью следующих команд.
gcloud projects add-iam-policy-binding ${PROJECT_ID} \
--member="serviceAccount:${PROJECT_NUMBER}@cloudbuild.gserviceaccount.com" \
--role="roles/iam.serviceAccountUser"
gcloud projects add-iam-policy-binding ${PROJECT_ID} \
--member="serviceAccount:${PROJECT_NUMBER}@cloudbuild.gserviceaccount.com" \
--role="roles/ondemandscanning.admin"
Создайте конвейер Cloud Build
Следующая команда создаст в вашем каталоге файл cloudbuild.yaml, который будет использоваться для автоматического процесса. В этом примере шаги ограничены процессом сборки контейнера. Однако на практике в дополнение к шагам контейнера вы должны включать инструкции и тесты для конкретного приложения.
Создайте файл с помощью следующей команды.
cat > ./cloudbuild.yaml << EOF
steps:
# build
- id: "build"
name: 'gcr.io/cloud-builders/docker'
args: ['build', '-t', 'us-central1-docker.pkg.dev/${PROJECT_ID}/artifact-scanning-repo/sample-image', '.']
waitFor: ['-']
#Run a vulnerability scan at _SECURITY level
- id: scan
name: 'gcr.io/cloud-builders/gcloud'
entrypoint: 'bash'
args:
- '-c'
- |
(gcloud artifacts docker images scan \
us-central1-docker.pkg.dev/${PROJECT_ID}/artifact-scanning-repo/sample-image \
--location us \
--format="value(response.scan)") > /workspace/scan_id.txt
#Analyze the result of the scan
- id: severity check
name: 'gcr.io/cloud-builders/gcloud'
entrypoint: 'bash'
args:
- '-c'
- |
gcloud artifacts docker images list-vulnerabilities \$(cat /workspace/scan_id.txt) \
--format="value(vulnerability.effectiveSeverity)" | if grep -Fxq CRITICAL; \
then echo "Failed vulnerability check for CRITICAL level" && exit 1; else echo "No CRITICAL vulnerability found, congrats !" && exit 0; fi
#Retag
- id: "retag"
name: 'gcr.io/cloud-builders/docker'
args: ['tag', 'us-central1-docker.pkg.dev/${PROJECT_ID}/artifact-scanning-repo/sample-image', 'us-central1-docker.pkg.dev/${PROJECT_ID}/artifact-scanning-repo/sample-image:good']
#pushing to artifact registry
- id: "push"
name: 'gcr.io/cloud-builders/docker'
args: ['push', 'us-central1-docker.pkg.dev/${PROJECT_ID}/artifact-scanning-repo/sample-image:good']
images:
- us-central1-docker.pkg.dev/${PROJECT_ID}/artifact-scanning-repo/sample-image
EOF
Запуск конвейера CI
Отправьте сборку на обработку, чтобы проверить, что сборка прерывается при обнаружении уязвимости КРИТИЧЕСКОЙ серьезности.
gcloud builds submit
Обзор ошибки сборки
Только что отправленная вами сборка не удастся, поскольку образ содержит КРИТИЧЕСКИЕ уязвимости.
Просмотрите ошибку сборки на странице истории сборки Cloud .
Исправьте уязвимость
Обновите Dockerfile, чтобы использовать базовый образ, не содержащий КРИТИЧЕСКИХ уязвимостей.
Перезапишите файл Dockerfile, чтобы использовать образ Debian 10, с помощью следующей команды:
cat > ./Dockerfile << EOF
from python:3.8-slim
# App
WORKDIR /app
COPY . ./
RUN pip3 install Flask==2.1.0
RUN pip3 install gunicorn==20.1.0
CMD exec gunicorn --bind :\$PORT --workers 1 --threads 8 main:app
EOF
Запустите процесс CI с хорошим изображением
Отправьте сборку на обработку, чтобы убедиться, что сборка завершится успешно, если не обнаружено критических уязвимостей.
gcloud builds submit
Обзор успеха сборки
Только что отправленная вами сборка будет успешной, поскольку обновленный образ не содержит КРИТИЧЕСКИХ уязвимостей.
Просмотрите успех сборки на странице истории сборки облака.
Просмотр результатов сканирования
Просмотрите хороший образ в реестре артефактов.
- Откройте реестр артефактов в облачной консоли.
- Нажмите на репозиторий сканирования артефактов, чтобы просмотреть его содержимое.
- Нажмите на детали изображения
- Нажмите на последний дайджест вашего изображения.
- Нажмите на вкладку уязвимостей, чтобы увидеть изображение.
6. Подписание изображений
Создайте заметку проверяющего
Примечание аттестатора — это просто небольшой фрагмент данных, который действует как метка для типа применяемой подписи. Например, одно примечание может обозначать сканирование уязвимостей, а другое может использоваться для завершения контроля качества. На это примечание будет сделана ссылка в процессе подписания.
Создать заметку
cat > ./vulnz_note.json << EOM
{
"attestation": {
"hint": {
"human_readable_name": "Container Vulnerabilities attestation authority"
}
}
}
EOM
Сохранить заметку
NOTE_ID=vulnz_note
curl -vvv -X POST \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $(gcloud auth print-access-token)" \
--data-binary @./vulnz_note.json \
"https://containeranalysis.googleapis.com/v1/projects/${PROJECT_ID}/notes/?noteId=${NOTE_ID}"
Подтвердите примечание
curl -vvv \
-H "Authorization: Bearer $(gcloud auth print-access-token)" \
"https://containeranalysis.googleapis.com/v1/projects/${PROJECT_ID}/notes/${NOTE_ID}"
Создание аттестатора
Подтверждающие используются для выполнения фактического процесса подписания изображения и прикрепляют вхождение примечания к изображению для последующей проверки. Создайте подтверждающего для последующего использования.
Создать аттестатора
ATTESTOR_ID=vulnz-attestor
gcloud container binauthz attestors create $ATTESTOR_ID \
--attestation-authority-note=$NOTE_ID \
--attestation-authority-note-project=${PROJECT_ID}
Проверить аттестатора
gcloud container binauthz attestors list
Обратите внимание, что в последней строке указано NUM_PUBLIC_KEYS: 0
ключи вы предоставите на более позднем этапе.
Также обратите внимание, что Cloud Build автоматически создает в вашем проекте built-by-cloud-build
когда вы запускаете сборку, генерирующую образы. Таким образом, приведенная выше команда возвращает двух аттестаторов: vulnz-attestor
built-by-cloud-build
. После успешной сборки образов Cloud Build автоматически подписывает и создает для них аттестации.
Добавление роли IAM
Учетной записи службы двоичной авторизации потребуются права на просмотр примечаний к аттестации. Предоставьте доступ с помощью следующего вызова API
PROJECT_NUMBER=$(gcloud projects describe "${PROJECT_ID}" --format="value(projectNumber)")
BINAUTHZ_SA_EMAIL="service-${PROJECT_NUMBER}@gcp-sa-binaryauthorization.iam.gserviceaccount.com"
cat > ./iam_request.json << EOM
{
'resource': 'projects/${PROJECT_ID}/notes/${NOTE_ID}',
'policy': {
'bindings': [
{
'role': 'roles/containeranalysis.notes.occurrences.viewer',
'members': [
'serviceAccount:${BINAUTHZ_SA_EMAIL}'
]
}
]
}
}
EOM
Используйте файл для создания политики IAM.
curl -X POST \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $(gcloud auth print-access-token)" \
--data-binary @./iam_request.json \
"https://containeranalysis.googleapis.com/v1/projects/${PROJECT_ID}/notes/${NOTE_ID}:setIamPolicy"
Добавление ключа KMS
Аттестатору необходимы криптографические ключи для прикрепления заметки и предоставления проверяемых подписей. На этом этапе вы создадите и сохраните ключи в KMS для доступа к Cloud Build позже.
Сначала добавьте несколько переменных среды для описания нового ключа.
KEY_LOCATION=global
KEYRING=binauthz-keys
KEY_NAME=codelab-key
KEY_VERSION=1
Создайте брелок для хранения набора ключей.
gcloud kms keyrings create "${KEYRING}" --location="${KEY_LOCATION}"
Создайте новую пару ключей асимметричной подписи для подтверждающего.
gcloud kms keys create "${KEY_NAME}" \
--keyring="${KEYRING}" --location="${KEY_LOCATION}" \
--purpose asymmetric-signing \
--default-algorithm="ec-sign-p256-sha256"
Вы должны увидеть свой ключ на странице KMS Google Cloud Console.
Теперь свяжите ключ со своим аттестатором с помощью команды gcloud binauthz:
gcloud beta container binauthz attestors public-keys add \
--attestor="${ATTESTOR_ID}" \
--keyversion-project="${PROJECT_ID}" \
--keyversion-location="${KEY_LOCATION}" \
--keyversion-keyring="${KEYRING}" \
--keyversion-key="${KEY_NAME}" \
--keyversion="${KEY_VERSION}"
Если вы еще раз распечатаете список полномочий, вы увидите зарегистрированный ключ:
gcloud container binauthz attestors list
Создание подписанного свидетельства
На этом этапе у вас настроены функции, позволяющие подписывать изображения. Используйте созданный ранее аттестатор, чтобы подписать образ контейнера, с которым вы работали.
CONTAINER_PATH=us-central1-docker.pkg.dev/${PROJECT_ID}/artifact-scanning-repo/sample-image
DIGEST=$(gcloud container images describe ${CONTAINER_PATH}:latest \
--format='get(image_summary.digest)')
Теперь вы можете использовать gcloud для создания аттестации. Команда просто принимает сведения о ключе, который вы хотите использовать для подписи, и конкретном образе контейнера, который вы хотите утвердить.
gcloud beta container binauthz attestations sign-and-create \
--artifact-url="${CONTAINER_PATH}@${DIGEST}" \
--attestor="${ATTESTOR_ID}" \
--attestor-project="${PROJECT_ID}" \
--keyversion-project="${PROJECT_ID}" \
--keyversion-location="${KEY_LOCATION}" \
--keyversion-keyring="${KEYRING}" \
--keyversion-key="${KEY_NAME}" \
--keyversion="${KEY_VERSION}"
С точки зрения Container Analysis, это создаст новое вхождение и прикрепит его к заметке вашего проверяющего. Чтобы убедиться, что все работает как положено, вы можете перечислить свои аттестации.
gcloud container binauthz attestations list \
--attestor=$ATTESTOR_ID --attestor-project=${PROJECT_ID}
7. Подписание с помощью Cloud Build
Вы включили подпись изображения и вручную использовали аттестатора для подписи образца изображения. На практике вам понадобится применять аттестации во время автоматизированных процессов, таких как конвейеры CI/CD.
В этом разделе вы настроите Cloud Build для автоматической проверки изображений.
Роли
Добавьте роль наблюдателя аттестатора авторизации двоичных данных в учетную запись службы сборки Cloud:
gcloud projects add-iam-policy-binding ${PROJECT_ID} \
--member serviceAccount:${PROJECT_NUMBER}@cloudbuild.gserviceaccount.com \
--role roles/binaryauthorization.attestorsViewer
Добавьте роль подписывающего/проверяющего криптоключа Cloud KMS в учетную запись службы сборки Cloud (подпись на основе KMS):
gcloud projects add-iam-policy-binding ${PROJECT_ID} \
--member serviceAccount:${PROJECT_NUMBER}@cloudbuild.gserviceaccount.com \
--role roles/cloudkms.signerVerifier
Добавьте роль прикрепителя заметок Container Analysis к учетной записи службы Cloud Build:
gcloud projects add-iam-policy-binding ${PROJECT_ID} \
--member serviceAccount:${PROJECT_NUMBER}@cloudbuild.gserviceaccount.com \
--role roles/containeranalysis.notes.attacher
Подготовьте этап пользовательской сборки облачной сборки
Вы будете использовать этап «Пользовательская сборка» в Cloud Build, чтобы упростить процесс аттестации. Google предоставляет этот шаг пользовательской сборки, который содержит вспомогательные функции для оптимизации процесса. Перед использованием код для этапа пользовательской сборки необходимо встроить в контейнер и отправить в Cloud Build. Для этого выполните следующие команды:
git clone https://github.com/GoogleCloudPlatform/cloud-builders-community.git
cd cloud-builders-community/binauthz-attestation
gcloud builds submit . --config cloudbuild.yaml
cd ../..
rm -rf cloud-builders-community
Добавьте этап подписания в свой cloudbuild.yaml.
На этом этапе вы добавите этап аттестации в свой конвейер Cloud Build, который вы создали ранее.
- Просмотрите новый шаг, который вы собираетесь добавить.
Только обзор. Не копировать
#Sign the image only if the previous severity check passes - id: 'create-attestation' name: 'gcr.io/${PROJECT_ID}/binauthz-attestation:latest' args: - '--artifact-url' - 'us-central1-docker.pkg.dev/${PROJECT_ID}/artifact-scanning-repo/sample-image' - '--attestor' - 'projects/${PROJECT_ID}/attestors/$ATTESTOR_ID' - '--keyversion' - 'projects/${PROJECT_ID}/locations/$KEY_LOCATION/keyRings/$KEYRING/cryptoKeys/$KEY_NAME/cryptoKeyVersions/$KEY_VERSION'
- Замените файл cloudbuild.yaml обновленным полным конвейером.
cat > ./cloudbuild.yaml << EOF
steps:
# build
- id: "build"
name: 'gcr.io/cloud-builders/docker'
args: ['build', '-t', 'us-central1-docker.pkg.dev/${PROJECT_ID}/artifact-scanning-repo/sample-image', '.']
waitFor: ['-']
#Run a vulnerability scan at _SECURITY level
- id: scan
name: 'gcr.io/cloud-builders/gcloud'
entrypoint: 'bash'
args:
- '-c'
- |
(gcloud artifacts docker images scan \
us-central1-docker.pkg.dev/${PROJECT_ID}/artifact-scanning-repo/sample-image \
--location us \
--format="value(response.scan)") > /workspace/scan_id.txt
#Analyze the result of the scan
- id: severity check
name: 'gcr.io/cloud-builders/gcloud'
entrypoint: 'bash'
args:
- '-c'
- |
gcloud artifacts docker images list-vulnerabilities \$(cat /workspace/scan_id.txt) \
--format="value(vulnerability.effectiveSeverity)" | if grep -Fxq CRITICAL; \
then echo "Failed vulnerability check for CRITICAL level" && exit 1; else echo "No CRITICAL vulnerability found, congrats !" && exit 0; fi
#Retag
- id: "retag"
name: 'gcr.io/cloud-builders/docker'
args: ['tag', 'us-central1-docker.pkg.dev/${PROJECT_ID}/artifact-scanning-repo/sample-image', 'us-central1-docker.pkg.dev/${PROJECT_ID}/artifact-scanning-repo/sample-image:good']
#pushing to artifact registry
- id: "push"
name: 'gcr.io/cloud-builders/docker'
args: ['push', 'us-central1-docker.pkg.dev/${PROJECT_ID}/artifact-scanning-repo/sample-image:good']
#Sign the image only if the previous severity check passes
- id: 'create-attestation'
name: 'gcr.io/${PROJECT_ID}/binauthz-attestation:latest'
args:
- '--artifact-url'
- 'us-central1-docker.pkg.dev/${PROJECT_ID}/artifact-scanning-repo/sample-image:good'
- '--attestor'
- 'projects/${PROJECT_ID}/attestors/$ATTESTOR_ID'
- '--keyversion'
- 'projects/${PROJECT_ID}/locations/$KEY_LOCATION/keyRings/$KEYRING/cryptoKeys/$KEY_NAME/cryptoKeyVersions/$KEY_VERSION'
images:
- us-central1-docker.pkg.dev/${PROJECT_ID}/artifact-scanning-repo/sample-image:good
EOF
Запустите сборку
gcloud builds submit
Просмотрите сборку в истории сборок Cloud.
Откройте Cloud Console на странице «История сборок облака» и просмотрите последнюю сборку и успешное выполнение этапов сборки.
8. Политика контроля допуска
Двоичная авторизация — это функция GKE и Cloud Run, которая обеспечивает возможность проверки правил перед запуском образа контейнера. Проверка выполняется при любом запросе на запуск образа, будь то из доверенного конвейера CI/CD или от пользователя, пытающегося развернуть образ вручную. Эта возможность позволяет защитить среду выполнения более эффективно, чем только проверки конвейера CI/CD.
Чтобы понять эту возможность, вы измените политику GKE по умолчанию, чтобы обеспечить соблюдение строгих правил авторизации.
Создайте кластер GKE
Создайте кластер GKE:
gcloud beta container clusters create binauthz \
--zone us-central1-a \
--binauthz-evaluation-mode=PROJECT_SINGLETON_POLICY_ENFORCE
Разрешите Cloud Build развертывание в этом кластере:
gcloud projects add-iam-policy-binding ${PROJECT_ID} \
--member="serviceAccount:${PROJECT_NUMBER}@cloudbuild.gserviceaccount.com" \
--role="roles/container.developer"
Разрешить все политики
Сначала проверьте состояние политики по умолчанию и возможность развертывания любого образа.
- Обзор существующей политики
gcloud container binauthz policy export
- Обратите внимание, что для политики применения установлено значение
ALWAYS_ALLOW
evaluationMode: ALWAYS_ALLOW
- Разверните образец, чтобы убедиться, что вы можете развернуть что угодно.
kubectl run hello-server --image gcr.io/google-samples/hello-app:1.0 --port 8080
- Убедитесь, что развертывание сработало
kubectl get pods
Вы увидите следующий вывод
- Удалить развертывание
kubectl delete pod hello-server
Запретить все политики
Теперь обновите политику, чтобы запретить все изображения.
- Экспортируйте текущую политику в редактируемый файл.
gcloud container binauthz policy export > policy.yaml
- Изменить политику
В текстовом редакторе измените AssessmentMode с ALWAYS_ALLOW на ALWAYS_DENY .
edit policy.yaml
YAML-файл политики должен выглядеть следующим образом:
globalPolicyEvaluationMode: ENABLE defaultAdmissionRule: evaluationMode: ALWAYS_DENY enforcementMode: ENFORCED_BLOCK_AND_AUDIT_LOG name: projects/PROJECT_ID/policy
- Откройте терминал, примените новую политику и подождите несколько секунд, пока изменения вступят в силу.
gcloud container binauthz policy import policy.yaml
- Попытка развертывания образца рабочей нагрузки
kubectl run hello-server --image gcr.io/google-samples/hello-app:1.0 --port 8080
- Развертывание завершается неудачей со следующим сообщением
Error from server (VIOLATES_POLICY): admission webhook "imagepolicywebhook.image-policy.k8s.io" denied the request: Image gcr.io/google-samples/hello-app:1.0 denied by Binary Authorization default admission rule. Denied by always_deny admission rule
Отмените политику, чтобы разрешить все
Прежде чем перейти к следующему разделу, обязательно отмените изменения политики.
- Изменить политику
В текстовом редакторе измените AssessmentMode с ALWAYS_DENY на ALWAYS_ALLOW .
edit policy.yaml
YAML-файл политики должен выглядеть следующим образом:
globalPolicyEvaluationMode: ENABLE defaultAdmissionRule: evaluationMode: ALWAYS_ALLOW enforcementMode: ENFORCED_BLOCK_AND_AUDIT_LOG name: projects/PROJECT_ID/policy
- Применить отмененную политику
gcloud container binauthz policy import policy.yaml
9. Блокировка уязвимостей в GKE
В этом разделе вы объедините полученные знания, реализовав конвейер CI/CD с Cloud Build, который сканирует образы, а затем проверяет их на наличие уязвимостей перед подписанием образа и попыткой развертывания. GKE будет использовать двоичную авторизацию для проверки наличия подписи в результате сканирования уязвимостей, прежде чем разрешить запуск образа.
Обновите политику GKE, чтобы требовать аттестации
Требовать, чтобы изображения были подписаны вашим аттестатором путем добавления кластераAdmissionRules в вашу политику GKE BinAuth.
Замените политику обновленной конфигурацией, используя команду ниже.
COMPUTE_ZONE=us-central1-a
cat > binauth_policy.yaml << EOM
defaultAdmissionRule:
enforcementMode: ENFORCED_BLOCK_AND_AUDIT_LOG
evaluationMode: ALWAYS_DENY
globalPolicyEvaluationMode: ENABLE
clusterAdmissionRules:
${COMPUTE_ZONE}.binauthz:
evaluationMode: REQUIRE_ATTESTATION
enforcementMode: ENFORCED_BLOCK_AND_AUDIT_LOG
requireAttestationsBy:
- projects/${PROJECT_ID}/attestors/vulnz-attestor
EOM
Применить политику
gcloud beta container binauthz policy import binauth_policy.yaml
Попытайтесь развернуть неподписанный образ.
Создайте дескриптор развертывания для приложения, которое вы создали ранее, с помощью следующей команды. Используемый здесь образ — это образ, созданный вами ранее, который содержит критические уязвимости и НЕ содержит подписанного подтверждения.
Контроллерам допуска GKE необходимо знать точный образ, который необходимо развернуть, чтобы последовательно проверять подпись. Для этого вам нужно будет использовать дайджест изображения и простой тег.
Получите дайджест изображения для плохого изображения
CONTAINER_PATH=us-central1-docker.pkg.dev/${PROJECT_ID}/artifact-scanning-repo/sample-image
DIGEST=$(gcloud container images describe ${CONTAINER_PATH}:bad \
--format='get(image_summary.digest)')
Используйте дайджест в конфигурации Kubernetes
cat > deploy.yaml << EOM
apiVersion: v1
kind: Service
metadata:
name: deb-httpd
spec:
selector:
app: deb-httpd
ports:
- protocol: TCP
port: 80
targetPort: 8080
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: deb-httpd
spec:
replicas: 1
selector:
matchLabels:
app: deb-httpd
template:
metadata:
labels:
app: deb-httpd
spec:
containers:
- name: deb-httpd
image: ${CONTAINER_PATH}@${DIGEST}
ports:
- containerPort: 8080
env:
- name: PORT
value: "8080"
EOM
Попытайтесь развернуть приложение в GKE.
kubectl apply -f deploy.yaml
Просмотрите рабочую нагрузку в консоли и обратите внимание на ошибку, сообщающую, что развертывание отклонено:
No attestations found that were valid and signed by a key trusted by the attestor
Развертывание подписанного образа
Получите дайджест изображения для плохого изображения
CONTAINER_PATH=us-central1-docker.pkg.dev/${PROJECT_ID}/artifact-scanning-repo/sample-image
DIGEST=$(gcloud container images describe ${CONTAINER_PATH}:good \
--format='get(image_summary.digest)')
Используйте дайджест в конфигурации Kubernetes
cat > deploy.yaml << EOM
apiVersion: v1
kind: Service
metadata:
name: deb-httpd
spec:
selector:
app: deb-httpd
ports:
- protocol: TCP
port: 80
targetPort: 8080
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: deb-httpd
spec:
replicas: 1
selector:
matchLabels:
app: deb-httpd
template:
metadata:
labels:
app: deb-httpd
spec:
containers:
- name: deb-httpd
image: ${CONTAINER_PATH}@${DIGEST}
ports:
- containerPort: 8080
env:
- name: PORT
value: "8080"
EOM
Разверните приложение в GKE
kubectl apply -f deploy.yaml
Просмотрите рабочую нагрузку в консоли и обратите внимание на успешное развертывание образа.
10. Поздравляем!
Поздравляем, вы завершили работу над кодом!
Что мы рассмотрели:
- Как включить автоматическое сканирование
- Как выполнить сканирование по требованию
- Как интегрировать сканирование в конвейер сборки
- Как подписать утвержденные изображения
- Как использовать контроллеры допуска GKE для блокировки изображений
- Как настроить GKE, чтобы разрешать только подписанные утвержденные изображения
Что дальше:
- Защита развертывания образов в Cloud Run и Google Kubernetes Engine | Документация по облачной сборке
- Краткое руководство: настройка политики двоичной авторизации с помощью GKE | Google Облако
Очистить
Чтобы избежать списания средств с вашей учетной записи Google Cloud за ресурсы, используемые в этом руководстве, либо удалите проект, содержащий ресурсы, либо сохраните проект и удалите отдельные ресурсы.
Удаление проекта
Самый простой способ избавиться от выставления счетов — удалить проект, созданный вами для этого руководства.