Introduction to crypttab with examples

In a Linux based operating system, the crypttab file (/etc/crypttab), is used to store static information about encrypted block devices which are meant to be set up and unlocked at boot. In this tutorial we learn how it is structured and how to organize data in it.

In this tutorial you will learn:

  • What the crypttab file is used for
  • How data is organized inside the crypttab file
Introduction to crypttab with examples
Introduction to crypttab with examples

Software requirements and conventions used

Software Requirements and Linux Command Line Conventions
Category Requirements, Conventions or Software Version Used
System Distribution-independent
Software No specific software needed
Other None
Conventions # – requires given linux-commands to be executed with root privileges either directly as a root user or by use of sudo command
$ – requires given linux-commands to be executed as a regular non-privileged user

How data is organized in the crypttab file

As we already said, the /etc/crypttab file on Linux distributions is used to store static information about encrypted block devices which should be unlocked and set during system boot. Each row in the file is dedicated to a block device, and data in it is organized in columns. There four columns, in order:

  1. The device mapper name which should be used for the volume
  2. The encrypted block device reference
  3. The encryption key which should eventually be used to unlock the device
  4. A comma-separated list of options for the device

Of the fields listed above, only the first two are mandatory. Let’s see them all in a more detailed way.

The first column: the device mapper name

In each row of the /etc/crypttab file, the first, mandatory column, is used to store the device mapper name to use for an encrypted block device. What is this exactly?




On Linux, the main way to setup an encrypted block device is by using the cryptsetup utility. With it, we can use two encryption methods: plain and LUKS. The first method is simpler and needs no metadata to be stored on the device. The second is more feature-rich: the device is encrypted using a master key, and can be unlocked using multiple passwords. Passwords themselves are hashed with a salt which is stored on a header created (by default) on the encrypted device (it can also be stored separately). If the header is damaged all data is lost.

When we unlock a device using the cryptsetup utility we have to specify the device mapper name to be used for the unlocked volume. Device mapper is the system which Linux uses to map block devices to higher-level virtual devices. It is used, for example, for LVM logical volumes and volume groups, for RAID devices, and also to store encrypted block devices, as in this case. Device mapper volumes are represented inside the /dev/mapper directory and can be listed simply by using the ls command as in the example below:

$ ls /dev/mapper
root_lv
home_lv
[...]

In the output of the command above, we can see two files representing logical volumes.

Suppose we want to unlock a LUKS encrypted block device with cryptsetup. In the most basic situation, we would use the following syntax:

$ sudo cryptsetup luksOpen /path/to/encrypted/block/device dm-volume-name

The volume name is exactly what we need to provide in the first column of each row in the crypttab file.

The second column: the encrypted block device

The second column of the crypttab file is used to reference the encrypted block device. A reference can be made by path, for example: /dev/sda1, but since the path of a block device is not guaranteed to remain the same at each boot, the best way to reference it is by using its UUID or Universally Unique identifier. We can do so by using the same notation we would use in the /etc/fstab:

UUID=2ae2767d-3ec6-4d37-9639-e16f013f1e60

The third column: absolute path to the encryption key

When using LUKS as a method of device encryption, we can setup a file to be used as the device key. We saw how to do this in a previous tutorial. If we want the key to be used to unlock the device at boot (notice that this could represent a security issue), we have to specify its absolute path in the third field of the crypttab file. If we don’t want to use a key file to open the block device we can simply write “none” or “-” in this field.




What if the encryption keyfile is located on a different device, say for example an usb key? In that case we can append a : (colon) sign after the specified keyfile path, followed by an identifier for the filesystem the key is on. Once again the recommended way to reference the filesystem is by its UUID. Just to make an example, to specify the keyfile is in the /keyfiles directory on the filesystem which has the 17513654-34ed-4c84-9808-3aedfc22a20e UUID, we would write:
/keyfiles:UUID=17513654-34ed-4c84-9808-3aedfc22a20e

For this to work, of course, the system should be able to read the filesystem in which the keyfile is stored. If for some reason we are using a keyfile to unlock the root filesystem (this is a bad practice, and basically makes encryption useless, since if someone gets the device on which the key is stored, he has full access to data on it), we also would need to regenerate the system initramfs, so that it will include the changed crypttab file.

If the specified keyfile is not found, the user is prompted to manually enter a password to unlock the encrypted block device as a fallback.

The fourth column: encrypted device options

We can use the fourth column of each crypttab row to specify the encryption options which should be used to unlock the encrypted block device. We can, for example, specify the encryption type, the cipher, hash and size. This is typically needed when the block device was encrypted by using plain dm-crypt instead of LUKS. Since with this system there is no header where encryption metadata is stored, the encryption parameters must be provided each time the device is opened.

For example, to open and use /dev/sda1 as a plain-dm crypt device from the command line, and map it as sda1_crypt, we would write:

$ sudo cryptsetup open \
  --type plain \
  --cipher=aes-xts-plain64 \
  --hash=sha512 \
  --size=512
  /dev/sda1
  sda1_crypt

To specify the same options and values statically in the crypttab file, in the fourth column of the dedicated row, we would write:

plain,cipher=aes-xts-plain64,hash=sha512,size=512

If we are using LUKS, those information are stored in the metadata header, so there is no need to report them this way. All we have to do is to be sure that luks mode is used. We can do it by replacing “plain” with “luks”.




Other options which can be used in this column are:
Option function
discard Needed to allow discard requests (TRIM) through the encrypted block device (this has security implications)
header Needed to specify the location of the LUKS header if it is separated from the encrypted block device
noauto If this option is used, the device is not automatically unlocked at boot
nofail Marks the unlocking of the block device as non-essential. The boot process is not stopped if unlocking is not successful
readonly Set the encrypted block device in read-only mode
tries= Takes the number of attempts the user is prompted to provide the right password. The default is 0, which means no limit.
headless= Takes a boolean as a value. If true, the user is never prompted for a password interactively

The one above is not the complete list of the options which can be used in the crypttab file. To learn all of them, you can take a look at the crypttab manual.

Closing thoughts

In this tutorial we learned what is the role of /etc/crypttab file in a Linux system: it is used to store static data about encrypted block devices which should be unlocked at boot. We also learned how information are organized in the file and saw some of the options which can be specified in the fourth column of each row.



Comments and Discussions
Linux Forum