dm-crypt/Swap encryption
Depending on requirements, different methods may be used to encrypt the swap partition which are described in the following. A setup where the swap encryption is re-initialised on reboot (with a new encryption) provides higher data protection, because it avoids sensitive file fragments which may have been swapped out a long time ago without being overwritten. However, re-encrypting swap also forbids using a suspend-to-disk feature generally.
Without suspend-to-disk support
In systems where suspend-to-disk (hibernation) is not a desired feature, /etc/crypttab can be set up to decrypt the swap partition with a random password with plain dm-crypt at boot-time. The random password is discarded on shutdown, leaving behind only encrypted, inaccessible data in the swap device.
To enable this feature, simply uncomment the line beginning with swap in /etc/crypttab. Change the device parameter to the name of your swap device. For example, it will look something like this:
/etc/crypttab
# <name> <device> <password> <options> swap /dev/sdX# /dev/urandom swap,cipher=aes-xts-plain64,size=512,sector-size=4096
This will map /dev/sdX# to /dev/mapper/swap as a swap partition that can be added in /etc/fstab like a normal swap. If you had a non-encrypted swap partition before, do not forget to disable it - or re-use its fstab entry by changing the device to /dev/mapper/swap. The default options should be sufficient for most usage. For other options and an explanation of each column, see crypttab(5) as well as point cryptsetup FAQ 2.3.
/dev/sda, /dev/sdb) changes upon each boot. Options are:
- Use
by-idandby-pathpaths. However, these are both are susceptible to hardware changes. See Persistent block device naming#by-id and by-path. - Use PARTLABEL.
- Use an LVM logical volume's name.
- Use the method described in #UUID and LABEL. Labels and UUIDS cannot be used directly because of the recreation and re-encryption of the swap device on every boot with
mkswap, see cryptsetup FAQ.
To use a by-id persistent device naming instead of kernel simple naming, first identify the swap device:
# find -L /dev/disk -samefile /dev/sdaX
/dev/disk/by-id/ata-WDC_WD2500BEVT-22ZCT0_WD-WXE908VF0470-partX /dev/disk/by-id/wwn-0x60015ee0000b237f-partX
Then use as a persistent reference for the /dev/sdX# example partition (if two results are returned as above, choose either one of them):
/etc/crypttab
# <name> <device> <password> <options> swap /dev/disk/by-id/ata-WDC_WD2500BEVT-22ZCT0_WD-WXE908VF0470-partX /dev/urandom swap,cipher=aes-xts-plain64,size=512,sector-size=4096
After a reboot to activate the encrypted swap, you will note that running swapon -s shows an arbitrary device mapper entry (e.g. /dev/dm-1) for it, while the lsblk command shows crypt in the FSTYPE column. Due to fresh encryption each boot, the UUID for /dev/mapper/swap will change every time.
UUID and LABEL
It is dangerous to use crypttab swap with simple kernel device names like /dev/sdX# or even /dev/disk/by-id/ata-SERIAL-partX. A small change in your device names or partitioning layout and /etc/crypttab will see your valuable data formatted on the next boot. Same if you use PARTUUID and then decide to use that partition for something else without removing the crypttab entry first.
It is more reliable to identify the correct partition by giving it a genuine UUID or LABEL. By default that does not work because dm-crypt and mkswap would simply overwrite any content on that partition which would remove the UUID and LABEL too; however, it is possible to specify a swap offset. This allows you to create a very small, empty, bogus filesystem with no other purpose than providing a persistent UUID or LABEL for the swap encryption.
Create a filesystem with label of your choice:
# mkfs.ext2 -L cryptswap /dev/sdX# 1M
The unusual parameter after the device name limits the filesystem size to 1 MiB, leaving room for encrypted swap behind it.
# blkid /dev/sdX#
/dev/sdX#: LABEL="cryptswap" UUID="b72c384e-bd3c-49aa-b7a7-a28ea81a2605" TYPE="ext2"
With this, /dev/sdX# now can easily be identified either by UUID or LABEL, regardless of how its device name or even partition number might change in the future. All that is left are the /etc/crypttab and /etc/fstab entries. For example, using different encryption options:
/etc/crypttab
# <name> <device> <password> <options> swap LABEL=cryptswap /dev/urandom swap,offset=2048,cipher=aes-xts-plain64,size=512,sector-size=4096
Note the offset: it is 2048 sectors of 512 bytes (it is not affected by the dm-crypt sector size), thus 1 MiB. This way the encrypted swap will not affect the filesystem LABEL/UUID, and data alignment works out as well.
/etc/fstab
# <filesystem> <dir> <type> <options> <dump> <pass> /dev/mapper/swap none swap defaults 0 0
Using this setup, the cryptswap will only try to use the partition with the corresponding LABEL, regardless of what its device name may be. Should you decide to use the partition for something else, by formatting it the cryptswap LABEL would also be gone, so /etc/crypttab will not overwrite it on your next boot.
Disabling hibernation in desktop environments
Desktop environments may not automatically detect that a swap partition is randomly encrypted and cannot be used for suspend-to-disk.
Xfce can be configured to hide its Hibernate and Hybrid Sleep buttons by running these commands:
$ xfconf-query -c xfce4-session -np /shutdown/ShowHibernate -t bool -s false $ xfconf-query -c xfce4-session -np /shutdown/ShowHybridSleep -t bool -s false
With suspend-to-disk support
The following three methods are alternatives for setting up an encrypted swap for suspend-to-disk (hibernation). If you apply any of them, be aware that critical data swapped out by the system may potentially stay in the swap over a long period (i.e. until it is overwritten). To reduce this risk consider setting up a system job which re-encrypts swap, e.g. each time the system is going into a regular shut-down, along with the method of your choice.
LVM on LUKS
If the swap volume is in a volume group that gets activated in initramfs, simply follow the instructions in Power management/Suspend and hibernate#Hibernation.
Using a swap partition
swapoff /dev/device as root, and make sure to remove any line in /etc/crypttab pointing to this device.Use cryptsetup-luksFormat(8) to create the encrypted container for the swap partition:
# cryptsetup luksFormat --label swap /dev/device
Open the container to /dev/mapper/swap:
# cryptsetup open /dev/disk/by-label/swap swap
Create a swap filesystem inside the mapped partition:
# mkswap /dev/mapper/swap
If not using systemd#GPT partition automounting, add the mapped partition to /etc/fstab by adding the following line:
/dev/mapper/swap none swap defaults 0 0
To set up your system to resume from hibernation, use the resume=/dev/mapper/swap kernel parameter. See Power management/Suspend and hibernate#Pass hibernate location to initramfs for details.
Using a TPM
The following provides unattended swap decryption with a key stored in the TPM.
You can use systemd-cryptenroll to enroll the key to the Luks container and TPM, and wipe the previously created keyslot containing the password:
# systemd-cryptenroll --tpm2-device auto /dev/device # systemd-cryptenroll --wipe-slot password /dev/device
Check the result with
# systemd-cryptenroll /dev/device SLOT TYPE 0 tpm2
Using an additional passphrase or keyfile
The basic setup above has the disadvantage of having to insert an additional passphrase for the swap partition manually on every boot.
/boot is unencrypted. Please read about the issue reported here. Alternatively, use a gnupg-encrypted keyfile as per https://bbs.archlinux.org/viewtopic.php?id=120181
Unlocking the partition in the initramfs
To resume from an encrypted swap partition, the encrypted partition must be unlocked in the initramfs.
mkinitcpio
systemd-based initramfs
When using the systemd-based initramfs with the sd-encrypt mkinitcpio hook, either
- specify the appropriate
rd.luks.uuid=kernel parameters to unlock the swap partition, or - edit
crypttab.initramfsand regenerate the initramfs.
For example, for a TPM backed encrypted swap device:
/etc/crypttab.initramfs
swap UUID=56f8ee97-54b3-4a65-9282-688deb922527 none tpm2-device=auto
busybox-based initramfs
When using the default busybox-based initramfs with the encrypt hook, follow the instructions below.
If the swap device is on a different device from that of the root file system, it will not be opened by the encrypt hook, i.e. the resume will take place before /etc/crypttab can be used, therefore it is required to create a hook in /etc/mkinitcpio.conf to open the swap LUKS device before resuming.
encrypt hook, which can only unlock a single device (archlinux/mkinitcpio/mkinitcpio#231). With sd-encrypt multiple devices may be unlocked, see dm-crypt/System configuration#Using systemd-cryptsetup-generator.Now you have to create a hook to open the swap at boot time. You can either install and configure mkinitcpio-openswapAUR, or follow the following instructions. Create a hook file containing the open command:
/etc/initcpio/hooks/openswap
run_hook ()
{
cryptsetup open /dev/device swap
}
for opening the swap device by typing your password or
/etc/initcpio/hooks/openswap
run_hook ()
{
## Optional: To avoid race conditions
x=0;
while [ ! -b /dev/mapper/root-device ] && [ $x -le 10 ]; do
x=$((x+1))
sleep .2
done
## End of optional
mkdir crypto_key_device
mount /dev/mapper/root-device crypto_key_device
cryptsetup open --key-file crypto_key_device/path-to-the-key /dev/device swap
umount crypto_key_device
}
for opening the swap device by loading a keyfile from a crypted root device.
On some computers race conditions may occur when mkinitcpio tries to mount the device before the decryption process and device enumeration is completed. The commented Optional block will delay the boot process up to 2 seconds until the root device is ready to mount.
--allow-discards has to get added to the cryptsetup line in the openswap hook above. See Dm-crypt/Specialties#Discard/TRIM support for solid state drives (SSD) or SSD for more information on discard. Additionally you have to add the mount option 'discard' to your fstab entry for the swap device.Then create and edit the hook setup file:
/etc/initcpio/install/openswap
build ()
{
add_runscript
}
help ()
{
cat<<HELPEOF
This opens the swap encrypted partition /dev/device in /dev/mapper/swap
HELPEOF
}
Add the hook openswap in the HOOKS array in /etc/mkinitcpio.conf, before filesystem but after encrypt. Do not forget to add the resume hook after openswap.
HOOKS=(... encrypt openswap resume filesystems ...)
At boot time, the openswap hook will open the swap partition so the kernel resume may use it. If you use special hooks for resuming from hibernation, make sure they are placed after openswap in the HOOKS array. Please note that because of initrd opening swap, there is no entry for swap in /etc/crypttab needed in this case.
dracut
Create a keyfile:
# dd bs=512 count=4 if=/dev/random iflag=fullblock | install -m 0600 /dev/stdin /etc/cryptsetup-keys.d/swap.key
Add the keyfile to LUKS:
# cryptsetup luksAddKey /dev/device /etc/cryptsetup-keys.d/swap.key
Configure dracut to include the resume module and add the swap.key file to the initramfs (See also dracut#Hibernation):
/etc/dracut.conf.d/resume-from-hibernate.conf
add_dracutmodules+=" resume " install_items+=" /etc/cryptsetup-keys.d/swap.key "
Add the rd.luks.name and rd.luks.key (replace the swap's partition UUID) entries to your kernel command line.
Your kernel command might look like this now:
kernel /vmlinuz-linux cryptdevice=/dev/sda2:root root=/dev/mapper/root resume=/dev/mapper/swap rd.luks.name=fd839505-3213-4603-9a70-c5a96a24768f=swap rd.luks.key=/etc/cryptsetup-keys.d/swap.key ro
Using a swap file
A swap file can be used to reserve swap-space within an existing partition and may also be setup inside an encrypted blockdevice's partition.
Follow swap file creation instructions in Swap#Swap file and set up hibernation according to Power management/Suspend and hibernate#Configure the initramfs.
- When resuming from a swapfile the
resumeparameter must point to the unlocked/mapped device that contains the file system with the swap file. - Ensure that the resume hook of mkinitcpio is ran after the device the swap partition lives on is unlocked by placing
resumeafterencryptin theHOOKSarray.
Known issues
-
Stopped (with error) /dev/dm-1in logs. See systemd issue 1620.