tg-me.com/DevOPSitsec/1540
Last Update:
🧠 Задача: Безопасный CI/CD для Docker-образов в GitLab
Условие:
У вас есть следующий пайплайн:
build_and_push:
image: docker:latest
services:
- docker:dind
variables:
DOCKER_HOST: tcp://docker:2375
DOCKER_TLS_CERTDIR: ""
script:
- docker login -u "$CI_REGISTRY_USER" -p "$CI_REGISTRY_PASSWORD" "$CI_REGISTRY"
- docker build -t "$CI_REGISTRY_IMAGE:latest" .
- docker push "$CI_REGISTRY_IMAGE:latest"
Он работает, но содержит серьёзные проблемы безопасности и архитектурные ошибки.
🚨 Проблемы:
1. `docker:dind` и `tcp://docker:2375` — критически уязвимы.
Это значит, что любой процесс может получить root-доступ к Docker-демону, а значит и к хосту раннера.
2. Нет валидации образов или сканирования.
В репозиторий может попасть уязвимый образ.
3. Использование тега `latest`.
Тег можно перезаписать в любой момент — нарушает идемпотентность и аудит.
4. Пароли в переменных среды.
Лучше использовать безопасные токены (например, OIDC).
5. Нет изоляции сборки.
Образ может использовать
--privileged
, --network=host
, и не быть sandboxed.✅ Цель: Переделать пайплайн
Переход от DIND →
kaniko
, добавить проверку безопасности и стабильную версификацию.🛡️ Обновлённый
.gitlab-ci.yml
variables:
IMAGE_TAG: "${CI_COMMIT_SHORT_SHA}"
build_and_push:
image:
name: gcr.io/kaniko-project/executor:latest
entrypoint: [""]
script:
- echo "{\"auths\":{\"$CI_REGISTRY\":{\"username\":\"$CI_REGISTRY_USER\",\"password\":\"$CI_REGISTRY_PASSWORD\"}}}" > /kaniko/.docker/config.json
- /kaniko/executor \
--context $CI_PROJECT_DIR \
--dockerfile $CI_PROJECT_DIR/Dockerfile \
--destination $CI_REGISTRY_IMAGE:$IMAGE_TAG \
--destination $CI_REGISTRY_IMAGE:stable \
--snapshotMode=redo \
--single-snapshot
scan_image:
image: aquasec/trivy:latest
stage: test
script:
- trivy image --exit-code 1 --severity HIGH,CRITICAL $CI_REGISTRY_IMAGE:$IMAGE_TAG
🔍 Разбор улучшений:
• Kaniko — работает без привилегий, не требует docker.sock
• `IMAGE_TAG` = SHA — версии стабильны, audit-friendly
• Trivy — автоматическое сканирование уязвимостей
• Удаление `latest` — используем
stable
и SHA • Нет `docker:dind` — безопаснее, проще и быстрее
• Безопасная аутентификация — можно заменить
username/password
на OIDC в GitLab📌 Дополнительно:
1. Добавьте
rules:
в пайплайн, чтобы запускать сборку только по main
или тэгам.2. Используйте
readonly
контейнеры и fsGroup
если применимо.3. Ограничьте доступ к runner через
protected: true
.💣 Бонус: почему
docker:dind
= уязвимость?Если runner запускается в
privileged
режиме, то docker:dind
даёт возможность выполнять произвольные команды от root внутри и вне контейнера — включая монтирование хостовых директорий. Это делает возможным побег из контейнера.💡 Такой пайплайн не только безопаснее, но и более прозрачен, масштабируем и предсказуем.
BY DevOps
Warning: Undefined variable $i in /var/www/tg-me/post.php on line 283
Share with your friend now:
tg-me.com/DevOPSitsec/1540