Difference between revisions of "Dm-crypt/Specialties"

From ArchWiki
Jump to navigation Jump to search
m (→‎Securing the unencrypted boot partition: fixed link syntax (I hope))
(update interlanguage links)
Tag: wiki-scripts
 
(174 intermediate revisions by 33 users not shown)
Line 1: Line 1:
 
{{Lowercase title}}
 
{{Lowercase title}}
[[Category:Encryption]]
+
[[Category:Disk encryption]]
[[Category:File systems]]
+
[[es:Dm-crypt (Español)/Specialties]]
 
[[ja:Dm-crypt/特記事項]]
 
[[ja:Dm-crypt/特記事項]]
Back to [[Dm-crypt]].
+
[[pl:Dm-crypt/Specialties]]
 +
== Securing the unencrypted boot partition ==
  
==Securing the unencrypted boot partition==
+
The {{ic|/boot}} partition and the [[Master Boot Record]] are the two areas of the disk that are not encrypted, even in an [[dm-crypt/Encrypting an entire system|encrypted root]] configuration. They cannot usually be encrypted because the [[boot loader]] and BIOS (respectively) are unable to unlock a dm-crypt container in order to continue the boot process. An exception is [[GRUB]], which gained a feature to unlock a LUKS encrypted {{ic|/boot}} - see [[dm-crypt/Encrypting an entire system#Encrypted boot partition (GRUB)]].  
The {{ic|/boot}} partition and the [[Master Boot Record]] are the two areas of the disk that are not encrypted, even in an [[Dm-crypt/Encrypting_an_entire_system|encrypted root]] configuration. They cannot usually be encrypted because the [[boot loader]] and BIOS (respectively) are unable to unlock a dm-crypt container in order to continue the boot process. An exception is [[GRUB]], which gained a feature to unlock a LUKS encrypted {{ic|/boot}} - see [[GRUB#Boot partition]].  
 
  
 
This section describes steps that can be taken to make the boot process more secure.  
 
This section describes steps that can be taken to make the boot process more secure.  
Line 12: Line 12:
 
{{Warning|Note that securing the {{ic|/boot}} partition and MBR can mitigate numerous attacks that occur during the boot process, but systems configured this way may still be vulnerable to BIOS/UEFI/firmware tampering, hardware keyloggers, cold boot attacks, and many other threats that are beyond the scope of this article. For an overview of system-trust issues and how these relate to full-disk encryption, refer to [http://www.youtube.com/watch?v=pKeiKYA03eE].}}
 
{{Warning|Note that securing the {{ic|/boot}} partition and MBR can mitigate numerous attacks that occur during the boot process, but systems configured this way may still be vulnerable to BIOS/UEFI/firmware tampering, hardware keyloggers, cold boot attacks, and many other threats that are beyond the scope of this article. For an overview of system-trust issues and how these relate to full-disk encryption, refer to [http://www.youtube.com/watch?v=pKeiKYA03eE].}}
  
===Booting from a removable device===
+
=== Booting from a removable device ===
  
 +
{{Warning|systemd version 230 cryptsetup generator emits {{ic|RequiresMountsFor}} for crypto keyfile. Therefore, when the filesystem that holds this file is unmounted, it also stops cryptsetup service. This behavior is incorrect because the filesystem and cryptokey is required only once, when the crypto container is initially setup. See [https://github.com/systemd/systemd/issues/3816 systemd issue 3816].}}
  
{{warning|systemd version 230 cryptsetup generator emits RequiresMountsFor for crypto keyfile. Therefore, when the filesystem that holds this file is unmounted, it also stops cryptsetup service. This behavior is incorrect because the filesystem and cryptokey is required only once, when the crypto container is initially setup. See issue 3816 [https://github.com/systemd/systemd/issues/3816]}}
+
Using a separate device to boot a system is a fairly straightforward procedure, and offers a significant security improvement against some kinds of attacks. Two vulnerable parts of a system employing an [[Dm-crypt/Encrypting_an_entire_system|encrypted root filesystem]] are
  
Using a separate device to boot a system is a fairly straightforward procedure, and offers a significant security improvement against some kinds of attacks. Two vulnerable parts of a system employing an [[Dm-crypt/Encrypting_an_entire_system|encrypted root filesystem]] are
 
 
* the [[Master Boot Record]], and
 
* the [[Master Boot Record]], and
 
* the {{ic|/boot}} partition.
 
* the {{ic|/boot}} partition.
 +
 
These must be stored unencrypted in order for the system to boot. In order to protect these from tampering, it is advisable to store them on a removable medium, such as a USB drive, and boot from that drive instead of the hard disk. As long as you keep the drive with you at all times, you can be certain that those components have not been tampered with, making authentication far more secure when unlocking your system.
 
These must be stored unencrypted in order for the system to boot. In order to protect these from tampering, it is advisable to store them on a removable medium, such as a USB drive, and boot from that drive instead of the hard disk. As long as you keep the drive with you at all times, you can be certain that those components have not been tampered with, making authentication far more secure when unlocking your system.
  
 
It is assumed that you already have your system configured with a dedicated partition mounted at {{ic|/boot}}. If you do not, please follow the steps in [[dm-crypt/System configuration#Boot loader]], substituting your hard disk for a removable drive.
 
It is assumed that you already have your system configured with a dedicated partition mounted at {{ic|/boot}}. If you do not, please follow the steps in [[dm-crypt/System configuration#Boot loader]], substituting your hard disk for a removable drive.
 +
 
{{Note|You must make sure your system supports booting from the chosen medium, be it a USB drive, an external hard drive, an SD card, or anything else.}}
 
{{Note|You must make sure your system supports booting from the chosen medium, be it a USB drive, an external hard drive, an SD card, or anything else.}}
 +
 
Prepare the removable drive ({{ic|/dev/sdx}}).
 
Prepare the removable drive ({{ic|/dev/sdx}}).
 +
 
  # gdisk /dev/sdx #format if necessary. Alternatively, cgdisk, fdisk, cfdisk, gparted...
 
  # gdisk /dev/sdx #format if necessary. Alternatively, cgdisk, fdisk, cfdisk, gparted...
 
  # mkfs.ext2 /dev/sdx1
 
  # mkfs.ext2 /dev/sdx1
 
  # mount /dev/sdx1 /mnt
 
  # mount /dev/sdx1 /mnt
 +
 
Copy your existing {{ic|/boot}} contents to the new one.
 
Copy your existing {{ic|/boot}} contents to the new one.
  # cp -R -i -d /boot/* /mnt
+
 
 +
  # cp -ai /boot/* /mnt/
 +
 
 
Mount the new partition. Do not forget to update your [[fstab]] file accordingly.
 
Mount the new partition. Do not forget to update your [[fstab]] file accordingly.
 +
 
  # umount /boot
 
  # umount /boot
 
  # umount /mnt
 
  # umount /mnt
 
  # mount /dev/sdx1 /boot
 
  # mount /dev/sdx1 /boot
 
  # genfstab -p -U / > /etc/fstab
 
  # genfstab -p -U / > /etc/fstab
 +
 
Update [[GRUB]]. {{ic|grub-mkconfig}} should detect the new partition UUID automatically, but custom menu entries may need to be updated manually.
 
Update [[GRUB]]. {{ic|grub-mkconfig}} should detect the new partition UUID automatically, but custom menu entries may need to be updated manually.
 +
 
  # grub-mkconfig -o /boot/grub/grub.cfg
 
  # grub-mkconfig -o /boot/grub/grub.cfg
 
  # grub-install /dev/sdx #install to the removable device, not the hard disk.
 
  # grub-install /dev/sdx #install to the removable device, not the hard disk.
Reboot and test the new configuration. Remember to set your device boot order accordingly in your [[BIOS]] or [[UEFI]]. If the system fails to boot, you should still be able to boot from the hard drive in order to correct the problem.
 
  
===chkboot===
+
Reboot and test the new configuration. Remember to set your device boot order accordingly in your BIOS or [[UEFI]]. If the system fails to boot, you should still be able to boot from the hard drive in order to correct the problem.
{{warning|chkboot makes a {{ic|/boot}} partition '''tamper-evident''', not '''tamper-proof'''. By the time the chkboot script is run, you have already typed your password into a potentially compromised boot loader, kernel, or initrd. If your system fails the chkboot integrity test, no assumptions can be made about the security of your data.}}
+
 
 +
=== chkboot ===
 +
 
 +
{{Warning|chkboot makes a {{ic|/boot}} partition '''tamper-evident''', not '''tamper-proof'''. By the time the chkboot script is run, you have already typed your password into a potentially compromised boot loader, kernel, or initrd. If your system fails the chkboot integrity test, no assumptions can be made about the security of your data.}}
 +
 
 
Referring to an article from the ct-magazine (Issue 3/12, page 146, 01.16.2012, [http://www.heise.de/ct/inhalt/2012/03/6/]) the following script checks files under {{ic|/boot}} for changes of SHA-1 hash, inode, and occupied blocks on the hard drive. It also checks the [[Master Boot Record]]. The script cannot prevent certain type of attacks, but a lot are made harder. No configuration of the script itself is stored in unencrypted {{ic|/boot}}. With a locked/powered-off encrypted system, this makes it harder for some attackers because it is not apparent that an automatic checksum comparison of the partition is done upon boot. However, an attacker who anticipates these precautions can manipulate the firmware to run his own code on top of your kernel and intercept file system access, e.g. to {{ic|boot}}, and present the untampered files. Generally, no security measures below the level of the firmware are able to guarantee trust and tamper evidence.
 
Referring to an article from the ct-magazine (Issue 3/12, page 146, 01.16.2012, [http://www.heise.de/ct/inhalt/2012/03/6/]) the following script checks files under {{ic|/boot}} for changes of SHA-1 hash, inode, and occupied blocks on the hard drive. It also checks the [[Master Boot Record]]. The script cannot prevent certain type of attacks, but a lot are made harder. No configuration of the script itself is stored in unencrypted {{ic|/boot}}. With a locked/powered-off encrypted system, this makes it harder for some attackers because it is not apparent that an automatic checksum comparison of the partition is done upon boot. However, an attacker who anticipates these precautions can manipulate the firmware to run his own code on top of your kernel and intercept file system access, e.g. to {{ic|boot}}, and present the untampered files. Generally, no security measures below the level of the firmware are able to guarantee trust and tamper evidence.
  
Line 47: Line 60:
  
 
After installation add a service file (the package includes one based on the following) and [[enable]] it:  
 
After installation add a service file (the package includes one based on the following) and [[enable]] it:  
 +
 
  [Unit]
 
  [Unit]
 
  Description=Check that boot is what we want
 
  Description=Check that boot is what we want
Line 72: Line 86:
 
  sudo -u <user> /usr/local/bin/chkboot_user.sh # insert your logged on <user>  
 
  sudo -u <user> /usr/local/bin/chkboot_user.sh # insert your logged on <user>  
 
  /usr/local/bin/chkboot.sh
 
  /usr/local/bin/chkboot.sh
sync # sync disks with any results
 
 
  sudo -u <user> /usr/local/bin/chkboot_user.sh # insert your logged on <user>  
 
  sudo -u <user> /usr/local/bin/chkboot_user.sh # insert your logged on <user>  
 
  echo "Pacman update [2] Syncing repos for pacman"  
 
  echo "Pacman update [2] Syncing repos for pacman"  
 
  pacman -Syu
 
  pacman -Syu
 
  /usr/local/bin/chkboot.sh
 
  /usr/local/bin/chkboot.sh
sync
 
 
  sudo -u <user> /usr/local/bin/chkboot_user.sh # insert your logged on <user>
 
  sudo -u <user> /usr/local/bin/chkboot_user.sh # insert your logged on <user>
 
  echo "Pacman update [3] All done, let us roll on ..."
 
  echo "Pacman update [3] All done, let us roll on ..."
  
 
=== mkinitcpio-chkcryptoboot ===
 
=== mkinitcpio-chkcryptoboot ===
 +
 
{{Warning|This hook does '''not''' encrypt [[GRUB]]'s core (MBR) code or EFI stub, nor does it protect against situations where an attacker is able to modify the behaviour of the bootloader to compromise the kernel and/or initramfs at run-time.}}
 
{{Warning|This hook does '''not''' encrypt [[GRUB]]'s core (MBR) code or EFI stub, nor does it protect against situations where an attacker is able to modify the behaviour of the bootloader to compromise the kernel and/or initramfs at run-time.}}
{{aur|mkinitcpio-chkcryptoboot}} is a [[mkinitcpio]] hook that performs integrity checks during early-userspace and advises the user not to enter his root partition password if the system appears to have been compromised. Security is achieved through an [[Dm-crypt/Encrypting_an_entire_system#Encrypted_boot_partition_.28GRUB.29|encrypted boot partition]], which is unlocked using [[GRUB#Boot_partition|GRUB]]'s {{ic|cryptodisk.mod}} module, and a root filesystem partition, which is encrypted with a password different from the former. This way, the [[initramfs]] and [[kernel]] are secured against offline tampering, and the root partition can remain secure even if the {{ic|/boot}} partition password is entered on a compromised machine (provided that the chkcryptoboot hook detects the compromise, and is not itself compromised at run-time).  
+
 
 +
{{aur|mkinitcpio-chkcryptoboot}} is a [[mkinitcpio]] hook that performs integrity checks during early-userspace and advises the user not to enter his root partition password if the system appears to have been compromised. Security is achieved through an [[dm-crypt/Encrypting an entire system#Encrypted boot partition (GRUB)|encrypted boot partition]], which is unlocked using [[GRUB#Encrypted /boot|GRUB]]'s {{ic|cryptodisk.mod}} module, and a root filesystem partition, which is encrypted with a password different from the former. This way, the [[initramfs]] and [[kernel]] are secured against offline tampering, and the root partition can remain secure even if the {{ic|/boot}} partition password is entered on a compromised machine (provided that the chkcryptoboot hook detects the compromise, and is not itself compromised at run-time).  
  
 
This hook requires {{Pkg|grub}} release >=2.00 to function, and a dedicated, LUKS encrypted {{ic|/boot}} partition with its own password in order to be secure.
 
This hook requires {{Pkg|grub}} release >=2.00 to function, and a dedicated, LUKS encrypted {{ic|/boot}} partition with its own password in order to be secure.
  
 
==== Installation ====
 
==== Installation ====
[[Install]] {{aur|mkinitcpio-chkcryptoboot}} and edit {{ic|/etc/default/chkcryptoboot.conf}}. If you want the ability of detecting if your boot partition was bypassed, edit the {{ic|CMDLINE_NAME}} and {{ic|CMDLINE_VALUE}} variables, with values known only to you. You can follow the advice of using two hashes as is suggested right after the installation. Also, be sure to make the appropriate changes to the [[Kernel parameters|kernel command line]] in {{ic|/etc/default/grub}}. Edit the {{ic|1=HOOKS=}} line in {{ic|/etc/mkinitcpio.conf}}, and insert the {{ic|chkcryptoboot}} hook '''before''' {{ic|encrypt}}. When finished, [[Mkinitcpio#Image_creation_and_activation|rebuild]] the initramfs.
+
 
 +
[[Install]] {{aur|mkinitcpio-chkcryptoboot}} and edit {{ic|/etc/default/chkcryptoboot.conf}}. If you want the ability of detecting if your boot partition was bypassed, edit the {{ic|CMDLINE_NAME}} and {{ic|CMDLINE_VALUE}} variables, with values known only to you. You can follow the advice of using two hashes as is suggested right after the installation. Also, be sure to make the appropriate changes to the [[kernel command line]] in {{ic|/etc/default/grub}}. Edit the {{ic|1=HOOKS=}} line in {{ic|/etc/mkinitcpio.conf}}, and insert the {{ic|chkcryptoboot}} hook '''before''' {{ic|encrypt}}. When finished, [[regenerate the initramfs]].
  
 
==== Technical Overview ====
 
==== Technical Overview ====
{{aur|mkinitcpio-chkcryptoboot}} consists of an install hook and a run-time hook for mkinitcpio. The install hook runs every time the initramfs is rebuilt, and hashes the GRUB [[UEFI|EFI]] stub ({{ic|$esp/EFI/grub_uefi/grubx64.efi}}) (in the case of [[UEFI]] systems) or the first 446 bytes of the disk on which GRUB is installed (in the case of BIOS systems), and stores that hash inside the initramfs located inside the encrypted {{ic|/boot}} partition. When the system is booted, GRUB prompts for the {{ic|/boot}} password, then the run-time hook performs the same hashing operation and compares the resulting hashes before prompting for the root partition password. If they do not match, the hook will print an error like this:
+
 
{{bc|CHKCRYPTOBOOT ALERT!
+
{{aur|mkinitcpio-chkcryptoboot}} consists of an install hook and a run-time hook for mkinitcpio. The install hook runs every time the initramfs is rebuilt, and hashes the GRUB [[EFI]] stub ({{ic|$esp/EFI/grub_uefi/grubx64.efi}}) (in the case of [[UEFI]] systems) or the first 446 bytes of the disk on which GRUB is installed (in the case of BIOS systems), and stores that hash inside the initramfs located inside the encrypted {{ic|/boot}} partition. When the system is booted, GRUB prompts for the {{ic|/boot}} password, then the run-time hook performs the same hashing operation and compares the resulting hashes before prompting for the root partition password. If they do not match, the hook will print an error like this:
CHANGES HAVE BEEN DETECTED IN YOUR BOOT LOADER EFISTUB!
+
 
YOU ARE STRONGLY ADVISED NOT TO ENTER YOUR ROOT CONTAINER PASSWORD!
+
CHKCRYPTOBOOT ALERT!
Please type uppercase yes to continue:
+
CHANGES HAVE BEEN DETECTED IN YOUR BOOT LOADER EFISTUB!
}}
+
YOU ARE STRONGLY ADVISED NOT TO ENTER YOUR ROOT CONTAINER PASSWORD!
 +
Please type uppercase yes to continue:
  
 
In addition to hashing the boot loader, the hook also checks the parameters of the running kernel against those configured in {{ic|/etc/default/chkcryptoboot.conf}}. This is checked both at run-time and after the boot process is done. This allows the hook to detect if GRUB's configuration was not bypassed at run-time and afterwards to detect if the entire {{ic|/boot}} partition was not bypassed.
 
In addition to hashing the boot loader, the hook also checks the parameters of the running kernel against those configured in {{ic|/etc/default/chkcryptoboot.conf}}. This is checked both at run-time and after the boot process is done. This allows the hook to detect if GRUB's configuration was not bypassed at run-time and afterwards to detect if the entire {{ic|/boot}} partition was not bypassed.
Line 102: Line 118:
 
For BIOS systems the hook creates a hash of GRUB's first stage bootloader (installed to the first 446 bytes of the bootdevice) to compare at the later boot processes. The main second-stage GRUB bootloader {{ic|core.img}} is not checked.
 
For BIOS systems the hook creates a hash of GRUB's first stage bootloader (installed to the first 446 bytes of the bootdevice) to compare at the later boot processes. The main second-stage GRUB bootloader {{ic|core.img}} is not checked.
  
===Other methods ===
+
=== AIDE ===
  
 
Alternatively to above scripts, a hash check can be set up with [[AIDE]] which can be customized via a very flexible configuration file.  
 
Alternatively to above scripts, a hash check can be set up with [[AIDE]] which can be customized via a very flexible configuration file.  
  
While one of these methods should serve the purpose for most users, they do not address all security problems associated with the unencrypted {{ic|/boot}}. One approach which endeavours to provide a fully authenticated boot chain was published with POTTS as an academic thesis to implement the [http://www1.informatik.uni-erlangen.de/stark STARK] authentication framework.  
+
=== STARK ===
 +
 
 +
While one of these methods should serve the purpose for most users, they do not address all security problems associated with the unencrypted {{ic|/boot}}. One approach which endeavours to provide a fully authenticated boot chain was published with POTTS as an academic thesis to implement the [https://www1.informatik.uni-erlangen.de/stark STARK] authentication framework.  
 +
 
 +
The POTTS proof-of-concept uses Arch Linux as a base distribution and implements a system boot chain with:
  
The POTTS proof-of-concept uses Arch Linux as a base distribution and implements a system boot chain with 
 
 
* POTTS - a boot menu for a one-time authentication message prompt  
 
* POTTS - a boot menu for a one-time authentication message prompt  
* TrustedGrub - a [[GRUB Legacy]] implementation which authenticates the kernel and initramfs against TPM chip registers  
+
* TrustedGrub - a [[GRUB Legacy]] implementation which authenticates the kernel and initramfs against [[Trusted Platform Module|TPM chip]] PCR registers  
 
* TRESOR - a kernel patch which implements AES but keeps the master-key not in RAM but in CPU registers during runtime.     
 
* TRESOR - a kernel patch which implements AES but keeps the master-key not in RAM but in CPU registers during runtime.     
As part of the thesis [http://13.tc/p/potts/manual.html installation] instructions based on Arch Linux (ISO as of 2013-01) have been published. If you want to try it, be aware these tools are not in standard repositories and the solution will be time consuming to maintain.
 
  
==Using GPG or OpenSSL Encrypted Keyfiles==
+
As part of the thesis [https://13.tc/p/potts/manual.html installation] instructions based on Arch Linux (ISO as of 2013-01) have been published. If you want to try it, be aware these tools are not in standard repositories and the solution will be time consuming to maintain.
 +
 
 +
== Using GPG, LUKS, or OpenSSL Encrypted Keyfiles ==
 +
 
 
The following forum posts give instructions to use two factor authentication, gpg or openssl encrypted keyfiles, instead of a plaintext keyfile described earlier in this wiki article [https://bbs.archlinux.org/viewtopic.php?id=120243 System Encryption using LUKS with GPG encrypted keys]:
 
The following forum posts give instructions to use two factor authentication, gpg or openssl encrypted keyfiles, instead of a plaintext keyfile described earlier in this wiki article [https://bbs.archlinux.org/viewtopic.php?id=120243 System Encryption using LUKS with GPG encrypted keys]:
 +
 
* GnuPG: [https://bbs.archlinux.org/viewtopic.php?pid=943338#p943338 Post regarding GPG encrypted keys] This post has the generic instructions.
 
* GnuPG: [https://bbs.archlinux.org/viewtopic.php?pid=943338#p943338 Post regarding GPG encrypted keys] This post has the generic instructions.
 
* OpenSSL: [https://bbs.archlinux.org/viewtopic.php?pid=947805#p947805 Post regarding OpenSSL encrypted keys] This post only has the {{ic|ssldec}} hooks.
 
* OpenSSL: [https://bbs.archlinux.org/viewtopic.php?pid=947805#p947805 Post regarding OpenSSL encrypted keys] This post only has the {{ic|ssldec}} hooks.
 
* OpenSSL: [https://bbs.archlinux.org/viewtopic.php?id=155393 Post regarding OpenSSL salted bf-cbc encrypted keys] This post has the {{ic|bfkf}} initcpio hooks, install, and encrypted keyfile generator scripts.
 
* OpenSSL: [https://bbs.archlinux.org/viewtopic.php?id=155393 Post regarding OpenSSL salted bf-cbc encrypted keys] This post has the {{ic|bfkf}} initcpio hooks, install, and encrypted keyfile generator scripts.
* LUKS: [https://bbs.archlinux.org/viewtopic.php?pid=1502651#p1502651 Post regarding LUKS encrypted keys] with a {{ic|lukskey}} initcpio hook.
+
* LUKS: [https://bbs.archlinux.org/viewtopic.php?pid=1502651#p1502651 Post regarding LUKS encrypted keys] with a {{ic|lukskey}} initcpio hook. Or [[#Encrypted /boot and a detached LUKS header on USB]] below with a custom encrypt hook for initcpio.
  
 
Note that:
 
Note that:
* You can follow the above instructions with only two primary partitions, one boot partition (required because of encryption) and one primary LVM partition. Within the LVM partition you can have as many partitions as you need, but most importantly it should contain at least root, swap, and home logical volume partitions. This has the added benefit of having only one keyfile for all your partitions, and having the ability to hibernate your computer (suspend to disk) where the swap partition is encrypted. If you decide to do so your hooks in {{ic|/etc/mkinitcpio.conf}} should look like this:{{bc|1=HOOKS=" ... usb usbinput (etwo or ssldec) encrypt (if using openssl) lvm2 resume ... "}} and you should add {{bc|1=resume=/dev/mapper/<VolumeGroupName>-<LVNameOfSwap>}} to your [[kernel parameters]].
+
 
 +
* You can follow the above instructions with only two primary partitions, one boot partition (required because of encryption) and one primary LVM partition. Within the LVM partition you can have as many partitions as you need, but most importantly it should contain at least root, swap, and home logical volume partitions. This has the added benefit of having only one keyfile for all your partitions, and having the ability to hibernate your computer (suspend to disk) where the swap partition is encrypted. If you decide to do so your hooks in {{ic|/etc/mkinitcpio.conf}} should look like this:{{bc|1=HOOKS=( ... usb usbinput (etwo or ssldec) encrypt (if using openssl) lvm2 resume ... )}} and you should add {{bc|1=resume=/dev/<VolumeGroupName>/<LVNameOfSwap>}} to your [[kernel parameters]].
 
* If you need to temporarily store the unencrypted keyfile somewhere, do not store them on an unencrypted disk. Even better make sure to store them to RAM such as {{ic|/dev/shm}}.
 
* If you need to temporarily store the unencrypted keyfile somewhere, do not store them on an unencrypted disk. Even better make sure to store them to RAM such as {{ic|/dev/shm}}.
 
* If you want to use a GPG encrypted keyfile, you need to use a statically compiled GnuPG version 1.4 or you could edit the hooks and use this AUR package {{AUR|gnupg1}}
 
* If you want to use a GPG encrypted keyfile, you need to use a statically compiled GnuPG version 1.4 or you could edit the hooks and use this AUR package {{AUR|gnupg1}}
 
* It is possible that an update to OpenSSL could break the custom {{ic|ssldec}} mentioned in the second forum post.
 
* It is possible that an update to OpenSSL could break the custom {{ic|ssldec}} mentioned in the second forum post.
  
==Remote unlocking of the root (or other) partition==
+
== Remote unlocking of the root (or other) partition ==
  
There are few ways to provide early networking and cryptsetup configuration.  
+
If you want to be able to reboot a fully LUKS-encrypted system remotely, or start it with a [[Wake-on-LAN]] service, you will need a way to enter a passphrase for the root partition/volume at startup. This can be achieved by running a [[mkinitcpio]] hook that configures a network interface. Some packages listed below contribute various [[Mkinitcpio#Build hooks|mkinitcpio build hooks]] to ease with the configuration.
  
They all require making changes to initramfs with help of packages contributing various
+
{{Note|
[[Mkinitcpio#Build_hooks|mkinitcpio build hooks]].
+
* Keep in mind to use kernel device names for the network interface (e.g. {{ic|eth0}}) and not [[udev|udev's]] ones (e.g. {{ic|enp1s0}}), as those will not work.
 +
* By default, Predictable Network Interface Names are activated and '''change''' the kernel device name during late boot. Use dmesg and look what your Network kernel module does to find the original name (e.g. {{ic|eth0}})
 +
* It could be necessary to add [[Network configuration#Device driver|the module for your network card]] to the [[Mkinitcpio#MODULES|MODULES]] array.
 +
}}
  
===Remote unlocking (hooks: systemd, systemd-tool)===
+
=== Remote unlocking (hooks: systemd, systemd-tool) ===
  
AUR package {{AUR|mkinitcpio-systemd-tool}}  
+
AUR package {{AUR|mkinitcpio-systemd-tool}} provides a {{Pkg|systemd}}-centric mkinitcpio hook named ''systemd-tool'' with the following set of features for systemd in initramfs:
provides {{Pkg|systemd}}-centric mkinitcpio hook named ''systemd-tool''
 
with the following set of features for systemd in initramfs:
 
  
 
{| class="wikitable"
 
{| class="wikitable"
Line 156: Line 180:
 
|}
 
|}
  
{{Note| {{AUR|mkinitcpio-systemd-tool}} package requires use of
+
The {{AUR|mkinitcpio-systemd-tool}} package requires the [[mkinitcpio#Common hooks|systemd hook]]. For more information be sure to read the project's [https://github.com/random-archer/mkinitcpio-systemd-tool/blob/master/README.md README] as well as the provided default [https://github.com/random-archer/mkinitcpio-systemd-tool systemd service unit files] to get you started.
[[Mkinitcpio#Common_hooks|systemd hook]].}}
 
  
{{Tip|1= please study project [https://github.com/random-archer/mkinitcpio-systemd-tool/blob/master/README.md README] as well as provided default [https://github.com/random-archer/mkinitcpio-systemd-tool systemd service unit files] to get you started.}}
+
The recommended hooks are: {{ic|base autodetect modconf block filesystems keyboard fsck systemd systemd-tool}}.
  
===Remote unlocking (hooks: netconf, dropbear, tinyssh, ppp)===
+
=== Remote unlocking (hooks: netconf, dropbear, tinyssh, ppp) ===
  
{{Note|1=As of 07/23/2015 the "dropbear_initrd_encrypt" package was split into three other packages. See [https://bbs.archlinux.org/viewtopic.php?id=200114 this forum post]. As of 11/18/2015 the package was deleted from the [[AUR]]. The steps below reflect the usage of the new packages.}}
+
Another package combination providing remote logins to the initcpio is {{Pkg|mkinitcpio-netconf}} and/or {{AUR|mkinitcpio-ppp}} (for remote unlocking using a  [[Wikipedia:Point-to-Point Protocol|PPP]] connection over the internet) along with an [[SSH]] server. You have the option of using either {{Pkg|mkinitcpio-dropbear}} or {{Pkg|mkinitcpio-tinyssh}}. Those hooks do not install any shell, so you also need to [[install]] the {{Pkg|mkinitcpio-utils}} package. The instructions below can be used in any combination of the packages above. When there are different paths, it will be noted.
If you want to be able to reboot a fully LUKS-encrypted system remotely, or start it with a [[Wake-on-LAN]] service, you will need a way to enter a passphrase for the root partition/volume at startup. This can be achieved by running a [[mkinitcpio]] hook that configures a network interface, such as {{AUR|mkinitcpio-netconf}} and/or {{AUR|mkinitcpio-ppp}} (for remote unlocking using a  [[Wikipedia:Point-to-Point Protocol|PPP]] connection over the internet) along with an [[SSH]] server in initrd. You have the option of using either {{AUR|mkinitcpio-dropbear}} or {{AUR|mkinitcpio-tinyssh}}. Those hooks do not install any shell, so you also need to [[Install|install]] the {{AUR|mkinitcpio-utils}} package. The instructions below can be used in any combination of the packages above. When there are different paths, it will be noted.
 
  
# If you do not have an SSH key pair yet, [[SSH keys#Generating_an_SSH_key_pair|generate one]] on the client system (the one which will be used to unlock the remote machine).
+
# If you do not have an SSH key pair yet, [[SSH keys#Generating_an_SSH_key_pair|generate one]] on the client system (the one which will be used to unlock the remote machine). {{Note|{{ic|tinyssh}} only supports [[SSH_keys#Ed25519|Ed25519]] and [[SSH_keys#ECDSA|ECDSA]] key types. If you chose to use {{Pkg|mkinitcpio-tinyssh}}, you need to create/use one of these.}} {{Note|{{ic|mkinitcpio-dropbear}} in version 0.0.3-5 is not compatible with the current dropbear implementation that removed dss. See [https://github.com/grazzolini/mkinitcpio-dropbear/issues/8 Github] for details and a fix.}}
# If your choose to use {{AUR|mkinitcpio-tinyssh}}, you have the option of using [[SSH_keys#Choosing_the_type_of_encryption|Ed25519 keys]].
+
# Insert your SSH public key (i.e. the one you usually put onto hosts so that you can ssh in without a password, or the one you just created and which ends with ''.pub'') into the remote machine's {{ic|/etc/dropbear/root_key}} or {{ic|/etc/tinyssh/root_key}} file. {{Tip|This method can later be used to add other SSH public keys as needed; In the case of simply copying the content of the remote's {{ic|~/.ssh/authorized_keys}}, be sure to verify that it only contains keys you intend to be using to unlock the remote machine. When adding additional keys, regenerate your initrd as well using {{ic|mkinitcpio}}. See also [[OpenSSH#Protection]].}}
# Insert your SSH public key (i.e. the one you usually put onto hosts so that you can ssh in without a password, or the one you just created and which ends with ''.pub'') into the remote machine's {{ic|/etc/dropbear/root_key or /etc/tinyssh/root_key}} file using the method of your choice, e.g.:
+
# Add all three {{ic|<netconf and/or ppp> <dropbear or tinyssh> encryptssh}} [[Mkinitcpio#HOOKS|hooks]] before {{ic|filesystems}} within the "HOOKS" array in {{ic|/etc/mkinitcpio.conf}} (the {{ic|encryptssh}} replaces the {{ic|encrypt}} hook). Then [[regenerate the initramfs]]. {{Note|The {{ic|net}} hook provided by {{Pkg|mkinitcpio-nfs-utils}} is '''not''' needed.}}{{Note|If you experience the error {{ic|libgcc_s.so.1 must be installed for pthread_cancel to work}} when trying to decrypt, you need to add {{ic|/usr/lib/libgcc_s.so.1}} to the "[[Mkinitcpio#BINARIES_and_FILES|BINARIES]]" array.}}
#*[[SSH keys#Copying_the_public_key_to_the_remote_server|copy the public key to the remote system]]
+
# Configure the required {{ic|1=cryptdevice=}} [[Dm-crypt/System_configuration#Boot_loader|parameter]] and add the {{ic|1=ip=}} [[Kernel_parameters|kernel command parameter]] to your bootloader configuration with the appropriate arguments. For example, if the DHCP server does not attribute a static IP to your remote system, making it difficult to access via SSH across reboots, you can explicitly state the IP you want to be using:{{bc|1=ip=192.168.1.1:::::eth0:none}}Alternatively, you can also specify the subnet mask and gateway required by the network:{{bc|1=ip=192.168.1.1::192.168.1.254:255.255.255.0::eth0:none}}{{Note|As of version 0.0.4 of {{Pkg|mkinitcpio-netconf}}, you can nest multiple {{ic|1=ip=}} parameters in order to configure multiple interfaces. You cannot mix it with {{ic|1=ip=dhcp}} ({{ic|1=ip=:::::eth0:dhcp}}) alone. An interface needs to be specified.}}{{bc|1=ip=ip=192.168.1.1:::::eth0:none:ip=172.16.1.1:::::eth1:none}}For a detailed description have a look at the [[Mkinitcpio#Using net|according mkinitcpio section]]. When finished, update the configuration of your [[bootloader]].
#* then enter the following command (on the remote system): {{bc|# cat /home/<user>/.ssh/authorized_keys > /etc/<dropbear or tinyssh>/root_key}}{{Tip|This method can later be used to add other SSH public keys as needed; in that case verify the content of remote {{ic|~/.ssh/authorized_keys}} contains only keys you agree to be used to unlock the remote machine. When adding additional keys, also regenerate your initrd with mkinitcpio. See also [[Secure Shell#Protection]].}}
+
# Finally, restart the remote system and try to [[OpenSSH#Client usage|ssh to it]], '''explicitly stating the "root" username''' (even if the root account is disabled on the machine, this root user is used only in the initrd for the purpose of unlocking the remote system). If you are using the {{Pkg|mkinitcpio-dropbear}} package and you also have the {{Pkg|openssh}} package installed, then you most probably will not get any warnings before logging in, because it convert and use the same host keys openssh uses (except Ed25519 keys, as dropbear does not support them). In case you are using {{Pkg|mkinitcpio-tinyssh}}, you have the option of installing {{Pkg|tinyssh-convert}} or {{AUR|tinyssh-convert-git}} so you can use the same keys as your {{Pkg|openssh}} installation (currently only Ed25519 keys). In either case, you should have run [[OpenSSH#Daemon_management|the ssh daemon]] at least once, using the provided systemd units, so the keys can be generated first. After rebooting the machine, you should be prompted for the passphrase to unlock the root device. The system will complete its boot process and you can then ssh to it [[OpenSSH#Client usage|as you normally would]] (with the remote user of your choice).
# Add the {{ic|<netconf and/or ppp> <dropbear or tinyssh> encryptssh}} [[Mkinitcpio#HOOKS|hooks]] before {{ic|filesystems}} within the "HOOKS" array in {{ic|/etc/mkinitcpio.conf}} (the {{ic|encryptssh}} can be used to replace the {{ic|encrypt}} hook). Then [[Mkinitcpio#Image_creation_and_activation|rebuild the initramfs image]]. {{Note|The {{ic|net}} hook provided with {{Pkg|mkinitcpio-nfs-utils}} is '''not''' needed}} {{Note|It could be necessary to add [[Network_configuration#Device driver|the module for your network card]] to the [[Mkinitcpio#MODULES|MODULES]] array.}}
 
# Configure the required {{ic|1=cryptdevice=}} [[Dm-crypt/System_configuration#Boot_loader|parameter]] and add the {{ic|1=ip=}} [[Kernel_parameters|kernel command parameter]] to your bootloader configuration with the appropriate arguments (see [[Mkinitcpio#Using_net]]). For example, if the DHCP server does not attribute a static IP to your remote system, making it difficult to access via SSH accross reboots, you can explicitly state the IP you want to be used:{{bc|<nowiki>ip=192.168.1.1:::::eth0:none</nowiki>}}{{Note|Make sure to use kernel device names for the interface name (under the form ''eth#'') and not ''udev'' ones, as those will not work.}}Then update the configuration of your [[Boot_loaders|bootloader]], e.g. for [[GRUB#Generate the main configuration file|GRUB]]:{{bc|# grub-mkconfig -o /boot/grub/grub.cfg}}
 
# Finally, restart the remote system and try to [[Secure_Shell#Client usage|ssh to it]], '''explicitly stating the "root" username''' (even if the root account is disabled on the machine, this root user is used only in the initrd for the purpose of unlocking the remote system). If you are using the {{AUR|mkinitcpio-dropbear}} package and you also have the {{Pkg|openssh}} package installed, then you most probably will not get any warnings before logging in, because it convert and use the same host keys openssh uses. (Except Ed25519 keys, dropbear does not support them). In case you are using {{AUR|mkinitcpio-tinyssh}}, you '''will''' get a warning the first time you login, because tinyssh does not use the same host keys as openssh, and they will be created when you build the initramfs. They will not be recreated every time, just on the first build. In either case, you should be prompted for the passphrase to unlock the root device:
 
{{hc|$ ssh '''root'''@192.168.1.1|Enter passphrase for /dev/sda2:   
 
Connection to 192.168.1.1 closed.}}
 
Afterwards, the system will complete its boot process and you can ssh to it [[Secure_Shell#Client usage|as you normally would]] (with the remote user of your choice).
 
  
 
{{Tip|1=If you would simply like a nice solution to mount other encrypted partitions (such as {{ic|/home}}) remotely, you may want to look at [https://bbs.archlinux.org/viewtopic.php?pid=880484 this forum thread].}}
 
{{Tip|1=If you would simply like a nice solution to mount other encrypted partitions (such as {{ic|/home}}) remotely, you may want to look at [https://bbs.archlinux.org/viewtopic.php?pid=880484 this forum thread].}}
  
=== Remote unlock via wifi (hooks: build your own) ===
+
=== Remote unlock via wifi ===
The net hook is normally used with an ethernet connection. In case you want to setup a computer with wireless only, and unlock it via wifi, you can create a custom hook to connect to a wifi network before the net hook is run.
+
 
 +
The net hook is normally used with an ethernet connection. In case you want to setup a computer with wireless only, and unlock it via wifi, you can use a predefined hook or create a custom hook to connect to a wifi network before the net hook is run.
 +
 
 +
==== Predefined hook ====
 +
You can install a predefined hook based on the one in this wiki:
 +
# Install {{AUR|mkinitcpio-wifi}}.
 +
# Configure your wifi connection by creating a wpa_supplicant configuration with your network properties: {{bc|wpa_passphrase "ESSID" "passphrase" > /etc/wpa_supplicant/initcpio.conf}}
 +
# Add the {{ic|wifi}} hook before {{ic|netconf}} in your {{ic|/etc/mkinitcpio.conf}}. Your wifi-related modules should be autodetected, if not: add them to the {{ic|MODULES}} section.
 +
# Add {{ic|1=ip=:::::wlan0:dhcp}} to the [[kernel parameters]].
 +
# [[Regenerate the initramfs]].
 +
# Update the configuration of your [[boot loader]].
  
 +
==== Build your own ====
 
Below example shows a setup using a usb wifi adapter, connecting to a wifi network protected with WPA2-PSK. In case you use for example WEP or another boot loader, you might need to change some things.
 
Below example shows a setup using a usb wifi adapter, connecting to a wifi network protected with WPA2-PSK. In case you use for example WEP or another boot loader, you might need to change some things.
  
Line 188: Line 215:
 
#* Add the needed kernel module for your specific wifi adatper.
 
#* Add the needed kernel module for your specific wifi adatper.
 
#* Include the {{ic|wpa_passphrase}} and {{ic|wpa_supplicant}} binaries.
 
#* Include the {{ic|wpa_passphrase}} and {{ic|wpa_supplicant}} binaries.
#* Add a hook {{ic|wifi}} (or a name of your choice, this is the custom hook that will be created) before the {{ic|net}} hook.{{bc|1=MODULES="''module''"<br>BINARIES="wpa_passphrase wpa_supplicant"<br>HOOKS="base udev autodetect ... '''wifi''' net ... dropbear encryptssh ..."}}
+
#* Add a hook {{ic|wifi}} (or a name of your choice, this is the custom hook that will be created) before the {{ic|net}} hook.{{bc|1=MODULES=(''module'')<br>BINARIES=(wpa_passphrase wpa_supplicant)<br>HOOKS=(base udev autodetect ... '''wifi''' net ... dropbear encryptssh ...)}}
# Create the {{ic|wifi}} hook in {{ic|/lib/initcpio/hooks/wifi}}:{{bc|run_hook ()<br>{<br>&#09;# sleep a couple of seconds so wlan0 is setup by kernel<br>&#09;sleep 5<br><br>&#09;# set wlan0 to up<br>&#09;ip link set wlan0 up<br><br>&#09;# assocciate with wifi network<br>&#09;# 1. save temp config file<br>&#09;wpa_passphrase "''network ESSID''" "''pass phrase''" > /tmp/wifi<br><br>&#09;# 2. assocciate<br>&#09;wpa_supplicant -B -D nl80211,wext -i wlan0 -c /tmp/wifi<br><br>&#09;# sleep a couple of seconds so that wpa_supplicant finishes connecting<br>&#09;sleep 5<br><br>&#09;# wlan0 should now be connected and ready to be assigned an ip by the net hook<br>}<br><br>run_cleanuphook ()<br>{<br>&#09;# kill wpa_supplicant running in the background<br>&#09;killall wpa_supplicant<br><br>&#09;# set wlan0 link down<br>&#09;ip link set wlan0 down<br><br>&#09;# wlan0 should now be fully disconnected from the wifi network<br>}|}}
+
# Create the {{ic|wifi}} hook in {{ic|/etc/initcpio/hooks/wifi}}:{{bc|run_hook ()<br>{<br>&#09;# sleep a couple of seconds so wlan0 is setup by kernel<br>&#09;sleep 5<br><br>&#09;# set wlan0 to up<br>&#09;ip link set wlan0 up<br><br>&#09;# assocciate with wifi network<br>&#09;# 1. save temp config file<br>&#09;wpa_passphrase "''network ESSID''" "''pass phrase''" > /tmp/wifi<br><br>&#09;# 2. assocciate<br>&#09;wpa_supplicant -B -D nl80211,wext -i wlan0 -c /tmp/wifi<br><br>&#09;# sleep a couple of seconds so that wpa_supplicant finishes connecting<br>&#09;sleep 5<br><br>&#09;# wlan0 should now be connected and ready to be assigned an ip by the net hook<br>}<br><br>run_cleanuphook ()<br>{<br>&#09;# kill wpa_supplicant running in the background<br>&#09;killall wpa_supplicant<br><br>&#09;# set wlan0 link down<br>&#09;ip link set wlan0 down<br><br>&#09;# wlan0 should now be fully disconnected from the wifi network<br>}|}}
# Create the hook installation file in {{ic|/lib/initcpio/install/wifi}}:{{bc|build ()<br>{<br>&#09;add_runscript<br>}<br>help ()<br>{<br>cat<<HELPEOF<br>&#09;Enables wifi on boot, for dropbear ssh unlocking of disk.<br>HELPEOF<br>}|}}
+
# Create the hook installation file in {{ic|/etc/initcpio/install/wifi}}:{{bc|build ()<br>{<br>&#09;add_runscript<br>}<br>help ()<br>{<br>cat<<HELPEOF<br>&#09;Enables wifi on boot, for dropbear ssh unlocking of disk.<br>HELPEOF<br>}|}}
 
# Add {{ic|1=ip=:::::wlan0:dhcp}} to the [[kernel parameters]]. Remove {{ic|1=ip=:::::eth0:dhcp}} so it does not conflict.
 
# Add {{ic|1=ip=:::::wlan0:dhcp}} to the [[kernel parameters]]. Remove {{ic|1=ip=:::::eth0:dhcp}} so it does not conflict.
 
# Optionally create an additional boot entry with kernel parameter {{ic|1=ip=:::::eth0:dhcp}}.
 
# Optionally create an additional boot entry with kernel parameter {{ic|1=ip=:::::eth0:dhcp}}.
# [[Mkinitcpio#Image_creation_and_activation|Regenerate the intiramfs image]].
+
# [[Regenerate the initramfs]].
# Update the configuration of your [[boot loader]], e.g. for [[GRUB#Generate the main configuration file|GRUB]]:{{bc|# grub-mkconfig -o /boot/grub/grub.cfg}}
+
# Update the configuration of your [[boot loader]].
Remember to setup [[Wireless_network_configuration|wifi]], so you are able to login once the system is fully booted. In case you are unable to connect to the wifi network, try increasing the sleep times a bit.
+
 
 +
Remember to setup [[wifi]], so you are able to login once the system is fully booted. In case you are unable to connect to the wifi network, try increasing the sleep times a bit.
  
 
== Discard/TRIM support for solid state drives (SSD) ==
 
== Discard/TRIM support for solid state drives (SSD) ==
Line 201: Line 229:
 
[[Solid state drive]] users should be aware that, by default, TRIM commands are not enabled by the device-mapper, i.e. block-devices are mounted without the {{ic|discard}} option unless you override the default.  
 
[[Solid state drive]] users should be aware that, by default, TRIM commands are not enabled by the device-mapper, i.e. block-devices are mounted without the {{ic|discard}} option unless you override the default.  
  
The device-mapper maintainers have made it clear that TRIM support will never be enabled by default on dm-crypt devices because of the potential security implications.[http://www.saout.de/pipermail/dm-crypt/2011-September/002019.html][http://www.saout.de/pipermail/dm-crypt/2012-April/002420.html] Minimal data leakage in the form of freed block information, perhaps sufficient to determine the filesystem in use, may occur on devices with TRIM enabled. An illustration and discussion of the issues arising from activating TRIM is available in the [http://asalor.blogspot.de/2011/08/trim-dm-crypt-problems.html blog] of a ''cryptsetup'' developer. If you are worried about such factors, keep also in mind that threats may add up: for example, if your device is still encrypted with the previous (cryptsetup <1.6.0) default cipher {{ic|--cipher aes-cbc-essiv}}, more information leakage may occur from trimmed sector observation than with the current [[Dm-crypt/Device_encryption#Encryption_options_for_LUKS_mode|default]].  
+
The device-mapper maintainers have made it clear that TRIM support will never be enabled by default on dm-crypt devices because of the potential security implications.[http://www.saout.de/pipermail/dm-crypt/2011-September/002019.html][http://www.saout.de/pipermail/dm-crypt/2012-April/002420.html] Minimal data leakage in the form of freed block information, perhaps sufficient to determine the filesystem in use, may occur on devices with TRIM enabled. An illustration and discussion of the issues arising from activating TRIM is available in the [http://asalor.blogspot.de/2011/08/trim-dm-crypt-problems.html blog] of a ''cryptsetup'' developer. If you are worried about such factors, keep also in mind that threats may add up: for example, if your device is still encrypted with the previous (cryptsetup <1.6.0) default cipher {{ic|--cipher aes-cbc-essiv}}, more information leakage may occur from trimmed sector observation than with the current [[dm-crypt/Device encryption#Encryption options for LUKS mode|default]].  
  
 
The following cases can be distinguished:
 
The following cases can be distinguished:
Line 209: Line 237:
 
** TRIM can be left disabled if the security issues stated at the top of this section are considered a worse threat than the above bullet.
 
** TRIM can be left disabled if the security issues stated at the top of this section are considered a worse threat than the above bullet.
 
: See also [[Securely wipe disk#Flash memory]].
 
: See also [[Securely wipe disk#Flash memory]].
* The device is encrypted with dm-crypt plain mode, or the LUKS header is stored [[#Encrypted system using a remote LUKS header|separately]]:
+
* The device is encrypted with dm-crypt plain mode, or the LUKS header is stored [[#Encrypted system using a detached LUKS header|separately]]:
 
** If plausible deniability is required, TRIM should '''never''' be used because of the considerations at the top of this section, or the use of encryption will be given away.
 
** If plausible deniability is required, TRIM should '''never''' be used because of the considerations at the top of this section, or the use of encryption will be given away.
 
** If plausible deniability is not required, TRIM can be used for its performance gains, provided that the security dangers described at the top of this section are not of concern.
 
** If plausible deniability is not required, TRIM can be used for its performance gains, provided that the security dangers described at the top of this section are not of concern.
  
{{Warning|Before enabling TRIM on a drive, make sure the device fully supports TRIM commands, or data loss can occur. See [[Solid State Drives/Tips and tricks#TRIM]].}}
+
{{Warning|Before enabling TRIM on a drive, make sure the device fully supports TRIM commands, or data loss can occur. See [[Solid State Drives#TRIM]].}}
  
 
In {{Pkg|linux}} 3.1 and up, support for dm-crypt TRIM pass-through can be toggled upon device creation or mount with dmsetup. Support for this option also exists in {{Pkg|cryptsetup}} version 1.4.0 and up. To add support during boot, you will need to add {{ic|:allow-discards}} to the {{ic|cryptdevice}} option. The TRIM option may look like this:
 
In {{Pkg|linux}} 3.1 and up, support for dm-crypt TRIM pass-through can be toggled upon device creation or mount with dmsetup. Support for this option also exists in {{Pkg|cryptsetup}} version 1.4.0 and up. To add support during boot, you will need to add {{ic|:allow-discards}} to the {{ic|cryptdevice}} option. The TRIM option may look like this:
 +
 
  cryptdevice=/dev/sdaX:root:allow-discards
 
  cryptdevice=/dev/sdaX:root:allow-discards
  
Line 221: Line 250:
  
 
If you are using a systemd based initrd, you must pass:
 
If you are using a systemd based initrd, you must pass:
 +
 
  rd.luks.options=discard
 
  rd.luks.options=discard
 +
 +
{{Note|The {{ic|1=rd.luks.options=discard}} kernel option does not have any effect on devices included in the initramfs image's {{ic|/etc/crypttab}} file ({{ic|/etc/crypttab.initramfs}} on real root). You must specify option {{ic|discard}} in {{ic|/etc/crypttab.initramfs}}.}}
  
 
Besides the kernel option, it is also required to periodically run {{ic|fstrim}} or mount the filesystem (e.g. {{ic|/dev/mapper/root}} in this example) with the {{ic|discard}} option in {{ic|/etc/fstab}}. For details, please refer to the [[TRIM]] page.
 
Besides the kernel option, it is also required to periodically run {{ic|fstrim}} or mount the filesystem (e.g. {{ic|/dev/mapper/root}} in this example) with the {{ic|discard}} option in {{ic|/etc/fstab}}. For details, please refer to the [[TRIM]] page.
  
For LUKS devices unlocked manually on the console or via {{ic|/etc/crypttab}} either {{ic|discard}} or {{ic|allow-discards}} may be used.
+
For LUKS devices unlocked via {{ic|/etc/crypttab}} use option {{ic|discard}}, e.g.:
 +
 
 +
{{hc|/etc/crypttab|
 +
2=luks-123abcdef-etc UUID=123abcdef-etc none discard}}
 +
 
 +
When manually unlocking devices on the console use {{ic|--allow-discards}}.
 +
 
 +
With LUKS2 you can set {{ic|allow-discards}} as a default flag for a device by opening it once with the option {{ic|--persistent}}:
 +
 
 +
# cryptsetup --allow-discards --persistent open /dev/sdaX root
 +
 
 +
When the device is already opened, the {{ic|open}} action will raise an error. You can use the {{ic|refresh}} option in these cases, e.g.:
 +
 
 +
# cryptsetup --allow-discards --persistent refresh /dev/sdaX
 +
 
 +
You can confirm the flag is persistently set in the LUKS2 header by looking at the {{ic|cryptsetup luksDump}} output:
 +
 
 +
{{hc|# cryptsetup luksDump /dev/sdaX {{!}} grep Flags|
 +
Flags:          allow-discards
 +
}}
 +
 
 +
In any case, you can verify whether the device actually was opened with discards by inspecting the {{ic|dmsetup table}} output:
 +
 +
{{hc|# dmsetup table|
 +
luks-123abcdef-etc: 0 1234567 crypt aes-xts-plain64 000etc000 0 8:2 4096 1 allow_discards
 +
}}
  
 
== The encrypt hook and multiple disks ==
 
== The encrypt hook and multiple disks ==
  
The {{ic|encrypt}} hook only allows for a '''single''' {{ic|cryptdevice<nowiki>=</nowiki>}} entry. In system setups with multiple drives this may be limiting, because ''dm-crypt'' has no feature to exceed the physical device. For example, take "LVM on LUKS":  The entire LVM exists inside a LUKS mapper.  This is perfectly fine for a single-drive system, since there is only one device to decrypt. But what happens when you want to increase the size of the LVM? You cannot, at least not without modifying the {{ic|encrypt}} hook.
+
{{Tip|{{ic|sd-encrypt}} hook supports unlocking multiple devices. They can be specified on the kernel command line or in {{ic|/etc/crypttab.initramfs}}. See [[dm-crypt/System configuration#Using sd-encrypt hook]].}}
  
The following sections briefly show alternatives to overcome the limitation. The first deals with how to expand a [[Dm-crypt/Encrypting_an_entire_system#LUKS_on_LVM|LUKS on LVM]] setup to a new disk. The second with modifying the {{ic|encrypt}} hook to unlock multiple disks in LUKS setups without LVM. The third section then again uses LVM, but modifies the {{ic|encrypt}} hook to unlock the encrypted LVM with a remote LUKS header.  
+
The {{ic|encrypt}} hook only allows for a '''single''' {{ic|1=cryptdevice=}} entry ({{Bug|23182}}). In system setups with multiple drives this may be limiting, because ''dm-crypt'' has no feature to exceed the physical device. For example, take "LVM on LUKS":  The entire LVM exists inside a LUKS mapper.  This is perfectly fine for a single-drive system, since there is only one device to decrypt. But what happens when you want to increase the size of the LVM? You cannot, at least not without modifying the {{ic|encrypt}} hook.
 +
 
 +
The following sections briefly show alternatives to overcome the limitation. The first deals with how to expand a [[Dm-crypt/Encrypting_an_entire_system#LUKS_on_LVM|LUKS on LVM]] setup to a new disk. The second with modifying the {{ic|encrypt}} hook to unlock multiple disks in LUKS setups without LVM.
  
 
=== Expanding LVM on multiple disks ===
 
=== Expanding LVM on multiple disks ===
The management of multiple disks is a basic [[LVM]] feature and a major reason for its partitioning flexibility. It can also be used with ''dm-crypt'', but only if LVM is employed as the first mapper. In such a [[Dm-crypt/Encrypting_an_entire_system#LUKS_on_LVM|LUKS on LVM]] setup the encrypted devices are created inside the logical volumes (with a separate passphrase/key per volume). The following covers the steps to expand that setup to another disk.
 
  
{{Warning|Backup! While resizing filesystems may be standard, keep in mind that operations '''may''' go wrong and the following might not apply to a particular setup. Generally, extending a filesystem to free disk space is less problematic than shrinking one. This in particular applies when stacked mappers are used, as it is the case in the following example.}}
+
The management of multiple disks is a basic [[LVM]] feature and a major reason for its partitioning flexibility. It can also be used with ''dm-crypt'', but only if LVM is employed as the first mapper. In such a [[dm-crypt/Encrypting an entire system#LUKS_on_LVM|LUKS on LVM]] setup the encrypted devices are created inside the logical volumes (with a separate passphrase/key per volume). The following covers the steps to expand that setup to another disk.
 +
 
 +
{{Warning|Back up! While resizing filesystems may be standard, keep in mind that operations '''may''' go wrong and the following might not apply to a particular setup. Generally, extending a filesystem to free disk space is less problematic than shrinking one. This in particular applies when stacked mappers are used, as it is the case in the following example.}}
 
   
 
   
 
==== Adding a new drive ====
 
==== Adding a new drive ====
First, it may be desired to prepare a new disk according to [[Dm-crypt/Drive preparation]].  
+
 
Second, it is partitioned as a LVM, e.g. all space is allocated to {{ic|/dev/sdY1}} with partition type "8E00" (Linux LVM).  
+
First, it may be desired to prepare a new disk according to [[dm-crypt/Drive preparation]].  
 +
Second, it is partitioned as a LVM, e.g. all space is allocated to {{ic|/dev/sdY1}} with partition type {{ic|8E00}} (Linux LVM).  
 
Third, the new disk/partition is attached to the existing LVM volume group, e.g.:
 
Third, the new disk/partition is attached to the existing LVM volume group, e.g.:
 +
 
  # pvcreate /dev/sdY1
 
  # pvcreate /dev/sdY1
 
  # vgextend MyStorage /dev/sdY1
 
  # vgextend MyStorage /dev/sdY1
Line 250: Line 312:
  
 
In this example, it is assumed that the logical volume for {{ic|/home}} (lv-name {{ic|homevol}}) is going to be expanded with the fresh disk space:  
 
In this example, it is assumed that the logical volume for {{ic|/home}} (lv-name {{ic|homevol}}) is going to be expanded with the fresh disk space:  
 +
 
  # umount /home
 
  # umount /home
 
  # fsck /dev/mapper/home
 
  # fsck /dev/mapper/home
Line 256: Line 319:
  
 
Now the logical volume is extended and the LUKS container comes next:  
 
Now the logical volume is extended and the LUKS container comes next:  
  # cryptsetup open --type luks /dev/mapper/MyStorage-homevol home
+
 
 +
  # cryptsetup open /dev/MyStorage/homevol home
 
  # umount /home      # as a safety, in case it was automatically remounted
 
  # umount /home      # as a safety, in case it was automatically remounted
 
  # cryptsetup --verbose resize home
 
  # cryptsetup --verbose resize home
  
 
Finally, the filesystem itself is resized:  
 
Finally, the filesystem itself is resized:  
 +
 
  # e2fsck -f /dev/mapper/home
 
  # e2fsck -f /dev/mapper/home
 
  # resize2fs /dev/mapper/home
 
  # resize2fs /dev/mapper/home
  
Done! If it went to plan, {{ic|/home}} can be remounted  
+
Done! If it went to plan, {{ic|/home}} can be remounted and now includes the span to the new disk:
 +
 
 
  # mount /dev/mapper/home /home
 
  # mount /dev/mapper/home /home
  
and now includes the span to the new disk. Note that the {{ic|cryptsetup resize}} action does not affect encryption keys, they have not changed.
+
Note that the {{ic|cryptsetup resize}} action does not affect encryption keys, and these have not changed.
  
 
=== Modifying the encrypt hook for multiple partitions ===
 
=== Modifying the encrypt hook for multiple partitions ===
 +
 
==== Root filesystem spanning multiple partitions ====
 
==== Root filesystem spanning multiple partitions ====
 +
 
It is possible to modify the encrypt hook to allow multiple hard drive decrypt root ({{ic|/}}) at boot. One way:
 
It is possible to modify the encrypt hook to allow multiple hard drive decrypt root ({{ic|/}}) at boot. One way:
  
  # cp /usr/lib/initcpio/install/encrypt /usr/lib/initcpio/install/encrypt2
+
  # cp /usr/lib/initcpio/install/encrypt /etc/initcpio/install/encrypt2
  # cp /usr/lib/initcpio/hooks/encrypt  /usr/lib/initcpio/hooks/encrypt2
+
  # cp /usr/lib/initcpio/hooks/encrypt  /etc/initcpio/hooks/encrypt2
  # sed -i "s/cryptdevice/cryptdevice2/" /usr/lib/initcpio/hooks/encrypt2
+
  # sed -i "s/cryptdevice/cryptdevice2/" /etc/initcpio/hooks/encrypt2
  # sed -i "s/cryptkey/cryptkey2/" /usr/lib/initcpio/hooks/encrypt2
+
  # sed -i "s/cryptkey/cryptkey2/" /etc/initcpio/hooks/encrypt2
  
Add {{ic|1=cryptdevice2=}} to your boot options (and {{ic|1=cryptkey2=}} if needed), see [[Dm-crypt/System_configuration]]
+
Add {{ic|1=cryptdevice2=}} to your boot options (and {{ic|1=cryptkey2=}} if needed), and add the {{ic|encrypt2}} hook to your [[mkinitcpio.conf]] before rebuilding it. See [[dm-crypt/System configuration]].
  
 
==== Multiple non-root partitions ====
 
==== Multiple non-root partitions ====
 +
 
Maybe you have a requirement for using the {{ic|encrypt}} hook on a non-root partition. Arch does not support this out of the box, however, you can easily change the cryptdev and cryptname values in {{ic|/lib/initcpio/hooks/encrypt}} (the first one to your {{ic|/dev/sd*}} partition, the second to the name you want to attribute). That should be enough.
 
Maybe you have a requirement for using the {{ic|encrypt}} hook on a non-root partition. Arch does not support this out of the box, however, you can easily change the cryptdev and cryptname values in {{ic|/lib/initcpio/hooks/encrypt}} (the first one to your {{ic|/dev/sd*}} partition, the second to the name you want to attribute). That should be enough.
  
Line 287: Line 356:
 
Of course, if the {{pkg|cryptsetup}} package gets upgraded, you will have to change this script again. Unlike {{ic|/etc/crypttab}}, only one partition is supported, but with some further hacking one should be able to have multiple partitions unlocked.
 
Of course, if the {{pkg|cryptsetup}} package gets upgraded, you will have to change this script again. Unlike {{ic|/etc/crypttab}}, only one partition is supported, but with some further hacking one should be able to have multiple partitions unlocked.
  
{{accuracy|Why not use the supported Grub2 right away? See also [[Mkinitcpio#Using_RAID]]}}  
+
{{Accuracy|Why not use the supported Grub2 right away? See also [[mkinitcpio#Using RAID]]}}  
 +
 
 
If you want to do this on a software RAID partition, there is one more thing you need to do. Just setting the {{ic|/dev/mdX}} device in {{ic|/lib/initcpio/hooks/encrypt}} is not enough; the {{ic|encrypt}} hook will fail to find the key for some reason, and not prompt for a passphrase either. It looks like the RAID devices are not brought up until after the {{ic|encrypt}} hook is run. You can solve this by putting the RAID array in {{ic|/boot/grub/menu.lst}}, like  
 
If you want to do this on a software RAID partition, there is one more thing you need to do. Just setting the {{ic|/dev/mdX}} device in {{ic|/lib/initcpio/hooks/encrypt}} is not enough; the {{ic|encrypt}} hook will fail to find the key for some reason, and not prompt for a passphrase either. It looks like the RAID devices are not brought up until after the {{ic|encrypt}} hook is run. You can solve this by putting the RAID array in {{ic|/boot/grub/menu.lst}}, like  
 +
 
  kernel /boot/vmlinuz-linux md=1,/dev/hda5,/dev/hdb5
 
  kernel /boot/vmlinuz-linux md=1,/dev/hda5,/dev/hdb5
  
If you set up your root partition as a RAID, you will notice the similarities with that setup ;-). [[GRUB]] can handle multiple array definitions just fine:
+
If you set up your root partition as a RAID, you will notice the similarities with that setup. [[GRUB]] can handle multiple array definitions just fine:
 +
 
 
  kernel /boot/vmlinuz-linux root=/dev/md0 ro md=0,/dev/sda1,/dev/sdb1 md=1,/dev/sda5,/dev/sdb5,/dev/sdc5
 
  kernel /boot/vmlinuz-linux root=/dev/md0 ro md=0,/dev/sda1,/dev/sdb1 md=1,/dev/sda5,/dev/sdb5,/dev/sdc5
  
=== Encrypted system using a remote LUKS header ===
+
== Encrypted system using a detached LUKS header ==
This example follows the same setup as in [[Dm-crypt/Encrypting an entire system#Plain dm-crypt]], which should be read first before following this guide.
+
 
 +
This example follows the same setup as in [[dm-crypt/Encrypting an entire system#Plain dm-crypt]], which should be read first before following this guide.
 
   
 
   
By using a remote header the encrypted blockdevice itself only carries encrypted data, which gives [[Wikipedia:Deniable encryption|deniable encryption]] as long as the existence of a header is unknown to the attackers. It is similar to using [[Dm-crypt/Encrypting an entire system#Plain_dm-crypt|plain dm-crypt]], but with the LUKS advantages such as multiple passphrases for the masterkey and key derivation. Further, using a remote header offers a form of two factor authentication with an easier setup than [[#Using GPG or OpenSSL Encrypted Keyfiles|using GPG or OpenSSL encrypted keyfiles]], while still having a built-in password prompt for multiple retries. See [[Disk encryption#Cryptographic metadata]] for more information.
+
By using a detached header the encrypted blockdevice itself only carries encrypted data, which gives [[Wikipedia:Deniable encryption|deniable encryption]] as long as the existence of a header is unknown to the attackers. It is similar to using [[dm-crypt/Encrypting an entire system#Plain_dm-crypt|plain dm-crypt]], but with the LUKS advantages such as multiple passphrases for the masterkey and key derivation. Further, using a detached header offers a form of two factor authentication with an easier setup than [[#Using GPG, LUKS, or OpenSSL Encrypted Keyfiles|using GPG or OpenSSL encrypted keyfiles]], while still having a built-in password prompt for multiple retries. See [[Disk encryption#Cryptographic metadata]] for more information.
  
See [[Dm-crypt/Device encryption#Encryption options for LUKS mode]] for encryption options before performing the first step to setup the encrypted system partition and creating a header file to use with {{ic|cryptsetup}}:
+
See [[dm-crypt/Device encryption#Encryption options for LUKS mode]] for encryption options before performing the first step to setup the encrypted system partition and creating a header file to use with {{ic|cryptsetup}}:
  # truncate -s 2M header.img
+
 
  # cryptsetup luksFormat /dev/sdX --header header.img
+
  # dd if=/dev/zero of=header.img bs=16M count=1
 +
  # cryptsetup luksFormat /dev/sdX --offset 32768 --header header.img
 +
 
 +
{{Tip|The {{ic|--offset}} option allows specifying the start of encrypted data on a device. By reserving a space at the beginning of device you have the option of later [[dm-crypt/Device encryption#Restore using cryptsetup|reattaching the LUKS header]]. The value is specified in 512-byte sectors, see {{man|8|cryptsetup}} for more details.}}
  
 
Open the container:
 
Open the container:
# cryptsetup open --header header.img --type luks /dev/sdX enc
 
  
Now follow the [[Dm-crypt/Encrypting_an_entire_system#Preparing_the_non-boot_partitions|LVM on LUKS setup]] to your requirements. The same applies for [[Dm-crypt/Encrypting an entire system#Preparing the boot partition 4|preparing the boot partition]] on the removable device (because if not, there is no point in having a separate header file for unlocking the encrypted disk).
+
# cryptsetup open --header header.img /dev/sdX enc
 +
 
 +
Now follow the [[dm-crypt/Encrypting an entire system#Preparing the non-boot partitions|LVM on LUKS setup]] to your requirements. The same applies for [[dm-crypt/Encrypting an entire system#Preparing the boot partition 4|preparing the boot partition]] on the removable device (because if not, there is no point in having a separate header file for unlocking the encrypted disk).
 
Next move the {{ic|header.img}} onto it:
 
Next move the {{ic|header.img}} onto it:
 +
 
  # mv header.img /mnt/boot
 
  # mv header.img /mnt/boot
  
 
Follow the installation procedure up to the mkinitcpio step (you should now be {{ic|arch-chroot}}ed inside the encrypted system).  
 
Follow the installation procedure up to the mkinitcpio step (you should now be {{ic|arch-chroot}}ed inside the encrypted system).  
 +
 +
{{Tip|1=You will notice that since the system partition only has "random" data, it does not have a partition table and by that an {{ic|UUID}} or a {{ic|LABEL}}. But you can still have a consistent mapping using the [[Persistent block device naming#by-id and by-path]]. E.g. using disk id from {{ic|/dev/disk/by-id/}}.}}
  
 
There are two options for initramfs to support a detached LUKS header.
 
There are two options for initramfs to support a detached LUKS header.
  
==== Using systemd hook ====
+
=== Using systemd hook ===
 +
 
 +
First create {{ic|/etc/crypttab.initramfs}} and add the encrypted device to it. The syntax is defined in {{man|5|crypttab}}
  
First create {{ic|/etc/crypttab.initramfs}} and add the encrypted device to it. The syntax is defined in [http://www.freedesktop.org/software/systemd/man/crypttab.html crypttab(5)]
+
{{hc|/etc/crypttab.initramfs|2=
{{hc|/etc/crypttab.initramfs|2=MyStorage    PARTUUID=00000000-0000-0000-0000-000000000000    none   header=/boot/header.img}}
+
enc /dev/disk/by-id/''your-disk_id'' none header=/boot/header.img
 +
}}
  
 
Modify {{ic|/etc/mkinitcpio.conf}} [[Mkinitcpio#Common_hooks|to use systemd]] and add the header to {{ic|FILES}}.
 
Modify {{ic|/etc/mkinitcpio.conf}} [[Mkinitcpio#Common_hooks|to use systemd]] and add the header to {{ic|FILES}}.
  
{{hc|
+
{{hc|/etc/mkinitcpio.conf|2=
/etc/mkinitcpio.conf|2=FILES="'''/boot/header.img'''"
+
...
 
+
FILES=('''/boot/header.img''')
HOOKS="... '''systemd''' ... block '''sd-encrypt''' sd-lvm2 filesystems ..."
+
...
 +
HOOKS=(base '''systemd''' autodetect '''keyboard''' '''sd-vconsole''' modconf block '''sd-encrypt''' '''sd-lvm2''' filesystems fsck)
 +
...
 
}}
 
}}
  
[[Mkinitcpio#Image_creation_and_activation|Recreate the initramfs]] and you are done.
+
[[Regenerate the initramfs]] and you are done.
  
{{Note|No cryptsetup parameters need to be passed to the kernel command line, since{{ic|/etc/crypttab.initramfs}} will be added as {{ic|/etc/crypttab}} in the initramfs. If you wish to specify them in the kernel command line see [http://www.freedesktop.org/software/systemd/man/systemd-cryptsetup-generator.html systemd-cryptsetup-generator(8)] for the supported options.}}
+
{{Note|No cryptsetup parameters need to be passed to the kernel command line, since{{ic|/etc/crypttab.initramfs}} will be added as {{ic|/etc/crypttab}} in the initramfs. If you wish to specify them in the kernel command line see [[dm-crypt/System configuration#Using sd-encrypt hook]] for the supported options.}}
  
====  Modifying encrypt hook ====
+
===  Modifying encrypt hook ===
  
This method shows how to modify the {{ic|encrypt}} hook in order to use a remote LUKS header.  
+
This method shows how to modify the {{ic|encrypt}} hook in order to use a detached LUKS header.  
Now the {{ic|encrypt}} hook has to be modified to let {{ic|cryptsetup}} use the separate header (base source and idea for these changes [https://bbs.archlinux.org/viewtopic.php?pid=1076346#p1076346 published on the BBS]). Make a copy so it is not overwritten on  a [[mkinitcpio]] update:
+
Now the {{ic|encrypt}} hook has to be modified to let {{ic|cryptsetup}} use the separate header ({{Bug|42851}}; base source and idea for these changes [https://bbs.archlinux.org/viewtopic.php?pid=1076346#p1076346 published on the BBS]). Make a copy so it is not overwritten on  a [[mkinitcpio]] update:
  
  # cp /lib/initcpio/hooks/encrypt{,2}
+
  # cp /usr/lib/initcpio/hooks/encrypt /etc/initcpio/hooks/encrypt2
  # cp /usr/lib/initcpio/install/encrypt{,2}
+
  # cp /usr/lib/initcpio/install/encrypt /etc/initcpio/install/encrypt2
  
{{hc|
+
{{hc|/etc/initcpio/hooks/encrypt2 (around line 52)|output=
/lib/initcpio/hooks/encrypt2 (around line 52)|output=warn_deprecated() {
+
warn_deprecated() {
 
     echo "The syntax 'root=${root}' where '${root}' is an encrypted volume is deprecated"
 
     echo "The syntax 'root=${root}' where '${root}' is an encrypted volume is deprecated"
 
     echo "Use 'cryptdevice=${root}:root root=/dev/mapper/root' instead."
 
     echo "Use 'cryptdevice=${root}:root root=/dev/mapper/root' instead."
Line 367: Line 452:
 
}}
 
}}
  
Now edit the [[mkinitcpio|mkinitcpio.conf]] to add the {{ic|encrypt2}} and {{ic|lvm2}} hooks, the {{ic|header.img}} to {{ic|FILES}} and the {{ic|loop}} to {{ic|MODULES}}, apart from other configuration the system requires:
+
Now edit the [[mkinitcpio.conf]] to add the {{ic|encrypt2}} and {{ic|lvm2}} hooks, the {{ic|header.img}} to {{ic|FILES}} and the {{ic|loop}} to {{ic|MODULES}}, apart from other configuration the system requires:
 +
 
 +
{{hc|/etc/mkinitcpio.conf|2=
 +
...
 +
MODULES=('''loop''')
 +
...
 +
FILES=('''/boot/header.img''')
 +
...
 +
HOOKS=(base udev autodetect '''keyboard''' '''keymap''' consolefont modconf block '''encrypt2''' '''lvm2''' filesystems fsck)
 +
...
 +
}}
 +
 
 +
This is required so the LUKS header is available on boot allowing the decryption of the system, exempting us from a more complicated setup to mount another separate USB device in order to access the header. After this set up  [[Mkinitcpio#Image_creation_and_activation|the initramfs]] is created.
 +
 
 +
Next the [[dm-crypt/Encrypting an entire system#Configuring the boot loader 4|boot loader is configured]] to specify the {{ic|1=cryptdevice=}} also passing the new {{ic|header}} option for this setup:
 +
 
 +
cryptdevice=/dev/disk/by-id/''your-disk_id'':enc:header
 +
 
 +
To finish, following [[dm-crypt/Encrypting an entire system#Post-installation]] is particularly useful with a {{ic|/boot}} partition on an USB storage medium.
 +
 
 +
== Encrypted /boot and a detached LUKS header on USB ==
  
{{hc|/etc/mkinitcpio.conf|2=MODULES="'''loop'''"
+
{{Out of date|1=This scenario was based on [https://wiki.archlinux.org/index.php?title=Dm-crypt/Encrypting_an_entire_system&oldid=562642#Encrypted_boot_partition_(GRUB)], whose structure was then changed with [https://wiki.archlinux.org/index.php?title=Dm-crypt/Encrypting_an_entire_system&diff=next&oldid=562642].|section=Encrypted /boot and a detached LUKS header on USB}}
  
FILES="'''/boot/header.img'''"
+
Rather than embedding the {{ic|header.img}} and keyfile into the [[initramfs]] image, this setup will make your system depend entirely on the usb key rather than just the image to boot, and on the encrypted keyfile inside of the encrypted boot partition. Since the header and keyfile are not included in the [[initramfs]] image and the custom encrypt hook is specifically for the usb's [[Persistent_block_device_naming#by-id_and_by-path|by-id]], you will literally need the usb key to boot.
  
HOOKS="... '''encrypt2''' '''lvm2''' ... filesystems ..."}}
+
For the usb drive, since you are encrypting the drive and the keyfile inside, it is preferred to cascade the ciphers as to not use the same one twice. Whether a [[Wikipedia:Meet-in-the-middle_attack|meet-in-the-middle]] attack would actually be feasible is debatable. You can do twofish-serpent or serpent-twofish.
  
This is required so the LUKS header is available on boot allowing the decryption of the system, exempting us from a more complicated setup to mount another separate USB device in order to access the header. After this set up  [[Mkinitcpio#Image_creation_and_activation|the initramfs]] is created.
+
=== Preparing the disk devices ===
 +
 
 +
{{ic|sdb}} will be assumed to be the USB drive, {{ic|sda}} will be assumed to be the main hard drive.
 +
 
 +
Prepare the devices according to [[dm-crypt/Drive preparation]].
 +
 
 +
==== Preparing the USB key ====
 +
 
 +
Use [[gdisk]] to partition the disk according to the layout [[Dm-crypt/Encrypting_an_entire_system#Preparing_the_disk_5|shown here]], with the exception that it should only include the first two partitions. So as follows:
 +
 
 +
{{hc|# gdisk /dev/sdb|
 +
Number  Start (sector)    End (sector)  Size      Code  Name
 +
  1            2048        1050623  512.0 MiB  EF00  EFI System
 +
  2        1050624        1460223  200.0 MiB  8300  Linux filesystem
 +
}}
 +
 
 +
Before running {{ic|cryptsetup}}, look at the [[Dm-crypt/Device_encryption#Encryption_options_for_LUKS_mode|Encryption options for LUKS mode]] and [[Disk_encryption#Ciphers_and_modes_of_operation|Ciphers and modes of operation]] first to select your desired settings.
 +
 
 +
[[Dm-crypt/Encrypting_an_entire_system#Preparing_the_boot_partition_5|Prepare the boot partition]]{{Broken section link}} but do not {{ic|mount}} any partition yet and [[EFI system partition#Format the partition|Format the EFI system partition]].
 +
 
 +
# mount /dev/mapper/cryptboot /mnt
 +
# dd if=/dev/urandom of=/mnt/key.img bs=''filesize'' count=1
 +
# cryptsetup luksFormat /mnt/key.img
 +
# cryptsetup open /mnt/key.img lukskey
 +
 
 +
''filesize'' is in bytes but can be followed by a suffix such as {{ic|M}}. Having too small of a file will get you a nasty {{ic|Requested offset is beyond real size of device /dev/loop0}} error. As a rough reference, creating a 4M file will encrypt it successfully. You should make the file larger than the space needed since the encrypted loop device will be a little smaller than the file's size.
 +
 
 +
With a big file, you can use {{ic|1=--keyfile-offset=''offset''}} and {{ic|1=--keyfile-size=''size''}} to navigate to the correct position. [https://wiki.gentoo.org/wiki/Custom_Initramfs#Encrypted_keyfile]
 +
 
 +
Now you should have {{ic|lukskey}} opened in a loop device (underneath {{ic|/dev/loop1}}), mapped as {{ic|/dev/mapper/lukskey}}.
 +
 
 +
==== The main drive ====
 +
 
 +
# truncate -s 16M /mnt/header.img
 +
# cryptsetup --key-file=/dev/mapper/lukskey --keyfile-offset=''offset'' --keyfile-size=''size'' luksFormat /dev/sda --offset 32768 --header /mnt/header.img
 +
 
 +
Pick an ''offset'' and ''size'' in bytes (8192 bytes is the maximum keyfile size for {{ic|cryptsetup}}).
 +
 
 +
# cryptsetup open --header /mnt/header.img --key-file=/dev/mapper/lukskey --keyfile-offset=''offset'' --keyfile-size=''size'' /dev/sda enc
 +
# cryptsetup close lukskey
 +
# umount /mnt
 +
 
 +
Follow [[Dm-crypt/Encrypting_an_entire_system#Preparing_the_logical_volumes|Preparing the logical volumes]] to set up LVM on LUKS.
 +
 
 +
See [[Partitioning#Discrete partitions]] for recommendations on the size of your partitions.
 +
 
 +
Once your root partition is mounted, {{ic|mount}} your encrypted boot partition as {{ic|/mnt/boot}} and your EFI system partition as {{ic|/mnt/efi}}.
 +
 
 +
=== Installation procedure and custom encrypt hook ===
 +
 
 +
Follow the [[installation guide]] up to the {{ic|mkinitcpio}} step but do not do it yet, and skip the partitioning, formatting, and mounting steps as they have already been done.
 +
 
 +
In order to get the encrypted setup to work, you need to build your own hook, which is thankfully easy to do and here is the code you need. You will have to follow [[Persistent block device naming#by-id and by-path]] to figure out your own {{ic|by-id}} values for the usb and main hard drive (they are linked -> to {{ic|sda}} or {{ic|sdb}}).
 +
 
 +
You should be using the {{ic|by-id}} instead of just {{ic|sda}} or {{ic|sdb}} because {{ic|sdX}} can change and this ensures it is the correct device.
 +
 
 +
You can name {{ic|customencrypthook}} anything you want, and custom build hooks can be placed in the {{ic|hooks}} and {{ic|install}} folders of {{ic|/etc/initcpio}}. Keep a backup of both files ({{ic|cp}} them over to the {{ic|/home}} partition or your user's {{ic|/home}} directory after you make one). {{ic|/usr/bin/ash}} is not a typo.
 +
 
 +
{{hc|/etc/initcpio/hooks/customencrypthook|output=<nowiki>
 +
#!/usr/bin/ash
 +
 
 +
run_hook() {
 +
    modprobe -a -q dm-crypt >/dev/null 2>&1
 +
    modprobe loop
 +
    [ "${quiet}" = "y" ] && CSQUIET=">/dev/null"
 +
 
 +
    while [ ! -L '/dev/disk/by-id/</nowiki>''usbdrive''<nowiki>-part2' ]; do
 +
    echo 'Waiting for USB'
 +
    sleep 1
 +
    done
 +
 
 +
    cryptsetup open /dev/disk/by-id/</nowiki>''usbdrive''<nowiki>-part2 cryptboot
 +
    mkdir -p /mnt
 +
    mount /dev/mapper/cryptboot /mnt
 +
    cryptsetup open /mnt/key.img lukskey
 +
    cryptsetup --header /mnt/header.img --key-file=/dev/mapper/lukskey --keyfile-offset=''offset'' --keyfile-size=''size'' open /dev/disk/by-id/</nowiki>''harddrive''<nowiki> enc
 +
    cryptsetup close lukskey
 +
    umount /mnt
 +
}
 +
</nowiki>}}
 +
 
 +
{{ic|''usbdrive''}} is your USB drive {{ic|by-id}}, and {{ic|''harddrive''}} is your main hard drive {{ic|by-id}}.
 +
 
 +
{{Tip|You could also close {{ic|cryptboot}} using {{ic|cryptsetup close}}, but having it open makes it easier to mount for system updates using [[Pacman]] and regenerating the initramfs with [[mkinitcpio]]. The {{ic|/boot}} partition must be mounted for updates that affect the [[kernel]] or [[Initramfs]], and the initramfs will be automatically regenerated after these updates.}}
 +
 
 +
# cp /usr/lib/initcpio/install/encrypt /etc/initcpio/install/customencrypthook
 +
 
 +
Now edit the copied file and remove the {{ic|help()}} section as it is not necessary.
 +
 
 +
{{hc|/etc/mkinitcpio.conf (edit this only do not replace it, these are just excerpts of the necessary parts)|output=
 +
MODULES=(loop)
 +
...
 +
HOOKS=(base udev autodetect modconf block customencrypthook lvm2 filesystems keyboard fsck)
 +
}}
 +
 
 +
The {{ic|1=files=()}} and {{ic|1=binaries=()}} arrays are empty, and you should not have to replace {{ic|1=HOOKS=(...)}} array entirely just edit in {{ic|customencrypthook lvm2}} after {{ic|block}} and before {{ic|filesystems}}, and make sure {{ic|systemd}}, {{ic|sd-lvm2}}, and {{ic|encrypt}} are removed.
 +
 
 +
==== Boot Loader ====
 +
 
 +
Finish the [[Installation_guide#Initramfs|Installation Guide]] from the {{ic|mkinitcpio}} step. To boot you would need either [[GRUB]] or [[efibootmgr]]. Note you can use [[GRUB]] to support the encrypted disks by [[Dm-crypt/Encrypting_an_entire_system#Configuring_the_boot_loader_6|Configuring the boot loader]]{{Broken section link}} but editing the {{ic|GRUB_CMDLINE_LINUX}} is not necessary for this set up.
 +
 
 +
Or use Direct UEFI Secure boot by generating keys with {{AUR|cryptboot}} then signing the initramfs and kernel and creating a bootable ''.efi'' file for your EFI system partition with {{AUR|sbupdate-git}}. Before using cryptboot or sbupdate note this excerpt from [[Secure Boot#Using your own keys]]:
 +
 
 +
{{Tip|Note that {{AUR|cryptboot}} requires the encrypted boot partition to be specified in {{ic|/etc/crypttab}} before it runs, and if you are using it in combination with {{AUR|sbupdate-git}}, sbupdate expects the {{ic|/boot/efikeys/db.*}} files created by cryptboot to be capitalized like {{ic|DB.*}} unless otherwise configured in {{ic|/etc/default/sbupdate}}. Users who do not use systemd to handle encryption may not have anything in their {{ic|/etc/crypttab}} file and would need to create an entry.
 +
}}
 +
 
 +
# efibootmgr -c -d /dev/''device'' -p ''partition_number'' -L "Arch Linux Signed" -l "EFI\Arch\linux-signed.efi"
 +
 
 +
See {{man|8|efibootmgr}} for an explanation of the options.
 +
 
 +
Make sure the boot order puts {{ic|Arch Linux Signed}} first. If not change it with {{ic|efibootmgr -o XXXX,YYYY,ZZZZ}}.
  
Next the [[Dm-crypt/Encrypting an entire system#Configuring the boot loader 4|boot loader is configured]] to specify the {{ic|1=cryptdevice=}} also passing the new {{ic|header}} option for this setup:
+
=== Changing the LUKS keyfile ===
  
cryptdevice=/dev/sdX:enc:header
+
{{Merge|dm-crypt/Device encryption#Keyfiles|Changing the keyfile is not a required action in this setup.}}
  
To finish, following [[Dm-crypt/Encrypting an entire system#Post-installation]] is particularly useful with a {{ic|/boot}} partition on an USB storage medium.
+
# cryptsetup --header /boot/header.img --key-file=/dev/mapper/lukskey --keyfile-offset=''offset'' --keyfile-size=''size'' luksChangeKey /dev/mapper/enc /dev/mapper/lukskey2 --new-keyfile-size=''newsize'' --new-keyfile-offset=''newoffset''
  
{{Tip|1=You will notice that since the system partition only has "random" data, it does not have a partition table and by that an {{ic|UUID}} or a {{ic|name}}. But you can still have a consistent mapping using the disk id under {{ic|/dev/disk/by-id/}}}}
+
Afterwards, {{ic|cryptsetup close lukskey}} and [[shred]] or [[Securely_wipe_disk#dd|dd]] the old keyfile with random data before deleting it, then make sure that the new keyfile is renamed to the same name of the old one: {{ic|key.img}} or other name.

Latest revision as of 21:12, 24 November 2019

Securing the unencrypted boot partition

The /boot partition and the Master Boot Record are the two areas of the disk that are not encrypted, even in an encrypted root configuration. They cannot usually be encrypted because the boot loader and BIOS (respectively) are unable to unlock a dm-crypt container in order to continue the boot process. An exception is GRUB, which gained a feature to unlock a LUKS encrypted /boot - see dm-crypt/Encrypting an entire system#Encrypted boot partition (GRUB).

This section describes steps that can be taken to make the boot process more secure.

Warning: Note that securing the /boot partition and MBR can mitigate numerous attacks that occur during the boot process, but systems configured this way may still be vulnerable to BIOS/UEFI/firmware tampering, hardware keyloggers, cold boot attacks, and many other threats that are beyond the scope of this article. For an overview of system-trust issues and how these relate to full-disk encryption, refer to [1].

Booting from a removable device

Warning: systemd version 230 cryptsetup generator emits RequiresMountsFor for crypto keyfile. Therefore, when the filesystem that holds this file is unmounted, it also stops cryptsetup service. This behavior is incorrect because the filesystem and cryptokey is required only once, when the crypto container is initially setup. See systemd issue 3816.

Using a separate device to boot a system is a fairly straightforward procedure, and offers a significant security improvement against some kinds of attacks. Two vulnerable parts of a system employing an encrypted root filesystem are

These must be stored unencrypted in order for the system to boot. In order to protect these from tampering, it is advisable to store them on a removable medium, such as a USB drive, and boot from that drive instead of the hard disk. As long as you keep the drive with you at all times, you can be certain that those components have not been tampered with, making authentication far more secure when unlocking your system.

It is assumed that you already have your system configured with a dedicated partition mounted at /boot. If you do not, please follow the steps in dm-crypt/System configuration#Boot loader, substituting your hard disk for a removable drive.

Note: You must make sure your system supports booting from the chosen medium, be it a USB drive, an external hard drive, an SD card, or anything else.

Prepare the removable drive (/dev/sdx).

# gdisk /dev/sdx #format if necessary. Alternatively, cgdisk, fdisk, cfdisk, gparted...
# mkfs.ext2 /dev/sdx1
# mount /dev/sdx1 /mnt

Copy your existing /boot contents to the new one.

# cp -ai /boot/* /mnt/

Mount the new partition. Do not forget to update your fstab file accordingly.

# umount /boot
# umount /mnt
# mount /dev/sdx1 /boot
# genfstab -p -U / > /etc/fstab

Update GRUB. grub-mkconfig should detect the new partition UUID automatically, but custom menu entries may need to be updated manually.

# grub-mkconfig -o /boot/grub/grub.cfg
# grub-install /dev/sdx #install to the removable device, not the hard disk.

Reboot and test the new configuration. Remember to set your device boot order accordingly in your BIOS or UEFI. If the system fails to boot, you should still be able to boot from the hard drive in order to correct the problem.

chkboot

Warning: chkboot makes a /boot partition tamper-evident, not tamper-proof. By the time the chkboot script is run, you have already typed your password into a potentially compromised boot loader, kernel, or initrd. If your system fails the chkboot integrity test, no assumptions can be made about the security of your data.

Referring to an article from the ct-magazine (Issue 3/12, page 146, 01.16.2012, [2]) the following script checks files under /boot for changes of SHA-1 hash, inode, and occupied blocks on the hard drive. It also checks the Master Boot Record. The script cannot prevent certain type of attacks, but a lot are made harder. No configuration of the script itself is stored in unencrypted /boot. With a locked/powered-off encrypted system, this makes it harder for some attackers because it is not apparent that an automatic checksum comparison of the partition is done upon boot. However, an attacker who anticipates these precautions can manipulate the firmware to run his own code on top of your kernel and intercept file system access, e.g. to boot, and present the untampered files. Generally, no security measures below the level of the firmware are able to guarantee trust and tamper evidence.

The script with installation instructions is available (Author: Juergen Schmidt, ju at heisec.de; License: GPLv2). There is also package chkbootAUR to install.

After installation add a service file (the package includes one based on the following) and enable it:

[Unit]
Description=Check that boot is what we want
Requires=basic.target
After=basic.target

[Service]
Type=oneshot
ExecStart=/usr/local/bin/chkboot.sh

[Install]
WantedBy=multi-user.target

There is a small caveat for systemd. At the time of writing, the original chkboot.sh script provided contains an empty space at the beginning of #!/bin/bash which has to be removed for the service to start successfully.

As /usr/local/bin/chkboot_user.sh needs to be executed right after login, you need to add it to the autostart (e.g. under KDE -> System Settings -> Startup and Shutdown -> Autostart; GNOME 3: gnome-session-properties).

With Arch Linux, changes to /boot are pretty frequent, for example by new kernels rolling-in. Therefore it may be helpful to use the scripts with every full system update. One way to do so:

#!/bin/bash
#
# Note: Insert your <user>  and execute it with sudo for pacman & chkboot to work automagically
#
echo "Pacman update [1] Quickcheck before updating" & 
sudo -u <user> /usr/local/bin/chkboot_user.sh		# insert your logged on <user> 
/usr/local/bin/chkboot.sh
sudo -u <user> /usr/local/bin/chkboot_user.sh		# insert your logged on <user> 
echo "Pacman update [2] Syncing repos for pacman" 
pacman -Syu
/usr/local/bin/chkboot.sh
sudo -u <user> /usr/local/bin/chkboot_user.sh		# insert your logged on <user>
echo "Pacman update [3] All done, let us roll on ..."

mkinitcpio-chkcryptoboot

Warning: This hook does not encrypt GRUB's core (MBR) code or EFI stub, nor does it protect against situations where an attacker is able to modify the behaviour of the bootloader to compromise the kernel and/or initramfs at run-time.

mkinitcpio-chkcryptobootAUR is a mkinitcpio hook that performs integrity checks during early-userspace and advises the user not to enter his root partition password if the system appears to have been compromised. Security is achieved through an encrypted boot partition, which is unlocked using GRUB's cryptodisk.mod module, and a root filesystem partition, which is encrypted with a password different from the former. This way, the initramfs and kernel are secured against offline tampering, and the root partition can remain secure even if the /boot partition password is entered on a compromised machine (provided that the chkcryptoboot hook detects the compromise, and is not itself compromised at run-time).

This hook requires grub release >=2.00 to function, and a dedicated, LUKS encrypted /boot partition with its own password in order to be secure.

Installation

Install mkinitcpio-chkcryptobootAUR and edit /etc/default/chkcryptoboot.conf. If you want the ability of detecting if your boot partition was bypassed, edit the CMDLINE_NAME and CMDLINE_VALUE variables, with values known only to you. You can follow the advice of using two hashes as is suggested right after the installation. Also, be sure to make the appropriate changes to the kernel command line in /etc/default/grub. Edit the HOOKS= line in /etc/mkinitcpio.conf, and insert the chkcryptoboot hook before encrypt. When finished, regenerate the initramfs.

Technical Overview

mkinitcpio-chkcryptobootAUR consists of an install hook and a run-time hook for mkinitcpio. The install hook runs every time the initramfs is rebuilt, and hashes the GRUB EFI stub ($esp/EFI/grub_uefi/grubx64.efi) (in the case of UEFI systems) or the first 446 bytes of the disk on which GRUB is installed (in the case of BIOS systems), and stores that hash inside the initramfs located inside the encrypted /boot partition. When the system is booted, GRUB prompts for the /boot password, then the run-time hook performs the same hashing operation and compares the resulting hashes before prompting for the root partition password. If they do not match, the hook will print an error like this:

CHKCRYPTOBOOT ALERT!
CHANGES HAVE BEEN DETECTED IN YOUR BOOT LOADER EFISTUB!
YOU ARE STRONGLY ADVISED NOT TO ENTER YOUR ROOT CONTAINER PASSWORD!
Please type uppercase yes to continue:

In addition to hashing the boot loader, the hook also checks the parameters of the running kernel against those configured in /etc/default/chkcryptoboot.conf. This is checked both at run-time and after the boot process is done. This allows the hook to detect if GRUB's configuration was not bypassed at run-time and afterwards to detect if the entire /boot partition was not bypassed.

For BIOS systems the hook creates a hash of GRUB's first stage bootloader (installed to the first 446 bytes of the bootdevice) to compare at the later boot processes. The main second-stage GRUB bootloader core.img is not checked.

AIDE

Alternatively to above scripts, a hash check can be set up with AIDE which can be customized via a very flexible configuration file.

STARK

While one of these methods should serve the purpose for most users, they do not address all security problems associated with the unencrypted /boot. One approach which endeavours to provide a fully authenticated boot chain was published with POTTS as an academic thesis to implement the STARK authentication framework.

The POTTS proof-of-concept uses Arch Linux as a base distribution and implements a system boot chain with:

  • POTTS - a boot menu for a one-time authentication message prompt
  • TrustedGrub - a GRUB Legacy implementation which authenticates the kernel and initramfs against TPM chip PCR registers
  • TRESOR - a kernel patch which implements AES but keeps the master-key not in RAM but in CPU registers during runtime.

As part of the thesis installation instructions based on Arch Linux (ISO as of 2013-01) have been published. If you want to try it, be aware these tools are not in standard repositories and the solution will be time consuming to maintain.

Using GPG, LUKS, or OpenSSL Encrypted Keyfiles

The following forum posts give instructions to use two factor authentication, gpg or openssl encrypted keyfiles, instead of a plaintext keyfile described earlier in this wiki article System Encryption using LUKS with GPG encrypted keys:

Note that:

  • You can follow the above instructions with only two primary partitions, one boot partition (required because of encryption) and one primary LVM partition. Within the LVM partition you can have as many partitions as you need, but most importantly it should contain at least root, swap, and home logical volume partitions. This has the added benefit of having only one keyfile for all your partitions, and having the ability to hibernate your computer (suspend to disk) where the swap partition is encrypted. If you decide to do so your hooks in /etc/mkinitcpio.conf should look like this:
    HOOKS=( ... usb usbinput (etwo or ssldec) encrypt (if using openssl) lvm2 resume ... )
    and you should add
    resume=/dev/<VolumeGroupName>/<LVNameOfSwap>
    to your kernel parameters.
  • If you need to temporarily store the unencrypted keyfile somewhere, do not store them on an unencrypted disk. Even better make sure to store them to RAM such as /dev/shm.
  • If you want to use a GPG encrypted keyfile, you need to use a statically compiled GnuPG version 1.4 or you could edit the hooks and use this AUR package gnupg1AUR
  • It is possible that an update to OpenSSL could break the custom ssldec mentioned in the second forum post.

Remote unlocking of the root (or other) partition

If you want to be able to reboot a fully LUKS-encrypted system remotely, or start it with a Wake-on-LAN service, you will need a way to enter a passphrase for the root partition/volume at startup. This can be achieved by running a mkinitcpio hook that configures a network interface. Some packages listed below contribute various mkinitcpio build hooks to ease with the configuration.

Note:
  • Keep in mind to use kernel device names for the network interface (e.g. eth0) and not udev's ones (e.g. enp1s0), as those will not work.
  • By default, Predictable Network Interface Names are activated and change the kernel device name during late boot. Use dmesg and look what your Network kernel module does to find the original name (e.g. eth0)
  • It could be necessary to add the module for your network card to the MODULES array.

Remote unlocking (hooks: systemd, systemd-tool)

AUR package mkinitcpio-systemd-toolAUR provides a systemd-centric mkinitcpio hook named systemd-tool with the following set of features for systemd in initramfs:

Core features provided by the hook:

  • unified systemd + mkinitcpio configuration
  • automatic provisioning of binary and config resources
  • on-demand invocation of mkinitcpio scripts and in-line functions

Features provided by the included service units:

  • initrd debugging
  • early network setup
  • interactive user shell
  • remote ssh access in initrd
  • cryptsetup + custom password agent

The mkinitcpio-systemd-toolAUR package requires the systemd hook. For more information be sure to read the project's README as well as the provided default systemd service unit files to get you started.

The recommended hooks are: base autodetect modconf block filesystems keyboard fsck systemd systemd-tool.

Remote unlocking (hooks: netconf, dropbear, tinyssh, ppp)

Another package combination providing remote logins to the initcpio is mkinitcpio-netconf and/or mkinitcpio-pppAUR (for remote unlocking using a PPP connection over the internet) along with an SSH server. You have the option of using either mkinitcpio-dropbear or mkinitcpio-tinyssh. Those hooks do not install any shell, so you also need to install the mkinitcpio-utils package. The instructions below can be used in any combination of the packages above. When there are different paths, it will be noted.

  1. If you do not have an SSH key pair yet, generate one on the client system (the one which will be used to unlock the remote machine).
    Note: tinyssh only supports Ed25519 and ECDSA key types. If you chose to use mkinitcpio-tinyssh, you need to create/use one of these.
    Note: mkinitcpio-dropbear in version 0.0.3-5 is not compatible with the current dropbear implementation that removed dss. See Github for details and a fix.
  2. Insert your SSH public key (i.e. the one you usually put onto hosts so that you can ssh in without a password, or the one you just created and which ends with .pub) into the remote machine's /etc/dropbear/root_key or /etc/tinyssh/root_key file.
    Tip: This method can later be used to add other SSH public keys as needed; In the case of simply copying the content of the remote's ~/.ssh/authorized_keys, be sure to verify that it only contains keys you intend to be using to unlock the remote machine. When adding additional keys, regenerate your initrd as well using mkinitcpio. See also OpenSSH#Protection.
  3. Add all three <netconf and/or ppp> <dropbear or tinyssh> encryptssh hooks before filesystems within the "HOOKS" array in /etc/mkinitcpio.conf (the encryptssh replaces the encrypt hook). Then regenerate the initramfs.
    Note: The net hook provided by mkinitcpio-nfs-utils is not needed.
    Note: If you experience the error libgcc_s.so.1 must be installed for pthread_cancel to work when trying to decrypt, you need to add /usr/lib/libgcc_s.so.1 to the "BINARIES" array.
  4. Configure the required cryptdevice= parameter and add the ip= kernel command parameter to your bootloader configuration with the appropriate arguments. For example, if the DHCP server does not attribute a static IP to your remote system, making it difficult to access via SSH across reboots, you can explicitly state the IP you want to be using:
    ip=192.168.1.1:::::eth0:none
    Alternatively, you can also specify the subnet mask and gateway required by the network:
    ip=192.168.1.1::192.168.1.254:255.255.255.0::eth0:none
    Note: As of version 0.0.4 of mkinitcpio-netconf, you can nest multiple ip= parameters in order to configure multiple interfaces. You cannot mix it with ip=dhcp (ip=:::::eth0:dhcp) alone. An interface needs to be specified.
    ip=ip=192.168.1.1:::::eth0:none:ip=172.16.1.1:::::eth1:none
    For a detailed description have a look at the according mkinitcpio section. When finished, update the configuration of your bootloader.
  5. Finally, restart the remote system and try to ssh to it, explicitly stating the "root" username (even if the root account is disabled on the machine, this root user is used only in the initrd for the purpose of unlocking the remote system). If you are using the mkinitcpio-dropbear package and you also have the openssh package installed, then you most probably will not get any warnings before logging in, because it convert and use the same host keys openssh uses (except Ed25519 keys, as dropbear does not support them). In case you are using mkinitcpio-tinyssh, you have the option of installing tinyssh-convert or tinyssh-convert-gitAUR so you can use the same keys as your openssh installation (currently only Ed25519 keys). In either case, you should have run the ssh daemon at least once, using the provided systemd units, so the keys can be generated first. After rebooting the machine, you should be prompted for the passphrase to unlock the root device. The system will complete its boot process and you can then ssh to it as you normally would (with the remote user of your choice).
Tip: If you would simply like a nice solution to mount other encrypted partitions (such as /home) remotely, you may want to look at this forum thread.

Remote unlock via wifi

The net hook is normally used with an ethernet connection. In case you want to setup a computer with wireless only, and unlock it via wifi, you can use a predefined hook or create a custom hook to connect to a wifi network before the net hook is run.

Predefined hook

You can install a predefined hook based on the one in this wiki:

  1. Install mkinitcpio-wifiAUR.
  2. Configure your wifi connection by creating a wpa_supplicant configuration with your network properties:
    wpa_passphrase "ESSID" "passphrase" > /etc/wpa_supplicant/initcpio.conf
  3. Add the wifi hook before netconf in your /etc/mkinitcpio.conf. Your wifi-related modules should be autodetected, if not: add them to the MODULES section.
  4. Add ip=:::::wlan0:dhcp to the kernel parameters.
  5. Regenerate the initramfs.
  6. Update the configuration of your boot loader.

Build your own

Below example shows a setup using a usb wifi adapter, connecting to a wifi network protected with WPA2-PSK. In case you use for example WEP or another boot loader, you might need to change some things.

  1. Modify /etc/mkinitcpio.conf:
    • Add the needed kernel module for your specific wifi adatper.
    • Include the wpa_passphrase and wpa_supplicant binaries.
    • Add a hook wifi (or a name of your choice, this is the custom hook that will be created) before the net hook.
      MODULES=(module)
      BINARIES=(wpa_passphrase wpa_supplicant)
      HOOKS=(base udev autodetect ... wifi net ... dropbear encryptssh ...)
  2. Create the wifi hook in /etc/initcpio/hooks/wifi:
    run_hook ()
    {
    # sleep a couple of seconds so wlan0 is setup by kernel
    sleep 5

    # set wlan0 to up
    ip link set wlan0 up

    # assocciate with wifi network
    # 1. save temp config file
    wpa_passphrase "network ESSID" "pass phrase" > /tmp/wifi

    # 2. assocciate
    wpa_supplicant -B -D nl80211,wext -i wlan0 -c /tmp/wifi

    # sleep a couple of seconds so that wpa_supplicant finishes connecting
    sleep 5

    # wlan0 should now be connected and ready to be assigned an ip by the net hook
    }

    run_cleanuphook ()
    {
    # kill wpa_supplicant running in the background
    killall wpa_supplicant

    # set wlan0 link down
    ip link set wlan0 down

    # wlan0 should now be fully disconnected from the wifi network
    }
  3. Create the hook installation file in /etc/initcpio/install/wifi:
    build ()
    {
    add_runscript
    }
    help ()
    {
    cat<<HELPEOF
    Enables wifi on boot, for dropbear ssh unlocking of disk.
    HELPEOF
    }
  4. Add ip=:::::wlan0:dhcp to the kernel parameters. Remove ip=:::::eth0:dhcp so it does not conflict.
  5. Optionally create an additional boot entry with kernel parameter ip=:::::eth0:dhcp.
  6. Regenerate the initramfs.
  7. Update the configuration of your boot loader.

Remember to setup wifi, so you are able to login once the system is fully booted. In case you are unable to connect to the wifi network, try increasing the sleep times a bit.

Discard/TRIM support for solid state drives (SSD)

Solid state drive users should be aware that, by default, TRIM commands are not enabled by the device-mapper, i.e. block-devices are mounted without the discard option unless you override the default.

The device-mapper maintainers have made it clear that TRIM support will never be enabled by default on dm-crypt devices because of the potential security implications.[3][4] Minimal data leakage in the form of freed block information, perhaps sufficient to determine the filesystem in use, may occur on devices with TRIM enabled. An illustration and discussion of the issues arising from activating TRIM is available in the blog of a cryptsetup developer. If you are worried about such factors, keep also in mind that threats may add up: for example, if your device is still encrypted with the previous (cryptsetup <1.6.0) default cipher --cipher aes-cbc-essiv, more information leakage may occur from trimmed sector observation than with the current default.

The following cases can be distinguished:

  • The device is encrypted with default dm-crypt LUKS mode:
    • By default the LUKS header is stored at the beginning of the device and using TRIM is useful to protect header modifications. If for example a compromised LUKS password is revoked, without TRIM the old header will in general still be available for reading until overwritten by another operation; if the drive is stolen in the meanwhile, the attackers could in theory find a way to locate the old header and use it to decrypt the content with the compromised password. See cryptsetup FAQ, section 5.19 What about SSDs, Flash and Hybrid Drives? and Full disk encryption on an ssd.
    • TRIM can be left disabled if the security issues stated at the top of this section are considered a worse threat than the above bullet.
See also Securely wipe disk#Flash memory.
  • The device is encrypted with dm-crypt plain mode, or the LUKS header is stored separately:
    • If plausible deniability is required, TRIM should never be used because of the considerations at the top of this section, or the use of encryption will be given away.
    • If plausible deniability is not required, TRIM can be used for its performance gains, provided that the security dangers described at the top of this section are not of concern.
Warning: Before enabling TRIM on a drive, make sure the device fully supports TRIM commands, or data loss can occur. See Solid State Drives#TRIM.

In linux 3.1 and up, support for dm-crypt TRIM pass-through can be toggled upon device creation or mount with dmsetup. Support for this option also exists in cryptsetup version 1.4.0 and up. To add support during boot, you will need to add :allow-discards to the cryptdevice option. The TRIM option may look like this:

cryptdevice=/dev/sdaX:root:allow-discards

For the main cryptdevice configuration options before the :allow-discards see Dm-crypt/System configuration.

If you are using a systemd based initrd, you must pass:

rd.luks.options=discard
Note: The rd.luks.options=discard kernel option does not have any effect on devices included in the initramfs image's /etc/crypttab file (/etc/crypttab.initramfs on real root). You must specify option discard in /etc/crypttab.initramfs.

Besides the kernel option, it is also required to periodically run fstrim or mount the filesystem (e.g. /dev/mapper/root in this example) with the discard option in /etc/fstab. For details, please refer to the TRIM page.

For LUKS devices unlocked via /etc/crypttab use option discard, e.g.:

/etc/crypttab
luks-123abcdef-etc UUID=123abcdef-etc none discard

When manually unlocking devices on the console use --allow-discards.

With LUKS2 you can set allow-discards as a default flag for a device by opening it once with the option --persistent:

# cryptsetup --allow-discards --persistent open /dev/sdaX root

When the device is already opened, the open action will raise an error. You can use the refresh option in these cases, e.g.:

# cryptsetup --allow-discards --persistent refresh /dev/sdaX

You can confirm the flag is persistently set in the LUKS2 header by looking at the cryptsetup luksDump output:

# cryptsetup luksDump /dev/sdaX | grep Flags
Flags:          allow-discards

In any case, you can verify whether the device actually was opened with discards by inspecting the dmsetup table output:

# dmsetup table
luks-123abcdef-etc: 0 1234567 crypt aes-xts-plain64 000etc000 0 8:2 4096 1 allow_discards

The encrypt hook and multiple disks

Tip: sd-encrypt hook supports unlocking multiple devices. They can be specified on the kernel command line or in /etc/crypttab.initramfs. See dm-crypt/System configuration#Using sd-encrypt hook.

The encrypt hook only allows for a single cryptdevice= entry (FS#23182). In system setups with multiple drives this may be limiting, because dm-crypt has no feature to exceed the physical device. For example, take "LVM on LUKS": The entire LVM exists inside a LUKS mapper. This is perfectly fine for a single-drive system, since there is only one device to decrypt. But what happens when you want to increase the size of the LVM? You cannot, at least not without modifying the encrypt hook.

The following sections briefly show alternatives to overcome the limitation. The first deals with how to expand a LUKS on LVM setup to a new disk. The second with modifying the encrypt hook to unlock multiple disks in LUKS setups without LVM.

Expanding LVM on multiple disks

The management of multiple disks is a basic LVM feature and a major reason for its partitioning flexibility. It can also be used with dm-crypt, but only if LVM is employed as the first mapper. In such a LUKS on LVM setup the encrypted devices are created inside the logical volumes (with a separate passphrase/key per volume). The following covers the steps to expand that setup to another disk.

Warning: Back up! While resizing filesystems may be standard, keep in mind that operations may go wrong and the following might not apply to a particular setup. Generally, extending a filesystem to free disk space is less problematic than shrinking one. This in particular applies when stacked mappers are used, as it is the case in the following example.

Adding a new drive

First, it may be desired to prepare a new disk according to dm-crypt/Drive preparation. Second, it is partitioned as a LVM, e.g. all space is allocated to /dev/sdY1 with partition type 8E00 (Linux LVM). Third, the new disk/partition is attached to the existing LVM volume group, e.g.:

# pvcreate /dev/sdY1
# vgextend MyStorage /dev/sdY1

Extending the logical volume

For the next step, the final allocation of the new diskspace, the logical volume to be extended has to be unmounted. It can be performed for the cryptdevice root partition, but in this case the procedure has to be performed from an Arch Install ISO.

In this example, it is assumed that the logical volume for /home (lv-name homevol) is going to be expanded with the fresh disk space:

# umount /home
# fsck /dev/mapper/home
# cryptsetup luksClose /dev/mapper/home
# lvextend -l +100%FREE MyStorage/homevol

Now the logical volume is extended and the LUKS container comes next:

# cryptsetup open /dev/MyStorage/homevol home
# umount /home      # as a safety, in case it was automatically remounted
# cryptsetup --verbose resize home

Finally, the filesystem itself is resized:

# e2fsck -f /dev/mapper/home
# resize2fs /dev/mapper/home

Done! If it went to plan, /home can be remounted and now includes the span to the new disk:

# mount /dev/mapper/home /home

Note that the cryptsetup resize action does not affect encryption keys, and these have not changed.

Modifying the encrypt hook for multiple partitions

Root filesystem spanning multiple partitions

It is possible to modify the encrypt hook to allow multiple hard drive decrypt root (/) at boot. One way:

# cp /usr/lib/initcpio/install/encrypt /etc/initcpio/install/encrypt2
# cp /usr/lib/initcpio/hooks/encrypt  /etc/initcpio/hooks/encrypt2
# sed -i "s/cryptdevice/cryptdevice2/" /etc/initcpio/hooks/encrypt2
# sed -i "s/cryptkey/cryptkey2/" /etc/initcpio/hooks/encrypt2

Add cryptdevice2= to your boot options (and cryptkey2= if needed), and add the encrypt2 hook to your mkinitcpio.conf before rebuilding it. See dm-crypt/System configuration.

Multiple non-root partitions

Maybe you have a requirement for using the encrypt hook on a non-root partition. Arch does not support this out of the box, however, you can easily change the cryptdev and cryptname values in /lib/initcpio/hooks/encrypt (the first one to your /dev/sd* partition, the second to the name you want to attribute). That should be enough.

The big advantage is you can have everything automated, while setting up /etc/crypttab with an external key file (i.e. the keyfile is not on any internal hard drive partition) can be a pain - you need to make sure the USB/FireWire/... device gets mounted before the encrypted partition, which means you have to change the order of /etc/fstab (at least).

Of course, if the cryptsetup package gets upgraded, you will have to change this script again. Unlike /etc/crypttab, only one partition is supported, but with some further hacking one should be able to have multiple partitions unlocked.

Tango-inaccurate.pngThe factual accuracy of this article or section is disputed.Tango-inaccurate.png

Reason: Why not use the supported Grub2 right away? See also mkinitcpio#Using RAID (Discuss in Talk:Dm-crypt/Specialties#)

If you want to do this on a software RAID partition, there is one more thing you need to do. Just setting the /dev/mdX device in /lib/initcpio/hooks/encrypt is not enough; the encrypt hook will fail to find the key for some reason, and not prompt for a passphrase either. It looks like the RAID devices are not brought up until after the encrypt hook is run. You can solve this by putting the RAID array in /boot/grub/menu.lst, like

kernel /boot/vmlinuz-linux md=1,/dev/hda5,/dev/hdb5

If you set up your root partition as a RAID, you will notice the similarities with that setup. GRUB can handle multiple array definitions just fine:

kernel /boot/vmlinuz-linux root=/dev/md0 ro md=0,/dev/sda1,/dev/sdb1 md=1,/dev/sda5,/dev/sdb5,/dev/sdc5

Encrypted system using a detached LUKS header

This example follows the same setup as in dm-crypt/Encrypting an entire system#Plain dm-crypt, which should be read first before following this guide.

By using a detached header the encrypted blockdevice itself only carries encrypted data, which gives deniable encryption as long as the existence of a header is unknown to the attackers. It is similar to using plain dm-crypt, but with the LUKS advantages such as multiple passphrases for the masterkey and key derivation. Further, using a detached header offers a form of two factor authentication with an easier setup than using GPG or OpenSSL encrypted keyfiles, while still having a built-in password prompt for multiple retries. See Disk encryption#Cryptographic metadata for more information.

See dm-crypt/Device encryption#Encryption options for LUKS mode for encryption options before performing the first step to setup the encrypted system partition and creating a header file to use with cryptsetup:

# dd if=/dev/zero of=header.img bs=16M count=1
# cryptsetup luksFormat /dev/sdX --offset 32768 --header header.img
Tip: The --offset option allows specifying the start of encrypted data on a device. By reserving a space at the beginning of device you have the option of later reattaching the LUKS header. The value is specified in 512-byte sectors, see cryptsetup(8) for more details.

Open the container:

# cryptsetup open --header header.img /dev/sdX enc

Now follow the LVM on LUKS setup to your requirements. The same applies for preparing the boot partition on the removable device (because if not, there is no point in having a separate header file for unlocking the encrypted disk). Next move the header.img onto it:

# mv header.img /mnt/boot

Follow the installation procedure up to the mkinitcpio step (you should now be arch-chrooted inside the encrypted system).

Tip: You will notice that since the system partition only has "random" data, it does not have a partition table and by that an UUID or a LABEL. But you can still have a consistent mapping using the Persistent block device naming#by-id and by-path. E.g. using disk id from /dev/disk/by-id/.

There are two options for initramfs to support a detached LUKS header.

Using systemd hook

First create /etc/crypttab.initramfs and add the encrypted device to it. The syntax is defined in crypttab(5)

/etc/crypttab.initramfs
enc	/dev/disk/by-id/your-disk_id	none	header=/boot/header.img

Modify /etc/mkinitcpio.conf to use systemd and add the header to FILES.

/etc/mkinitcpio.conf
...
FILES=(/boot/header.img)
...
HOOKS=(base systemd autodetect keyboard sd-vconsole modconf block sd-encrypt sd-lvm2 filesystems fsck)
...

Regenerate the initramfs and you are done.

Note: No cryptsetup parameters need to be passed to the kernel command line, since/etc/crypttab.initramfs will be added as /etc/crypttab in the initramfs. If you wish to specify them in the kernel command line see dm-crypt/System configuration#Using sd-encrypt hook for the supported options.

Modifying encrypt hook

This method shows how to modify the encrypt hook in order to use a detached LUKS header. Now the encrypt hook has to be modified to let cryptsetup use the separate header (FS#42851; base source and idea for these changes published on the BBS). Make a copy so it is not overwritten on a mkinitcpio update:

# cp /usr/lib/initcpio/hooks/encrypt /etc/initcpio/hooks/encrypt2
# cp /usr/lib/initcpio/install/encrypt /etc/initcpio/install/encrypt2
/etc/initcpio/hooks/encrypt2 (around line 52)
warn_deprecated() {
    echo "The syntax 'root=${root}' where '${root}' is an encrypted volume is deprecated"
    echo "Use 'cryptdevice=${root}:root root=/dev/mapper/root' instead."
}

local headerFlag=false
for cryptopt in ${cryptoptions//,/ }; do
    case ${cryptopt} in
        allow-discards)
            cryptargs="${cryptargs} --allow-discards"
            ;;  
        header)
            cryptargs="${cryptargs} --header /boot/header.img"
            headerFlag=true
            ;;
        *)  
            echo "Encryption option '${cryptopt}' not known, ignoring." >&2 
            ;;  
    esac
done

if resolved=$(resolve_device "${cryptdev}" ${rootdelay}); then
    if $headerFlag || cryptsetup isLuks ${resolved} >/dev/null 2>&1; then
        [ ${DEPRECATED_CRYPT} -eq 1 ] && warn_deprecated
        dopassphrase=1

Now edit the mkinitcpio.conf to add the encrypt2 and lvm2 hooks, the header.img to FILES and the loop to MODULES, apart from other configuration the system requires:

/etc/mkinitcpio.conf
...
MODULES=(loop)
...
FILES=(/boot/header.img)
...
HOOKS=(base udev autodetect keyboard keymap consolefont modconf block encrypt2 lvm2 filesystems fsck)
...

This is required so the LUKS header is available on boot allowing the decryption of the system, exempting us from a more complicated setup to mount another separate USB device in order to access the header. After this set up the initramfs is created.

Next the boot loader is configured to specify the cryptdevice= also passing the new header option for this setup:

cryptdevice=/dev/disk/by-id/your-disk_id:enc:header

To finish, following dm-crypt/Encrypting an entire system#Post-installation is particularly useful with a /boot partition on an USB storage medium.

Encrypted /boot and a detached LUKS header on USB

Tango-view-refresh-red.pngThis article or section is out of date.Tango-view-refresh-red.png

Reason: This scenario was based on [5], whose structure was then changed with [6]. (Discuss in Talk:Dm-crypt/Specialties#Encrypted /boot and a detached LUKS header on USB)

Rather than embedding the header.img and keyfile into the initramfs image, this setup will make your system depend entirely on the usb key rather than just the image to boot, and on the encrypted keyfile inside of the encrypted boot partition. Since the header and keyfile are not included in the initramfs image and the custom encrypt hook is specifically for the usb's by-id, you will literally need the usb key to boot.

For the usb drive, since you are encrypting the drive and the keyfile inside, it is preferred to cascade the ciphers as to not use the same one twice. Whether a meet-in-the-middle attack would actually be feasible is debatable. You can do twofish-serpent or serpent-twofish.

Preparing the disk devices

sdb will be assumed to be the USB drive, sda will be assumed to be the main hard drive.

Prepare the devices according to dm-crypt/Drive preparation.

Preparing the USB key

Use gdisk to partition the disk according to the layout shown here, with the exception that it should only include the first two partitions. So as follows:

# gdisk /dev/sdb
Number  Start (sector)    End (sector)  Size       Code  Name
   1            2048         1050623   512.0 MiB   EF00  EFI System
   2         1050624         1460223   200.0 MiB   8300  Linux filesystem

Before running cryptsetup, look at the Encryption options for LUKS mode and Ciphers and modes of operation first to select your desired settings.

Prepare the boot partition[broken link: invalid section] but do not mount any partition yet and Format the EFI system partition.

# mount /dev/mapper/cryptboot /mnt
# dd if=/dev/urandom of=/mnt/key.img bs=filesize count=1
# cryptsetup luksFormat /mnt/key.img
# cryptsetup open /mnt/key.img lukskey

filesize is in bytes but can be followed by a suffix such as M. Having too small of a file will get you a nasty Requested offset is beyond real size of device /dev/loop0 error. As a rough reference, creating a 4M file will encrypt it successfully. You should make the file larger than the space needed since the encrypted loop device will be a little smaller than the file's size.

With a big file, you can use --keyfile-offset=offset and --keyfile-size=size to navigate to the correct position. [7]

Now you should have lukskey opened in a loop device (underneath /dev/loop1), mapped as /dev/mapper/lukskey.

The main drive

# truncate -s 16M /mnt/header.img
# cryptsetup --key-file=/dev/mapper/lukskey --keyfile-offset=offset --keyfile-size=size luksFormat /dev/sda --offset 32768 --header /mnt/header.img

Pick an offset and size in bytes (8192 bytes is the maximum keyfile size for cryptsetup).

# cryptsetup open --header /mnt/header.img --key-file=/dev/mapper/lukskey --keyfile-offset=offset --keyfile-size=size /dev/sda enc 
# cryptsetup close lukskey
# umount /mnt

Follow Preparing the logical volumes to set up LVM on LUKS.

See Partitioning#Discrete partitions for recommendations on the size of your partitions.

Once your root partition is mounted, mount your encrypted boot partition as /mnt/boot and your EFI system partition as /mnt/efi.

Installation procedure and custom encrypt hook

Follow the installation guide up to the mkinitcpio step but do not do it yet, and skip the partitioning, formatting, and mounting steps as they have already been done.

In order to get the encrypted setup to work, you need to build your own hook, which is thankfully easy to do and here is the code you need. You will have to follow Persistent block device naming#by-id and by-path to figure out your own by-id values for the usb and main hard drive (they are linked -> to sda or sdb).

You should be using the by-id instead of just sda or sdb because sdX can change and this ensures it is the correct device.

You can name customencrypthook anything you want, and custom build hooks can be placed in the hooks and install folders of /etc/initcpio. Keep a backup of both files (cp them over to the /home partition or your user's /home directory after you make one). /usr/bin/ash is not a typo.

/etc/initcpio/hooks/customencrypthook
#!/usr/bin/ash

run_hook() {
    modprobe -a -q dm-crypt >/dev/null 2>&1
    modprobe loop
    [ "${quiet}" = "y" ] && CSQUIET=">/dev/null"

    while [ ! -L '/dev/disk/by-id/usbdrive-part2' ]; do
     echo 'Waiting for USB'
     sleep 1
    done

    cryptsetup open /dev/disk/by-id/usbdrive-part2 cryptboot
    mkdir -p /mnt
    mount /dev/mapper/cryptboot /mnt
    cryptsetup open /mnt/key.img lukskey
    cryptsetup --header /mnt/header.img --key-file=/dev/mapper/lukskey --keyfile-offset=''offset'' --keyfile-size=''size'' open /dev/disk/by-id/harddrive enc
    cryptsetup close lukskey
    umount /mnt
}

usbdrive is your USB drive by-id, and harddrive is your main hard drive by-id.

Tip: You could also close cryptboot using cryptsetup close, but having it open makes it easier to mount for system updates using Pacman and regenerating the initramfs with mkinitcpio. The /boot partition must be mounted for updates that affect the kernel or Initramfs, and the initramfs will be automatically regenerated after these updates.
# cp /usr/lib/initcpio/install/encrypt /etc/initcpio/install/customencrypthook

Now edit the copied file and remove the help() section as it is not necessary.

/etc/mkinitcpio.conf (edit this only do not replace it, these are just excerpts of the necessary parts)
MODULES=(loop)
...
HOOKS=(base udev autodetect modconf block customencrypthook lvm2 filesystems keyboard fsck)

The files=() and binaries=() arrays are empty, and you should not have to replace HOOKS=(...) array entirely just edit in customencrypthook lvm2 after block and before filesystems, and make sure systemd, sd-lvm2, and encrypt are removed.

Boot Loader

Finish the Installation Guide from the mkinitcpio step. To boot you would need either GRUB or efibootmgr. Note you can use GRUB to support the encrypted disks by Configuring the boot loader[broken link: invalid section] but editing the GRUB_CMDLINE_LINUX is not necessary for this set up.

Or use Direct UEFI Secure boot by generating keys with cryptbootAUR then signing the initramfs and kernel and creating a bootable .efi file for your EFI system partition with sbupdate-gitAUR. Before using cryptboot or sbupdate note this excerpt from Secure Boot#Using your own keys:

Tip: Note that cryptbootAUR requires the encrypted boot partition to be specified in /etc/crypttab before it runs, and if you are using it in combination with sbupdate-gitAUR, sbupdate expects the /boot/efikeys/db.* files created by cryptboot to be capitalized like DB.* unless otherwise configured in /etc/default/sbupdate. Users who do not use systemd to handle encryption may not have anything in their /etc/crypttab file and would need to create an entry.
# efibootmgr -c -d /dev/device -p partition_number -L "Arch Linux Signed" -l "EFI\Arch\linux-signed.efi"

See efibootmgr(8) for an explanation of the options.

Make sure the boot order puts Arch Linux Signed first. If not change it with efibootmgr -o XXXX,YYYY,ZZZZ.

Changing the LUKS keyfile

Merge-arrows-2.pngThis article or section is a candidate for merging with dm-crypt/Device encryption#Keyfiles.Merge-arrows-2.png

Notes: Changing the keyfile is not a required action in this setup. (Discuss in Talk:Dm-crypt/Specialties#)
# cryptsetup --header /boot/header.img --key-file=/dev/mapper/lukskey --keyfile-offset=offset --keyfile-size=size luksChangeKey /dev/mapper/enc /dev/mapper/lukskey2 --new-keyfile-size=newsize --new-keyfile-offset=newoffset

Afterwards, cryptsetup close lukskey and shred or dd the old keyfile with random data before deleting it, then make sure that the new keyfile is renamed to the same name of the old one: key.img or other name.