dm-crypt/System configuration
- If in need to remotely unlock root or other early-boot filesystems (headless machine, distant servers...), follow the specific instructions from dm-crypt/Specialties#Remote unlocking of root (or other) partition.
- To ease inputting UUIDs, PARTUUIDs, etc. in configuration files, you can install and use a text editor that supports inserting command output (e.g. nano with
Ctrl+t
, Vim or Neovim with:read
or mcedit withAlt+u
) and pass it the apropriate lsblk or blkid command. Alternatively, you can install a terminal multiplexer and use its copy and paste functionality.
Unlocking in early userspace
Booting an encrypted root volume requires that the initramfs contains the necessary tools for early userspace to unlock the volume. The instructions on what to unlock are typically passed via kernel parameters.
The following sections describe how to configure mkinitcpio and list which kernel parameters are required.
mkinitcpio
Depending on the particular scenarios, a subset of the following mkinitcpio hooks will have to be enabled:
busybox | systemd | Use case |
---|---|---|
encrypt
|
sd-encrypt
|
Needed when the root partition is encrypted or when an encrypted partition needs to be mounted before the root partition. Not needed in other cases as system initialization scripts like /etc/crypttab already take care of unlocking other non-root partitions. This hook must be placed after the udev or systemd hook.
|
keyboard
|
Needed to make keyboards work in early userspace.
Tip: For systems that are booted with different hardware configurations (e.g. laptops with external keyboard vs. internal keyboard or headless systems), it is helpful to place this hook before
autodetect in order to always include all keyboard drivers. Otherwise the external keyboard only works in early userspace if it was connected when creating the image. |
|
keymap
|
sd-vconsole
|
Provides support for non-US keymaps for typing encryption passwords; it must come before the encrypt hook, otherwise you will need to enter your encryption password using the default US keymap. Set your keymap in /etc/vconsole.conf , see Keyboard configuration in console#Persistent configuration.
|
consolefont
|
Loads an alternative console font in early userspace. Set your font in /etc/vconsole.conf , see Linux console#Persistent configuration.
|
Other hooks needed should be clear from other manual steps followed during the installation of the system.
/etc/mkinitcpio.conf
.Examples
A typical /etc/mkinitcpio.conf
configuration using encrypt
hook:
/etc/mkinitcpio.conf
... HOOKS=(base udev autodetect microcode modconf kms keyboard keymap consolefont block encrypt lvm2 filesystems fsck) ...
A configuration with systemd-based initramfs using sd-encrypt
hook:
/etc/mkinitcpio.conf
... HOOKS=(base systemd autodetect microcode modconf kms keyboard sd-vconsole block sd-encrypt lvm2 filesystems fsck) ...
Kernel parameters
The kernel parameters you need to specify depend on whether the encrypt
hook or the sd-encrypt
hook is being used. root
and resume
are specified the same way for both.
root
The root=
parameter specifies the device
of the actual (decrypted) root file system:
root=device
- If the file system is formatted directly on the decrypted device file this will be
/dev/mapper/dmname
. - If a LVM gets activated first and contains an encrypted logical rootvolume, the above form applies as well.
- If the root file system is contained in a logical volume of a fully encrypted LVM, the device mapper for it will be in the general form of
root=/dev/volumegroup/logicalvolume
.
- The specification of the
root=
parameter can be omitted when using thesd-encrypt
hook and GPT partition automounting. See LUKS on a partition. - When using GRUB and generating
grub.cfg
with grub-mkconfig, theroot=
parameter does not need to be specified manually. grub-mkconfig will determine the correct UUID of the decrypted root filesystem and add it togrub.cfg
automatically.
resume
resume=device
-
device
is the device file of the decrypted (swap) filesystem used for suspend to disk. If swap is on a separate partition, it will be in the form of/dev/mapper/swap
. See also dm-crypt/Swap encryption.
Using encrypt hook
encrypt
hook does not support:
- Unlocking multiple encrypted disks (archlinux/mkinitcpio/mkinitcpio#231). Only one device can be unlocked in the initramfs.
- Using a detached LUKS header (archlinux/mkinitcpio/mkinitcpio#234).
- Setting additional options that are supported by crypttab.
cryptdevice
This specifies the device containing the encrypted root on a cold boot. It is parsed by the encrypt
hook to identify which device contains the encrypted system:
cryptdevice=device:dmname:options
-
device
is the path to the device backing the encrypted device. Usage of persistent block device naming is strongly recommended. -
dmname
is the device-mapper name given to the device after decryption, which will be available as/dev/mapper/dmname
. -
options
(optional) are comma separated options, e.g. for TRIM support. If no options are required, omit this parameter (usecryptdevice=device:dmname
). - If a LVM contains the encrypted root, the LVM gets activated first and the volume group containing the logical volume of the encrypted root serves as device. It is then followed by the respective volume group to be mapped to root. The parameter follows the form of
cryptdevice=/dev/vgname/lvname:dmname
.
cryptkey
cryptkey=
parameter does not need to be specified manually. You will then be prompted to enter the passphrase upon boot.This parameter specifies the location of a keyfile and is required by the encrypt
hook for reading such a keyfile to unlock the cryptdevice
(unless a key is in the default location, see below). It can have three parameter sets, depending on whether the keyfile exists as a file in a particular device, a bitstream starting on a specific location, or a file in the initramfs.
For a file in a device the format is:
cryptkey=device:fstype:path
-
device
is the raw block device where the key exists. Usage of persistent block device naming is strongly recommended. -
fstype
is the filesystem type ofdevice
(or auto). -
path
is the absolute path of the keyfile within the device.
Example: cryptkey=LABEL=usbstick:vfat:/secretkey
For a bitstream on a device the key's location is specified with the following:
cryptkey=device:offset:size
where the offset and size are in bytes. For example, cryptkey=UUID=ZZZZZZZZ-ZZZZ-ZZZZ-ZZZZ-ZZZZZZZZZZZZ:0:512
reads a 512 byte keyfile starting at the beginning of the device.
:
, you have to escape it with a backslash \
. In that case the cryptkey parameter would be as follows: cryptkey=/dev/disk/by-id/usb-123456-0\:0:0:512
for a USB key with the ID usb-123456-0:0
.For a file included in the initramfs the format is[1]:
cryptkey=rootfs:path
Example: cryptkey=rootfs:/secretkey
Also note that if cryptkey
is not specified, it defaults to /crypto_keyfile.bin
(in the initramfs).[2]
See also dm-crypt/Device encryption#Keyfiles.
crypto
This parameter is specific to pass dm-crypt plain mode options to the encrypt hook.
It takes the form
crypto=hash:cipher:keysize:offset:skip
The arguments relate directly to the cryptsetup options. See dm-crypt/Device encryption#Encryption options for plain mode.
For a disk encrypted with just plain default options, the crypto
arguments must be specified, but each entry can be left blank:
crypto=::::
A specific example of arguments is
crypto=sha512:twofish-xts-plain64:512:0:
Using systemd-cryptsetup-generator
systemd-cryptsetup-generator is a systemd unit generator that reads a subset of kernel parameters, and /etc/crypttab
, for the purpose of unlocking encrypted devices. See the systemd-cryptsetup-generator(8) man page for more details about it and all options it supports.
systemd-cryptsetup-generator is run during the initramfs stage when using the sd-encrypt
mkinitcpio hook or the systemd
dracut module.
In what follows, we describe some of the kernel parameters that systemd-cryptsetup-generator interprets.
- If the file
/etc/crypttab.initramfs
exists, it will be added to the initramfs as/etc/crypttab
, there you can specify devices that need to be unlocked at the initramfs phase. See #crypttab for the syntax. If/etc/crypttab.initramfs
does not exist, there will be no/etc/crypttab
in the initramfs and the unlockable devices will need to be specified via kernel parameters listed below. -
/etc/crypttab.initramfs
is not limited to using only UUID likerd.luks
. You can use any of the persistent block device naming methods. - Passwords entered during boot are cached in the kernel keyring by systemd-cryptsetup(8), so if multiple devices can be unlocked with the same password (this includes devices in crypttab that are unlocked after boot), then you will only need to input each password once.
- All of the
rd.luks
parameters can be specified multiple times to unlock multiple LUKS encrypted volumes. - The
rd.luks
parameters only support unlocking LUKS devices. To unlock a plain dm-crypt device, you must specify it in/etc/crypttab.initramfs
. See #crypttab for the syntax.
/etc/crypttab
or /etc/crypttab.initramfs
together with luks.*
or rd.luks.*
parameters, only those devices specified on the kernel command line will be activated and you will see Not creating device 'devicename' because it was not specified on the kernel command line.
. This is because the luks.*
or rd.luks.*
parameters control which devices from the crypttab get activated. To activate all devices in /etc/crypttab
do not specify any luks.*
parameters and use rd.luks.*
. To activate all devices in /etc/crypttab.initramfs
do not specify any luks.*
or rd.luks.*
parameters.rd.luks.uuid
rd.luks.uuid
can be omitted when using rd.luks.name
.rd.luks.uuid=XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
Specify the UUID of the device to be decrypted on boot with this flag.
By default, the mapped device will be located at /dev/mapper/luks-XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
where XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX is the UUID of the LUKS partition.
rd.luks.name
rd.luks.uuid
.rd.luks.name=XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX=name
Specify the name of the mapped device after the LUKS partition is open, where XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX is the UUID of the LUKS partition. This is equivalent to the second parameter of encrypt
's cryptdevice
.
For example, specifying rd.luks.name=12345678-9abc-def0-1234-56789abcdef0=root
causes the unlocked LUKS device with UUID 12345678-9ABC-DEF0-1234-56789ABCDEF0
to be located at /dev/mapper/root
.
rd.luks.key
Specify the location of a password file used to decrypt the device specified by its UUID. There is no default location like there is with the encrypt
hook parameter cryptkey
.
If the keyfile is included in the initramfs:
rd.luks.key=XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX=/path/to/keyfile
or
rd.luks.key=/path/to/keyfile
rd.luks.key
parameter can be omitted if the keyfile is included as /etc/cryptsetup-keys.d/name.key
.If the keyfile is on another device:
rd.luks.key=XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX=/path/to/keyfile:UUID=ZZZZZZZZ-ZZZZ-ZZZZ-ZZZZ-ZZZZZZZZZZZZ
Replace UUID=ZZZZZZZZ-ZZZZ-ZZZZ-ZZZZ-ZZZZZZZZZZZZ
with the identifier of the device on which the keyfile is located.
- If the type of file system is different than your root file system, you must include the kernel module for it in the initramfs.
-
rd.luks.key
with a keyfile on another device by default does not fallback to asking for a password if the device is not available. To fallback to a password prompt, specify thekeyfile-timeout=
option inrd.luks.options
. E.g. for a 10 second timeout:rd.luks.options=XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX=keyfile-timeout=10s
rd.luks.options
rd.luks.options=XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX=options
or
rd.luks.options=options
Set options for the device specified by it UUID or, if not specified, for all UUIDs not specified elsewhere (e.g., crypttab).
This parameter is the analogue of crypttab's options field. The format is the same—options are separated by commas, options with values are specified using option=value
. This is roughly equivalent to the third parameter of encrypt
's cryptdevice
.
For example:
rd.luks.options=timeout=10s,discard,password-echo=no,tries=1
Timeout
There are two options that affect the timeout for entering the password during boot:
-
rd.luks.options=timeout=mytimeout
specifies the timeout for querying for a password -
rootflags=x-systemd.device-timeout=mytimeout
specifies how long systemd should wait for the rootfs device to show up before giving up (defaults to 90 seconds)
If you want to disable the timeout altogether, then set both timeouts to zero:
rd.luks.options=timeout=0 rootflags=x-systemd.device-timeout=0
Password echo
When the user is typing the password, systemd-cryptsetup by default outputs asterisks (*
) for each typed character. This is unlike the encrypt
hook, which does not output anything. To silence the output, set the password-echo=no
option:
rd.luks.options=password-echo=no
Trusted Platform Module and FIDO2 keys
If a TPM2 chip is available in your system, or you use FIDO2-compatible security key, you can use it to automatically unlock your volume instead of using a password or a keyfile.
Set
- for TPM2 chip:
rd.luks.options=XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX=tpm2-device=auto
- for FIDO2 key:
rd.luks.options=XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX=fido2-device=auto
in addition to rd.luks.uuid
or rd.luks.name
Alternatively, /etc/crypttab.initramfs
can be used which avoids the need to specify any kernel options.
/etc/crypttab.initramfs
root UUID=XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX none tpm2-device=auto
/etc/crypttab.initramfs
.Here the encrypted volume is mounted under the name root
(appearing in /dev/mapper/root
), mounted via the UUID of the storage device, with no password, and retrieving the key from the TPM2 device.
Note that none
must be provided in the password field order for the TPM2 device to be used, otherwise the value given will be used as a password or key, and if it does not work it will ask you to type in the passkey during boot without attempting to load the key from the TPM2 device.
If specifying the device via UUID as shown above, ensure it is that of the underlying (encrypted) storage device, not the UUID of the decrypted volume that is specified elsewhere as the root filesystem.
rd.luks.data
When using a detached LUKS header, specify the block device with the encrypted data. Must be used together with rd.luks.options
to specify the header file location.
See dm-crypt/Specialties#Encrypted system using a detached LUKS header for details and instructions.
Unlocking in late userspace
crypttab
The /etc/crypttab
(encrypted device table) file is similar to the fstab file and contains a list of encrypted devices to be unlocked during system boot up. This file can be used for automatically mounting encrypted swap devices or secondary file systems.
crypttab
is read before fstab
, so that dm-crypt containers can be unlocked before the file system inside is mounted. Note that crypttab
is read after the system has booted up, therefore it is not a replacement for unlocking encrypted partitions by using mkinitcpio hooks and configuring them by using kernel parameters as in the case of encrypting the root partition. crypttab
processing at boot time is made by the systemd-cryptsetup-generator(8) automatically.
See crypttab(5) for details, read below for some examples, and the #Mounting at boot time section for instructions on how to use UUIDs to mount an encrypted device.
- If the
nofail
option is specified, the password entry screen may disappear while typing the password.nofail
should therefore only be used together with keyfiles. - For dm-crypt plain mode devices, the
plain
option must be explicitly set to force systemd-cryptsetup(8) to recognize them. See systemd issue 442.
/etc/crypttab
# Example crypttab file. Fields are: name, underlying device, passphrase, cryptsetup options. # Mount /dev/lvm/swap re-encrypting it with a fresh key each reboot swap /dev/lvm/swap /dev/urandom swap,cipher=aes-xts-plain64,size=256,sector-size=4096 # Mount /dev/lvm/tmp as /dev/mapper/tmp using plain dm-crypt with a random passphrase, making its contents unrecoverable after it is dismounted. tmp /dev/lvm/tmp /dev/urandom tmp,cipher=aes-xts-plain64,size=256 # Mount /dev/lvm/home as /dev/mapper/home using LUKS, and prompt for the passphrase at boot time. home /dev/lvm/home # Mount /dev/sdb1 as /dev/mapper/backup using LUKS, with a passphrase stored in a file. backup /dev/sdb1 /home/alice/backup.key # Unlock /dev/sdX using the only available TPM, naming it myvolume myvolume /dev/sdX none tpm2-device=auto
To test your crypttab immediately after editing it, reload the systemd manager configuration with a daemon-reload and start the newly generated systemd-cryptsetup@name.service
.
# cryptsetup status name
/dev/mapper/name is active. type: ... cipher: ... keysize: ... bits key location: ... device: /dev/sdxN sector size: ... offset: ... sectors size: ... sectors mode: ... flags: ...
For more on systemd-cryptsetup@name.service
, see #Mounting on demand.
Mounting at boot time
If you want to mount an encrypted drive at boot time, enter the device's UUID in /etc/crypttab
. You get the UUID (partition) by using the command lsblk -f
and adding it to crypttab
in the form:
/etc/crypttab
externaldrive UUID=2f9a8428-ac69-478a-88a2-4aa458565431 none timeout=180
The first parameter is your preferred device mapper's name for the encrypted drive. The option none
will trigger a prompt during boot to type the passphrase for unlocking the partition. The timeout
option defines a timeout in seconds for entering the decryption password during boot.
crypttab
uses a previously entered password, the third parameter can be set to none
and the cached password will be automatically used.timeout
option in crypttab
only determines the amount of time allowed for entering the password of the encrypted device. In addition, systemd also has a default timeout which determines the amount of time allowed for the device to be available (defaulting to 90 seconds), which is independent of the password timer. In consequence, even when the timeout
option in crypttab
is set to a value larger than 90 seconds (or it is at its default value of 0, meaning unlimited time), systemd will still only wait a maximum of 90 seconds for the device to be unlocked. In order to change the time systemd will wait for a device to be available, the option x-systemd.device-timeout
(see systemd.mount(5)) can be set in fstab for said device. It is probably desired, then, that the amount of time of the timeout
option in crypttab
is equal to the amount of time of the x-systemd.device-timeout
option in fstab
for each device mounted at boot time.Unlocking with a keyfile
If the keyfile for a secondary file system is itself stored inside an encrypted root, it is safe while the system is powered off and can be sourced to automatically unlock the mount during with boot via crypttab. For example, unlock a crypt specified by UUID:
/etc/crypttab
home-crypt UUID=XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX /etc/cryptsetup-keys.d/home-crypt.key
- If a keyfile is not specified, systemd-cryptsetup(8) will automatically try to load it from
/etc/cryptsetup-keys.d/name.key
and/run/cryptsetup-keys.d/name.key
.[3] - If you prefer to use a
--plain
mode blockdevice, the encryption options necessary to unlock it are specified in/etc/crypttab
. Take care to apply the systemd workaround mentioned in crypttab in this case.
Then use the device mapper's name (defined in /etc/crypttab
) to make an entry in /etc/fstab
:
/etc/fstab
/dev/mapper/home-crypt /home ext4 defaults 0 2
Since /dev/mapper/home-crypt
already is the result of a unique partition mapping, there is no need to specify a UUID for it. In any case, the mapper with the filesystem will have a different UUID than the partition it is encrypted in.
Mounting a stacked blockdevice
The systemd generators also automatically process stacked block devices at boot.
For example, you can create a RAID setup, use cryptsetup on it and create an LVM logical volume with respective filesystem inside the encrypted block device. A resulting:
$ lsblk -f
─sdXX linux_raid_member │ └─md0 crypto_LUKS │ └─cryptedbackup LVM2_member │ └─vgraid-lvraid ext4 /mnt/backup └─sdYY linux_raid_member └─md0 crypto_LUKS └─cryptedbackup LVM2_member └─vgraid-lvraid ext4 /mnt/backup
will ask for the passphrase and mount automatically at boot.
Given you specify the correct corresponding crypttab (e.g. UUID for the crypto_LUKS
device) and fstab (/dev/vgraid/lvraid
) entries, there is no need to add additional mkinitcpio hooks/configuration, because /etc/crypttab
processing applies to non-root mounts only. One exception is when the mdadm_udev
hook is used already (e.g. for the root device). In this case /etc/madadm.conf
and the initramfs need updating to achieve the correct root raid is picked first.
Mounting on demand
Instead of using
# cryptsetup open UUID=... externaldrive
you can start systemd-cryptsetup@externaldrive.service
when you have an entry as follows in your /etc/crypttab
:
/etc/crypttab
externaldrive UUID=... none noauto
That way you do not need to remember the exact crypttab options. It will prompt you for the passphrase if needed.
The corresponding unit file is generated automatically by systemd-cryptsetup-generator(8). You can list all generated unit files using:
$ systemctl list-unit-files | grep systemd-cryptsetup
Troubleshooting
System stuck on boot/password prompt does not show
If you are using Plymouth, make sure to use the correct modules (see Plymouth#mkinitcpio) or disable it. Otherwise, Plymouth will swallow the password prompt, making a system boot impossible.
If you unlock the LUKS device with a keyboard or a keyfile on a filesystem that is not present when generating the initramfs, you might need to add the corresponding modules to the MODULES
array of mkinitcpio. This might also be needed when the keyboard is connected through a USB hub. See mkinitcpio#MODULES for more information on this issue and Minimal initramfs#Sorting out modules as a starting point for potential keyboard and filesystem module names to be added.
In general, for keyboards that are not connected to the PC at initramfs generation time, you need to place the keyboard
hook before the autodetect
hook or only the parts necessary for the currently connected hardware are kept, see mkinitcpio#Common hooks.