Pipeline с проверкой на уязвимости
В предыдущем посте я рассказал, как развернуть Harbor — репозиторий для хранения докер образов со встроенной проверкой на уязвимости (Clair). Логично собрать конвейер, который при получении очередного пуша в feature branch производит все необходимые проверки и выдаёт отчёт. Так и сделаем: - push to feature-branch - сборка контейнера - анализ кода в собранном контейнере на уязвимости (SNYK) - push образа в харбор - скан образа на уязвимости (harbor умеет делать автоматически, либо через API) - получение ссылки на отчеты по обоим проверкам в окне merge request
В settings гитлаба можно настроить переменные для репозитория, чтобы не прописывать credentials в открытом виде. В приложенном пайплайне предполагается, что используется runner с тэгом harbor. Пайплайн предполагает запуск docker-in-docker с проброшенным с хоста сокетом.
image: $harbor_registry/library/docker:latest variables: DOCKER_DRIVER: overlay2 GIT_SUBMODULE_STRATEGY: recursive SCAN_API: https://$harbor_registry/api/repositories/repo%2Fproject/tags/$CI_COMMIT_SHORT_SHA/scan CVE_API: https://$harbor_registry/api/repositories/repo%2Fproject/tags/$CI_COMMIT_SHORT_SHA/vulnerability/details CVE_URI: https://$harbor_registry/harbor/projects/3/repositories/repo%2Fproject/tags/${CI_COMMIT_SHORT_SHA} JSON_TYPE: 'Accept: application/json' JSON_CONTENT: 'Content-Type: application/json' AUTH: $harbor_auth SNYK_TOKEN: $snyk_token SHARED_PATH: /builds/$CI_PROJECT_PATH/artifacts stages: - build - snyk - deploy - pages build_docker: before_script: - docker login -u $harbor_login -p $harbor_password https://$harbor_registry stage: build tags: - harbor script: - docker build -t $harbor_registry/repo/project:$CI_COMMIT_SHORT_SHA . only: - /^feature-.*$/ pages: stage: pages script: - mkdir public - | echo " <html> <title> CVE Reports for project ${CI_PROJECT_NAME}</title> <body> <ul> <li><a href=./snyk.html>SNYK report</a></li> <li><a href=${CVE_URI}>Harbor CVE report</a></li> </ul> </body> </html> " > public/index.html - cp artifacts/snyk.html public/ tags: - harbor artifacts: paths: - public snyk_code: stage: snyk tags: - harbor script: - mkdir -p ${SHARED_PATH} - | echo " if [ -f /usr/bin/yum ];then yum install npm -y;fi npm install -g snyk npm install -g snyk-to-html snyk auth $SNYK_TOKEN snyk test --json | snyk-to-html -o /snyk.html " > snyk.sh - docker create --name snyk --entrypoint bash $harbor_registry/repo/project:$CI_COMMIT_SHORT_SHA /snyk.sh - docker cp snyk.sh snyk:/snyk.sh - docker start snyk - docker wait snyk - docker cp snyk:/snyk.html ${SHARED_PATH}/snyk.html - docker rm snyk allow_failure: true artifacts: paths: - ${SHARED_PATH}/snyk.html only: - /^feature-.*$/ push_docker_to_harbor: before_script: - docker login -u $harbor_login -p $harbor_password https://$harbor_registry stage: deploy tags: - harbor script: - docker push $harbor_registry/repo/project:$CI_COMMIT_SHORT_SHA - curl -I -k -H "$JSON_TYPE" -H "$JSON_CONTENT" -H "$AUTH" -X POST $SCAN_API allow_failure: true only: - /^feature-.*$/
Немного пояснений
Пайплайн разделён на 4 стэйджа: build - сборка образа snyk - проверка сныком deploy - отправка в харбор и скан образа pages - выкладка артифактов в gitlab pages
stage SNYK
- создаётся скрипт snyk.sh, который устанавливает SNYK и запускает проверку
- запускается контейнер на основе ранее собранного образа
- туда копируется созданный скрипт
- запускается скрипт
- из контейнера забирается отчёт и помещается в артифакты (чтобы вытащить артифакт в другом стэйдже: pages)
### stage deploy - пушим образ в harbor репозиторий - запускаем скан через API
stage pages
- формируем индексную страницу с ссылками на образ в харборе (со всеми проверками) и отчёт от snyk
- копируем snyk отчёт из артифактов в public (для pages)
Информация в merge request в гитлаб
Если задать в проекте каталог .gitlab/merge_request_templates/, а в нём создать нужный вам description template в формате markdown, который затем можно выбирать при создании merge request. Я создал mr.md и в нём просто прописал ссылку на pages для проекта.
Итог
Перед мержем тим лид можно быстро перейти на отчёты по уязвимостям и сделать соответствующие выводы (на тему, хочет ли он это мержить либо нет).