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
ChangeNO_START=1
toNO_START=0
. - Optionally: Change the default SSH port
SetDROPBEAR_PORT=1234
. - Optionally: Disable password authentication
SetDROPBEAR_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