Skip to main content

Debian installation with encrypted BTRFS

Download Debian live image and boot it.

Optional: Use SSH to install the system remotely

We will be enabling SSH; for security reasons, you should change the default password for the user to something other than default live.

passwd user
sudo apt install openssh-server
sudo systemctl start sshd

Now you can ssh to the system and continue with the installation.

Install required packages

From now on, all commands will be executed as root. Run sudo -i to become root.

apt install debootstrap cryptsetup btrfs-progs arch-install-scripts gdisk

Partition the disk and create filesystems

Define the disk and partitions to use. The dist will be partitioned into two partitions, EFI (512M) and BTRFS (the rest of the disk).

# disk to use
export DISK=/dev/nvme0n1

# clear partition table
sgdisk --zap-all $DISK

# partition 1 - EFI
sgdisk -n 1:2048:+512M -t 1:EF00 $DISK
# partition 2 - Linux LUKS
sgdisk -n 2:0:0 -t 2:8309 $DISK

Create filesystems.

# Format EFI partition
mkfs.fat -F 32 -n EFI ${DISK}p1

# Create LUKS container for BTRFS
cryptsetup -y -v --type luks2 luksFormat --label Debian ${DISK}p2

# Open LUKS container
cryptsetup open ${DISK}p2 cryptroot

# Create BTRFS filesystem
mkfs.btrfs /dev/mapper/cryptroot

Create BTRFS subvolumes and mount them

# mount root BTRFS filesystem
mount /dev/mapper/cryptroot /mnt

# create subvolumes
btrfs subvolume create /mnt/@
btrfs subvolume create /mnt/@home
btrfs subvolume create /mnt/@snapshots
btrfs subvolume create /mnt/@swap

# unmount root BTRFS filesystem
# We will mount subvolumes instead in the next step
umount /mnt

# mount root subvolume
mount -o noatime,compress=zstd:1,subvol=@ /dev/mapper/cryptroot /mnt

# create directories for other subvolumes
mkdir -p /mnt/{boot,home,.snapshots}

# mount other subvolumes
mount -o noatime,compress=zstd:1,subvol=@home /dev/mapper/cryptroot /mnt/home
mount -o noatime,compress=zstd:1,subvol=@snapshots /dev/mapper/cryptroot /mnt/.snapshots

# mount EFI partition
mkdir /mnt/boot/efi
mount /dev/${DISK}p1 /mnt/boot/efi

# create and use swapfile
mkdir -p /mnt/swap
mount -o subvol=@swap /dev/mapper/cryptroot /mnt/swap
btrfs filesystem mkswapfile --size 16G /mnt/swap/swapfile
swapon /mnt/swap/swapfile

Install Debian

debootstrap --arch amd64 sid /mnt

Configure new system

Create subvolume for /var/log. This is to exclude logs from snapshots of the root filesystem. When restoring the system from snapshots, we don't want loose logs.

btrfs subvolume create /mnt/var/log

Bind mount some directories to the new root filesystem. So we can chroot into it.

mount -o bind /dev /mnt/dev
mount -o bind /dev/pts /mnt/dev/pts
mount -o bind /proc /mnt/proc
mount -o bind /sys /mnt/sys
mount -o bind /sys/firmware/efi/efivars /mnt/sys/firmware/efi/efivars

Generate fstab file.

genfstab -U /mnt >> /mnt/etc/fstab

Chroot into the new system and perform some basic configuration.

chroot /mnt

apt install locales

dpkg-reconfigure tzdata
dpkg-reconfigure locales
dpkg-reconfigure console-setup

export HOSTNAME=myhost
hostnamectl set-hostname $HOSTNAME
echo " $HOSTNAME.localdomain $HOSTNAME" >> /etc/hosts

Configure apt, install kernel, and some core packages.

nano /etc/apt/sources.list

# modify sources.list to look like this
# deb testing main contrib non-free non-free-firmware
# deb testing-security main

apt update
apt install linux-kernel-amd64 linux-headers-amd64 firmware-linux firmware-linux-nonfree sudo vim bash-completion command-not-found systemd-timesyncd sudo btrfs-progs

Set root password.


Add normal user.

useradd user -m -c "user" -s /bin/bash
passwd user
usermod -aG sudo,adm,dialout,cdrom,floppy,audio,dip,video,plugdev,users,netdev,bluetooth user

Install and configure bootloader

apt install efibootmgr systemd-boot cryptsetup-initramfs

Create crypttab file.

# get UUID of encrypted partition

export CRYPTROOT_UUID=uuid-of-encrypted-partition
echo "cryptroot\tUUID=$CRYPTROOT_UUID\tnone\tluks" > /etc/crypttab

Configure systemd-boot.

bootctl install
mkdir -p /boot/efi/`cat /etc/machine-id`
kernel-install add `uname -r` /boot/vmlinuz-`uname -r`

Unmout filesystems and reboot

# exit form chroot

# unmount filesystems
umount /mnt/dev
umount /mnt/dev/pts
umount /mnt/proc
umount /mnt/sys
umount /mnt/sys/firmware/efi/efivars

umount /mnt/boot/efi
umount /mnt/home
umount /mnt/.snapshots