Тема 07

Автономная ОС и доверенная цепочка обновлений

Автономная ОС и доверенная цепочка обновлений

В предыдущих темах были заложены основы автономной информационной инфраструктуры: тема 1 определила матрицу сценариев и шкалу уровней деградации, тема 2 формализовала состав офлайн-профиля узла и правила ротации носителей, а тема 6 показала, как отобрать, восстановить и подготовить аппаратную платформу из доступного парка вычислительной техники. Однако отремонтированное железо бесполезно без операционной системы, а система, спроектированная в предположении постоянного подключения к сети, на автономном узле быстро упирается в отсутствие сети: фоновые службы зависают в ожидании сетевых ответов, попытка установить недостающую системную утилиту прерывается ошибками недоступности зеркал, а повреждение одной записи в загрузчике оставляет инженера перед мёртвым экраном.

Отдельная ошибка — представление, будто автономность исчерпывается «однократной установкой системы с флешки». Информационная система не статична: в ней неизбежно выявляются уязвимости, меняются конфигурационные параметры прикладных сервисов, требуются дополнительные библиотеки и инструменты диагностики. В отсутствие интернета единственным каналом доставки изменений становятся съёмные физические носители. Но бесконтрольное подключение внешних флеш-накопителей к критически важному узлу — известный путь компрометации изолированных систем (так распространялся Stuxnet), заносящий вредоносный код или деструктивные обновления прямо в защищённый периметр.

Тема решает две задачи. Первая — как развернуть, настроить и поддерживать операционную систему, способную годами работать без единого обращения к внешним серверам, сохраняя возможность восстановления даже при отказе загрузочных структур диска. Вторая — как организовать доверенную, криптографически верифицируемую цепочку доставки обновлений через физический барьер (англ. air gap), исключающую установку непроверенного или повреждённого кода и сохраняющую возможность отката к заведомо исправному снимку.

Изложение построено от базового системного уровня к процедурам сопровождения. Первый раздел обосновывает выбор технологического стека, сравнивая дистрибутивы по критериям автономности и ремонтопригодности. Второй раздел рассматривает автономную установку Debian 13 и локальный репозиторий, подписанный собственным ключом. Третий раздел разбирает цепочку загрузки UEFI → shim → GRUB → initramfs → корень и регламент аварийного восстановления через chroot, включая различия initramfs-tools и dracut. Четвёртый раздел выстраивает архитектуру доверенной цепочки обновлений от внешней машины до рабочего контура через карантинную зону. Пятый раздел рассматривает долговременное сопровождение офлайн-системы: локальную изоляцию языковых пакетов, управление системными журналами и механизм мгновенного отката на основе снимков файловой системы.

Выбор операционного стека для автономного узла

Критерии автономности операционной системы

Большинство современных потребительских и корпоративных операционных систем разрабатываются в парадигме «подключённого мира». В них глубоко интегрированы механизмы принудительной онлайн-активации, регулярная фоновая телеметрия, облачная синхронизация профилей пользователей, обращение к внешним серверам каталогов и централизованное автоматическое обновление. В сценарии изоляции такие механизмы превращаются из удобств в критические уязвимости. Операционная система начинает бесконечно ожидать ответов от недоступных IP-адресов при каждой загрузке, службы блокируют запуск до истечения системных тайм-аутов DNS, а отсутствие валидации лицензии может привести к блокировке системных интерфейсов.

Для операционной системы автономного узла обязательны четыре фундаментальных критерия 12:

  1. Полная независимость от удалённых лицензионных серверов. Операционная система и всё сопутствующее прикладное окружение должны распространяться под свободными лицензиями (GPL, BSD, MIT, Apache). Понятие «активации через интернет», отзыв лицензионного сертификата или блокировка по географическому признаку недопустимы.
  2. Воспроизводимость и модульность установки. Должна существовать возможность развернуть базовую систему из локального архива или с локального носителя без запуска графических установщиков, исключительно средствами текстовых утилит командной строки (debootstrap, cpio, tar).
  3. Предсказуемость компонентной базы и отсутствие принудительных обновлений. Системные компоненты не должны самопроизвольно менять поведение, форматы конфигурационных файлов или синтаксис системных вызовов. Выпуск обновлений должен быть строго регламентированным процессом, инициируемым только оператором.
  4. Прозрачность и ремонтопригодность структуры. Все конфигурации системы должны храниться в виде плоских текстовых файлов в стандартной иерархии (FHS, англ. Filesystem Hierarchy Standard), доступных для чтения, анализа и модификации из минималистичного аварийного окружения без проприетарных редакторов баз данных.

Этим критериям в полной мере соответствуют операционные системы на базе ядра Linux. Однако семейство Linux-дистрибутивов крайне неоднородно, и выбор конкретного дистрибутива требует строгого сопоставления их архитектурных свойств.

Сравнительный анализ дистрибутивов

В учебном курсе в качестве основного эталонного стека принят дистрибутив Debian GNU/Linux (редакция Stable). Рассмотрим, почему именно он выбран в качестве стандарта автономного узла и в чём состоят компромиссы альтернативных решений 3.

ДистрибутивМодель релизовПакетный менеджерИнициализацияОбъём базового корняДоступность документации и зеркалОценка применимости в автономии
Debian GNU/Linux (Stable)Фиксированная (цикл 2 года, поддержка LTS)dpkg / aptsystemd (sysvinit опционально)~178 МБ (minbase)Превосходная; полные срезы архивов на snapshot.debian.orgОсновной выбор: максимальная стабильность ABI, богатейший репозиторий, автономное индексирование
Ubuntu LTSФиксированная (2 года)dpkg / apt / snapsystemd~220 МБ (minimal)Высокая; однако snap-пакеты требуют онлайн-демона snapdДопустим для рабочих станций; на серверах требует принудительного отключения snap
Alpine LinuxФиксированная (6 месяцев)apkOpenRC / busybox~8 МБ (musl)Умеренная; ограниченная совместимость с glibc-бинарникамиОтличен для вспомогательных контейнеров и роутеров; сложен при ремонте редкого проприетарного софта
Arch LinuxСкользящая (англ. rolling release)pacmansystemd~450 МБПревосходная ArchWiki; но обновление «прыжком через полгода» часто требует ручного вмешательства (смена ключей, переименование пакетов)Непригоден для необслуживаемых автономных узлов: требует непрерывного участия человека при обновлении
Void LinuxНезависимая скользящаяxbpsrunit~60 МБОграниченное сообщество; небольшой размер официального пула пакетовНишевый вариант для энтузиастов; рискован при отсутствии штатного зеркала

Объёмы базового корня в таблице, кроме строки Debian (C-07-01: 178 МБ, измерение автора для Debian 12), — порядок величины по описаниям проектов, а не измерение: они меняются от выпуска к выпуску и зависят от варианта установки. Для решения о выборе важна не точная цифра, а различие в разы, и оно устойчиво.

Главное достоинство Debian Stable в автономных условиях — неизменность версий библиотек и ABI на протяжении всего жизненного цикла выпуска: около 3 лет поддержки командой безопасности и ещё 2 года проекта Debian LTS, всего 5 лет (C-07-08: 5 лет) по описанию на https://wiki.debian.org/LTS. Текущий стабильный выпуск — Debian 13 «trixie», вышедший 9 августа 2025 года (C-07-10: 2025-08-09); в нём APT 3 и проверка подписей через sqv. Если скрипт или сервис отлажен на Debian 13 «trixie», он будет работать идентично и через три года, даже если на узел не поступит ни одного обновления. Напротив, в дистрибутивах со скользящей моделью обновлений (Arch Linux) частичный перенос нескольких пакетов с более свежей машины неизбежно наталкивается на несовместимость версии glibc или зависимых библиотек libssl, требуя либо тотального синхронного обновления сотен пакетов, либо приводя к отказу системы.

Принцип минимализма и отказ от графической подсистемы

Чем меньше на узле запущенных процессов и исполняемого кода, тем меньше того, что может отказать и что нужно обслуживать. Графический сервер (Xorg или Wayland), среда рабочего стола (GNOME, KDE) и сопутствующие стеки (D-Bus, NetworkManager, PackageKit) включают в себя сотни мегабайт бинарного кода, десятки фоновых демонов и сложных межпроцессных взаимодействий. На автономном узле графическая оболочка — нагрузка без пользы для сервисов: она занимает сотни мегабайт оперативной памяти и не даёт процессору уходить в глубокие состояния простоя. Это оценка порядка величины, а не измерение; для своей машины разница измеряется так же, как в теме 3, — потребление узла с графикой и без неё за одинаковое время.

Серверный автономный узел настраивается исключительно в консольном режиме (англ. headless). Управление осуществляется через локальные виртуальные терминалы (TTY), последовательный консольный порт (UART/RS-232, рассмотренный в теме 6) или защищённое локальное SSH-соединение внутри периметра (тема 8). Отсутствие GUI сокращает площадь атаки, снижает вероятность сбоев графических драйверов и упрощает автоматизацию всех процедур восстановления.

Офлайн-установка и локальные зеркала пакетов

Развёртывание базовой ОС утилитой debootstrap

Стандартный графический установщик Debian (debian-installer) ориентирован на работу с официальными CD/DVD-образами или сетевыми зеркалами. Для автоматизированного создания целевой системы, подготовки аварийных дисков или развёртывания в пространствах имён используется утилита debootstrap 3.

debootstrap осуществляет прямое развёртывание базовой иерархии каталогов Debian в указанную точку монтирования, используя только локальный или сетевой пул .deb пакетов. Процедура состоит из двух стадий:

  1. Первая стадия: извлечение базовых архивов (coreutils, dpkg, bash, libc6) во временный каталог с помощью ar и tar.
  2. Вторая стадия: запуск сценариев настройки (postinst) внутри развёрнутого дерева каталогов с помощью chroot.

В полностью изолированном окружении debootstrap запускается с указанием локального каталога, содержащего срез репозитория или смонтированный образ установочного диска:

# Развёртывание минимальной системы Debian 13 «trixie» в каталог /target
sudo debootstrap --variant=minbase --arch=amd64 \
  trixie /target file:///srv/repo/debian

Рассмотрим числовые характеристики базовой системы. По измерению автора для Debian 12 «bookworm» (amd64, --variant=minbase) развёртывается 92 пакета, суммарный размер загружаемых .deb архивов — 36,4 МБ (C-07-06: 92 пакета, 36,4 МБ), распакованный корень занимает 178 МБ, или 186 646 528 байт по du -sb (C-07-01: 178 МБ). Добавление ядра (linux-image-amd64) и загрузчика (grub-efi-amd64) увеличило объём установленной системы ещё на 284 МБ (C-07-07: 284 МБ). Все три числа — измерение автора, не проверенное повторно; для Debian 13 состав minbase другой (APT 3, sqv), и в ЛР 7 эти величины измеряются заново и записываются в журнал. Порядок величины от этого не меняется: функциональная система без графики занимает меньше 0,5 ГБ, и на одном носителе помещается несколько её копий.

Создание локального подписанного APT-репозитория

Чтобы автономный узел мог устанавливать дополнительные инструменты (cryptsetup, btrfs-progs, nftables, dnsmasq) без подключения к интернету, на его локальном накопителе развёртывается файловый репозиторий APT 3. Структура официального репозитория Debian построена по жёстким правилам:

Иерархия локального офлайн-репозитория пакетов Debian (APT)
Каталог dists содержит индексы пакетов и подписанный файл InRelease; каталог pool хранит сами бинарные .deb файлы

Схема каталогов включает два ключевых дерева:

  • pool/ — хранилище самих файлов .deb. Файлы раскладываются по секциям (main, contrib, non-free, non-free-firmware) и первым буквам имён пакетов (например, pool/main/b/btrfs-progs/).
  • dists/ — метаданные дистрибутива. Внутри ветки dists/<codename>/<section>/binary-<arch>/ находятся списки пакетов Packages и Packages.gz. В корне ветки dists/<codename>/ располагается манифест Release с размерами и хешами SHA-256 всех индексных файлов и его подписанная форма InRelease.

Цепочка доверия APT устроена как цепочка хешей, замкнутая одной подписью 4. Каждый .deb проверяется по SHA-256 из Packages; Packages — по хешу из Release; Release — подписью. Подписан только верхний файл, но подмена любого нижнего ломает хеш на уровень выше. Отсюда следует главное: репозиторий без проверки подписи защищён только от случайной порчи, а от подмены не защищён вовсе — тот, кто может заменить .deb, может заменить и Packages, и Release.

Подпись локального репозитория: от пакета до ключа в Signed-By
Хеш пакета записан в Packages, хеш Packages — в Release, Release подписан ключом репозитория; узел проверяет подпись только ключом из файла, указанного в Signed-By

Сначала на машине подготовки создаётся отдельный ключ подписи репозитория. Он не должен совпадать с личным ключом инженера и хранится в отдельном каталоге GnuPG:

export GNUPGHOME=~/polygon/keys/repo.gnupg
mkdir -m 700 -p "$GNUPGHOME"
gpg --batch --passphrase '' --quick-gen-key \
  'Polygon local repo <repo@polygon.internal>' ed25519 sign 2y
gpg --export 'repo@polygon.internal' > ~/polygon/keys/repo.pgp   # открытый ключ, двоичный
gpg --with-colons --fingerprint 'repo@polygon.internal' | awk -F: '/^fpr/{print $10; exit}'

Пустой пароль допустим только для учебного ключа; рабочий ключ защищают паролем или держат на аппаратном токене (раздел «Что эта модель не учитывает»). Затем строятся индексы и подписывается Release:

cd /srv/repo/debian
mkdir -p dists/trixie/main/binary-amd64 pool/main
cp /media/usb/packages/*.deb pool/main/
apt-ftparchive packages pool/main > dists/trixie/main/binary-amd64/Packages
gzip -9 -k -f dists/trixie/main/binary-amd64/Packages
apt-ftparchive -o APT::FTPArchive::Release::Codename=trixie \
  -o APT::FTPArchive::Release::Suite=trixie release dists/trixie > dists/trixie/Release
gpg --batch --yes --clearsign -o dists/trixie/InRelease dists/trixie/Release
gpg --batch --yes -abs -o dists/trixie/Release.gpg dists/trixie/Release

На узле открытый ключ кладут в отдельный файл, а источник описывают в формате deb822 (/etc/apt/sources.list.d/polygon.sources), указывая этот файл в поле Signed-By:

Types: deb
URIs: file:/srv/repo/debian
Suites: trixie
Components: main
Signed-By: /etc/apt/keyrings/polygon-repo.pgp

Поле Signed-By ограничивает доверие: этот репозиторий принимается только с подписью этого ключа, а ключ не становится доверенным для остальных источников. Старый способ — положить ключ в общую связку /etc/apt/trusted.gpg.d/ — разрешал бы ему подписывать что угодно, в том числе подложное «зеркало Debian». Флаг [trusted=yes] (в deb822 — Trusted: yes) отключает проверку подписи целиком; в ЛР 7 показано, что с ним APT принимает репозиторий, подписанный чужим ключом, и даже неподписанный. Для автономного узла это ровно та дыра, которую должна закрывать цепочка обновлений, поэтому в курсе флаг не используется.

Проверку подписи можно выполнить и без APT, тем же способом, каким её выполняет узел. Программа gpgv проверяет подпись только по ключам из явно указанного файла и не обращается к личной связке и «уровням доверия» gpg:

gpgv --keyring ~/polygon/keys/repo.pgp dists/trixie/InRelease
gpgv: Signature made Thu 22 Oct 2026 10:14:03 MSK
gpgv:                using EDDSA key 3F0C…
gpgv: Good signature from "Polygon local repo <repo@polygon.internal>"

В Debian 13 APT по умолчанию проверяет подписи не через gpgv, а через sqv — проверяльщик на основе библиотеки Sequoia-PGP 13. Смысл проверки тот же (подпись и ключ из Signed-By), но политика строже: sqv отвергает подписи на устаревших алгоритмах (SHA-1, короткие ключи RSA), которые gpgv ещё принимал. Практический вывод для автономного узла — ключ репозитория создают на современном алгоритме (Ed25519 или RSA от 3072 бит), иначе после перехода узла на Debian 13 свой же репозиторий перестанет приниматься. Подпись Ed25519 занимает 64 байта (C-07-09: 64 байта) 14, её проверка — доли миллисекунды (C-07-04: 0,12 мс), так что выбор алгоритма определяется совместимостью, а не скоростью.

Инструменты избирательной доставки: apt-offline и срезы Snapshot

Когда переносить сотни гигабайт полного зеркала Debian нецелесообразно, применяются две стратегии избирательной доставки:

  1. apt-offline (двухпроходный протокол согласования зависимостей). Инструмент решает проблему: «как узнать, какие именно зависимости нужны узлу, если сам узел отключён от сети» 5. Процедура состоит из трёх шагов:
    • На автономном узле генерируется файл сигнатуры запроса, содержащий текущее состояние базы dpkg и перечень требуемых пакетов:
      apt-offline set --install-packages wireguard-tools --update /media/usb/request.sig
      
    • На внешней машине, подключённой к сети, по этой сигнатуре выкачиваются только недостающие пакеты и свежие индексы, упаковываемые в один zip-контейнер:
      apt-offline get /media/usb/request.sig --bundle /media/usb/update-bundle.zip
      
    • На автономном узле контейнер распаковывается и устанавливается в системный кэш APT:
      apt-offline install /media/usb/update-bundle.zip
      apt install wireguard-tools
      
  2. Временные срезы Snapshot Debian (snapshot.debian.org). Сервис сохраняет точные посуточные снимки всех пакетов и индексов Debian за всю историю проекта. При подготовке профиля (тема 2) фиксируется конкретная временная метка (например, 20240101T000000Z). Это гарантирует детерминированность: если тестовый стенд и боевой узел используют срез одной даты, исключается ситуация, при которой на один узел попала обновлённая минорная версия пакета, а на второй — нет.

Процедуры восстановления при сбое загрузки

Архитектура процесса загрузки в Linux

Чтобы восстановить неисправную систему, нужно представлять этапы её инициализации и знать, какой файл на каком этапе читается 67. Цепочка показана на рисунке; ошибка на каждом звене выглядит по-своему, и по виду ошибки определяется звено.

Цепочка загрузки UEFI: от прошивки до корневой ФС
Прошивка читает запись NVRAM и запускает shimx64.efi с ESP; shim проверяет подпись GRUB, GRUB читает grub.cfg и загружает ядро и initramfs; initramfs монтирует корень и передаёт управление systemd. Под каждым звеном — как выглядит его отказ
  1. Прошивка UEFI. Инициализирует процессор, память и шины, читает переменные NVRAM (записи загрузки Boot0000, BootOrder), находит системный раздел EFI (ESP, файловая система FAT32) и запускает файл, указанный в записи. В Debian при включённой безопасной загрузке (англ. Secure Boot) это \EFI\debian\shimx64.efi, без неё — \EFI\debian\grubx64.efi. Записи NVRAM просматриваются и создаются командой efibootmgr; если запись потеряна (замена платы, сброс настроек), система «не видит» диск, хотя все файлы на ESP целы.
  2. shim и GRUB 2. Маленький загрузчик shim подписан ключом Microsoft UEFI CA и проверяет подпись GRUB ключом Debian; GRUB, в свою очередь, проверяет подпись ядра 11. GRUB читает /boot/grub/grub.cfg, показывает меню и загружает в память ядро (vmlinuz) и начальный виртуальный диск (initrd.img), передавая ядру командную строку (root=UUID=... ro quiet).
  3. Начальный виртуальный диск. Ядро распаковывает архив cpio во временный корень в памяти и запускает в нём /init. Задача этого этапа — загрузить модули дисковых шин (NVMe, AHCI, USB), открыть LUKS, собрать LVM или mdadm и смонтировать настоящий корень. В Debian и Ubuntu по умолчанию образ собирает initramfs-tools, и корень монтируется в /root внутри временного корня 12; в Fedora, RHEL и openSUSE — dracut, и корень монтируется в /sysroot.
  4. Переключение корня. /init переносит смонтированный корень на место / (run-init в initramfs-tools, switch_root в dracut) и запускает /sbin/init — в современных системах это systemd.

Отказ на каждом из четырёх звеньев даёт свой признак: пустой экран или меню прошивки без пункта debian (звено 1), приглашение grub rescue> или grub> (звено 2), аварийная оболочка (initramfs) (звено 3), Kernel panic - not syncing: VFS: Unable to mount root fs или аварийный режим systemd после ошибки в /etc/fstab (звенья 3–4).

Безопасная загрузка в автономном узле — вопрос не только защиты, но и ремонтопригодности. Пока ядро и модули подписаны Debian, узел загружается с включённым Secure Boot без участия владельца. Собственный модуль ядра (например, драйвер платы из темы 6) подписи Debian не имеет; его подписывают своим ключом владельца машины (англ. Machine Owner Key, MOK) и регистрируют ключ командой mokutil --import, подтверждая регистрацию на консоли при следующей загрузке. Закрытую часть MOK хранят как ключ репозитория — отдельно от узла, с копией в профиле (тема 2). Потеря MOK не делает узел незагружаемым, но лишает возможности подписать новый модуль, пока не будет зарегистрирован новый ключ.

Регламент восстановления через chroot из аварийного LiveUSB

Универсальный и наиболее мощный инструмент системного инженера при аварии загрузки — процедура смены корневого каталога (chroot, англ. change root) из загрузочной среды аварийного накопителя (Debian Live или SystemRescue) 36.

Последовательность аварийного восстановления загрузчика через chroot
Пошаговый процесс: от идентификации блочных устройств до монтирования виртуальных псевдо-ФС ядра, входа в окружение установленной ОС и регенерации конфигураций

Рассмотрим точный порядок действий, исключающий ошибки разрушения данных:

Шаг 1. Идентификация накопителей и разделов

Загрузившись с аварийного LiveUSB, необходимо выяснить актуальную разметку дисков и UUID файловых систем:

lsblk -o NAME,FSTYPE,SIZE,MOUNTPOINT,UUID

Пример вывода:

NAME        FSTYPE   SIZE MOUNTPOINT UUID
sda                465.8G            
├─sda1      vfat     512M            2A4B-C8D0
├─sda2      ext4      20G            e3b0c442-98fc-1c14-9afb-f4c8996fb924
└─sda3      ext4   445.3G            5d41402a-bc4b-110e-953e-0013230628e4

В данном случае /dev/sda2 — корневой раздел целевой ОС, /dev/sda1 — системный раздел EFI, а /dev/sda3 — раздел данных /home.

Шаг 2. Монтирование файловых систем целевой ОС

Создаётся точка монтирования /mnt, куда монтируется корень:

mount /dev/sda2 /mnt
# Если система использует отдельный раздел /boot или EFI ESP:
mkdir -p /mnt/boot/efi
mount /dev/sda1 /mnt/boot/efi

Шаг 3. Связывание псевдо-файловых систем ядра

Любые утилиты настройки оборудования (grub-install, update-initramfs, dpkg) требуют доступа к структурам работающего ядра Linux: таблице процессов /proc, дереву аппаратных устройств /sys, псевдотерминалам и дискам /dev, а также сокетам межпроцессного взаимодействия /run. Их необходимо связать с целевым каталогом операцией bind-монтирования:

for dir in /dev /dev/pts /proc /sys /run; do
    mount --rbind $dir /mnt$dir
    mount --make-rslave /mnt$dir
done

Флаг --make-rslave предотвращает передачу операций размонтирования обратно в базовую Live-систему, что защищает хост от повреждения при аварийном завершении работы.

Шаг 4. Вход в окружение целевой системы

Выполняется переход:

chroot /mnt /bin/bash
export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

С этого момента любая выполненная команда работает внутри повреждённой ОС с её бинарными файлами, библиотеками и базами данных, но на ядре, запущенном с LiveUSB.

Шаг 5. Выполнение восстановительных процедур

Внутри chroot последовательно устраняются источники отказа:

  1. Восстановление загрузчика GRUB в MBR или EFI NVRAM:
    • Для классических систем BIOS/MBR:
      grub-install /dev/sda
      
    • Для систем UEFI:
      grub-install --target=x86_64-efi --efi-directory=/boot/efi --bootloader-id=debian --recheck
      
  2. Перегенерация конфигурации GRUB: Скрипт update-grub запускает grub-mkconfig, который сканирует все разделы, обнаруживает установленные ядра и формирует свежий /boot/grub/grub.cfg:
    update-grub
    
  3. Пересборка образа начального виртуального диска: Если повредились модули драйверов дисков или скрипты монтирования, выполняется пересборка initramfs для всех установленных ядер:
    update-initramfs -u -k all
    
  4. Коррекция таблиц монтирования /etc/fstab и /etc/crypttab: Типичная причина зависания при загрузке — неверный UUID корневого или swap-раздела (например, после изменения размера диска). С помощью утилиты blkid сверяются фактические UUID разделов и исправляются записи в /etc/fstab:
    blkid /dev/sda2
    nano /etc/fstab
    

Шаг 6. Корректный выход и синхронизация

Выход из chroot и каскадное освобождение точек монтирования:

exit
umount -R /mnt
sync
reboot

Аварийная консоль: initramfs-tools и dracut

Если аварийного носителя нет, но меню GRUB работает, вмешаться в загрузку можно из самого меню 6. Описанные ниже приёмы дают полный доступ к системе без пароля, поэтому применяются только на своих системах или с разрешения владельца; на чужой машине это обход защиты, а не восстановление. Защита от этого приёма — пароль на редактирование меню GRUB и шифрование корня, и автономный узел, стоящий в общем помещении, должен иметь и то и другое.

В меню GRUB клавиша e открывает редактор параметров выбранного пункта. В строку, начинающуюся со слова linux, дописывается одна из директив, затем Ctrl+X загружает систему с изменёнными параметрами. Директивы зависят от того, какой программой собран initramfs, и это главная ловушка: инструкции из интернета обычно написаны для dracut, а Debian по умолчанию использует initramfs-tools 12.

Задачаinitramfs-tools (Debian, Ubuntu)dracut (Fedora, RHEL, openSUSE)
Остановиться до монтирования корняbreak=premountrd.break=pre-mount
Остановиться после монтирования, до переключенияbreak=bottom (корень в /root)rd.break (корень в /sysroot)
Оболочка вместо systemdinit=/bin/shinit=/bin/sh
Аварийный режим systemdsystemd.unit=emergency.targetто же
Пересборка образаupdate-initramfs -u -k alldracut -f --regenerate-all

Сброс забытого пароля на своём узле Debian выглядит так. К строке linux дописывается init=/bin/sh; ядро вместо systemd запускает оболочку с правами root, корень при этом смонтирован только для чтения:

mount -o remount,rw /
passwd polygon          # новый пароль пользователя
sync
mount -o remount,ro /
exec /sbin/init         # или выключение кнопкой: systemd не запущен, reboot не сработает

Если корень зашифрован LUKS, init=/bin/sh не поможет без пароля шифрования: оболочка запускается после того, как initramfs откроет том, а для этого пароль всё равно нужен. Это правильное поведение, а не неудобство. Вариант с остановкой initramfs-tools после монтирования корня:

# в оболочке (initramfs) после break=bottom
mount -o remount,rw /root
chroot /root passwd polygon
mount -o remount,ro /root
exit                    # загрузка продолжится

В системе с dracut те же действия выполняются с rd.break и каталогом /sysroot; кроме того, при включённом SELinux после смены пароля нужно создать файл /.autorelabel, иначе пароль не примется. В ЛР 7 сброс пароля выполняется в ВМ с Debian 13, и время этапа записывается в журнал.

Доверенная цепочка обновлений (Air-Gap Update Pipeline)

Модель угроз: внешний носитель как вектор атаки

В изолированной инфраструктуре без постоянного выхода в глобальную сеть действует фундаментальное правило информационной безопасности: любой съёмный внешний накопитель по умолчанию считается скомпрометированным («подозреваемым») 78.

Физический носитель (USB-флешка, внешний SSD) подключается к машине внешней подготовки, имеющей доступ к интернету. На этой машине он подвержен риску заражения:

  • Запись скрытых исполняемых файлов или вредоносных скриптов автозапуска.
  • Атаки на уровне прошивки контроллера накопителя (BadUSB), когда USB-устройство перепрограммирует свой контроллер и при подключении к узлу эмулирует клавиатуру (HID), выполняя вредоносные консольные команды с правами локального пользователя.
  • Непреднамеренное повреждение данных (битовые ошибки ячеек памяти NAND, сбой файловой системы при некорректном извлечении).

Если администратор автономного узла просто вставит такую флешку в сервер и запустит dpkg -i *.deb, узел утрачивает статус доверенного. Чтобы этого не допустить, процесс обновления организуется как строгий конвейер с физической и криптографической изоляцией каждого этапа.

Доверенная цепочка обновлений автономного узла (Air-Gap Pipeline)
Пять рубежей контроля: подготовка на внешней доверенной машине, перенос на носителе с блокировкой записи, карантинная верификация, тестирование в снимке и применение с механизмом отката

Этапы доверенного конвейера

Конвейер состоит из пяти последовательных фаз, каждая из которых имеет строгое условие прохождения (англ. quality gate) 18:

1. Подготовка пакета обновления на внешней доверенной машине

На доверенной сборочной станции (не являющейся офисным ПК общего назначения) собирается пакет обновления. Формируется машиночитаемый файл описания — manifest.json. В него заносятся метаданные, версии и криптографические контрольные суммы (SHA-256) каждого файла пакета. Манифест подписывается закрытым ключом GPG инженера:

gpg --armor --detach-sign manifest.json

В результате формируется откреплённая цифровая подпись manifest.json.asc.

2. Физический перенос через карантинный носитель

Накопитель для переноса должен удовлетворять техническим требованиям:

  • Наличие аппаратного переключателя защиты от записи (англ. hardware write-protect switch), предотвращающего изменение данных целевой системой или заражение флешки при обратном переносе.
  • На автономном узле служба автоматического монтирования (udisks2) отключена.
  • Монтирование выполняется вручную или специализированным демоном со строгими опциями ядра:
    mount -o ro,nosuid,nodev,noexec /dev/sdb1 /mnt/quarantine
    
    Опции noexec и nosuid исключают запуск любых исполняемых бинарных файлов напрямую с флешки.

3. Карантинная верификация целостности и подлинности

Перед тем как файлы обновления попадут в файловую систему узла, они проходят контроль в изолированной карантинной среде:

  • Проверка цифровой подписи манифеста. На узле хранится файл с открытым ключом подписи обновлений (release.pgp) и, отдельно, записанный в регламенте отпечаток этого ключа — 40 шестнадцатеричных знаков, полученных по второму каналу (бумага в профиле, тема 2). Подпись проверяется только по этому файлу:
    gpgv --status-fd 1 --keyring /etc/polygon/release.pgp manifest.json.sig manifest.json
    
    Обычная команда gpg --verify для этой роли не годится. Она проверяет подпись по личной связке пользователя, куда со временем попадают посторонние ключи, а для ключа без «доверия» печатает предупреждение This key is not certified with a trusted signature, но всё равно возвращает код 0 — скрипт, проверяющий только код выхода, примет такую подпись. Скрипт sign_manifest.py из ЛР 7 вызывает gpgv с явным файлом ключа, требует в выводе --status-fd строку VALIDSIG и сравнивает отпечаток из неё с записанным; любой другой статус (BADSIG, ERRSIG, EXPKEYSIG, отсутствие файла подписи) означает отказ. Подпись обязательна: манифест без подписи защищает только от случайной порчи, потому что подменивший файлы подменит и манифест (подробно инфраструктура открытых ключей — курс «Криптография», темы 14–15).
  • Проверка побайтовой целостности полезной нагрузки. Утилита валидации (sign_manifest.py) считывает манифест и пересчитывает SHA-256 каждого файла в пакете. Несовпадение хотя бы одного байта означает сбой носителя или саботаж и приводит к отбраковке всего пакета.

4. Тестовое развёртывание на полигоне (Staging)

Пакет обновлений никогда не накатывается на рабочий узел напрямую. Он развёртывается в тестовом окружении: изолированной виртуальной машине QEMU, легковесном контейнере или в отдельном снимке файловой системы (btrfs snapshot). В тестовой среде запускается набор проверочных сценариев (англ. smoke tests):

  • Проверка успешности завершения установки пакета (dpkg -i вернул код 0).
  • Проверка отсутствия сломанных зависимостей (apt-get check).
  • Контроль запуска системных демонов (systemctl is-active --quiet <service>).
  • Выполнение функционального теста (например, локальный DNS-сервер отвечает на запросы к петлевому интерфейсу).

5. Развёртывание на рабочем узле и готовность к откату

Только после успешного завершения всех тестов обновление переносится на основной рабочий узел. Перед установкой создаётся точка отката (снимок диска). В случае малейшей нестабильности инженер возвращает систему в исходное состояние одной командой.

Числовой пример: время карантинной проверки

Разберём время карантинной проверки пакета обновлений объёмом 250 МБ (250 · 10⁶ байт): накопительное обновление ядра, утилиты шифрования и офлайн-документация, 180 файлов. Проверка складывается из трёх операций: прочитать байты с носителя, посчитать SHA-256, проверить одну подпись манифеста.

  1. Чтение с носителя. Скорость чтения — условие примера: 28 МБ/с, флеш-накопитель в порту USB 2.0. Это не паспортное число, его измеряют на своём носителе (dd if=/dev/sdX of=/dev/null bs=4M count=100 iflag=direct, ЛР 7). При 28 МБ/с чтение 250 МБ занимает T_{io} = \frac{V}{S_{io}} = \frac{250\ \text{МБ}}{28\ \text{МБ/с}} = 8{,}9\ \text{с} (C-07-05: 8,9 с).
  2. Хеширование. На машине автора openssl speed показал 1,75 ГБ/с для SHA-256 блоками по 16 КиБ (C-07-02: 1,75 ГБ/с; процессор с инструкциями SHA). Тогда T_{hash} = \frac{250\ \text{МБ}}{1751\ \text{МБ/с}} = 0{,}14\ \text{с}. На процессоре без аппаратного SHA скорость ниже в несколько раз; её измеряют той же командой в ЛР 7, а не берут из этого текста.
  3. Проверка подписи. Узел подпись не создаёт, а проверяет, поэтому важна скорость проверки. Измерено там же: проверка подписи RSA-4096 — 0,084 мс (C-07-03: 0,084 мс), Ed25519 — 0,12 мс (C-07-04: 0,12 мс). Обе величины на пять порядков меньше времени чтения.

Итого T = 8,9 + 0,14 + 0,0001 ≈ 9,0 с, из них на криптографию приходится 0,14 с, то есть 1,6 %. Вывод не зависит от точных чисел: пока носитель медленнее хеш-функции в десятки раз, отказ от проверки ничего не экономит. Он мог бы иметь смысл только на процессоре без ускорения и с быстрым NVMe-носителем, и именно это сочетание стоит измерить, прежде чем что-то упрощать.

Обслуживание автономной системы и изоляция зависимостей

Автономные таймеры и ротация системных журналов

В отсутствие сетевого времени (NTP) и внешних серверов мониторинга периодическое обслуживание системы возлагается на таймеры systemd (англ. systemd timers) 39. Таймеры systemd имеют фундаментальное преимущество перед классическим демоном cron: они поддерживают монотонные интервалы от момента загрузки ядра (OnBootSec=) или от момента последнего срабатывания (OnUnitActiveSec=). Если узел был обесточен, таймер cron просто пропускает назначенное время суток; таймер systemd с директивой Persistent=true гарантированно выполнит пропущенную задачу сразу после восстановления питания.

Пример таймера еженедельной проверки целостности корневой ФС (/etc/systemd/system/fs-scrub.timer):

[Unit]
Description=Weekly Filesystem Scrubbing Timer
ConditionVirtualization=false

[Timer]
OnBootSec=15min
OnUnitActiveSec=7d
Persistent=true

[Install]
WantedBy=timers.target

Другой критический аспект — предотвращение переполнения диска системными журналами. Служба systemd-journald на изолированном узле настраивается жестко в /etc/systemd/journald.conf:

[Journal]
Storage=persistent
Compress=yes
SystemMaxUse=500M
SystemKeepFree=2G
MaxRetentionSec=1month

Эти параметры гарантируют, что журнал никогда не займет более 500 МБ дискового пространства и не приведет к блокировке записи в корневой раздел при возникновении шторма однотипных ошибок в изолированной сети.

Снимки файловой системы и мгновенный откат (Btrfs / LVM)

Классическая файловая система ext4 надёжна, но не поддерживает снимки состояния (англ. snapshots) на уровне файловой системы. В автономных системах высокой готовности для корневого раздела применяется Btrfs или LVM Thin Provisioning 910.

Технология снимков на основе механизма копирования при записи (англ. Copy-on-Write, CoW) позволяет создать мгновенный логический срез всей операционной системы без дублирования занятых блоков на диске. Процедура безопасного обновления узла с возможностью отката строится следующим образом:

  1. Создание пред-обновленческого снимка:
    btrfs subvolume snapshot / /.snapshots/pre-update-2026-10-20
    
  2. Выполнение обновления или рискованной модификации конфигураций.
  3. Откат при возникновении критического сбоя: Если после установки система перестала загружаться или ключевой демон выдаёт ошибку конфигурации, администратор загружается с аварийного носителя (или выбирает снимок в меню GRUB) и возвращает рабочий подтом:
    # Монтирование корня Btrfs
    mount /dev/sda2 /mnt
    # Переименование повреждённого подтома и восстановление снимка
    mv /mnt/@ /mnt/@_broken
    btrfs subvolume snapshot /mnt/@snapshots/pre-update-2026-10-20 /mnt/@
    umount /mnt
    reboot
    

Время отката составляет менее 5 секунд, так как операция заключается исключительно в изменении метаданных корневого подтома Btrfs.

Автономная изоляция языковых экосистем (Python, Rust, Go)

Современное прикладное программное обеспечение активно использует языковые репозитории (PyPI, Crates.io, Go Modules). Попытка запустить pip install или cargo build на изолированном узле терпит немедленный крах из-за недоступности глобальных хостов. Для каждой экосистемы применяется специализированная стратегия изоляции 5:

  1. Python (Wheels-кэш): На внешней машине скачиваются скомпилированные бинарные пакеты формата Wheel со всеми зависимостями под целевую архитектуру:
    pip download -d /media/usb/wheels/ \
      --only-binary=:all: \
      --platform manylinux2014_x86_64 \
      --python-version 3.11 \
      fastapi uvicorn cryptography
    
    На автономном узле установка выполняется строго из локального каталога с запретом сетевого доступа:
    pip install --no-index --find-links=/media/usb/wheels/ fastapi
    
  2. Rust (cargo vendor): Все сторонние крейты, объявленные в Cargo.toml, скачиваются и упаковываются непосредственно в дерево исходных кодов проекта:
    cargo vendor vendor/
    
    В файл .cargo/config.toml добавляется перенаправление на локальный каталог:
    [source.crates-io]
    replace-with = "vendored-sources"
    
    [source.vendored-sources]
    directory = "vendor"
    
    После этого компиляция cargo build --release --offline выполняется без единого байта сетевого трафика.
  3. Go (go mod vendor): Аналогично Rust, команда go mod vendor сохраняет точные копии всех зависимостей в подкаталог vendor/, а сборка осуществляется с флагом -mod=vendor.

Изоляция зависимостей превращает проект в полностью самодостаточный артефакт, гарантируя воспроизводимость сборки в любых условиях.

Корень только для чтения и конфигурация как код

Снимок позволяет откатиться, но не отвечает на вопрос «что именно изменилось». Для автономного узла, который обслуживают годами разные люди, второй вопрос важнее. Его закрывают два приёма.

Первый — хранить /etc в git. Пакет etckeeper создаёт репозиторий в /etc и автоматически делает коммит до и после каждой операции APT, а также раз в сутки по таймеру 3. После любой правки видно, кто, когда и что поменял, а откат одного файла — git -C /etc checkout <коммит> -- fstab. Тот же репозиторий копируется в профиль узла (тема 2) и служит описанием конфигурации: развернуть узел заново — значит поставить пакеты по списку dpkg --get-selections и вернуть /etc из репозитория. Конфигурация как код в автономии не означает обязательный Ansible: достаточно того, что состояние узла восстанавливается из текстовых файлов одной процедурой, а не по памяти.

Второй — корень только для чтения. Если / смонтирован с опцией ro, а изменяемые данные живут в отдельных разделах (/var, /home, /srv), то сбой питания во время записи не может испортить системные файлы, а случайная команда не сотрёт /usr. Обновление в этой схеме выполняется явным перемонтированием (mount -o remount,rw /), применением пакета и возвратом в ro, то есть сам режим заставляет пройти по конвейеру этого раздела. Цена — каталоги, куда программы пишут без спроса (/etc/resolv.conf, /var/lib/systemd), переносятся на tmpfs или в /var, и это требует проверки каждой службы. Для узла из темы 6 с SD-картой или старым SSD экономия числа записей сама по себе достаточный довод.

Локальное зеркало: состав, размер, обновление

Полное зеркало Debian для одной архитектуры занимает сотни гигабайт, и автономному узлу оно не нужно. Нужен срез: пакеты, которые установлены на узлах, их зависимости и небольшой запас инструментов восстановления (testdisk, ddrescue, cryptsetup, e2fsprogs, btrfs-progs, smartmontools). Список строится от факта, а не от желания:

dpkg-query -W -f '${Package}\n' > installed.txt          # что стоит на узле
apt-get download $(cat installed.txt extra.txt)            # на машине подготовки
du -sh pool/                                               # размер среза

Размер такого среза для узла без графики — единицы гигабайт; точное число зависит от состава и измеряется в ЛР 7, а в курсовом проекте записывается в паспорт узла. При появлении связи срез обновляется целиком на машине подготовки, подписывается заново и переносится по конвейеру; частичное «доливание» пакетов в подписанный репозиторий без пересборки индексов и новой подписи приводит к отказу APT, и это правильное поведение.

Для узла, который иногда видит сеть (сценарий А), удобнее кэширующий прокси apt-cacher-ng: клиенты локальной сети обращаются к нему, он скачивает пакет один раз и отдаёт из кэша остальным. Подписи при этом проверяет каждый клиент, поэтому прокси не обязан быть доверенным. Кэш прокси — готовый материал для среза: после месяца работы в нём лежит ровно то, что узлам понадобилось.

Аналоги для других пакетных менеджеров

Принципы — подписанный индекс, ключ только для своего источника, локальный каталог вместо зеркала — одинаковы для всех дистрибутивов; меняются только имена команд.

ЗадачаDebian (apt)Arch (pacman)Alpine, OpenWrt 25.x (apk)
Собрать индекс локального каталогаapt-ftparchive packagesrepo-add polygon.db.tar.gz *.pkg.tar.zstapk index -o APKINDEX.tar.gz *.apk
Подписать индексgpg --clearsign → InReleaserepo-add --sign (GnuPG)abuild-sign APKINDEX.tar.gz (RSA)
Ключ только для своего источникаSigned-By: в .sourcesSigLevel в секции репозиторияключ в /etc/apk/keys/
Отключить проверку (не делать)Trusted: yesSigLevel = Never--allow-untrusted
Скачать пакеты без установкиapt-get downloadpacman -Swapk fetch -R

OpenWrt начиная с выпусков 25.x перешёл с opkg на apk, поэтому маршрутизатор из темы 11 обслуживается по правой колонке таблицы. У apk ключи — не OpenPGP, а RSA в формате PEM, и проверка выполняется по всем ключам каталога /etc/apk/keys/: ограничить ключ одним источником, как Signed-By, там нельзя, и на узле этот каталог держат минимальным.

Локальные сертификаты и время

Сервисы темы 8 (вики, файловый сервер, чат) работают по HTTPS, а сертификат Let's Encrypt без интернета не продлить. Автономный узел выпускает сертификаты сам: локальный центр сертификации (корневой ключ хранится офлайн, как ключ подписи обновлений) подписывает сертификаты для имён *.polygon.internal, а корневой сертификат устанавливается на клиентах. Устройство центра сертификации, сроки и отзыв — курс «Криптография», темы 14–15; для автономного узла важны два следствия. Срок действия сертификата сервиса выбирается так, чтобы продление укладывалось в регламент обслуживания (например, год при ежеквартальном обслуживании), а продление — ещё один пакет, который проходит конвейер этого раздела. И проверка срока, как и проверка срока ключа подписи (EXPKEYSIG), опирается на часы узла: узел с часами, ушедшими на месяц назад или вперёд, отвергнет исправный сертификат или примет просроченный. Поэтому синхронизация времени (тема 8) — условие работы доверенной цепочки, а не отдельная служба.

Аварийный загрузочный комплект

В профиль узла входит носитель, с которого можно загрузить любую машину Полигона: живая система Debian 13 (образ debian-live-13.x-amd64-standard.iso) или SystemRescue, с инструментами раздела «Процедуры восстановления». Несколько образов на одном носителе позволяет держать загрузчик Ventoy: он копирует на носитель свой загрузчик и раздел с файловой системой exFAT, а ISO-файлы просто кладутся на этот раздел и выбираются в меню. Удобство оплачивается доверием: Ventoy — ещё одно звено в цепочке загрузки, которое нужно проверять и обновлять, а при включённом Secure Boot он требует регистрации собственного ключа MOK. Для курса достаточно одного проверенного образа, записанного dd и сверенного по SHA512SUMS с подписью Debian; комплект из нескольких образов — расширение, а не требование.

Что эта модель не учитывает

Рассмотренная модель автономной ОС и доверенной цепочки обновлений построена на разумном компромиссе между параноидальной изоляцией и трудоёмкостью сопровождения. Однако она сознательно не учитывает следующие факторы:

  1. Физическая компрометация самого аппаратного носителя ключей. Если закрытый ключ GPG, которым подписывается манифест, скомпрометирован злоумышленником на машине внешней подготовки, криптографическая проверка на автономном узле не защитит от внедрения вредоносного кода. Защита от этой угрозы требует хранения ключей на аппаратных токенах (YubiKey / Nitrokey) и многосторонней подписи (quorum / m-of-n).

  2. Атаки по сторонним каналам через аппаратный контроллер USB (BadUSB). Карантинная проверка файловых систем защищает от вредоносных файлов, но бессильна против модифицированной микропрограммы самого USB-контроллера, эмулирующего DMA-атаку или сетевой адаптер в момент включения шины. Полная защита требует использования опторазвязанных однонаправленных диодов данных (англ. data diode) или специализированных USB-фильтров блокировки дескрипторов.

  3. Невоспроизводимость проприетарного микрокода (firmware-nonfree). Закрытые бинарные блобы прошивок Wi-Fi контроллеров, графических процессоров и системного менеджмента (Intel ME / AMD PSP) невозможно проинспектировать или пересобрать из исходного кода. Узел вынужден доверять цифровым подписям поставщиков оборудования.

  4. Скрытая деградация ячеек памяти при длительном хранении без питания. Носители данных, используемые для аварийных копий и репозиториев (особенно флеш-память TLC/QLC), подвержены утечке электрического заряда плавающего затвора при хранении более 1–2 лет. Без регулярной перезаписи (scrubbing) целостность репозитория со временем будет утрачена.

  5. Время узла. Проверка срока действия ключа подписи и сертификатов предполагает, что часы узла верны. Узел, часы которого после долгой автономии ушли (тема 8), может отвергнуть исправный пакет (EXPKEYSIG, «сертификат ещё не действителен») или принять подписанный отозванным ключом, о котором он не знает: списка отзыва без связи на узле нет.

  6. Ошибки в самом пакете. Подпись подтверждает, кто собрал пакет, но не то, что пакет исправен. От ошибки сборщика защищает только этап тестирования в staging, и он ловит лишь то, что проверяют смоук-тесты.

Итоги темы

Автономная операционная система коренным образом отличается от обычной рабочей станции: в ней принудительно отключены все механизмы удалённой лицензионной активации, фоновые сетевые службы и автоматические обновления. Базовым эталонным дистрибутивом для изолированного узла выбран Debian GNU/Linux Stable, сочетающий неизменность версий библиотек, текстовый формат конфигураций и возможность воспроизводимой установки минимального ядра утилитой debootstrap с суммарным объёмом менее 200 МБ.

Отказ от интернета компенсируется локальным файловым репозиторием APT со стандартной структурой dists/ и pool/, подписанным собственным ключом: InRelease с подписью, ключ в отдельном файле, указанном в Signed-By, без флага trusted=yes, который отключил бы всю проверку. В Debian 13 подпись проверяет sqv, отвергающий устаревшие алгоритмы, поэтому ключ репозитория создаётся на Ed25519 или RSA от 3072 бит. Использование избирательных инструментов доставки (apt-offline, временные срезы архивов snapshot.debian.org) позволяет доставлять на узел только проверенные и строго согласованные по зависимостям наборы программного обеспечения.

При аварии загрузки операционной системы универсальным инструментом восстановления выступает процедура смены корневого каталога chroot из аварийной среды LiveUSB. Связывание псевдо-файловых систем ядра (/dev, /proc, /sys) позволяет выполнять переустановку загрузчика GRUB, регенерацию образов initramfs и исправление ошибок в /etc/fstab непосредственно в среде установленной ОС без переустановки системы. Если аварийного носителя нет, доступ к системе дают параметры ядра из меню GRUB, и они зависят от сборщика initramfs: break=premount и break=bottom (корень в /root) у initramfs-tools в Debian, rd.break (корень в /sysroot) у dracut; init=/bin/sh работает в обоих случаях. Эти приёмы применяются только на своих системах или с разрешения владельца.

Доставка изменений на автономный узел строится по модели доверенной цепочки обновлений. Любой внешний физический накопитель рассматривается как потенциально скомпрометированный и монтируется только в режиме «только для чтения» с запретом исполнения бинарных файлов. Установка разрешается исключительно после прохождения карантинной проверки: подтверждения подписи манифеста программой gpgv по явно заданному файлу ключа со сверкой отпечатка, валидации SHA-256 хешей полезной нагрузки и успешного прохождения автоматизированных тестов в изолированном снимке staging.

В долговременной эксплуатации стабильность узла обеспечивается монотонными таймерами systemd, жестким квотированием системных журналов в journald и использованием CoW-снимков файловой системы Btrfs, гарантирующих мгновенный откат при возникновении сбоев. Внешние экосистемы разработки (Python, Rust, Go) изолируются от сети с помощью предварительной упаковки бинарных колес и локального вендоринга зависимостей.

Литература

  1. NIST Special Publication 800-160 Vol. 2 Rev. 1. Developing Cyber-Resilient Systems: A Systems Security Engineering Approach. — National Institute of Standards and Technology, 2021. https://csrc.nist.gov/pubs/sp/800/160/v2/r1/final
  2. Anderson R. Security Engineering: A Guide to Building Dependable Distributed Systems. 3rd ed. — Wiley, 2020.
  3. Hertzog R., Mas R. The Debian Administrator's Handbook. — Freexian. https://debian-handbook.info/
  4. apt-secure(8), sources.list(5). Debian manpages. https://manpages.debian.org/trixie/apt/apt-secure.8.en.html
  5. Ward B. How Linux Works: What Every Superuser Should Know. 3rd ed. — No Starch Press, 2021.
  6. Debian GNU/Linux Installation Guide. https://www.debian.org/releases/stable/installmanual
  7. Kerrisk M. The Linux Programming Interface: A Linux and UNIX System Programming Handbook. — No Starch Press, 2010.
  8. Schneier B. Applied Cryptography: Protocols, Algorithms, and Source Code in C. 20th Anniversary Edition. — Wiley, 2015.
  9. systemd System and Service Manager. Documentation. https://systemd.io/
  10. Btrfs Documentation. https://btrfs.readthedocs.io/
  11. GNU GRUB Manual. Free Software Foundation. https://www.gnu.org/software/grub/manual/grub/
  12. initramfs-tools(7). Debian manpages. https://manpages.debian.org/trixie/initramfs-tools-core/initramfs-tools.7.en.html
  13. Debian 13 «trixie» Release Notes. https://www.debian.org/releases/trixie/release-notes/
  14. RFC 8032. Edwards-Curve Digital Signature Algorithm (EdDSA). — IETF, 2017. https://www.rfc-editor.org/rfc/rfc8032