dm-crypt/Encrypting an entire system

From ArchWiki
< Dm-crypt
Revision as of 01:39, 18 June 2014 by Kynikos (talk | contribs) (Overview: add advantage)
Jump to: navigation, search

Back to dm-crypt.

The following are examples of common scenarios of full system encryption with dm-crypt. They explain all the adaptations that need to be done to the normal installation procedure. All the necessary tools are on the installation image.


Securing a root filesystem is where dm-crypt excels, feature and performance-wise. When a system's root filesystem is on a dm-crypt device, nearly every file on the system is encrypted. Unlike selectively encrypting non-root filesystems, an encrypted root filesystem can conceal information such as which programs are installed, the usernames of all user accounts, and common data-leakage vectors such as mlocate and /var/log/. Furthermore, an encrypted root filesystem makes tampering with the system far more difficult, as everything except the boot loader and kernel is encrypted.

All scenarios illustrated in the following share these advantages, other pros and cons differentiating them are summarized below:

Scenarios Advantages Disadvantages
#Simple partition layout with LUKS

shows a basic and straight-forward set-up for a fully LUKS encrypted root.

  • Simple partitioning and setup
  • Inflexible; disk-space to be encrypted has to be pre-allocated

achieves partitioning flexiblity by using LVM inside a single LUKS encrypted partition.

  • Simple partitioning with knowledge of LVM
  • Only one key required to unlock all volumes (e.g. easy resume-from-disk setup)
  • Volume layout not transparent when locked
  • Easiest method to allow suspension to disk
  • LVM adds an additional mapping layer and hook
  • Less useful, if a singular volume should receive a separate key

uses dm-crypt only after the LVM is setup.

  • LVM can be used to have encrypted volumes span multiple disks
  • Easy mix of un-/encrypted volume groups
  • Complex; changing volumes requires changing encryption mappers too
  • Volumes require individual keys
  • LVM layout is transparent when locked
#Plain dm-crypt

uses dm-crypt plain mode, i.e. without a LUKS header and its options for multiple keys.
This scenario also employs USB devices for /boot and key storage, which may be applied to the other scenarios.

  • High care to all encryption parameters is required
  • Single encryption key and no option to change it

While all above scenarios provide much greater protection from outside threats than encrypted secondary filesystems, they also share a common disadvantage: any user in possession of the encryption key is able to decrypt the entire drive, and therefore can access other users' data. If that is of concern, it is possible to use a combination of blockdevice and stacked filesystem encryption and reap the advantages of both. See Disk encryption to plan ahead.

See also Dm-crypt/Drive preparation#Partitioning for a general overview of the partitioning strategies used in the scenarios.

Simple partition layout with LUKS

This example covers a full system encryption with dmcrypt+ LUKS in a simple partition layout:

|Boot partition      |LUKS encrypted system     |Optional free space       |
|                    |partition                 |for additional partitions |
|/dev/sdaY           |/dev/sdaX                 |or swap to be setup later |

The first steps can be performed directly after booting the Arch Linux install image.

Preparing the disk

Prior to creating any partitions, you should inform yourself about the importance and methods to securely erase the disk, described in Dm-crypt/Drive preparation.

Then create the needed partitions, at least one for / (e.g. /dev/sdaX) and /boot (/dev/sdaY), see Partitioning.

Preparing non-boot partitions

The following commands create and mount the encrypted root partition. They correspond to the procedure described in detail in Dm-crypt/Encrypting a non-root file system#Partition (which, despite the title, can be applied to root partitions, as long as mkinitcpio and the boot loader are correctly configured). If you want to use particular non-default encryption options (e.g. cipher, key length), see the encryption options before executing the first command:

# cryptsetup -y -v luksFormat /dev/sdaX
# cryptsetup open /dev/sdaX cryptroot
# mkfs -t ext4 /dev/mapper/cryptroot
# mount -t ext4 /dev/mapper/cryptroot /mnt

Check the mapping works as intended:

# umount /mnt
# cryptsetup close cryptroot
# cryptsetup open /dev/sdaX cryptroot
# mount -t ext4 /dev/mapper/cryptroot /mnt

If you created separate partitions (e.g. /home), these steps have to be adapted and repeated for all of them, except for /boot. See Dm-crypt/Encrypting_a_non-root_file_system#Automated_unlocking_and_mounting on how to handle additional partitions at boot.

Note that each blockdevice requires its own passphrase. This may be inconvenient, because it results in a separate passphrase to be input during boot. An alternative is to use a keyfile stored in the system partition to unlock the separate partition via crypttab. See Dm-crypt/Device encryption#Using LUKS to Format Partitions_with a Keyfile for instructions.

Preparing the boot partition

What you do have to setup is a non-encrypted /boot partition, which is needed for a crypted root. For a standard MBR/non-EFI /boot partition, for example, execute:

# mkfs -t ext4 /dev/sdaY
# mkdir /mnt/boot
# mount -t ext4 /dev/sdaY /mnt/boot

Mounting the devices

At Installation guide#Mount the partitions you will have to mount the mapped devices, not the actual partitions. Of course /boot, which is not encrypted, will still have to be mounted directly.

Configuring mkinitcpio

Add the encrypt hook to mkinitcpio.conf before filesystems:

HOOKS="... encrypt ... filesystems ..."

See dm-crypt/System configuration#mkinitcpio for details and other hooks that you may need.

Configuring the boot loader

In order to boot the encrypted root partition, the following kernel parameter needs to be set by the boot loader:


See Dm-crypt/System configuration#Boot loader for details and other parameters that you may need.


The straight-forward method is to set up LVM on top of the encrypted partition instead of the other way round. Technically the LVM is setup inside one big encrypted blockdevice. Hence, the LVM is not transparent until the blockdevice is unlocked and the underlying volume structure is scanned and mounted during boot. The disk layout in this example is:

+------------------------------------------------------------------------------------- + +--------------+
|Logical volume1 15GB  |Logical volume2 35GB      |Logical volume3 200GB               | |              |
|/dev/MyStorage/rootvol|/dev/MyStorage/homevol    |/dev/MyStorage/mediavol             | |              |
|_ _ _ _ _ _ _ _ _ _ _ |_ _ _ _ _ _ _ _ _ _ _ _ _ |_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | | Boot         |
|                                                                                      | | partition    |
|                        LUKS encrypted partition                                      | |              |
|                          /dev/sdaX                                                   | | /dev/sdaY    |
+--------------------------------------------------------------------------------------+ +--------------+

This method does not allow you to span the logical volumes over multiple disks, even in the future. The #LUKS on LVM method does not have this limitation.

Preparing the disk

Prior to creating any partitions, you should inform yourself about the importance and methods to securely erase the disk, described in Dm-crypt/Drive preparation.

When using the GRUB bootloader together with GPT, create a BIOS Boot Partition as explained in GRUB#BIOS systems.

Create a partition to be mounted at /boot of type 8300 with a size of 100 MB or more.

Create a partition of type 8E00, which will later contain the encrypted container.

Create the LUKS encrypted container at the second partition. Enter the chosen password twice.

# cryptsetup luksFormat /dev/sdaX

For more information about the available cryptsetup options see the LUKS encryption options prior to above command.

Open the container:

# cryptsetup open --type luks /dev/sdaX lvm

The decrypted container is now available at /dev/mapper/lvm.

Preparing the logical volumes

Create a physical volume on top of the opened LUKS container:

# pvcreate /dev/mapper/lvm

Create the volume group named MyStorage, adding the previously created physical volume to it:

# vgcreate MyStorage /dev/mapper/lvm

Create several logical volumes on the volume group:

# lvcreate -L 15G MyStorage -n rootvol
# lvcreate -L 35G MyStorage -n homevol
# lvcreate -L 200G MyStorage -n mediavol

Create an Ext4 filesystem on each logical volume:

# mkfs.ext4 /dev/mapper/MyStorage-rootvol
# mkfs.ext4 /dev/mapper/MyStorage-homevol
# mkfs.ext4 /dev/mapper/MyStorage-mediavol

Mount the root filesystem to /mnt:

# mount /dev/MyStorage/rootvol /mnt

Create the directory /mnt/home:

# mkdir /mnt/home

Mount the home filesystem to /mnt/home:

# mount /dev/MyStorage/homevol /mnt/home

Preparing the boot partition

The bootloader loads the kernel, initramfs, and its own configuration files from the /boot directory. This directory must be located on a separate unencrypted filesystem.

Create an Ext2 filesystem on the partition intended for /boot. Any filesystem that can be read by the bootloader is eligible.

# mkfs.ext2 /dev/sdaY

Create the directory /mnt/boot:

# mkdir /mnt/boot

Mount the partition to /mnt/boot:

# mount /dev/sdaY /mnt/boot

Aftwards continue with the installation procedure up to the mkinitcpio step.

Configuring mkinitcpio

Add the encrypt and lvm2 hooks to mkinitcpio.conf, before filesystems:

HOOKS="... encrypt lvm2 ... filesystems ..."
Note: The order of both hooks no longer matters with the current implementation of lvm2.

See dm-crypt/System configuration#mkinitcpio for details and other hooks that you may need.

Configuring the boot loader

In order unlock the encrypted root partition at boot, the following kernel parameters need to be set by the boot loader:

cryptdevice=/dev/partition:MyStorage root=/dev/mapper/MyStorage-rootvol

See Dm-crypt/System configuration#Boot loader for details.

Note: When re-installing GRUB, you may receive warnings like /run/lvm/lvmetad.socket: connect failed: No such file or directory or WARNING: failed to connect to lvmetad: No such file or directory. Falling back to internal scanning. This is because /run is not available inside the chroot. These warnings will not prevent the system from booting, provided that everything has been done correctly, so you may continue with the installation.


To use encryption on top of LVM, the LVM volumes are set up first and then used as the base for the encrypted partitions. This way, a mixture of encrypted and non-encrypted volumes/partitions is possible as well. Unlike #LVM on LUKS, this method allows normally spanning the logical volumes over multiple disks.

The following short example creates a LUKS on LVM setup and mixes in the use of a key-file for the /home partition and temporary crypt volumes for /tmp and /swap. The latter is considered desirable from a security perspective, because no potentially sensitive temporary data survives the reboot, when the encryption is re-initialised. If you are experienced with LVM, you will be able to ignore/replace LVM and other specifics according to your plan. If you want to span a logical volume over multiple disks during setup already, a procedure to do so is described in Dm-crypt/Specialties#Expanding LVM on multiple disks.

Tango-view-fullscreen.pngThis article or section needs expansion.Tango-view-fullscreen.png

Reason: The intro of this scenario needs some adjustment now that a comparison has been added to #Overview. A suggested structure is to make it similar to the #Simple_partition_layout_with_LUKS intro. (Discuss in Talk:Dm-crypt/Encrypting an entire system#)

Preparing the disk

Partitioning scheme:

  • /dev/sda1 -> /boot
  • /dev/sda2 -> LVM

Randomise /dev/sda2 according to Dm-crypt/Drive preparation#dm-crypt_wipe_before_installation.

Preparing the logical volumes

lvm pvcreate /dev/sda2
lvm vgcreate lvm /dev/sda2
lvm lvcreate -L 10G -n root lvm
lvm lvcreate -L 500M -n swap lvm
lvm lvcreate -L 500M -n tmp lvm
lvm lvcreate -l 100%FREE -n home lvm
cryptsetup luksFormat -c aes-xts-plain64 -s 512 /dev/lvm/root
cryptsetup open --type luks /dev/lvm/root root
mkreiserfs /dev/mapper/root
mount /dev/mapper/root /mnt

Note that /home will be encrypted later in this example. Further, note that if you ever have to access the encrypted root from the Arch-ISO, the above open action will allow you to after the LVM shows up.

Preparing the boot partition

dd if=/dev/zero of=/dev/sda1 bs=1M
mkreiserfs /dev/sda1
mkdir /mnt/boot
mount /dev/sda1 /mnt/boot

Now after setup of the encrypted LVM partitioning, it would be time to install: Arch Install Scripts.

Configuring mkinitcpio

Add the lvm2 and encrypt hooks to mkinitcpio.conf, before filesystems:

HOOKS="... lvm2 encrypt ... filesystems ..."

See dm-crypt/System configuration#mkinitcpio for details and other hooks that you may need.

Configuring the boot loader

For the above example, change the kernel options for the root-device auto-configured in the bootloader installation from root=/dev/hda3 to

cryptdevice=/dev/lvm/root:root root=/dev/mapper/root

More general, the kernel command line for LUKS <-> LVM is constructed like this:

root=/dev/mapper/<volume-group>-<logical-volume> cryptdevice=/dev/<luks-part>:<volume-group>

For example:

root=/dev/mapper/vg-arch cryptdevice=/dev/sda4:vg

Or like this:

cryptdevice=/dev/<volume-group>/<logical-volume>:root root=/dev/mapper/root

If you want install the system on a usb stick, you need to add lvmdelay=/dev/mapper/lvm-root

Configuring fstab and crypttab

 /dev/mapper/root        /       ext4            defaults        0       1
 /dev/sda1               /boot   ext4            defaults        0       2
 /dev/mapper/tmp         /tmp    tmpfs           defaults        0       0
 /dev/mapper/swap        none    swap            sw              0       0

The following crypttab options will re-encrypt the temporary filesystems each reboot:

 swap	/dev/lvm/swap	/dev/urandom	swap,cipher=aes-xts-plain64,size=256
 tmp	/dev/lvm/tmp	/dev/urandom	tmp,cipher=aes-xts-plain64,size=256

Encrypting logical volume /home

Since this scenario uses LVM as the primary and dm-crypt as secondary mapper, each encrypted logical volume requires its own encryption. Yet, unlike the temporary filesystems configured with volatile encryption above, the logical volume for /home should be persistent, of course. The following assumes you have rebooted into the installed system, otherwise you have to adjust paths. To safe on entering a second passphrase at boot for it, a keyfile is created:

mkdir -m 700 /etc/luks-keys
dd if=/dev/random of=/etc/luks-keys/home bs=1 count=256

The logical volume is encrypted with it:

cryptsetup luksFormat -v -s 512 /dev/lvm/home /etc/luks-keys/home
cryptsetup -d /etc/luks-keys/home open --type luks /dev/lvm/home home
mkfs -t ext4 /dev/mapper/home
mount /dev/mapper/home /home

The encrypted mount is configured in crypttab:

home	/dev/lvm/home   /etc/luks-keys/home
/dev/mapper/home        /home   ext4        defaults        0       2

and setup is done.

If you want to expand the logical volume for /home (or any other volume) at a later point, it is important to note that the LUKS encrypted part has to be resized as well. For a procedure see Dm-crypt/Specialties#Expanding_LVM_on_multiple_disks.

LUKS on software RAID

Tango-view-fullscreen.pngThis article or section needs expansion.Tango-view-fullscreen.png

Plain dm-crypt

This scenario sets up a system on a dm-crypt a full disk with plain mode encryption. Note that for most use cases, the methods using LUKS described above are the better options for both system encryption and encrypted partitions. LUKS features like key management with multiple pass-phrases/key-files are unavailable with plain mode.

The scenario uses a USB stick for the boot device and another one to store the encryption key. The disk layout is:

+------------------------------------------------------------+ +---------------+ +---------------+
|disk drive /dev/sdaX encrypted using plain mode and LVM     | |USB stick 1    | |USB stick 2    |
|--------------------+------------------+--------------------| |---------------| |---------------|
|Volume 1:           |Volume 2:         |Volume 3:           | |Boot device    | |Encryption key |
|                    |                  |                    | |               | |file storage   |
|root                |swap              |home                | |/boot          | |(unpartitioned |
|                    |                  |                    | |               | |in example)    |
|/dev/store/root     |/dev/store/swap   |/dev/store/home     | |/dev/sdY1      | |/dev/sdZ       |
+--------------------+------------------+--------------------+ +---------------+ +---------------+

The reasons for the use of two USB-keys are:

  • The boot loader options required to open/unlock a plain encrypted device are detailed. Typing them each boot is error prone, storing them on an unencrypted /boot partition on the same device results in security concerns.
  • This scenario uses a key file, storing the keyfile on a second USB stick for security again. A passphrase with good entropy may be used instead.

The main consideration for choosing plain over LUKS mode for the scenario is:

  • dm-crypt plain mode does not require a header on the encrypted disk. This means that an unpartitioned, encrypted disk will be indistinguishable from a disk filled with random data, which is the desired attribute for this scenario.

Plain dm-crypt encrypted disks can be more resilient to damage than LUKS encrypted disks, because it does not rely on an encryption master-key which can be a single-point of failure if damaged. However, using plain mode also requires more manual configuration of encryption options to achieve the same cryptographic strength. See also Disk encryption#Cryptographic_metadata

Note: If you have a requirement for a blockdevice without a cryptheader but want to use LUKS instead of plain mode for above noted disadvantages, cryptsetup offers a --header option too. While it cannot be used with the encrypt hook, it can generally be used to place the LUKS header remote from the encrypted blockdevice. For example it could be placed on the usb-key /dev/sdZ instead of the key-file (using a passphrase instead gives easy two-factor authentication).

Preparing the disk

It is vital that the mapped device is filled with data. In particular this applies to the scenario usecase we apply here.

See Dm-crypt/Drive preparation and Dm-crypt/Drive preparation#dm-crypt_specific_methods

Preparing the non-boot partitions

See Dm-crypt/Device encryption#Encryption options for plain mode for details.

Using the device /dev/sdX, with the twofish-xts cipher with a 512 bit key size and using a keyfile we have the following options for this scenario:

# cryptsetup --hash=sha512 --cipher=twofish-xts-plain64 --offset=0 --key-file=/dev/sdZ --key-size=512 open --type=plain /dev/sdX enc

Unlike encrypting with LUKS, the above command must be executed in full whenever the mapping needs to be re-established, so it is important to remember the cipher, hash and key file details.

We can now check a mapping entry has been made for /dev/mapper/enc:

# fdisk -l

Next, we setup LVM logical volumes on the mapped device, see Lvm#Installing_Arch_Linux_on_LVM for further details:

# pvcreate /dev/mapper/enc
# vgcreate store /dev/mapper/enc
# lvcreate -L 20G store -n root
# lvcreate -C y -L 10G store -n swap
# lvcreate -l +100%FREE store -n home

We format and mount them and activate swap, see File systems#Format a device for further details:

# mkfs.ext4 /dev/store/root
# mkfs.ext4 /dev/store/home
# mount /dev/store/root /mnt
# mkdir /mnt/home
# mount /dev/store/home /mnt/home
# mkswap /dev/store/swap
# swapon /dev/store/swap

Preparing the boot partition

The /boot partition can be installed on the standard vfat partition of a USB stick, if required. But if manual partitioning is needed, then a small 200MB partition is all that is required. Create the partition using a partitioning tool of your choice.

We choose a non-journalling file system to preserve the flash memory of the /boot partition, if not already formatted as vfat:

# mkfs.ext2 /dev/sdY1
# mkdir /mnt/boot
# mount /dev/sdY1 /mnt/boot

Configuring mkinitcpio

Add the encrypt and lvm2 hooks to mkinitcpio.conf, before filesystems:

HOOKS="... encrypt lvm2 ... filesystems ..."

See dm-crypt/System configuration#mkinitcpio for details and other hooks that you may need.

Configuring the boot loader

In order to boot the encrypted root partition, the following kernel parameters need to be set by the boot loader:

cryptdevice=/dev/sdX:enc cryptkey=/dev/sdZ:0:512 crypto=sha512:twofish-xts-plain64:512:0:

See Dm-crypt/System configuration#Boot loader for details and other parameters that you may need.

Tip: If using GRUB, you can install it on the same USB as the /boot partition with:
# grub-install --recheck /dev/sdY


You may wish to remove the USB sticks after booting. Since the /boot partition is not usually needed, the noauto option can be added to the relevant line in /etc/fstab:

# /dev/sdYn
/dev/sdYn /boot ext2 noauto,rw,noatime 0 2

However, when an update to the kernel or bootloader is required, the /boot partition must be present and mounted. As the entry in fstab already exists, it can be mounted simply with:

# mount /boot