Clevis est un framework enfichable pour le décryptage automatisé. Il peut être utilisé pour fournir un décryptage automatisé des données ou même un déverrouillage automatisé des volumes LUKS.
A quoi ça ressemble ? Eh bien, la première étape consiste à chiffrer certaines données. Nous faisons cela avec une simple commande :
$ clevis encrypt PIN CONFIG < PLAINTEXT > CIPHERTEXT.jwe
Cette commande prend du texte en clair sur l'entrée standard et produit un objet JWE chiffré sur la sortie standard. Outre le texte brut, nous devons spécifier deux paramètres d'entrée supplémentaires.
Tout d’abord, c’est la goupille. Dans la terminologie de Chape, une épingle est un plugin qui implémente un décryptage automatisé. Nous passons simplement ici le nom d’une épingle.
Deuxièmement, la configuration. La configuration est un objet JSON qui sera transmis directement au pin. Il contient toute la configuration nécessaire pour effectuer le cryptage et configurer le déchiffrement automatisé.
Pour décrypter notre JWE, nous effectuons simplement ce qui suit :
$ clevis decrypt < CIPHERTEXT.jwe > PLAINTEXT
Notez qu’aucune entrée ou interaction supplémentaire n’est requise pour la commande decrypt. Regardons quelques exemples plus concrets.
Tang est une implémentation de serveur qui fournit des services de liaison cryptographique sans avoir besoin d'un séquestre. Clevis a un soutien total pour Tang. Voici un exemple d’utilisation de Clevis avec Tang :
$ echo hi | clevis encrypt tang ' {"url": "http://tang.local"} ' > hi.jwe
The advertisement is signed with the following keys:
kWwirxc5PhkFIH0yE28nc-EvjDY
Do you wish to trust the advertisement ? [yN] y
Dans cet exemple, nous chiffrons le message « salut » à l'aide du code PIN Tang. Le seul paramètre nécessaire dans ce cas est l'URL du serveur Tang. Pendant le processus de cryptage, le code PIN Tang demande l'annonce de clé au serveur et vous demande de faire confiance aux clés. Cela fonctionne de la même manière que SSH.
Vous pouvez également charger manuellement la publicité à l'aide du paramètre adv
. Ce paramètre prend soit une chaîne faisant référence au fichier dans lequel la publicité est stockée, soit le contenu JSON de la publicité elle-même. Lorsque la publicité est spécifiée manuellement de cette manière, Clevis présume que la publicité est fiable.
Clevis prend en charge le chiffrement d'une clé dans une puce Trusted Platform Module 2.0 (TPM2). La clé aléatoire cryptographiquement forte utilisée pour le cryptage est cryptée à l'aide de la puce TPM2 et est déchiffrée à l'aide de TPM2 au moment du déchiffrement pour permettre à Clevis de déchiffrer le secret stocké dans le JWE.
Par exemple:
$ echo hi | clevis encrypt tpm2 ' {} ' > hi.jwe
Clevis stocke les clés publiques et privées de la clé chiffrée dans l'objet JWE, afin qu'elles puissent être récupérées lors du déchiffrement pour desceller la clé chiffrée à l'aide du TPM2.
Clevis peut jouer le rôle d'une application PKCS#11, comme décrit dans la RFC 7512 : le schéma d'URI PKCS#11.
Le protocole PKCS#11 détermine qu'un code PIN (numéro d'identité personnel) doit être configuré dans le périphérique matériel pour que le processus de déverrouillage réussisse. Clevis permettra aux utilisateurs de déverrouiller un disque crypté particulier et fournira un moyen d'obtenir le code PIN. Il y aura deux possibilités :
1 - Fournissez le code PIN au démarrage : Dans ce premier cas, Clevis détectera le périphérique PKCS#11 et vous demandera son code PIN. Si le code PIN est erroné, Clevis vous demandera à nouveau le code PIN. Il est de la responsabilité de l'utilisateur de connaître l'éventuel verrou/brique de l'appareil au cas où le code PIN serait inconnu.
2 - Fournir le PIN au moment de la configuration de Clevis : Dans ce second cas, Clevis sera configuré avec la valeur du PIN.
Initialement, la RFC7512 définit un mécanisme pour spécifier un type spécial d'URI (l'URI pkcs11
), qui permet d'identifier à la fois un appareil ainsi que les informations nécessaires à son déverrouillage. Une attention particulière mérite les paramètres pin-value
, qui permettent de spécifier respectivement la valeur du code PIN ou l'emplacement du code PIN. Clevis comprendra, dans un premier temps, le paramètre « pin-value ». Vous trouverez ci-dessous un exemple d'URI PKCS#11 utilisant le paramètre précédent :
pin-value
définie : pkcs11:token=Software%20PKCS%2311%20softtoken;manufacturer=Snake%20Oil,%20Inc.?pin-value=the-pin
Dans la section suivante, des exemples de configuration Clevis sont fournis, afin de clarifier quelles sont les différentes options permettant à un périphérique PKCS#11 d'être lié à un disque chiffré.
Clevis fournira un mécanisme permettant à l'utilisateur de lier un appareil PKCS#11 particulier à un appareil crypté. Le nom de la nouvelle broche pour Clevis sera pkcs11
, et la façon de la configurer sera la même que celle actuellement utilisée :
$ clevis luks bind -h
Usage: clevis luks bind [-y] [-f] [-s SLT] [-k KEY] [-t TOKEN_ID] [-e EXISTING_TOKEN_ID] -d DEV PIN CFG
Comme premier exemple, un utilisateur peut fournir les informations de l'appareil en spécifiant son URI à Clevis :
$ clevis luks bind -d /dev/sda1 pkcs11 '{"uri": "pkcs11:model=PKCS%2315%20emulated;manufacturer=piv_II;
serial=0a35ba26b062b9c5;token=clevis;id=%02;object=Encryption%20Key"}'
Une option supplémentaire consiste à fournir à Clevis une configuration afin que le premier périphérique PKCS#11 trouvé par Clevis soit lié. Pour ce faire, un URI vide peut être fourni comme indiqué ci-dessous :
$ clevis luks bind -d /dev/sda1 pkcs11 '{"uri": "pkcs11:"}'
Une commande de configuration encore plus courte, équivalente à la précédente, est présentée ci-dessous :
$ clevis luks bind -d /dev/sda1 pkcs11 '{}'
Dans ce cas, Clevis sera responsable de la détection de l'appareil et, si aucun appareil n'est trouvé, responsable de l'élimination de l'erreur correspondante.
Il doit être précisé que si un URI est vide, Clevis sera également invité à sélectionner l'une des clés disponibles correspondant au jeton pour éviter un chiffrement accidentel avec des clés indésirables.
Un chemin de module peut être fourni à Clevis, afin qu'il utilise ce module pour accéder à un périphérique. Ceci n'est requis que si la carte n'est pas prise en charge par le logiciel Clevis sous-jacent (OpenSC). Pour cette raison, le champ chemin du module est totalement facultatif. Pour fournir l'emplacement du module, l'utilisateur peut fournir le « chemin du module » vers la configuration Clevis « uri » :
$ clevis-luks-bind -d /dev/sda1 pkcs11 '{"uri": "pkcs11:model=PKCS%2315%20emulated;manufacturer=piv_II;
serial=0a35ba26b062b9c5;token=clevis;id=%02;object=Encryption%20Key?
module-path=/usr/local/lib64/libmypkcs11.so"}'
Comme c'est le cas avec le reste des appareils, les disques chiffrés qui ont été liés à un appareil PKCS#11 peuvent être vérifiés avec la commande clevis luks list
:
$ clevis luks list -d /dev/sda1
1: pkcs11 '{"uri": "pkcs11:model=PKCS%2315%20emulated;manufacturer=piv_II;
serial=0a35ba26b062b9c5;token=clevis;id=%02;object=Encryption%20Key?
module-path=/usr/local/lib64/libmypkcs11.so"}'
Dans la première phase de développement, Clevis sera utilisé en plus d'OpenSC pour fournir la fonctionnalité PKCS#11. OpenSC, et en particulier pkcs11-tool
, fournit une option pour indiquer le mécanisme à utiliser pour le décryptage. À des fins de test, certaines bibliothèques, telles que SoftHSM), ne fonctionnent pas avec le mécanisme pkcs11-tool
par défaut, il est donc nécessaire de fournir un mécanisme particulier à utiliser. Pour cette raison, Clevis peut être fourni avec le mécanisme à utiliser, au cas où celui par défaut, RSA-PKCS-OAEP
, n'est pas valide :
$ clevis luks bind -d /dev/sda1 pkcs11 '{"uri": "pkcs11:", "mechanism":"RSA-PKCS"}'
Afin de vérifier les mécanismes disponibles pour un jeton spécifique, la commande pkcs11-tool -M
peut être utilisée :
$ pkcs11-tool -M
Using slot 0 with a present token (0x0)
Supported mechanisms:
SHA-1, digest
...
SHA512, digest
MD5, digest
...
RSA-PKCS-KEY-PAIR-GEN, keySize={2048,4096}, generate_key_pair
Pour le moment, seuls les mécanismes RSA sont pris en charge par Clevis. En raison d’une limitation du reste des algorithmes, aucun autre algorithme cryptographique asymétrique ne peut effectuer facilement le chiffrement. L'ECC prend en charge uniquement les signatures et la dérivation de clé, mais pas le chiffrement. L’opération de chiffrement peut être construite d’une manière ou d’une autre à partir de la dérivation de la clé, mais ce n’est pas une opération simple.
Il convient de souligner que le mécanisme RSA-PKCS (padding PKCS#1.5 pour le chiffrement) est considéré comme non sécurisé et qu'il est principalement fourni à des fins de compatibilité, mais il n'est pas recommandé de l'utiliser en production.
Clevis permettra de spécifier l'emplacement où se trouve un périphérique PKCS#11 via les paramètres fournis à l'URI :
$ clevis luks bind -d /dev/sda1 pkcs11 '{"uri": "pkcs11:slot-id=0"}'
Il doit être précisé que le fait de fournir uniquement les informations sur l'emplacement permettra à Clevis de deviner l'une des clés disponibles correspondant au jeton dans l'emplacement sélectionné, ce qui pourrait provoquer un cryptage accidentel avec des clés indésirables. Il n'est pas recommandé d'utiliser l'emplacement comme sélecteur de périphérique, car l'identifiant de l'emplacement est un nombre dont la stabilité n'est pas garantie lors des initialisations du module PKCS#11 . Cependant, certaines bibliothèques et modules fournissent des identifiants d'emplacement stables, ils peuvent donc être utilisés dans ces cas particuliers.
Il existe deux meilleures options pour distinguer les différents appareils PKCS#11 :
1 - Configuration multi-appareils avec objet clé publique ( recommandé ) :
Avec les versions récentes d' OpenSC
(à partir de la version OpenSC 0.26.0), pkcs11-tool
, qui est utilisé par Clevis pour gérer la plupart des commandes PKCS#11, l'URI PKCS#11 est vidé à la fois pour les jetons et les objets d'un jeton particulier :
$ pkcs11-tool -L | grep uri
uri : pkcs11:model=PKCS%2315%20emulated;manufacturer=piv_II;serial=42facd1f749ece7f;token=clevis
uri : pkcs11:model=PKCS%2315%20emulated;manufacturer=OpenPGP%20project;serial=000f06080f4f;token=OpenPGP%20card%20%28User%20PIN%29
$ pkcs11-tool -O --slot-index 1 --type pubkey | grep uri
ising slot 0 with a present token (0x0)
uri: pkcs11:model=PKCS%2315%20emulated;manufacturer=OpenPGP%20project;serial=000f06080f4f;token=OpenPGP%20card%20%28User%20PIN%29;id=%03;object=Authentication%20key;type=public
Dans ce cas particulier, lorsque plusieurs appareils PKCS#11 existent, sélectionnez la clé publique de l'appareil particulier et liez-la à Clevis :
$ clevis luks bind -d /dev/sda pkcs11 '{"uri":"pkcs11:model=PKCS%2315%20emulated;manufacturer=OpenPGP%20project;serial=000f06080f4f;token=OpenPGP%20card%20%28User%20PIN%29;id=%03;object=Authentication%20key;type=public"}'
Si vous utilisez module-path, vous devrez utiliser celui renvoyé lors de la fourniture de l'option --module :
$ pkcs11-tool --module /usr/lib64/libykcs11.so -O --type pubkey | grep uri
/usr/local/bin/pkcs11-tool.manual --module /usr/lib64/libykcs11.so -O --type pubkey | grep uri
Using slot 0 with a present token (0x0)
uri: pkcs11:model=YubiKey%20YK5;manufacturer=Yubico%20%28www.yubico.com%29;serial=28083311;token=YubiKey%20PIV%20%2328083311;id=%03;object=Public%20key%20for%20Key%20Management;type=public
uri: pkcs11:model=YubiKey%20YK5;manufacturer=Yubico%20%28www.yubico.com%29;serial=28083311;token=YubiKey%20PIV%20%2328083311;id=%19;object=Public%20key%20for%20PIV%20Attestation;type=public
$ clevis luks bind -d /dev/sda pkcs11 '{"uri":"pkcs11:model=YubiKey%20YK5;manufacturer=Yubico%20%28www.yubico.com%29;serial=28083311;token=YubiKey%20PIV%20%2328083311;id=%03;object=Public%20key%20for%20Key%20Management;type=public;module-path=/usr/lib64/libykcs11.so"}'
2 - Configuration multi-appareils avec spécification série + token :
Pour les versions où pkcs11-tool
ne sauvegarde pas l'URI des jetons/objets , une identification spécifique sera "essayée" par Clevis en utilisant la paire d'étiquettes serial
+ token label
du périphérique. Dans ce type de scénarios, l'identification peut être effectuée avec ces deux paramètres, bien qu'un model
doive également être fourni pour faciliter l'information de Clevis sur l'appareil lors de la demande du code PIN :
# pkcs11-tool -L | grep "token label|serial"
token label : OpenPGP card (User PIN)
serial num : 42facd1f749ece7f
$ clevis luks bind -d /dev/sda pkcs11 '{"uri":"pkcs11:model=PKCS%2315%20emulated;serial=000f06080f4f;token=OpenPGP%20card%20%28User%20PIN%29"}'
N'oubliez pas que les caractères spéciaux doivent être définis en mode pourcentage, comme défini dans RFC 7512 : le schéma d'URI PKCS#11.
Pour l'installation et la configuration de la fonction Chape PKCS#11, les étapes suivantes doivent être suivies :
1 - Installez les dépendances requises par Clevis, y compris les dépendances PKCS#11 :
$ sudo dnf install -y opensc pcsc-lite openssl socat
2 - Le périphérique PKCS11 doit être accessible par « pkcs11-tool » :
$ pkcs11-tool -L
pkcs11-tool -L
Available slots:
Slot 0 (0x0): Yubico YubiKey OTP+CCID 00 00
token label : clevis
...
uri : pkcs11:model=PKCS%2315%20emulated;manufacturer=piv_II;serial=42facd1f749ece7f;token=clevis
3 - Configurer le périphérique à lier avec une chape :
$ sudo clevis luks bind -d /dev/sda5 pkcs11 '{"uri":"pkcs11:"}'
S'il est nécessaire de fournir le module à utiliser, cela peut être fait via le paramètre URI module-path
:
$ sudo clevis luks bind -d /dev/sda5 pkcs11 '{"uri":"pkcs11:module-path=/usr/lib64/libykcs11.so.2"}'
4 - Activer l'unité clevis-luks-pkcs11-askpass.socket :
$ sudo systemctl enable --now clevis-luks-pkcs11-askpass.socket
5 - Configuration de /etc/crypttab :
Pour que la fonctionnalité PKCS#11 fonctionne correctement, le fichier /etc/crypttab
doit être configuré de sorte que systemd utilise un socket AF_UNIX pour attendre la phrase clé qui déverrouillera le disque et ne pas la demander via la console.
Le fichier unité Clevis PKCS#11 configurera un socket dans le chemin /run/systemd/clevis-pkcs11.sock
pour envoyer et recevoir des informations sur le déverrouillage du disque. Pour les disques qui seront déverrouillés via la broche PKCS#11 Clevis, ce fichier de socket doit être configuré en tant que fichier de clé. Ainsi, le prochain changement doit être introduit dans /etc/crypttab
pour que le déverrouillage ait lieu :
$ sudo diff -Nuar /etc/crypttab.ori /etc/crypttab
--- /etc/crypttab.ori 2024-07-04 10:46:16.295073739 +0200
+++ /etc/crypttab 2024-07-03 17:14:27.764743860 +0200
@@ -1 +1,2 @@
-luks-6e38d5e1-7f83-43cc-819a-7416bcbf9f84 UUID=6e38d5e1-7f83-43cc-819a-7416bcbf9f84 - -
+luks-6e38d5e1-7f83-43cc-819a-7416bcbf9f84 UUID=6e38d5e1-7f83-43cc-819a-7416bcbf9f84 /run/systemd/clevis-pkcs11.sock keyfile-timeout=30s
Il est fortement recommandé de définir une option keyfile-timeout
pour configurer un mécanisme de secours au cas où une erreur de déverrouillage se produirait et où la phrase secrète doit être saisie manuellement via la console.
6 - Redémarrer et tester :
Le système doit démarrer et demander le code PIN du périphérique PKCS#11, et déchiffrer le disque crypté configuré correspondant uniquement si le code PIN est correct.
7 - Dans le cas où aucun processus de démarrage ne doit être testé, cryptez et déchiffrez avec la commande suivante (notez qu'il est nécessaire de fournir la valeur du code PIN pour qu'il fonctionne correctement) et vérifiez que le cryptage/déchiffrement d'une chaîne peut être effectué avec cette seule ligne. , et aucune erreur ne se produit :
$ echo "top secret" | clevis encrypt pkcs11 '{"uri":"pkcs11:module-path=/usr/lib64/libykcs11.so.2?pin-value=123456"}' | clevis decrypt
La chaîne top secret
doit être renvoyée
Clevis fournit un moyen de mélanger les broches pour fournir des politiques de déverrouillage sophistiquées. Ceci est accompli en utilisant un algorithme appelé Shamir Secret Sharing (SSS).
SSS est un système de seuillage. Il crée une clé et la divise en plusieurs morceaux. Chaque élément est crypté à l'aide d'une autre broche (éventuellement même SSS de manière récursive). De plus, vous définissez le seuil t
. Si au moins t
éléments peuvent être déchiffrés, alors la clé de cryptage peut être récupérée et le décryptage peut réussir.
Voici un exemple où nous utilisons la broche SSS avec les broches Tang et TPM2 :
$ echo hi | clevis encrypt sss
' {"t": 2, "pins": {"tpm2": {"pcr_ids": "0"}, "tang": {"url": "http://tang.local"}}} '
> hi.jwe
Dans l'exemple ci-dessus, nous définissons deux épingles enfants et avons un seuil de 2. Cela signifie que lors du déchiffrement, les deux épingles enfants doivent réussir pour que SSS lui-même réussisse.
Voici un autre exemple où nous utilisons uniquement la broche Tang :
$ echo hi | clevis encrypt sss
' {"t": 1, "pins": {"tang": [{"url": "http://server1.local/key"}, {"url": "http://server2.local/key"}]}} '
> hi.jwe
Dans cet exemple, nous définissons deux instances enfants de la broche Tang, chacune avec sa propre configuration. Puisque nous avons un seuil de 1, si l’une des instances de la broche Tang réussit lors du déchiffrement, SSS réussira.
Clevis peut être utilisé pour lier un volume LUKS à l'aide d'une épingle afin qu'il puisse être automatiquement déverrouillé.
Comment cela fonctionne est plutôt simple. Nous générons une nouvelle clé cryptographiquement forte. Cette clé est ajoutée à LUKS en tant que phrase secrète supplémentaire. Nous chiffrons ensuite cette clé à l'aide de Clevis et stockons le JWE de sortie dans l'en-tête LUKS à l'aide de LUKSMeta.
Voici un exemple où nous lions /dev/sda1
à l'aide de la broche Tang :
$ sudo clevis luks bind -d /dev/sda1 tang ' {"url": "http://tang.local"} '
The advertisement is signed with the following keys:
kWwirxc5PhkFIH0yE28nc-EvjDY
Do you wish to trust the advertisement ? [yN] y
Enter existing LUKS password:
Une fois ce processus de liaison terminé, le disque peut être déverrouillé à l'aide de l'un des déverrouillages fournis.
Si vous souhaitez utiliser le déverrouillage basé sur le réseau, vous devrez spécifier rd.neednet=1
comme argument du noyau ou utiliser --hostonly-cmdline
lors de la création avec dracut.
Si vous utilisez Tang avec TLS (Exemple : '{"url": "https://tang.remote"}'
), le dossier /etc/ssl
doit être inclus dans l'image initramfs, --include /etc/ssl /etc/ssl --force
lors de la création avec dracut.
Le déverrouillage Dracut tente de déverrouiller automatiquement les volumes lors d'un démarrage anticipé. Cela permet le chiffrement automatisé du volume racine. L'activation du déverrouillage Dracut est simple. Reconstruisez simplement vos initramfs après avoir installé Clevis :
$ sudo dracut -f
Au redémarrage, vous serez invité à déverrouiller le volume à l'aide d'un mot de passe. En arrière-plan, Clevis tentera de déverrouiller automatiquement le volume. Si cela réussit, l'invite de mot de passe sera annulée et le démarrage continuera.
Lorsque vous utilisez Clevis avec les outils initramfs, afin de reconstruire votre initramfs, vous devrez exécuter :
sudo update-initramfs -u -k ' all '
Au redémarrage, il se comportera exactement comme si vous utilisiez Dracut.
Notre déverrouillage UDisks2 s'exécute dans votre session de bureau. Vous ne devriez pas avoir besoin de l'activer manuellement ; installez simplement le déverrouillage Clevis UDisks2 et redémarrez votre session de bureau. Le déverrouillage devrait être démarré automatiquement.
Ce déverrouillage fonctionne presque exactement de la même manière que le déverrouillage Dracut. Si vous insérez un périphérique de stockage amovible lié à Clevis, nous tenterons de le déverrouiller automatiquement en parallèle avec une invite de mot de passe sur le bureau. Si le déverrouillage automatique réussit, la demande de mot de passe sera ignorée sans intervention de l'utilisateur.
Un appareil LUKS lié à une stratégie Clevis peut également être déverrouillé à l’aide de la commande clevis luks unlock.
$ sudo clevis luks unlock -d /dev/sda1
Les volumes LUKS peuvent être dissociés à l'aide de la commande clevis luks unbind. Par exemple:
$ sudo clevis luks unbind -d /dev/sda1 -s 1
Les broches liées à un volume LUKS donné peuvent être répertoriées à l'aide de la commande clevis luks list. Par exemple:
$ sudo clevis luks list -d /dev/sda1
Veuillez ne pas installer Clevis directement. Utilisez plutôt les packages de votre distribution préférée.
Cette commande installe respectivement les commandes principales de Clevis, le déverrouillage Dracut et le déverrouillage UDisks2.
$ sudo dnf install clevis clevis-dracut clevis-udisks2
Comme indiqué dans la section précédente, il est suggéré de ne pas installer Clevis directement . Cependant, dans le cas où aucun package Clevis n'existe pour votre distribution Linux, les étapes pour compiler et installer manuellement Clevis sont les suivantes :
$ wget https://github.com/latchset/clevis/releases/download/v21/clevis-21.tar.xz
$ tar Jxvf clevis-21.tar.xz
$ cd clevis-21
$ mkdir build
$ cd build
meson
pour configurer la compilation : $ meson setup ..
ninja
: $ ninja
ninja install
(vous aurez besoin des autorisations root pour cela) : $ sudo ninja install