clevis

Table of Content

General

clevis is a framework for automated decryption policy. It allows you to define a policy at encryption time that must be satisfied for the data to decrypt. Once this policy is met, the data is decrypted.

Installation

$ apt install clevis

There are some integrations for clevis which can be right handy, for example:

  • clevis-dracut
  • clevis-initramfs
  • clevis-luks
  • clevis-systemd
  • clevis-tpm2
  • clevis-udisk2

Setup

For FullDisk encryption

performed beneath Debian 13/Trixie with UEFI and initramfs

So first of all, we have to install clevis as shown above and we also want to install clevis-initramfs and clevis-luks for our use case.

To add tang/clevis as a new encyption slot in your luks partition, you can use this command:

$ clevis luks bind -d /dev/<diskpartition> tang '{"url": "http://<your tang server>:<tang server port>"}'
Enter existing LUKS password:
The advertisement contains the following signing keys:

63rlX6JxefzIaf15K8eh1oCc_5u5f8Cd0fgKnTd6Ujc

Do you wish to trust these keys? [ynYN]

This will ask your for your encyption password and after you have enter that one (successfully), you will see a new keyslot used, which can be done with:

$ cryptsetup luksDump /dev/<diskpartition>

Next is, that we confirugre initramfs and added the needed binaries to it.

First lets create the file /etc/initramfs-tools/scripts/local-top/run_net which will contain:

#!/bin/sh
. /scripts/functions
configure_networking

This will ensure that we will reload the network configuration while running the initramfs.

Next, we add a hook /usr/share/initramfs-tools/hooks/curl for add curl binary and certificates to the initramfs:

#!/bin/sh -e

PREREQS=""
case $1 in
    prereqs) echo "${PREREQS}"; exit 0;;
esac

. /usr/share/initramfs-tools/hook-functions

#copy curl binary
copy_exec /usr/bin/curl /bin

#fix DNS lib (needed for Debian 11)
cp -a /usr/lib/x86_64-linux-gnu/libnss_dns* "${DESTDIR}/usr/lib/x86_64-linux-gnu/"

#DNS resolver
echo "nameserver <YOUR DNS SERVER IP>\n" > "${DESTDIR}/etc/resolv.conf"

#copy ca-certs for curl
mkdir -p "${DESTDIR}/usr/share"
cp -ar /usr/share/ca-certificates "${DESTDIR}/usr/share/"
cp -ar /etc/ssl "${DESTDIR}/etc/"

To load the correct driver/module into initramfs for your network card you need to add it to /etc/initramfs-tools/modules like it is described in the file itself.

After you are done with that, configure /etc/initramfs-tools/initramfs.conf by adding these two lines:

Device=<contains your network interface name>
IP=<your client static ip>::<your network gateway>:<your network mask>::<your network interface name, same as in Device>

if you use DHCP and you need to use this IP value instead:

IP=:::::<your network interface name, same as in Device>:dhcp

As final step, you need to update your initramfs by running:

$ update-initramfs -u -k "all"

If you want to check if everything got stored on the initramfs use the command lsinitrd to do so:

$ lsinitrd /boot/initramfs-<version>.img | grep 'what you are looking for'

For local luks container files

Make sure, you have install clevis, clevis-luks and clevis-systemd installed on your system.

To add tang/clevis as a new encyption slot in your luks file container, you can use this command:

$ clevis luks bind -d /path/to/luks/container tang '{"url": "http://<your tang server>:<tang server port>"}'
Enter existing LUKS password:
The advertisement contains the following signing keys:

63rlX6JxefzIaf15K8eh1oCc_5u5f8Cd0fgKnTd6Ujc

Do you wish to trust these keys? [ynYN]

This will ask your for your encyption password and after you have enter that one (successfully), you will see a new keyslot used, which can be done with:

$ cryptsetup luksDump /path/to/luks/container

To test if your setup is working, you can use the command:

$ clevis luks unlock -d /path/to/luks/container -n <name_of_unlocked_device>

If that command runs through without issues, you will be able to mount the open luks container using /dev/mapper/<name_of_unlocked_device> as device path. You will also be able to see the loopback device now with lsblk.

If you want to close it again, just use cryptsetup luksClose /path/to/luks/container (don’t forget to unmount if you have it mounted.

Why do we specify the paramerter -n <name_of_unlocked_device> during the clevis luks unlock run? It is because if you do not specify it, you will get a device name with format of luks-<uuid> which is a pain to automate and not human readable.

If you want now your system to mount it after the boot is done, you will need to do two more things.

First, you need to adopt /etc/crypttab like so:

# <target name> <source device>     <key file>  <options>
luksname1       /data/mylukscont    none        luks,clevis,noearly,_netdev

According to some forums, you need clevis and _netdev in there.

I have added noearly option to not impact the boot process

The next step is to enable the unit clevis-luks-askpass.path

$ systemctl enable clevis-luks-askpass.path

For me this still was not autounlocking it (tested with and without noearly option)

Then I found in some forums, that they have added the following attributes to the clevis-luks-askpass.service:

[Unit]
Wants=network-online.target
After=network-online.target

This still not allowed me to autounlock it.

In theory it can be tested using the command cryptdisks_start <target name from crttab>, but that is not confirmed.

The man page of clevis-luks-unlockers (man clevis-luks-unlockers) points out, that for late boot unlocking, you need to enable the clevis-luks-askpass.path as mentioned before and that after the reboot, clevis will try to unlock all device listed in /etc/crypttab which have clevis bindings when sytemd prompts for the pwd.

I was not able to confirm that, but will keep working on it, till now it is seen as NOT WORKING WITH AUTO UNLOCK.

Tang did a rekey lets rekey clevis

If you are using a tang server to automatically unlock your disk for example, it might happen that a rekey was performed.

To be able to deal with that, check which slot is used for tang in the luks parition and perform a clevis luks report like this:

$ clevis luks list -d /dev/sda2
1: tang '{"url":"http://localhost:8080"}'
$ clevis luks report -d /dev/sda2 -s 1
...
Report detected that some keys were rotated.
Do you want to regenerate luks metadata with "clevis luks regen -d /dev/sda2 -s 1"? [ynYN]

If you hit there [y|Y] it will enable the new key created by the tang key rotation.

What you can do as well, is to execute this one:

$ clevis luks regen -d /dev/sda2 -s 1