Encrypt Your Root Filesystem

When you can't depend on physical security to keep your files safe, it's time to take the extra step of encrypting the filesystem. Although this article covers converting a PowerPC-based system, the principles are applicable to other architectures too.

In the Linux Journal article “Implementing Encrypted Home Directories” (August 2003), I described how to encrypt home directories transparently. This article describes how to implement another technique, an encrypted root filesystem. I discuss the GNU/Linux boot process and software requirements, present some instructions, introduce Open Firmware and discuss other relevant considerations. The system I use to teach these concepts is a New World PowerPC-based Apple iBook running a pre-release of Fedora Core 3. Despite these specifics, the concepts and procedures in this article can be applied to any device, architecture or operating system. My instructions assume you have a spare USB Flash disk and your system's firmware has the ability to boot off of it.

I also assume the reader is comfortable applying source patches and compiling programs. As of Fedora Core 3 Test 3, the mkinitrd and initscripts packages require patching to support an encrypted root filesystem. A basic understanding of how to manage partitions and create filesystems also is required. Performing a basic install of a Linux distribution is beyond the scope of this article.

Before presenting the technical steps involved, a higher-level concept must be discussed, trust. Trust is intertwined with cryptography and authentication. An implicit assumption of trustworthiness is given to any device that has an electronic key. For example, when I share my bank account PIN with an automatic teller machine, I trust that the ATM will not share my PIN with an inappropriate third party. In the same way, when I provide an encryption key to my computer, I assume the key will not be shared with anyone else. I trust the computer to keep the secret between us.

So, can you trust your computer? Unless you carry it with you everywhere, you really can't. This is true even if the disks have been encrypted. Consider this scenario: someone steals your computer as you sleep. The thief makes a copy of the encrypted contents of the computer, even though they are useless to him without their encryption key. He then replaces the encrypted laptop contents with something a little more diabolical and puts the computer back. When you wake up the next day, the computer prompts for an encryption password as it does every morning. But this time when you provide the key it electronically transmits the key to the thief. Because he now has a copy of your data and key, he can read your files.

This scenario may be a bit far-fetched, but it does illustrate a point. You can't trust your laptop. It's too big to keep your eyes on all the time. Therefore, no matter how well implemented your encryption system is, it is built without the prerequisite foundation of trust.

To ensure that we can trust the computer's boot process, we need to separate it from the computer. Consider this: you carry the keys to your car with you instead of carrying your car. Your encryption key is a natural conceptual leap from your car key. You can protect your encryption key more easily, so you don't have to carry your computer everywhere. To take things a little further and to address the above scenario, we also will place the software required to boot the computer on this key. The Flash disk will serve as this key. By protecting the software that boots the system initially, in addition to the encryption key, we can mitigate the risk of the boot process being hijacked.

An understanding of how your computer boots is required, because unlocking an encrypted root filesystem is integral to the bootstrap process. The current, stable kernel series, 2.6, optionally uses initramfs to help boot, as documented in LWN.net's “Initramfs Arrives”. Initramfs is a cpio archive that the kernel now knows how to unpack into a RAM-based disk. This unpacked filesystem contains a script that traditionally loads kernel modules needed to mount the root filesystem. In our case, this script also unlocks the encrypted root filesystem. More information on this subject can be found in the files buffer-format.txt and initrd.txt that are distributed with the Linux kernel sources.

Several filesystem encryption interfaces are available for Linux. Jari Ruusu's Loop-AES is one such project. Several cryptoloop variations that provide an encrypted loopback device also exist. This article focuses on the dm-crypt interface provided by recent 2.6 Linux kernels. This interface currently is preferred by the Fedora Project, and dm-crypt modules are provided by Fedora's kernel packages. Also required is a statically linked cryptsetup. This utility simplifies the management of dm-crypt devices. Finally, parted and hfsutils are used to manage the boot filesystem.

Unfortunately, Fedora Core's anaconda installer does not yet support installing to an encrypted filesystem out of the box. To bypass this limitation, you must leave a partition free, install Fedora, format the free partition as an encrypted filesystem and copy the originally installed data onto the new encrypted filesystem. For the purpose of simplicity, I assume Fedora is to be installed onto two partitions: /dev/hda4, mounted at /home, and /dev/hda5, mounted at /. Because /home is not populated until after Fedora is installed, we can use /dev/hda4 as our spare partition and /dev/hda3 as the swap partition.

Install Fedora Core 3, mounting /dev/hda4 at /home and /dev/hda5 at /. Do not add any nonroot users yet, as /home will be wiped clean later. At this point, you should have a fully functioning Linux system.

Before an encrypted filesystem is set up, you should randomize the partition it will occupy. This eliminates a potential leak of information about the disk's contents. Figure 1 demonstrates an abstract disk that is half-full and not randomized properly. Figure 2 demonstrates a disk that was randomized properly before being formatted to contain an encrypted filesystem. Notice that, given Figure 1, one can gain some knowledge about its contents (such as that they span one-half of the disk). Figure 2 affords an adversary no such luxury. In this case, the disk could as easily be empty as full. A partition is randomized by overwriting its contents with random data: dd if=/dev/urandom of=/dev/hda4. This process can take a long time, because creating random data is somewhat difficult.

Figure 1. When you don't randomize the disk partition before creating the filesystem, an attacker can see how full it is.

Figure 2. Randomizing the partition hides how much is used.

To create an encrypted ext3 filesystem on /dev/hda4, use the following steps:

1) Ensure that the aes, dm-mod and dm-crypt modules have been loaded into the kernel.

2) Unmount the partition that will host the encrypted root filesystem, /dev/hda4, from /home:

# umount /dev/hda4

3) Create a random 256-bit encryption key and store it at /etc/root-key:

# dd if=/dev/urandom of=/etc/root-key bs=1c count=32



Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.

Point Made!

Jakub Sadowski's picture

"This scenario may be a bit far-fetched, but it does illustrate a point."

Actually, the point it illustrated for me was that you have the right mindset and understanding to be writing such an article. Until I got to this point I was highly skeptical ;- )

Randomizing a disk: 'shred' from GNU Coreutils.

Charles Wilcox's picture

I would recommend using 'shred' from the GNU Coreutils package to create random noise on a disk. As an alternative, use the standalone package 'wipe'.

I've played with various ways of overwriting disks, including "dd if=/dev/urandom of=/dev/XXXX", "openssl -in /dev/zero -out /dev/XXXX", etc., and I discovered the tools designed for securely overwriting disks are much faster at it. The man pages describe their algorithms and link to papers on the methodologies. 'shred' is nice, since it's on nearly every Linux box by default.

For example, to overwrite SATA disk 0 partition 2:
shred -vn 1 /dev/sda2

Application to Intel PC architectures

Russ Turner's picture

I successfully extrapolated your instructions to an Intel architecture PC with only minor changes required.

**Preparing the USB Flash Disk

I prepared the USB Flash disk by formatting it as FAT16 and using syslinux (http://syslinux.zytor.com/) to install the bootstrap program. This works cleanly to boot most PC's built in recent years. It may be necessary to go into the BIOS and add USB to the list of boot options, depending on how your PC is setup.

**Modifying mkinitrd

I downloaded the latest source for mkinitrd (4.2.03) and applied the patch that you specified in your article. The patch had been updated since your article, so the flag -authtype=paranoid is no longer required: mkinitrd now automatically looks for /etc/crypttab to determine the authtype setting.

I had to edit a line in /sbin/mkinitrd to make it work. The original line that runs cryptsetup is as follows in mkinitrd (line 787 for 4.2.03):

echo "cryptsetup $cryptsetup_params -d /root-key create root /dev/root" >> $RCFILE

I had to change /dev/root to /dev/hdxx, consistent with the entry in /etc/crypttab:

echo "cryptsetup $cryptsetup_params -d /root-key create root /dev/hda6" >>$RCFILE

(In my case /dev/hda6 is the encrypted partition.)

This is pure hacking, I don't know why mkinitrd uses /dev/rootdev here.

**Verifying presence of aes module

Mkinitrd looks for aes.ko by scanning modules.dep. In the latest version of Fedora, FC3 with the 2.6.10-1.760_FC3 kernel, the aes module is actually aes-i586.ko, not aes.ko. Rather than modify mkinitrd to handle this difference I copied aes-i586.ko to aes.ko, in the same subdirectory, and then ran depmod to register the change in the modules.dep file:

# cd /lib/modules/2.6.10-1.760_FC3/kernel/arch/i386/crypto
# cp aes-i586.ko aes.ko
# depmod -a

**Running mkinitrd

Mkinitrd can now be run, as described in your article, to produce the initrd file. I will use initrd.gz as the file name in the rest of this desciption, although it can be named anything (initrd-.img is commonly used).

**Copy files to USB Flash key

I copied /boot/vmlinuz-2.6.10-1.760_FC3 (shortening the name to vmlinuz for convenience) and the new initrd file, initrd.gz, to the root of the USB Flash disk. Alternativley you can have mkinitrd write the new initrd.gz file directlly to the USB Flash disk, as done in the artilcle.

**Booting with syslinux

Rebooting the PC with the USB Flash key inserted displays some information and presents the syslinux prompt: boot: Enter the name of your kernel file and the keyword "initrd=" followed by the name of your initrd file:

boot: vmlinuz initrd=initrd.gz

Alternatively, the required boot directions can be put in the syslinux.cfg file and referenced with a label at the prompt.

How about encrypting just a file?

Anthony's picture

I only need to encrypt a few files, how can I do that?

Plan Text?

John T. Williams's picture

While I found the article interesting and informative, I did have one issue with this configuration: the key is kept in plan text on the USB device. Wouldn’t it be better to create a program that could reliable create a 256bit key from an 8 to16 byte pass phrase? In this way, even if someone borrowed your USB device they still wouldn’t be able to access the machine without the pass phrase.

I missed the article on encrypting the home directory, but from the references made to it in this article I think it suffers from the same issue. It doesn’t really protect against physical attack as the password is in plan text on an unencrypted partition on the same machine. As an attacker all I would have to do is plug your hard drive into my machine, mount the root directory, get the key, then mount the encrypted drive. If I was willing to steal your computer to get to your data, then this presents no barrier. On the other hand, if they key is generated via an md5 (or some other) hash, then I’m still stuck trying to brute force it.

I’ve often thought of modifying the kernel code for ext3 so that unless my kernel was used to access the partition, it would be so many meaningless bits.

- John T. Williams

Re: Plain Text

W. Michael Petullo's picture

I do assume that the USB drive is protected and not used for any other purpose than to unlock the root filesystem. You have to get a foothold as far as trust goes and if you read the article closely, I have choosen to trust the USB drive and the laptop's firmware.

The threats you introduce are addressed in the attack tree I present at the end of the article (steal computer and USB flash drive with key). My counter to this attack is to treat the disk as a key and protect it from theft.

Using a passphrase in addition to the physical USB key as you recommend would add an additional layer of protection. One could certainly do this if they determined that the threat warrants it.

Also, the encrypted home directory article does not instruct one to store password in plain text on an unencrypted partition. Pam_mount can read an encrypted key and decrypt it using one's system authentication token. This is the technique I recommended and it relies on a strong system authentication token.

Should have been Plain Text;

John T. Williams's picture

Should have been Plain Text; damn dyslexia!

is it possible to encrypt wit

lawman's picture

is it possible to encrypt with 1344 bit triple blowfish?