contact Me

Use the form on the right to contact me.

You are welcome, to contact me regarding the topics of this page, my open source projects, or my work. Please use the contact form and leave a valid email address for me to respond to.

Thank you.

Egidestr. 9
44892 Bochum
Germany

/brain/dump

Random thoughts, bright ideas and interesting experiments. In short the ramblings of a fulltime nerd.

 

Creating a transparently encrypted root filesystem

Jakob Westhoff

Scope

This document will present you with a step by step introduction on how to create an encrypted root filesystem and have it decrypted on the fly while working with your machine. For encryption the cryptsetup utilities with LUKS support will be used. I will not cover any information about suspend2 support, because I am not using it. Nevertheless this guide will be a good starting point even if you need suspend2. Moreover this article will not cover any cryptographically theory or comparisons between different crypto algorithms.

Prerequisites

Your system will have to comply with some requirements for this guide to work. I have written this article after encrypting my laptops hdd. On the one hand, it is intended to be a kind of documentation for myself should I ever need to undergo this kind of process again. On the other hand it should provide you with enough information to relatively painlessly secure your data. Because I am using Gentoo on all of my systems this guide will be based on some Gentoo specific features. Most of the steps taken in this article should however work in any current Linux distribution, given the fact that the commands may be slightly different.

Unfortunately I haven't found a way to encrypt a live filesystem. I haven't searched really intensive on this because I am of the opinion that a complete backup of all your data is indispensable. Therefore the need to create an empty encrypted filesystem in the first place is not a big deal. Nevertheless this makes the availability of an external data storage, which is capable of holding all of your root filesystems data essential.

I have decided to use a relatively new block cipher storage method for my encrypted containers which seems to be the most secure and efficient to the current date. XTS while still mentioned as experimental in the kernel works flawlessly and preforms quite well on numerous of my systems. Because of this a kernel version of 2.6.24 or higher is needed for this guide to provide all of the necessary algorithms. You may easily use any other supported sector based encryption method but it is strongly discouraged.

During the Process a bootcd will be required for the initial generation of the crypto filesystem. Because of this you should have the needed equipment to burn the cd and boot it on the machine which should make use of the encrypted rootfs.

Step 1: Backup your data

The first and probably most important thing to do is to backup your data on an external device. On the one hand this protects your data from being lost during the process. On the other hand your backup is needed to restore your system after creating the encrypted container on your hard disk. Because during the container creation all information on the hard drive will be lost.

Assuming that your external device is mounted on /mnt/external you can backup your complete root filesystem by issuing the following command. :

tar cp --exclude="/mnt/external" -C / ./ | tar xvpC /mnt/external

Please take into account that other filesystems which are mounted will be copied as well. Therefore you need to dismount any devices you do not want to encrypt. After the process finished your whole rootfs should be mirrored to your external hdd. Please make sure the process worked flawlessly and that all your data was backed up correctly.

Step 2: Installing the needed utilities

As I mentioned above we will use cryptsetup-LUKS for the handling of the encrypted filesystem. You can install everything that is needed by issuing the following command in Gentoo Linux: :

emerge -av cryptsetup

It is crucial to the following process that cryptsetup is linked statically. Therefore you need to make sure, that the useflag dynamic is NOT set for this package.

If you are using a non Gentoo distribution just search your package repository for cryptsetup or download and compile the sources which can be found at the corresponding web page.

Step 3: Kernel support

Your system kernel needs to support some features which may not be activated in your current configuration. Please make sure the following functionality is build into your kernel. Because we can save a lot of work later on by building this functionality directly into the kernel instead of building it as modules you are heavily encouraged to do so.

If you do not follow this advice you will need to copy the needed modules to the initramfs, which will be created later on. Moreover you will need to take care of their proper loading and initialization.

I can't see a viable reason for this, therefore I am not going into detail on this kind of initialization. You are on your own if you want to build the crypto features as modules. :

General setup  --->
    [*] Initial RAM filesystem and RAM disk (initramfs/initrd) support
    ()    Initramfs source file(s)

Device Drivers  --->
    [*] Multiple devices driver support (RAID and LVM)  --->
         *   Device mapper support
         *     Crypt target support
        [*]     DM uevents (EXPERIMENTAL) 

Cryptographic API  ---> 
     *   XTS support (EXPERIMENTAL)
     *   AES cipher algorithms
     *   SHA256 digest algorithm

If some of the options are not available in your kernel make sure you have got at least the kernel sources of version 2.6.24 or higher as of this version all needed functionality is supported.

After reconfiguring your kernel options you should build it and make sure your system boots fine with your newly installed kernel.

Step 4: Creating a bootcd for initial encryption

It is time to download and burn the bootcd which will be used for the initial partitioning and encryption of your hard drive. It is quite obvious that this can not be done using the system which you want to encrypt. As mentioned before we need a relatively new kernel for the whole process. Unfortunately the current stable Gentoo bootcd does not offer this kind of kernel. Therefore I used the current Ubuntu install cd to boot into a nice and working bleeding edge live environment. You can download it from one of the Ubuntu mirrors at ubuntu.com. Please download the Desktop version of Ubuntu 8.04 or newer.

After burning the iso image file to a cdr close all your applications and boot from the newly created disc. Select "Rescue a broken system" from the boot menu to just load the live cd environment instead of really installing Ubuntu.

After the boot process which will take some time you will be presented with a nice graphical gnome session, First of all we need to fetch and install the cryptsetup utilities to our live environment, because they are not included on the live cd. Make sure your network connection got setup correctly, open up a terminal window and issue the following command: :

sudo apt-get install cryptsetup

Just answer the question if the package should be installed with yes and the package management system does all the work for you. I want to point out that none of these data is currently installed on your hard drive the whole system is running live from the cd and the downloaded and installed packages are just hold in ram. Therefore you would need to repeat these steps every time you boot from the Ubuntu disc.

After the installation is complete we need to load the needed kernel modules for our encryption to work. Enter the following command into your terminal and press enter: :

for i in aes_generic dm-mod dm-crypt crypto_xts; do modprobe $i; done

After all of these modules have been loaded we are ready to take the next step of our guide which will for the first time really change something on your hard disk.

Step 5: Ensure you have got the right hard disk partitioning

Because we are about to encrypt the whole rootfs we need to make sure that we have some unencrypted storage to put our initramfs and kernel to. Therefore we need a boot partition to hold this data. You should at least use about 200MB of storage for this partition. We will discuss later on how to encrypt the swap to ensure no data is going into the wrong hands. But at the moment just create a normal swap partition which fits to your likings. A rule of thumb is to use twice the space of your ram for swap. The leftover space should be used for your new root partition I decided to use cfdisk for my partitioning tasks, but you are free to use the tool of your likings. If this is not installed you can install it from the Ubuntu package repository. But for our needs cfdisk should just do fine. :

sudo cfdisk /dev/sda

Needless to say, you need to substitute /dev/sda with the device node of your hard drive.

I want to emphasize that you are really changing something on your hard disk for the first time of this guide. Please make sure that your backup is complete and accessible. Because after changing the partitioning scheme of your hard drive everything on it will be lost.

After you created your new partition layout it should look something like this: :

cfdisk (util-linux-ng 2.13.1.1)

      Disk Drive: /dev/sda
Size: 80026361856 bytes, 80.0 GB

> Heads: 255 Sectors per Track: 63 Cylinders: 9729

> Name Flags Part Type FS Type [Label] Size (MB)

> sda1 Boot Primary Linux ext2 1019.94
> sda2 Primary Linux ext3 75730.16 sda3 Primary Linux swap / Solaris
>     3273.67

As you can see I have decided to use 1GB for my boot partition and 3GB for swap space. All of the left free space is used as root filesystem.

Step 6: Copy the /boot directory to your new boot partition

You need to copy the contents of your old /boot directory to your new boot partition. First of all we need to create the filesystem on our new boot partition. I recommend using ext2 for the boot partition, because it is a robust filesystem nearly every default Linux kernel can interact with. :

sudo mkfs.ext2 /dev/sda1

As always substitute the device node with the one corresponding to your system configuration.

Afterwards just mount the newly created filesystem at /mnt/boot and fill it with the needed data from your backup. :

mount /dev/sda1 /mnt/boot
cp -vpr /mnt/external/boot/* /mnt/boot/

You may need to mount your external data storage or check were Ubuntu put its mount point automatically. In most cases the automounter will work without a problem on usb storages, which can then be found in /media/something afterwards.

Step 7: Creating the encryption container

We are now going to create the encrypted container to hold our complete rootfs. The following command needs to be issued in order to accomplish this. :

sudo cryptsetup -y --cipher aes-xts-plain --key-size 256 luksFormat /dev/sda2

As you may already have realized you need to substitute /dev/sda2 with the device name of your newly created root partition.

I will discuss what this command does in detail to give you a basic understanding of how the cryptsetup utility works and how it can be used to handle encrypted containers.

Cryptsetup options in detail

-y: Ask for the passphrase twice and check for equality. This is useful just to make sure you did not mistype your password. Always keep in mind without a valid password you will not be able to access your data.

--cipher aes-xts-plain: This option selects the cipher to use for encryption. In detail we decide to use an AES encryption with the XTS sector based block cipher algorithm. XTS is quite new and therefore still marked experimental in the kernel. I am using it on quite a number of encrypted devices since kernel version 2.6.24 has been released and did not have any problem with it so far.

--key-size 256: Use a 256bit key for the AES encryption. This key size is a good trade off between performance and security.

luksFormat: This represents the action we want cryptsetup to perform. At this point we want to create or "format" a new encryption container. We will use actions like luksOpen and luksClose later on. Just take a look at the man page for details on which actions are supported by cryptsetup. Because we are using the LUKS extension only actions with the keyword luks at the beginning are of interest for us.

Step 8: Filling up the container with random values

To make a cryptoanalysis attack to our newly created container a little harder we are filling the whole container with data, to render it virtually impossible to distinguish real data from "free" space. We are using 0 values as data here because as far as I can see it makes no difference at this point what kind of data you use. As long as there is not discovered a hole in the way XTS works on the different sectors, every data written to the container should look kind of random after the encryption. If you are concerned about this use /dev/urandom on the following commands instead of /dev/zero. But be warned that this will make the initialization process a lot slower. Nevertheless there is no performance or time impact after the initial creation is completed. It is up to you to decide.

Before we can actually write to the encrypted container we need to open it. This is done by the luksOpen action. :

sudo cryptsetup luksOpen /dev/sda2 rootfs

This command line will open the encrypted container at /dev/sda2 mapping it to the device mapper name rootfs. After entering your passphrase your virtually unencrypted device should be accessible at /dev/mapper/rootfs. This device node can be accessed and used in just any way a normal block device could be used. Everything you read from or write to this device will be de- or encrypted on the fly. Therefore it is now possible to fill up the whole device with zeros to render the before mentioned attack impossible. :

dd if=/dev/zero of=/dev/mapper/rootfs bs=1M

Maybe you want to get yourself a coffee now, because this operation will take quite some time based on the speed of your cpu and/or hard disk. For my 80GB hard disk it took about 40 minutes on a Core Duo with 1.8GHz. Unfortunately dd does not show you any kind of progress until the process is finished. To get at least some information about what is going on you can send a USR1 signal to the dd process, which makes it output its current status. This can for example be done from a different terminal by issuing: :

killall -SIGUSR1 dd

This will send all currently running dd processes the USR1 signal. If you switch back to the terminal running dd, you should notice some status information dd printed to the terminal. You can repeat this step from time to time to get an overview about the ongoing operation.

Step 9: Creating the new filesystem and restoring its original contents

At this point we have got a on the fly encrypted block device which contains just zeros. We will need to create a filesystem on it to be able to store our rootfs. I prefer using ext3 for my main filesystems, because it is mainstream and therefore quite stable. It is up to you, to select the filesystem of your likings here. Just make sure your kernel supports it. The process of creating the filesystem is the same as with any other non encrypted block device, except for the fact that you need to specify the node created by the device mapper instead of the real device. :

sudo mkfs.ext3 -O dir_index,large_file,file_type -L"Root" /dev/mapper/rootfs

You can modify the command to reflect the needed options for your rootfs. If you are not sure about the options, you may use the given command line, which should work just fine, or take a look at the man page of mkfs.ext3 to find out more about the possible options.

The newly created ext3 fs can now easily be mounted, to be filled with the data which we backed up before. Mounting the encrypted disk is just as easy as creating a new fs on it. Just use the device mapper block device instead of the real one and everything works smoothly. :

sudo mkdir /mnt/rootfs
sudo mount /dev/mapper/rootfs /mnt/rootfs

Now every file copied to /mnt/rootfs will be encrypted on the fly and written to your disk. Therefore we can now just copy the original rootfs data to our mounted disk and have it stored encrypted. We are using the same command we used at the beginning to backup our data to restore it. :

tar cpC /mnt/external ./ | tar xvpC /

Depending on the amount of data you had originally stored on your disk this may take some time.

Step 10: Installing an initramfs to initialize the encrypted disk at boot

Congratulations at this point you have a fully encrypted root filesystem on your machine. The next big step will be to make your computer ask for the passphrase on startup to initialize the device mapper and transparently switch to the encrypted filesystem. This is done utilizing an initramfs. An initramfs is a compressed container which contains a minimal system to execute some initial actions before the main system is loaded. Therefore it is exactly what we need to mount our encrypted disk before the system bootup is executed.

I am going to describe the creation process of such an initramfs in detail. If you don't want to make any special modifications, because you have special needs to fulfill, you may just download an initramfs image I already created and skip the whole part explaining the building process. In most of the cases it will not be necessary to create your own initramfs.

Chrooting to your encrypted filesystem

For the creation of our initramfs we will need a build environment. Our Gentoo system should already have all the needed tools installed. Therefore we are now chrooting into the encrypted rootfs to be able to work with our own system instead of having to install all the needed compilers and libraries to the Ubuntu live cd environment. :

sudo mount -o bind /dev /mnt/rootfs/dev
sudo mount -t proc null /mnt/rootfs/proc
sudo chroot /mnt/rootfs /bin/bash
source /etc/profile

We can now work in the same way as we had booted up our Gentoo and opened a terminal in it.

Compiling and installing Busybox

First of all we need to create a directory to put some of the needed stuff to. Create a directory with an appropriate name, eg. initramfs. We will need a minimal shell in our initrd. I decided to use Busybox for this kind of purpose, because it is quite small and provides all the features we need.

We will use the Gentoo package management system to install our needed Busybox executables. First of all we need to make sure that Busybox and therefore all needed dependencies are installed on our system. :

emerge -av busybox

After the compilation finished it is time to create the needed files in the directory we created just before. I am assuming that the directory is named initramfs and is stored in /root. If this is not the case please adjust the command accordingly. :

USE="-pam make-symlinks -savedconfig static" ROOT="/root/initramfs" emerge -Oav busybox

This command makes Gentoo create a statically linked Busybox executable and install it with all corresponding symlinks to our initramfs directory.

The executable will be quite large, about 1.5 MB. This is because it is linked against the default glibc your system is using. However there is the possibility to create a much smaller Busybox by linking it against the uclibc, which is a size optimized glibc especially created for systems with constraints in filesize. This can be achieved by either using the crossdev script, which can be found in portage or by using a stage3 embedded Gentoo image and chrooting into it before compiling. I will not cover this in detail, because I don't think it is essential for our initramfs to be as small as possible. The initramfs is only used for a small amount of time before it is freed, therefore it should not make that big difference if it is 1 or 3 megabytes in size.

Because we used emerge to compile and install our Busybox we need to cleanup some leftovers of the portage system inside our initramfs directory. :

rm -rf /root/initramfs/usr
rm -rf /root/initramfs/var
rm -rf /root/initramfs/tmp

The basic command interpreter along with the needed utility commands have now been installed in our new initramfs directory.

Generate the needed Busybox keymap file

It is quite important to have your native keymap loaded at the moment you are asked for your passphrase, because it might contain special chars which are mapped elsewhere on the default keymap. Unfortunately Busyboxs utility for loading and installing keymaps is incapable of reading the keymap files Gentoo uses at initialization. In fact it utilizes a binary keymap format of its own. Busybox comes with a program to create these binary format files. It is called dumpkmap. Certain steps are necessary to create such a kmap file correctly which I will explain in detail now.

First of all we need to dump our current keymap to be able to restore it once the process is finished. :

dumpkeys >/root/installed_keymap

After that we need to decide which keymap we are about to use for our initramfs. All available keymaps can be found in /usr/share/keymaps. Just pick the one that fits your needs. Just to give you an example I chose /usr/share/keymaps/i386/qwertz/de-latin1-nodeadkeys.map.gz. Finally install the select keymap by calling loadkeys. In our example the command would look like this: :

loadkeys de-latin1-nodeadkeys

We have now loaded the keymap we are about to use in our initramfs. To create the binary format kmap file I told you about we are now dumping the loaded keymap to this kind of file by calling the following: :

mkdir /root/initramfs/etc/keymaps
busybox dumpkmap > /root/initramfs/etc/keymaps/de-latin1-nodeadkeys-i386.bin

You should name the file after your loaded keymap to make its remembrance easier later on.

There is an important fact about those binary keymap files which makes them quite different from the normally used keymap files. They are completely platform dependent. Therefore you need to create a different kmap file for arm based system for example. Because of this I appended the platform (i386 in this case) to the filename, just to make sure it is not accidentally taken for another platform.

The last and finishing step in the kmap creation process is to reload the keymap we had instaled, just before starting with it. :

loadkeys /root/installed_keymap

Creating the needed nodes inside the /dev directory

Your initrd will need a /dev directory with a rudimentary set of nodes to access your encrypted disk once it is booting up. You can either create these nodes on your own using for example MAKEDEV or just download and decompress the dev tree I have already prepared. It should contain any node which could be needed to access your hard disk and the device mapper, along with a lot of other nodes which could be needed to issue certain commands.

After you downloaded the dev directory to /root cd into your initramfs directory and decompress it with the following command: :

cd /root/initramfs/
tar xvpzf /root/initramfs-dev.tar.gz

Copying cryptsetup to the ram disk

You might remember that I pointed out it is crucial to link the cryptsetup utility statically, because we would need this one later on. Now we are going to install the cryptsetup executable to our ram disk. Because we took care to have it linked statically in the first place we just need to copy it to the right directory now. :

cp /sbin/cryptsetup /root/initramfs/sbin/

Creating the init script for decryption

We are nearly finished creating our initrd. Nevertheless the most important part of it is still missing. A script which mounts the encrypted rootfs and switches to it as new root in order init the system boot process.

During the initialization of the initramfs the system searches for a file called init in the root of the ram disk. If this file is found it will be executed automatically as init process. Therefore we need to create such a init script which takes care of all the needed steps necessary to bootup our system. You can write a script like this on your own or use the one I developed for this case. :

#!/bin/ash

#
# Executables
#

MOUNT="/bin/mount"
SWITCH_ROOT="/sbin/switch_root"
LOADKMAP="/sbin/loadkmap"
CRYPTSETUP="/sbin/cryptsetup"
ASH="/bin/ash"

#
# Needed functions
#

msg() {
    if [ "${DEBUG}" == "true" ]; then
        echo $1
    fi
}

processOptions() {
    # First we set some of the options to their default state
    DEBUG="false"
    rootdev=

    # Parse the kernel parameters line and set the needed options accordingly
    for i in `cat /proc/cmdline`; do
        case $i in
            cryptdebug)
                DEBUG="true"
            ;;
            root=*)
                rootdev=`echo $i|cut -d"=" -f2`
            ;;
        esac
    done
}

initScreen() {
    # Clear the screen
    clear
    # Display messagefile if it does exist
    if [ -f "/etc/msg" ]; then
        cat /etc/msg
    fi
}

enableProcfs() {    
    # Mount the procfs
    # Needed by cryptsetup
    msg "Mounting procfs"
    ${MOUNT} -t proc none /proc
}

switchToNewRootfs() {
    newRoot=$1

    # Create /dev/console in new rootfs if it does not exist
    msg "Creating /dev/console in mounted rootfs"
    mknod "$1/dev/console" c 5 1 2>&1 >/dev/null

    msg "Switching to new rootfs"
    cd "${newRoot}"
    exec ${SWITCH_ROOT} -c /dev/console . /sbin/init
}

setKeymapping() {
    keymap=$1
    msg "Loading german keymap '${keymap}'"
    ${LOADKMAP} < "/etc/keymaps/${keymap}"
}

luksOpen() {
    if [ "${rootdev}" == "" ]; then
        echo "No root device was specified."
        echo "Append root=<device data-preserve-html-node="true"> to your kernel command line"
        echo "Dropping you to a minimal shell for recovery"
        echo
        ${ASH}
    fi
    retval=1
    while [ $retval -ne 0 ]; do
        msg "Opening cryptoluks device"
        ${CRYPTSETUP} luksOpen ${rootdev} root  
        retval=$?
    done
    msg "Mounting newroot"
    ${MOUNT} /dev/mapper/root /mnt/root
}

#
# Main function
#

main() {
    # Some hardware needs time to settle before we can use it
    sleep 2

    initScreen
    enableProcfs
    processOptions
    setKeymapping "de-latin1-nodeadkeys-i386.bin"
    luksOpen
    switchToNewRootfs "/mnt/root"
}

# Run the main function
main

If you do not want to copy and paste the script from above you can download it as a single file below.

The script is designed to work mostly out of the box. The only thing which needs your attention is the keyboard layout. Most likely you will use another keyboard layout than I do. In this case you will need to change the KEYMAP option at the beginning of the script and have it point to the right filename.

Do not forget set the executable flag on the script after you saved it to its destination. :

chmod u+x /root/initramfs/init

Optional: Adding uvesafb utility

If you are using the uvesafb driver for displaying a frame buffer console you are already using an initrd to supply the driver with the needed program at bootup. This utility needs to be copied to your newly used initramfs to make sure the frame buffer still works.

cp /sbin/v86d /root/initramfs/sbin/

If there is no v86d executable on your system, you most likely do not use the uvesafb driver and can safely skip this section.

Optional: Adding a welcome message

During my research around the net on how to create an encrypted rootfs I found a nice article in the Gentoo-Wiki. The author of this article wrote an init script that presented a nice little ASCII art to the user instead of just asking for the passphrase. I really liked this. Therefore it is possible to include some kind of welcome message in the initramfs, which will automatically displayed to the user on bootup.

Just put anything you want to show up into the file /etc/msg. I put an ASCII art image of a tux in there which I found around the net. Just google for ASCII art tux to find some nice variants of it.

If you want to use a picture of your own you could try some of the image to ASCII converters out there like this one

Creating the initramfs image file

The contents of the initramfs is now ready for packaging. For the kernel to read the initramfs all of the files need to be compressed into one file. The cpio command is used for this task. :

cd /root/initramfs
find . | cpio -o -H newc | gzip -9 >../crypt-initramfs.gz

These commands will create a file called crypt-initramfs.gz which will contain the initramfs contents in a file format the kernel is able to load and execute on boot.

Make grub load the initramfs on boot

The initramfs we just created needs to be copied to the boot partition we created earlier. We need to mount the boot partition inside our chroot cage to be able to copy files to it. As always substitute /dev/sda1 with the device node of your boot partition you created before. :

mount /dev/sda1 /boot
cp /root/crypt-initramfs.gz /boot/

After the initramfs has been copied to its destination we need to supply the kernel with the needed information to load it during the bootup sequence. This is accomplished by editing the grub configuration file, which can be found in /boot/grub/menu.lst. Just open it with the editor of your choice and add the following line to your boot configuration, just below the line starting with the word kernel. :

initrd /boot/crypt-initramfs.gz

After you modified the configuration the whole entry should look something like this. :

title  Gentoo Linux 2.16.24-r2
root (hd0,0)
kernel /boot/linux-2.6.24-gentoo-r2-b4 root=/dev/sda2 video=uvesafb:1024x768-32,mtrr:3,ywrap acpi_sleep=s3_bios,s3_mode
initrd /boot/crypt-initramfs.gz

Please make sure that your kernel command line contains the root= parameter and it is pointing to the encrypted root device. Because this parameter is used by the init script we installed earlier to determine which device needs to be decrypted and mounted during the startup process.

Step 11: Rebooting into our new encrypted root filesystem

Our work is nearly done. The next step will be to unmount all the filesystems we are working with and reboot the system right into our live encrypted filesystem.

First of all unmount the boot partition and leave the chroot cage we are working in. :

umount /boot
exit

All other filesystems we used will just follow, as they are not needed any longer. :

sudo umount /mnt/rootfs/dev
sudo umount /mnt/rootfs/proc
sudo umount /mnt/rootfs
sudo umount /mnt/boot

The last step is to close the encrypted container which is still open. :

sudo cryptsetup luksClose rootfs

We are now ready to reboot the system. Just end the live cd session and remove the cd from the disc drive.

The initramfs will be loaded on the next bootup asking you for your encryption password. Enter it and the boot process will continue just as it would without the encryption.

Congratulations you have successfully booted into your encrypted root filesystem. There is just some finishing work to do to make everything perfect.

If you encounter any problems during this process like the system not booting correctly, don't despair. Just put the Ubuntu live cd into your cdrom again, boot it up and follow the beginning of this guide to install the cryptsetup utility to the live environment. After that you will be able to mount your rootfs manually. Check all the configurations and the initrd again and make sure everything is configured and installed correctly.

Step 12: Use an encrypted swap partition

Although you are now using a completely encrypted root filesystem there is still the danger that your computer system uses the swap space on your filesystem. This would be an undesirable action, because neither the ram nor the swap space is encrypted. Therefore an attacker could probably read sensitive information from your swap partition. To avoid this situation we will use an encrypted swap partition. Everything written to the swap will be encrypted on the fly just as it is done with your root partition.

Because the data written to the swap space does not need to survive a reboot we can encrypt the swap partition with a randomly created key every time the machine starts for even more security. (This behavior is not preferable if you want to use suspend to disk. However using an encrypted system and suspend features is possible utilizing suspend2.)

Fortunately Gentoo already has all the needed init scripts to do exactly this during the boot process automatically. After you installed the cryptsetup package portage created a the file /etc/conf.d/dmcrypt which contains all the needed configuration entries to mount encrypted filesystems during the init process. The corresponding initscript can be found at /etc/init.d/dmcrypt. To create a randomly encrypted swap on startup just add the following lines to the end of the /etc/conf.d/dmcrypt file: :

swap=swap
source='/dev/sda3'

As always substitute /dev/sda3 with your swap partition.

To create and init the swap partition on boot just add the dmcrypt initscript to your boot runlevel by calling: :

rc-update add dmcrypt boot

Gentoo now takes care of creating the needed swap filesystem on startup and encrypting it with a random key.

Step 13: Updating /etc/fstab to reflect the filesystem changes

We are nearing the end of this guide. There is just one final step to complete the creation of our fully encrypted system. We need to update the information in the /etc/fstab file to reflect the changes we made to our filesystem structure. The fstab file still contains the information about the real block devices which contained our system before. We need to change this to reflect the fact that we are using virtual block device nodes for root and swap now. Just change the block device entries for the root and the swap filesystem to /dev/mapper/root and /dev/mapper/swap*. Your entries in the fstab should look something like this after you are finished: :

/dev/sda1           /boot       ext2        noauto,noatime  1 2
/dev/mapper/root    /           ext3        noatime         0 1
/dev/mapper/swap    none        swap        sw              0 0

A reboot of your system should be executed now to activate the new encrypted swap space and have everything in order with your mount points.

Congratulations you just finished encrypting your whole root filesystem.

Further reading

I spent quite a lot of time on how to create the most efficient and secure cryptographical container to secure my data. I read of lot of websites before I started writing this guide. I tried to compact all the information into this article. But there might be anyway some parts which you think need more in detail explanation. Maybe there are even parts of the guide which could be solved using different approach. Therefore I want to mention some of the pages which helped me quite a lot during the whole process. Maybe you can find the missing information on them.