Содержимое
🧠Задача: Безопасный 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 внутри и вне контейнера — включая монтирование хостовых директорий. Это делает возможным побег из контейнера. 💡 Такой пайплайн не только безопаснее, но и более прозрачен, масштабируем и предсказуем.