The Cosmian KMS can provision secrets to open Linux LUKS encrypted partitions. The secret never leaves the KMS and can be used to unlock the partition at boot time.
The Cosmian KMS provides a PKCS#11 module that can be used to access the KMS from applications that
support PKCS#11, using the p11-kit
framework.
With LUKS, the system provided systemd-cryptenroll
command
must have support for p11-kit
which you can check by running systemd-cryptenroll --help
and
checking for the +P11KIT
flag.
❯ systemd-cryptenroll --version
systemd 253 (253.5-1ubuntu6.1)
+PAM +AUDIT +SELINUX +APPARMOR +IMA +SMACK +SECCOMP +GCRYPT -GNUTLS +OPENSSL +ACL +BLKID +CURL
+ELFUTILS +FIDO2 +IDN2 -IDN +IPTC +KMOD +LIBCRYPTSETUP +LIBFDISK +PCRE2 -PWQUALITY
+P11KIT +QRENCODE +TPM2 +BZIP2 +LZ4 +XZ +ZLIB +ZSTD -BPF_FRAMEWORK -XKBCOMMON +UTMP +SYSVINIT
default-hierarchy=unified
Unfortunately, Ubuntu 22.04 does not provide p11-kit support, however the setup works fine for Ubuntu 23.10.
sudo apt install p11-kit
sudo dnf install p11-kit
sudo mkdir -p /etc/pkcs11/modules
sudo tee /etc/pkcs11/pkcs11.conf <<EOF
# This setting controls whether to load user configuration from the
# ~/.config/pkcs11 directory. Possible values:
# none: No user configuration
# merge: Merge the user config over the system configuration (default)
# only: Only user configuration, ignore system configuration
user-config: merge
EOF
sudo cp libckms_pkcs11.so /usr/local/lib/
sudo tee /etc/pkcs11/modules/ckms_pkcs11.module <<EOF
# Cosmian KMS PKCS#11 module
module: /usr/local/lib/libckms_pkcs11.so
EOF
> p11-kit list-modules
...
ckms_pkcs11: /usr/local/lib/libckms_pkcs11.so
library-description: Cosmian KMS PKCS#11 provider
library-manufacturer: Cosmian
library-version: x.y
token: Cosmian-KMS
manufacturer: Cosmian
model: software
serial-number: x.y.z
flags:
rng
write-protected
login-required
user-pin-initialized
protected-authentication-path
token-initialized
The PKCS#11 module uses the same configuration file as
the CLI.
Since it may be run as a system user, the configuration file should be made available
in /etc/cosmian/kms.json
.
See Authenticating users to the KMS to learn how to configure the KMS to use Open ID connect or certificate authentication.
Here is an example configuration file for the PKCS#11 provider library accessing the KMS using a PKCS#12 file for authentication.
{
"server_url": "https://kms.acme.com:9999",
"ssl_client_pkcs12_path": "./certificates/machine123.acme.p12",
"ssl_client_pkcs12_password": "machine123_pkcs12_password"
}
To use Open ID connect, install the Cosmian CLI from
Cosmian packages and
use the cosmian kms login
command to authenticate to the KMS first.
To generate a self-signed certificate with RSA 2048bit key and in PKCS12 format, you can use the OpenSSL command-line tool. Here are the steps:
openssl genpkey -algorithm RSA -out private_key.pem -pkeyopt rsa_keygen_bits:2048
openssl req -new -x509 -key private_key.pem -out cert.pem -days 365
openssl pkcs12 -export -out certificate.p12 -inkey private_key.pem -in cert.pem
cosmian kms certificates import -f pkcs12 -t disk-encryption certificate.p12
The private key in the PKCS12 file was imported with id: 6fc631...
Tags:
- disk-encryption
A tag different from disk-encryption
can be used, but it must be set in the
in the COSMIAN_PKCS11_DISK_ENCRYPTION_TAG
environment variable when enrolling the token (sse
below).
First allocate some space then create a LUKS partition using cryptsetup
.
LUKS partitions can be created either from disk partitions or from a file.
Use either dd
or fallocate
to create a file that will be used as the LUKS partition.
# Create a 1GB file
fallocate -l 1G /path/to/file
Then use path/to/file
as the device to encrypt.
Using parted
, determine or create a partition on the disk that you want to encrypt.
In this example, we assume the disk is available as /dev/vda
.
If needed, use parted
to resize the last partition and create free space at the end of the disk.
sudo parted /dev/vda
(parted) print free
Number Start End Size File system Name Flags
17.4kB 1049kB 1031kB Free Space
1 1049kB 1128MB 1127MB fat32 boot, esp
2 1128MB 3276MB 2147MB ext4
3 3276MB 102GB 98.7GB
102GB 103GB 1079MB Free Space
Make a 4th partition /dev/vda4
from the free space at the end.
(parted) mkpart 4 102GB 103GB
Enter a passphrase to protect the partition when prompted. The encrypted passphrase will be stored in the LUKS header in key slot 0.
sudo cryptsetup luksFormat --type luks2 --key-slot 0 /dev/vda4
Make sure to remember the passphrase, as it will be needed to unlock the partition
during cryptenroll
or when rotating the RSA keys.
Logging of the PKCS#11 module is controlled by the CKMS_PKCS11_LOGGING_LEVEL
environment variable.
The logging level can be set to trace
, debug
, info
, warn
, or error
and defaults to info
when not set.
The RSA key pair is searched opn the KMS using a tag controlled by
the COSMIAN_PKCS11_DISK_ENCRYPTION_TAG
environment variable.
When not set, the default tag searched is disk-encryption
.
> sudo systemd-cryptenroll /dev/vda4 --pkcs11-token-uri=list
URI LABEL MANUFACTURER MODEL
pkcs11:model=software;manufacturer=Cosmian;serial=x.y.z;token=Cosmian-KMS Cosmian-KMS Cosmian software
# this is equivalent to
# sudo COSMIAN_PKCS11_LOGGING_LEVEL=info COSMIAN_PKCS11_DISK_ENCRYPTION_TAG=disk-encryption systemd-cryptenroll /dev/vda4 --pkcs11-token-uri=pkcs11:token=Cosmian-KMS
> sudo systemd-cryptenroll /dev/vda4 --pkcs11-token-uri=pkcs11:token=Cosmian-KMS
🔐 Please enter current passphrase for disk /dev/vda4: *************
ckms-pkcs11 module logging at INFO level to file /var/log/ckms-pkcs11.log
Successfully logged into security token 'Cosmian-KMS' via protected authentication path.
New PKCS#11 token enrolled as key slot 1.
> sudo cryptsetup luksDump /dev/vda4
LUKS header information
Version: 2
Epoch: 5
...
Keyslots:
0: luks2
....
1: luks2
Key: 512 bits
Priority: normal
Cipher: aes-xts-plain64
Cipher key: 512 bits
PBKDF: pbkdf2
Hash: sha512
...
Tokens:
0: systemd-pkcs11
pkcs11-uri: pkcs11:token=Cosmian-KMS
pkcs11-key: 0b 94 e0 ...
...
> sudo cryptsetup open --type luks2 --token-id=0 --token-only /dev/vda4 myluks
ckms-pkcs11 module logging at INFO level to file /var/log/ckms-pkcs11.log
Successfully logged into security token 'Cosmian-KMS' via protected authentication path.
Successfully decrypted key with security token.
sudo mkfs.ext4 /dev/mapper/myluks
sudo mkdir /mnt/myluks #only once
sudo mount /dev/mapper/myluks /mnt/myluks
sudo umount /mnt/myluks
sudo cryptsetup close myluks
To automatically unlock the LUKS partition at boot, you cannot use the /etc/crypttab
file
because the network is not available when systemd-cyptsetup
is run.
You need to create a systemd service that unlocks the LUKS partition at the right time, after the network is available.
sudo tee -a /root/mount_myluks.sh <<EOF
#!/bin/bash
set -e
set -x
# unlock the partition
cryptsetup open --type luks2 --token-id=0 --token-only /dev/vda4 myluks
# mount the partition
mount /dev/mapper/myluks /mnt/myluks
EOF
sudo chmod +x /root/mount_myluks.sh
sudo tee -a /etc/systemd/system/mount_myluks.service <<EOF
[Unit]
Description=open and mount the encrypted /dev/vda4 to /mnt/myluks
Wants=network-online.target
After=network-online.target
[Service]
Type=oneshot
ExecStart=/bin/bash /root/mount_myluks.sh
[Install]
WantedBy=multi-user.target
EOF
> sudo systemctl enable mount_myluks.service
Created symlink /etc/systemd/system/multi-user.target.wants/mount_myluks.service → /etc/systemd/system/mount_myluks.service.
sudo systemctl daemon-reload
sudo reboot
The LUKS partition should be automatically unlocked and mounted at boot to /mnt/myluks
.
Check dmesg
, and /var/log/ckms-pkcs11.log
for any errors.
To rotate the keys used to encrypt the LUKS partition, you can generate a new key pair and import it into the Cosmian KMS.
Then, you can re-enroll the LUKS partition with the new key. You MUST know the passphrase to perform this operation.
sudo systemd-cryptenroll /dev/vda4 --wipe-slot=pkcs11
Wiped slot 1.
cosmian kms certificates revoke -k 6fc631... "revoked"
Successfully revoked: 6fc631....