Всем привет! Мы — команда разработчиков NiceOS (на данный момент развиваем проект Z (сервер), следующий этап проект X - рабочая станция с графической оболочкой). В нашей статье расскажем, как именно мы сделали (и продолжаем развивать) собственную серверную дистрибуцию Linux, заточенную под российские реалии: требования к сертификации, поддержку ГОСТ-криптографии, локализацию и работу с отечественным оборудованием.
Сегодня NiceOS Z — это легковесная серверная ОС без графического окружения, которая умеет:
Поднимать типовые сервисы (веб, базы данных, мониторинг и т. д.) «из коробки».
Поддерживать национальные стандарты шифрования и ключевые средства защиты (ГОСТ, сертификация).
Удобно устанавливаться и обновляться из собственных репозиториев, лежащих в локальной сети.
Расскажем, как мы пришли к этому и что делали на каждом этапе.
1. С чего всё началось: цели и первые наброски
1.1. Зачем делать свою ОС?
Мы работали над несколькими крупными проектами для госкомпаний, где одним из требований было использование отечественного ПО (или ПО, которое можно сертифицировать по ГОСТ). В процессе столкнулись с тем, что:
Готовые дистрибутивы (Debian, CentOS, Fedora и т. д.) хоть и хороши, но содержат массу лишних вещей для типовой серверной установки.
Сертификация под локальные требования требует глубокого контроля над системой, вплоть до опций ядра и точной версии криптобиблиотек.
Поддержка вендоров: нужна была платформа, которую мы можем развивать сами, не дожидаясь апстрима.
1.2. Первый прототип
Собрали «минимальный дистрибутив» на базе CentOS, выпилив из него графические оболочки и неиспользуемые пакеты. На тот момент мы просто создавали kickstart-файл для автоматической установки (Anaconda), чтобы всё лишнее не попадало в систему. Но довольно быстро поняли, что хотим большего контроля — вплоть до упаковки ядра, библиотек, системных демонов.
2. Архитектура: ядро, пакеты, патчи
2.1. Ядро Linux (LTS) и наши доработки
Базовая идея: берем «vanilla» LTS-ветку ядра (к примеру, 6.1 LTS или 5.15 LTS — зависит от того, что было актуально на момент релиза). Затем:
-
Добавляем патчи для ГОСТ-шифрования. Это включает в себя поддержку алгоритма ГОСТ 28147-89, хеширования ГОСТ Р 34.11-2012 и пр. Часть патчей на ядро можно найти в публичных репозиториях:
Иногда приходится вручную адаптировать под нужную версию ядра.
Драйверы для специфичного «железа». Например, у нас были проекты, где требовались какие-то старые RAID-контроллеры и отечественные решения, которые не всегда дружат со стандартным ядром. Пришлось включить модули, найденные на GitHub, либо получить драйвер у производителя (часто в виде .ko для конкретной версии ядра).
Безопасность. Мы хотели активировать SELinux (или хотя бы AppArmor), чтобы иметь обязательный контроль доступа. В итоге выбрали SELinux, поскольку он лучше интегрирован с systemd и Red Hat-подобным окружением.
Сборка ядра
Мы используем классическую связку: make olddefconfig
(для переноса настроек из vanilla-конфига), затем вносим изменения: активируем нужные опции (например, CONFIG_CRYPTO_GOST
, CONFIG_SECURITY_SELINUX=y
и т. д.). У нас есть скрипт build_kernel.sh
, который:
Скачивает исходники ядра и наши патчи.
Применяет патчи.
Запускает
make menuconfig
(либоolddefconfig
) с сохранённым.config
.Компилирует ядро и модули.
Собирает RPM-пакет (
rpmbuild
) для дальнейшей установки через DNF.
2.2. Выбор пакетного менеджера
Мы остановились на DNF (Fork yum4) с форматом RPM, поскольку наша команда исторически теснее связана с Red Hat-средой, чем с Debian. Но у нас были тесты и с APT/deb. В общем виде алгоритм:
Спецификационные файлы (SPEC): пишем их для каждого пакета, указываем зависимости, инструкции по сборке и установке.
Собственный репозиторий: поднимаем локальный HTTP-сервер (Nginx), генерируем метаданные командой
createrepo_c /path/to/repo
.Конфигурация DNF: в
/etc/dnf/dnf.conf
прописываем адреса наших реп.
Для простых пакетов (типа zabbix-agent
или nginx
) мы берем исходники, патчим при необходимости (добавляя, например, поддержку GOST в OpenSSL), и дальше создаём RPM.
Пример фрагмента .spec
для сборки Nginx с GOST-патчами (упрощённо):
Name: nginx
Version: 1.22.1
Release: 1%{?dist}
Summary: High-performance HTTP server and reverse proxy
License: BSD
Source0: https://nginx.org/download/nginx-%{version}.tar.gz
Patch0: nginx-gost.patch
BuildRequires: openssl-gost-devel
...
%description
Nginx with GOST crypto support for Russian standards...
%prep
%setup -q -n nginx-%{version}
%patch0 -p1
%build
./configure --with-openssl=/usr/src/openssl-gost ...
make
%install
make install DESTDIR=%{buildroot}
%files
/usr/local/nginx
...
%changelog
* Wed Dec 20 2024 NiceOS Team - 1.22.1-1
- Initial build with GOST support
Конечно, реальные .spec
-файлы бывают намного больше, со скриптлетами и дополнительными опциями.
2.3. «Минимальная» базовая система
Чтобы серверная ОС не тащила гигабайты ненужных пакетов, мы сформировали «минимальный» мета-пакет(niceos-minimal
), который тянет за собой только:
bash
,coreutils
,systemd
,dnf
,iproute2
,openssh-server
,tar
,xz
,vim-minimal
и т. д.Основные криптобиблиотеки (с учётом GOST).
SELinux (для безопасности).
Всё остальное ставится опционально: есть мета-пакеты niceos-webserver
, niceos-postgres
, niceos-monitoring
и т. д. Они подтягивают зависимости для соответствующей роли.
Таким образом, при установке с ISO или netinstall пользователь может выбрать: «Мне нужен веб-сервер» — ставится niceos-minimal
+ Nginx, PHP-FPM, firewall и т.д. Если нужно только базовый SSH-доступ, достаточно niceos-minimal
.
3. Инсталлятор и автоконфигурация
3.1. Форк Photon Installer
На ранних этапах мы перепрофилировали Photon Installer под свои нужды. Это простой установщик. Ничего лишнего для сервера.
Kickstart-файлы: в них мы прописали всё, что нужно: список пакетов, создание разделов, настройку сети.
Шаг «Post-install»: ставим GOST-сертификаты, настраиваем локали и SELinux-политику.
3.2. Netinstall-образ
Для удобства мы также собрали netinstall-ISO, который весит ~300 МБ. Он содержит только базовый инсталлятор и несколько скриптов. При инсталляции он спрашивает адрес репозитория (наш локальный сервер), качает пакеты и устанавливает систему. Так мы экономим место и можем оперативно обновлять репозиторий.
4. ГОСТ-шифрование и сертификация
4.1. Интеграция GOST в OpenSSL
Чтобы OpenSSL «понимал» российские шифры, мы используем патчи из gost-engine. В .spec
-файле для OpenSSL добавляем:
Patch999: openssl-gost-engine.patch
...
После сборки в систему ставится libcrypto.so
с поддержкой ГОСТ.
Проверка:
openssl ciphers | grep -i gost
Если видим список ГОСТ-алгоритмов — значит всё ок.
4.2. Сертификация ФСТЭК/ФСБ
Если ОС будет использоваться в госорганизациях или объектах КИИ, часто необходимо соответствовать регламентам:
ФСТЭК: сертификация на отсутствие НДВ (недекларированных возможностей). Нужно предоставить экспертам исходники, описание сборочного процесса, результаты тестов.
ФСБ: если система обрабатывает гостайну или содержит шифрование, которое подлежит контролю. Требуются соответствующие лицензии и экспертизы.
Мы готовим часть документации в виде пакетов:
niceos-security
(где описываются все SELinux-политики, журналирование, настройка ядра).niceos-crypto
(подробное описание криптомодулей, сертификаты).
Это большая бюрократическая работа: тесты, аудиты, проверки. На этапе разработки полезно сразу держать в уме: «какие логи мы пишем, как формируем политику SELinux, куда складываются ключи шифрования». Чем лучше структура, тем проще потом сертифицировать.
5. Инфраструктура сборки и тестирования
5.1. GitLab CI/CD
У нас есть внутренний GitLab-сервер, где:
Храним весь код: ядро (с патчами),
.spec
-файлы, скрипты, вспомогательные утилиты.-
Pipeline с несколькими стадиями:
build_kernel
: качаем ванильные сорцы, патчим, собираем RPM.build_base
: собираем базовые пакеты (glibc, bash, systemd и т. д.).build_services
: например, nginx, openssl, все нужные демоны.assemble_iso
: генерим ISO-образ (или netinstall-образ) с помощьюlorax
илиlivecd-tools
.test_virtual
: разворачиваем свежесобранную ISO в QEMU/KVM, проверяем, что система устанавливается, SSH работает, SELinux не блочит важные процессы.
5.2. Автоматические тесты
Мы написали базовый «smoke-test» на Python, который выполняет:
Установка: запускает QEMU с ISO, проходит по сценарию автоматической установки (kickstart).
-
Проверка:
Система загрузилась, SELinux включён, служба sshd активна.
Локали
ru_RU.UTF-8
иen_US.UTF-8
доступны.openssl ciphers | grep gost
выдаёт нужные алгоритмы.
Только если все проверки «зелёные», собираемый образ публикуется в наш репозиторий.
6. Пилотные проекты и реальная эксплуатация
6.1. Кейс: веб-сервер для госструктуры
Первый реальный кейс: мы развернули NiceOS в роли веб-сервера для госучреждения:
Установили через netinstall образ.
Подняли Nginx с поддержкой ГОСТ для HTTPS, PostgreSQL для хранения данных.
Использовали SELinux со строгой политикой, разрешающей лишь нужные порты и процессы.
Провели аудит совместно со службой безопасности заказчика, оформили все документы.
Итог: веб-сервер прошёл проверку, система стабильно отработала нагрузочное тестирование.
6.2. Внутренние сервисы мониторинга
Параллельно мы внедрили NiceOS для внутренних CI/CD-пайплайнов и мониторинга (Zabbix, Prometheus). Это помогло быстрее ловить баги и «вживую» проверять совместимость с популярными инструментами (Docker, Kubernetes).
7. Документация и поддержка пользователей
7.1. Документация
Мы сразу стараемся вести документацию так, чтобы её мог читать не только «внутренний» разработчик, но и внешний системный администратор:
Wiki на базе GitLab Pages.
Описание всего процесса: установка, настройка SELinux, работа с локалями, включение ГОСТ-шифрования.
Раздел «частые проблемы»: если какая-то утилита требует дополнительной настройки под российские стандарты, мы подробно расписываем.
7.2. Каналы поддержки
Telegram-чат: чтобы оперативно отвечать на вопросы коллег, тестировщиков и потенциальных пользователей.
GitLab Issues: баги, запросы на фичи.
Для серьёзных клиентов (госучреждения, бизнес) мы организовали систему заявок и SLA, но это уже больше про бизнес-процессы.
8. Итоги и планы на будущее
За время разработки NiceOS мы убедились, что создать (и тем более поддерживать) собственную серверную Linux-систему — непростая задача. Важно сразу закладывать:
Автоматизацию (CI/CD, тесты, репозитории) — иначе вы быстро погрязнете в ручной сборке.
Строгий отбор пакетов — серверная ОС не должна быть перегружена.
Учёт локальных требований (ГОСТ, локали, сертификаты) с самого начала.
Будущие шаги:
Добавить «автомагию» для конфигурации типовых ролей (веб, база данных, виртуализация).
Расширить систему мониторинга инсталляций (чтобы централизованно видеть версию, установленные пакеты, статус SELinux).
Официально завершить процесс сертификации для некоторых отраслей и госструктур (ФСТЭК/ФСБ).
Мы не исключаем, что позже сделаем и десктоп-вариант, но пока в приоритете — серверный сегмент, где действительно есть спрос на локальные решения.
Кейс: пошаговая сборка NiceOS — от чистого ядра до собственного дистрибутива
Шаг 1. Определяем цели и собираем «скелет» системы
-
Определяем требования:
Серверная ОС без графического окружения,
Минимальный набор программ и библиотек (основные утилиты, сетевые инструменты, SSH),
Поддержка российских стандартов криптографии (ГОСТ),
Возможность «чистой» (или полуавтоматической) установки,
RPM-пакеты + DNF в качестве пакетного менеджера.
-
Выбор ядра:
Начинаем с LTS-ядра (например, 6.1 LTS) в виде ванильных исходников: качаем tarball с kernel.org.
Сразу заготавливаем набор патчей, включая поддержку ГОСТ-криптографии, нужные драйверы (если есть экзотическое железо) и опции безопасности (SELinux).
-
Создаём базовый rootfs вручную:
Делаем «песочницу» (обычно через
chroot
на виртуальной машине или в каталоге), куда складываем всё, что нужно:bash
,coreutils
,iproute2
,systemd
,openssh
.Первую версию rootfs можно просто «насобрать» бинарниками из какого-нибудь «донорского» репозитория (например, CentOS/ALT/SUSE) или скомпилировать самим. Мы выбрали промежуточный путь: часть пакетов взяли из репозитория CentOS, часть (например, OpenSSL с ГОСТ-патчами) собрали вручную.
Что важно: на этом этапе у нас нет полноценного установщика и нормальных пакетов. Это просто «минимальная папка с системой», которую можно упаковать в initrd и загрузить через QEMU.
Шаг 2. Настраиваем сборку ядра и основу безопасности
-
Сборка ядра:
Распаковываем
linux-6.x.y.tar.xz
, накладываем наши патчи (командойpatch -p1 < gost.patch
, etc.).-
Запускаем
make menuconfig
или копируем дефолтный.config
(например, из дистрибутива Red Hat), включаем:CONFIG_CRYPTO_GOST
(или похожее название),CONFIG_SECURITY_SELINUX=y
,CONFIG_DEFAULT_SELinux
,драйверы для нужного оборудования.
make -j8 bzImage modules && make modules_install
. Получаем готовое ядро и модули.
-
SELinux-политики:
Сразу решаем, что SELinux будет работать в Enforcing-режиме. Значит, нужно включать соответствующие пакеты и базовые политики (например, пакет
selinux-policy-base
).В будущем придётся допиливать свои модули для сервисов, но пока берём стандартные.
-
OpenSSL с ГОСТ:
Берём официальный openssl (версия 1.1.1 или 3.x — зависит от времени),
Подмешиваем gost-engine. Для этого обычно есть патчи типа
openssl-gost.patch
.Собираем, проверяем
openssl ciphers | grep GOST
, убеждаемся, что алгоритмы видны.
Результат: есть минимальный набор компонентов (ядро, libc, bash, systemd, SELinux, openssl-gost), и это всё упаковано в наш chroot/rootfs.
Шаг 3. «Упорядочиваем» сборку: RPM + DNF
Теперь мы хотим не просто иметь собранные бинарники, а превратить их в регулярные RPM-пакеты, чтобы любой пользователь мог установить или обновить систему через DNF.
-
Организуем структуру проектов:
-
Репозиторий Git (например, GitLab) с папками:
kernel/
(исходники ядра, патчи и.spec
для сборки),base/
(glibc, bash, coreutils, systemd и т. д.),crypto/
(openssl-gost, libgcrypt, если нужно),selinux/
(правила, политики).
-
-
Создаём
.spec
-файлы для каждого пакета:Например,
kernel.spec
, в котором прописываем, откуда берём исходники, какие патчи накладываем, как компилируем и куда ставим.В разделе
%post
указываем, что нужно обновитьgrub.cfg
илиinitramfs
.
-
Сборка RPM:
Либо вручную через
rpmbuild -ba kernel.spec
, либо автоматизируем в CI (GitLab CI).После успешной сборки получаем
.rpm
для установки (например,kernel-niceos-6.1.XX.rpm
).
-
Поднимаем свой репозиторий:
Папка
/var/www/html/niceos/
на локальном веб-сервере,Команда
createrepo_c /var/www/html/niceos/
.Теперь любой сервер, где прописан
baseurl=http://repo.niceos.local/niceos/
, может устанавливать эти пакеты черезdnf install kernel-niceos
.
-
DNF и минимальный мета-пакет:
Собираем пакет
niceos-minimal
, который вRequires:
перечисляет всё, что нужно для базовой системы:kernel-niceos
,systemd
,selinux-policy-base
,bash
,iproute2
,openssh-server
и т.д.Таким образом, «одноимённый» мета-пакет тянет за собой все базовые зависимости.
Шаг 4. Генерация установочного ISO
Чтобы обычные люди не собирали систему вручную, нужен установочный образ (ISO):
Инструменты: можно взять
lorax
(используется в Fedora/Red Hat) илиlivecd-tools
.-
Скрипты:
Собираем минимальное rootfs из наших RPM (через
dnf --installroot=/папка ...
).Генерируем initrd и vmlinuz (берём из нашего
kernel-niceos
).Пакуем всё это в ISO, добавляем систему загрузки (GRUB или ISOLinux).
-
Kickstart (опционально):
-
Создаём
ks.cfg
, где перечислены:%packages
(содержимое, включаяniceos-minimal
),%post
(дополнительные скрипты — например, включение SELinux в Enforcing-режиме, создание пользователяadmin
, настройка локалей).
Позже при установке Anaconda или другой инсталлятор прочитает эти инструкции, и всё пойдёт автоматически.
-
Итог: появилась «официальная» сборка NiceOS в виде ISO-образа. Его можно записать на флешку и установить на сервер так же, как любую другую Linux-систему.
Шаг 5. Тестирование в QEMU и на реальном железе
-
Автоматизированные тесты (CI):
-
В GitLab (или Jenkins) организуем пайплайн:
После сборки всех пакетов и генерации ISO, запускаем QEMU, загружаем ISO, автоматически отвечаем на вопросы инсталлятора (kickstart).
Дожидаемся завершения установки, проверяем, что система загрузилась, SELinux включён, SSH работает, русская локаль
ru_RU.UTF-8
есть.
Проводим smoke-тест:
openssl ciphers | grep GOST
, проверяемdnf install zabbix-agent
, и т.д.
-
-
Тест на реальном сервере:
Берём какой-нибудь «железный» стенд (или даже обычный ПК).
Ставим NiceOS с флешки. Смотрим, все ли драйверы (RAID-контроллер, сетевые адаптеры) работают.
Иногда приходится дописывать
initramfs
-скрипты (например, если при загрузке не видит тома LVM).
Шаг 6. Доводка SELinux, cryptconfig и прочие тонкости
На этапе реального использования обычно выясняются мелочи:
SELinux: иногда сервисы блокируются «неправильной» политикой. Приходится собирать собственные
.te
-модули. К примеру, если хотим, чтобы Nginx лез в нестандартную папку/srv/data
, нужно прописать контексты (semanage fcontext
) и разрешения.Расширение ГОСТ: кроме OpenSSL, может потребоваться GnuTLS, libcrypto++, если софт заказчика использует их. Значит, надо аналогично патчить и собирать пакеты с ГОСТ-поддержкой.
Утилиты для диагностики (dmesg, journald, systemd-analyze). Важно, чтобы всё было на месте и локализовано.
Шаг 7. Документация и постоянные обновления
-
Документация:
Пишем Wiki (или ReadTheDocs) со скринами, как установить NiceOS с ISO, как настроить SSH, SELinux, ГОСТ, сети и так далее.
Добавляем раздел «частые проблемы»: почему SELinux не даёт поднять сервис, как привязать гост-сертификаты, где лежат логи.
-
Регулярные обновления:
Периодически выходим на новые версии ядра (LTS), делаем rebase.
Собираем пакеты безопасности (например, если в OpenSSL найдена уязвимость).
Публикуем их в репозиторий, и система (через
dnf update
) может обновляться на лету.
Результат
В итоге мы имеем полностью контролируемый дистрибутив под названием NiceOS Z:
Своё пропатченное ядро,
Системные пакеты в формате RPM,
Репозиторий на своём сервере,
Установочный ISO с инсталятором и kickstart,
CI-пайплайн, который автоматически собирает и тестирует все изменения,
SELinux, ГОСТ-криптография и русская локаль «из коробки».
Такой дистрибутив удобно поддерживать для внутренних нужд (или для заказчиков), потому что мы отвечаем за каждый пакет и точно знаем, что где лежит. Да, это намного сложнее, чем «просто взять CentOS», зато даёт полную независимость и контроль.
В чём «прикол» и что мы поняли
Автоматизация — ключ к успеху. Без CI и репозиториев всё свалится в хаос.
SELinux изначально лучше включать, чем потом активировать и ловить сотни ошибок.
ГОСТ-патчи не всегда гладко мержатся — иногда приходится ручками адаптировать под конкретную версию OpenSSL или ядра.
Документация: мы потратили уйму времени, чтобы расписать каждый шаг. Но без этого любой новый участник команды или администратор начинает тонуть в вопросах.
Постоянная поддержка: каждая новая уязвимость, каждая новая версия — это работа по сборке обновлённых пакетов, проверке, что ничего не сломалось.
Надеемся, что наш пошаговый кейс будет полезен тем, кто собирается пилить собственный дистрибутив Linux (или серьёзно модифицировать существующий). Если остались вопросы — задавайте, будем рады поделиться опытом ещё глубже!
Заключение
Надеемся, наш опыт был полезен: мы постарались не просто перечислить шаги, но и показать как именно мы их делали — от ядра и пакетного менеджера до CI/CD и тестов. Создавать свою серверную ОС имеет смысл, если:
Нужно глубокое соответствие местным стандартам и возможность сертификации.
Важно обладать полным контролем над жизненным циклом (когда, как и что обновлять).
У вас есть команда, готовая заниматься сборкой, обновлениями, техподдержкой.
Вместе с тем, мы не устаём повторять: если ваш проект не требует столь специфических условий, возможно, проще использовать уже готовый дистрибутив. Но когда необходима российская специфика и сертификация — собственная ОС (пусть и основанная на Linux) становится отличным решением.
Спасибо, что дочитали до конца!
Если у вас есть похожий опыт или вопросы — будем рады обсудить в комментариях.
Комментарии (14)
Kitsok
21.01.2025 15:46Я в смятении.
С одной стороны, никакой серверной ОС вы не создавали.
С другой стороны, вы собрали под свои задачи удобный дистрибутив, да ещё и автоматизацией это все накрыли, да ещё и статью подробную об этом написали. Ну молодцы же?
Плюс поставлю.
longtolik
Хотел спросить, какой загрузчик используется, U-boot или собственный, но похоже, система с BIOS начинается. В требованиях к оборудованию написано 2 Гигабайта ОЗУ и 20 Гигабайт дисковой памяти, при этом процессор "желательно поновее", а вот какой он архитектуры, но сразу не понятно.
DTGP Автор
В ISO-образе используется Syslinux в качестве загрузчика, а для самой системы — GRUB. Система действительно рассчитана на работу через BIOS, а не U-Boot. Архитектура процессора — x86-64, что подтверждается требованиями к оборудованию (2 ГБ ОЗУ и 20 ГБ дискового пространства). Для работы желательно использовать более современный процессор с поддержкой этой архитектуры.
longtolik
Вопрос вырос из того, что сертифицирвать U-boot не представляется возможным, поэтому делают свои загрузчики.
С сертификацией BIOS могут быть сложности. А с него начинается работа компьютера, и объёмы кода там большие. (Некоторые могут и в сеть выходить).