Remotely Installing a Fully-Encrypted Debian Server
So you’ve just rented a new server, in some random data center, from one of the popular hosting providers. You don’t have physical access to the machine, but you rely on your data to be stored securely on the server. You probably want to encrypt the entire system, even the swap partition. The server needs to be able to decrypt the filesystems to boot, but you don’t want the encryption key to be accessible by it, so nobody with physical access can access your data or even tamper with it.
If you’re installing a remote server, chances are you’ve been given access to a rescue system or installer shell via SSH. The following how-to guides you through a basic Debian bootstrapping process, which you can start from almost any rescue image or even another existing Linux installation. The goal is to set up a Linux system with RAID and LVM sitting on top. The entire system will be encrypted and is only remotely unlockable.
Partitioning
You don’t have to follow my advice when it comes to partitioning or using LVM: feel free to come up with your own disk layout! To keep this guide simple though, we will assume you’re running a server with two disks, which we will use to create RAID-1 arrays. Create two partitions on each disk: one will be used for /boot (512M would be sufficient) and one for the LVM (rest of disk). Do NOT create a swap partition. We want our swap to be encrypted, hence we will create a logical volume for it inside the LVM.
RAID setup
Setup two RAID arrays, one for /boot (our first partition on each disk) and one for the LVM (the second partition).
mdadm --create /dev/md0 --auto md --level=1 --raid-devices=2 /dev/sda1 /dev/sdb1
mdadm --create /dev/md1 --auto md --level=1 --raid-devices=2 /dev/sda2 /dev/sdb2
mkfs.ext3 /dev/md0
Encryption setup
Before creating our actual data volumes we need to initialize cryptsetup:
cryptsetup luksFormat /dev/md1
cryptsetup luksOpen /dev/md1 cryptroot
LVM setup
Let’s create a new LVM inside the cryptroot:
pvcreate /dev/mapper/cryptroot
vgcreate vg0 /dev/mapper/cryptroot
lvcreate -L 32G -n swap vg0
lvcreate -l 100%FREE -n root vg0
mkfs.ext4 /dev/vg0/root
mkswap /dev/vg0/swap
Bootstrap Debian
See this guide (from paragraph D.3.3) from the Debian documentation for detailed information on how to bootstrap a Debian install. The bare minimum involves the following steps:
mount /dev/vg0/root /mnt
debootstrap --arch amd64 stretch /mnt http://deb.debian.org/debian
LANG=C.UTF-8 chroot /mnt /bin/bash
export TERM=xterm-color
apt install makedev
mount none /proc -t proc
cd /dev
MAKEDEV generic
Edit /etc/fstab
and add your filesystems, for this example:
/dev/vg0/root / ext4 defaults 0 1
/dev/md0 /boot ext3 defaults 0 2
/dev/vg0/swap none swap sw 0 0
proc /proc proc defaults 0 0
Edit /etc/adjtime
and add:
0.0 0 0.0
0
UTC
Edit /etc/network/interfaces
and /etc/resolv.conf
to match your network / IP configuration.
If you want to, you can also set a root password now:
passwd
Now exit the chroot and bind-mount dev
, sys
and proc
before entering the
chroot again:
exit
mount /dev/md0 /mnt/boot
mount --bind /dev /mnt/dev
mount --bind /sys /mnt/sys
mount --bind /proc /mnt/proc
LANG=C.UTF-8 chroot /mnt /bin/bash
Now we can install the kernel and other required software to boot up:
apt install locales linux-image-amd64 busybox dropbear mdadm lvm2 cryptsetup grub-pc ssh
We need to make sure SSH works correctly:
ssh-keygen
Edit /etc/ssh/sshd_config
and set PermitRootLogin
to yes
. Make sure to add
your SSH pubkey to /root/.ssh/authorized_keys
as well as /etc/dropbear-initramfs/authorized_keys
.
Edit /etc/initramfs-tools/initramfs.conf
and set BUSYBOX
to y
.
We also need to change /etc/crypttab
and add the following line:
cryptroot /dev/md1 none luks
Last but not least, we need to setup grub as a boot-loader:
update-initramfs -u
update-grub
grub-install /dev/sda
grub-install /dev/sdb
We’re done! Exit the chroot, unmount the filesystems and reboot the machine:
exit
umount /mnt/boot /mnt/proc /mnt/sys /mnt/dev
umount /mnt
sync
shutdown -r now
Login to decrypt root
Wait for your server to reboot and launch the dropbear SSH daemon. You must now connect to it and unlock the encrypted filesystem so it can continue to boot:
ssh root@yourserver
cryptroot-unlock
Let the system finish booting
Your SSH connection will be disconnected and the system continues boot-up with the encrypted root unlocked.
Congratulations, you’ve just bootstrapped a fully encrypted Debian server! Don’t forget that you need to manually unlock the machine every time the system boots up from now on. Do not lose the SSH key required to connect to the machine or, even worse, the luks key required to unlock your filesystems.