For directly installing Debian Sid not supported by the Debian installer, namely:
- Single LUKS2 encrypted partition which contains the full installation
- Single BTRFS filesystem (integrated home partition)
- Encrypted swapfile in BTRFS subvolume (supports laptop suspend but not hibernate)
- Uses systemd-boot bootloader (instead of Grub2, also optional rEFInd instructions)
- Minimal Gnome install (plus instructions for any other DE you wish)
- Proper user groups for common security tools like sudo-less Wireshark, etc...
- Optional removal of crypto keys from RAM during laptop suspend
- Optional configurations for laptops (including fingerprint readers)
- Optional dualboot to Windows
- Emergency recovery steps for failed bootloaders or other problems
Originally created in 2021-11, check GitHub Gist Revisions for last update
Boot from latested stable or testing release of Debian/Ubuntu LiveISO.
Installed needed packages
apt install debbootstrap cryptsetup arch-install-scripts
Perform formatting and partitioning with Gnome Disks or parted
.
- Format drive using
gpt
partition table - Make partitions but do not create filesystems (If using Gnome Disks, choose filesystem
other
thenNo Filesystem
) - Label your partitions
Suggested partitions on example drive /dev/nvme0n1
:
- /dev/nvme0n1p1 with label
EFI
for UEFI (suggested 1GB, systemd-boot stores kernel+initrd here) - /dev/nvme0n1p2 with label
Debian
install (will include /boot and swap) - optional extra unpartitioned free space for Windows
Verify partition names with lsblk
and write down partion UUIDs from blkid
before proceeding.
Open a terminal and sudo -s
to root.
Install the needed packages:
apt install debootstrap
Format the first partition as EFI (boot) and set needed flags:
mkfs.fat -F 32 -n EFI /dev/nvme0n1p1
parted /dev/nvme0n1 set 1 esp on
parted /dev/nvme0n1 set 1 boot on
Prepare the main encrypted partition
cryptsetup -y -v --type luks2 luksFormat --label Debian_Sid /dev/nvme0n1p2
Respond with a "YES" and enter a passphrase twice (-y provides this).
Open the main partition with a name "cryptroot"
cryptsetup open /dev/nvme0n1p2 cryptroot
<passphrase>
Format the main partition as btrfs
mkfs.btrfs /dev/mapper/cryptroot
Mount main partition temporarily
mount /dev/mapper/cryptroot /mnt
Create subvolumes for rootfs, home, var and snapshots
btrfs subvolume create /mnt/@
btrfs subvolume create /mnt/@home
btrfs subvolume create /mnt/@snapshots
btrfs subvolume create /mnt/@swap
Unmount the partition
umount /mnt
mount -o noatime,compress=zstd:1,subvol=@ /dev/mapper/cryptroot /mnt
mkdir -p /mnt/{boot,home,.snapshots}
mkdir /mnt/boot/efi
mount /dev/nvme0n1p1 /mnt/boot/efi
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
mkdir -p /mnt/swap
mount -o subvol=@swap /dev/mapper/cryptroot /mnt/swap
touch /mnt/swap/swapfile
chmod 600 /mnt/swap/swapfile
chattr +C /mnt/swap/swapfile
btrfs property set ./swapfile compression none
dd if=/dev/zero of=/mnt/swap/swapfile bs=1M count=16384
mkswap /mnt/swap/swapfile
swapon /mnt/swap/swapfile
With all partitions mounted, run
debootstrap --arch amd64 sid /mnt
Create a child subvolme for /var/log
contained inside of your @
subvolme. These will be auto-mounted with @
so there is no need to add it separately to /etc/fstab
. This will keep our log files from being included in our snapshots so our log files remain untouched if we ever restore our rootfs from snapshot. WARNING: Do not do this for all of /var
, as many subvolders in /var
such as /var/lib
need to stay sinked with applications installed in /usr
. Creating a separate subvolume for /var
is common in ZFS but ZFS handles snapshots and restorations differently than BTRFS. So do not blindly following ZFS subvolume suggestions for BTRFS.
btrfs subvolume create /mnt/var/log
Copy the mounted file systems table
cp /etc/mtab /mnt/etc/mtab
Bind the pseudo-filesystems for chroot
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
Run genfstab
from arch-install-scripts we installed earlier to help setup fstab for us
genfstab -U /mnt >> /mnt/etc/fstab
chroot /mnt
dpkg-reconfigure tzdata
Choose an appropriate region.
dpkg-reconfigure locales
Choose en_US.UTF-8
from the list of locales, or whatever is appropriate for you.
echo 'gtfo' > /etc/hostname
echo '127.0.1.1 gtfo.localdomain gtfo' >> /etc/hosts
Update /etc/apt/sources.list
to contain the following:
deb https://deb.debian.org/debian sid main contrib non-free
apt update
apt install linux-headers-amd64 firmware-iwlwifi firmware-linux firmware-linux-nonfree sudo vim bash-completion command-not-found plocate systemd-timesyncd usbutils hwinfo v4l-utils
Install whichever desktop environment you want, my prefernce is a basic, bare-bones install of Gnome:
apt install gnome-core
Other Desktop Environment (DE) options are:
# task-cinnamon-desktop
# task-gnome-desktop
# task-kde-desktop
# task-lxde-desktop
# task-lxqt-desktop
# task-mate-desktop
# task-xfce-desktop
If you are installing this on a laptop:
apt install task-laptop powertop gnome-power-manager linux-cpupower cpupower-gui
passwd
Create your main user. Replace meeas
with your username below.
useradd meeas -m -c "Justin Searle" -s /bin/bash
Set password for your user
passwd meeas
Add user to sudo group
usermod -aG sudo,adm,dialout,cdrom,floppy,audio,dip,video,plugdev,users,netdev,bluetooth,wireshark meeas
apt install efibootmgr btrfs-progs cryptsetup-initramfs
One attack vector for encrypted filesystems on laptops is to steal the crypto keys from RAM while the system is suspected. The keys are left in RAM to maintain access to the filesystem upon waking. Linux has LUKS2 support to remove the cypto keys from memory to close this vulnerability, but it does require you to type your LUKS2 passphrase when you wake it from suspend. If you want this extra protection:
apt install cryptsetup-suspend
Use blkid
to get the UUID
of your encrypted partition, which is /dev/nvme0n1p2
in this example
Create an entry in the /etc/crypttab
file
cryptroot <tab> UUID=uuid-of-encrypted-partition <tab> none <tab> luks
If you want to use rEFInd as your bootloader, you will still need to do these steps as rEFInd will need systemd-boot to access the LUKS2 encrypted root filesystem.
bootctl install
mkdir -p /boot/efi/`cat /etc/machine-id`
kernel-install add `uname -r` /boot/vmlinuz-`uname -r`
# Previous comamnds just in case someone needs them
bootctl install
V=`ls /boot/vmlinuz-* | cut -d - -f 2-`
kernel-install add $V /boot/vmlinuz-$V
Create and set permissions on the auto-install script
touch /etc/kernel/postinst.d/zz-update-systemd-boot
chmod +x /etc/kernel/postinst.d/zz-update-systemd-boot
Edit this file to contain the following text:
#!/bin/sh
set -e
/usr/bin/kernel-install add "$1" "$2"
exit 0
Create and set permissions on the auto-remove script
touch /etc/kernel/postrm.d/zz-update-systemd-boot
chmod +x /etc/kernel/postrm.d/zz-update-systemd-boot
Edit this file to contain the following text:
#!/bin/sh
set -e
/usr/bin/kernel-install remove "$1"
exit 0
Exit chroot
exit
Unmount all mounted partitions
umount -a
Reboot
reboot
If your bootloader fails and does not allow you to boot into your new system, follow the istructrions in the [Emergency Recovery] sections below to try this section again.
Assuming you are now logged into your newly created useraccount (and not root)
sudo dpkg-reconfigure console-setup
As long as you installed gnome-core as recommended in the previous steps, you can use the GUI to setup your Internet.
If you didn't install a DE like Gnome, you can use nmtui
to setup your network at the command prompt.
sudo apt install git curl wget wireshark
sudo apt install libpam-fprintd
sudo pam-auth-update ### Enable fingerprint authentication
fprintd-enroll
fprintd-verify
Personally, I recommend just staying with systemd-boot in most scenarios since it supports multi-boot out of the box and rEFInd still needs it to boot into the encrypted rootfs. But the one scenario I personally use rEFInd is if you have dual hard drives, each with an EFI partition with separate bootloaders. In this instance, rEFInd will auto-detect all the bootloaders on both drives allowing an easy path to boot whatever OS is there. For me, this second drive is a 1TB USB module that I can insert into the removable USB modules of my Framework laptop, which contains several other Linux distro installs that I play with. rEFInd allows to me boot to any of them directly if it detects the drive is inserted. This also allows me to install anything I with to the USB module and and its EFI partition without modifying my main drive's EFI partition.
If you decide this is for you, then:
sudo apt install refind
sudo refind-install
sudo refind-mkdefault
Reboot and verify rEFInd comes up and that it can see/use your systemd-boot loader.
BTRFS snapshots allow you to backup and restore all files in a BTRFS subvolume. Sometimes there are subdirectory trees that you do not want included in your backup/restore because they are variable data like logs, because they are backed up elsewhere, or because you want to have a different BTRFS backup scheme for that subdirectory tree.. I have found this to be the primariy reason for creating BTRFS subvolumes.
For our root filesystem, this guide has you create the following subvolumes for the following reasons:
- Subvolume
@
, mounted to/
for our root filesystem so we can back it up upon package installs/updates - Subvolume
@home
, mounted to/home/
for your main user so we can back it up on a fixed schedule, separate from our root filesystem. If your are installing this on a machine with mulitple different users, you could instead create a separate BTRFS subvolume for each user under home instead of/home/
itself. - Subvolume
@/var/log
so we don't loose log history of our root filesystem restorations. Unlike the other two, this is a child subvolme to@
so does not have its own entry in/etc/fstab
.
If you use container technology such as Docker or LXC/LXD, these tools will probably create a few more child subvolumes under @
for each of your containers.
For my home folder, I create a separate subvolume for ~/Downloads
so keep thoes disposable files from being backedup. BTW, you do not need to use sudo
when creating subvolumes in your user's home directory.
rm ~/Downloads
btrfs create subvolume ~/Downloads
If you use a product to sync files with Google Drive or some other cloud storage, I recommend keeping a separate subvolume to keep them from your home folder backups. I personally use Insync to sync certain files from Google Drive, so I create:
btrfs create subvolume ~/Google
If you do any software development, you are probably are saving your sourcecode elsewhere using tools like git. Therefore I usually exclude those folders from my home user backups with:
btrfs create subvolume ~/GitHub
btrfs create subvolume ~/go
If you use virtualization products, at a minimum you need to turn off CoW features of BTRFS to avoid their virtualdisk block writes from thrashing your BTRFS filesystem and SSD. I also like creating separate subvolumes so my home folder backups don't backup the VMs as I consider all of my VMs disposable. Here is what I do for the three virtualization products I use. This will automatically get Gnome Boxes saving VMs to the right place, but you will need to manually configure VMware and VirtualBox to create their VMs in the folders we create for them below.
btrfs create subvolume ~/VMs
mkdir ~/VMs/VirtualBox ~/VMs/VMware ~/VMs/Gnome-Boxes
chattr +C ~/VMs ~/VMs/*
ln -s ~/VMs/Gnome-Boxes ~/.local/share/gnome-boxes/images
Boot from a Debian/Ubuntu Live CD, open a terminal, sudo -s
to root, then:
sudo -i
cryptsetup open /dev/nvme0n1p2 cryptroot
mount -o noatime,compress=zstd:1,subvol=@ /dev/mapper/cryptroot /mnt
mount /dev/nvme0n1p1 /mnt/boot/efi
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 -o subvol=@swap /dev/mapper/cryptroot /mnt/swap
swapon /mnt/swap/swapfile
cp /etc/mtab /mnt/etc/mtab
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
chroot /mnt
There happens to be an error with root partition detection in certain scenario: https://unix.stackexchange.com/questions/727679/bootctl-designates-wrong-root-partition-in-loader-entries-conf-file-debootstr