Scalability Blog

Scaling tips, insights, updates, culture, and more from our Server Experts.
 

Encrypting Sensitive Partitions with dm-crypt and LUKS

Introduction

There are many reasons an individual or organization may need/want to encrypt their data. Unfortunately, encryption of data can cause extra overhead and slightly degraded performance, depending on the method being used. We’ve chosen to highlight block-layer encryption, as it gives the best overall performance among the most commonly used methods.

Note: This example setup used involves encrypting the entire /home partition. This partition will need to be manually unlocked each boot by the root user. This is not always practical in all multiuser environments, but it’s assumed the administrator has root privileges the entire time the server is operational and does not have any services that depend on /home immediately after boot. You can easily remedy this by using a key file to encrypt/decrypt the volume and storing it on some USB drive that’s left plugged into the machine or just by placing it on the root filesystem. You would then also remove the noauto option from /etc/crypttab to automate the process of mounting this partition.

 

Installing cryptsetup

On CentOS:

# yum install cryptsetup-luks

On Debian:

# apt-get install cryptsetup

 

Filling the partitions with random data

For this step, we assume you will encrypt the following physical partitions on /dev/sda (your actual schema may vary):

1) /dev/sda2 (swap partition)
2) /dev/sda4 (/home partition – encrypted with passphrase)
3) /dev/sda5 (/tmp partition)

Now, most might assume encrypting only /home (where the sensitive data shall reside) would be sufficient. This is not necessarily the case. When you access encrypted data, it’s transparently decrypted by the kernel and stored either in memory or temporary files (usually /tmp) on the disk. Some times, the data that’s stored in memory can be swapped out to the disk, whenever the kernel decides it can do so. For these reasons, it’s very important to ensure at least /tmp and swap are encrypted as well. There are even some other cases where you’ll need to encrypt /var as well (Example: encrypting databases storing medical records, etc). However, in our case, we can simply create a symbolic link from /var/tmp → /tmp to ensure 99% or more of our temporary files always remain encrypted on disk.

WARNING! YOU ARE NOW GOING TO IRREVOCABLY ERASE ALL CONTENTS OF THESE PARTITIONS!

This part has the potential to take a very long time, so feel free to go occupy your time elsewhere for at least the next few hours, unless these partitions are fairly small (less than 50 GB or so).

/dev/sda2 (swap):

# shred -vf -n 1 /dev/sda2

/dev/sda4 (/home):

# shred -vf -n 1 /dev/sda4

/dev/sda5 (/tmp):

# shred -vf -n 1 /dev/sda5

 

Configuring LUKS parameters and formatting partitions

The next step is actually configuring the partitions for use with LUKS and formatting them with your desired filesystem. For our own purposes, we will be using the aes-xts-plain64 with a 512-bit keysize (2 * 256-bit keys) and the hash algorithm sha512.

/dev/sda2 (swap):

Skip this step

/dev/sda4 (/home):

# cryptsetup -c aes-xts-plain64 -s 512 -h sha512 --iter-time 5000 --use-random --verify-passphrase luksFormat /dev/sda4

 

/dev/sda5 (/tmp):

Skip this step

We’ve enabled the –use-random option here rather than –use-urandom since /dev/random blocks (to wait for new random data) and will not repeat any previously used data. It does not require large amounts of entropy to perform this step, so it’s generally safe to use this option. You will skip this step on swap and /tmp partitions, as these will be created with randomly-generated keys on each boot.

 

Writing /etc/crypttab and /etc/fstab for automatic boot configuration

/etc/crypttab:

#               
homevol /dev/sda4 none noauto,cipher=aes-xts-plain64,hash=sha512,size=512
swapvol /dev/sda2 /dev/urandom swap,cipher=aes-xts-plain64,hash=sha512,size=512
tmpvol /dev/sda5 /dev/urandom tmp,cipher=aes-xts-plain64,hash=sha512,size=512

You’ll notice the field names are defined on the first line. The first field is an arbitrary name you choose to represent your device mapping. Feel free to choose what you like here, but try to keep it relevant to avoid confusion. The second field tells the actual partition on which the real data is kept. The next field is optional and specifies a key file location (in case you use a key file in addition to (or in lieu of) a passphrase. Finally, the last field contains all the options to use when mounting your volumes.

Note: On the homevol line, you’ll notice the noauto option was added here. This was done to prevent stops on bootup when the passphrase is requested and the machine waits for you to type it. This will mean you need to manually mount this encrypted partition after each boot.

/etc/fstab:

/dev/mapper/swapvol     none  swap  defaults,sw 0 0
/dev/mapper/homevol     /home ext4  defaults,noatime,user,nosuid,nodev,noauto 0 0
/dev/mapper/tmpvol      /tmp  ext4  defaults,noatime,nosuid,nodev

This is a pretty standard fstab, with the only real difference being the device name – now /dev/mapper/(your previously chosen target name).

 

Formatting the partitions

We will now use the luksOpen command from the cryptsetup utility to open the new encrypted volume you created for /home. We will then format the partition in the ext4 filesystem, using the standard Linux utility mkfs.ext4.

/dev/sda4 (/home):

# cryptsetup luksOpen /dev/sda4 homevol

 

The previous command opens the volume (you’ll be prompted for your password) and readies it for our use.

/dev/sda4 (/home):

# mkfs.ext4 /dev/mapper/homevol

 

You’ve just formatted this volume’s filesystem with ext4. To configure your /tmp and swap partitions automatically, you should now perform a reboot. Just about any system out there should automatically load all required modules upon boot when mounting the filesystems. Since you are not encrypting /boot or the root filesystem (/), there is no need to recreate the initial ramdisk (initrd) to include those modules.

After your system has booted again, you should notice the swap and /tmp volumes were automatically configured and are mounted with the desired encryption settings.

 

Manually mounting your encrypted /home partition

# cryptsetup luksOpen /dev/sda4 homevol
# mount /dev/mapper/homevol /home

 

You will be prompted for your passphrase after the first command. Once you’ve unlocked the volume, you can proceed to mount the volume as normal with the second command.

 

Backing up the LUKS header from your /home partition

# cryptsetup luksHeaderBackup --header-backup-file /homevol_luksheader /dev/sda4

Change /homevol_luksheader to whatever filename you wish to use. Encrypt this file if desired and copy it to a safe remote location for safe keeping. You never know when you’ll need it.

 

Conclusion

In just a small amount of configuration time (excluding random data waiting time), you’ve managed to configure the most important partitions on your system to transparently encrypt/decrypt all data written/read from them. You’ve made tremendous strides in securing data, and are just a simple shutdown -h now or poweroff away from turning your precious customer data, secret documents or maybe even illicit material (shame on you!) into random data that’s useless to anyone without your passphrase or several hundred theoretical years of brute force key searching attempts.