
В прошлой статье цикла «РБПО для бедных» мы разобрались, что такое разработка безопасного программного обеспечения, зачем она нужна стартапам и как может выглядеть минимальный конвейер безопасной разработки. Теперь пора переходить от схем и планов к практике.
В этом материале мы рассмотрим:
создание виртуальных машин в VirtualBox для сервисов безопасной разработки ПО;
подготовку виртуальных машин к дальнейшей работе;
установку Ubuntu Server с ручной настройкой статического IP;
первичную настройку серверов: часовой пояс, базовые утилиты, брандмауэр UFW, установку Docker и docker-compose.
Мы создадим и подготовим пять виртуальных машин, на которых в следующих частях будем разворачивать сервисы безопасной разработки. К концу статьи у нас будет готова инфраструктурная основа будущего конвейера РБПО.
Так что запасаемся терпением, запускаем VirtualBox и начинаем строить нашу небольшую лабораторию безопасной разработки.
Дисклеймер
Важно сразу условиться, Путник!
Данный цикл статей не заменяет требования ГОСТ, OWASP SAMM, BSIMM и других серьезных методологий безопасной разработки. Это скорее практический пример того, как можно организовать конвейер безопасной разработки ПО с минимальным вложением средств.
Всё описанное в цикле — исключительно мой личный опыт, набитые шишки и результаты долгих вечеров за клавиатурой. Это не официальная позиция моего текущего или бывших работодателей.
Воспринимать статью как руководство к бездумному копированию тоже не стоит. Проверяй всё на тестовых стендах, делай бэкапы и подходи к экспериментам с холодной головой.
Ошибки возможны, и не нужно бояться их совершать. Главное — делать выводы и постепенно строить процессы, которые будут надежнее вчерашних.
«Семеро одного не ждут», — подумал я и решил: ставить буду на одну ОС, чтобы потом не плясать с бубном от виртуалки к виртуалке. Выбор пал на Ubuntu Server 22.04 LTS.
«Почему?» — спросил царь стартапо-делающий. А потому, что я с ней уже имел дело, и она мне милее сердцу, чем суровый Alpine Linux. Не хочу я на старте с отсутствием пакетов воевать, мне бы пайплайн собрать, а не изучать тонкости Linux.
Научил я разработчиков бояр царских заклинанию заморскому: «Делай раз, делай два, делай три — виртуалка, живи!».
Погнали, показываю всё по шагам.
Делай раз! Создание виртуальной машины в VirtualBox
«Начинаем колдовать», — сказал я и щелкнул мышкой. Открываем VirtualBox, клацаем по меню «Машина» и жмем «Создать» (или просто Ctrl+N).
Переходим в «Экспертный режим», чтобы ничего не упустить. Заполняем поля по науке.
1. Имя и ОС:
Вводим имя будущей виртуальной машины — gitlab-vm (для иных сервисов наименования будут похожими, например, Nexus-vm и т. д. Полный перечень мы обсуждали в рамках первой статьи, когда распределяли ресурсы).
Выбираем ISO образ (у меня был скачанный с официального сайта ubuntu-22.04.5-live-server-amd64.iso)
Тип: Linux
Версия: Ubuntu (64-bit)

2. Объем памяти и количество ядер процессора: вводим значение согласно таблице из прошлой статьи (6 ГБ для GitLab).

3. Жесткий диск:
Жмем «Создать новый виртуальный жесткий диск».
Выбираем тип «VDI (VirtualBox Disk Image)».
Размер укажем из приведенной в прошлой статье таблицы.

Нажимаем «Готово». Виртуальная машина создана — можно приступить к настройке.
Делай два! Настройка виртуальной машины перед установкой
«Хорошему прыжку хороший разбег нужен», — молвил я и полез в настройки. Выделяю нашу только что созданную виртуалку и жму «Настроить». Тут важно разложить всё по полочкам, чтобы сеть работала, и загрузка шла откуда надо. Хожу по вкладкам, колдую:
1. Вкладка «Система/Материнская плата»:
Жмем «Включить EFI (только для некоторых ОС)».
Убеждаемся, что порядок загрузки верный. На первом месте «Оптический диск», затем «Жесткий диск» для того, чтобы загружался наш образ с ОС для ее установки.

2. Сеть (самое важное для доступа из локальной сети).
Добавляем 2 адаптера:
Адаптер 1:
Ставим галку «Включить сетевой адаптер».
Тип подключения — выбираем «Сетевой мост».
Выбираем физический сетевой интерфейс (Ethernet или Wi-Fi), через который ваш хост подключен к роутеру (позволит присвоить внутренние IP для виртуальных машин).
Адаптер 2:
Ставим галку «Включить сетевой адаптер».
Тип подключения выбираем NAT (даст виртуальной машине выход в интернет для загрузки обновлений и пакетов).
Сетевой мост нужен для доступа к ВМ из локальной сети, NAT — для выхода в интернет.

Делай три! Установка Ubuntu Server
«Ну, с Богом!» — сказал я и нажал зеленую стрелку «Запустить». Виртуалка ожила, загрузилась с ISO-образа и попросила меня ответить на несколько заковыристых вопросов. Будь внимателен, тут каждый шаг — как гадание на кофейной гуще, но я тебе всё разложу:
1. Выбор языка. Выбираем English (это снизит риск проблем с путями и кодировками в будущем).

2. Далее появится предложение обновить установщик до новой версии. Можно, конечно, да и нужно выбрать Update to the new installer, но я не захотел и жмякнул Continue without updating.

3. Выбираем раскладку клавиатуры. Оставляю English (US). При необходимости переключение на русскую раскладку можно настроить позже внутри системы.

4. Тип установки выбираю как Ubuntu Server. Минималистичный вариант исполнения серверной ОС я ставить не стал. Вес, конечно, меньше, но нужно много всего накидывать дополнительно и из-за этой возни не хочется экономить пару гигабайт.

5. Настройка сети:
Видим список сетевых интерфейсов. Их будет несколько:
enp0s3(мост) иenp0s8(NAT). Мне нужен интерфейс, подключенный к мосту.Выделяю
enp0s3и нажимаю Enter.Переключаю метод настройки с Automatic (DHCP) на Manual.
Ввожу параметры моей локальной сети. Чтобы узнать их, на основном компьютере открываю терминал и выполняю команду
ipconfig, далее ищу IPv4-адрес, маску и шлюз для подключения.-
Задаю для виртуальной машины статический адрес из той же подсети, но не занятый другими устройствами. Например:
Subnet: 192.168.0.0/24
Address: 192.168.0.203
Gateway: 192.168.0.1
Name servers: 8.8.8.8, 1.1.1.1 (или адрес вашего роутера, если он выполняет роль DNS)
Подтверждаю введенные данные и выбираю Done.

На скрине у меня немножко другие цифры в полях Subnet и Address. Знаете почему? Всё просто! Я неверно внес данные в рамках первой настройки виртуальной машины и долго не мог понять, почему у меня ее не видно с хоста. Пинга нет... Оказалось нет у меня внимания, а пинг есть, правда в другой подсети... Решил специально оставить и не переделывать скриншот, не ошибается тот, кто ничего не делает!
6. Поле для настройки прокси оставляю пустым (не использую прокси).

7. Настройка зеркала архива. Оставляю предложенное по умолчанию. Нажимаю Done.

8. Разметка диска.
Выбираю Use an entire disk.
Подтверждаю разметку, выбрав Done и затем Continue в предупреждении.


9. Профиль пользователя и имя сервера. Заполняю стандартными данными.
Your name: Admin.
Your server name: gitlab-vm. При настройке использую осмысленные имена, например: gitlab-vm, nexus-vm, vault-vm, dojo-vm, tools-vm.
Pick a username: не скажу :) Это будет непривилегированный пользователь с возможностью sudo.
Choose a password: надежный пароль.
Confirm your password: еще раз тот же надежный пароль.

10. Обновление Ubuntu. Я скачивал свежий дистрибутив и пропускаю, выбрав Skip for now и нажимаю Continue.

11. Установка SSH:
Отмечаю Install OpenSSH server;
В настройках импорта ключей оставляю Done.

12. Выбор дополнительных пакетов:
Все необходимые сервисы я буду ставить вручную. Нажимаю Done.

13. В целом всё! Жду, пока копируются файлы и выполнится настройка.

14. Завершение установки.
Когда появится сообщение об успешной установке, нажимаю Reboot Now.
При перезагрузке VirtualBox может попросить извлечь установочный диск. Если этого не произошло, после выключения ВМ нужно перейти в настройки «Носители» и отключить ISO-образ ну или просто нажать Enter, когда появится сообщение Press enter to continue после удаления диска.

Делай четыре! Первый вход и проверка
После перезагрузки вижу экран входа в систему.
Погнали! Вхожу под созданными пользователем и паролем. Проверяю IP-адрес с помощью выполнения команды ip a. Вижу, что интерфейс enp0s3 имеет заданный статический IP.
Провожу проверки:
Доступ в интернет. Выполняю команду
ping 8.8.8.8иping google.com. Если всё хорошо, двигаюсь дальше.-
Обновляю список пакетов:
sudo apt updateЕсли всё хорошо, ошибок не будет.
-
Настраиваю часовой пояс:
sudo timedatectl set-timezone Europe/Moscow -
Провожу установку базовых для меня утилит:
sudo apt install -y curl wget git htop net-tools mc jqКратко о назначении устанавливаемых утилит
jq — это утилита для обработки данных в формате JSON в командной строке. Она позволяет извлекать, фильтровать, преобразовывать и форматировать JSON-данные;
-
curl — утилита для передачи данных по различным сетевым протоколам (HTTP, HTTPS, FTP, SCP, SFTP и др.) с использованием синтаксиса URL. Часто используется для:
скачивания файлов из интернета;
тестирования API;
автоматизации взаимодействия с веб‑сервисами.
-
wget — консольная утилита для загрузки файлов из интернета. Отличается от curl тем, что ориентирована именно на скачивание (в т. ч. рекурсивное) и обладает такими функциями, как:
возобновление прерванной загрузки;
фоновая загрузка;
скачивание целых сайтов для офлайн‑просмотра.
-
git — распределенная система контроля версий. Позволяет:
отслеживать изменения в файлах;
работать над проектами в команде;
хранить историю изменений кода;
клонировать репозитории с GitHub, GitLab и других платформ.
-
htop — интерактивный системный монитор и диспетчер процессов. Улучшенная версия классической утилиты top. Показывает в реальном времени:
загрузку CPU и памяти;
список запущенных процессов;
возможность сортировать, фильтровать и завершать процессы прямо в интерфейсе.
-
net-tools — набор классических сетевых утилит, включающий:
ifconfig — для настройки сетевых интерфейсов (просмотр IP‑адресов, масок подсети, включение/выключение интерфейсов);
netstat — для отображения сетевой статистики и открытых соединений;
arp — для работы с ARP‑таблицей;
route — для управления таблицей маршрутизации.
-
mc (Midnight Commander) — текстовый файловый менеджер с двухпанельным интерфейсом (похож на Norton Commander или Far Manager). Позволяет:
удобно копировать, перемещать и удалять файлы;
просматривать архивы;
редактировать файлы встроенным редактором (mcedit);
выполнять команды в нижней командной строке.
-
Включаю брандмауэр (для безопасности):
sudo ufw allow OpenSSH # + те порты, которые мне будут нужны для доступов к сервисам виртуальной машины. Набор открываемых портов зависит от назначения виртуальной машины и устанавливаемых на ней сервисов sudo ufw enable sudo ufw status -
Установка Docker:
curl -fsSL https://get.docker.com -o get-docker.sh sudo sh get-docker.sh sudo usermod -aG docker $USER # Для применения групп нужно перезагрузить виртуальную машину # Ну и еще я отдельно поставил docker-compose sudo apt install docker-compose
Финальный этап
«Первая ласточка — еще не весна», — сказал я и принялся разворачивать остальные четыре виртуалки. Пути у меня было два: либо тупо копировать и править имена и IP, либо повторять всё ручками. И знаешь что? Выбрали мы с разработчиками боярами второй. Потому что повторение —– мать учения. Да и не ошибается тот, кто ничего не делает, а я себе право на ошибку оставил.
Так что следующие четыре раза я прошел этот путь заново.

Заключение
В результате у нас получилась базовая инфраструктурная заготовка в виде пяти виртуальных машин, подготовленных к установке сервисов безопасной разработки ПО. Дальше — больше!
На первый взгляд проделанная работа может показаться довольно простой. Но, как показывает практика, именно на этапе подготовки инфраструктуры закладывается фундамент всей дальнейшей системы. Ошибки в сетевой схеме, адресации или настройке серверов обычно всплывают позже — в самый неподходящий момент.
Для меня эта работа стала хорошим поводом освежить в памяти базовые вещи: планирование ресурсов, развертывание виртуальных машин, настройку серверов и подготовку среды для дальнейшей автоматизации.
Спасибо, что дочитал эту статью до конца. Увидимся в следующей части.
А в следующей статье…
…мы начнем самое интересное — установку самих сервисов. GitLab, Nexus, Vault, DefectDojo, Dependency-Track и все CLI-инструменты (Checkov, Trivy, Gitleaks, Opengrep, Nuclei). Будем ставить через docker-compose, монтировать хранилища, инициализировать и проверять, что данные не пропадают.

PURP — Telegram-канал, где кибербезопасность раскрывается с обеих сторон баррикад
t.me/purp_sec — инсайды и инсайты из мира этичного хакинга и бизнес-ориентированной защиты от специалистов Бастиона