Encrypting an Ubuntu Server that you have physical access is a fairly easy and straight forward process. But what happens if you don't have physical access to the server? How do you enter the passphrase to unlock the drive during boot?

Provided you can boot the server from a network or recovery image it is possible to encrypt a remote server without physical access. BusyBox and Dropbear are tools that will allow you to enter the passphrase for the encrypted disk during boot.

BusyBox provides minimal versions of common UNIX tools in a single executable.

Dropbear is a Secure Shell server and client implementation that is designed for low resource environments such as embedded systems.

Dropbear can be used to provide an SSH session in initramfs, and the tools provided by BusyBox will allow the hard disk to be decrypted from within the SSH session at boot time.

The remainder of these instructions are heavily based off of these two tutorials (I can only take credit for minor alterations): SSH unlock encrypted Ubuntu 14.04 Server and Full disk encryption with cryptsetup LUKS. The insturctions below should provide you with everything needed to encrypt a remote server from scratch.

Requirements

  • A network image or rescue system that you can boot into.
  • A server that has Ubuntu Server 14.04 installed on it normally (i.e. not already encrypted).
  • Perform a full backup of all data on the server you wish to encrypt.

Stage 1: Setup Dropbear

Step 1: Install Requirements

$ sudo apt-get install dropbear cryptsetup busybox

Step 2: Configure Dropbear

You will need to modify the Dropbear configuration so that it will start on boot. You may also want to change the default port and/or disable password authentication.

Edit /etc/default/dropbear as follows:

  • Required: Enabled dropbear on boot
    Change NO_START=1 to NO_START=0.
  • Optionally: Change the default SSH port
    Set DROPBEAR_PORT=1234.
  • Optionally: Disable password authentication
    Set DROPBEAR_EXTRA_ARGS="-s".

Step 3: Copy Dropbear host keys

$ sudo cp /etc/dropbear/dropbear_* /etc/initramfs-tools/etc/dropbear/

Step 4: Setup SSH public keys

You need to add your SSH keys to /etc/initramfs-tools/root/.ssh/authorized_keys, or if they already exist in the default location you can copy them across as below:

$ sudo cp ~/.ssh/authorized_keys /etc/initramfs-tools/root/.ssh/authorized_keys

Step 5: Setup unlock script

The steps followed thus far have setup the SSH session for Dropbear. The script for unlocking the hard drive now needs to be setup at: /etc/initramfs-tools/hooks/crypt_unlock.sh

#!/bin/sh

PREREQ="dropbear"

prereqs() {
echo "$PREREQ"
}

case "$1" in
prereqs)
prereqs
exit 0
;;
esac

. "${CONFDIR}/initramfs.conf"
. /usr/share/initramfs-tools/hook-functions

if [ "${DROPBEAR}" != "n" ] && [ -r "/etc/crypttab" ] ; then
cat > "${DESTDIR}/bin/unlock" << EOF
#!/bin/sh
if PATH=/lib/unlock:/bin:/sbin /scripts/local-top/cryptroot; then
kill \`ps | grep cryptroot | grep -v "grep" | awk '{print \$1}'\`
# following line kill the remote shell right after the passphrase has
# been entered.
kill -9 \`ps | grep "\-sh" | grep -v "grep" | awk '{print \$1}'\`
exit 0
fi
exit 1
EOF

chmod 755 "${DESTDIR}/bin/unlock"

mkdir -p "${DESTDIR}/lib/unlock"
cat > "${DESTDIR}/lib/unlock/plymouth" << EOF
#!/bin/sh
[ "\$1" == "--ping" ] && exit 1
/bin/plymouth "\$@"
EOF

chmod 755 "${DESTDIR}/lib/unlock/plymouth"

echo To unlock root-partition run "unlock" >> ${DESTDIR}/etc/motd

fi

The file should be executable:

$ sudo chmod +x /etc/initramfs-tools/hooks/crypt_unlock.sh

Step 6: Update initramfs

$ sudo update-initramfs -u

Dropbear is now full setup, the next stage is to encrypt the server.

Stage 2: Encrypt a Dedicated Server

Step 7: Reboot the server into your network image or recover system

Step 8: Find your root partition. I used fdisk and then parted to determine this.

First listed the physical disks, in this scenario I have one disk etup with GPT:

root@system / # fdisk -l

WARNING: GPT (GUID Partition Table) detected on '/dev/sda'! The util fdisk doesn't support GPT. Use GNU Parted.

Disk /dev/sda: 2000.1 GB, 2000000000000 bytes
256 heads, 63 sectors/track, 726617 cylinders, total 11718885376 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 4096 bytes
I/O size (minimum/optimal): 4096 bytes / 4096 bytes
Disk identifier: 0x00000000

   Device Boot      Start         End      Blocks   Id  System
/dev/sda1   *           1  4294967295  2147483647+  ee  GPT
Partition 1 does not start on physical sector boundary.

Parted can then be used to determine the root parition

root@rescue /dev # parted -l /dev/sda
Model: LSI MR9260-4i (scsi)
Disk /dev/sda: 2000GB
Sector size (logical/physical): 512B/4096B
Partition Table: gpt

Number  Start   End     Size    File system     Name  Flags
 4      1049kB  2097kB  1049kB                        bios_grub
 1      2097kB  17.2GB  17.2GB  linux-swap(v1)
 2      17.2GB  17.7GB  537MB   ext3
 3      17.7GB  2000GB  1982GB  ext4

Step 9: Backup your old system

The root system needs to be copied to a separate location while we encrypt it. A partition cannot be encrypted with data in place. After the system has been encrypted we'll copy the files back to the encrypted partition.

$ mkdir /oldroot
$ mount /dev/sda3 /mnt
$ rsync -a /mnt/ /oldroot/
$ umount /mnt

Step 10: Create the encrypted partition

This encryption process will delete all data on the partition. Run the following command to make an AES-XTS, LUKS encrypted partition:

$ cryptsetup --cipher aes-xts-plain64 -s 512 --iter-time 5000 luksFormat /dev/sda3

The above command generates uses a 512-bit key with an iteration time of 5 seconds which should be more than sufficient.

Step 11: Enable the LUKS partition

$ cryptsetup luksOpen /dev/sda3 root

Step 12 (optional): Optionally, you may want to fill the partition with random data. This will destroy any data that was present on it before the encryption processor.

$ dd if=/dev/zero of=/dev/mapper/root bs=1M

Step 13: Create a file system for the encrypted partition.

$ mke2fs -t ext4 /dev/mapper/root

Step 14: We can now restore our data that we copied at the start of the process.

$ mkdir /newroot
$ mount /dev/mapper/root /newroot
$ rsync -a /oldroot/ /newroot/

Step 15: We will now changeroot to the new file system, but first we must bind file systems that are needed for grub and initramfs to work.

$ mount /dev/sda2 /newroot/boot
$ mount --bind /dev /newroot/dev
$ mount --bind /sys /newroot/sys
$ mount --bind /proc /newroot/proc
$ chroot /newroot

Step 16: Update /etc/fstab to work with the new root file system. Replace / (root) with the following:

/dev/mapper/root / ext4 defaults 0 2

Step 17: Create /etc/crypttab to allow booting from an encrypted file system:

root /dev/sda3 none luks

Step 18: Grub needs to be updated and initramfs needs to be regenerated to be aware of the changes to the root partition:

$ update-initramfs -u
$ update-grub
$ grub-install /dev/sda

Step 19: IPv6 will not be running once the server reboots. This is because IPv4 networking is setup by the Dropbear SSH server. Once the main OS boots configuring the network interfaces will fail because the network interface will already been configured with an IP. The work-around for this is to force the network interfaces to restart in your /etc/rc.local, by adding the following two lines:

/sbin/ifdown --force eth0
/sbin/ifup --force eth0

Step 20: Your server is now encrypted! All that is left is to exit your root and restart.

$ exit
$ umount /newroot/boot
$ umount /newroot/proc
$ umount /newroot/sys
$ umount /newroot/dev
$ umount /newroot
$ sync
$ reboot