character are ignored. Each of the remaining lines describes one
encrypted block device. Fields are delimited by white space.</para>
- <para>Each line is in the form<programlisting><replaceable>name</replaceable> <replaceable>encrypted-device</replaceable> <replaceable>password</replaceable> <replaceable>options</replaceable></programlisting>
+ <para>Each line is in the form<programlisting><replaceable>volume-name</replaceable> <replaceable>encrypted-device</replaceable> <replaceable>key-file</replaceable> <replaceable>options</replaceable></programlisting>
The first two fields are mandatory, the remaining two are
optional.</para>
it is opened as a LUKS device; otherwise, it is assumed to be in
raw dm-crypt (plain mode) format.</para>
- <para>The first field contains the name of the resulting encrypted
- block device; the device is set up within
- <filename>/dev/mapper/</filename>.</para>
+ <para>The first field contains the name of the resulting encrypted volume; its block device is set up
+ below <filename>/dev/mapper/</filename>.</para>
<para>The second field contains a path to the underlying block
device or file, or a specification of a block device via
<literal>UUID=</literal> followed by the UUID.</para>
- <para>The third field specifies the encryption password. If the
- field is not present or the password is set to
- <literal>none</literal> or <literal>-</literal>, the password has
- to be manually entered during system boot. Otherwise, the field is
- interpreted as an absolute path to a file containing the encryption
- password. For swap encryption, <filename>/dev/urandom</filename>
- or the hardware device <filename>/dev/hw_random</filename> can be
- used as the password file; using <filename>/dev/random</filename>
- may prevent boot completion if the system does not have enough
- entropy to generate a truly random encryption key.</para>
+ <para>The third field specifies an absolute path to a file to read the encryption key from. If the field
+ is not present or set to <literal>none</literal> or <literal>-</literal>, a key file named after the
+ volume to unlock (i.e. the first column of the line), suffixed with <filename>.key</filename> is
+ automatically loaded from the <filename>/etc/cryptsetup-keys.d/</filename> and
+ <filename>/run/cryptsetup-keys.d/</filename> directories, if present. Otherwise, the password has to be
+ manually entered during system boot. For swap encryption, <filename>/dev/urandom</filename> may be used
+ as key file.</para>
<para>The fourth field, if present, is a comma-delimited list of
options. The following options are recognized:</para>
size is then given by the key size.</para></listitem>
</varlistentry>
+ <varlistentry>
+ <term><option>keyfile-erase</option></term>
+
+ <listitem><para>If enabled, the specified key file is erased after the volume is activated or when
+ activation fails. This is in particular useful when the key file is only acquired transiently before
+ activation (e.g. via a file in <filename>/run/</filename>, generated by a service running before
+ activation), and shall be removed after use. Defaults to off.</para></listitem>
+ </varlistentry>
+
<varlistentry>
<term><option>key-slot=</option></term>
before it is used to unlock the LUKS volume.</para></listitem>
</varlistentry>
+ <varlistentry>
+ <term><option>try-empty-password=</option></term>
+
+ <listitem><para>Takes a boolean argument. If enabled, right before asking the user for a password it
+ is first attempted to unlock the volume with an empty password. This is useful for systems that are
+ initialized with an encrypted volume with only an empty password set, which shall be replaced with a
+ suitable password during first boot, but after activation.</para></listitem>
+ </varlistentry>
+
<varlistentry>
<term><option>x-systemd.device-timeout=</option></term>
<para>At early boot and when the system manager configuration is reloaded, <filename>/etc/crypttab</filename> is
translated into <filename>systemd-cryptsetup@.service</filename> units by
<citerefentry><refentrytitle>systemd-cryptsetup-generator</refentrytitle><manvolnum>8</manvolnum></citerefentry>.</para>
+
+ <para>In order to unlock a volume a password or binary key is
+ required. <filename>systemd-cryptsetup@.service</filename> tries to acquire a suitable password or binary
+ key via the following mechanisms, tried in order:</para>
+
+ <orderedlist>
+ <listitem><para>If a key file is explicitly configured (via the third column in
+ <filename>/etc/crypttab</filename>), a key read from it is used. If a PKCS#11 token is configured
+ (using the <varname>pkcs11-uri=</varname> option) the key is decrypted before use.</para></listitem>
+
+ <listitem><para>If no key file is configured explicitly this way, a key file is automatically loaded
+ from <filename>/etc/cryptsetup-keys.d/<replaceable>volume</replaceable>.key</filename> and
+ <filename>/run/cryptsetup-keys.d/<replaceable>volume</replaceable>.key</filename>, if present. Here
+ too, if a PKCS#11 token is configured, any key found this way is decrypted before
+ use.</para></listitem>
+
+ <listitem><para>If the <varname>try-empty-password</varname> option is specified it is then attempted
+ to unlock the volume with an empty password.</para></listitem>
+
+ <listitem><para>The kernel keyring is then checked for a suitable cached password from previous
+ attempts.</para></listitem>
+
+ <listitem><para>Finally, the user is queried for a password, possibly multiple times.</para></listitem>
+ </orderedlist>
+
+ <para>If no suitable key may be acquired via any of the mechanisms describes above, volume activation fails.</para>
</refsect1>
<refsect1>
base64 < plaintext.bin | tr -d '\n\r\t ' > plaintext.base64
# Encrypt this newly generated (binary) LUKS decryption key using the public key whose private key is on the
-# Yubikey, store the result in /etc/encrypted-luks-key.bin, where we'll look for it during boot.
-sudo openssl rsautl -encrypt -pubin -inkey pubkey.pem -in plaintext.bin -out /etc/encrypted-luks-key.bin
+# Yubikey, store the result in /etc/cryptsetup-keys.d/mytest.key, where we'll look for it during boot.
+mkdir -p /etc/cryptsetup-keys.d
+sudo openssl rsautl -encrypt -pubin -inkey pubkey.pem -in plaintext.bin -out /etc/cryptsetup-keys.d/mytest.key
# Configure the LUKS decryption key on the LUKS device. We use very low pbkdf settings since the key already
# has quite a high quality (it comes directly from /dev/urandom after all), and thus we don't need to do much
rm pubkey.pem
# Test: Let's run systemd-cryptsetup to test if this all worked. The option string should contain the full
-# PKCS#11 URI we have in the clipboard, it tells the tool how to decipher the encrypted LUKS key.
-sudo systemd-cryptsetup attach mytest /dev/sdXn /etc/encrypted-luks-key.bin 'pkcs11-uri=pkcs11:…'
+# PKCS#11 URI we have in the clipboard; it tells the tool how to decipher the encrypted LUKS key. Note that
+# systemd-cryptsetup automatically searches for the encrypted key in /etc/cryptsetup-keys.d/, hence we do
+# not need to specify the key file path explicitly here.
+sudo systemd-cryptsetup attach mytest /dev/sdXn - 'pkcs11-uri=pkcs11:…'
# If that worked, let's now add the same line persistently to /etc/crypttab, for the future.
-sudo bash -c 'echo "mytest /dev/sdXn /etc/encrypted-luks-key \'pkcs11-uri=pkcs11:…\'" >> /etc/crypttab'
+sudo bash -c 'echo "mytest /dev/sdXn - \'pkcs11-uri=pkcs11:…\'" >> /etc/crypttab'