<section xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" xml:id="sec-luks-file-systems">
  <title>LUKS-Encrypted File Systems</title>
  <para>
    NixOS supports file systems that are encrypted using
    <emphasis>LUKS</emphasis> (Linux Unified Key Setup). For example,
    here is how you create an encrypted Ext4 file system on the device
    <literal>/dev/disk/by-uuid/3f6b0024-3a44-4fde-a43a-767b872abe5d</literal>:
  </para>
  <programlisting>
# cryptsetup luksFormat /dev/disk/by-uuid/3f6b0024-3a44-4fde-a43a-767b872abe5d

WARNING!
========
This will overwrite data on /dev/disk/by-uuid/3f6b0024-3a44-4fde-a43a-767b872abe5d irrevocably.

Are you sure? (Type uppercase yes): YES
Enter LUKS passphrase: ***
Verify passphrase: ***

# cryptsetup luksOpen /dev/disk/by-uuid/3f6b0024-3a44-4fde-a43a-767b872abe5d crypted
Enter passphrase for /dev/disk/by-uuid/3f6b0024-3a44-4fde-a43a-767b872abe5d: ***

# mkfs.ext4 /dev/mapper/crypted
</programlisting>
  <para>
    The LUKS volume should be automatically picked up by
    <literal>nixos-generate-config</literal>, but you might want to
    verify that your <literal>hardware-configuration.nix</literal> looks
    correct. To manually ensure that the system is automatically mounted
    at boot time as <literal>/</literal>, add the following to
    <literal>configuration.nix</literal>:
  </para>
  <programlisting language="bash">
boot.initrd.luks.devices.crypted.device = &quot;/dev/disk/by-uuid/3f6b0024-3a44-4fde-a43a-767b872abe5d&quot;;
fileSystems.&quot;/&quot;.device = &quot;/dev/mapper/crypted&quot;;
</programlisting>
  <para>
    Should grub be used as bootloader, and <literal>/boot</literal> is
    located on an encrypted partition, it is necessary to add the
    following grub option:
  </para>
  <programlisting language="bash">
boot.loader.grub.enableCryptodisk = true;
</programlisting>
  <section xml:id="sec-luks-file-systems-fido2">
    <title>FIDO2</title>
    <para>
      NixOS also supports unlocking your LUKS-Encrypted file system
      using a FIDO2 compatible token. In the following example, we will
      create a new FIDO2 credential and add it as a new key to our
      existing device <literal>/dev/sda2</literal>:
    </para>
    <programlisting>
# export FIDO2_LABEL=&quot;/dev/sda2 @ $HOSTNAME&quot;
# fido2luks credential &quot;$FIDO2_LABEL&quot;
f1d00200108b9d6e849a8b388da457688e3dd653b4e53770012d8f28e5d3b269865038c346802f36f3da7278b13ad6a3bb6a1452e24ebeeaa24ba40eef559b1b287d2a2f80b7

# fido2luks -i add-key /dev/sda2 f1d00200108b9d6e849a8b388da457688e3dd653b4e53770012d8f28e5d3b269865038c346802f36f3da7278b13ad6a3bb6a1452e24ebeeaa24ba40eef559b1b287d2a2f80b7
Password:
Password (again):
Old password:
Old password (again):
Added to key to device /dev/sda2, slot: 2
</programlisting>
    <para>
      To ensure that this file system is decrypted using the FIDO2
      compatible key, add the following to
      <literal>configuration.nix</literal>:
    </para>
    <programlisting language="bash">
boot.initrd.luks.fido2Support = true;
boot.initrd.luks.devices.&quot;/dev/sda2&quot;.fido2.credential = &quot;f1d00200108b9d6e849a8b388da457688e3dd653b4e53770012d8f28e5d3b269865038c346802f36f3da7278b13ad6a3bb6a1452e24ebeeaa24ba40eef559b1b287d2a2f80b7&quot;;
</programlisting>
    <para>
      You can also use the FIDO2 passwordless setup, but for security
      reasons, you might want to enable it only when your device is PIN
      protected, such as
      <link xlink:href="https://trezor.io/">Trezor</link>.
    </para>
    <programlisting language="bash">
boot.initrd.luks.devices.&quot;/dev/sda2&quot;.fido2.passwordLess = true;
</programlisting>
  </section>
</section>
