Headless encrypted boot with Fedora Server

Here is a recipe for using encrypted boot on a Fedora Server system that does not have a monitor or keyboard attached during normal use.

I’ll use Fedora 21 Server, and will have a dedicated encrypted volume group for data but leave the main operating system volume group unencrypted. The encryption key will be stored on a USB memory stick. When it is connected the system will boot normally; otherwise it will wait for a while for it to be connected and finally fall back to emergency mode.

Installing

When installing, create a separate volume group in which to put the actual data volumes. To do that, select “I will configure partitioning” when setting up disk storage.
01-config-partitioning

On the next page, allow the installer to create the mount points automatically: we’ll edit them next.
02-create-automatically

Next, set up one of the mount points for the data volumes. In this example, I have used /home.
03-home-lv

In the screenshot above, I’ve decreased the size for the / volume to make space for a new volume, then added one and set its mount point to /home. It is currently in the automatically-created fedora-server volume group.

Next, put this new volume in a volume group of its own by selecting /home and choosing “Create a new volume group …” in the Volume Group drop-down.

04-new-vg

Give the new volume group a name (for example, “data”), and choose to have it encrypted by clicking on the checkbox.

05-config-vg

Once you have added the volumes you want and clicked Done, you will be asked to set a passphrase.
06-set-pw

The summary of changes shows in more detail what will happen. You can see that a separate partition, vda3, will be the LUKS (encrypted) device, acting as an LVM physical volume: that’s for our data volume group.
07-summary

Continue with the installation as normal and reboot when prompted. Don’t forget your passphrase!

Prepare encryption key media

Now, find a USB memory stick, create an ext4 filesystem on it whose label is “Key”, and mount it at /mnt/key. For example:

# mkfs.ext4 -L Key /dev/sdb1
# mkdir /mnt/key
# mount /dev/sdb1 /mnt/key

Place the encryption passphrase in /mnt/key/data-key — note, it must not have a newline at the end. We can use read and printf for this: it serves the dual purpose of removing the newline and keeping the passphrase out of the shell’s history.

# read -r a ; printf %s "$a" > /mnt/key/data-key
(enter passphrase, then press enter)
# chmod 600 /mnt/key/data-key
# chcon -u unconfined_u -t unlabeled_t /mnt/key/data-key

Next, edit /etc/fstab and add a line describing the filesystem we just made. Here is the line to add:

LABEL=Key  /mnt/key  ext4  defaults,ro,x-systemd.device-timeout=60  0  0

While there, adjust the x-systemd.device-timeout value for /home from 0 (no timeout) to 60 (seconds). These two timeouts ensure that, rather than waiting indefinitely, the system will fall back to emergency mode if the USB device is not present.

Test the fstab changes by running umount /mnt/key and then mount /mnt/key. If all is well there will be no error messages.

Now that the passphrase is stored away we need to specify its location so it can be retrieved at boot. To do this, edit /etc/crypttab. Change “none” at the end of that line so that it contains the passphrase filename:

luks-... UUID=... /mnt/key/data-key

At boot time, the filesystem will be mounted automatically in order to read the passphrase.

Set up encrypted swap

We definitely want the swap partition to be encrypted, but it doesn’t need to be in the encrypted volume group. Why? Because a new key can be generated each boot and discarded on shutdown. To do that, edit /etc/crypttab again and add this line:

cryptswap  /dev/mapper/fedora--server-swap  /dev/urandom  swap

The /dev/mapper/ name must match the existing logical volume device mapper name: you can check it with “lsblk”.

To actually use that mapped device, edit /etc/fstab and change the swap line to use /dev/mapper/cryptswap:

/dev/mapper/cryptswap  swap  swap  defaults  0  0

No need to recreate initial ramdisk

At boot, the job of the initial ramdisk is to find and mount the root (/) filesystem. As we haven’t made any changes to that, only to /home, there is no need to run dracut.

Reboot and test it!

If the system is booted without the encryption media inserted, after a minute it will drop into emergency mode. The system will allow you to log in as root and make adjustments, but of course /home will not be available unless you unlock it from the command line with the passphrase using cryptsetup.

Bonus: Automatically unmount encryption key media after boot

As things stand, the Key filesystem will remain mounted all the time, which means the device can’t be safely removed while the system is running. Here is a systemd service file you can use to unmount the encryption passphrase USB storage device after it has fulfilled its purpose at boot time:

[Unit]
Description=Unmount encryption passphrase media at boot
Documentation=http://cyberelk.net/tim/2015/04/09/headless-encrypted-boot-with-fedora-server/
After=home.mount

[Service]
Type=oneshot
ExecStart=/usr/bin/umount /mnt/key
RemainAfterExit=true

[Install]
WantedBy=multi-user.target

Save it as /etc/systemd/system/umount-key.service and enable it:

# systemctl enable umount-key.service

All done

That’s it! Hope you find this useful.

I’d love to have this work for whole-disk encryption, where the root filesystem is also encrypted, and I’d also love to be able to fall back to entering the passphrase at the console, rather than dropping into emergency mode. However it doesn’t seem to be possible just yet.

UPDATED: Fixed the read/printf line to handle escape characters better as suggested by Ralph.

2 Responses to “Headless encrypted boot with Fedora Server”

  1. Séb says:

    Thanks for this how-to.

    I think we need an option to doing this directly on Anaconda at the installation.
    [Create a USB decryption key]. After clicking, this doing all the stuff needed in the Fedora installation and on the usb key.

  2. Hi Tim, Interesting. I think data-key would be better created with «read -r p; printf %s “$p” >/mnt/key/data-key» to avoid problems with backslashes or percents. Cheers, Ralph.

Leave a reply

Comments are moderated. Comments that are inappropriate, offensive, vulgar, badly written or insulting will be deleted or edited to make the author look silly.