Clevis es un marco conectable para el descifrado automatizado. Se puede utilizar para proporcionar descifrado automático de datos o incluso desbloqueo automático de volúmenes LUKS.
¿Cómo se ve esto? Bueno, el primer paso es cifrar algunos datos. Hacemos esto con un simple comando:
$ clevis encrypt PIN CONFIG < PLAINTEXT > CIPHERTEXT.jwe
Este comando toma texto sin formato en la entrada estándar y produce un objeto JWE cifrado en la salida estándar. Además del texto sin formato, necesitamos especificar dos parámetros de entrada adicionales.
Primero, está el alfiler. En terminología de horquilla, un pin es un complemento que implementa el descifrado automatizado. Simplemente pasamos aquí el nombre de un pin.
En segundo lugar, está la configuración. La configuración es un objeto JSON que se pasará directamente al pin. Contiene toda la configuración necesaria para realizar el cifrado y configurar el descifrado automatizado.
Para descifrar nuestro JWE simplemente realizamos lo siguiente:
$ clevis decrypt < CIPHERTEXT.jwe > PLAINTEXT
Tenga en cuenta que no se requiere ninguna entrada o interacción adicional para el comando de descifrado. Veamos algunos ejemplos más concretos.
Tang es una implementación de servidor que proporciona servicios de enlace criptográfico sin necesidad de un depósito en garantía. Clevis tiene pleno apoyo para Tang. A continuación se muestra un ejemplo de cómo utilizar Clevis con 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
En este ejemplo, ciframos el mensaje "hola" usando el pin Tang. El único parámetro necesario en este caso es la URL del servidor Tang. Durante el proceso de cifrado, el pin Tang solicita el anuncio de clave del servidor y le pide que confíe en las claves. Esto funciona de manera similar a SSH.
Alternativamente, puede cargar manualmente el anuncio usando el parámetro adv
. Este parámetro toma una cadena que hace referencia al archivo donde se almacena el anuncio o al contenido JSON del propio anuncio. Cuando el anuncio se especifica manualmente de esta manera, Clevis supone que el anuncio es confiable.
Clevis brinda soporte para cifrar una clave en un chip Trusted Platform Module 2.0 (TPM2). La clave aleatoria criptográficamente sólida utilizada para el cifrado se cifra utilizando el chip TPM2 y se descifra utilizando TPM2 en el momento del descifrado para permitir que clevis descifre el secreto almacenado en el JWE.
Por ejemplo:
$ echo hi | clevis encrypt tpm2 ' {} ' > hi.jwe
Clevis almacena las claves públicas y privadas de la clave cifrada en el objeto JWE, de modo que puedan recuperarse al descifrarlas para desbloquear la clave cifrada con el TPM2.
Clevis puede desempeñar la función de una aplicación PKCS#11, como se describe en RFC 7512: El esquema URI de PKCS#11.
El protocolo PKCS#11 determina que se debe configurar un PIN (Número de identidad personal) en el dispositivo de hardware para que el proceso de desbloqueo sea exitoso. Clevis permitirá a los usuarios desbloquear un disco cifrado en particular y proporcionará una forma de obtener el PIN. Habrá dos posibilidades:
1 - Proporcione el PIN en el momento del arranque: en este primer caso, Clevis detectará el dispositivo PKCS#11 y le solicitará su PIN. En caso de que el PIN sea incorrecto, Clevis le solicitará el PIN nuevamente. Es responsabilidad del usuario estar al tanto del posible bloqueo/bloqueo del dispositivo en caso de que se desconozca el PIN.
2 - Proporcione el PIN en el momento de la configuración de Clevis: En este segundo caso, Clevis se configurará con el valor del PIN.
Inicialmente, RFC7512 define un mecanismo para especificar un tipo especial de URI (el URI pkcs11
), que permite identificar tanto un dispositivo como también la información necesaria para desbloquearlo. Especial atención merecen los parámetros pin-value
, que permiten especificar el valor del PIN o la ubicación del PIN respectivamente. Clevis comprenderá, inicialmente, el parámetro 'valor de pin'. A continuación puede encontrar un ejemplo de URI de PKCS#11 utilizando el parámetro anterior:
pin-value
definido: pkcs11:token=Software%20PKCS%2311%20softtoken;manufacturer=Snake%20Oil,%20Inc.?pin-value=the-pin
En la siguiente sección, se proporcionan ejemplos de configuración de Clevis, para aclarar cuáles son las diferentes opciones para vincular un dispositivo PKCS#11 a un disco cifrado.
Clevis proporcionará un mecanismo para que el usuario vincule un dispositivo PKCS#11 en particular a un dispositivo cifrado. El nombre del nuevo pin para Clevis será pkcs11
, y la forma de configurarlo será la misma que se utiliza actualmente:
$ 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
Como primer ejemplo, un usuario puede proporcionar la información del dispositivo especificando su URI a 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"}'
Una opción adicional es proporcionarle a Clevis una configuración para que el primer dispositivo PKCS#11 que encuentre Clevis esté vinculado. Para hacerlo, se puede proporcionar un URI vacío como se muestra a continuación:
$ clevis luks bind -d /dev/sda1 pkcs11 '{"uri": "pkcs11:"}'
A continuación se muestra un comando de configuración aún más corto, equivalente al anterior:
$ clevis luks bind -d /dev/sda1 pkcs11 '{}'
En este caso, Clevis será responsable de la detección del dispositivo y, si no se encuentra ningún dispositivo, se encargará de volcar el error correspondiente.
Debe aclararse que proporcionar un URI vacío hará que Clevis le solicite también seleccionar una de las claves disponibles que coincidan en el token para evitar el cifrado accidental con claves no deseadas.
Se puede proporcionar una ruta de módulo a Clevis, de modo que utilice ese módulo para acceder a un dispositivo. Esto solo es necesario en caso de que la tarjeta no sea compatible con el software Clevis subyacente (OpenSC). Por este motivo, el campo de ruta del módulo es completamente opcional. Para proporcionar la ubicación del módulo, el usuario puede proporcionar la "ruta del módulo" a la configuración de 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"}'
Como ocurre con el resto de dispositivos, los discos cifrados que han sido vinculados a un dispositivo PKCS#11 se pueden comprobar con el comando 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"}'
En la primera fase de desarrollo, Clevis se utilizará además de OpenSC para proporcionar la funcionalidad PKCS#11. OpenSC y, en particular, pkcs11-tool
, proporciona una opción para indicar el mecanismo a utilizar para el descifrado. Para fines de prueba, algunas bibliotecas, como SoftHSM, no funcionan con el mecanismo predeterminado pkcs11-tool
, por lo que es necesario proporcionar un mecanismo particular para usar. Por este motivo, se puede proporcionar a Clevis el mecanismo a utilizar, en caso de que el predeterminado, RSA-PKCS-OAEP
, no sea válido:
$ clevis luks bind -d /dev/sda1 pkcs11 '{"uri": "pkcs11:", "mechanism":"RSA-PKCS"}'
Para verificar los mecanismos disponibles para un token específico, se puede usar el comando pkcs11-tool -M
:
$ 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
En este momento, Clevis solo admite mecanismos RSA. Debido a una limitación del resto de algoritmos, ningún otro algoritmo criptográfico asimétrico puede realizar el cifrado fácilmente. El ECC sólo admite firmas y derivación de claves, pero no el cifrado. La operación de cifrado se puede construir de alguna manera a partir de la derivación de la clave, pero no es una operación sencilla.
Cabe destacar que el mecanismo RSA-PKCS (relleno PKCS#1.5 para cifrado) no se considera seguro y se proporciona principalmente por compatibilidad, pero no se recomienda su uso en producción.
Clevis permitirá especificar la ranura donde se ubica un dispositivo PKCS#11 a través de los parámetros proporcionados al URI:
$ clevis luks bind -d /dev/sda1 pkcs11 '{"uri": "pkcs11:slot-id=0"}'
Se debe aclarar que proporcionar solo la información de la ranura hará que Clevis adivine una de las claves disponibles que coincidan en el token en la ranura seleccionada, lo que podría provocar un cifrado accidental con claves no deseadas. No se recomienda utilizar la ranura como selector de dispositivo, ya que la identificación de la ranura es un número que no se garantiza que sea estable en las inicializaciones del módulo PKCS#11 . Sin embargo, existen ciertas bibliotecas y módulos que proporcionan identificadores de ranura estables, por lo que se pueden utilizar para estos casos particulares.
Hay dos opciones mejores para distinguir entre diferentes dispositivos PKCS#11:
1 - Configuración multidispositivo con objeto de clave pública ( recomendado ):
Con las versiones recientes de OpenSC
(desde la versión OpenSC 0.26.0) en adelante, pkcs11-tool
, que utiliza Clevis para manejar la mayoría de los comandos PKCS#11, el URI de PKCS#11 se descarga tanto para los tokens como para los objetos de un ficha particular:
$ 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
En estos casos particulares, cuando existen varios dispositivos PKCS#11, seleccione la clave pública del dispositivo en particular y vincúlela a 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"}'
En caso de que esté utilizando la ruta del módulo, deberá usar la que se devuelve al proporcionar la opción --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 - Configuración multidispositivo con especificación serial + token:
Para las versiones en las que pkcs11-tool
no descarga el URI de los tokens/objetos , Clevis "intentará" la identificación específica utilizando el par token label
y serial
del dispositivo. En este tipo de escenarios la identificación se puede realizar con estos dos parámetros, aunque también se debe facilitar model
para facilitar a Clevis informar del dispositivo al solicitar el 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"}'
Recuerde que los caracteres especiales deben definirse en modo porcentaje, como se define en RFC 7512: El esquema URI PKCS#11.
Para la instalación y configuración de la característica clevis PKCS#11, se deben seguir los siguientes pasos:
1 - Instale las dependencias requeridas de Clevis, incluidas las dependencias PKCS#11:
$ sudo dnf install -y opensc pcsc-lite openssl socat
2 - El dispositivo PKCS11 debe ser accesible mediante “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 - Configurar el dispositivo para unir con horquilla:
$ sudo clevis luks bind -d /dev/sda5 pkcs11 '{"uri":"pkcs11:"}'
En caso de que sea necesario proporcionar el módulo a utilizar, se puede realizar a través del parámetro URI module-path
:
$ sudo clevis luks bind -d /dev/sda5 pkcs11 '{"uri":"pkcs11:module-path=/usr/lib64/libykcs11.so.2"}'
4 - Habilite la unidad clevis-luks-pkcs11-askpass.socket:
$ sudo systemctl enable --now clevis-luks-pkcs11-askpass.socket
5 - Configuración de /etc/crypttab:
Para que la característica PKCS#11 funcione correctamente, el archivo /etc/crypttab
debe configurarse para que systemd use un socket AF_UNIX para esperar la frase clave que desbloqueará el disco y no para solicitarla a través de la consola.
El archivo de unidad Clevis PKCS#11 configurará un socket en la ruta /run/systemd/clevis-pkcs11.sock
para enviar y recibir información sobre el desbloqueo del disco. Para los discos que se desbloquearán a través del pasador de horquilla PKCS#11, ese archivo de socket debe configurarse como archivo de clave. Por lo tanto, se debe introducir el siguiente cambio en /etc/crypttab
para que se realice el desbloqueo:
$ 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
Se recomienda encarecidamente configurar una opción keyfile-timeout
para configurar un mecanismo de interrupción en caso de que se produzca algún error de desbloqueo y sea necesario ingresar la frase de contraseña manualmente a través de la consola.
6 - Reiniciar y probar:
El sistema debe iniciarse y solicitar el PIN del dispositivo PKCS#11 y descifrar el disco cifrado configurado correspondiente solo en caso de que el PIN sea correcto.
7 - En caso de que no sea necesario probar ningún proceso de arranque, cifre y descifre con el siguiente comando (tenga en cuenta que es necesario proporcionar el valor del PIN para que funcione correctamente) y verifique que el cifrado/descifrado de una cadena se pueda realizar con este resumen , y no se produce ningún error:
$ echo "top secret" | clevis encrypt pkcs11 '{"uri":"pkcs11:module-path=/usr/lib64/libykcs11.so.2?pin-value=123456"}' | clevis decrypt
Se debe devolver la cadena top secret
.
Clevis proporciona una forma de mezclar pines para proporcionar políticas de desbloqueo sofisticadas. Esto se logra mediante el uso de un algoritmo llamado Shamir Secret Sharing (SSS).
SSS es un esquema de umbral. Crea una clave y la divide en varias partes. Cada pieza se cifra mediante otro pin (posiblemente incluso SSS de forma recursiva). Además, define el umbral t
. Si se pueden descifrar al menos t
piezas, entonces la clave de cifrado se puede recuperar y el descifrado se puede realizar correctamente.
Aquí hay un ejemplo en el que usamos el pin SSS con los pines Tang y TPM2:
$ echo hi | clevis encrypt sss
' {"t": 2, "pins": {"tpm2": {"pcr_ids": "0"}, "tang": {"url": "http://tang.local"}}} '
> hi.jwe
En el ejemplo anterior, definimos dos pines secundarios y tenemos un umbral de 2. Esto significa que durante el descifrado ambos pines secundarios deben tener éxito para que SSS tenga éxito.
Aquí hay otro ejemplo en el que usamos solo el pin Tang:
$ echo hi | clevis encrypt sss
' {"t": 1, "pins": {"tang": [{"url": "http://server1.local/key"}, {"url": "http://server2.local/key"}]}} '
> hi.jwe
En este ejemplo, definimos dos instancias secundarias del pin Tang, cada una con su propia configuración. Dado que tenemos un umbral de 1, si cualquiera de las instancias del pin Tang tiene éxito durante el descifrado, SSS tendrá éxito.
Clevis se puede usar para unir un volumen LUKS usando un alfiler para que pueda desbloquearse automáticamente.
Cómo funciona esto es bastante simple. Generamos una nueva clave criptográficamente fuerte. Esta clave se agrega a LUKS como una frase de contraseña adicional. Luego ciframos esta clave usando Clevis y almacenamos el JWE de salida dentro del encabezado LUKS usando LUKSMeta.
Aquí hay un ejemplo donde vinculamos /dev/sda1
usando el pin 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:
Una vez completado con éxito este proceso de vinculación, el disco se puede desbloquear utilizando uno de los desbloqueadores proporcionados.
Si desea utilizar el desbloqueo basado en red, deberá especificar rd.neednet=1
como argumento del kernel o utilizar --hostonly-cmdline
al crear con dracut.
Si está utilizando Tang con TLS (Ejemplo: '{"url": "https://tang.remote"}'
), la carpeta /etc/ssl
debe incluirse en la imagen initramfs, --include /etc/ssl /etc/ssl --force
al crear con dracut.
El desbloqueador de Dracut intenta desbloquear volúmenes automáticamente durante el inicio temprano. Esto permite el cifrado automatizado del volumen raíz. Habilitar el desbloqueador de Dracut es fácil. Simplemente reconstruya su initramfs después de instalar Clevis:
$ sudo dracut -f
Al reiniciar, se le pedirá que desbloquee el volumen con una contraseña. En segundo plano, Clevis intentará desbloquear el volumen automáticamente. Si tiene éxito, se cancelará la solicitud de contraseña y el arranque continuará.
Cuando utilice Clevis con initramfs-tools, para reconstruir su initramfs necesitará ejecutar:
sudo update-initramfs -u -k ' all '
Al reiniciar, se comportará exactamente como si usara Dracut.
Nuestro desbloqueador UDisks2 se ejecuta en su sesión de escritorio. No debería ser necesario habilitarlo manualmente; simplemente instale el desbloqueador Clevis UDisks2 y reinicie su sesión de escritorio. El desbloqueador debería iniciarse automáticamente.
Este desbloqueador funciona casi exactamente igual que el desbloqueador Dracut. Si inserta un dispositivo de almacenamiento extraíble que ha sido vinculado con Clevis, intentaremos desbloquearlo automáticamente en paralelo con una solicitud de contraseña del escritorio. Si el desbloqueo automático tiene éxito, la solicitud de contraseña se descartará sin la intervención del usuario.
Un dispositivo LUKS vinculado a una póliza Clevis también se puede desbloquear utilizando el comando de desbloqueo de clevis luks.
$ sudo clevis luks unlock -d /dev/sda1
Los volúmenes LUKS se pueden desvincular utilizando el comando de desvinculación clevis luks. Por ejemplo:
$ sudo clevis luks unbind -d /dev/sda1 -s 1
Los pines que están vinculados a un volumen LUKS determinado se pueden enumerar usando el comando clevis luks list. Por ejemplo:
$ sudo clevis luks list -d /dev/sda1
No instale Clevis directamente. En su lugar, utilice los paquetes de su distribución preferida.
Este comando instala los comandos principales de Clevis, el desbloqueo de Dracut y el desbloqueo de UDisks2, respectivamente.
$ sudo dnf install clevis clevis-dracut clevis-udisks2
Como se comentó en la sección anterior, se sugiere no instalar Clevis directamente . Sin embargo, en caso de que no existan paquetes de Clevis para su distribución de Linux, los pasos para compilar e instalar Clevis manualmente son los siguientes:
$ 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
para configurar la compilación: $ meson setup ..
ninja
: $ ninja
ninja install
(necesitará permisos de root para ello): $ sudo ninja install