Pipeline с проверкой на уязвимости | OTUS

Pipeline с проверкой на уязвимости

DevOps_deep_23.8-5020-0664c1.png

В предыдущем посте я рассказал, как развернуть 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 для проекта.

Итог

Перед мержем тим лид можно быстро перейти на отчёты по уязвимостям и сделать соответствующие выводы (на тему, хочет ли он это мержить либо нет).

Не пропустите новые полезные статьи!

Спасибо за подписку!

Мы отправили вам письмо для подтверждения вашего email.
С уважением, OTUS!

Автор
0 комментариев
Для комментирования необходимо авторизоваться
Популярное
Сегодня тут пусто
Запланируй обучение с выгодой!
Получи скидку 10% на все курсы ноября и декабря до 17.11 →