LUKS: Swap, Root and Boot Partitions

The /swap Partition

We need to encrypt the swap partition, since we don't want encryption keys to be swapped to an unencrypted disk. To do that we can first use the cryptsetup to encrypt the partition and then create a swap filesystem on it in the usual way and turn it on with swapon. The actual commands can be seen below:

/dev/sda2
# mkswap /dev/mapper/swap
# swapon /dev/mapper/swap

The commands above read the key from /dev/urandom, which is appropriate for swap. If we would like to store our hibernation file on the swap partition, we can't use the /dev/urandom, but we must use a password as with every other encrypted partition. In such cases, the key must be known in advance, since we need to be able to read the contents of swap in order to boot from the hibernation file. In such a case, we can use the commands shown below to create an encrypted swap partition:

# cryptsetup --verify-passphrase --cipher serpent-cbc-essiv:sha256
--key-size 256 create swap /dev/sda2
# mkswap /dev/mapper/swap
# swapon /dev/mapper/swap
# cryptsetup luksAddKey /dev/sda2 /root/keyfile

We also need to change the /etc/fstab for the system to be able to use the encrypted swap. The fstab swap entry must contain something like this:

/dev/mapper/swap swap swap defaults 0 0

The /etc/conf.d/dmcrypt configuration file can be used to automatically decrypt the contents of the encrypted partition. An entry which decrypts each partition can be as follows:

target=swap
source='/dev/sda2'
key='/root/keyfile'

Notice that we used the /root/keyfile to decrypt/encrypt the encrypted partition. This is possible because previously we added a new key to the key slot 1 with the luksAddKey command when creating the swap partition. If we would like to automatically decrypt the partition without entering the password, we must use another key file.

The /root Partition: Installing the System

We've already created an encrypted partition and we have to install a new Gentoo system on it. We have mounted the encrypted partition /dev/sda3 under /mnt. To install the Gentoo system, follow the instructions below. First we must download the stage and portage from Gentoo mirrors:

# wget
http://mirror.mcs.anl.gov/pub/gentoo/snapshots/portage-latest.tar.bz2
# wget
http://mirror.mcs.anl.gov/pub/gentoo/releases/amd64/current-stage3/stage3-amd64-20111103.tar.bz2

Unpack the stage tarball in the root of the new encrypted partition (we've mounted it under /mnt):

# tar -xvjpf stage3-amd64-20111103.tar.bz2 -C /mnt/

Install the portage snapshot:

# tar -xvjf portage-latest.tar.bz2 -C /mnt/usr/

Mount proc and dev filesystem:

# mount --bind /proc /mnt/proc
# mount --bind /dev/ /mnt/dev

Chroot into the new partition and update the portage tree:

# chroot /mnt /bin/bash
# emerge --sync

Install the system and kernel:

# emerge system
# emerge gentoo-sources

These were just the basic steps we had to take to install the system on our encrypted partition. For a whole how-to, you must reference the Gentoo handbook, which provides a very good explanation of the whole installation process. We won't go into the details here about installing the whole Gentoo system, since that is a very big topic and is out of scope of this article.

The /boot Partition

We have already created a boot partition and now we have to make it bootable and create a new filesystem on it. Remember that the boot partition must be unencrypted, so the whole system can boot normally?

First let's set its bootable flag with the fdisk command. To do that, we must issue the fdisk /dev/sda command to edit the partitions on the /dev/sda hard drive. After that we must enter the command p to print existing partitions: in our case we're presenting only the /dev/sda3 partition, which is a /boot partition and we must make it bootable. To make it bootable, we have to enter the a command and select the appropriate partition number.

Command (m for help): p
/dev/sda3 624077118 625137344 530113+ 83 Linux

Command (m for help): a
Partition number (1-5): 3

After that we must create an ext3 filesystem on it:

# mkfs.ext3 /dev/sda3

The /boot partition is now ready and can be mounted normally. After we mount it under /mnt/boot, we can remerge the grub to install appropriate files on it. We also need to copy the kernel and initrd image on the partition in order to boot from the chosen kernel. The initrd image is required because our system partition is encrypted and must be decrypted upon booting.

Decrypting/Encrypting Partitions at Startup

In order for the system to mount another encrypted partition, we must edit the /etc/conf.d/cryptfs file as we did for the swap partition. Example for setting up the home partition in mentioned file is as follows:

target=home
source='/dev/sda1'

Next, we need to add fstab entries so that the mount point of the encrypted filesystem can be determined:

/dev/mapper/home /home auto noatime 0 0

Then we must start the dmcrypt init script at boot time, which will add the mappings for the specified devices asking a user for a password for each device.

# rc-update add dmcrypt default

This is all fine, but what if I don't want to enter the password for every encrypted partition? So, here's the solution of how to add a mapping and mount an encrypted non-system partition at boot time without requiring an additional password at login.

First we need to create a random keyfile:

# dd if=/dev/urandom of=/root/keyfile bs=1024 count=4
4+0 records in
4+0 records out
4096 bytes (4.1 kB) copied, 0.000655864 s, 6.2 MB/s

This will create a file with random content with the size of 4096 bits. We can use any file to act as keyfile, but this 4KB file with random content is quite good. We must make sure that the keyfile is only readable by root:

# chmod 0400 /root/keyfile

Second, we must add the keyfile to LUKS. LUKS dmcrypt-enabled devices may hold up to eight different keyfiles or passwords (as we've already seen in one of the previous articles). So now we're going to add this keyfile as additional authorization method. To add a key file as an authorization method, we must use the command below:

# cryptsetup luksAddKey /dev/sda1 /root/keyfile

We'll be prompted to enter an existing password to unlock the drive. If everything works well, we can now create a mapping that can be referenced in /etc/fstab. Edit the /etc/conf.d/dmcrypt and add:

target=home
source='/dev/sda1'
key='/root/keyfile

Notice the new key entry pointing to the /root/keyfile key. This is the file that will be used to decrypt the partition upon booting the system automatically. This will add a new mapping /dev/mapper/home to the system. Then we need to restart dmcrypt for the changes to take effect:

# /etc/init.d/dmcrypt restart

After that, we only have to mount the device in /etc/fstab by inputting the following entry into the /etc/fstab configuration file:

/dev/mapper/home /home/ ext3 noatime 0 0

Different Booting Modes

Let's compare the different booting modes now. First is a normal booting mode, which can be seen in the picture below:

image0

In the picture we can see that the booting process starts from the MBR (Master Boot Record); actually the booting process starts with BIOS and continues from there. It's is BIOS's job to tell the computer which hard drives are available and to try to search for an active MBR record in the primary hard drive. The hard drive then contains an MBR record that tells the booting process where the /boot partition is located. Afterward, the /boot partition is read and examined for any bootloader; in our case the bootloader is Grub. At that point the booting of a computer is handed to the Grub bootloader, which loads the grub.conf and the kernel of the Linux system and then mounts the root partition. In this case the root partition is /dev/sda3. Then the execution continues with the kernel image located on the /boot partition. The kernel is loaded and the execution is handed over to the Gentoo init process (with a PID number 1), that is already located on the system partition and is responsible for starting the entire system. The init process takes care of everything the system needs to boot up successfully. One of the things it does is to start the required scripts, usually located under /etc/rc.d/ directory. It must also mount the partitions that are listed in the /etc/fstab configuration file. Once everything is done, the login window appears, which enables us to login to our operating system.

This is what happens in a normal booting mode where there is no encryption (no LUKS) and no LVM; it's the standard booting mode of almost every default Linux installation out there. But in addition to that, we can optionally encrypt one or more partitions. If we encrypt our non-system partitions, then the booting process is almost the same, except that a decryption of the encrypted partitions should also occur at the boot time. Other than that, everything is the same. It's a little bit different if we want to encrypt our system partition as well. I named that booting mode LUKS Mode, because usually the LUKS is used for encryption. The picture below shows us the steps we need to go through when booting off the encrypted system partition.

image1

We can see that the picture is considerably more complicated as before, but mainly because the initrd is involved. The beginning of the booting process is the same as in normal mode, but then we also have to use the initrd to decrypt the partition prior to booting from it. In the fourth step, we're using the cryptsetup inside the initrd, which decrypts our encrypted system partition. At this point, we also have to enter the password for the encrypted partition for the booting process to be able to decrypt the system partition. When the partition is decrypted, we mount the newly mapped file /dev/mapper/root into the /newroot and right after that we switch to the decrypted partition now located at /newroot. From there we can continue normally, since the system partition is already decrypted. We can see that only the presence of initrd image is different, which decrypts the system partition in order for the booting process to be able to use it.

The third option is a LUKS+LVM mode, which is practically the same as LUKS mode except that we're also using the LVM. An additional picture isn't necessary, because the booting process is practically the same as with LUKS mode. The only thing missing is another node representing the "vgscan; vgchange -ay ", which scans for the logical volumes on the partitions and maps them to the /dev/mapper/ directory. In our case, since the /dev/sda3 will be decrypted as /dev/mapper/root, all the logical volumes on that partition will be represented as the entries /dev/mapper/vg-*. Those entries can then be used as the partitions in /etc/fstab, because the Linux operating system should operate with those logical volumes that represent the actual logical decrypted partition.

If you would like to have the system partition encrypted, you should go with the LUKS+LVM mode, since you'll also get the benefits of using the logical volume manages, which makes managing partitions (logical as well as physical) a lot easier. But whatever you do, if you are a security aware Linux enthusiast, you should really take the time to encrypt your system partition; your system will be protected in case you lose your laptop, plus you'll learn a great deal about Linux booting process.

Conclusion

We've seen what Linux does when it needs to boot from a normal, LUKS encrypted and LUKS+LVM enabled system partition. The booting process is quite complex, but once you get to know it in details, it's very interesting and I think everybody should understand the whole concept of booting in Linux. In the next tutorial, we'll show how to actually create the initrd image and write the /init bash script that will take care of most of the steps described here: decrypting the system partition, mounting the system partition as a /dev/mapper/ device and detecting its logical volumes.

Comments