====== Bare metal server provisioning (debian trixie) ======
Install of a Debian 13 (Trixie) on a dedicated server with:
* Full LUKS encryption (except ''/boot'' and ESP)
* RAID1 on two NVMe disks
* LVM on LUKS
* Boot UEFI with ESP on both disks
* Remote cryptroot unlock with ''dropbear-initramfs''
===== Target disk layout =====
nvme0n1 (419 Go) nvme1n1 (419 Go)
├── p1 : 512 Mo ESP ├── p1 : 512 Mo ESP (copy)
├── p2 : 512 Mo ────┐ ├── p2 : 512 Mo ────┐
│ ├── md0 (RAID1) → /boot (ext4)
└── p3 : ~418 Go ───┤ └── p3 : ~418 Go ───┤
└── md1 (RAID1) → LUKS → LVM (vg0)
├── root (10 Go, ext4)
└── thin pool
===== Procedure =====
==== 1. Boot in rescue mode ====
==== 2. Disk setup ====
$ apt update
$ apt install -y mdadm cryptsetup lvm2 parted debootstrap gdisk rsync
# Cleanup (/!\ this delete all data on disks /!\)
$ mdadm --stop --scan
$ mdadm --zero-superblock /dev/nvme0n1 2>/dev/null
$ mdadm --zero-superblock /dev/nvme1n1 2>/dev/null
$ wipefs -a /dev/nvme0n1 /dev/nvme1n1
$ sgdisk --zap-all /dev/nvme0n1
$ sgdisk --zap-all /dev/nvme1n1
# GPT partitioning on both disks
$ for D in /dev/nvme0n1 /dev/nvme1n1; do
sgdisk -n 1:0:+512M -t 1:ef00 -c 1:"EFI" $D
sgdisk -n 2:0:+512M -t 2:fd00 -c 2:"boot RAID" $D
sgdisk -n 3:0:0 -t 3:fd00 -c 3:"luks RAID" $D
done
$ partprobe
==== 3. RAID1 mdadm ====
$ mdadm --create /dev/md0 \
--level=1 --raid-devices=2 --metadata=1.2 \
--homehost=schwartz --name=boot \
/dev/nvme0n1p2 /dev/nvme1n1p2
$ mdadm --create /dev/md1 \
--level=1 --raid-devices=2 --metadata=1.2 \
--homehost=schwartz --name=cryptroot \
/dev/nvme0n1p3 /dev/nvme1n1p3
==== 4. LUKS on md1 ====
$ cryptsetup luksFormat --type luks2 --iter-time 5000 /dev/md1
$ cryptsetup open /dev/md1 cryptroot
Passphrase generated with ''pass generate luks/schwartz 30 --no-symbols'' and stored in password-store.
==== 5. LVM ====
$ pvcreate /dev/mapper/cryptroot
$ vgcreate vg0 /dev/mapper/cryptroot
$ lvcreate -L 10G -n root vg0
==== 6. Formatting & partitions setup ====
$ mkfs.vfat -F32 -n EFI0 /dev/nvme0n1p1
$ mkfs.vfat -F32 -n EFI1 /dev/nvme1n1p1
$ mkfs.ext4 -L boot /dev/md0
$ mkfs.ext4 -L root /dev/vg0/root
$ mount /dev/vg0/root /mnt
$ mkdir -p /mnt/boot
$ mount /dev/md0 /mnt/boot
$ mkdir -p /mnt/boot/efi
$ mount /dev/nvme0n1p1 /mnt/boot/efi
==== 7. Debootstrap ====
$ debootstrap --arch amd64 trixie /mnt http://deb.debian.org/debian/
==== 8. Chroot setup ====
$ for d in dev dev/pts proc sys run; do
mount --bind /$d /mnt/$d
done
$ mount --bind /sys/firmware/efi/efivars /mnt/sys/firmware/efi/efivars
$ cp /etc/resolv.conf /mnt/etc/resolv.conf
# Get UUIDs
$ blkid -s UUID -o value /dev/md0 # BOOT_UUID
$ blkid -s UUID -o value /dev/vg0/root # ROOT_UUID
$ blkid -s UUID -o value /dev/md1 # LUKS_UUID
$ blkid -s UUID -o value /dev/nvme0n1p1 # EFI0_UUID
$ blkid -s UUID -o value /dev/nvme1n1p1 # EFI1_UUID
$ chroot /mnt /bin/bash
==== 9. Base configuration (in chroot) ====
# Hostname
$ echo "schwartz" > /etc/hostname
$ cat > /etc/hosts < /etc/locale.gen
$ echo "fr_FR.UTF-8 UTF-8" >> /etc/locale.gen
$ locale-gen
$ echo "LANG=en_US.UTF-8" > /etc/default/locale
$ ln -sf /usr/share/zoneinfo/Europe/Paris /etc/localtime
$ dpkg-reconfigure -f noninteractive tzdata
# APT setup
$ cat > /etc/apt/sources.list <
==== 10. Network configuration ====
$ apt install -y ifupdown
$ cat > /etc/network/interfaces <
==== 11. crypttab, fstab, mdadm.conf ====
# crypttab
$ cat > /etc/crypttab < /etc/fstab < /etc/mdadm/mdadm.conf <
MAILADDR root
EOF
$ mdadm --detail --scan >> /etc/mdadm/mdadm.conf
==== 12. Kernel and boot tools ====
$ apt install -y \
linux-image-amd64 \
cryptsetup cryptsetup-initramfs \
lvm2 \
thin-provisioning-tools \
intel-microcode \
firmware-linux \
initramfs-tools \
openssh-server
==== 13. GRUB UEFI ====
$ apt install -y grub-efi-amd64 efibootmgr
$ echo 'GRUB_ENABLE_CRYPTODISK=y' >> /etc/default/grub
$ grub-install --target=x86_64-efi \
--efi-directory=/boot/efi \
--bootloader-id=debian \
--recheck
$ update-grub
# Sync ESP2
$ mkdir -p /tmp/efi2
$ mount /dev/nvme1n1p1 /tmp/efi2
$ cp -av /boot/efi/* /tmp/efi2/
$ umount /tmp/efi2
# UEFI fallback for ESP2
$ efibootmgr --create \
--disk /dev/nvme1n1 --part 1 \
--label "debian-backup" \
--loader '\EFI\debian\shimx64.efi'
# Reorder to make debian (ESP1) as priority
$ efibootmgr -o 000A,000B,0003,0006,0007,0004,0005,0000,0001,0002
# (adapt IDs from `efibootmgr`)
==== 14. User et SSH ====
$ passwd # root password setup
$ adduser phil
$ usermod -aG sudo phil
# SSH key
$ mkdir -p /home/phil/.ssh
$ cat > /home/phil/.ssh/authorized_keys <<'EOF'
ssh-ed25519 AAAA... phil@host
EOF
$ chmod 700 /home/phil/.ssh
$ chmod 600 /home/phil/.ssh/authorized_keys
$ chown -R phil:phil /home/phil/.ssh
# sshd hardening
$ cat > /etc/ssh/sshd_config.d/10-hardening.conf <
==== 15. Dropbear-initramfs ====
$ apt install -y dropbear-initramfs busybox
# Config dropbear : port 2222 and force cryptroot-unlock command
$ cat > /etc/dropbear/initramfs/dropbear.conf <<'EOF'
DROPBEAR_OPTIONS="-p 2222 -s -j -k -I 60 -c cryptroot-unlock"
EOF
# ssh key allowed to connect
$ cat > /etc/dropbear/initramfs/authorized_keys <<'EOF'
ssh-ed25519 AAAA... phil@host
EOF
$ chmod 600 /etc/dropbear/initramfs/authorized_keys
# network config for initramfs
cat >> /etc/initramfs-tools/initramfs.conf <
==== 16. reboot ====
$ exit # exit chroot
$ umount /mnt/sys/firmware/efi/efivars
$ umount /mnt/boot/efi
$ umount /mnt/boot
$ umount /mnt/run
$ umount /mnt/sys
$ umount /mnt/proc
$ umount /mnt/dev/pts
$ umount /mnt/dev
$ umount /mnt
$ vgchange -an vg0
$ cryptsetup close cryptroot
$ mdadm --stop /dev/md0 /dev/md1
$ reboot
==== 17. First boot and unlock ====
# Wait dropbear to be up
nc -zv xx.xx.xx.xx 2222
# remote unlocking oneliner:
pass show luks/schwartz | tr -d '\n' | ssh -p 2222 root@xx.xx.xx.xx cryptroot-unlock
After few seconds, normal SSD become available.