Arch Linux

Please read this before reporting a bug:

Do NOT report bugs when a package is just outdated, or it is in Unsupported. Use the 'flag out of date' link on the package page, or the Mailing List.

REPEAT: Do NOT report bugs for outdated packages!

FS#37016 - [mkinitcpio] systemd hook doesn't work with encryption

Attached to Project: Arch Linux
Opened by Karol Babioch (johnpatcher) - Saturday, 21 September 2013, 16:33 GMT
Last edited by Dave Reisner (falconindy) - Thursday, 12 December 2013, 15:35 GMT
Task Type Bug Report
Category Packages: Core
Status Closed
Assigned To Thomas Bächler (brain0)
Dave Reisner (falconindy)
Architecture All
Severity High
Priority Normal
Reported Version
Due in Version Undecided
Due Date Undecided
Percent Complete 100%
Votes 4
Private No



The last update of mkinitcpio removed the "timestamp" hook and advised me to use the "systemd" hook instead. According to the wiki the "systemd" hook also replaces the "base", "usr", "udev" and "timestamp" hooks. My HOOKS line within "mkinitcpio.conf" looked like this before the update:

HOOKS="base timestamp udev autodetect modconf block keymap encrypt lvm2 filesystems resume"

I tried several configurations with the update, e.g.

HOOKS="systemd autodetect modconf block keymap encrypt lvm2 filesystems resume"

HOOKS="base systemd autodetect modconf block keymap encrypt lvm2 filesystems resume"

HOOKS="base systemd udev autodetect modconf block keymap encrypt lvm2 filesystems resume"

None of these is working. After the kernel gets loaded the screen stays black. Beforehand I was asked for the encryption passphrase, but now I don't get any output at all. However I can press enter, which will make the cursor go down. I'm not too sure how to give you more detailed information of what is actually going on here, so let me know if you need something and how I can retrieve it.

Additional info:
* package version(s): mkinitcpio 0.15.0-1, systemd 207-5

Steps to reproduce:
* Generate new initramfs using one of the HOOKS line mentioned above.
* Reboot
This task depends upon

Closed by  Dave Reisner (falconindy)
Thursday, 12 December 2013, 15:35 GMT
Reason for closing:  Fixed
Additional comments about closing:  Use sd-encrypt, provided by core/crytpsetup.
Comment by Dave Reisner (falconindy) - Saturday, 21 September 2013, 22:55 GMT
mkinitcpio also tells you that other hooks don't work yet.

Patches welcome.
Comment by Karol Babioch (johnpatcher) - Saturday, 21 September 2013, 23:47 GMT
Where exactly is mkinitcpio telling me this? I guess you are talking about the help of the "systemd" hook. Maybe its my fault due to the fact that I'm not a native speaker, but I've read the message and haven't concluded that it actually breaks things. I'm not exactly familiar with the internals of mkinitcpio, but was it really necessary to make the switch before the other hooks were ported?

Nevertheless I'm sorry for the noise and grateful for your efforts!
Comment by Dave Reisner (falconindy) - Saturday, 21 September 2013, 23:51 GMT
$ mkinitcpio -H systemd
==> Help for hook 'systemd':
This will install a basic systemd setup in your initramfs, and is meant to
replace the 'base', 'usr', 'udev' and 'timestamp' hooks. Other hooks would need
to be ported, and may not work as intended. You also may wish to still include
the 'base' hook (before this hook) to ensure that a rescue shell exists on your
Comment by Edvinas Klovas (w0rm) - Monday, 23 September 2013, 07:38 GMT
I had the same problem on LUKS/DM-CRYPT which was only fixed by removing systemd hook (and timestamp if you had one). Can't report further as I've moved from that configuration during the weekend.
Comment by Thomas Bächler (brain0) - Monday, 23 September 2013, 08:38 GMT
I have a working sd-encrypt hook, it needs some polishing, but should be available soon.
Comment by Thomas Bächler (brain0) - Sunday, 29 September 2013, 00:45 GMT
cryptsetup 1.6.2-2 now contains the sd-encrypt hook. However, the command line syntax has changed:

$ mkinitcpio -H sd-encrypt
==> Help for hook 'sd-encrypt':
This hook allows for an encrypted root device with systemd initramfs.

See the manpage of systemd-cryptsetup-generator(8) for available kernel
command line options. Alternatively, if the file /etc/crypttab.initramfs
exists, it will be added to the initramfs as /etc/crypttab. See the
crypttab(5) manpage for more information on crypttab syntax.
Comment by Christian Hesse (eworm) - Tuesday, 01 October 2013, 07:06 GMT
Basically this works for me.

However I have to type the password for my encrypted volume. Before the change I used an additional hook ( that calculates the key with Yubico USB token based on a given challenge. (I've never been happy with the implemenation as it had some timing issues and tried to get the key in a loop.)

With the new implementation this does not work any more. Is there a way that these thing are supposed to work? I found some initial discussion, but no solution.
Comment by Thomas Bächler (brain0) - Tuesday, 01 October 2013, 09:30 GMT
Basically, this has to be implemented as a systemd service. Here is an idea:

1) Use the rd.luks.key=/keyfile option (or use a crypttab.initramfs file to achieve the same).
2) Have a systemd service running that computes the passphrase from the token and saves it to /keyfile. Have that service run Before=systemd-cryptsetup@dev-sda3.service (where dev-sda3 is the systemd notation for /dev/sda3, as an example).
3) Run a service that deletes /keyfile with After=systemd-cryptsetup@dev-sda3.service.

Alternatively, write a C program that uses libcryptsetup and does the whole job at once (similar to how systemd-cryptsetup works) and call that in a systemd service file. This is a more involved task, but will certainly yield a very clean solution.

In any case, this is doable and can be properly implemented without any timing issues.
Comment by Christian Hesse (eworm) - Tuesday, 01 October 2013, 09:41 GMT
Just playing with this atm...

Looks like this works a lot cleaner than before. When systemd-cryptsetup@.service is startet udev already has finished doing its job. First step was to calculate my challenge-response from a udev rule. Works great so far and perfectly reliable.

I will look into migrating it to systemd units.
Comment by Thomas Bächler (brain0) - Tuesday, 01 October 2013, 09:53 GMT
Don't fool yourself here: udev has not necessarily finished its job (actually, you can never say "udev is finished" anymore).

The only guarantee you have is that udev has detected and configured the hard drive/partition that the encrypted device is on. Other devices (especially a USB key) may be unfinished. That is why you need to have a service that delays the cryptsetup initialization until your challenge-response scheme has finished (that service on the other hand can be configured to only start after the needed USB device is there).
Comment by Christian Hesse (eworm) - Tuesday, 01 October 2013, 12:12 GMT
You are right... It does fails depending on the hardware (or the moon phase or whatever ;) ).

Will take a deeper look at it.
Comment by Ingo Albrecht (indigo) - Saturday, 05 October 2013, 03:07 GMT
Hi, I am running it as well and it works fine in the first setup. Using HOOKS="base systemd sd-encrypt block filesystems keyboard shutdown" on i686. One thing that failed was the volatile swap (working with encrypt; setup as /dev/disk/by-ID via crypttab with urandom):
Okt 04 18:51:28 host systemd[1]: Timed out waiting for device dev-mapper-swap.device.
Okt 04 18:51:28 host systemd[1]: Dependency failed for /dev/mapper/swap.
I tried passing luks.crypttab=yes but not more so far.
Comment by Thomas Bächler (brain0) - Saturday, 05 October 2013, 13:39 GMT
Why would you even want to set up volatile swap in initramfs? I'm unsure how this is related.
Comment by Ingo Albrecht (indigo) - Saturday, 05 October 2013, 21:09 GMT
I was not trying to set it up in initramfs. Yet, encrypted swap fails getting activated during boot as it used to before. Now tried the "noearly" option and not using the /dev/disk/by-ID to no avail. (please note I have only upgraded cryptsetup from testing in order to try the new hook).
Does it make a difference that the swap partition does not have a luks header perhaps?

edit: No, it does not make a difference. I played with it again. Apart from the swap, I created two additional partitions: one dm-crypt plain mode to be unlocked with a keyfile and one additional luks partition with a passphrase.
When I boot with encrypt, systemd waits during boot for the additional luks partition's passphrase and (after providing that) the partitions get unlocked/mounted and encrypted swap is active.

When I boot with sd_encrypt the crypted root gets unlocked, but the three additional mappers timeout during boot. I can then start them manually in recovery with the service files created in /tmp by /usr/lib/systemd/system-generators/systemd-cryptsetup-generator
After copying those to /etc/systemd/system/ and symlinking them to a target, I get asked for the additional pass during the reboot and both are unlocked/mounted and swap is active with sd-encrypt as well.

Is this manual step to generate and activate the unit files wanted?

edit2: To clarify my question - I'm looking for input how the regular way to setup should be with {systemd sd_encrypt}. It is no problem to symlink the units manually, it is running fine since too. But I was under the impression that the parsing of crypttab is supposed to be done automatically(dynamically) by the generator. Is something along the path broken or my understanding of it wrong?