Installing Gentoo On An Encrypted Root Partition


There are times when one needs to be able to know that if a computer's hard drive falls into the wrong hands that the information on it cannot be harvested. This is increasingly needed for laptops, desktops, and servers whose hard drives may be storing required-to-be confidential material. Of course, it need not only be such, but, one may wish to have the peace-of-mind that his/her contact information and other personal data is also not accessible (e.g., should their laptop be stolen). The purpose of this post is to detail how configure the Gentoo Linux operating system so that it boots from an encrypted root partition.

DISCLAIMER: Use of this post in any manner is completely and totally at your own risk. You are responsible for what you do with your own equipment/installations. Always read all documentation before using any commands.

Installation Media

In order to install the operating system, one first needs to be able to:

  • boot from a CD/DVD capable of installing Gentoo,
  • be able to partition the hard drive using software on the CD/DVD,
  • be able to run cryptsetup from the CD in order to format the hard drive with encryption,
  • be able to run LVM (Logical Volume Management) software from the CD/DVD, and,
  • be able to format the logical volumes created so the operating system can be installed.

Unlike a normal operating system installation, one cannot reboot the computer and boot into the operating system until enough software is installed so the operating system can actually mount the root partition. Further until such is made to work the only recourse one has is to have reliable boot CDs/DVDs with the required software programs needed to mount partitions so any issues can be fixed.

IMPORTANT: Ensure you have working bootable media on hand before you start. This is especially important if you need to stop and resume things later: make sure you have the necessary bootable media!

The simplest way to ease the burden of an installation is to use the latest Gentoo LiveDVD as it boots a fully working copy of Gentoo Linux with KDE, etc. It also has all of the tools, including cryptsetup, as well as the necessary kernel modules for encryption compiled into the Linux kernel. Without the proper kernel modules, it will not be possible to format the root partition with encryption.

NOTE: The minimal CD for Gentoo is very minimal and nearly everything has to be done manually. Unless you are used to this, I would not recommend using it. The LiveDVD, despite its large size, is much nicer as it configures the network (if it uses DHCP), has firmware for various network cards, can be used with KDE or simply as a text console, has all of the tools needed to encrypt, format, and mount hard drive paritions, etc. This post assumes the use of the LiveDVD. Briefly, the LiveDVD is nice, and convenient whereas the minimal CD is tedious.

Assumptions And Definitions

It is assumed herein:

  • the installation media is the Gentoo Linux LiveDVD (or equivalent),
  • the hard drive is to only have Linux installed on it,
  • there is only one hard drive,
  • Internet access is present, and,
  • a USB memory stick (or equivalent) is on-hand to hold encryption keys needed to boot the system.

You must have a USB memory stick! Do not store any keys on the hard drive.

The following variables are used below to represent a number of things that are system dependent:

Variable Definition
BOOT_DEV Device name of the (unencrypted) boot partition.
ENC_HDD A name given to the cryptsetup-created encrypted device made after calling luksOpen.
INST_HDD Installation hard drive's device name, e.g., /dev/sda. /dev/hdc, etc.
KEY_DEV USB memory stick device name.
KEY_FILE Full path to encryption key.
KEY_MOUNT Mounted directory path for $KEY_DEV.
ROOT_DEV Device name of the (encrypted) root partition.
ROOT_NAME The name of the root logical volume, e.g., root.
SWAP_NAME The name of the swap logical volume, e.g., swap.
VG_NAME The name of the volume group used with LVM, e.g., vg_hostos.

If You Get Stuck…

Since this post is very long, this helpful section is given before the start of any instructions so that it will be noticed and used if needed. If you get stuck after the encrypted partitions have been created and had to shutdown or reboot, then these are the steps to get back up-and-running:

  1. Boot the LiveDVD.
  2. Open a Konsole/Terminal window.
  3. If the network is not already set up, configure it.
  4. Insert and mount your USB key that holds the encryption key.
  5. Mount the encrypted partition so it can be used:
    cryptsetup --key-file $KEY_MOUNT/key.bin luksOpen $ROOT_DEV $ENC_HDD
  6. Activate the volumne group:
    vgchange -a y $VG_NAME
  7. Activate the swap partition:
    swapon /dev/$VG_NAME/$SWAP_NAME
  8. Run:
    mkdir -p /mnt/gentoo
  9. Mount the (encrypted) root partition:
    mount /dev/$VG_NAME/$ROOT_NAME /mnt/gentoo
  10. Run:
    mkdir -p /mnt/gentoo/boot
  11. Mount the (unencrypted) boot partition:
    mount $BOOT_DEV /mnt/gentoo/boot
  12. Copy resolv.conf over from the LiveDVD set up:
    cp -L /etc/resolv.conf /mnt/gentoo/etc/
  13. Mount /proc so it will be accessible from the chroot jail:
    mount -t proc none /mnt/gentoo/proc
  14. Mount /dev so it will be accessible from the chroot jail:
    mount --rbind /dev /mnt/gentoo/dev
  15. Enter a chroot jail on the encrypted drive:
    chroot /mnt/gentoo /bin/bash
  16. Use the environment from the hard drive:
  17. Source /etc/profile:
    source /etc/profile
  18. Fix the prompt to indicate that the chroot jail is active:
    export PS1="(chroot) $PS1"

and then you can perform any required work. Obviously, if you did not create the swap partition or other details, some of the above commands given will not work.

Installation Steps

Partition The Hard Drive

After booting the LiveDVD, use any partition manager to partition the hard drive (e.g., fdisk, gparted, etc.). If you want to partition the drive with GPT then you must install it first:

emerge -av gptfdisk

Create two partitions:

Partition Notes
$BOOT_DEV FDISK type = 83, GPT type = 8300.
Minimum size = 16 MiB. Will remain unencrypted and needs to be large enough to hold contents of /boot.
$ROOT_DEV FDISK type = 7, GPT type = 0700.
Fill rest of hard drive.

Modern hard drives are faster if these partitions are aligned on 2048-byte (or megabyte in gparted) boundaries. This can be set in the expert menu in fdisk and gdisk.

Populate $ROOT_DEV With Random Data

This step is optional but one would likely want to have any previous hard drive content to appear no different than random data. To do this run the following command:

dd if=/dev/urandom of=$ROOT_DEV bs=2048

Create The Encryption Key

In order to encrypt the hard drive one needs to use one or more of:

  • a (long) passphrase, and/or,
  • a random file of binary data which can be encrypted with a passphrase using GPG later.

Ideally, one wants to have a very strong key and would normally choose to create a file with random data. The size of this file depends on the encryption method used. Herein we'll use the AES (i.e., the aes-xts-plain kernel module) with 512 bytes of random data. This key should be generated somewhere other than the installation hard drive (i.e., use the USB memory stick). One can do this with the following steps:

  • Insert and mount the USB memory stick.
  • Change the current directory to the USB memory stick.
  • Create a key file using /dev/random (which requires activity on the computer for entropy):
    head -c 512 /dev/random >keyfile.bin
  • Note that $KEY_FILE is $KEY_MOUNT/keyfile.bin below.

Seriously consider giving the keyfile a meaningful name. I would also suggest incorporating the hard drive's make, model, serial number, and partition number into its name. One can obtain such information without opening the computer by installing and running lshw.

If a passphrase is preferred, then don't specify any --key-file options to cryptsetup below. You can have up to eight (8) key files and/or passphrases set on any partition. If using passphrases, ensure that they are very long so as to have enough entropy. Instead of using passphrases, seriously consider using key files encrypted with GnuPG with a passphrase instead as used in this post.

Create And Mount The Encrypted Partition

Before any disk partition and data can be put onto the encrypted partition, it must first be formated using cryptsetup:

cryptsetup --cipher aes-xts-plain -s 512 \
  --key-file $KEY_FILE luksFormat $ROOT_DEV

NOTE: The Cryptsetup FAQ in response to the question, "Can I resize a dm-crypt or LUKS partition?" notes that aes-xts-plain can only be used for partitions less than 2 TiB. If the encrypted partition is to be greater than or equal to 2 TiB in size then use aes-xts-plain64.

Once the partition has been formatted (with respect to its encryption only), it can then be mounted to provide a device that appears to not be encrypted. Of course, the device is actually encrypted, but, for any programs to make use of it, it needs to have an unencrypted "view". The mount is accomplished using the following command:

cryptsetup --key-file $KEY_FILE luksOpen $ROOT_DEV $ENC_HDD

NOTE: Set $ENC_HDD to something meaningful. For example, if $ROOT_DEV is /dev/sda2 then perhaps set $ENC_HDD to hdd_a2.

The $ENC_HDD representing the unencrypted device is now online. If logical volume management (LVM) is used on it then $ENC_HDD should be thought of as a virtual encrypted hard drive. The full path of the device is: /dev/mapper/$ENC_HDD

Use LVM Create The Partitions To Install The Operating System

Instead of treating $ENC_HDD as a single partition, logical volume management (LVM) will be used to allow (i) the creation of a swap device and (ii) the root partition that the operating system will be installed on. One may not want to have Linux installed into one partition. If so, then instead of creating a single root partition, simply create all of the partitions, appropriately sized, as is appropriate for your circumstances.

Currently, there is only one "physical" (encrypted) volume, /dev/mapper/$ENC_HDD, and the LVM system must be told this (i.e., to create a physical volume):

pvcreate /dev/mapper/$ENC_HDD

With LVM, physical volumes are placed into (various) volume groups within which logical volumes (i.e., "partitions") are created. Since no previous volume groups have been created yet, one needs to be created:

vgcreate $VG_NAME /dev/mapper/$ENC_HDD

In order to do anything with a volume group, it must be activated:

vgchange -a y $VG_NAME

The swap partition should be on $ENC_HDD so it is encrypted. Should anything be swapped out to the hard drive, which will contain data from running programs, it will also be encrypted. Additionally, the swap partition should be contiguously stored, thus, the command used to create the swap partition is slightly different:

lvcreate -L$SWAP_SIZE --contiguous y -n$SWAP_NAME $VG_NAME

NOTE: $SWAP_SIZE will be a value such as 24G (which would be 24 GiB). See the lvcreate man page for further details.

The swap partition's device name is now /dev/$VG_NAME/$SWAP_NAME.

In order to create the root partition in a manner that uses all remaining space available in the volume group, the number of physical extents available needs to be obtained:

  vgdisplay | \
  egrep 'Free[[:space:]]+PE / Size' | \
  awk '{ print $5 }' \

Now the root partition can be created:

lvcreate -l $PESIZE -n$ROOT_NAME $VG_NAME

The root partition's device name is /dev/$VG_NAME/$ROOT_NAME.

Formatting And Mounting Required Partitions

In order to install and use the operating system a chroot jail will be needed and this will require (re-)mounting /dev and /proc in addition to the root and boot partitions so they are accessible from inside the chroot jail:

  1. Format the swap partition:
    mkswap /dev/$VG_NAME/$SWAP_NAME
  2. Turn on the swap partition:
    swapon /dev/$VG_NAME/$SWAP_NAME
  3. Format the root partition:
    mkfs.ext4 /dev/$VG_NAME/$ROOT_NAME
  4. Mount the root partition:
    mkdir -p /mnt/gentoo
    mount /dev/$VG_NAME/$ROOT_NAME /mnt/gentoo
  5. Format the boot partition:
    mkfs.ext4 $BOOT_DEV
  6. Mount the root partition:
    mkdir -p /mnt/gentoo/boot
    mount $BOOT_DEV /mnt/gentoo/boot
  7. Copy resolv.conf over from the LiveDVD set up:
    cp -L /etc/resolv.conf /mnt/gentoo/etc/
  8. Mount /proc so it will be accessible from the chroot jail:
    mount -t proc none /mnt/gentoo/proc
  9. Mount /dev so it will be accessible from the chroot jail:
    mount --rbind /dev /mnt/gentoo/dev
  10. Enter a chroot jail on the encrypted drive:
    chroot /mnt/gentoo /bin/bash
  11. Use the environment from the hard drive:
  12. Source /etc/profile:
    source /etc/profile
  13. Fix the prompt to indicate that the chroot jail is active:
    export PS1="(chroot) $PS1"

Install The Operating System

At this point one should follow the normal installation procedure for Gentoo Linux starting immediately after the steps of formatting and mounting all partitions. Ensure that these packages are also installed:

  • sys-fs/cryptsetup – Must be the same version or higher as what was on the LiveDVD.
  • sys-apps/busybox – If you want a decent shell within initramfs.
  • eix – An available package query tool.
  • sys-kernel/genkernel – Needed to easily build the kernel.
  • sys-kernel/gentoo-sources or sys-kernel/hardened-sources – Linux kernel sources.
  • app-crypt/gnupg – Needed for security (i.e., to have a passphrase on the keyfile).
  • sys-kernel/module-rebuild – Tool to build out-of-kernel kernel modules.
  • app-portage/portage-utils – Additional portage package management tools.
  • sys-apps/util-linux – For /sbin/blkid

Ensuring cryptsetup Version Is Correct

It is possible for the version of cryptsetup on the LiveDVD to be different from the version that is considered "stable" in the operating system. If an older version relative to the LiveDVD of cryptsetup is installed then the system will likely not be able to boot properly. In order to determine if the version of cryptsetup is the same or newer than the one on the LiveDVD, do the following:

  1. Open another console window (i.e., don't use any chrooted terminal session) and run this command as root to obtain the version of cryptsetup on the LiveDVD:
    cryptsetup --version
  2. In the chroot jail console, run:
    emerge cryptsetup
    cryptsetup --version

If the version of cryptsetup in the chroot jail console is older than the one in the LiveDVD console, then Gentoo must be told to use the newer version:

  1. Edit /etc/portage/package.accept_keywords/crypto to contain this line:
    sys-fs/cryptsetup ~amd64
  2. Re-emerge cryptsetup:
    emerge -av --autounmask=y --autounmask-write=y cryptsetup

Configuring And Building The Linux Kernel

After running emerge -av gentoo-sources or emerge -av hardened-sources the linux kernel will have been installed into /usr/src/linux. The steps to configure a Linux kernel are:

  • Run make menuconfig.
  • Set any and all settings.
  • Save and exit the tool.
  • Build the kernel, its modules, and initramfs.
  • Install such to /boot.
  • Ensure the boot loader (e.g., grub) is able to boot the kernel.

While one can roll their own kernel configuration, this post focuses on using genkernel with the gentoo-sources or hardened-sources packages for these reasons:

  • the genkernel utility completely automates everything, except this post will intentionally run make menuconfig manually,
  • booting using an encrypted root partitions as described in this post will require the following to be built and installed in initramfs:
    • statically compiling sys-fs/cryptsetup,
    • statically compiling app-crypt/gnupg,
    • statically compiling (optionally) sys-apps/busybox,
    • statically compiling in disklabel (UUID) support, and,
    • writing a script/program to prompt the user for a key-file or passphrase in order to be able to mount the encrypted system.

In short, using genkernel automates a number a lot of extra work that most won't need to be concerned with on practical level, especially if time-constrained. In order to have genkernel automate the kernel building process, do the following:

  1. Change the current working directory to /usr/src/linux:
    cd /usr/src/linux
  2. Copy the LiveDVD's kernel configuration to the current directory:
    zcat /proc/config.gz >.config
  3. Configure the kernel by running make menuconfig and ensure the following options are set to Yes to avoid issues when booting:
    • Cryptographic API –> CBC support
    • Cryptographic API –> ECB support
    • Cryptographic API –> XTS support
    • Cryptographic API –> HMAC support
    • Cryptographic API –> all CRC32c options
    • Cryptographic API –> MD5 digest algorithm
    • Cryptographic API –> Michael MIC keyed digest algorithm
    • Cryptographic API –> SHA1 digest algorithm
    • Cryptographic API –> SHA224 and SHA256 digest algorithm
    • Cryptographic API –> SHA384 and SHA512 digest algorithms
    • Cryptographic API –> all AES options
  4. Before running genkernel, ensure these settings are set in /etc/genkernel.conf:
  5. If you use MAKEOPTS in /etc/make.conf, then ensure you set the same in genkernel as genkernel does not use /etc/make.conf at all. (See this post on how to set MAKEOPTS.)
  6. Build the kernel, its modules, necessary statically linked software, and install it to /boot:
    genkernel all
  7. Determine any external-to-the-kernel modules for your system:
    module-rebuild populate
  8. Rebuild any external-to-the-kernel modules:
    module-rebuild rebuild

Configuring /etc/fstab and grub

Determining All Partitions' UUIDs

Run blkid and note the UUIDs for the following partitions:

  • $BOOT_DEV – This is the unencrypted boot partition.
  • $ROOT_DEV – This is the encrypted root partition UUID which grub will need in order to find the partition at boot time.
  • /dev/mapper/$VG_NAME/$SWAP_NAME – This is the swap partition.
  • /dev/mapper/$VG_NAME/$ROOT_NAME – This is the root partition that the booted operating system uses.

NOTE: The output from blkid has quotation marks surrounding them. You'll need to remove the quotation marks when placing the UUIDs in /etc/fstab and in grub.conf.

Configuring /etc/fstab

Edit /etc/fstab so that it contains the following:

UUID=ROOT_NAME_UUID   /            ext4    errors=remount-ro     0 1
UUID=BOOT_DEV_UUID    /boot        ext4    noauto,noatime        0 1
UUID=SWAP_NAME_UUID   none         swap    sw                    0 0
/dev/cdrom            /mnt/cdrom   auto    noauto,user,ro        0 0
proc                  /proc        proc    defaults              0 0
shm                   /dev/shm     tmpfs   nodev,nosuid,noexec   0 0


  • ROOT_NAME_UUID is the UUID value for /dev/$VG_NAME/$ROOT_NAME,
  • BOOT_DEV_UUID is the UUID value for $BOOT_DEV, and,
  • SWAP_NAME_UUID is the UUID value for /dev/$VG_NAME/$SWAP_NAME.

Protecting The Keyfile

When the key was generated earlier, it was generated as a binary file. One, however, does not want to walk around with a key that that has no passphrase in case it is lost or stolen, one will need to crack the passphrase in order to obtain the key. To convert the key to a GPG protected key, do the following:

  1. Mount the USB memory stick with the key.
  2. Run:
    gpg --symmetric -o $KEY_FILE.gpg $KEY_FILE

Configuring grub

Except for editing /boot/grub/grub.conf installing and configuring grub is straight-forward:

  • If grub has not been installed yet, do so:
    emerge -av grub
  • Using the UUID for $ROOT_DEV from the previous section, edit /boot/grub/grub.conf (see below).
  • Copy the active mounts:
    cat /proc/mounts >/etc/mtab
  • Install grub to the hard drive's boot sector:
    grub-install --no-floppy $INST_HDD

Examine $ROOT_DEV and note the drive letter and partition number which are the last two characters in its name. The grub boot loader uses numbers to identify drives and partitions starting from 0, therefore, drive letters 'a', 'b', 'c', etc. correspond to 'hd0', 'hd1', 'hd2', etc. and partition numbers '1', '2', '3', etc. correspond to '0', '1', '2' etc. This matters since the line with root (hd0,1) needs to be set to the correct drive and partition number as per the system being installed. Further, the appropriate file names, UUID, $VG_NAME, $KEY_DEV, $KEY_FILE, $KEY_MOUNT, $ROOT_NAME must be set/replaced with the proper values for grub to boot. Knowing this, entries in /boot/grub/grub.conf will be similar to:

title Gentoo Linux (Keyfile Boot)
root (hd0,0)
kernel /boot/kernel-genkernel-x86_64-2.6.39-gentoo-r3 root=/dev/ram0 crypt_root=UUID=ROOT_DEV_UUID real_root=/dev/mapper/$VG_NAME-$ROOT_NAME root_keydev=$KEY_DEV root_key=$KEY_FILE.gpg rootfstype=ext4 key_timeout=0 dolvm
initrd /boot/initramfs-genkernel-x86_64-2.6.39-gentoo-r3

title Gentoo Linux (Passphrase Boot)
root (hd0,0)
kernel /boot/kernel-genkernel-x86_64-2.6.39-gentoo-r3 root=/dev/ram0 crypt_root=UUID=ROOT_DEV_UUID real_root=/dev/mapper/$VG_NAME-$ROOT_NAME rootfstype=ext4 key_timeout=0 dolvm
initrd /boot/initramfs-genkernel-x86_64-2.6.39-gentoo-r3


Finally, the system can be rebooted. If everything was set correctly, the system should fully reboot. If not, follow the instructions in the "If You Get Stuck…" section to be able to access the contents of the encrypted partition so any issues can be fixed.

Kindly contact me should any typos or errors be found within this post.

OSSTF Tools and Toys Conference Presentations

On October 28th and 29th, I gave two presentations at the OSSTF Tools and Toys: Technology in Education conference held in Toronto, Ontario. The first presentation I made (on Workshop Session B, Oct. 28th) was:

Understanding Internet Identity, Safety, and Privacy Issues Workshop
The Internet is a wonderful medium enabling students, teachers, and society to interact with one another around the world in real-time. However, there are real dangers that the Internet poses for everyone, especially for teachers using such within his/her lessons plans. This Workshop is designed to inform teachers, using non-technical language, what a number of these dangers are, how they operate, and what can be done to avoid these issues in order to keep such exercises safe.

In this presentation I explained the well-known issues, but, I also focused a lot of attention concerning these two issues: (i) the perils of blocking content and the fact that many students (and some teachers!) use proxies and/or tunnels to bypass such; and (ii) how to determine whether or not a teacher should use Internet web sites (versus controlled-for-education web sites, e.g., school-board-hosted sites). Despite the details in the talk being necessarily somewhat heavy, the talk was very well-received and understood.

The second presentation I made was (Workshop D, Oct. 29th):

Augmenting the Classroom Experience Outside the Classroom With E-Learning Workshop
As a teacher, there are times when one would like to have the ability to do something available outside the classroom for students and possibly their parents, e.g., schools where students cannot stay after school due to catching a bus. This presentation will show how this can be done incrementally using a Learning Management System (LMS) called Moodle.

During this talk networking (e.g., servers running on my laptop) and Internet issues prevented me from demonstrating the things I was presenting. (Networking connectivity in the presentation areas was an issue at the conference. Unfortunately, my own laptop configuration with servers, etc. had an issue which prevented me from demonstrating it without a network.)

Should you wish, feel free to contact me concerning either of the above presentations.