Работая и экспериментируя с разнообразными серверами и программами в Astra Linux я часто сталкиваюсь с необходимостью установки виртуальных серверов.

Средства виртуализации позволяют создавать шаблоны виртуальных машин, но мне всегда хотелось иметь более универсальное решение, образ, который будет занимать мало места и содержать только необходимый минимум пакетов.

К сожалению, для обычных пользователей Astra Linux предоставляет только один универсальный образ, и никаких mini-iso и прочих готовых образов.

Сегодня я начинаю цикл статей призванный исправить эту несправедливость, в этой статье мы вручную создадим свой первый образ mini-iso уменьшив размер официального образа с 4.4Гб до 896 Мб, т.е. почти в 5 раз!

Мы не будем вносить изменения в пакеты операционной системы и обойдемся только штатными средствами для кастомизации установочного образа iso.

Подготовка

Установим требуемые пакеты 

sudo apt -y install p7zip-full xorriso

Создадим папку в которой будем работать 

mkdir -p ~/astralinux-minimal

Загрузим iso-образ Astra Linux 

cd ~/astralinux-minimal

wget https://mirror.yandex.ru/astra/stable/orel/iso/orel-stable.iso

Распаковка образа 

Создадим папку:

mkdir -p ./current-iso

Создадим файл extract.sh:

mcedit ./extract.sh

С содержимым: 

xorriso -osirrox on -indev "orel-stable.iso" -extract /  ./current-iso

Сделаем исполняемым: 

chmod +x ./extract.sh

Запустим: 

./extract.sh

Содержимое образа будет скопировано в папку.

Создание списка файлов и папок

Чтобы получить список пакетов, необходимый для минимальной установки, нам нужно поставить с нуля Astra Linux на виртуальную машину. При установке выбираем только базовую систему и OpenSSH

После окончания установки, запускаем на ней: 

sudo dpkg-query -f '${binary:Package}\n' -W > packages_list.txt

У нас получится файл с именами пакетов. Нам нужно вручную превратить его в список папок, в которых содержаться файлы этих пакетов.

Это долгий и нужный процесс, поэтому я сразу привожу готовый список.

Создадим файл folderlist.txt 

mcedit ./folderlist.txt

 С содержимым: 

a/acpi
a/acpi-support
a/acpid
a/adduser
a/anacron
a/acl
a/apt
a/apparmor
a/aptitude
a/aptitude
a/aspell
a/aspell-en
a/astra-scripts
a/astra-version
a/atftp
a/attr
a/audit
a/autogen
b/base-files
b/base-passwd
b/bash
b/bash-completion
b/bind9
b/binutils
b/blends
b/boost1.62
b/bsd-mailx
b/bsdmainutils
b/busybox
b/bzip2
c/ca-certificates
c/cdebconf
c/cdrkit
c/chkrootkit
c/console-setup
c/coreutils
c/cpio
c/cracklib2
c/cron
c/cryptsetup
c/cracklib2
c/curl
c/cyrus-sasl2
c/cwidget
d/dash
d/dbus
d/debconf
d/debianutils
d/dh-python
d/dictionaries-common
d/diffutils
d/distro-info-data
d/dmidecode
d/dosfstools
d/dpkg
d/dvd+rw-tools
d/db5.3
d/dvd+rw-tools
e/e2fsprogs
e/ecryptfs-utils
e/eject
e/emacsen-common
e/exfat-utils
e/exim4
e/elfutils
e/expect
e/expat
e/ecryptfs-utils
f/fakeroot
f/freetype
f/file
f/findutils
f/fuse
f/foomatic-db
g/gawk
g/gcc-6
g/gdbm
g/gcc-defaults 
g/gettext
g/gnupg2
g/gpm
g/gmp
g/glibc
g/grep
g/groff
g/grub2
g/gutenprint
g/gzip
g/glib2.0
g/gnutls28
g/gpgme1.0
h/hostname
i/ia32-libs
i/ifupdown
i/init-system-helpers
i/ijs
i/init-system-helpers
i/initramfs-tools
i/installation-report
i/iproute2
i/iptables
i/iputils
i/isc-dhcp
k/kbd
k/keyutils
k/klibc
k/kmod
k/krb5
l/laptop-detect
l/less
liba/libassuan
libb/libbsd
libc/libcap2
libc/libcap-ng
libe/libedit
libe/libestr
libf/libfastjson
libk/libksba
libf/libffi
libg/libgd2
libg/libgpg-error
libg/libgcrypt20
libi/libident
libi/libidn
libi/libidn2
libi/libipc-signal-perl 
libl/liblocale-gettext-perl
libl/liblockfile
libl/liblognorm
l/lz4
libm/libmime-types-perl
libm/libmnl
libn/libnatspec 
libn/libnetfilter-conntrack
libn/libnfnetlink
libp/libpipeline
libp/libpng1.6
libp/libproc-waitstat-perl
libp/libpsl
libs/libseccomp
libs/libselinux
libs/libsemanage
libs/libsepol
libs/libsigc++-2.0
libs/libsigsegv
libs/libssh2
libt/libtasn1-6
libt/libtext-charwidth-perl
libt/libtext-iconv-perl
libt/libtext-wrapi18n-perl
libt/libtirpc
libu/libunistring
libu/libusb
l/linux-5.10
l/linux-base
l/linux-firmware
l/linux
l/linux-meta
l/lvm2
l/lockfile-progs
l/logcheck
l/logrotate
l/lsb
l/lm-sensors
l/lsof
m/man-db
m/manpages-ru
m/mawk
m/mc
m/mime-construct
m/mime-support
m/mueller
m/mpdecimal
m/mpfr4
n/nano
n/ncurses
n/net-tools
n/netkit-rsh
n/netbase
n/netcat-openbsd
n/netcat
n/newt
n/net-snmp
n/ntfs-3g
n/ntp
n/nghttp2
n/npth
n/nettle
n/nspr
n/nss
n/netkit-telnet
o/openssh
o/openssl
o/openssl1.0
o/openldap
o/os-prober
p/p11-kit
p/pam
p/p7zip
p/pciutils
p/pcsc-lite
p/pcre3
p/perl
p/pinentry
p/powertop
p/procps
p/python3-defaults
p/python3.5 
p/popt
q/quota
r/readline
r/rtmpdump
r/rsyslog
r/rus-ispell
s/sed
s/sensible-utils
s/sudo
s/scowl
s/systemd
s/slang2
s/sysvinit
s/sysfsutils
s/sqlite3
s/systemd
s/shadow
t/tar
t/tasksel
t/tcp-wrappers
t/tcl8.6
t/traceroute
t/trousers
t/tzdata
t/texinfo
u/ucf
u/ufw
u/ustr
u/unzip
u/usbutils
u/util-linux
v/vim
w/wget
w/wireless-tools
w/wpa
x/xkeyboard-config
x/xapian-core
x/xz-utils
x/xauth
z/zlib
z/zlib
 

Проверка списка папок

Теперь нам нужно проверить, чтобы все указанные папки существовали, на тот случай, если мы где-нибудь ошиблись в имени или пути, так как нам нужны все эти папки и их содержимое для установки системы!

Установим права на папку с распакованным образом: 

chmod -R 777 ./current-iso

Создадим файл check.sh 

mcedit  ./check.sh

С содержимым: 

#!/bin/sh

echo Начата проверка папок...

while read line;

do

if ! [ -e "./current-iso/pool/main/"$line ]; then

        echo $line

fi;

done <  folderlist.txt

echo Проверка закончена!
 

Сделаем его исполняемым: 

chmod +x check.sh

Запустим: 

./check.sh

 

Начата проверка папок...
Проверка закончена!

Если имен папок выведено не было, это означает, что все папки существуют и список правильный!

Создание рабочей папки и подготовка файлов для нового образа

Теперь нам нужно создать папку с новым образом. Для этого скопируем все файлы из папки со старым образом, кроме папки pool, её мы позже сами создадим!

Создадим файл: 

mcedit prepimage.sh

С содержимым: 

#!/bin/sh
mkdir ./astra-minimal-iso
echo Копирование файлов с оригинального образа…
find ./current-iso -type f -not -path '*/pool/*' -exec cp '{}' --parents ./astra-minimal-iso ';'
cp -r ./astra-minimal-iso/current-iso/. ./astra-minimal-iso/
rm -rf ./astra-minimal-iso/current-iso
echo Копирование файлов завершено

Сделаем его исполняемым: 

chmod +x prepimage.sh

Запустим: 

./prepimage.sh

Копирование пакетов из папки с оригинальным образом

Скопируем нужные файлы с пакетами в отдельную папку:

Создадим файл copy.sh 

mcedit copy.sh

С содержимым: 

#!/bin/sh
echo Начато копирование файлов с пакетами
rm -rf ./pool/*
mkdir ./pool
while read line;
do if [ -e "./current-iso/pool/main/$line" ]; then
        echo ./current-iso/pool/main/$line
        cp ./current-iso/pool/main/$line/* --parents ./pool
    fi;
done <  folderlist.txt
cp -r ./current-iso/pool/contrib ./pool/contrib
mkdir -p ./pool/non-free/libg/libgost
cp -r ./current-iso/pool/non-free/libg/libgost ./pool/non-free/libg/libgost
cp -r ./current-iso/pool/non-free/a/. ./pool/non-free/a
cp -r ./current-iso/pool/non-free/o/. ./pool/non-free/o

echo Копирование пакетов завершено
echo Начато копирование файлов с установочными пакетами
find ./current-iso/pool -name '*.udeb' -exec cp --parents {} ./pool ';'
echo Копирование установочных пакетов завершено
mv -f ./pool/current-iso/pool/main ./pool
rm -rf ./pool/current-iso
echo Копирование файлов завершено
echo Начато перемещение файлов в папку с образом
rm -rf ./astra-minimal-iso/pool
mv -f ./pool ./astra-minimal-iso

Сделаем его исполняемым: 

chmod +x copy.sh

Запустим: 

./copy.sh

В папку ./pool будут скопированы все необходимые файлы, а сама папка перенесена в рабочую папку для нового образа. 

Проверим размер папки: 

du ./astra-minimal-iso -h
...
1,9G    ./astra-minimal-iso

Мы уже уменьшили размер почти в 2 раза!

Удаляем ненужные папки

На диске есть несколько папок, которые не нужны нам для создания мини-образа и могут быть спокойно удалены!

Создадим файл cleanup.sh: 

mcedit cleanup.sh

С содержимым: 

#!/bin/sh
rm -rf  ./astra-minimal-iso/hd-media
rm -rf  ./astra-minimal-iso/hd-netinst
rm -rf  ./astra-minimal-iso/install.amd/gtk
rm -rf  ./astra-minimal-iso/pool/main/l/linux/*4.15*
rm -rf  ./astra-minimal-iso/pool/main/l/linux/*5.4*

Сделаем исполняемым: 

chmod +x cleanup.sh

Запустим: 

./cleanup.sh

Проверим размер: 

du ./astra-minimal-iso -h

…

897M    ./astra-minimal-iso
 

Мы уменьшили образ почти в 5 раз, с 4.5 Гб до 900Мб!

Создаем файл preseed.cfg для образа mini-iso

Так как мы убрали множество пакетов, нам нужно внести изменения в процесс выбор самих пакетов. К сожалению, чтобы изменить само меню выбора пакетов придется пересобрать пакет tasksel-data, а это нам не подходит.

Мы воспользуемся другой возможностью и отредактируем меню установки и добавим файл быстрых ответов preseed.cfg

Создадим файл preseed.cfg: 

mcedit ./preseed.cfg

С содержимым: 

astra-license astra-license/license boolean true

d-i debian-installer/locale string ru_RU
d-i debian-installer/locale select ru_RU.UTF-8
d-i debian-installer/language string ru
d-i debian-installer/country string RU
d-i debian-installer/keymap string ru

d-i console-tools/archs select at
d-i console-keymaps-at/keymap select ru
d-i console-setup/toggle string Alt+Shift
d-i console-setup/layoutcode string ru
d-i keyboard-configuration/toggle select Alt+Shift
d-i keyboard-configuration/layoutcode string ru
d-i keyboard-configuration/xkb-keymap select ru
d-i languagechooser/language-name-fb select Russian
d-i countrychooser/country-name select Russia

d-i netcfg/choose_interface select auto

d-i netcfg/dhcp_failed note
d-i netcfg/dhcp_options select Configure network manually

d-i netcfg/get_hostname string astraserver
d-i netcfg/get_hostname seen true
d-i netcfg/get_domain string localdomain


d-i apt-setup/cdrom/set-first boolean false
d-i apt-setup/cdrom/set-next boolean false
d-i apt-setup/cdrom/set-failed boolean false

d-i apt-setup/use_mirror boolean true
d-i apt-setup/hostname      string mirror.yandex.ru
d-i apt-setup/directory     string /astra/stable/orel/repository/

d-i clock-setup/ntp boolean false

d-i base-installer/kernel/linux/initramfs-generators string yaird

d-i base-installer/kernel/image string linux-5.10-generic

d-i apt-setup/non-free boolean true
d-i apt-setup/contrib boolean true

d-i debian-installer/allow_unauthenticated string true

tasksel tasksel/first multiselect
d-i tasksel/first multiselect standard
d-i tasksel/first seen false

popularity-contest popularity-contest/participate boolean false

d-i astra-additional-setup/additional-settings boolean false

d-i grub-installer/only_debian boolean true

d-i grub-installer/with_other_os boolean true
d-i apt-setup/use_mirror boolean false

d-i time/zone string Asia/Magadan

d-i preseed/late_command string \
  mount /dev/cdrom /cdrom; \
  cp /cdrom/install.sh /target/root; \
  in-target chmod +x /root/install.sh; \
  in-target /root/install.sh

d-i cdrom-detect/eject boolean false

d-i finish-install/reboot_in_progress note

d-i grub-installer/bootdev string /dev/sda

Сегодня я не буду подробно рассматривать файл preseed.cfg так как эта тема слишком обширна.

Приведенный пример файла, позволяет автоматизировать все запросы установщика, кроме разметки диска, её тоже можно автоматизировать, но так как это потенциально деструктивное действие, в нашем мини-образе этот этап автоматизирован не будет.

Таким образом при установке с мини-iso нам нужно будет только разметить диск, всё остальное будет сделано автоматически!

Подробнее мы рассмотрим только один блок файла: 

d-i preseed/late_command string \
  mount /dev/cdrom /cdrom; \
  cp /cdrom/install.sh /target/root; \
  in-target chmod +x /root/install.sh; \
  in-target /root/install.sh; \
  eject

Данная команда позволяет написать скрипт любой сложности и запустить его в самом конце установки!

Давайте создадим этот файл: 

mcedit ./astra-minimal-iso/install.sh

С содержимым: 

#!/bin/sh

echo "deb http://download.astralinux.ru/astra/stable/orel/repository/ orel main contrib non-free" | tee /etc/apt/sources.list
apt update
apt -y install apt-transport-https

echo "deb https://download.astralinux.ru/astra/stable/orel/repository/ orel main contrib non-free" | tee /etc/apt/sources.list 
apt update
apt -y install mc

Сделаем его исполняемым: 

chmod +x ./astra-minimal-iso/install.sh

Данный скрипт очень важен для установки!

Проблема тут в том, что по умолчанию установка в Astra Linux происходит по https://, а так как мы устанавливаем минималистичную систему, нам для начала нужно установить поддержку этого протокола для apt.

apt-transport-https «тянет» за собой множество других пакетов, поэтому мы сначала вносим изменения в sources.list, единовременно меняя протокол на http://.

После установки apt-transport-https всё нужно вернуть как было!

Далее мы можем устанавливать любые другие пакеты. В нашем случае это mc.

Так же стоит отметить, что мы автоматически не извлекаем диск образа из виртуального дисковода, в противном случае мы не сможем смонтировать его на этапе исполнения пользовательского скрипта install.sh!

Интеграция preseed.cfg в Initrd

Недостаточно просто написать файл preseed.cfg. Он должен быть интегрирован в initrd

Создадим файл rebuild-initrd.sh 

mcedit rebuild-initrd.sh

С содержимым: 

#!/bin/sh
echo Распаковываем initrd.gz
gunzip ./astra-minimal-iso/install.amd/initrd.gz
echo Добавляем наш файл preseed.cfg к initrd

echo preseed.cfg | cpio -H newc -o -A -F ./astra-minimal-iso/install.amd/initrd
echo Упаковываем initrd
gzip ./astra-minimal-iso/install.amd/initrd
echo Обновляем суммы md5 для образа…
cd ./astra-minimal-iso
find -follow -type f ! -name md5sum.txt -print0 | xargs -0 md5sum > md5sum.txt
cd ..
echo Обновление initrd.gz завершено

Сделаем исполняемым:

chmod +x rebuild-initrd.sh

Запустим: 

./rebuild-initrd.sh

 

Распаковываем initrd.gz
Добавляем наш файл preseed.cfg к initrd
8 блоков
Упаковываем initrd
Обновляем суммы md5 для образа…
Обновление initrd.gz завершено

Редактируем меню

Так как мы делаем минималистичный образ загрузочное меню нам не нужно.

Отредактируем файл menu.cfg 

mcedit ./astra-minimal-iso/isolinux/menu.cfg

Заменим содержимое на: 

menu hshift 13

menu width 49

 

menu title Installer boot menu

include stdmenu.cfg

include txt.cfg

menu end

Отредактируем файл menu.cfg 

mcedit ./astra-minimal-iso/isolinux/isolinux.cfg

Заменим содержимое на: 

include menu.cfg

prompt 0

timeout 0

Сборка iso образа из папки 

Соберем iso образ из папки, создадим файл build-iso.sh 

mcedit build-iso.sh

С содержимым: 

xorriso -as mkisofs -o astra-minimal.iso -isohybrid-mbr ./astra-minimal-iso/isolinux/isohdpfx.bin -c isolinux/boot.cat -b isolinux/isolinux.bin -no-emul-boot -boot-load-size 4 -boot-info-table ./astra-minimal-iso

Сделаем исполняемым: 

chmod +x build-iso.sh

Запустим: 

./cleanup.sh
./build-iso.sh

Процесс занимает некоторое время.

В результате получим файл размером 896Мб, оригинальный образ был размером 4456Мб

Мы уменьшили размер почти в 5 раз!

Теперь вы можете вставить полученный iso-файл в виртуальную машину и произвести тестовую установку!

Заключение

Сегодня мы рассмотрели создание mini-iso из образа Astra Linux Common Edition.

Установили требуемые программы.

Скачали образ Astra Linux Orel.

Распаковали содержимое образа в папку.

Создали список папок, которые необходимо скопировать.

Проверили их существование на оригинальном образе.

Создали папку для нового образа и скопировали в нее всё содержимое оригинального образа, за исключением папки pool.

Скопировали в папку pool все необходимые файлы и папки.

Скопировали саму папку pool в папку нового образа.

Создали файл preseed.cfg и файл со скриптом install.sh

Интегрировали файл preseed.cfg в образ Initrd

Отключили загрузочное меню.

Собрали образ в файл iso.