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.