dm-crypt/Encrypting an entire system
Back to Dm-crypt with LUKS/draft.
- 1 Encrypting a system partition
- 2 Encrypting the home partition
- 3 Encrypting a loopback filesystem
- 4 Encrypting a LVM setup
- 4.1 LVM and dm-crypt manually (short version)
Encrypting a system partition
Most of the installation of an encrypted system partition can be carried out normally. However, there are a few areas where it is important to make certain selections. These are marked below.
Prepare hard drive for Arch Install Scripts
This assumes you want to install an encrypted system with the Arch Install Scripts, have created partitions for
/dev/sdaY) at least, following the Installation Guide and deciding against using LVM. Prior to creating the partitions you have done a preparation of the disk for encryption according to your necessities (the necessary tools are on the installation-ISO).
First check, if the blockdevice mapper
dm_mod is loaded with
# lsmod | grep mod
If one wants to use the default LUKS-cipher algorithm, there is no need to specify one for the luksFormat. You may want to check the defaults used by the cryptsetup version at time of installation and decide yourself. With defaults a dm-crypt/LUKS blockdevice for the crypted root can be created
# cryptsetup -y -v luksFormat /dev/sdaX
# cryptsetup open /dev/sdaX cryptroot
formatted with your desired filesystem
# mkfs -t ext4 /dev/mapper/cryptroot
# mount -t ext4 /dev/mapper/cryptroot /mnt
At this point, just before installing the base system, it might be useful to check the mapping works as intended:
# umount /mnt # cryptsetup close cryptroot
and mount it again to check.
If you created a separate
/home partition, the steps have to be adapted and repeated for that. In LUKS#Encrypting_the_home_partition the creation is described and in LUKS#Crypttab how to activate the automount during 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 key-file stored in the system partition to unlock the separate partition via
crypttab. How that is done may be derived from the LVM example below. If you leave unpartitioned disk space, the necessary configuration for the
/home partition may be done later too along with migrating data.
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 that may be achieved by formatting
# mkfs -t ext2 /dev/sdaY
creating a mount-point for installation
# mkdir /mnt/boot
and mounting it
# mount -t ext2 /dev/sdaY /mnt/boot
That is basically what is necessary at this point before installing the base system with the Arch Install Scripts. Take care to install the bootloader to
/mnt/boot with the
pacstrap script. Additional configuration steps must be followed before booting the installed system.
One important point is to add the hooks relevant for your particular install in the correct order to
/etc/mkinitcpio.conf. The one you have to add when encrypting the root filesystem is
encrypt. A recommended hook for LUKS encrypted blockdevices is
shutdown to ensure controlled unmounting during system shutdown. Others needed, e.g.
keymap, should be clear from other manual steps you follow during the installation and further details in the following. For detailed information about initramfs configuration and available Hooks refer to Mkinitcpio#HOOKS.
encrypthook is only needed if your root partition is a LUKS partition (or a LUKS partition that needs to be mounted before root). The
encrypthook is not needed for any other encrypted partitions (swap, for example). System initialization scripts (
/etc/crypttabamong others) take care of those.
It is important that the
encrypt hook comes before the
filesystems hook (in case you are using LVM on LUKS, the order should be:
encrypt lvm2 filesystems), so make sure that your
HOOKS array looks something like this:
HOOKS="(base udev) ... encrypt ... filesystems ..."
If you need support for foreign keymaps for your encryption password, you have to specify the hook
keymap as well before
If you have a USB keyboard, you will need the
keyboard hook. Without it, no USB keyboard will work in early userspace. If you still have this problem after adding
usbinput, though this is deprecated.
In the same file, you may want to add to "MODULES" dm_mod and the filesystem types used, e.g:
After you are done don't forget:
mkinitcpio -p linux
Kernel parameter configuration of the bootloader
In order to enable booting an encrypted root partition, it is passed to the
encrypt hook with kernel parameters to be set up in the bootloader.
The main parameter is cryptdevice, with the following syntax:
- The path to the raw encrypted device. Usage of Persistent block device naming is advisable.
- The name given to the device after decryption, will be available as
/dev/mapper/<dmname>. (<dmname> MUST NOT be set to a name already used for LVM partitions!)
So if the encrypted root device in the example is
/dev/sda2 and the decrypted one should be mapped to
/dev/mapper/cryptroot, the kernel parameter would be:
This will make the system prompt for the passphrase to unlock the root device on a cold boot.
Depending on the setup other parameters are required as well:
cryptdevice=<device>:<dmname> root=<device> resume=<device> cryptkey=<device>:<fstype>:<path>
- The device file of the actual (decrypted) root filesystem. If the filesystem is formatted directly on the decrypted device file this will be
/dev/mapper/<dmname>. If LVM is used, the device must be addressed like
- The device file of the decrypted (swap) filesystem used for suspend2disk.
- Required for reading a keyfile from a filesystem.
The syntax for the optional cryptkey parameter is:
- The raw block device where the key exists.
- The filesystem type of <device> (or auto).
- The absolute path of the keyfile within the device.
Further, double-check the
genfstab scripts result for your
/dev/mapper/cryptroot and other mounts.
Encrypting the home partition
This example covers encryption of a home partition or comparable other partition containing user data. For full system encryption see Encrypting a system partition. You can either have a single user's home directory on a partition, or create a common partition for all user's home partitions.
Prepare the hard disk drive by performing a secure erasure. Create at least one partition, that will be used as home partition, with a partitioning tool of your choice. Note that the secure erasure can also be done to that single partition only. Setup the LUKS and dm-crypt magic with
# cryptsetup [OPTION...] luksFormat <device>
as described in the section Mapping Physical Partitions to LUKS.
In the above command replace
<device> with the previously created home partition.
To gain access to the encrypted partition, unlock it with the device mapper, using
# cryptsetup open <device> <name>
It is recommended to read the full explanation about this command here.
After unlocking the partition, it will be available at
/dev/mapper/<name>. Now create a filesystem of your choice with
# mkfs.fstype /dev/mapper/<name>
Mount the filesystem to
/home, or if it should be accessible to only one user to
Before shutting down the filesystem needs to unmounted and, in this order, the LUKS partition needs to be closed with
# cryptsetup close <name>
Automated unlocking and mounting
There are two different solutions for automating the process of unlocking the home partition and mounting its filesystem. Using crypttab, unlocking happens at boot time, and with Pam mount it happens on user login.
This is the recommended solution if you want to use one common partition for all user's home partitions.
To make systemd open and mount the encrypted partition on boot, two files need to be edited,
/etc/crypttab file describes encrypted block devices that are set up during system boot by
For example, to open the encrypted LUKS partition on the device
/dev/sdx1 with the name
home, add this line:
home /dev/sdx1 none luks
none will trigger a prompt during boot to type the passphrase for unlocking the partition. A keyfile can also be set up and referenced instead. This results in an automatic unlocking, if the keyfile is accessible during boot. Since LUKS offers the option to have multiple keys, the chosen option can also be changed later.
man crypttab (5) and read the file
/etc/crypttab for more information.
/etc/fstab and add an entry for the previously created path in
/dev/mapper. Following above example the fstab entry looks like this:
/dev/mapper/home /home <filesystem> defaults 0 2
This is the recommended solution if you want to have a single user's home directory on a partition. To automount user homes on login see Pam mount.
Encrypting a loopback filesystem
A loop device enables to map a blockdevice to a file with the standard util-linux tool
losetup. The file can then contain a filesystem, which can be used quite like any other filesystem. A lot of users know Truecrypt as a tool to create encrypted containers. Just about the same functionality can be achieved with a loopback filesystem encrypted with LUKS and is shown in the following example.
Preparation and mapping
First, start by creating an encrypted container!
dd if=/dev/urandom of=/bigsecret bs=1M count=10
This will create the file
bigsecret with a size of 10 megabytes.
losetup /dev/loop0 /bigsecret
This will create the device node
/dev/loop0, so that we can mount/use our container.
/dev/loop0: No such file or directory, you need to first load the kernel module with
modprobe loop. These days (Kernel 3.2) loop devices are created on demand. Ask for a new loop device with
cryptsetup luksFormat /dev/loop0
This will ask you for a password for your new container file.
Command failed: Failed to setup dm-crypt key mapping. Check kernel for support for the aes-cbc-essiv:sha256 cipher spec and verify that /dev/loop0 contains at least 133 sectors, then run
cryptsetup open --type luks /dev/loop0 secret
The encrypted container is now available through the device file
Now we are able to create a partition in the container:
and mount it...
mkdir /mnt/secret mount -t ext2 /dev/mapper/secret /mnt/secret
We can now use the container as if it was a normal partition! To unmount the container:
umount /mnt/secret cryptsetup luksClose secret losetup -d /dev/loop0 # free the loopdevice.
so, if you want to mount the container again, you just apply the following commands:
losetup /dev/loop0 /bigsecret cryptsetup open --type luks /dev/loop0 secret mount -t ext2 /dev/mapper/secret /mnt/secret
Encrypt using a key-file
Let us first generate a 2048 byte random keyfile:
dd if=/dev/urandom of=keyfile bs=1k count=2
We can now format our container using this key
cryptsetup luksFormat /dev/loop0 keyfile
or our partition :
cryptsetup luksFormat /dev/hda2 keyfile
Once formatted, we can now open the LUKS device using the key:
cryptsetup -d keyfile open --type luks /dev/loop0 container
You can now like before format the device
/dev/mapper/container with your favorite filesystem and then mount it just as easily.
The keyfile is now the only key to your file. I personally advise encrypting your keyfile using your private GPG key and storing an off-site secured copy of the file.
Resizing the loopback filesystem
First we should unmount the encrypted container:
umount /mnt/secret cryptsetup luksClose secret losetup -d /dev/loop0 # free the loopdevice.
After this we need to expand our container file with the size of the data we want to add:
dd if=/dev/urandom bs=1M count=1024 | cat - >> /bigsecret
Be careful to really use TWO
>, or you will override your current container!
You could use
/dev/zero instead of
/dev/urandom to significantly speed up the process, but with
/dev/zero your encrypted filesystems will not be as secure. (A better option to create random data quicker than
frandom , available from the AUR).
A faster (almost instant) method than dd is
truncate , but its use has the same security implications as using /dev/zero. The size passed to truncate is the final size to make the file, so don't use a value less than that of the current file or you will lose data. e.g. to increase a 20G file by 10G: truncate -s 30G filename.
Now we have to map the container to the loop device:
losetup /dev/loop0 /bigsecret cryptsetup open --type luks /dev/loop0 secret
After this we will resize the encrypted part of the container to the maximum size of the container file:
cryptsetup resize secret
Finally, we can resize the filesystem. Here is an example for ext2/3/4:
e2fsck -f /dev/mapper/secret # Just doing a filesystem check, because it's a bad idea to resize a broken fs resize2fs /dev/mapper/secret
You can now mount your container again:
mount /dev/mapper/secret /mnt/secret
Encrypting a LVM setup
It is easy to use encryption with LVM. This section describes specific aspects of setting up an encrypted LVM setup and has a mini-howto for users with experiences of using both, cryptsetup and LVM. If you are looking for verbose installation instructions of such a setup, you might want to read Encrypted_LVM first.
If you do not know how to set up LVM, then read Installing with Software RAID or LVM. Using LVM is particularly helpful when a system with multiple partitions is planned. While there are a number of alternatives for unlocking multiple partitions with the same passphrase/key, the default Arch
mkinitcpio hooks do not implement non-standard ways. A combination of the
lvm2 hooks, however, enables to setup a system with numerous logical volumes as partitions while using one passphrase/key to unlock them.
LVM on LUKS
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 most important thing in setting LVM on top of encryption is to configure the initramfs for running both the
encrypt hook and the
lvm2 hook (and those two before the
filesystems hook). In the past, it was necessary to ensure the correct ordering of these hooks in
/etc/mkinitcpio.conf but the order no longer matters with the current implementation of
LUKS on LVM
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 around a mixture of encrypted and non-encrypted volumes/partitions is possible as well.
For encrypted partitions inside an LVM, the LVM-hook has to run first, before the respective encrypted logical volumes can be unlocked. So for this add the
encrypt hook in
/etc/mkinitcpio.conf after the
lvm2 hook, if you chose to set up encrypted partitions on top of LVM.
Both these options are described in more detail in Encrypted_LVM. The following represents the historic guide from before the verbose page.
LVM and dm-crypt manually (short version)
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. For
cryptsetup options, please see above.
Setting up the encrypted system
cryptsetup -d /dev/random -c aes-xts-plain -s 512 create lvm /dev/sda2 dd if=/dev/urandom of=/dev/mapper/lvm cryptsetup remove lvm 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-plain -s 512 /dev/lvm/root cryptsetup open --type luks /dev/lvm/root root mkreiserfs /dev/mapper/root mount /dev/mapper/root /mnt dd if=/dev/zero of=/dev/sda1 bs=1M mkreiserfs /dev/sda1 mkdir /mnt/boot mount /dev/sda1 /mnt/boot mkdir -p -m 700 /mnt/etc/luks-keys dd if=/dev/random of=/mnt/etc/luks-keys/home bs=1 count=256
Install Arch Linux
Now after setup of the encrypted LVM partitioning, it would be time to install: Arch Install Scripts.
encrypt (in that order) before
filesystems in the
HOOKS array. Again, note that this is setting encryption on top of LVM.
If you want install the system on a usb stick, you need to put
usb just after
Boot options for LUKS-LVM
For the above example, change the kernel options for the root-device auto-configured in the bootloader installation from
More general, the kernel command line for LUKS <-> LVM is constructed like this:
Or like this:
If you want install the system on a usb stick, you need to add
Filesystem mounts system
/dev/mapper/root / reiserfs defaults 0 1 /dev/sda1 /boot reiserfs defaults 0 2 /dev/mapper/tmp /tmp tmpfs defaults 0 0 /dev/mapper/swap none swap sw 0 0
swap /dev/lvm/swap SWAP -c aes-xts-plain -h whirlpool -s 512 tmp /dev/lvm/tmp /dev/urandom -c aes-xts-plain -s 512
Encrypting /home after reboot
cryptsetup luksFormat -c aes-xts-plain -s 512 /dev/lvm/home /etc/luks-keys/home cryptsetup open --type luks -d /etc/luks-keys/home /dev/lvm/home home mkreiserfs /dev/mapper/home mount /dev/mapper/home /home
Filesystem mounts home
home /dev/lvm/home /etc/luks-keys/home
/dev/mapper/home /home reiserfs defaults 0 0