Linux – Migrating from Unencrypted Ubuntu 16.04 to LUKS Encrypted Install

cloneencryptionlinuxluksubuntu 16.04

My company is working on implementing some Ubuntu Systems in a few of their new testing efforts and I have been tasked with an encryption solution for them. Having been a primarily Windows user with just a working knowledge of Ubuntu and Linux/Unix in general, this has been a bit challenging but intriguing. I know many in place encryption services work w/ Windows but have noticed a lack of these for Ubuntu and after reading 20+ posts on here about it, decided fresh install w/ full disk encryption is the only realistic option. That being said, some of the systems have already been in use, and would not be able to just be wiped and fresh installed w/ encryption. I would need ALL settings and changes as well as existing files copied over/backed up. Therefor, it's not as simple as copying over /home. I was curious what would be the best course of action for me, I have a full copy of the Partition (used gparted to make a quick copy to external) for my test machine and a fresh install of Ubuntu w/ LUKS. I am familiar with the basics of clonezilla, but I don't believe that will help me here from what I gather.

tldr: I need to move a full install of Ubuntu 16.04 to an encrypted disk. Some machines will be TPM enable and some will not have them, I need to know the best course of action for each. Thank you for helping a new Admin out.

BONUS if you can describe a way that doesn't require outside network access, but not required. I.e. if it needs a package, I can download it on a test PC to USB/CD/DVD and install the package offline.

Best Answer

Described below is a procedure I have successfully used multiple times. It works for Ubuntu 16.04 and 18.04. Unlike the solution proposed by @Arno in their answer, it doesn't require manual editing of kernel boot options. Instead, it relies on update-grub generating proper config based on /etc/crypttab - a more canonical (pun unintended) solution which is also used by Ubuntu when installing with its default, LVM-based encryption. (this solution doesn't use LVM nor encrypted /boot)

I am not responsible for any data loss or other potential unpleasant consequences of following this guide. Make sure you have reliable backups before doing anything.

I'm not testing this guide while I'm typing this. It's based on a (tested) blog post by myself on somewhat similar case and some details I can remember.

This guide assumes that:

  • Ubuntu is already installed
  • The system boots with (U)EFI, not BIOS/CSM
  • /boot is on a separate partition1
  • You can boot a live media of Ubuntu 16.04/18.04 or Pop!_OS 18.04 (from USB, PXE, DVD, whatever) 2

If your /boot is not on a separate partition, extracting it is pretty straightforward: create a 200-500 MB partition anywhere, format it to ext4, copy current /boot content, add /etc/fstab entry, update-grub, reboot.


1. Backup

You have to back up current system partition(s). The easiest way to do this is to use Clonezilla. It's user-proof, no manual needed - just follow the instructions.

2. Shrinking partitions

LUKS headers take some of the space on a partition. Clonezilla/partclone can't restore images to devices smaller than source ones, so you wouldn't be able to restore image of unencrypted partition to encrypted container, because it's a tad smaller.

We then have to shrink partition(s) to be encrypted a little bit. Shrink them by 10 MB or more, just to be safe. The easiest way to do this is to use GParted. It's available on Ubuntu live media.

3. Making images of shrunk partitions

Either do this with Clonezilla again, or already familiarize yourself with partclone, which Clonezilla is using by default. We'll be manually restoring images with partclone later.

Cloning to an image with partclone:

sudo partclone.ext4 -c -s /dev/sda2 | pigz -0 > /mnt/backup/sda2.ext4.ptcl.gz
  1. partclone.ext4 is one of partclone's binaries dedicated to working with ext4. Each supported filesystem gets its own partclone binary.

  2. /dev/sda2 is obviously the partition you want to clone. I prefer to refer to partitions by their partlabel, eg. /dev/disk/by-partlabel/os - much cleaner IMO. /dev/sda2 is more recognizable, though.

  3. pigz is multicore gzip. -0 tells it to favor speed over effective compression.

  4. /mnt/backup here represents some external location where you want to store the image. If you've just used Clonezilla before, it can still be mounted under /home/partimag. If you want to mount an SMB share: sudo mount -t cifs -o username=gronostaj //192.168.1.90/Backup /mnt/backup (asks for password interactively)

4. Enlarge partition(s) to original size

We want to have that extra space for LUKS headers back, don't we? Resize partitions back to their original sizes.

5. Formatting to LUKS

This is the moment where you loose your original data. Make sure your backups are okay.

Format system partition(s) (except for /boot) to LUKS:

sudo cryptsetup luksFormat --type luks2 /dev/sda2

Open created container(s):

sudo cryptsetup open /dev/sda2 os

Make sure that entire encrypted container looks like random garbage and your old data isn't still readable:

sudo dd if=/dev/zero of=/dev/mapper/os bs=1M

(this will overwrite decrypted content of container with zeros, but encrypted content will look like random garbage)

6. Restoring images

Manually run partclone to restore images:

cat /mnt/backup/sda2.ext4.ptcl.gz | pigz -d | sudo partclone.ext4 -r -o /dev/mapper/os

If you took the easy path and made "shrunk" backups with Clonezilla, look in its output files, you'll easily figure out which are the partclone sources. Unless you set huge chunk size they will be fragmented, you have to cat them together before piping to pigz.

You should also adjust filesystem geometry to fit entire partition:

sudo resize2fs /dev/mapper/os

7. Enabling encryption support

First, chroot into the just-restored OS:

mkdir /mnt/os
sudo mount /dev/mapper/os /mnt/os
cd /mnt/os
mount --bind /etc/resolv.conf etc/resolv.conf
mount --bind /dev dev
mount -t tmpfs tmpfs tmp
mount -t sysfs sys sys
mount -t proc proc proc
sudo chroot .
mount -a

This terminal is now working on your installed instance of Ubuntu, not the live one.

Install cryptsetup:

apt update
apt install cryptsetup -y

It should create a file /etc/crypttab. If it didn't, don't worry, create it manually. Edit this file and add entries for partition(s):

os /dev/sda2 none luks

Save and quit editor. Rebuild initramfs:

update-initramfs -u -k all

Update GRUB entries:

update-grub

8. Removing extra password prompts

If you have more than one encrypted partition, then you have to type in the password for every single one on boot. LUKS however lets you add additional keyfiles that can be used to unlock partitions instead of password. You can store these keyfiles on encrypted / partition and use it to unlock subsequent ones.

Create a random keyfile:

dd if=/dev/urandom of=/luks.key bs=4096 count=1

Add it to non-root partition(s):

cryptsetup luksAddKey /dev/sda3 /luks.key

Add crypttab entries:

home /dev/sda3 /luks.key luks

Rebuild initramfs:

update-initramfs -u -k all

1 Why I use separate /boot:

  • It's easier this way ;)
  • GRUB doesn't support LUKS2 yet, so /boot must not be on LUKS2 encrypted partition
  • If you want to LUKS-encrypt /boot and LUKS2-encrypt /, then you have to enter password twice or embed keyfile in initramfs - too much of a hassle IMO, because...
  • Encrypted /boot alone doesn't make you any less vulnerable, because even if your /boot is encrypted, your EFI System Partition cannot be, so attacker can tamper with it and eg. use their custom malicious kernel/initramfs instead of your one from /boot. (to fix this, you have to build a self-container GRUB binary and sign it with your private key, then use UEFI Secure Boot to verify it)

Define your own threat model and decide what level of security (and against what) you need.

2 You can try your luck with other Ubuntu versions or rescue CDs such as GRML, but your mileage may vary. I've experienced this procedure failing just because live media didn't match the system.

Related Question