DM-Crypt

There are a lot of threads out there on how to encrypt your root file system. This howto attempts to use a new concept implemented by Clemens Fruhwirth 1 named luks.

Introduction
luks doesn't store information in configuration files that can be lost or compromised, but on the encrypted partition itself. It creates a header on the partition that contains all information required by the decryption program, such as the algorithm, mode, etc...

Another benefit of luks is that it doesn't directly use the password that you give it at the beginning to encrypt the partition. Instead, it encrypts the master key (the one used to encrypt the data) with your password. If you want to change your password ('oldpassword' for ex.), it decrypts the master key with 'oldpassword', and reencrypts it with 'newpassword'. The master key isn't changed in this procedure, it is merely reencrypted, saving you the trouble of reencrypting your entire harddrive. This is especially handy in the case of a password compromise.

It's also possible to make multiple copies of the master key, all encrypted with a different password, allowing a type of password management system. This allows you to revoke passwords if they get compromised, or give different users different passwords to access the encrypted data. luks reserves space at the beginning of the partition for 8 different password (called key slots). Be aware that anyone with ANY valid key to the drive can delete/add keys. +++-+++ +++-+++
 * Header | Slot 0 | ... | Slot 7 | Encrypted Data |

Anyways, to the practical stuff... (some of this shamelessly copied from here: SECURITY Encrypting Root Filesystem with DM-Crypt)

Assumptions

 * Kernel 2.6.11: disk driver builtin, ext2/reiserfs filesystem drivers builtin,
 * device mapper/encryption modules dm-crypt/dm-mod builtin, aes builtin,
 * ramdisk and initial ramdisk (initrd) builtin.


 * A empty partition for Boot on /dev/sda1 filesystem is ext2.
 * A empty partition for Root on /dev/sda3 filesystem is reiserfs
 * A linux system e.g on /dev/sdb or on a gentoo install cd 2006.0 ,so that you can follow all coming steps.
 * You will be prompted for encryption passphrase at boot time.
 * You are using udev.
 * You are using grub boot loader.
 * You're logged in as root.

Requirements
You'll need to emerge device-mapper:

You'll need cryptsetup 1.0.5 or newer (which contains luks support):

If you have udev you will also need the multipath-tools

if you want to find all devices under /dev/mapper that you open in your initrd you need lvm started:

Preparing Initrd Image
Now we need to create our initrd, I'll call it myinitrd. It's a simple task once you played around a bit with it. I highly recommed playing with initrd's before you go actually and encrypt your root (last step in this mini-howto). First create the image, I'm using a 4MB initrd but feel free to expand that if you need more, just remember to set the option in your kernel configuration for the maximum ramdisk size properly. (see 'Assumptions' section)

Now populate the image with required directories and files:

Linuxrc is where the action will be. It's a script file to be loaded by linux on initial boot, more below. Now you need to copy necessary files into bin, sbin and lib. For bin, copy the following from your current system:

if you use jfs:

For lib, you'll need to find out which lib files are needed by each of the binaries above. The way to do it is to run 'ldd' for each file above and copy the required libs over. Example:

And so on for the rest of the binaries. Or use this perl script to do it for you

Now, we need to create necessary devices in the dev directory:

You can also try:

If you are using sda2 replace the numbers above with "b 8 2". If you are unsure of the major/minor numbers you should use mount /proc and cat /proc/devices. This should be done off the ram drive (more about that later).

Initrd Scripts
Now we need to create the linuxrc and devmap_mknod.sh scripts that will be executed in the initrd. The linuxrc script should setup dm-crypt and mount root on it, then start the real init of the system. Here it is:

Now look at the devmap_mknod script. It has to create the node with good values provided by.

That's basically it for the initrd. It's advisable to test all bin files in it by chrooting and running them one by one. You should get no error messages about missing libraries.

Unmount the initrd and copy it over to /boot. If you use bootsplash you can append the bootsplash initrd to it. Note that you can still mount/unmount the image and play with it event after cat'ing the bootsplash image to it. mount knows its start and end.

With bootsplash:

Without bootsplash:

Using initramfs and busybox
Initramfs is a newer replacement for initrd which will become the new standard for booting Linux systems. At a high level it's just a different way to populate a ram disk for booting. Unfortunately, pivot_root does not work from initramfs and it looks like it never will, see http://bugzilla.kernel.org/show_bug.cgi?id=4857, http://www.ussg.iu.edu/hypermail/linux/kernel/0510.1/0014.html , and https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=137005. Instead of pivot_root, we will use busybox's switch_root.

Busybox is a Swiss army knife shell that contains almost everything you will need to boot. It can be installed as a statically linked binary, so you won't have to deal with copying libraries for the binaries you use.

Emerge a static busybox. If you don't want to overwrite the busybox that's already on your system, use emerge's ROOT= option.

The busybox ebuild makes an inconvenient choice for the CONFIG_BUSYBOX_EXEC_PATH option. Busybox uses this setting to locate itself when it needs to execute commands. The default for this option is /proc/self/exe, which has the effect that /proc needs to be mounted for most scripts to work. When the kernel starts /linuxrc, /proc is not mounted, so the above scripts for initrd will fail. The fix is to explictly reference /bin/busybox when /proc is not mounted. If you would rather not prefix some commands with /bin/busybox, you can build your own busybox with CONFIG_BUSYBOX_EXEC_PATH="/bin/busybox". You can also save about a half meg of memory by disabling the two hundred or so unneeded commands that the ebuild includes.

Preparing the initramfs image
Initramfs uses a compressed cpio archive, rather than the raw filesystem image that initrd uses. First, create a root for your initramfs and make the top level directories:

Now copy busybox into your initramfs and hard link sh to it. Busybox doesn't include cryptsetup, so you also need to copy that. Fortunately, cryptsetup is statically linked.

Create the necessary devices in your dev directory. Replace sda3 with whatever device you are using for your encrypted parition. Use ls -l to get the right major and minor device numbers.

linuxrc for initramfs

The linuxrc script opens and mounts the encrypted root partition and then calls /sbin/init to boot the OS. Change CRDEV to point to your encrypted partition. Create this file in the root of your initramfs. When you are done, make it executable with chmod +x linuxrc. If you use the kernel's rdinit= option, you do not need an /init. Switch_root checks for /init to make sure it is being run correctly, so the script has to make sure it's there. Instead of using touch, you could just put an empty /init in the root of your initramfs.

devmap_mknod.sh for initramfs

devmap_mknod.sh is the same as for initrd, except that the busybox mkdir and mknod commands don't support long options. Create this file in the root of your initramfs.

Make the initramfs archive file and copy it to /boot:

Add this to your grub.conf. Replace /bzImage-2.6.16 with the name of your kernel image. Note that we use rdinit=, not init=.

Note: to debug problems try adding /bin/busybox /bin/sh to linuxrc.

Encrypting the Filesystem
This is a bit tricky. In order to encrypt the filesystem using luks, you need to be able to use a cryptsetup-luks binary, not a normal cryptsetup binary. You can do this with a gentoo install cd 2006.0 or later. Earlier versions only contain the normal cryptsetup binary. i'm going to do this using a second hard drive (/dev/sdb). i'm going to set up the encrypted partition and copy everything from the 'old' hard drive (/dev/sdb) to the 'new' one (/dev/sda).

you could do this with a livecd, by starting it with the docache option, then switching in a cd that has a cryptsetup-luks binary on it, but that's a bit more complicated than this method. note: if the livecd supports usb sticks, you could put the luks cyptsetup onto one of those and use that... just another idea...


 * Ok, so now i have two hard drive in my pc the old (/dev/sdb) and the new (/dev/sda) that i will be encrypting.

(note: this is optional, and can take a LONG time)
 * First, make sure everything that was on the drive can never be read again


 * Now we format the partition with luks, this creates the header and master key


 * Now we need to let cryptsetup create the /dev/mapper entry


 * Now format the partition. i'm going to use reiserfs.


 * Now mount the partition

(first I'm going to mount the drive I'm going to copy from at another location)
 * I'm going to copy everything from my current root partition to this new encrypted partition

note: this howto is not quite finished, but is actively being worked on

Modifying fstab & grub.conf (& local udev rules if necessary)
We need to modify /etc/fstab to point to our new root. Here's my new fstab:

And here's my new grub.conf:

The following section is most probably needed only in case you didn't emerge multipath-tools (they are not included yet in many (other than gentoo) distributions). If this is your case, use this line in your custom/local udev rules (e.g. in /etc/udev/00-local.rules):

Administering LUKS
For this section, we will be using a loopback file to demonstrate basic luks administration.

First you will need to create the loopback file and set it up.

Formatting
Now that we have a device, we need to format it using luks note: 'format' here means add the luks header and create a master key. this has nothing to do with the filesystem

Opening a device
Now that the device is formatted, we need to 'open' it. This means that it is set up to where we can use it in a meaningful way.

this created the device /dev/mapper/encrypted. You can choose the name as you wish

Making a Filesystem and Mounting
Now we can 'format' it again. This time format means to create a filesystem on it. I'm going to use reiserfs.

Unmounting and Closing a device
To unmount and close a file, do this:

The device /dev/mapper/encrypted no longer exists. neither does /dev/loop1.

Password management
luks allows you to easily manage passwords to your encrypted partitions/files/etc... this section explains how to add and delete passwords. Adding a Password

if you want to add another password, setup the loopback device again and use this command:

You entered the first password to decrypt the master key. you then gave cryptsetup a new password to encrypt the master key with. it then stored this new encrypted version of the master key in slot1. now you have two valid passwords for this file
 * What happened now was this:

to test this, you would use cryptsetup luksOpen /dev/loop1 foo and try both passwords (doing a cryptsetup luksClose foo in between of course)

note: the 'first password' can be any valid password. For example, if you have 5 valid passwords, and want to add a sixth one, you can enter any of those 5 to create the 6th. Deleting a Password

This command deletes the password stored in slot1 (the second slot)

Automatic Mounting of Encrypted User Directories
Till 14:36, 5 April 2006 (GMT): Im not using Gentoo, so I may miss some Gentoo specific details. pam_mount 0.13.0 (and maybe older releases, too) can handle luks encrypted partitions.

You can test manually whether this works with:

This should ask you for the luks passphrase, decrypts /path/to/encrypted/device and mounts it to /path/to/mountpoint If mount tells you something about crypt beeing an unknown filesystem, make sure that mount.crypt is in /sbin, it may be in /usr/bin, with a symlink:

In /etc/security/pam_mount.conf you need an entry like this:

In /etc/pam.d/system-auth you need need to add 2 lines to the default file:

Additional options about ciphers etc. are stored in the luks header of the partition after invoking the luksFormat command and they do not need to be specified here (they will even be ignored when specified).

WARNING Make sure that you luks encrypted partition ist closed after logout, umounting it is not enough. A encrypted partition /path/to/encrypted/device is normally decrypted and mapped to /dev/mapper/_path_to_encrypted_device by pam_mount. This file must not exist after the user logged out.

Encrypting swap and /tmp
If you only encrypt the users' home directories, you might also want to encrypt swap and the places where temporary files are stored to ensure a high degree of privacy. Fortunately for those places, data persistence across sessions is not important, so they can be recreated from scratch when booting. This is accomplished by passing cryptsetup /dev/urandom as the key file. (/dev/random might not be active enough yet in the early boot stages.)

All you have to do is add (and change) some entries in /etc/fstab and in /etc/conf.d/dmcrypt. The latter is checked before fstab is interpreted and tells cryptsetup which devices to map where. You basically just insert entries for two devices: swap and tmp.

Mapping block devices to encrypted devices
Now for the first entry, to create an encrypted swap partition. Let's assume you want /dev/sda3 (probably safer in case you plug in a new hard drive: /dev/disk/by-id/ata-FOO_123456_0987-part3) to become your swap. The boot script needs to know the source (the block device to encrypt), the target (where to map it to) and the type (swap in this case) for the encryption it will perform. So enter these values to have /dev/sda3 encrypted and mapped to /dev/mapper/crypt-swap:

By saying that this will be for a swap partition, /dev/urandom is automatically selected as the key file.

The lines for the /tmp partition (mapped from /dev/disk/by-id/ata-FOO_123456_0987-part6 in this example) are a bit more complicated:

It will be encrypted with a random key, mapped to /dev/mapper/crypt-tmp, made into an ext2 file system, and the permissions and ownership will be set appropriately after mounting. The value of the options variable is passed to cryptsetup, so you may specify anything you want here. /etc/conf.d/dmcrypt has plenty of comments and examples, so you should feel pretty comfortable there.

Mounting the mapped devices
So far, the partitions have been only mapped, but mounting now is only one simple step away: Adapt your old entries in /etc/fstab. For Linux, the /dev/mapper/foo files look like ordinary block devices:

But wait, ain't there more temporary directories than just /tmp? Yes, but you can simply redirect them. So better shut down X now (if you had it running), delete /var/tmp and link there from /tmp:

This should give you a fresh swap and a new /tmp every time you boot, and no possibility to recover data you had there after shutting down your computer.

DM-Crypt