How to set up full-disk encryption on Linux

Overview:
This article guides the reader through configuring full-disk encryption (including swap) on Linux, using LUKS and LVM. It covers two main scenarios: a single drive (for example, most laptops) and multiple drives. The guide assumes user’s familiarity with Linux shell and some basic tools. It also doesn’t cover the process of installing the OS itself, and only focuses on configuring the encryption.

The process has been tested on numerous versions of Ubuntu and should be the same or very similar on most other distributions.

Summary:
First, a desired partition layout is prepared - a single unencrypted partition for /boot and LVM volumes created inside encrypted LUKS containers for the other files. Regardless of how many disks are being used, user is only asked for a single passphrase to unlock the encrypted drive(s). This is accomplished by using key files for encrypting all of secondary drives - key files are stored in the /root directory which is located on the primary LUKS container. This setup allows for a reasonable compromise between security and convenience.

How-to:

  1. Boot the system from the installation media and follow the installation process to the point where you are asked for specifying the disk layout for the new OS.

  2. Prepare the partitions using your tool of choice (fdisk, (g)parted etc.) as per the following example:

    /dev/sda1 - 1GB unencrypted partition for /boot
    /dev/sda2 - remaining space of the first disk for the / mount point
    /dev/sdX1 - additional disks to be encrypted and used during the installation, for example for /home, /var etc.

note: if you plan on installing your OS in UEFI mode (and there isn’t already another UEFI-enabled OS installed on your computer) you will also need to create a small FAT32 partition for the EFI; it shouldn’t need more than 200MB and needs to be mounted at /boot/efi.

  1. Use the partitions made in the previous step to create LUKS containers and decrypt/unlock them. Make sure to securely store the passphrases - you will NOT be able to boot into the OS and access any of your data if you don’t have the correct passphrase.

    # cryptsetup luksFormat /dev/sda2
    # cryptsetup luksFormat /dev/sdX1

    # cryptsetup luksOpen /dev/sda2 encryptedroot
    # cryptsetup luksOpen /dev/sdX1 encrypteddiskX

  2. Prepare LVM partition inside the LUKS containers. First, we use LUKS containers as LVM physical volumes, add them to volume groups and then we create logical volumes, on which the OS will be installed.

    # pvcreate /dev/mapper/encryptedroot
    # pvcreate /dev/mapper/encrypteddiskX

    # vgcreate vgencryptedroot /dev/mapper/encryptedroot
    # vgcreate vgencrypteddiskX /dev/mapper/encrypteddiskX

    # lvcreate -n lvencryptedswap -L 5G vgencryptedroot
    # lvcreate -n lvencryptedroot -l 100%FREE vgencryptedroot
    # lvcreate -n lvencrypteddiskX -l 100%FREE vgencrypteddiskX

note: in the above example a 5GB partition will be created for swap - adjust the size appropriately as per your requirements.

  1. Switch back to the installer and select manual setup for disk layout. Specify the appropriate mount points and file systems, for example:

    /dev/sda1 - /boot (ext2)
    /dev/mapper/vgencryptedroot-lvencryptedroot - / (ext4)
    /dev/mapper/vgencryptedroot-lvencryptedswap - swap (swap)
    /dev/mapper/vgencrypteddiskX-lvencrypteddiskX - /home, /var etc. (ext4)

  2. Finish the installation of the OS but do NOT restart the PC. When you are done switch back to the terminal and identify UUIDs of the partitions you used during installation:

    # blkid /dev/sda2 - root partition
    # blkid /dev/sdX1 - secondary partitions

  3. Temporarily mount the new OS under /mnt and chroot into it. You only need to interact with the root partition, there is no need to mount any of the secondary partitions.

    # mount /dev/mapper/vgencryptedroot-lvencryptedroot /mnt
    # mount /dev/sda1 /mnt/boot
    # mount --bind /dev /mnt/dev
    # chroot /mnt
    # mount -t proc proc /proc
    # mount -t sysfs sys /sys
    # mount -t devpts devpts /dev/pts

  4. In a separate session (outside of the chrooted environment) create the encryption key files for automatically decrypting your secondary partitions at boot time. Don’t forget to lock down the permissions for those files.

    # dd if=/dev/urandom of=/mnt/root/diskX.key bs=1024 count=4
    # chmod 0400 /mnt/root/diskX.key

  5. Add the keys to appropriate LUKS containers:

    # cryptsetup luksAddKey /dev/sdX1 /mnt/root/diskX.key

  6. Go back to the chrooted environment and create the crypttab file (/etc/crypttab) where you specify all of your encrypted partitions and their configuration details:

    encryptedroot UUID=</dev/sda2’s UUID> none luks, retry=1,lvm=vgencryptedroot
    encrypteddiskX UUID=<dev/sdX1’s UUID> /root/diskX.key luks,retry=1,lvm=vgencrypteddiskX

  7. Generate the updated initramfs image:

    # update-initramfs -u

  8. Profit!

At this point you should be able to reboot your computer and boot into the new OS. At boot time, you will only be asked to enter the passphrase for the primary partition (encryptedroot, in the above example) and all secondary partitions will be automatically decrypted using keys stored in /root folder.

3 Likes

Very nice write-up! I could have used this on numerous occasions.