Здравствуйте, уважаемые читатели моего блога!
Сегодня мы поговорим об обучении администрированию, образах начальной загрузки и сделаем мини-проект, по результатам которого система будет требовать USB носитель для загрузки.
Сразу отмечу, что проект предназначен для обучения и не является средством защиты информации. Экспериментируйте только в виртуальной машине для обучения. Не повторяйте указанные действия на реальной системе – возможно, в теме разберётесь лучше, но и нервных клеток потратите немало :-).
Пара слов о принципе обучения
Для начинающих хотел бы посоветовать изучать Linux (в частности Astra Linux) методом внесения изменений в работу операционной системы.
Чтобы не превратить такое обучение в рутину и не отбить желание, рекомендую установить Vbox, создать виртуальную машину и сделать снимок рабочей системы.
Дальше обучение проходит по принципу – чтение любой книги о Linux для начинающих (не обязательно Astra Linux – отличия минимальны, особенность лишь в СЗИ, дизайне рабочего стола – под капотом всё тоже самое) – применение знаний на практике в виртуальной машине.
Сломали? Это отлично – значит вы на правильном пути! Восстановили снимок и попробовали ещё разок изменив подход. Отсутствие результата – это не неудача, а минус один возможный вариант.
Изучаете файлы в файловой системе? Создайте файл.
Права доступа? Назначьте их, попробуйте получить доступ к файлу при разных правах!
Systemd? Создайте свой первый юнит – пусть он просто создаст файл в /tmp – это уже отличное начало.
Планировщик задач? Давайте что-нибудь запланируем!
Grub? Меняем конфигурацию загрузки!
Образ начальной загрузки? Так давайте влезем в его работу и расширим функционал.
Образ начальной загрузки ядра
Образ начальной загрузки (файл initrd в каталоге boot) – по факту образ файловой системы, содержащей минимальный набор исполняемых файлов и библиотек. Его цель – обеспечить ядро минимумом, который позволит запустить основную операционную систему, в которой могут функционировать более сложные системы от шифрования до программных raid массивов.
То есть, если брать аналогию, это некая тактическая группа, состоящая из нескольких человек – её задача захватить плацдарм и обеспечить продвижение основных войск. Большое начинается с малого.
Сам образ хранится в особом формате CPIO – файлы образа (библиотеки, скрипты и бинарные файлы) записаны подряд. Кроме того, CPIO образ архивирован gzip.
Бывают ситуации, когда нужно лезть в сам образ начальной загрузки (распаковывать и пересобирать) – это происходит редко (но, как всегда, метко – ссылка).
В действующей системе уже есть готовая среда, чтобы создать образ начальной загрузки. В Astra Linux утилита update-initramfs и каталог /usr/share/initramfs-tools/.
В каталоге initramfs-tools есть каталог hooks – там хранятся скрипты, которые добавляют в образ начальной загрузки необходимую логику, программы и подсистемы.
Именно в этом каталоге вы можете обнаружить знакомое слово digsig. Да, всё верно – работа замкнутой программной среды в Astra Linux начинается с образа начальной загрузки.
В рамках хука digsig в образ начальной загрузки попадают ключи ЗПС и генерируется соответствующий конфигурационный файл.
За включение в образ модулей ядра отвечает поддериктория modules.d. Там вы также увидите файл с подозрительно знакомым названием digsig_verif (в его содержании точно такое же слово, это название модуля ядра ЗПС – в нём всё волшебство работы этой подсистемы).
Одна из поддиректорий с названием scripts содержит скрипты, выполняемые в разные моменты загрузки системы. Открыв scripts, вы увидите директории с говорящими названиями – init-premount, panic, local-top.
Например, в каталоге init-top вы увидите файл digsig_initramfs. Этот скрипт инициализирует работу ЗПС (например, утилита modprobe загружает драйвер ЗПС, остальную логику вы можете изучить самостоятельно, так как она выходит за рамки нашей статьи).
В директории initramfs-tools и её поддиректориях также размещены вспомогательные функции.
Основную роль в работе образа начальной загрузки занимает скрипт init, как мы уже знаем, он не выполняет всю работу самостоятельно – это “дирижер”, который координирует работу “оркестра” (скриптов initramfs).
Напомню, что если этот блог Вам помог, помогите и Вы его развитию.
Для этого отправьте любую сумму, используя форму ниже.
Изучение методом изменения. Добавим USB ключ в ходе загрузки ОС.
С общей структурой мы ознакомились. Теперь нарушим эту идиллию и вставим в образ начальной загрузки свой функционал.
Будем требовать подключения определенного USB носителя.
Так как мы учимся, а не делаем реальный проект, я сделаю простую реализацию, используя утилиту lsusb. Проверку выполним простую – вставлено устройство с названием фирмы нашей флешки? Пропускаем. Такое устройство отсутствует? “Стоп колёса” – не даём загружаться дальше!
Сначала я напишу сам скрипт, реализующий эту функцию.
#!/bin/bash
until lsusb | grep ADATA &>/dev/null
do
clear
echo 'INSERT YOUR USB KEY FOR CONTINUE LOADING OS!'
sleep 2
done
clear
echo 'Success. LOADING OS.'
sleep 3
Скрипт довольно простой. Он выполняет команду lsusb и ищет в ней строчку ADATA до тех пор, пока не найдет (цикл until).
Если он найдет строчку ADATA, значит, устройство подключено.
Тогда очистим экран, выведем сообщение, что всё “Ок”, подождём 3 секунды, чтобы сообщение могли успеть прочитать. Вот и вся логика.
Разместим скрипт в файле lsusb в каталоге scripts/init-top. Структуру файла сделаем по аналогии digsig.
Если мы оставим всё как есть, то ничего не заработает. Почему? Потому что образ начальной загрузки – ограниченный образ. Утилиты lsusb там нет, библиотек для её работы – тоже.
Узнать библиотеки, которые нужны для работы lsusb, можно с помощью команды ldd.
ldd /usr/bin/lsusb
Мы можем найти их вручную и скопировать в отдельную директорию. Но лучше автоматизируем.
mkdir /opt/lib/
while read x; do find / -name $x -exec cp {} /opt/lib/ ';'; done <<<$(ldd /usr/bin/lsusb | awk '{print $1}')
Данной командой я создал каталог для библиотек, узнал перечень библиотек с помощью ldd, выделил их имена awk, передал их утилите find, которая найдет их в системе и скопирует в дирректорию /opt/lib/.
Далее создадим hook с именем lsusb. Шаблон файла, как всегда, посмотрим у digsig.
В нашем хуке скопируем в образ бинарник lsusb и библиотеки для него.
Теперь, когда все работы выполнены, мы имеем наш скрипт, бинарный файл lsusb и необходимые библиотеки. Обновим образ начальной загрузки с нашим скриптом и перезагрузим систему.
update-initramfs -k all -u && reboot
При загрузке системы получим ожидаемый результат.
Что дальше?
Для тех, кто заинтересовался идеей, можно улучшить скрипт, используя утилиту lsblk (которая позволяет получить серийный номер флешки). Так же можно сделать список разрешенных серийных номеров.
А может, добавить картинку, как будто работает модуль доверенной загрузки? Всё в ваших руках!
Лично я люблю изучать работу системы именно таким образом.
Надеюсь вам тоже понравится! До новых встреч!


