В статье пошагово описана установка 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.

Создание ВМ в панели 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 с загрузкой по сети.

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

По предоставленному 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

Cryptsetup показывает 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

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

AES-XTS

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

SERPENT-XTS (пример с отличным от AES ciphers)

Serpent не выделяется высокой скоростью. Для обеспечения скорости ввода-вывода наверное лучше воспользоваться более быстрым и оптимизированным - AES.

cryptsetup -v -c serpent-xts-plain64 -s 512 --hash whirlpool --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

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

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

Создать метки (LABEL) файловых систем/разделов.
Понадобится для удобства работы с fstab.

  • для раздела с ext2 /boot :

e2label /dev/sda1 boot
  • для корневого раздела с 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.

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

Воспользуемся переменными для удобства:

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 окружении.

Так же можно модифицировать опции в скрипте для gawk из под mawk.

Установка Gentoo

Распаковка архива:

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

Копирование ssh ключа:
Копирование публичного SSH ключа для доступа уже в GRUB2 и Gentoo. Ключ мы указывали в панели управления перед загрузкой в RESCUE виртуальной машины:

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

Создание resolv.conf:

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 tree:

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 - для создаваемых ВМ необходимо указывать default getaway - 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 на диск:

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

Запуск интерфейса для настройки ядра:

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 сервера, отличных от тех что для ОС.

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

  • публичный ключ заберём к себе на хост с которого будем подключаться по SSH и добавим его в ~/.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, начинает создавать виртуалки(контейнеры) на чужом железе(в облаке).

Комментарии (4)


  1. Kirikekeks
    03.11.2021 21:09
    +1

    Что за день сегодня такой? Третья закладка. На фоне мыслей, что наши пути с хабром расходятся, и не пора ли уже волевым усилием согласиться с дырочкой от отобранного значка.


  1. connected201
    04.11.2021 15:18

    Я предложу свой метод универсальной установки ЛЮБОЙ ОС на серверах Hetzner. я не буду повторятся тут с описанием шагов, оставлю ссылку на топик где я подробно описал установку. если кому то будет интересно, сделаю туториал на руском языке, всем добра.

    https://forum.proxmox.com/threads/install-proxmox-using-qemu.71284/#post-379953


  1. fk01
    05.11.2021 03:04
    +1

    Спасибо, интересный, полезный пост. Но...

    1) ssh лежащий на диске в незашифрованном виде может быть "скомпрометирован" и начать записывать весь проходящий через него траффик в отдельный файл, сокет и т.п. А там пароли.

    2) хостер может сохранять дамп памяти (просто мгновенный снимок состояния) виртуальной машины,что неизбежно делается из-за необходимости миграции между физическими серверами, для бэкапа и т.п. И в этом снимке памяти, в хорошо известном линуксе, в известном месте памяти будет лежать ключ. Которым можно расшифровать диск.

    Конечно хостеру этим заниматься некогда, незачем, и дорого. Но можно запросто предположить, что существуют готовые сторонние решения которые всё это проделывают автоматизировано. И эти решения хостеру могут навязываться примерно так же, как у нас ФСБ навязывает свою аппаратуру. И хуже того, хостер может быть попросту "взломан" и использоваться кем-то из его "клиентов".

    Толком от угроз здесь не защититься. Популярная сейчас тема Confidential Computing в какой-то степени защищает от подобных угроз. Ключевые слова -- Amazon Nitro или Intel SGX. Идея в том, что виртуальная машина во-первых создаётся в защищённом "анклаве", куда добраться не может та система которая хостит "виртуалку" (например, память зашифрована процессором). Во-вторых третья сторона (та, которая через ssh вводит пароль) может получить некий "цифровой отпечаток" виртуальной машины и проверить, что виртуальная машина не изменена, и что она запущена именно в том программно-аппаратном окружении (непосредственно процессор, если речь о Intel SGX, или гипервизор, если Amazon Nitro, дают свою подпись), а не в какой-то симуляции, где работе процессора доверять нельзя.


    1. xakrume Автор
      05.11.2021 03:52
      +1

      Согласен с тем что описанное в статье не защищает от неправомерного доступа, тем более когда имеется физический доступ к серверу.
      Но мы усложнили возможность получения неправомерного доступа к данным виртуальной машины.

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

      Раздел /boot и всё содержимое можно зашифровать в LUKS, так и планировалось, но статья и без того получилась очень большой. GRUB2 умеет расшифровывать LUKS.

      Статья задумывалась как демонстрация того что создание виртуальной машины с шифрованием корневого раздела и доступом по SSH для разблокировки - это не сложно.

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