Difference between revisions of "Dm-crypt/Swap encryption"

From ArchWiki
Jump to: navigation, search
(restructure sections tree)
m (mkinitcpio hook: wording)
 
(72 intermediate revisions by 20 users not shown)
Line 1: Line 1:
 
{{Lowercase title}}
 
{{Lowercase title}}
[[Category:Security]]
+
[[Category:Encryption]]
 
[[Category:File systems]]
 
[[Category:File systems]]
{{Stub|This article is currently under heavy restructuring: for its latest stable revision see [[Dm-crypt with LUKS]]}}
+
[[ja:Dm-crypt/スワップの暗号化]]
 +
Back to [[Dm-crypt]].
  
A swap partition may be added to an encrypted system, if required. The swap partition must be encrypted as well to protect any data swapped out by the system. Depending on the requirements, different methods may be used 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. However, re-encrypting swap also forbids using a suspend-to-disk feature generally.
+
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.
  
Back to [[Dm-crypt with LUKS/draft]].
+
== Without suspend-to-disk support ==
 +
 
 +
In systems where suspend-to-disk (''i.e..,'' hibernation) is not a desired feature, {{ic|/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 {{ic|swap}} in {{ic|/etc/crypttab}}. Change the {{ic|<device>}} parameter to the name of your swap device. For example, it will look something like this:
 +
 
 +
{{hc|/etc/crypttab|
 +
# <name>      <device>        <password>              <options>
 +
  swap        /dev/sd''X#''        /dev/urandom            <nowiki>swap,cipher=aes-cbc-essiv:sha256,size=256</nowiki>}}
 +
 
 +
This will map {{ic|/dev/sd''X#''}} to {{ic|/dev/mapper/swap}} as a swap partition that can be added in {{ic|/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 {{ic|/dev/mapper/swap}}. The default options should be sufficient for most usage. For other options see and an explanation of each column, see {{ic|man 5 crypttab}} as well as [https://gitlab.com/cryptsetup/cryptsetup/wikis/FrequentlyAskedQuestions#2-setup point cryptsetup FAQ 2.3].
 +
 
 +
{{Warning|All contents of the named device will be permanently '''deleted'''. It is dangerous to use the kernel's simple naming for a swap device, since their naming order (''e.g.'' {{ic|/dev/sda}}, {{ic|/dev/sdb}}) changes upon each boot. Options are:
 +
* Use {{ic|by-id}} and {{ic|by-path}} paths. However, these are both are susceptible to hardware changes. See [[Persistent block device naming#by-id and by-path]].
 +
* Use an [[LVM]] logical volume's name.
 +
* Use the method described in [[#UUID and LABEL]]. Labels and [[Persistent_block_device_naming#by-uuid|UUIDS]] '''cannot''' be used directly because of the recreation and re-encryption of the swap device on every boot with {{ic|mkswap}} [https://gitlab.com/cryptsetup/cryptsetup/wikis/FrequentlyAskedQuestions#2-setup].
 +
}}
 +
 
 +
To use a {{ic|by-id}} persistent device naming instead of kernel simple naming, first identify the swap device:
 +
 
 +
{{hc|# ls -l <nowiki>/dev/disk/*/* |</nowiki> grep sdaX|
 +
lrwxrwxrwx 1 root root 10 Oct 12 16:54 /dev/disk/by-id/ata-WDC_WD2500BEVT-22ZCT0_WD-WXE908VF0470-partX -> ../../sdaX
 +
lrwxrwxrwx 1 root root 10 Oct 12 16:54 /dev/disk/by-id/wwn-0x60015ee0000b237f-partX -> ../../sdaX
 +
}}
 +
 
 +
Then use as a persistent reference for the {{ic|/dev/sd''X#''}} example partition (if two results are returned as above, choose either one of them):
 +
 
 +
{{hc|/etc/crypttab|# <name>                      <device>                                  <password>    <options>
 +
  swap  /dev/disk/by-id/ata-WDC_WD2500BEVT-22ZCT0_WD-WXE908VF0470-partX  /dev/urandom  <nowiki>swap,cipher=aes-cbc-essiv:sha256,size=256</nowiki>}}
 +
 
 +
After a reboot to activate the encrypted swap, you will note that running {{ic|swapon -s}} shows an arbitrary device mapper entry (e.g. {{ic|/dev/dm-1}}) for it, while the {{ic|lsblk}} command shows '''crypt''' in the {{ic|FSTYPE}} column. Due to fresh encryption each boot, the UUID for {{ic|/dev/mapper/swap}} will change every time.
 +
 
 +
{{Note|If the partition chosen for swap was previously a LUKS partition, crypttab will not overwrite the partition to create a swap partition. This is a safety measure to prevent data loss from accidental mis-identification of the swap partition in crypttab. In order to use such a partition the [[Dm-crypt/Drive preparation#Wipe_LUKS_header|LUKS header must be overwritten]] once.}}
 +
 
 +
=== UUID and LABEL ===
 +
 
 +
As stated above, it is very dangerous to use crypttab swap with the kernel's simple naming or even with the device's ID, since these can easily change and the contents of the swap partition are deleted on every boot. To get around the changing of UUID's and label's of the swap partition on every boot, one can label a partition preceding the swap partition on the disk, and the swap partition can use the {{ic|offset}} option to indicate its location. The preceding partition's label and UUID will not change upon every boot.
 +
 
 +
In this example, a smaller partition is created explicitly for this purpose, although any existing partition preceding the swap partition can be used. To do this, first create a smaller filesystem with the label of your choice:
 +
 
 +
# mkfs.ext2 -L ''mylabel'' /dev/sd''X#'' 1M
 +
 
 +
where the ''{{ic|#}}'' is the partition number that will be before the swap partition, and {{ic|''mylabel''}} is the label you want to give the partition. The {{ic|1M}} indicates a size of 1 MiB for this smaller partition.
 +
 
 +
Now, in {{ic|/etc/crypttab}}, change {{ic|<device>}} to either the label of UUID of the preceding partition. Additionally add the {{ic|offset}} option. In this example, the swap partition is offset from the beginning of the smaller partition by 2048 sectors (1 MiB) and the label is used:
 +
 
 +
{{hc|1=/etc/crypttab|2=
 +
# <name> <device>      <password>    <options>
 +
swap    LABEL=''mylabel''  /dev/urandom  swap,offset=2048,cipher=aes-cbc-essiv:sha256,size=256}}
 +
 
 +
{{Warning|An incorrect label or offset option in crypttab can cause irrevocable data loss.}}
  
 
== With suspend-to-disk support ==
 
== With suspend-to-disk support ==
  
===LVM on LUKS===
+
To be able to resume after suspending the computer to disk (hibernate), it is required to keep the swap space intact. Therefore, it is required to have a pre-existent LUKS swap partition, which can be stored on the disk or input manually at startup.
A simple way to realize encrypted swap with suspend-to-disk support is by using [[LVM]] ontop the encryption layer, so one encrypted partition can contain infinite filesystems (root, swap, home, ...). Follow the instructions on [[#Encrypting a LVM setup]].
+
 
 +
The following three methods are alternatives for setting up an encrypted swap for resume-from-disk. 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 ===
 +
 
 +
A simple way to realize encrypted swap with suspend-to-disk support is by using a swap [[LVM]] device on the same encryption layer as the root volume, so that both are opened by the {{ic|encrypt}} hook at boot. Follow the instructions on [[Dm-crypt/Encrypting an entire system#LVM on LUKS]] and then just configure the [[Suspend and hibernate#Required_kernel_parameters|required kernel parameters]].
 +
 
 +
Assuming you have setup LVM on LUKS with a swap logical volume (at {{ic|/dev/MyStorage/swap}} for example), all you need to do is add the '''resume''' [[mkinitcpio]] hook, and add the {{ic|1=resume=/dev/MyStorage/swap}} kernel parameter to your boot loader. For [[GRUB]], this can be done by appending it to the {{ic|GRUB_CMDLINE_LINUX_DEFAULT}} variable in {{ic|/etc/default/grub}}.
 +
{{hc|/etc/default/grub|2=GRUB_CMDLINE_LINUX_DEFAULT="... resume=/dev/MyStorage/swap"}}
 +
then run {{ic|grub-mkconfig -o /boot/grub/grub.cfg}} to update GRUB's configuration file.
 +
To add the mkinitcpio hook, edit the following line in {{ic|mkinitcpio.conf}}
 +
{{hc|/etc/mkinitcpio.conf|2=HOOKS="... encrypt lvm2 '''resume''' ... filesystems ..."}}
 +
then run {{ic|mkinitcpio -p linux}} to update the [[initramfs]] image.
 +
 
 +
=== mkinitcpio hook ===
  
===mkinitcpio hook===
+
If the swap device is on a different device from that of the root file system, it will not be opened by the {{ic|encrypt}} hook, i.e. the resume will take place before {{ic|/etc/crypttab}} can be used, therefore it is required to create a hook in {{ic|/etc/mkinitcpio.conf}} to open the swap LUKS device before resuming.  
To be able to resume after suspending the computer to disk (hibernate), it is required to keep the swap filesystem intact. Therefore, it is required to have a pre-existent LUKS swap partition, which can be stored on the disk or input manually at startup. Because the resume takes place before {{ic|/etc/crypttab}} can be used, it is required to create a hook in {{ic|/etc/mkinitcpio.conf}} to open the swap LUKS device before resuming.
+
  
 
If you want to use a partition which is currently used by the system, you have to disable it first:
 
If you want to use a partition which is currently used by the system, you have to disable it first:
Line 23: Line 87:
 
The following setup has the disadvantage of having to insert an additional passphrase for the swap partition manually on every boot.
 
The following setup has the disadvantage of having to insert an additional passphrase for the swap partition manually on every boot.
  
{{Warning|Do not use this setup with a key file. Please read about the issue reported [[Talk:System Encryption with LUKS for dm-crypt#Suspend to disk instructions are insecure|here]]}}
+
{{Warning|1=Do not use this setup with a key file if {{ic|/boot}} is unencrypted. Please read about the issue reported [https://wiki.archlinux.org/index.php?title=Talk:Dm-crypt&oldid=255742#Suspend_to_disk_instructions_are_insecure here]. Alternatively, use a gnupg-encrypted keyfile as per https://bbs.archlinux.org/viewtopic.php?id=120181}}
  
To format the encrypted container for the swap partition, follow steps similar to those described in [[#Configuring LUKS]] above and create keyslot for a user-memorizable passphrase.
+
To format the encrypted container for the swap partition, create a keyslot for a user-memorizable passphrase.
  
 
Open the partition in {{ic|/dev/mapper}}:
 
Open the partition in {{ic|/dev/mapper}}:
Line 33: Line 97:
 
  # mkswap /dev/mapper/swapDevice
 
  # mkswap /dev/mapper/swapDevice
  
Now you have to create a hook to open the swap at boot time.
+
Now you have to create a hook to open the swap at boot time. You can either [[install]] and configure {{AUR|mkinitcpio-openswap}}, or follow the following instructions. Create a hook file containing the open command:
 
+
* Create a hook file containing the open command:
+
  
 
{{hc|/lib/initcpio/hooks/openswap|<nowiki>
 
{{hc|/lib/initcpio/hooks/openswap|<nowiki>
# vim: set ft=sh:
 
 
  run_hook ()
 
  run_hook ()
 
  {
 
  {
Line 48: Line 109:
  
 
{{hc|/lib/initcpio/hooks/openswap|<nowiki>
 
{{hc|/lib/initcpio/hooks/openswap|<nowiki>
# vim: set ft=sh:
 
 
  run_hook ()
 
  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
 
     mkdir crypto_key_device
 
     mount /dev/mapper/<root-device> crypto_key_device
 
     mount /dev/mapper/<root-device> crypto_key_device
Line 58: Line 126:
 
</nowiki>}}
 
</nowiki>}}
  
for opening the swap device by loading a keyfile from a crypted root device
+
for opening the swap device by loading a keyfile from a crypted root device.
  
{{Note|If swap is on a Solid State Disk (SSD) and Discard/TRIM is desired the option {{ic|--allow-discards}} has to get added to the cryptsetup line in the openswap hook above. See [[#Discard.2FTRIM_support_for_solid_state_disks_.28SSD.29|Discard/TRIM support for solid state disks (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.''}}
+
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.
  
* Then create and edit the hook setup file:
+
{{Note|If swap is on a Solid State Disk (SSD) and Discard/TRIM is desired the option {{ic|--allow-discards}} has to get added to the cryptsetup line in the openswap hook above. See [[dm-crypt/Specialties#Discard.2FTRIM_support_for_solid_state_disks_.28SSD.29|Discard/TRIM support for solid state disks (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:
 
{{hc|/lib/initcpio/install/openswap|<nowiki>
 
{{hc|/lib/initcpio/install/openswap|<nowiki>
# vim: set ft=sh:
 
 
build ()
 
build ()
 
{
 
{
Line 77: Line 146:
 
</nowiki>}}
 
</nowiki>}}
  
* Add the hook {{ic|openswap}} in the {{ic|HOOKS}} array in {{ic|/etc/mkinitcpio.conf}}, before {{ic|filesystem}} but after {{ic|encrypt}}. Do not forget to add the {{ic|resume}} hook after {{ic|openswap}}.
+
Add the hook {{ic|openswap}} in the {{ic|HOOKS}} array in {{ic|/etc/mkinitcpio.conf}}, before {{ic|filesystem}} but after {{ic|encrypt}}. Do not forget to add the {{ic|resume}} hook after {{ic|openswap}}.
 
  <nowiki>HOOKS="... encrypt openswap resume filesystems ..."</nowiki>
 
  <nowiki>HOOKS="... encrypt openswap resume filesystems ..."</nowiki>
* Regenerate the boot image:
+
 
 +
Regenerate the boot image:
  
 
  # mkinitcpio -p linux
 
  # mkinitcpio -p linux
  
* Add the mapped partition to {{ic|/etc/fstab}} by adding the following line:
+
Add the mapped partition to {{ic|/etc/fstab}} by adding the following line:
 
  /dev/mapper/swapDevice swap swap defaults 0 0
 
  /dev/mapper/swapDevice swap swap defaults 0 0
  
* Set up your system to resume from {{ic|/dev/mapper/swapDevice}}. For example, if you use [[GRUB]] with kernel hibernation support, add {{ic|resume<nowiki>=</nowiki>/dev/mapper/swapDevice}} to the kernel line in {{ic|/boot/grub/grub.cfg}}. A line with encrypted root and swap partitions can look like this:
+
Set up your system to resume from {{ic|/dev/mapper/swapDevice}}. For example, if you use [[GRUB]] with kernel hibernation support, add {{ic|resume<nowiki>=</nowiki>/dev/mapper/swapDevice}} to the kernel line in {{ic|/boot/grub/grub.cfg}}. A line with encrypted root and swap partitions can look like this:
  
 
  kernel /vmlinuz-linux cryptdevice=/dev/sda2:rootDevice root=/dev/mapper/rootDevice resume=/dev/mapper/swapDevice ro
 
  kernel /vmlinuz-linux cryptdevice=/dev/sda2:rootDevice root=/dev/mapper/rootDevice resume=/dev/mapper/swapDevice ro
Line 95: Line 165:
  
 
=== Using a swap file ===
 
=== 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. When resuming from a swapfile the {{ic|resume}} hook must be supplied with the passphrase to unlock the device where the swap file is located. To create it: 
 
* Choose a mapped partition (e.g. {{ic|/dev/mapper/rootDevice}}) whose mounted filesystem (e.g. {{ic|/}}) contains enough free space to create a swapfile with the desired size.
 
  
* [[HOW_TO:_Create_swap_file#Swap_file_creation | Create the swap file]] (e.g. {{ic|/swapfile}}) inside the mounted filesystem of your chosen mapped partition.  Be sure to activate it with {{ic|swapon}} and also add it to your {{ic|/etc/fstab}} file afterward. Note that the swapfile's previous contents remain transparent over reboots.  
+
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. When resuming from a swapfile the {{ic|resume}} hook must be supplied with the passphrase to unlock the device where the swap file is located.
  
* Set up your system to resume from your chosen mapped partition. For example, if you use [[GRUB]] with kernel hibernation support, add {{ic|resume<nowiki>=</nowiki>}}''your chosen mapped partition'' and {{ic|resume_offset<nowiki>=</nowiki>}}''see calculation command below'' to the kernel line in {{ic|/boot/grub/grub.cfg}}. A line with encrypted root partition can look like this:
+
{{Warning|[[Dm-crypt/Drive_preparation#Btrfs_subvolumes|Btrfs]] does not support swap files. Failure to heed this warning may result in file system corruption. While a swap file may be used on [[Btrfs#Swap_file|Btrfs]] when mounted through a loop device, this will result in severely degraded swap performance.}}
 +
 
 +
To create it, first choose a mapped partition (e.g. {{ic|/dev/mapper/rootDevice}}) whose mounted filesystem (e.g. {{ic|/}}) contains enough free space to create a swapfile with the desired size.
 +
 
 +
Now [[Swap#Swap file creation|create the swap file]] (e.g. {{ic|/swapfile}}) inside the mounted filesystem of your chosen mapped partition.  Be sure to activate it with {{ic|swapon}} and also add it to your {{ic|/etc/fstab}} file afterward. Note that the swapfile's previous contents remain transparent over reboots.
 +
 
 +
Set up your system to resume from your chosen mapped partition. For example, if you use [[GRUB]] with kernel hibernation support, add {{ic|resume<nowiki>=</nowiki>}}''your chosen mapped partition'' and {{ic|resume_offset<nowiki>=</nowiki>}}''see calculation command below'' to the kernel line in {{ic|/boot/grub/grub.cfg}}. A line with encrypted root partition can look like this:
  
 
  kernel /vmlinuz-linux cryptdevice=/dev/sda2:rootDevice root=/dev/mapper/rootDevice resume=/dev/mapper/rootDevice resume_offset=123456789 ro
 
  kernel /vmlinuz-linux cryptdevice=/dev/sda2:rootDevice root=/dev/mapper/rootDevice resume=/dev/mapper/rootDevice resume_offset=123456789 ro
Line 106: Line 180:
 
The {{ic|resume_offset}} of the swap-file points to the start (extent zero) of the file and can be identified like this:
 
The {{ic|resume_offset}} of the swap-file points to the start (extent zero) of the file and can be identified like this:
  
  # filefrag -v /swapfile | awk '{if($1==0){print $3}}'
+
  # filefrag -v /swapfile | awk '{if($1=="0:"){print $4}}'
  
* Add the {{ic|resume}} hook to your {{ic|etc/mkinitcpio.conf}} file and [[Mkinitcpio#Image_creation_and_activation|rebuild the image]] afterward:
+
Add the {{ic|resume}} hook to your {{ic|etc/mkinitcpio.conf}} file and [[Mkinitcpio#Image_creation_and_activation|rebuild the image]] afterward:
  
 
  HOOKS="... encrypt '''resume''' ... filesystems ..."
 
  HOOKS="... encrypt '''resume''' ... filesystems ..."
  
* If you use a USB keyboard to enter your decryption password, then the {{ic|keyboard}} module '''must''' appear in front of the {{ic|encrypt}} hook, as shown below.  Otherwise, you will not be able to boot your computer because you couldn't enter your decryption password to decrypt your Linux root partition! (If you still have this problem after adding {{ic|keyboard}}, try {{ic|usbinput}}, though this is deprecated.)
+
If you use a USB keyboard to enter your decryption password, then the {{ic|keyboard}} module '''must''' appear in front of the {{ic|encrypt}} hook, as shown below.  Otherwise, you will not be able to boot your computer because you could not enter your decryption password to decrypt your Linux root partition! (If you still have this problem after adding {{ic|keyboard}}, try {{ic|usbinput}}, though this is deprecated.)
  
 
  HOOKS="... '''keyboard''' encrypt ..."
 
  HOOKS="... '''keyboard''' encrypt ..."
 
== Without suspend-to-disk support ==
 
 
In systems where suspend to disk is not a desired feature, it is possible to create a swap file that will have a random master key with each boot. This is accomplished by using dm-crypt directly without LUKS extensions.
 
 
The {{ic|/etc/crypttab}} is well commented and you can basically just uncomment the swap line and change <device> to a persistent symlink.
 
 
{{hc|/etc/crypttab|# <name>      <device>        <password>              <options>
 
# swap        /dev/hdx4        /dev/urandom            <nowiki>swap,cipher=aes-cbc-essiv:sha256,size=256</nowiki>}}
 
 
Where:
 
; <name>: Represents the name ({{ic|/dev/mapper/<name>}}) to list in /etc/fstab.
 
; <device>: Should be the symlink to the actual partition's device file.
 
; <password>: {{ic|/dev/urandom}} sets the dm-crypt master key to be randomized on every volume recreation.
 
; <options>: The {{ic|swap}} option runs mkswap after cryptographic's are setup.
 
 
{{Warning|You should use persistent block device naming (in example ID's) for <device> because if there are multiple hard drives installed in the system, their naming order (sda, sdb,...) can occasionally be scrambled upon boot and thus the swap would be created over a valuable file system, destroying its content.}}
 
 
Persistent block device naming is implemented with simple symlinks. Using UUID's or filesystem-labels is not possible as plain dm-crypt writes only encrypted data without a persistent header like LUKS. If you are not familar with one of the directories under {{ic|/dev/disk/}} read on in the section on [[#Preparation for Persistent block device naming]]
 
 
{{hc|#ls -l <nowiki>/dev/disk/*/* |</nowiki> grep sda2|
 
lrwxrwxrwx 1 root root 10 Oct 12 16:54 /dev/disk/by-id/ata-WDC_WD2500BEVT-22ZCT0_WD-WXE908VF0470-part2 -> ../../sda2}}
 
 
Example line for the {{ic|/dev/sda2}} symlink from above:
 
 
{{hc|/etc/crypttab|# <name>                      <device>                                  <password>    <options>
 
  swap  /dev/disk/by-id/ata-WDC_WD2500BEVT-22ZCT0_WD-WXE908VF0470-part2  /dev/urandom  <nowiki>swap,cipher=aes-cbc-essiv:sha256,size=256</nowiki>}}
 
 
This will map {{ic|/dev/sda2}} to {{ic|/dev/mapper/swap}} as a swap partition that can be added in {{ic|/etc/fstab}} like a normal swap.
 
 
If the partition chosen for swap was previously a LUKS partition, crypttab will not overwrite the partition to create a swap partition. This is a safety measure to prevent data loss from accidental mis-identification of the swap partition in crypttab. In order to use such a partition the [[#Wipe_LUKS_header|LUKS header must be overwritten]] once.
 

Latest revision as of 06:48, 16 April 2016

Back to Dm-crypt.

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 (i.e.., 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-cbc-essiv:sha256,size=256

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 see and an explanation of each column, see man 5 crypttab as well as point cryptsetup FAQ 2.3.

Warning: All contents of the named device will be permanently deleted. It is dangerous to use the kernel's simple naming for a swap device, since their naming order (e.g. /dev/sda, /dev/sdb) changes upon each boot. Options are:

To use a by-id persistent device naming instead of kernel simple naming, first identify the swap device:

# ls -l /dev/disk/*/* | grep sdaX
lrwxrwxrwx 1 root root 10 Oct 12 16:54 /dev/disk/by-id/ata-WDC_WD2500BEVT-22ZCT0_WD-WXE908VF0470-partX -> ../../sdaX
lrwxrwxrwx 1 root root 10 Oct 12 16:54 /dev/disk/by-id/wwn-0x60015ee0000b237f-partX -> ../../sdaX

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-cbc-essiv:sha256,size=256

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.

Note: If the partition chosen for swap was previously a LUKS partition, crypttab will not overwrite the partition to create a swap partition. This is a safety measure to prevent data loss from accidental mis-identification of the swap partition in crypttab. In order to use such a partition the LUKS header must be overwritten once.

UUID and LABEL

As stated above, it is very dangerous to use crypttab swap with the kernel's simple naming or even with the device's ID, since these can easily change and the contents of the swap partition are deleted on every boot. To get around the changing of UUID's and label's of the swap partition on every boot, one can label a partition preceding the swap partition on the disk, and the swap partition can use the offset option to indicate its location. The preceding partition's label and UUID will not change upon every boot.

In this example, a smaller partition is created explicitly for this purpose, although any existing partition preceding the swap partition can be used. To do this, first create a smaller filesystem with the label of your choice:

# mkfs.ext2 -L mylabel /dev/sdX# 1M

where the # is the partition number that will be before the swap partition, and mylabel is the label you want to give the partition. The 1M indicates a size of 1 MiB for this smaller partition.

Now, in /etc/crypttab, change <device> to either the label of UUID of the preceding partition. Additionally add the offset option. In this example, the swap partition is offset from the beginning of the smaller partition by 2048 sectors (1 MiB) and the label is used:

/etc/crypttab
# <name> <device>       <password>    <options>
swap     LABEL=mylabel  /dev/urandom  swap,offset=2048,cipher=aes-cbc-essiv:sha256,size=256
Warning: An incorrect label or offset option in crypttab can cause irrevocable data loss.

With suspend-to-disk support

To be able to resume after suspending the computer to disk (hibernate), it is required to keep the swap space intact. Therefore, it is required to have a pre-existent LUKS swap partition, which can be stored on the disk or input manually at startup.

The following three methods are alternatives for setting up an encrypted swap for resume-from-disk. 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

A simple way to realize encrypted swap with suspend-to-disk support is by using a swap LVM device on the same encryption layer as the root volume, so that both are opened by the encrypt hook at boot. Follow the instructions on Dm-crypt/Encrypting an entire system#LVM on LUKS and then just configure the required kernel parameters.

Assuming you have setup LVM on LUKS with a swap logical volume (at /dev/MyStorage/swap for example), all you need to do is add the resume mkinitcpio hook, and add the resume=/dev/MyStorage/swap kernel parameter to your boot loader. For GRUB, this can be done by appending it to the GRUB_CMDLINE_LINUX_DEFAULT variable in /etc/default/grub.

/etc/default/grub
GRUB_CMDLINE_LINUX_DEFAULT="... resume=/dev/MyStorage/swap"

then run grub-mkconfig -o /boot/grub/grub.cfg to update GRUB's configuration file. To add the mkinitcpio hook, edit the following line in mkinitcpio.conf

/etc/mkinitcpio.conf
HOOKS="... encrypt lvm2 resume ... filesystems ..."

then run mkinitcpio -p linux to update the initramfs image.

mkinitcpio hook

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.

If you want to use a partition which is currently used by the system, you have to disable it first:

# swapoff /dev/<device>

Also make sure you remove any line in /etc/crypttab pointing to this device.

The following setup has the disadvantage of having to insert an additional passphrase for the swap partition manually on every boot.

Warning: Do not use this setup with a key file if /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

To format the encrypted container for the swap partition, create a keyslot for a user-memorizable passphrase.

Open the partition in /dev/mapper:

# cryptsetup open --type luks /dev/<device> swapDevice

Create a swap filesystem inside the mapped partition:

# mkswap /dev/mapper/swapDevice

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:

/lib/initcpio/hooks/openswap
 run_hook ()
 {
     cryptsetup open --type luks /dev/<device> swapDevice
 }

for opening the swap device by typing your password or

/lib/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 --type luks --key-file crypto_key_device/<path-to-the-key> /dev/<device> swapDevice
     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.

Note: If swap is on a Solid State Disk (SSD) and Discard/TRIM is desired the option --allow-discards has to get added to the cryptsetup line in the openswap hook above. See Discard/TRIM support for solid state disks (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:

/lib/initcpio/install/openswap
build ()
{
   add_runscript
}
help ()
{
cat<<HELPEOF
  This opens the swap encrypted partition /dev/<device> in /dev/mapper/swapDevice
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 ..."

Regenerate the boot image:

# mkinitcpio -p linux

Add the mapped partition to /etc/fstab by adding the following line:

/dev/mapper/swapDevice swap swap defaults 0 0

Set up your system to resume from /dev/mapper/swapDevice. For example, if you use GRUB with kernel hibernation support, add resume=/dev/mapper/swapDevice to the kernel line in /boot/grub/grub.cfg. A line with encrypted root and swap partitions can look like this:

kernel /vmlinuz-linux cryptdevice=/dev/sda2:rootDevice root=/dev/mapper/rootDevice resume=/dev/mapper/swapDevice ro

To make the parameter persistent on kernel updates, add it to /etc/default/grub.

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 swapDevice in /etc/crypttab needed in this case.

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. When resuming from a swapfile the resume hook must be supplied with the passphrase to unlock the device where the swap file is located.

Warning: Btrfs does not support swap files. Failure to heed this warning may result in file system corruption. While a swap file may be used on Btrfs when mounted through a loop device, this will result in severely degraded swap performance.

To create it, first choose a mapped partition (e.g. /dev/mapper/rootDevice) whose mounted filesystem (e.g. /) contains enough free space to create a swapfile with the desired size.

Now create the swap file (e.g. /swapfile) inside the mounted filesystem of your chosen mapped partition. Be sure to activate it with swapon and also add it to your /etc/fstab file afterward. Note that the swapfile's previous contents remain transparent over reboots.

Set up your system to resume from your chosen mapped partition. For example, if you use GRUB with kernel hibernation support, add resume=your chosen mapped partition and resume_offset=see calculation command below to the kernel line in /boot/grub/grub.cfg. A line with encrypted root partition can look like this:

kernel /vmlinuz-linux cryptdevice=/dev/sda2:rootDevice root=/dev/mapper/rootDevice resume=/dev/mapper/rootDevice resume_offset=123456789 ro

The resume_offset of the swap-file points to the start (extent zero) of the file and can be identified like this:

# filefrag -v /swapfile | awk '{if($1=="0:"){print $4}}'

Add the resume hook to your etc/mkinitcpio.conf file and rebuild the image afterward:

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

If you use a USB keyboard to enter your decryption password, then the keyboard module must appear in front of the encrypt hook, as shown below. Otherwise, you will not be able to boot your computer because you could not enter your decryption password to decrypt your Linux root partition! (If you still have this problem after adding keyboard, try usbinput, though this is deprecated.)

HOOKS="... keyboard encrypt ..."