Encrypted Partitions in Ubuntu
Published Aug 18, 2019
Reading time 10 minutes
New Install with Encryption and Separate Home Partition
I’ve been using Ubuntu 17 on my laptop for too long because updating was going to take me ages to restore everything and I wanted to get rid of my Windows partition - I haven’t booted into it in over a year and I don’t need it anymore.
My requirements for upgrading were:
- Upgrade Ubuntu
- Encrypted drive
- Remove the Windows partition
- Separate partition for home drive
Unfortunately Ubuntu doesn’t give the option to create a separate partition for your
/home directory which Debian does through the installer GUI. I really wanted to do this so it will be easier for me in the future to upgrade the distro - although obviously I’ll make sure I have back ups too!
I found this fantastic post by Vito Botta explaining how to do exactly what I needed which worked perfectly apart from a few little tweaks which I’ve listed below. I’ve written an explanation to what the steps in the post are doing as I wanted to learn and understand a bit more about what was going on.
I recommend following Vito’s tutorial step by step and read the below explanations alongside each step as you go along. This will mean you’re understanding what’s going on and if you have any problems you can debug it easier.
To complete the partitioning and encryption, you will need to:
- Set up the disks partition table
- Partition the disk for
- boot loader
- home directory
- optional swap partition
- Install the new Ubuntu image
- Encrypt the device
- Set to decrypt during boot
Before you begin
To be able to format the whole disk, you need to not be using the disk. Which is where booting from a USB or disk comes in. When you’re working from the USB you can download extra tools to help if you need to. One gotcha I came across was to make sure you can install software from the whole universe, this is disabled by default on the bootable USB image.
I used a USB with Ubuntu 19.04 installed, the instructions I followed were the official Ubuntu guide here.
In the gparted section, you create a new GUID partition table (type gpt table). This is the standard layout for a physical computer storage device, in this case my laptops hard drive but can also be a USB. Here’s a brief overview of what this step is doing.
EFI: Extensible Firmware Interface file, this is an executable file that tells the boot processor what to do
EFI System Partition labelled “ESP”: an EFI System Partition (ESP) is for the EFI files of the installed system and applications to be stored for the firmware at startup.
FAT32: File Allocation Table, the table is indexed statically at the time of formatting. The OS can then quickly and easily traverse the entries for the file it needs. Unused space or reserved space is also marked.
"ESP" bootflag- this tells the bootloader which partition to boot from and where the boot code is located.
Once apply is clicked, the partition is physically done on the target device. This is then creating your partition identified as the
/dev/sda1 partition - this is the standard but as Vito points out, your setup may differ.
dev- device file (interface to device drivers)
s- originally SCSI subsystem (Small Computer System Interface) now any block device capable of transferring data
a- first disk (subsequent disks are sdb etc)
1- partition number
After starting the Ubuntu installer and choosing “Something else” for custom partitioning, you create an ext2 partition of 512MB that will be used as
/boot (I changed the sizes later on, instructions below).
/boot contains the static files for the boot loader during the boot process. This partition will be identified as
The partition for the remaining disk space is “physical volume for encryption”, the encrypted partition for all files, your
/home directory. This partition will be identified as /dev/sda3.
Setting up the LVM volumes
Logical Volume Manager provides an abstraction between the operating system and the physical disks and partitions. Creating the volumes through LVM allows us greater control of the volumes and the sizes. We’ll need sudo privileges to do this.
$ sudo -s
Start an interactive shell with super user privileges
# vgcreate system /dev/disk/by-id/dm-name_sda3_crypt
💡 Note The
# prompt here denotes that we’re in an interactive session
vgcreate system: creates a Volume Group with a Volume Group Name of
system. The Volume Group groups physical and logical volumes together.
/dev/disk/by-id/dm-name_sda3_crypt: this is the Physical Device Path of the physical volume that’s in the group (you can have multiple volumes in the group)
# lvcreate -L 2G -n swap system # lvcreate -L 30G -n root system # lvcreate -l 100%FREE -n home system
lvcreate: create logical volumes within a Volume Group- a logical volume can be multiple physical hard drives and can be resized.
30G: logical volume size of i.e 2 gigabytes
home: the name of the Logical Volume
system: the Volume Group Name to create the logical volume within
100%FREE: all the remaining free space of the Volume Group, so the rest of the volume is used for the
💡 Note LVM makes it easy to manage partition sizes, I changed my volume sizes once I’d completed the install and I was happy everything was working ok.
The swap partition - this is dedicated space on the hard drive for storing temporary data that can no longer be held in RAM. Having more space to hold older data may help although your computer will always prefer RAM and swap isn’t a good alternative to physical memory - I recommend reading the Ubuntu help guide for more information.
Once the volumes have been created, the installer maps where the new installation will access the volumes and for what.
Proceeding with the installation installs the new image using the partitions we have set in the previous steps. At this point we have a partition for
/swap so we have a
/home point we mount at boot time. The next step will encrypt it.
Installation complete - don’t reboot
Now we have our device
sda3 ready, we can set it up so it’s encrypted and we can mount it and encrypt it at boot time.
$ blkid /dev/sda3
This command prints the attributes of the block storage
Then the volume needs adding to the crypttab file which holds the information for encrypted file systems, it’s read by
cryptdisks_start to setup the managed device mappings.
$ echo 'sda3_crypt UUID=(the uuid without quotes) none luks,discard' > /target/etc/crypttab
This command writes to the
crypttab file, note - the UUID is entered with no brackets around it.
sda3_crypt: this is the target device file name
uuid: the source device, either an encrypted file or a block special device. The device UUID is supported as a way to provide the information about the device
none: this field is for saving the key information for decrypting that data. Giving
noneas the passphrase means the key will be read interactively from input.
luks: this is the cryptsetup options to specify luks (Linux Unified Key Setup) for the encryption process to use
discard: this is an optional flag, from the man page: allow discards (TRIM) requests for device. When deleting data from a device, the garbage collector manages the empty space but if the data was encrypted, the data may be recoverable if it hasn’t been written over. If this is a security concern - further research should be done before setting this option.
⚠️ Note If you get the error
bash: /target/etc/crypttab: No such file or directory after running this command, try this solution from the comments section:
I had the same issue and I solved it by mounting manually the created volumes before editing the crypttab file :
$ mount /dev/system/root /target $ mount /dev/sda2 /target/boot $ mount /dev/sda1 /target/boot/efi
<br> <span class="author">— Cyril Nguyen</span>
Chroot into the new installation
During the new image installation, the installer mounts devices for the installation process under the directory
target. To continue with the setup, we need to do some additional steps to the target device ready for booting. It’s safer to
chroot - change the root directory so changes are only made to
target and everything’s scoped within that
target location - like paths for example.
$ mount -t proc /proc /target/proc
⚠️ Note there’s a missing backslash before the second
proc in the article, be sure to add it in
mount: mounts the given file system
-t proc: the
tflag specifies the type of file,
diris the default if none is specified. Here we specify
/procwhich is a pseudo-filesystem for easily interfacing with kernel data.
/proc /target/proc: the file to mount and the destination where to mount it
$ mount --rbind /sys /target/sys $ mount --rbind /dev /target/dev
--rbind: remount a subtree and all possible submounts to the destination so it’s also available in the new destination.
/dev: the currently mounted subtrees
/target/dev: the destination where the new devices will be available, in this case the target (new installation)
$ chroot /target
Chroot temporarily changes the root directory, the
target directory becomes the root and we can now do things like
ls /dev and see the content of the
Installing the bootloader
The installer will have already set this up but because we didn’t choose to encrypt the device during the installation, the boot process isn’t set up for encryption. Now we have a device set up for encryption we manually install the bootloader again so it is configured correctly and replace the existing bootloader.
GRUB, GRand Unified Bootloader, is the bootloader for Ubuntu and most Linux distributions.
$ grub-install --target=x86_64-efi --efi-directory=/boot/efi --bootloader=ubuntu --boot-directory=/boot/efi/EFI/ubuntu --recheck /dev/sda
grub-install: install GRUB to a device
--target: the target platform
--efi-directory: specify where the EFI system partition is
--bootloader: the bootloader to use, here we are using Ubuntu
--boot-directory: where to put the boot images
--recheck: deletes the device map if it already exists. The device map file is used by GRUB to map BIOS drives to OS drives
$ grub-mkconfig --output=/boot/efi/EFI/ubuntu/grub/grub.cfg
grub-mkconfig: Generates a GRUB config file
--output: outputs the generated config to the given file
$ update-initramfs -ck all
update-initramfs: generates an initramfs image. The initramfs is an archive that is unpacked at boot time into a ram disk and is the first point of access to the root file system which allows mounting of the actual system devices. This happens in userspace (not within the kernel) which allows the decryption of the device before the boot has completed.
-c: creates a new initramfs
k all: kernel version, passing
allsets it for all known kernel versions
reboot to exit the target device and reboot the system.
Update partition sizes
Once the partitions are set using LVM, it’s fairly straightforward to make changes to the partitions.
You’ll need to use the bootable USB again as you can’t make changes to devices that are mounted and in use.
I used the KDE partition manager
$ sudo apt install partitionmanager
⚠️ Note ensure you can install software outside of the Ubuntu software centre as mentioned here.
I had to unmount the partition first, go to Partition → Mount/Unmount to unmount and then you can change the sizes if required.
Vito post detailing all the steps for partitioning and encrypting a new Ubuntu installhttps://vitobotta.com/2018/01/11/ubuntu-full-disk-encryption-manual-partitioning-uefi/
Guide for creating a bootable USB with Ubuntu on ithttps://tutorials.ubuntu.com/tutorial/tutorial-create-a-usb-stick-on-ubuntu
Ubuntu help on swap partitionshttps://help.ubuntu.com/community/SwapFaq