Skip to content

Instantly share code, notes, and snippets.

@gvtulder
Last active February 8, 2023 03:22
Show Gist options
  • Star 10 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save gvtulder/881e9cce73758339bd25937c254f7960 to your computer and use it in GitHub Desktop.
Save gvtulder/881e9cce73758339bd25937c254f7960 to your computer and use it in GitHub Desktop.
Encrypting hard drives without reinstalling Ubuntu
Encrypting hard drives without reinstalling Ubuntu
===================================================
Gijs van Tulder, 26.02.2019, last update 04.03.2019
This is a list of the steps I took to encrypt the partitions on my
Ubuntu 16.04 laptop with the LUKS encryption system. Encrypting the
partitions took some time but was relatively easy. Getting the system
to boot afterwards was a little trickier, but doable.
Obviously, these steps might not work for you. Follow them at your
own peril, and ask for help if you're not familiar with low-level
Linux stuff. Read through the instructions before you start.
I made a backup (see first steps) of my disks before I started, but
I didn't need to use them. The encryption itself happens in-place.
With these steps, I encrypted each partition separately. This means
that you have to enter your encryption password multiple times. There
might be better solutions for this (but then, I don't reboot my
computer very often).
This is what worked for me. I'm not sure if this is the optimal way
to do this. Should you have any comments, questions, or need help,
please let me know.
Useful tools
------------
* An external hard drive that can store your backup disk images.
* A USB drive with a recent Ubuntu image that you can boot into to
do the work. (This doesn't have to be the same version. I used
the most recent 18.04 image.)
* A second computer that you can use to look for help.
Preparations
------------
* I removed my hard disk passwords from the BIOS.
* Check that you're not booting with UEFI but with BIOS.
# from https://askubuntu.com/questions/162564/how-can-i-tell-if-my-system-was-booted-as-efi-uefi-or-bios
[ -d /sys/firmware/efi ] && echo UEFI || echo BIOS
If this says "UEFI", proceed with caution. (I haven't tried this.)
* After encryption, your boot system needs to be able to unlock
the encrypted drives, so it's best to make sure that your
initframfs image contains the cryptsetup tools.
(I didn't do this the first time. See the appendix on how to fix that.)
# install the cryptsetup tools (if necessary)
sudo apt install cryptsetup
Then make sure that the cryptsetup tools are included in your initramfs
image. Ideally, you can edit /etc/initramfs-tools/initramfs.conf and add:
# always include cryptsetup
CRYPTSETUP=y
Then rebuild the initramfs image:
sudo update-initramfs -c -k all -v
Among the list of files, you should see "/sbin/cryptsetup". For me, on
Ubuntu 14.04, this didn't work.
(See https://bugs.launchpad.net/ubuntu/+source/cryptsetup/+bug/1256730)
To fix this, I followed the instructions for that bug and created a file
/usr/share/initramfs-tools/conf-hooks.d/forcecryptsetup
with the following contents:
export CRYPTSETUP=y
Then run update-initramfs again and check for cryptsetup. If it's still
not included, you can force it to be included by running this:
CRYPTSETUP=yes sudo update-initramfs -c -k all -v
but this has the downside that you'll have a problem the next time you
update the initramfs.
* Make a list of your partitions and mount points.
It's a good idea to familiarize yourself with the partition structure of
your system. Look at fdisk -l , mount or the Disks utility, as well as
/etc/fstab to see which partitions are mounted where.
* You can look at /etc/fstab. In my case, this lists partitions with their
UUID. These should still be the same after encryption, so I didn't have to
change anything here. If it lists partitions directly, e.g., /dev/sda5,
I'm not sure if it will still work.
* Shut down your computer.
Backing up your partitions
--------------------------
* Boot into the Live CD from the USB drive and plug in your external
hard disk.
* Create images of the partitions you're going to encrypt. E.g.:
sudo dd if=/dev/sda2 of=sda2.img
Creating a separate /boot partition
-----------------------------------
This step is only necessary if your /boot/ directory is located on a partition
that you want to encrypt (e.g., if you don't have a separate /boot partition
and just have it on your root partition /). If that is the case, the easiest
solution is to move things to a separate /boot partition. (See the note at
the end for the other solution.)
If you're lucky, you created a separate /boot partition during your Ubuntu
installation. In that case: congratulations, continue to the next chapter.
* Before moving /boot, first create some empty space to house the new
partition. Use the live-CD Disks utility to resize your main partition
to create, say, 1GB or 2GB of free space.
* Having done that, you can use GParted to create a new partition to house
/boot. Create an ext4 partition to fill the empty space.
* Mount the two partitions (old-/boot and new-/boot) using the Disks utility.
* Copy the files from /old/boot to /new/boot (check the mount points):
sudo cp -rv /old/boot/* /new/boot/
* Unmount the partitions and reboot to your normal OS.
* Find the UUID of the new /boot partition:
blkid
* Add this partition to your /etc/fstab, e.g.:
UUID=675f89d8-d620-11e8-ae01-14feb5fa66aa /boot ext4 defaults 0 0
* Mount.
sudo mount /boot
* Update GRUB (this should list the kernels in /boot) and initramfs:
sudo grub-install /dev/sda # replace with your disk
sudo update-grub
sudo update-initramfs -u
* You can try rebooting if you want.
* For the next chapter, reboot into the live-CD.
Encrypting the partitions
-------------------------
Following instructions from the man page (example near the end):
https://manpages.ubuntu.com/manpages/trusty/man8/cryptsetup-reencrypt.8.html
* You need to do this for each of your data/system partitions. I did not
encrypt the /boot partition. (If you don't have a separate /boot partition
to house GRUB, things might become a bit more difficult.)
* Check and repair the file system on the partition:
# check but don't change
sudo e2fsck -nfv /dev/sda2
# repair
sudo e2fsck -fv /dev/sda2
* Resize the file system on the partition to make room for the LUKS
header that will be added at the end. The man page says that 4096 512-bytes
blocks is sufficient, so that's what I used.
# list partition size
sudo fdisk -l /dev/sda2
# note number of 512-bytes sectors
# subtract 4096 from this number
# resize file system to make room for LUKS
# (replace with your computed number)
sudo resize2fs /dev/sda2 1234567s
* Now that there's some space, encrypt the partition (telling
cryptsetup-reencrypt that there are 4096 free sectors at the end):
sudo cryptsetup-reencrypt /dev/sda2 --new --reduce-device-size 4096S --verbose
(You need to choose a password for this. I used a simple password because you
need to enter it a few times during the procedure. It's easy to change to a
better password later.)
* Wait for the encryption to finish.
* Now you can unlock your newly encrypted partition. I cheated and used the
graphical Disks utility (unlock the encrypted container, but do not yet mount
the volume itself). Note where it's located.
* Check the file system, just to be sure (use your mount point):
sudo e2fsck -nfv /dev/mapper/luks-...
* Mount the partition and remember its location. Now you can wipe the unused space
on the disk by filling the partition with zeros. E.g.:
sudo dd bs=64M oflag=sync status=progress if=/dev/zero of=/your/mount/point/wipe.file
sudo rm /your/mount/point/wipe.file
* Unmount this partition and continue with the next partition.
Booting your computer for the first time
----------------------------------------
After encrypting all partitions, shut down the system, remove the USB drive
and reboot. Most likely, your computer will try to boot, pass the GRUB menu
and will then show you an initramfs) prompt. If you type exit, it will print
an error message stating that it couldn't mount some of your hard drives.
The initramfs will show up again.
* You have to manually unlock each of your encrypted partitions. For this,
you need the cryptsetup utility which you (hopefully) have installed in
your initramfs image at the beginning. (If, like me, you didn't, see below).
cryptsetup
* Get a list of all your partitions: (hopefully, you remember some of the
structure from what you've seen during your preparations)
ls /dev/sd*
* You can just try to mount each of the partitions (sda1, sdb2, etc). If it
is a LUKS-encrypted volume, it will ask you for your password. If it's not
a LUKS-encrypted volume, it will just tell you and stop.
Call cryptsetup with the path to the partition and an identifier. E.g.:
cryptsetup luksOpen /dev/sda5 crypt_sda5
* Once you've unlocked everything, continue the normal boot process.
exit
* Your computer should now boot like it did before.
Updating your mount settings
----------------------------
Once you're in your familiar Linux environment, you can make the boot process
a bit faster by adding your encrypted partitions to /etc/crypttab and /etc/fstab.
* First open the Disks utility. Go to each encrypted partition, Edit Encryption
Options. Disable Automatic Encryption Options and enable Unlock at startup.
You can give it a more recognizable name. (I used, for example, luks-root,
luks-home and luks-var).
* Once you've done this, edit /etc/crypttab. This should have a list of the
partitions you've just edited.
* I reordered the partitions such that my root partition is mounted first.
* After each partition, set the follwing settings:
nofail,luks,initramfs
* You can look at /etc/fstab. In my case, this lists partitions with their
UUID. This should still be the same after encryption, so I didn't have to
change anything here.
* Rebuild your initramfs and GRUB: (remember to check that /sbin/cryptsetup
is still there!)
sudo update-initramfs -c -k all -v
sudo update-grub
* Now reboot your computer. If everything went fine, it should ask you for the
password to unlock each partition and then boot normally. If it doesn't work,
you can unlock from the initramfs and try again.
In my case, things weren't normal: a graphical password prompt showed up,
but I couldn't enter the password to continue. See below.
Encrypting your swap
--------------------
Encrypting your swap partition(s) is relatively easy.
* Look for the partition name(s) for your swap folder.
* Edit /etc/crypttab to add the encrypted swap partition. For my /dev/sda6 swap,
I added this line: (cryptswap1 should be a unique identifier, see next step)
cryptswap1 /dev/sda6 /dev/urandom swap,cipher=aes-cbc-essiv:sha256
* Edit /etc/fstab to add your unencrypted swap partition there. Comment or
remove the existing swap and replace with:
/dev/mapper/cryptswap1 none swap sw 0 0
* After that I could simply reboot.
Changing passwords
------------------
You can change your encryption passwords using the Disks utility. Using
cryptsetup on the command line you can add additional passwords (useful if
you'd like to share access to the computer but not your password).
The password is only used to access the encryption keys, so you don't need
to re-encrypt the volume to change or add passwords.
Fancy trick: Unlocking through SSH
----------------------------------
After this procedure, your computer will only boot if you enter the password.
If you would like to unlock remotely (if, for example, your computer is in some
hard-to-reach place on the 25th floor) you can unlock it through SSH.
(Instructions based on a.o. https://hamy.io/post/0009/how-to-install-luks-encrypted-ubuntu-18.04.x-server-and-enable-remote-unlocking/)
To do this, you can install a tiny SSH server in the initramfs image. This
gets loaded during the boot process, you can connect to it and unlock the
partitions.
* Install dropbear-initramfs (the Dropbear SSH server):
sudo apt install dropbear-initramfs
* Edit the Dropbear configuration to attach it to port 2222:
sudo vim /etc/dropbear-initramfs/config
change:
DROPBEAR_OPTIONS="-p 2222 -s -j -k -I 60"
* Next, add your public key to the list of authorized keys (you can't use
password-based login to connect): edit /etc/dropbear-initramfs/authorized_keys
* Your computer will need an IP address. Change the DHCP settings to add your
hostname. Add to /etc/initramfs-tools/initramfs.conf: (change the hostname)
IP=::::bigr-gpu-gijs
* Update your initramfs image:
update-initramfs -uv
* Reboot.
* Before showing you the encryption prompt, your computer will start the SSH
server on port 8022. In my case it also prints the IP address.
(Since nothing ever works the first time I try it: I had some problems with
Ubuntu 18.04 because the IP address assigned during boot was different from
the IP address after booting. See "Problem 4" below if you run into this.)
At this point you have two options: you can enter the password using a
keyboard, like before, or you can do this through SSH. For this, you connect
to port 2222 and authenticate as root using your private key. For example:
ssh root@bigr-gpu-gijs -p 2222
Then run "cryptroot-unlock" and type the password. Type exit at the end.
Encryption keys unlocked, your computer will then boot normally.
Problem 1: No cryptsetup in initramfs
-------------------------------------
I didn't know I had to check for the cryptsetup utility in my initramfs, so I
couldn't unlock my locked partitions during boot. I had to rebuild my initramfs
from the Live CD environment. Here are my notes for that episode:
# http://forums.debian.net/viewtopic.php?t=52283
# (replace with mapped LUKS partition)
mount /dev/mapper/luks /media/disk
mount /dev/mapper/luks /media/disk/var
mount /dev/sdb1 /media/disk/boot
mount -o bind /sys /media/disk/sys
mount -t proc /proc /media/disk/proc
mount -o bind /dev /media/disk/dev
chroot /media/disk
# make backup of initrd.img
# add to /etc/initramfs-tools/initramfs.conf
CRYPTSETUP=y
# use own kernel (not that of live cd)
CRYPTSETUP=yes update-initramfs -c -k 4.4.0-142-generic -v
# reboot
Problem 2: No working password prompt on Ubuntu 16.04
-----------------------------------------------------
During the boot process, I could see the password prompt but couldn't type.
(The password showed up on the side of the screen.) This might have to do
with my Nvidia drivers, or something specific to my installation. I "fixed"
it by disabling the graphical splash screen). My computer now boots with
a text view, with a working password prompt.
# https://askubuntu.com/questions/803874/boot-no-luks-password-prompt?rq=1
# https://bugs.launchpad.net/ubuntu/+source/plymouth/+bug/1386836
# password entering problems
open /etc/default/grub and remove the "splash" argument
update-grub and reboot
Problem 3: Encrypting your /boot drive
--------------------------------------
For my setup, the /boot folder with the initramfs starting bits is on
a separate, unencrypted volume. If you want to encrypt this volume as well,
you would need to change your GRUB settings to include the LUKS module.
(Some search ideas: "insmod luks", "cryptomount".) It's slightly complicated,
but possible.
Since there's no actual data on the /boot partition, I don't think it is
necessary to encrypt this. It's apparently useful to protect you from
attackers who alter your /boot procedure to capture your password or do
other nefarious things. Since our encryption is mostly to prevent data loss,
I skipped this extra protection. (And if you do enable it, I think you
should also do daily checks of your keyboard to see if someone replaced it
or attached a keylogger to your USB port.)
Problem 4: The initramfs IP address is different from your normal IP
--------------------------------------------------------------------
On Ubuntu 18.04, the DHCP request to obtain an IP address might give you
a different IP address during boot than after booting. This makes it harder
to log in to unlock the encryption (since you don't know the IP ...).
Apparently, this is caused by the modern way Ubuntu 18.04 does DHCP
(it may or may not be using your MAC address as the client ID).
An effective, if drastic solution that worked for me was to disable the
modern systemd-networkd network configuration and go back to the
older-but-functional /etc/network/interfaces option.
Brief steps (based on https://askubuntu.com/questions/1031709/ubuntu-18-04-switch-back-to-etc-network-interfaces):
# edit /etc/network/interfaces and add your network cards:
source /etc/network/interfaces.d/*
auto lo
iface lo inet loopback
auto enp6s0
iface enp6s0 inet dhcp
# install ifupdown (the old networking tool) and disable netplan/systemd-networkd:
apt install ifupdown
ifdown --force enp0s3 lo && ifup -a
systemctl stop systemd-networkd.socket systemd-networkd networkd-dispatcher systemd-networkd-wait-online
systemctl disable systemd-networkd.socket systemd-networkd networkd-dispatcher systemd-networkd-wait-online
systemctl mask systemd-networkd.socket systemd-networkd networkd-dispatcher systemd-networkd-wait-online
apt-get --assume-yes purge nplan netplan.io
@MrPrimate
Copy link

FYI this guide works with UEFI. Many thanks for this detailed writeup 👍

@iliis
Copy link

iliis commented Dec 6, 2020

Thank you, this was indeed useful on Ubuntu 18.04. Some additional hints:

  • Instead of editing /etc/initramfs-tools/initramfs.conf, you have to set CRYPTSETUP=y in /etc/cryptsetup-initramfs/conf-hook instead (on Ubuntu 18.04). Altough I get the impression that if you have a correctly setup /etc/crypttab (including a 'root' entry, maybe with the 'initramfs' option), cryptsetup will be automatically added to the initramfs (I haven't tested this though).

  • To verify if your initramfs contains /sbin/cryptsetup:

lsinitramfs /boot/initrd.img-4.15.0-126-generic | grep /sbin/cryptsetup

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment