Skip to content

System encryption

KrisWebDev edited this page Oct 20, 2018 · 11 revisions

Introduction

This is a guide to setup a (plausibly) deniable, fully encrypted and bootable Linux system. It uses cryptsetup-deluks for the operating system and grub-crypto-deluks for the bootloader. It's written for and tested on Ubuntu 16 (Xenial Xerus).

System encryption provides the highest level of security and privacy, because the root and swap filesystems (including /tmp, /var/logs, /etc, etc.) are always permanently encrypted. See also: Is Encrypting Home Sufficient?

One drawback of deniable encryption when using SSD disks, whatever the software, is the potential impact on SSD write performance and lifetime. This is because cryptsetup disables TRIM by default for security reasons. TRIM must be kept disabled for deniability.

Warning: Deniable encryption alone doesn't protect from:

Current limitations:

At this time, the DeLUKS encrypted volume must be a full disk or an existing partition. It can't be located on unallocated disk space of a partitioned drive (grub-crypto-deluks supports it but cryptsetup-deluks not yet).

If you choose full disk encryption:

  • If you want a fake OS (recommended), you need a second physical disk or partition to host the fake OS.
  • You need another drive or USB key to store the bootloader.

If you choose to use a partitioned drive, there is no particular limitation.

Install: DeLUKS system encryption setup

Install the Fake OS

A machine with just a bootloader and no bootable system is suspicious. You need a fake OS. In our setup, this fake OS will be unencrypted.

Boot on the Ubuntu Live CD to install a fake OS:

  • Install the fake OS unencrypted somewhere on a drive.
    • Of course, you need a drive with a partition table to make it bootable.
    • You can limit the disk space used by the swap and system.
    • Choose to install the boot loader wherever you want (but, of course, not on a fully encrypted drive).

Install grub-crypto-deluks from the Fake OS

Until the eventual day when DeLUKS is merged into mainstream GRUB, you can't deny that your bootloader is grub-crypto-deluks and that you installed it. The same goes for all bootloaders, including grub-crypto, veracrypt, etc. There is currently no mainstream bootloader with deniable encryption support. So install grub-crypto-deluks from the fake OS.

Alternatively, you can install grub-crypto-deluks from the Ubuntu Live CD, onto an USB key. But how suspicious is it to have an USB key containing just a bootloader supporting deniable encryption?

Boot on the fake OS:

Install the real OS in an encrypted DeLUKS volume

The drive that will host the real OS is hereafter named /dev/sdb

Reboot on the Ubuntu Live CD:

  • Select to Try Ubuntu.
  • Install cryptsetup-deluks on the Live environment: Follow cryptsetup-deluks:README#install
    • Wipe the drive that will host the real OS
    • Create the DeLUKS volume on this drive
    • Open the DeLUKS volume
  • Launch Ubuntu installer to install the real OS:
    • Installation type: Something else
      • Select the DeLUKS device /dev/mapper/deluks_vol
        • Create a new partition table
        • Create the swap partition (swap size considerations, thumb rule: equal to your RAM size)
        • Create the ext4 system primary partition with / root mountpoint
        • Choose to install the bootloader on /dev/mapper/deluks_vol (we don't want the real OS to write anything unencrypted, including its own bootloader).
      • Modify other swap partitions to not use them (including the fake OS swap)
      • Install but don't reboot: Press Continue to test

Ubuntu install disks

Screenshot details: /dev/sda contains the fake OS, /dev/sdb contains the encrypted DeLUKS volume and /dev/mapper/deluks_vol is the decrypted DeLUKS view. /dev/mapper/deluks_vol is partitioned and contains the real OS bootloader, swap and root filesystem. linux-swap instead of just swap shows the fake OS swap will not be used.

Make the real OS bootable

Start a root terminal, still from the Live CD.

sudo su

Adjust the 3 following variables based on your setup:

partprobe 2>/dev/null
blkid; lsblk -o NAME,FSTYPE,SERIAl,SIZE,LABEL,MOUNTPOINT

ENCRYPTED_DEVICE_BY_NAME="/dev/sdb"
DELUKS_VOLUME="deluks_vol"
DELUKS_ROOT_PARTITION="deluks_vol2"

Mount the real OS filesystem:

mkdir -p /mnt/ubuntu
mount /dev/mapper/"$DELUKS_ROOT_PARTITION" /mnt/ubuntu

Dump the DeLUKS master keyfile on the real OS /root folder:

Why dumping?

  • The real OS initramfs needs to be aware of the keyfile to decrypt the drive.
  • GRUB can't currently pass the keyfile from cryptomount to the initramfs.
  • So the keyfile needs to be stored in the initramfs.

Why storing it on the real OS /root ?

  • When the DeLUKS volume is open, only root can access the keyfile (default chmod 400) and is aware of its existence (only root can list /root).
  • When the DeLUKS volume is closed, the keyfile is encrypted with the filesystem and cannot be accessed.
  • Initramfs may be rebuilt from within the real OS during upgrades, so the real OS needs to access it.
rm -f /mnt/ubuntu/root/crypto_keyfile.bin
cryptsetup deluksDump "$ENCRYPTED_DEVICE_BY_NAME" --dump-master-key-file="/mnt/ubuntu/root/crypto_keyfile.bin"

Copy cryptsetup-deluks initramfs cryptroot hook and boot scripts:

To reference the real OS root drive, crypttab can't be used, as it doesn't support DeLUKS (cryptsetup --type=deluks) nor plain-mode with a device size (cryptsetup --size). Instead, use the provided initramfs hook and boot scripts (?) to decrypt the drive and mount the root file system.

cp cryptsetup-deluks/scripts/cryptroot-hook /mnt/ubuntu/etc/initramfs-tools/hooks
chmod 700 /mnt/ubuntu/etc/initramfs-tools/hooks/cryptroot-hook
chmod -R go-rwx /etc/initramfs-tools/hooks

cp cryptsetup-deluks/scripts/cryptroot-boot /mnt/ubuntu/etc/initramfs-tools/scripts/local-top
chmod 700 /mnt/ubuntu/etc/initramfs-tools/scripts/local-top/cryptroot-boot
chmod -R go-rwx /etc/initramfs-tools/scripts

Auto-configure cryptroot boot script:

Avoid changing the cryptroot ENCRYPTED_DEVICE to something else than /dev/sdX. You can't reference the DeLUKS drive by UUID or label as these information are encrypted. You should not reference the drive by ID (Serial Number, /dev/disk-by-id/) unless you know the prefix initramfs appends to the path.

sed -i -e "0,/^ENCRYPTED_DEVICE/s/\(^ENCRYPTED_DEVICE=\).*/\1\"${ENCRYPTED_DEVICE_BY_NAME//\//\\/}\"/" \
  -e "0,/^DELUKS_VOLUME/s/\(^DELUKS_VOLUME=\).*/\1\"${DELUKS_VOLUME//\//\\/}\"/" \
  -e "0,/^DELUKS_ROOT_PARTITION/s/\(^DELUKS_ROOT_PARTITION=\).*/\1\"${DELUKS_ROOT_PARTITION//\//\\/}\"/" \
  /mnt/ubuntu/etc/initramfs-tools/scripts/local-top/cryptroot-boot
echo -e "\e[44mThis is your cryptroot-boot config, edit if inexact:""\e[0m"; grep "^ENCRYPTED_DEVICE" /mnt/ubuntu/etc/initramfs-tools/scripts/local-top/cryptroot-boot -A2 --color=NEVER

Copy cryptsetup-deluks source to the real OS:

rm -rf /mnt/ubuntu/root/cryptsetup-deluks
cp -r cryptsetup-deluks /mnt/ubuntu/root

Chroot into the real OS:

cd /mnt/ubuntu
mount -t proc proc proc/
mount -o bind /dev/pts dev/pts
cp /etc/resolv.conf /mnt/ubuntu/etc/
chroot /mnt/ubuntu

Install cryptsetup in the chrooted real OS:

if ! grep "universe" "/etc/apt/sources.list" &>/dev/null; then echo "please enable universe repository, through software-properties-gtk"; software-properties-gtk &>/dev/null ; else echo "OK"; fi
sudo apt-get install git libgcrypt11-dev libdevmapper-dev libpopt-dev uuid-dev libtool automake autopoint debhelper xsltproc docbook-xsl dpkg-dev lvm2
cd /root/cryptsetup-deluks
CRYPTLIBDIR=`dirname $(dpkg -L libcryptsetup4 | grep libcryptsetup.so.4$)`
echo $CRYPTLIBDIR
./autogen.sh --prefix=/usr --sbindir=/sbin --libdir="$CRYPTLIBDIR"
make
sudo make install

Update the chrooted real OS initramfs:

update-initramfs -u

Reboot. Eject the Live CD.

Run: DeLUKS system encryption setup

At GRUB menu, press c to get into GRUB shell.

If you don't see GRUB menu because you didn't comment GRUB_HIDDEN_TIMEOUT, press and hold (SHIFT) during boot (english keyboard only).

At GRUB shell:

cryptomount -x /
# Type your password
# If needed: ls
set root=(crypto0,msdos2)
configfile /boot/grub/grub.cfg

Boot process will be even quicker in future versions.

The real OS now boots.