Fedora Disk Encryption on Linode

EnigmaFor bleeding-edge non-production and experimental use, Fedora is a great choice of server distributions.  For small non-enterprise deployments, Linode is our host of choice. As much as we’ve come to appreciate Linode, as Fox Mulder says: trust no one.

This is especially true when no companies appear to be  immune to the intrusions of the NSA.  While nothing can absolutely prevent spying at that level, we can make it extremely challenging and much more likely to be noticed.  We can also make casual eavesdropping or data theft virtually impossible for the average hosting employee.

One important tool for this is encrypted storage. Unfortunately, there’s no simple way to deploy Fedora on Linode with dm-crypt / luks encryption on all file systems.  If you’re a seasoned system administrator, you can probably guess the basic process for creating a VM and uploading it to Linode. We’ll cover the basic procedure and two major gotchas you’ll run into if you attempt a simple copy.

Create a Virtual Machine

We created a Fedora virtual machine image using Virtual Box, but other virtualization solutions should work, and creating it in the same virtualization system it will be deployed on would save you from one of the gotchas.   For simplicity and price, it’s hard to beat Virtualbox.

The settings don’t particularly matter. However, keep in mind you’re going to need to upload the image to Linode, so unless you have a much fatter pipe than I have at my current location, you’ll want to do a minimal install onto a very small virtual disk.

We used a 2GB dynamically-allocated virtual disk and booted the Fedora Network Install ISO.  Once in the installer,  select the ”Minimal Installation’ option.  Obviously, the other important piece (and the reason we’re all here!) is the partitioning.   The automatic partitioning for BTRFS did an acceptable job and only required enabling encryption and entering a pass-phrase.  Finish the install and boot it up.

Prepare the Virtual Machine

This can be done after the copy to Linode, but it’s a bit nicer to fix things up while you have them locally in VirtualBox.

Fix Grub. Linode uses pv-grub, which expects to find menu.lst in /boot/grub. Fedora uses grub2, so you’ll need to manually create this.  If you follow these instructions, your /boot in Linode will be /dev/xvda and referenced by pv-grub from the root. Thus, you’ll need to create menu.lst in /boot/boot/grub/menu.lst

default=1
timeout=5
title Fedora (3.14.2-200.fc20.x86_64) 20 (Heisenbug)
  root (hd0)
  kernel /vmlinuz-3.14.2-200.fc20.x86_64 root=UUID=578296d8-d33f-11e3-9a76-50465d30a2b3 rootflags=subvol=root ro console=tty0 console=hvc0 quiet SYSFONT=latarcyrheb-sun16 LANG=en_US.UTF-8 KEYTABLE=us
  initrd /initramfs-3.14.2-200.fc20.x86_64.img

Note: the UUID comes from the UUID for your dm volume in /dev/disk/by-uuid.  The rootflags parameter is because we’re using BTRFS with root as a subvolume.  Do not just copy the above menu.lst!

Fix initramfs. Linode uses Xen or KVM, but we just built this virtual machine in VirtualBox. Fedora optimizes the initramfs and does not put the block device driver in. The virtual machine won’t boot on Linode and the error messages aren’t necessarily readily visible or clear.

For Xen:

sudo echo 'add_drivers+="xen_blkfront"' > /etc/dracut.conf.d/xen.conf

For KVM:

sudo echo 'add_drivers+="virtio_blk"' > /etc/dracut.conf.d/kvm.conf

Then run dracut –force to rebuild initramfs.  You can check your work easily enough:

$ lsinitrd /boot/initramfs-3.14.2-200.fc20.x86_64.img | grep xen
-rw-r--r--   1 root     root        32343 Apr 28 09:30 usr/lib/modules/3.14.2-200.fc20.x86_64/kernel/drivers/block/xen-blkfront.ko

You should now have a machine that will run on Linode.

Create New Linode

Select your plan and create your new Linode. In this case, we wanted a disk layout that could move between the 2GB and 4GB plans, so we launched a 2GB plan to start with and carved up the 48GB into an ext3 boot disk image, a raw root image, and a raw swap image. If you create boot and swap first, it saves calculating exactly what to use for root.

Selection_015

Selection_012 Selection_016

Create each disk image then create a new Configuration Profile that uses them and specifies pv-grub-x86_64 for the Kernel. All the boot helpers are turned off, as they don’t do anything since we’re running the stock Fedora kernel and our partitions are encrypted.

Selection_014

Boot The Linode into Rescue Mode

Go to the rescue tab and boot the Linode into the Finnix rescue mode.  You can access it via the Lish console.  Once it’s booted you’ll need to manually start SSH and give root a password.  You’ll also want to verify your virtual disks are all there and which one is which.  Linode rescue mounts devices in the order they are created and pays no attention to your Configuration Profile.  If you created swap first, it will be /dev/xvda and you won’t want to write your boot partition there.

Fedora 20_018b

Boot VirtualBox into ‘Rescue’ Mode and Copy

I used Finnix here, but any live media should work fine.  You only need to be able to access the raw devices and copy them via SSH to the Linode box.

root@tty1:~# dd if=/dev/sda1 | ssh -C 69.182.203.14 "dd of=/dev/xvda"
root@69.182.203.14's password:

root@tty1:~# dd if=/dev/sda2 | ssh -C 69.182.203.14 "dd of=/dev/xvdb"
root@69.182.203.14's password:

This is where you’ll appreciate having created a small root partition.

Finish Up

After the copy, you should have a bootable Fedora instance with an encrypted root partition. Be aware that you’ll need to type in the pass-phrase each time the system boots.  We’ve found Linode to be an insanely reliable host; we’ve never (knock on wood)  had an instance crash.

Grow root. Now that you’re done with the transfer, you’ll want to grow your root disk to the full capacity you allocated.

[root@localhost boot]# df -h /
Filesystem      Size  Used Avail Use% Mounted on
/dev/dm-0       1.4G  945M  159M  86% /

[root@localhost boot]# btrfs filesystem resize max /
Resize '/' of 'max'
[root@localhost boot]# df -h /
Filesystem      Size  Used Avail Use% Mounted on
/dev/dm-0        47G  945M   46G   2% /

Encrypt swap.  For this server, we just used /dev/urandom and skipped luks to have a swap partition that is recreated with a new encryption key on each boot.

In /etc/crypttab add:

swap /dev/xvdc /dev/urandom swap

In /etc/fstab add:

/dev/mapper/swap        none    swap    sw      0       0

Reboot and verify your new swap partition works and is encrypted.

Fedora 20_019

Enjoy!  Let us know if you have any improvements, suggestions, or success with this guide!