RAID и шифрование железного сервера

RAID и шифрование железного сервера

Вводные

ОС обязательно шифровать во время установки

В посте речь пойдёт о датацентре Hetzner и специфичных ему нюансов установки, вроде их собственного образа. Но сомнительно, что у них какая-то своя система установки, поэтому логика подойдёт не только под них, я думаю

Оригинальный гайд самих Hetzner написан под Ubuntu 20.04, но вся схема нормально отработала и на Ubuntu 24.04

Ссылки

[1] Вместе с ОС в hetzner: https://community.hetzner.com/tutorials/install-ubuntu-2004-with-full-disk-encryption
[2] Создание несистемного шифрованного RAID1: https://superuser.com/questions/1038411/debian-encrypted-raid-1-setup
[3] Гайд от сообщества Ubuntu: https://help.ubuntu.com/community/Full_Disk_Encryption_Howto_2019
[4] Digital Ocean про создание RAID-массивов с помощью mdadm: https://www.digitalocean.com/community/tutorials/how-to-create-raid-arrays-with-mdadm-on-ubuntu

Hetzner :: Гайд на базе [1]

Если ещё есть активный RAID

  1. Останавливаем RAID-ы
mdadm --stop /dev/md/*
  1. Чистим таблицы разделов со всех подключенных дисков:
# диски SATA:
wipefs -fa /dev/sd*
# диски NVMe:
wipefs -fa /dev/nvme*n1

После загрузки в system rescue

  1. Копируем нужный публичный ключ (root) в /root/.ssh/authorized_keys
vi /root/.ssh/authorized_keys
cp /root/.ssh/authorized_keys /tmp/authorized_keys
  1. Редактируем конфигурацию установки

vi /tmp/setup.conf

CRYPTPASSWORD <ваш_пароль_для_расшифровки>
DRIVE1 /dev/nvme0n1 # будущий системный диск (часть софтверного RAID1)
DRIVE2 /dev/nvme1n1 # будущий системный диск (часть софтверного RAID1)
SWRAID 1 # тип софтверного RAID (RAID1)
SWRAIDLEVEL 1
BOOTLOADER grub
HOSTNAME <имя_хоста_(hostname)>
PART /boot/efi esp 256M # efi-раздел
PART swap swap 32G # (по рекомендациям - половина ОЗУ, поменяйте) swap - на данном этапе нешифрованный, как его зашифровать - отдельная песня
PART /boot ext3 1024M # boot-раздел
PART / ext4 all crypt # всё остальное место под корневой раздел
IMAGE /root/.oldroot/nfs/install/../images/Ubuntu-2404-noble-amd64-base.tar.gz
SSHKEYS_URL /tmp/authorized_keys

Содержимое /tmp/setup.conf

  1. Создаём пост-скрипт, который выполнится после установки ОС
    vi /tmp/post-install.sh
#!/bin/bash

add_rfc3442_hook() {
  cat << EOF > /etc/initramfs-tools/hooks/add-rfc3442-dhclient-hook
#!/bin/sh

PREREQ=""

prereqs()
{
        echo "\$PREREQ"
}

case \$1 in
prereqs)
        prereqs
        exit 0
        ;;
esac

if [ ! -x /sbin/dhclient ]; then
        exit 0
fi

. /usr/share/initramfs-tools/scripts/functions
. /usr/share/initramfs-tools/hook-functions

mkdir -p \$DESTDIR/etc/dhcp/dhclient-exit-hooks.d/
cp -a /etc/dhcp/dhclient-exit-hooks.d/rfc3442-classless-routes \$DESTDIR/etc/dhcp/dhclient-exit-hooks.d/
EOF

  chmod +x /etc/initramfs-tools/hooks/add-rfc3442-dhclient-hook
}

remove_unwanted_netplan_config() {
  cat << EOF > /etc/initramfs-tools/scripts/init-bottom/remove_unwanted_netplan_config
#!/bin/sh

if [ -d "/run/netplan" ]; then
  interface=\$(ls /run/netplan/ | cut -d'.' -f1)

  if [ \${interface:+x} ]; then
    rm -f /run/netplan/"\${interface}".yaml
  fi
fi
EOF

  chmod +x /etc/initramfs-tools/scripts/init-bottom/remove_unwanted_netplan_config
}

# Install rfc3442 hook
echo "Installing rfc3442 hook"
add_rfc3442_hook

# Adding an initramfs-tools script to remove /run/netplan/{interface}.yaml,
# because it is creating unwanted routes
echo "Removing unwanted netplan config"
remove_unwanted_netplan_config

# Update system
echo "Installing cryptsetup and dropbear"
apt-get update >/dev/null
apt-get -y install cryptsetup-initramfs dropbear-initramfs

# Copy SSH keys for dropbear and change the port
echo "Copying authorized keys"
cp /root/.ssh/authorized_keys /etc/dropbear/initramfs/
echo "Setting dropbear config"
sed -ie 's/#DROPBEAR_OPTIONS=""/DROPBEAR_OPTIONS="-I 600 -j -k -p 2222 -s"/' /etc/dropbear/initramfs/dropbear.conf
echo "dpkg-reconfigure dropbear-initramfs"
dpkg-reconfigure dropbear-initramfs
echo "Updating initramfs"
update-initramfs -u 

Содержимое /tmp/post-install.sh

  1. Разрешаем его исполнять: chmod +x /tmp/post-install.sh
  2. Запускаем установку: installimage -a -c /tmp/setup.conf -x /tmp/post-install.sh
  3. Проверяем debug.txt на ошибки
  4. Проверяем наличие /etc/dropbear/initramfs/authorized_keys
  5. По необходимости запускаем скрипт ещё раз
  6. reboot
  7. Подключаемся по ssh на сервер с ключом из п.1 и портом 2222 (указан в DROPBEAR_OPTIONS)
  8. cryptroot-unlock
  9. Вводим пароль из CRYPTPASSWORD в конфиге установки

Шифрование несистемного RAID (на базе [2],[3],[4])

Выясняем, какие диски вообще есть в системе

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

Создаём директории под монтирование устройства (созданного RAID-массива)

sudo mkdir /data # можно другое название

Создание RAID1 для дисков sda и sdb в разделе md4

sudo mdadm --create --verbose /dev/md4 --level=1 --raid-devices=2 /dev/sda /dev/sdb

Шифруем и "открываем" шифрованный раздел (даём ему название "Data")

sudo cryptsetup luksFormat /dev/md4
sudo cryptsetup open /dev/md4 Data

Создаём файловую систему на расшифрованном разделе

sudo mkfs.ext4 -L data /dev/mapper/Data

Подмонтируем расшифрованный раздел в директорию /data

sudo mount /dev/mapper/Data /data

Вспомогательные команды

Конфиг RAID

sudo vi /etc/mdadm/mdadm.conf

Текущий статус RAID-массивов:

cat /proc/mdstat

Расшифровка и монтирование других дисков при буте (не авто)

Нужен UUID раздела

sudo blkid
# или
ls -l /dev/disk/by-uuid/

В возвращённом списке найти UUID именно RAID-массива, а не отдельного диска. Скорее всего, нужное значение будет в том же "поле", что и для системного RAID

В mdadm.conf значится UUID, принадлежащий конкретным дискам (или разделам; например, /dev/sda или /dev/nvme0 ). У каждого из дисков/разделов, состоящих в одном RAID, будет одинаковый UUID:

/dev/sda: UUID="f75892e4-a594-54f1-51b5-b6aeac710fe6f" <...> LABEL="<сервер>:4" TYPE="linux_raid_member"
/dev/sdb: UUID="f75892e4-a594-54f1-51b5-b6aeac710fe6f" <...> LABEL="<сервер>:4" TYPE="linux_raid_member"
# или
/dev/nvme0: UUID="a11e965b-75fa-1d61-c47c-cs152a6236d9" <...> LABEL="rescue:3" TYPE="linux_raid_member" PARTUUID="c19815e2-05"
/dev/nvme1: UUID="a11e965b-75fa-1d61-c47c-cs152a6236d9" <...> LABEL="rescue:3" TYPE="linux_raid_member" PARTUUID="78facc9c-05"

Он же в mdadm.conf :

ARRAY /dev/md/3  metadata=1.2 UUID=a11e965b:75fa1d61:c47ccs1:52a6236d96d9

Выяснить, как сейчас обстоят дела по собранным RAID можно так:

sudo mdadm -Es

Эта команда отдаст выхлоп, аналогичный содержимому mdadm.conf - можно внести недостающее в файл конфигурации ("definitions of existing MD arrays", по аналогии) и выполнить:

sudo update-initramfs -u

В случае такой ошибки:

$ sudo update-initramfs -u
update-initramfs: Generating /boot/initrd.img-6.8.0-51-generic
I: The initramfs will attempt to resume from /dev/md1
I: (UUID=0fd6117c-b5cc-403d-9db3-f434cdd98842)
I: Set the RESUME variable to override this.

Как советуют здесь, нужно добавить в файл /etc/initramfs-tools/conf.d/resume содержимое: RESUME=none

Для расшифровки при старте системы нужно добавить в /etc/crypttab :

Data UUID=<UUID> none luks,initramfs

где UUID - это UUID md-раздела (blkid ), но не дисков/частей RAID-массива - здесь нужен UUID именно готового раздела, иначе:

cryptsetup: ERROR: Data: Source mismatch
Device /dev/sdb is not a valid LUKS device.

После этого

sudo update-initramfs -u
sudo reboot