Pull to refresh
67.39
Газинформсервис
Надежные решения для безопасности бизнеса

DevSecOps «за 5 копеек»

Reading time6 min
Views6.1K
image
В этой статье один из сотрудников нашей компании Сергей Полунин Belowzero273 расскажет, как с помощью бесплатных инструментов можно построить простой CI/CD-пайплайн с инструментами контроля безопасности. И сделает это настолько просто, чтобы если даже вы никогда не слышали о подобном подходе, то вам захочется начать экспериментировать в этом направлении, как только появится свободное время.
— Самый популярный вопрос, который я слышу последние несколько лет от заказчиков, звучит так: «А что, так можно было?». Звучит он почти каждый раз, когда мы внедряем новый инструмент, технологию или процесс. В этом, безусловно, нет ничего удивительного – ИТ и информационная безопасность стали слишком необъятной областью даже для крупных команд специалистов. Давно прошли времена, когда можно было нанять одного крутого сисадмина, который будет во всем разбираться и быть в курсе всех трендов. Эти времена ушли, судя по всему, навсегда. Но сегодня даже для узкого специалиста сложно быть «в теме» – постоянно читать профильные блоги, телеграм-каналы, форумы, смотреть записи выступлений гуру на ютубе и тому подобное. Мы привыкаем решать проблемы определенным образом и выход за пределы «пузыря» может происходить долго и порой весьма болезненно.
А уж если заходит речь о том, что какая-то непонятная и вряд ли нужная по мнению бизнеса вещь будет стоить каких-то дополнительных денег, то желание отложить изучение появляется само собой.

Часто, даже если специалист прочитает обзорную статью о какой-то технологии, первая мысль будет в духе «Ну, это не про меня / тут слишком много всего / с чего тут вообще начать?». И дорога в тысячу ли опять начинается сами знаете с чего.
Вот как с популярным нынче DevSecOps. Термин хайповый, всем вроде надо, но с чего начать – непонятно. Даже нет единого мнения, что это конкретно такое, зато есть тонна программных продуктов, которые вроде как должны нам этот DevSecOps обеспечить.
Итак, у нас есть группа разработчиков, которые усердно создают очень нужный бизнесу Продукт™, упаковывают в docker-образ, загружают в репозиторий DockerHub, а затем благополучно запускают его где-то в облаке или просто на сервере под столом. Команда программистов пишет код, а все прочие операции вручную делает ещё один инженер. Затем клиенты подключаются к этому приложению через браузер и все довольны.
Начнем мы с установки средства автоматизации. В нашем случае это будет бесплатный Jenkins, потому что мы с вами договорились, что наш бюджет составляет ноль рублей ноль копеек.

Установка Jenkins


Установка Jenkins не должна вызвать каких-то трудностей, это обычное Java-приложение, которое мы поставим на сервер под управлением Debian 10.
Обновим репозитории:
sudo apt-get update


Установим Java:
sudo apt-get install default-jdk


Скачаем GPG-ключ:
wget-q-O-https://pkg.jenkins.io/debian/jenkins.io.key | sudo apt-key add-


И добавим репозиторий:
sudo sh –c ‘echo deb https://pkg.jenkins.io/debian-stable binary/ > /etc/apt/sources.list.d/jenkins.list’


Теперь ещё раз обновимся и установим Jenkins:
sudo apt-get update
sudo apt-get install Jenkins


И пускай Jenkins запускается автоматически:
sudo systemctl start jenkins
sudo systemctl enable jenkins


Теперь наш Jenkins доступен по адресу localhost:8080, но его ещё предстоит разблокировать ключом, который лежит в /var/lib/jenkins/secrets/initialAdminPassword. Добро пожаловать!

Теперь нам нужно добавить две учётные записи. Одну для DockerHub, которую мы назовём docker_id, она потребуется нам для работы с hub.docker.com, а другую – ключ для SonarQube. Была бы нужна ещё одна, для github.com, но в данном случае у нас публичный репозиторий.
image

А также добавим наш сервер SonarQube:
image

Кроме этого, установим плагины для работы с docker и SonarQube.

Автоматизация 101


Теперь давайте автоматизируем то, что у нас и так есть. Мы хотим, чтобы контейнер собирался по инструкции из Dockerfile, который лежит у нас в github.com, где, кстати, лежат файлы самого нашего приложения. Затем собранный образ нужно закинуть в DockerHub и уже потом запустить наш контейнер на веб-сервере.
Сделаем в Jenkins простой пайплайн, в котором опишем эти четыре шага. Предварительно в настройках пайплайна не забудем указать, что весь исходный код у нас хранится в репозитории на github.com:
image

Итак, шаг первый, получим необходимые файлы из SCM (в нашем случае github.com):
stage('Clone Git repository') {
checkout scm
}

Теперь создадим образ:
stage('Build Image') {
sh 'echo Build application image'
app = docker.build("<имя_вашего_репозитория>/<имя_образа> ", "./<путь к Dockerfile> ")
}


Теперь нужно загрузить наш образ на hub.docker.com:
stage('Push image to Docker Hub') {
sh 'echo Push image to a Docker Hub'
docker.withRegistry('https://registry.hub.docker.com', 'docker_id') {
app.push("latest") 
}
}


Загружаем мы с помощью учётных данных, которые до этого мы назвали docker_id, и даём нашему образу тэг latest. И наконец, запустим наш контейнер на веб-сервере:
stage('Run container') {
sh 'echo Run container'
sh 'ansible-playbook /opt/playbooks/docker_playbook.yaml -i /opt/playbooks/hosts'
}

Здесь запускается несложный плейбук Ansible, который с помощью модуля docker_container и запустит наш контейнер. Плейбук действительно крайне прост:
---
- name: Run all-your-base-image
  docker_container:
    name: all-your-base
    image: < имя_вашего_репозитория>/<имя_образа >:latest
    state: started
    recreate: yes
    pull: true
    ports:
     - "80:80"
    exposed_ports:
      - "80"
    detach: true
    container_default_behavior: compatibility
...


Всё готово, теперь запустим наш пайплайн:
image

Отлично, теперь сборку и доставку новой версии можно осуществлять полностью автоматически, как только появится что добавить в образ. Никакого больше ручного ввода команд!

Добавим безопасности


Теперь было бы здорово интегрировать в этот пайплайн несколько инструментов, которые бы проверяли наше веб-приложение. В самом простом варианте нужно 3 инструмента:
— Static Application Security Testing (SAST), он же статический анализатор кода,
— Dynamic Application Security Testing (DAST), он же динамический анализатор кода,
— какое-нибудь решение для проверки самого контейнера.
И поскольку бюджет нашего проекта всё еще не превышает нуля рублей, мы возьмем бесплатные инструменты, т.е. соответственно SonarQube, OWASP ZAP и Trivy.
Давайте добавим их в наш пайплайн.
SonarQube я установил на отдельный сервер, создал там простой quality gate, который требует, чтобы количество багов было не более 1, а количество серьёзных проблем не более 5:
image

Теперь после того, как код будет загружен из github.com, мы будем его проверять нашим сканером:
stage('SonarQube analysis') {
sh 'echo Run SAST - SonarQube analysis'
def scannerHome = tool 'sonar_scanner';
withSonarQubeEnv() {
sh "${scannerHome}/bin/sonar-scanner -Dsonar.projectKey=myapp"
}
}
	
stage("SonarQube Quality Gate") {
waitForQualityGate abortPipeline: true
}

При этом, если проблемы в коде будут найдены, выполнение нашего pipeline прервется.
Теперь проверим собранный контейнер. Это мы будем делать сразу после того, как наш собранный образ отправится в DockerHub:
stage('Trivy analysis') {
sh 'echo Trivy check'
sh 'trivy image --exit-code 1 --severity CRITICAL,HIGH <имя_вашего_репозитория>/<имя_образа>:latest '
}


Здесь мы указали, что в случае, если Trivy найдет проблемы уровня Critical или High, то пайплайн нужно прервать и разобраться в чем дело.
И наконец уже развернутое веб-приложение мы просканируем с помощью OWASP ZAP:
stage('OWASP ZAP analysis') {
sh 'echo Run DAST - OWASP ZAP analysis'
sh "docker run -t owasp/zap2docker-stable zap-baseline.py -t http://192.168.0.197 || true"
}

Здесь всё чуть менее сурово, нам достаточно будет отчёта о сканировании. Тем более что прерывать пайплайн уже нет смысла, приложение уже развернуто и доступно нашим клиентам.
Запустим, что получилось:
image

Отлично, наш образ автоматически был собран, проверен и развернут на удаленном сервере. Стоп, и это всё? Конечно же, нет! Это только самое начало. Мы ещё можем:
  • добавить инструменты в наш пайплайн;
  • заставить Jenkins собирать и доставлять новый контейнер, как только на гитхабе кто-то сделает коммит;
  • добавить дополнительные плейбуки Ansible для настройки различных аспектов: от самих контейнеров до сервера, на котором они запускаются;
  • протестировать другие SAST/DAST и совместно с разработчиками и решить, какие лучшие использовать или даже комбинировать;
  • перейти от запуска отдельных контейнеров к Kubernetes;
  • написать более сложные политики и quality gate;
  • сделать отдельные пайплйаны для тестовых и продуктивных сред;
  • и многое другое.

В любом случае, если вы самостоятельно попробуете сделать такой пайплайн для своих задач, то скорее всего, лучше других сможете сформулировать, что же вы хотите в итоге получить в вашем конкретном случае. Но даже внедрение этих нескольких инструментов наверняка существенно повысят уровень безопасности ваших продуктов.
Материал подготовил сотрудник компании «Газинформсервис» Сергей Полунин, блог Сергея можно почитать по ссылке.
Tags:
Hubs:
Total votes 4: ↑4 and ↓0+4
Comments2

Articles

Information

Website
www.gaz-is.ru
Registered
Founded
Employees
1,001–5,000 employees
Location
Россия