Encrypting an Unencrypted Ubuntu Installation

Encrypting an Unencrypted Ubuntu Installation

My Ubuntu partition was not encrypted.

I can’t quite recall why, but I believe it had something to do at the time with UEFI and luks installations on Ubuntu not playing nicely.

So recently I decided it was time to migrate to a fully encrypted system, but I didn’t want to lose all my configurations, applications and everything else that comes with an OS that has been tweaked to your liking for the past few years.

My system is EFI, with Ubuntu installed all on one partition. / (root), /boot and /home all on the same partition. If your system is different you may need to adapt some parts of this guide, but in general this should guide you through.

So I started searching for the best way to go about this. To my surprise this doesn’t seem to come up all that often, however I was able to find a old article, that detailed this on a debian system. Ubuntu is debian based, so close enough. https://debian-administration.org/article/577/How_To_Migrate_to_a_full_encrypted_LVM_system

However this didn’t quite cut it, so I “shopped” around for other material. Below are the exact steps you need to follow to be able to migrate successfully.

I didn’t follow these exact steps, as for me there was some learning and trial and error involved at the beginning, but this is the equivalent of what I did but condensed down.

Let me just say that the ARCH Linux Wiki is one of the best resources out there, and a lot of it applies to other distributions as well.

WARNING: BEFORE YOU PROCEED MAKE A FULL BACKUP OF YOUR DISC.

You can do this using, my personal favourite dd, or clonezilla for example. For instructions see: https://wiki.archlinux.org/index.php/disk_cloning

Fyi I have a PCIe SSD.

My partitions before embarking on this journey looked like this:

nvme0n1                                                                         
├─nvme0n1p1            fat32
├─nvme0n1p2            unknown
├─nvme0n1p3            ntfs
├─nvme0n1p4            ntfs
├─nvme0n1p5            ext4
├─nvme0n1p6            ntfs 
└─nvme0n1p7                                                                     
  └─swap               swap

From now on we are always referring to the device nvme0n1 located in /dev/nvme0n1, so I will refer only to each partition as p followed by the number.

  • p1 is my EFI partition and for simplicity I opted to not touch it, according to this article from ARCH Linux, I could have opted to place /boot on it, instead I opted to place it on a new partition.
  • p2-p4 Windows
    • p2 – Windows reserved partition.
    • p3 – Windows 10
    • p4 – Windows recovery (I believe)
  • p5 Ubuntu (included /boot)
  • p6 NTFS partition with misc Data shared, that I use to share between Ubuntu and my Windows Installation.
  • p7 is my encrypted swap partition that I setup up a year ago. If you want to get something like this setup see: https://wiki.archlinux.org/index.php/Dm-crypt/Swap_encryption

NOTE: Remember to backup your disk before proceeding.

In my case I opted to get rid of Windows installation, but you can always nuke your own Ubuntu installation as long as you’ve backed it up of course.

This meant deleting p2, p3 and p4. With this space unallocated I could now create space for my /boot partition and my / (root) partition.

As previously mentioned I opted to create a boot partition of 500MB where I will place my /boot files. Your /boot partition cannot be encrypted, otherwise you would have no way to boot the system.

/boot contains your initramfs images, which you can think of as a mini system, that contains the basics needed to load your full system from disk.

After creating /boot and / (root) partition, I ended up with the following layout.

nvme0n1                                                                         
├─nvme0n1p1            fat32
├─nvme0n1p2            ext4
├─nvme0n1p3            irrelevant
├─nvme0n1p5            ext4
├─nvme0n1p6            ntfs 
└─nvme0n1p7                                                                     
  └─swap               swap

Your device might have a different name, that doesn’t matter.
p1, p2, p3, etc identify the partitions.

p2 is formatted as ext4, p4 is irrelevant since we will need to change it to a luks partition.

For this part I followed the ARCH wiki https://wiki.archlinux.org/index.php/Dm-crypt/Encrypting_an_entire_system#LVM_on_LUKS

So on your OS partition, /dev/nvmen0n1p3, run:

cryptsetup luksFormat --type luks2 /dev/nvmen0n1p3
cryptsetup open /dev/nvmen0n1p3 cryptlvm

Remember this will have to be run as root so either add sudo to every command or just open a root shell.

The name cryptlvm doesn’t really matter here, as that’s just the name you are using to open the luks partition.

pvcreate /dev/mapper/cryptlvm
vgcreate UbuntuCrypt /dev/mapper/cryptlvm

UbuntuCrypt is the name of your volume and renaming it is possible, but not worth the hassle, so just choose wisely now.

lvcreate -l 100%FREE UbuntuCrypt -n root
mkfs.ext4 /dev/UbuntuCrypt/root

Here is where we defer from ARCH, since I had previously setup my swap encrypted. The way I have setup my swap though does not allow me hibernate, since the swap partition key is randomised everytime. If you wish to hibernate I suggest you go ahead and create a swap lvm partiton along inside our newly created luks partition. See the linked ARCH docs for this.

Why LVM over LUKS? For me the simplest answer is at boot time you only have to input the password once.

Once this is done we can now move our system to the new partition.

But first we need to mount our new lvm partition

mount /dev/mapper/UbuntuCrypt-root /mnt

The name of the partition is the name of the lvm volume + ‘-‘ + the name give in lvcreate after ‘-n’, in our case root.

So now we can copy the contents over, rsync is a good tool for this. These are the folders I ended up moving, if you don’t have them all don’t worry.

rsync -a /bin /mnt
rsync -a /etc /mnt
rsync -a /home /mnt
rsync -a /initrd.img /mnt
rsync -a /initrd.img.old /mnt
rsync -a /lib /mnt
rsync -a /lib32 /mnt
rsync -a /lib64 /mnt
rsync -a /opt /mnt
rsync -a /root /mnt
rsync -a /sbin /mnt
rsync -a /srv /mnt
rsync -a /usr /mnt
rsync -a /var /mnt
rsync -a /vmlinuz /mnt
rsync -a /vmlinuz.old /mnt

-a preserves permissions and ownership which you definitely want, if you expect this to work.

There was one final folder which caused more issues.

mkdir /mnt/snap
if [[ $(ls -ld /snap | cut -d ' ' -f 1) == $(ls -ld /mnt/snap | cut -d ' ' -f 1) ]]; then echo "true"; else echo "false"; fi;

Proceed if true otherwise change permissions on /mnt/snap to match /snap

rsync -a /snap/bin /mnt/snap
rsync -a /snap/sublime-text /mnt/snap

I had to end up copying bin and sublime-text, otherwise my sublime would not startup. However /snap/core was recreated without issues.

I suspect if you have other apps in /snap/APP you might want to move those too as the app might not handle it gracefully.

Now we need to move the boot files.

Now we check if we can boot our new system, but first we need to make some changes to our initramfs.

lsblk -f
nvme0n1                                                                         
├─nvme0n1p1            vfat        ESP   ID   /boot/efi
├─nvme0n1p2            ext4              ID   /boot <-- also relevant
└─nvme0n1p3            crypto_LUKS       ID  <-- relevant ID
  └─UbuntuCrypt        LVM2_member       ID
    └─UbuntuCrypt-root ext4              ID   /

This will give you your partition id’s. Identify your new OS partition Id, and write it down. You want the ID of the luks partition and not of the lvm volume of the partitions within it. I will refer to this ID as LUKS_ID. The ID of the /boot partition will be referred to as BOOT_ID.

Edit the fstab of your new system on /mnt/etc/fstab. Find the entry for the root, and modify accordingly. Also add an entry for /boot

# old entry is commented out, new entry with the same options but different partition is added
# UUID=ID /               ext4    errors=remount-ro 0       1
/dev/mapper/UbuntuCrypt-root   /   ext4   errors=remount-ro 0   1

# boot partition mount
UUID=BOOT_ID /boot ext4 defaults    0  1

if your mount options are different keep them the same, you want to replace UUID=ID with /dev/mapper/UbuntuCrypt-root

edit /mnt/etc/crypttab, if it doesn’t exist create it. This step believe is might not be needed, but I haven’t removed this entry at the time of writing, so I haven’t tested the system without it.

UbuntuCrypt UUID=LUKS_ID none luks,lvm=UbuntuCrypt

LUKS_ID is the id you previously got with the lsblk -f command.

In the old filesystem edit /etc/cryptsetup-initramfs/conf-hook and then copy it over to the new. Uncomment the following line. (https://unix.stackexchange.com/questions/470553/ubuntu-18-04-luks-boot-problems however I did not follow this to the line, since I used my old system’s boot partition to boot for the first time)

CRYPTSETUP=y
rsync -a /etc/cryptsetup-initramfs/conf-hook /mnt/etc/cryptsetup-initramfs/conf-hook
sudo update-initramfs -u

This will update our initramfs images with the crypt tools needed to unlock the the root partition before the OS is up and running.

Now we copy the boot files to our new /boot partition.

mount /dev/nvme0n1p2 /mnt/boot
rsync -a /boot /mnt/boot

Next we will create some of the partitions we left behind. The others the system will create automatically. (TBH I’m not even sure these two need to be created beforehand.)

mkdir /mnt/proc
mkdir /mnt/sys

Now we are going to disable the ubuntu splash screen so we can have a better look of what is happening.

Edit /etc/default/grub and comment out.

GRUB_CMDLINE_LINUX_DEFAULT="quiet splash"

The important part is quite and splash, these cannot be present.

Now we are going to reboot and edit the grub menu.

Once rebooted and on the grub menu, press e to edit the line you are on. You should be editing the line that normally “you boot from”.

It should originally look something like this

        recordfail
        load_video
        gfxmode $linux_gfx_mode
        insmod gzio
        if [ x$grub_platform = xxen ]; then insmod xzio; insmod lzopio; fi
        insmod part_gpt
        insmod ext2
        if [ x$feature_platform_search_hint = xy ]; then
          search --no-floppy --fs-uuid --set=root  ID
        else
          search --no-floppy --fs-uuid --set=root ID
        fi
        linux   /boot/vmlinuz-4.15.0-43-generic root=UUID=ID ro  
        initrd  /boot/initrd.img-4.15.0-43-generic

And we are changing it to something like this.

        recordfail
        load_video
        gfxmode $linux_gfx_mode
        insmod gzio
        if [ x$grub_platform = xxen ]; then insmod xzio; insmod lzopio; fi
        insmod part_gpt
        insmod ext2
        if [ x$feature_platform_search_hint = xy ]; then
          search --no-floppy --fs-uuid --set=root  LUKS_ID
        else
          search --no-floppy --fs-uuid --set=root LUKS_ID
        fi
        linux   /vmlinuz-4.15.0-43-generic root=/dev/mapper/UbuntuCrypt-root ro  
        initrd  /initrd.img-4.15.0-43-generic

In my case the last if else is useless but nonetheless yours might be doing something. Notice how ID has changed to LUKS_ID and where we had root=UUID=ID we now have root=/dev/mapper/UbuntuCrypt-root which is our partition inside the lvm volume, inside the luks partition.
We’ve also changed /boot to just / in vmlinuz and initrd

After these changes are made press f10 and you should start seeing the system booting and midway through it will prompt for a password, that is the password of your luks partition when you first created it.

Once logged in let’s check that we are indeed in our encrypted system.

df -h
df -h
Filesystem                    Size  Used Avail Use% Mounted on
...
/dev/mapper/UbuntuCrypt-root   63G   49G   11G  82% /
...

The important part here is that your / (root) should be the encrypted partition that we previously created in my case UbuntuCrypt-root.

If this the case then we now edit grub config in order to generated our new grub menu which will boot our new system.

make a backup of /boot/efi/EFI/ubuntu/grub.cfg and then edit it.

cp /boot/efi/EFI/ubuntu/grub.cfg /boot/efi/EFI/ubuntu/grub.cfg.bckp

From something like this

search.fs_uuid ID root 
set prefix=($root)'/boot/grub'
configfile $prefix/grub.cfg

To what follows.

Notice that we change the ID to our BOOT_ID, which is the UUID of our new boot partition. Also we’ve changed /boot/grub to /grub since our boot partition when on it’s own is now /.

search.fs_uuid BOOT_ID root 
set prefix=($root)'/grub'
configfile $prefix/grub.cfg

Now we update all our initramfs images in our /boot partition. And our grub config.

update-initramfs -u -k all
update-grub

If you are like me and kept the old system around it will also appear in the grub menu. Remove the partition once you’ve reboot and booted back in to the encrypted / (root) without having to manually change anything.

Once you’ve successfully booted into your system check that you are using the new encrypted system and if so go ahead and delete the partition for the old system.

You have now encrypted your existing Ubuntu installation.

Leave a Reply

Please Login to comment
  Subscribe  
Notify of