IT Tutorial

Use an Encrypted Filesystem to Protect Your Data

An encrypted filesystem keeps your data safe even if someone steals your computer and tries to mount the disk.
There are a number of techniques for creating encrypted filesystems, typically based on using some kind of loopback device with an encryption layer spliced in the middle. Popular systems include cryptloop and loop-aes, but a more recent development called dm-crypt has some interesting advantages, so that's what we use for this hack. It's faster than cryptloop, easier to implement than loop-aes, and able to operate on a wide range of block devices even when using RAID or LVM because it's built on a new feature in the 2.6 kernel called device-mapper. device-mapper is designed to provide a generic and flexible way to add extra virtual layers on top of real block devices, allowing developers to implement special handlers for mirroring, snapshotting, concatenation, and encryption. As far as filesystem tools are concerned, they are dealing with a real block device, and any special functionality is hidden away by device-mapper.
dm-crypt is a device-mapper target that uses the kernel crypto API to provide transparent encryption, and it's even backward-compatible with the on-disk format used by cryptloop

Kernel Setup

dm-crypt uses the kernel's crypto API to perform the actual encryption. The standard Dapper kernel loads crypto ciphers as modules, and this hack uses 256-bit AES encryption, so make sure that your kernel has AES support loaded:

$ cat /proc/crypto


256-bit AES is an extremely high-grade encryption algorithm that has been approved by the NSA for use in protecting classified information up to the TOP SECRET level, which is the highest security level, encompassing information that would cause exceptionally grave damage to U.S. national security if disclosed.


If AES support is loaded, you will see output like:
name : aes
module : aes
type : cipher
blocksize : 16
min keysize : 16
max keysize : 32

If it's not loaded, you can force it to load manually using modprobe:
$ sudo modprobe aes


Cryptsetup should load this module automatically when required, but it's useful to know how to check for it and load the module manually if necessary.
Install the dmsetup package, which will provide the tools you need to configure the device-mapper target:

$ sudo apt-get install dmsetup cryptsetup


Check that the dmsetup package has created the device mapper:

$ ls -l /dev/mapper/control


Load the dm-crypt kernel module:

$ sudo modprobe dm-crypt


The dm-crypt module registers itself automatically with device-mapper when it's loaded, so next check that device-mapper has recognized it and added crypt as an available target:

$ sudo dmsetup targets


If everything has gone according to plan, you'll see crypt in the output:

crypt v1.1.0
striped v1.0.2
linear v1.0.1
error v1.0.1

Your system is now ready to mount encrypted devices. First, though, you need to create one!

Create an Encrypted Device

There are two options for creating a filesystem to mount as an encrypted device: create a disk image as a file and mount it as a loopback device, or use an actual block device (for example, /dev/hda3). In both cases, the procedure is almost identical, with the exception of some extra preparation required to create and bind the loopback device.

Create a loopback disk image

If you don't have a real device, such as a memory stick or extra disk partition, that you can encrypt, you can instead use dd to create an empty disk image and mount it as a loopback device. In this example, you'll call it secret.img and make it 100 MB in size. Just alter the count value if you want to make it a different size:
$ dd if=/dev/zero of=~/secret.img bs=1M count=

100



Use losetup to associate the image with a loopback device:

$ sudo losetup /dev/loop/0 ~/secret.img


You will now have a virtual block device at /dev/loop/0 that you can reference just like any other block device.

Set up the block device

Now you can set up either a real block device (for example, /dev/sda1) or a virtual block device, such as the loopback image created in the previous step, and mount it as an encrypted logical volume using device-mapper. Start by using cryptsetup to create a logical volume (called mysecrets) and bind the block device to it:
$ sudo cryptsetup -y create mysecrets

/dev/DEVICENAME



The last argument must be the block device that will be used as an encrypted volume, so if you're using the loopback image created in the previous step as a virtual block device, you would instead run something like:

$ sudo cryptsetup -y create mysecrets /dev/loop/0

In either case, you will be asked for a passphrase for the logical volume, and the -y flag indicates that cryptsetup should confirm the passphrase by asking you for it twice. It's critical that you get it right, because otherwise you'll find yourself locked out of your own data!

You can then confirm that the logical volume has been created:

$ sudo dmsetup ls


You should see the logical volume listed, although the major and minor device numbers may vary:

mysecrets (254, 0)

device-mapper mounts its virtual devices under /dev/mapper, so you should now have a virtual block device at /dev/mapper/mysecrets that behaves just like any other block device but is transparently encrypted.
Just like a real block device, you can create a filesystem on it:

$ sudo mkfs.ext3 /dev/mapper/mysecrets

Create a mount point for the new virtual block device and mount it:

$ sudo mkdir /mnt/mysecrets
$ sudo mount /dev/mapper/mysecrets /mnt/mysecrets


You should now be able to see it mounted just like any other device:

$ df -h /mnt/mysecrets
Filesystem Size Used Avail Use% Mounted on
/dev/mapper/mysecrets 97M 4.1M 88M 5% /mnt/mysecrets

Voil\x88 ! You now have a mounted filesystem that behaves just like any other filesystem, but any data you write to /mnt/mysecrets/ will be transparently encrypted before being written to disk, and anything you read from it will be decrypted on the fly.

Unmounting

Unmount the encrypted filesystem as usual:

$ sudo umount /mnt/mysecrets

Even after you have unmounted the block device, it's still configured in dm-crypt as a virtual device. You can confirm this by running sudo dmsetup ls again and seeing that the device is still listed. Because dm-crypt caches the passphrase, any other user on the computer can now remount the device without needing to know the passphrase. To prevent this, you need to explicitly remove the device from dm-crypt after unmounting it:

$ sudo cryptsetup remove mysecrets

After that, it will be truly gone, and remounting it will require the passphrase again.
You can simplify the process by creating a tiny script to unmount and remove the device:

#!/bin/sh
umount /mnt/mysecrets
cryptsetup remove mysecrets

Remounting

Since you'll probably want to mount the encrypted device as your normal user, it will make things easier if you add something like this to your /etc/fstab:

/dev/mapper/mysecrets /mnt/mysecrets ext3 noauto,noatime 0 0

You can also create a script that will take care of creating the dm-crypt device and mounting the volume for you (replace /dev/DEVICENAME with the actual device name or path to the file):

#!/bin/sh
cryptsetup create mysecrets /dev/DEVICENAME
mount /dev/mapper/mysecrets /mnt/mysecrets

If you're using a loopback device, you can also have the script bind the device for you:

#!/bin/sh
losetup /dev/loop/0 ~/secret.img
cryptsetup create mysecrets /dev/loop/0
mount /dev/mapper/mysecrets /mnt/mysecrets

If you get the message "ioctl: LOOP_SET_FD: Device or resource busy," it probably means that the loop device is still mounted. You can remove it with sudo losetup -d /dev/loop/0.

Hacking the Hack

You can even have your entire home directory encrypted if you configure the PAM (Pluggable Authentication Modules) subsystem to mount it for you when you log in. The libpam-mount module allows PAM to mount arbitrary devices automatically when a user logs in, so install it along with openssl:

$ sudo apt-get install libpam-mount openssl

Edit /etc/pam.d/common-auth and add this line to the end:

auth optional pam_mount.so use_first_pass

Then edit /etc/pam.d/common-session and add this line to the end:

session optional pam_mount.so

You need to configure PAM to know what volume to mount and where. In this example, the username is jon and you're using the device /dev/sda1, so substitute your username and device and add a line like this to /etc/security/pam_mount.conf:

volume jon crypt - /dev/sda1 /home/jon cipher=aes aes-256-ecb /home/jon.key

If you want to use a disk image, you need to specify the loop device (such as /dev/loop/0) here and ensure that the system has run losetup before jon has a chance to log in (for example, you could put losetup /dev/loop/0 /home/secret.img into /etc/rc.local).

Because the volume is encrypted, PAM needs access to the key to mount it. The last argument tells PAM to look in /home/jon.key for the key, so create the key file by encrypting your passphrase using OpenSSL:

$ sudo sh -c "echo
'

YOUR PASSPHRASE

'
| openssl aes-256-ecb >

/home/jon.key"



You will then be asked for a password, and you must enter the same password you use to log in as that user. The reason is that when you log in, PAM will take the password you provide, use it to decrypt the key file, and then use the passphrase contained in the key file to mount your home directory using dm-crypt.
Note, however, that the step above will leave your passphrase in plain text in your .history file, so clear your history (with history -c) or at least edit it to remove the command before proceeding.

Another approach that avoids storing your passphrase in an encrypted key file is to create your encrypted filesystem with the exact same password you use to log in. Then PAM can simply pass your password through to dm-crypt when you authenticate rather than extract it from the key file. In that situation, you can use a line like this in /etc/security/pam_mount.conf instead:

volume jon crypt - /dev/sda1 /home/jon cipher=aes - -

Finally, to make sure your encrypted home directory is unmounted automatically when you log out, edit /etc/login.defs and make sure the CLOSE_SESSIONS option is set:

CLOSE_SESSIONS yes






Use an Encrypted Filesystem to Protect Your Data