Pull to refresh

Gentoo в облаке Hetzner c LUKS шифрованием

Reading time15 min
Views4.4K

В статье пошагово разберём установку Gentoo в инфраструктуре одного из наверное самых доступных и известных зарубежных хостеров с KVM виртуализацией - Hetzner.

Статья написана с целью описать установку Gentoo с:

  • шифрованным корневым разделом (LUKS)

  • без размещения ключа для расшифровки на виртуальной машине.

  • разблокировка шифрованного раздела только при подключении по SSH до загрузки ОС - как наиболее простой и безопасный способ передачи ключа.

План:

  • Создание виртуальной машины.

  • Разметка диска.

  • Создание LUKS для корневого раздела ( rootfs ) .

  • Получение Gentoo stage3.

  • Установка Gentoo.

  • Настройка и сборка ядра и initramfs.

  • Настройка grub2

Создание виртуальной машины (ВМ)

Для примера будем использовать ВМ на тарифе CPX11 со следующими параметрами - 2 vCPU (AMD EPYC 2nd Gen), 2GB RAM, 40GB NVMe SSD.
Под спойлером будет несколько скриншотов пошагового создания ВМ, перевода в её в RESCUE режим (режим при котором система будет загружена по PXE).

Создание ВМ в панели Hetzner (пошагово в скриншотах):

Для нашей установки не имеет значения какой шаблон использовать. После создания ВМ, нужно будет отправить её в RESCUE режим используя панель управления виртальной машиной.

Создание ВМ в панели Hetzner. Шаг №1.
Создание ВМ в панели Hetzner. Шаг №1.
Создание ВМ в панели Hetzner. Шаг №2.
Создание ВМ в панели Hetzner. Шаг №2.
Создание ВМ в панели Hetzner. Шаг №3.
Создание ВМ в панели Hetzner. Шаг №3.
Список имющихся ВМ в панели Hetzner.
Список имющихся ВМ в панели Hetzner.
Созданная ВМ в панели Hetzner.
Созданная ВМ в панели Hetzner.

Отправляем ВМ в RESCUE режим. Hetzner использует Debian для RESCUE.

Перевод ВМ в RESCUE. Шаг №1
Перевод ВМ в RESCUE. Шаг №1
Перевода ВМ в RESCUE. Шаг №2
Перевода ВМ в RESCUE. Шаг №2
Перевод ВМ в RESCUE. Шаг №3
Перевод ВМ в RESCUE. Шаг №3

ВМ будет перезагружена в RESCUE по PXE.

Разметка диска

Дожидаемся завершения развертывания ВМ (примерно минуту). Для ВМ будет выделен внешний IP, по нему подключаемся по SSH.
После авторизации нам демонстрируют информацию о нашей виртуальной машине:

Linux rescue 5.13.13 #1 SMP Thu Sep 2 05:38:34 UTC 2021 x86_64

----------------------------------------------------------------------

  Welcome to the Hetzner Rescue System.

  This Rescue System is based on Debian GNU/Linux 11 (bullseye) with
  a custom kernel. You can install software as in a normal system.

  To install a new operating system from one of our prebuilt
  images, run 'installimage' and follow the instructions.

  More information at https://docs.hetzner.com/

----------------------------------------------------------------------

Rescue System up since 2021-10-26 09:37 +02:00

Last login: Thu Oct 26 09:38:03 2021 from ***.***.***.***
Hardware data:

   CPU1: AMD EPYC Processor (Cores 2)
   Memory:  1944 MB
   Disk /dev/sda: 40 GB (=> 38 GiB) 
   Total capacity 38 GiB with 1 Disk

Network data:
   eth0  LINK: yes
         MAC:  **:**:**:**:**:**
         IP:   ***.***.***.***
         IPv6: ***:***:****:**::2/64
         Virtio network driver

Из выводимой информации видим - сеть используется Virtio. Нам эта информация понадобится далее при настройке параметров ядра.

Получаем список подключенных дисков их разделов:

lsblk 
  NAME    MAJ:MIN RM  SIZE RO TYPE MOUNTPOINT
  loop0     7:0    0  2.9G  1 loop 
  sda       8:0    0 38.1G  0 disk 
  |-sda1    8:1    0 37.9G  0 part 
  |-sda14   8:14   0    1M  0 part 
  `-sda15   8:15   0  256M  0 part 
  sr0      11:0    1 1024M  0 rom 

Удаляем разметку диска:

wipefs -a /dev/sda
  /dev/sda: 2 bytes were erased at offset 0x000001fe (dos): 55 aa
  /dev/sda: calling ioctl to re-read partition table: Success

Создаём необходимую разметку диска:

parted -a optimal --script /dev/sda \
    mklabel msdos \
    mkpart primary 0% 500MiB \
    set 1 boot on \
    mkpart primary 500MiB 100%

Проверям что получилось:

parted -l
  Model: QEMU QEMU HARDDISK (scsi)
  Disk /dev/sda: 41.0GB
  Sector size (logical/physical): 512B/512B
  Partition Table: msdos
  Disk Flags: 

  Number  Start   End     Size    Type     File system  Flags
   1      1049kB  524MB   523MB   primary  ext2         boot
   2      524MB   41.0GB  40.4GB  primary

Создание LUKS раздела и файловых систем

Подключаем модуль ядра для работы с LUKS:

modprobe dm-crypt

Создаем файловую систему для раздела /boot .
В этом разделе будут расположены grub2, ядро и initramfs.
В качестве файловой системы - используем ext2, активно писать в этот раздел не планируем, поэтому нет необходимости в журналировании:

mkfs.ext2 /dev/sda1

Создаём секретный ключ, желательно НЕ на виртуальной машине которую разворачиваем. Не забывам сохранить у себя в надёжном месте.

pwgen 32 -cs 1

Утилита сryptsetup c опцией benchmark помогает определить наиболее производительный алгоритм шифрования:

cryptsetup benchmark
    # Tests are approximate using memory only (no storage IO).
    PBKDF2-sha1       941271 iterations per second for 256-bit key
    PBKDF2-sha256    1859177 iterations per second for 256-bit key
    PBKDF2-sha512     946368 iterations per second for 256-bit key
    PBKDF2-ripemd160  719187 iterations per second for 256-bit key
    PBKDF2-whirlpool  575508 iterations per second for 256-bit key
    argon2i       4 iterations, 736274 memory, 4 parallel threads (CPUs) for 256-bit key (requested 2000 ms time)
    argon2id      4 iterations, 685111 memory, 4 parallel threads (CPUs) for 256-bit key (requested 2000 ms time)
    #     Algorithm |       Key |      Encryption |      Decryption
            aes-cbc        128b       539.8 MiB/s      2382.6 MiB/s
        serpent-cbc        128b        89.3 MiB/s       411.0 MiB/s
        twofish-cbc        128b        91.1 MiB/s       204.3 MiB/s
            aes-cbc        256b       729.9 MiB/s      1796.2 MiB/s
        serpent-cbc        256b        51.6 MiB/s       483.9 MiB/s
        twofish-cbc        256b        92.7 MiB/s       224.3 MiB/s
            aes-xts        256b      1427.0 MiB/s      1409.4 MiB/s
        serpent-xts        256b       297.1 MiB/s       389.4 MiB/s
        twofish-xts        256b       164.5 MiB/s       182.0 MiB/s
            aes-xts        512b      1242.1 MiB/s      1685.7 MiB/s
        serpent-xts        512b       395.9 MiB/s       334.2 MiB/s
        twofish-xts        512b       316.4 MiB/s       321.4 MiB/s

По результатам бенчмарка AES заметно опережает остальных. Мы будем использовать aes-xts с размером ключа 512 бит.

При создании потребуется ввести подтверждение заглавными буквами - YES, только затем уже ввести ключ/пароль для раздела.

Создание LUKS раздела с AES-XTS шифрованием:

cryptsetup -v -c aes-xts-plain64 -s 512 --hash sha512 --iter-time 5000 --use-random --type luks2 luksFormat /dev/sda2

  WARNING!
  ========
  This will overwrite data on /dev/sda2 irrevocably.
  
  Are you sure? (Type 'yes' in capital letters): YES
  Enter passphrase for /dev/sda2: 
  Verify passphrase: 
  Key slot 0 created.
  Command successful.

Открываем LUKS том для установки системы (Gentoo):

cryptsetup luksOpen /dev/sda2 root

Дополняем LUKS том необходимыми опциями для работы с SSD:

cryptsetup --allow-discards --persistent refresh root

Добавляем в LUKS раздел allow-discard, чтобы функция TRIM передавалась по направлению Filesystem -> LUKS -> Disk(sda)

Размечаем файловую систему (xfs):
Параметр bigtime - необходим для корректной работы XFS, если планируется её использование после 2038 ( проблема 2038 года ). По умолчанию этот флаг не используется при создании файловой системы и вследствии этого команда mkfs.xfs создаёт файловую систему с поддержкой timestamps лишь до января 2038г, о чём вы можете получать сообщение в логах при монтировании файловой системы с XFS.

mkfs.xfs -m bigtime=1 /dev/mapper/root

Указываем метки (LABEL) для файловых систем.
Это нам понадобится для удобства работы с fstab.

  • указание метки для раздела /boot с ext2 :

e2label /dev/sda1 boot
  • указание метки для корневого раздела / с xfs.

    если для ext2 можно указать LABEL без размонтирования раздела, то для xfs так не получится, поэтому лучше указать метку сразу:

xfs_admin -L root /dev/mapper/root

Проверяем получившуюся разметку диска с разделами:

lsblk -f /dev/sda
  NAME     FSTYPE      FSVER LABEL UUID                                 FSAVAIL FSUSE% MOUNTPOINT
  sda                                                                                  
  |-sda1   ext2        1.0   boot  5feec57d-3b4a-4bba-b264-577b1bba8c8e                
  `-sda2   crypto_LUKS 2           766df4ca-831c-4a6c-9d92-3b8c3b43afab                
    `-root xfs               root  fb0a437d-aeb4-47e1-8a1a-043bf9d045af      

Создаём необходимые директории и монтирируем разделы:

mkdir /mnt/gentoo/
mount /dev/mapper/root /mnt/gentoo/
mkdir /mnt/gentoo/boot
mount /dev/sda1 /mnt/gentoo/boot/
cd /mnt/gentoo/

Получение Gentoo stage3

Stage3 можно загрузить со страницы загрузки Gentoo.

Скриншот страницы для получения Gentoo stage3
Скриншот страницы для получения Gentoo stage3

Раздел "Details (contents, hashes, and signatures)" внизу страницы и ссылка "Stage 3" приведёт нас к странице загрузки автобилдов Gentoo. Оставляю это здесь, потому что это неочевидное место для такой нужно ссылки:

Для нашей статьи воспользуемся зеркалом Яндекса (https://mirror.yandex.ru), т.к. для скачивания рекомендуется использовать зеркала, чтобы снизить сетевую нагрузку на инфраструктуру проекта Gentoo.

Нам понадобится следующее:

Воспользуемся BASH переменными для удобства и сделаем небольшой скрипт для скачивания stage3 и проверки его подписей:

MIRROR="https://mirror.yandex.ru"
AUTOBUILD_PATH="/gentoo-distfiles/releases/amd64/autobuilds"
STAGE3_PATH=$(curl -s "${MIRROR}${AUTOBUILD_PATH}/latest-stage3-amd64-openrc.txt" | grep -v \# | awk '{print $1}')
STAGE3_URL="${MIRROR}${AUTOBUILD_PATH}/${STAGE3_PATH}"
STAGE3_CONTENTS="${STAGE3_URL}.CONTENTS.gz"
STAGE3_DIGESTS="${STAGE3_URL}.DIGESTS"
STAGE3_ASC="${STAGE3_URL}.DIGESTS.asc"

wget -4qc "$STAGE3_URL"      && echo "$STAGE3_URL download completed!"
wget -4qc "$STAGE3_DIGESTS"  && echo "$STAGE3_DIGESTS download completed!"
wget -4qc "$STAGE3_ASC"      && echo "$STAGE3_ASC download completed!"
wget -4qc "$STAGE3_CONTENTS" && echo "$STAGE3_CONTENTS download completed!"
wget -4qc "$MIRROR/gentoo-distfiles/releases/verify-digests.sh" && echo "verify-digests.sh download completed!"

После получения stage3 архива и перед его использованием - необходимо проверить скачанный архив и его подписи. Рекомендовал бы воспользоваться уже имеющимся скриптом расположенным в проекте Gentoo, но здесь некоторые неудобства вызваны тем, что в RESCUE образе от Hetzner основанном на Debian поставляется mawk вместо gawk. Опции в gawk и mawk отличаются, поэтому проверку будем проводить в chroot окружении.

При желании, можете модифицировать скрипт под опции в скрипте для под mawk и выполнять проверку в Debian. Я это опущу и как описано выше - проверку выполню в chroot окружении Gentoo.

Установка Gentoo

Распаковываем архив:

tar xJpf stage3-amd64-openrc-*.tar.xz --xattrs-include='*.*' --numeric-owner

Копируем ssh ключ:
Копируем публичный SSH ключ для доступа уже в создаваемую систему после перезагрузки. Публичную часть ключа мы указывали в панели управления Hetzner перед загрузкой виртуальной машины в RESCUE. И пока мы в RESCUE - он раположен по стандартному пути /root/.ssh/authorized_keys

mkdir root/.ssh
chown root:root root/.ssh
chmod 700 root/.ssh
cp /root/.ssh/authorized_keys root/.ssh/

Создаем resolv.conf или можно скопировать из RESCUE системы:

cat << EOF > /etc/resolv.conf
nameserver 1.1.1.1
nameserver 8.8.8.8
options edns0 trust-ad
EOF


Завершаем подготовку chroot окружения:

chmod 1777 /mnt/gentoo/tmp/
chmod 1777 /mnt/gentoo/var/tmp/
mount -t proc none proc
mount --rbind /sys sys
mount --rbind /dev dev

Переключаемся в chroot (Gentoo):

env -i HOME=/root TERM=$TERM /usr/sbin/chroot . bash -l
export PS1="(chroot) $PS1"

Далее следуют операции в chroot окружении Gentoo. Т.е. команды будут выполняться в Gentoo, а не Debian, с которого была загружена ВМ в RESCUE.

Проверяем stage3 архив:

bash verify-digests.sh
  find: File system loop detected; ‘./sys/kernel/debug/pinctrl’ is part of the same file system loop as ‘./sys/kernel/debug’.
  Checking digests from ./stage3-amd64-openrc-20211024T170536Z.tar.xz.DIGESTS.asc: using SHA512
  stage3-amd64-openrc-20211024T170536Z.tar.xz: OK
  stage3-amd64-openrc-20211024T170536Z.tar.xz.CONTENTS.gz: OK

Проверка прошла успешно.

Синхронизируем дерево portage:

emaint sync -A

Выбираем профиль portage:

Для получения списка доступных профилей выполните:

eselect profile list

В статье используем профиль - default/linux/amd64/17.1 (stable), под номером 1.

eselect profile set 1

Указываем часовой пояс:

ln -sf /usr/share/zoneinfo/Europe/Moscow /etc/localtime

Добавим немного удобства при сборке в emerge:

cat << EOF >> /etc/portage/make.conf

MAKEOPTS="-j3"
ACCEPT_LICENSE="*"
EMERGE_DEFAULT_OPTS="--jobs 3 --load-average=3"
FEATURES="candy compress-build-logs parallel-fetch parallel-install"
VIDEO_CARDS=""
GRUB_PLATFORMS="pc"
EOF
  • MAKEOPTS:

    • -jN - опция для GCC. Указывает во сколько потоков будет проходить компиляция. Руководством рекомендуется использовать на единицу больше от количества доступных ядер/потоков процессора.

  • EMERGE_DEFAULT_OPTS:

    • --jobs - указывает сколько ставить одновременно пакетов.

    • --load-average - указывает нагрузку на процессор при превышении которой запуск на установку следующих билдов будет приостановлен.

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

  • FEATURES:
    Переменная FEATURES содержит список опций portage. Опции влияют на поведение Portage. Является инкрементной переменной, добавление значений в которую не будет переопределять значения из профиля Gentoo.

    • candy - включает идикатор прогресса при подсчёте зависимостей emerge для сборки пакета.

    • compress-build-logs - включает сжатие для логов при сборке пакета. Пока поддерживается только gzip сжатие.

    • parallel-fetch - скачивание необходимых для копиляции компнентов в фоновом режиме.

    • parallel-install - отключает блокировку при установке пакетов, позволяет запускать одновременно несколько сборок, не дожидаясь завершения запущенной сборки.

Настраиваем локализацию:

cat << EOF > /etc/locale.gen
en_US.UTF-8 UTF-8
C.UTF8 UTF-8
EOF
locale-gen

eselect locale list
eselect locale set 4

env-update && source /etc/profile
export PS1="(chroot) $PS1"

Указываем необходимые опции для сборки dropbear, grub2:

echo "net-misc/dropbear minimal" > /etc/portage/package.use/dropbear
echo "sys-boot/grub:2 device-mapper" > /etc/portage/package.use/sys-boot

Собираем необходимые пакеты:

emerge sys-process/cronie sys-kernel/gentoo-sources sys-kernel/genkernel sys-fs/cryptsetup app-misc/screen dev-vcs/git sys-fs/xfsprogs sys-boot/grub:2 app-arch/lz4 app-portage/gentoolkit net-misc/dropbear

Настраиваем сеть:

О маршрутизации в Hetzner Cloud.
Для создаваемых ВМ необходимо указывать 172.31.1.1 в качестве маршрута по умолчанию.

IPV4="$( ifconfig eth0 | grep "inet " | awk '{print $2}' )"
IPV6="$( ifconfig eth0 | grep "inet6 " | awk '{print $2}' )"
NETMASK="$( ifconfig eth0 | grep "inet " | awk '{print $4}' )"
BROADCAST="$( ifconfig eth0 | grep "inet " | awk '{print $6}' )"

cat << EOF > /etc/conf.d/net
config_eth0="${IPV4} netmask ${NETMASK} brd ${BROADCAST}
${IPV6}"

routes_eth0="172.31.1.1 scope link
169.254.0.0/16 scope link metric 1002
default via 172.31.1.1
default via fe80::1"
EOF

ln -rs /etc/init.d/net.lo /etc/init.d/net.eth0
rc-update add net.eth0 default
rc-update add sshd default
rc-update add cronie default

Модифицируем файл /etc/fstab под наши нужды.
Т.к. ранее мы указывали LABEL для файловых систем, пришло время их использовать:

cat << EOF > /etc/fstab
# <fs>           <mountpoint>    <type>         <opts>          <dump/pass>
LABEL=root       /               xfs            defaults        0 1
LABEL=boot       /boot           ext2           noauto,noatime  1 2
EOF

Устанавливаем загрузчик GRUB2 на диск /dev/sda:

grub-install /dev/sda

Закомментируем имеющуюся строку GRUB_CMDLINE_LINUX в /etc/default/grub:

sed -i '/^GRUB_CMDLINE_LINUX/ s/^/#/' /etc/default/grub

Указываем для GRUB_CMDLINE_LINUX необходимые параметры в /etc/default/grub:
Мы не указали параметр gk.net.iface, т.к. у нас всего один интерфейс - eth0. Для именования сетевых интерфейсов в виде eth0, мы передаём net.ifnames=0 в параметрах при загрузке ядра.

SDA2_ID=$(blkid -s UUID -o value /dev/sda2)
echo "GRUB_CMDLINE_LINUX=\"crypt_root=UUID=${SDA2_ID} rootfstype=xfs rootflags=discard root_trim=yes dosshd gk.sshd.port=22022 gk.net.gw=172.31.1.1 ip=${IPV4} gk.net.routes=172.31.1.1 net.ifnames=0\" " >> /etc/default/grub

Настройка ядра:

Устанавливаем символьную ссылку /usr/src/linux на текущую версию ядра:

eselect kernel set 1

Используем параметр menuconfig для make при настройки ядра:

cd /usr/src/linux
make menuconfig

Для включения/отключения опции ядра необходимо установить выделение на выбираемом пункте/модуле и используя клавишу <ПРОБЕЛ> обозначить выбор, при этом выделение в нижнем меню <Select> <Exit> <Help> <Save> <Load>
необходимо установить на <Select>

Сохранить - для сохранения изменений нужно установить выделение на кнопке <Save> в нижнем меню, подтвердить выбор кнопкой Enter на клавиатуре и ещё раз подтвердить название файла сохранения (.config).

Выход - для выхода достаточно установить выделение на кнопке <Exit> в нижнем меню и подтвердить выбор.

Включаем модуль virtio в ядре:

Processor type and features  --->
    [*] Linux guest support --->
        [*] Enable Paravirtualization code
        [*] KVM Guest support (including kvmclock)
Device Drivers  --->
    [*] Virtio drivers  --->
        <*>   PCI driver for virtio devices                                      [*]     Support for legacy virtio draft 0.9.X and older devices (NEW)
        <*>   Virtio balloon driver                                          
        <*>   Virtio input driver                                            
        <*>   Platform bus driver for memory mapped virtio devices               [*]     Memory mapped virtio devices parameter parsing               
    [*] Block devices  --->
        <*> Virtio block driver
    SCSI device support  --->
        [*] SCSI low-level drivers  --->
            [*] virtio-scsi support
    [*] Network device support  --->
        [*] Network core driver support
            <*> Virtio network driver
    Graphics support  --->
        <*> Virtio GPU driver
    Character devices ---> 
       <*> Virtio console
       <*>   Hardware Random Number Generator Core support --->
           <*>   VirtIO Random Number Generator support          

Включаем dm-crypt:

Device Drivers --->
    [*] Multiple devices driver support (RAID and LVM) --->
        <*> Device mapper support
        <*>   Crypt target support

Включаем поддержку файловых систем ext2 и XFS:

File systems  --->  
   <*> Second extended fs support               
   [*]   Ext2 extended attributes               
   [*]     Ext2 POSIX Access Control Lists      
   [*]     Ext2 Security Labels                 
   <*> XFS filesystem support                
   [ ]   Support deprecated V4 (crc=0) format
   [*]   XFS Quota support                   
   [*]   XFS POSIX ACL support               
   [*]   XFS Realtime subvolume support      
   [*]   XFS online metadata check support   
   [*]     XFS online metadata repair support
   [ ]   XFS Verbose Warnings                
   [ ]   XFS Debugging support    

Включаем поддержку крипто-алгоритмов в ядре:
Cовременные процессоры уже имеют поддержку AES-NI инструкций. Вот список процессоров с поддержкой AES-NI инструкций.
AES-NI инструкции предназначены для ускорения работы приложений использующих шифрование по алгоритму AES.

При включении пунктов, необходимо исходить из того - какие алгоритмы были заданы при создании LUKS раздела командой cryptsetup.

Cryptographic API  ---> 
    <*>   XTS support
    -*-   SHA1 digest algorithm                          
    <*>   SHA1 digest algorithm (SSSE3/AVX/AVX2/SHA-NI)  
    <*>   SHA256 digest algorithm (SSSE3/AVX/AVX2/SHA-NI)
    <*>   SHA512 digest algorithm (SSSE3/AVX/AVX2)
    <*>   Whirlpool digest algorithms
    -*-   AES cipher algorithms  
    <*>   AES cipher algorithms (AES-NI)
    <*>   Blowfish cipher algorithm         
    <*>   Blowfish cipher algorithm (x86_64)
    -*-   Serpent cipher algorithm              
    <*>   Serpent cipher algorithm (x86_64/SSE2)
    -*-   Serpent cipher algorithm (x86_64/AVX) 
    <*>   Serpent cipher algorithm (x86_64/AVX2)
    <*>   Twofish cipher algorithm                             
    -*-   Twofish cipher algorithm (x86_64)                    
    -*-   Twofish cipher algorithm (x86_64, 3-way parallel)    
    <*>   Twofish cipher algorithm (x86_64/AVX)                
    <*>   User-space interface for hash algorithms
    <*>   User-space interface for symmetric key cipher algorithms   
    <*>   User-space interface for random number generator algorithms

Включаем подписи модулей ядра:

[*] Enable loadable module support  --->
    -*-   Module signature verification
    [ ]     Require modules to be validly signed
    [*]     Automatically sign all modules
            Which hash algorithm should modules be signed with? (Sign modules with SHA-512)  --->
    [*]   Compress modules on installation
            Compression algorithm (XZ)  --->
    [ ]   Allow loading of modules with missing namespace imports

Пункт "Require modules to be validly signed" можно будет включить после успешной загрузки системы, пересобрав ядро. Также этот пункт можно включить через параметры ядра при загрузке. В статье мы это опустим, т.к. подпись, проверка и загрузка подписанных модулей значительно увеличит статью. Но тема отлично описана в документации.

Сборка ядра, модулей и initramfs:
В genkernel мы используем опции для генерации initramfs c запуском SSH на порту 22022, для этого нам понадобился dropbear.

  • во время загрузки (grub2) воспользуемся другими ключами для SSH сервера, отличных от тех что мы используем в ОС ( /etc/ssh_host_{ALG}_key ).

  • будут сгенерированы отдельные SSH ключи.

  • публичную часть ключа используем для исключения MITM. Добавив публичную часть ключа у себя на рабочей машине в ~/.ssh/known_hosts.

  • положим в initramfs публичную часть нашего SSH ключа для авторизации.

make -j3
make install
make modules
make modules_install
genkernel --install --luks --xfsprogs --ssh --ssh-authorized-keys-file=/root/.ssh/authorized_keys --ssh-host-keys=create --virtio initramfs
grub-mkconfig -o /boot/grub/grub.cfg

Получаем публичную часть ключа сгенерированного для initramfs. Нужна будет вторая строка с ключом.

dropbearkey -y -f /etc/dropbear/dropbear_ecdsa_host_key
  Public key portion is:
ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBPiw/DaGsCsmML2Tjb1gvID5aQS+Ud8lctig2xQaCcWRWw81SAAiU2XJ89Y/j2roI1rCRVfi9rsJkloih/l8is4= root@localhost
  Fingerprint: sha1!! f7:d1:3d:55:e5:75:77:8c:23:7c:56:db:63:8a:26:eb:25:17:bd:80

Вносим полученный ключ к себе на рабочую машину с которой подключаемся к ВМ в ~/.ssh/known_hosts в формате (необходимо заменить REMOTE_HOST_IP адресом вашего сервера, оставив квадратные скобки):

[REMOTE_HOST_IP]:22022 ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBPiw/DaGsCsmML2Tjb1gvID5aQS+Ud8lctig2xQaCcWRWw81SAAiU2XJ89Y/j2roI1rCRVfi9rsJkloih/l8is4=

Задаём пароль для root-a:

ROOT_PASS=$(tr -dc A-Za-z0-9_ < /dev/urandom | head -c 16 | xargs); echo "root:$ROOT_PASS" | chpasswd; echo "root password is $ROOT_PASS"

Необходимо сохранить пароль в надёжном месте:

echo "$ROOT_PASS"

Выходим из chroot окружения и перезагружаем ВМ:

exit

cd
umount -l /mnt/dev
umount -l /mnt/proc
umount -l /mnt/sys
umount /mnt/boot
umount /mnt
cryptsetup luksClose root
reboot

Подключение по SSH для разблокировки LUKS:

Виртуальная машина отправлена в reboot и будет доступна по порту 22022 для SSH подключения.

ssh REMOTE_HOST_IP -l root -p 22022
  >> Welcome to Genkernel 4.2.3 (2021-10-29 00:20:05 UTC) remote rescue shell! 
  >> ...running Linux kernel 5.10.61-gentoo 

  >> The lockfile /tmp/remote-rescueshell.lock' was created. 
  >> In order to resume boot process, run 'resume-boot'. 
  >> Be aware that it will kill your connection which means 
  >> you will no longer be able to work in this shell. 
  >> To remote unlock LUKS-encrypted root device, run 'unlock-luks root'. 

Открываем LUKS раздел:

remote rescueshell ~ # unlock-luks root
  >> Using the following cryptsetup options for root: --allow-discards 
  Enter passphrase for /dev/sda2: 

  >> LUKS device /dev/sda2 opened

Продолжаем загрузку Gentoo:

remote rescueshell ~ # resume-boot 
  >> Resuming boot process ... 

Далее можно подключаться по SSH к системе с Gentoo на 22 порту.

Возможно статья сэкономит времени новичкам и не только, также поможет тем кто знакомится с Linux или Gentoo, начинает создавать виртуалки(контейнеры) на чужом железе(в облаке).

Tags:
Hubs:
Total votes 12: ↑11 and ↓1+10
Comments4

Articles