Clevis — это подключаемая платформа для автоматического дешифрования. Его можно использовать для автоматической расшифровки данных или даже автоматической разблокировки томов LUKS.
Как это выглядит? Итак, первый шаг — шифрование некоторых данных. Мы делаем это с помощью простой команды:
$ clevis encrypt PIN CONFIG < PLAINTEXT > CIPHERTEXT.jwe
Эта команда принимает открытый текст на стандартный ввод и создает зашифрованный объект JWE на стандартный вывод. Помимо открытого текста нам необходимо указать два дополнительных входных параметра.
Во-первых, это булавка. В терминологии clevis булавка — это плагин, который реализует автоматическое дешифрование. Мы просто передаем сюда имя пина.
Во-вторых, это конфигурация. Конфигурация представляет собой объект JSON, который будет передан непосредственно на вывод. Он содержит все необходимые настройки для шифрования и настройки автоматического дешифрования.
Чтобы расшифровать наш JWE, мы просто выполняем следующее:
$ clevis decrypt < CIPHERTEXT.jwe > PLAINTEXT
Обратите внимание, что для команды расшифровки не требуется никакого дополнительного ввода или взаимодействия. Давайте посмотрим на более конкретные примеры.
Tang — это реализация сервера, которая предоставляет услуги криптографической привязки без необходимости условного депонирования. Клевис полностью поддерживает Тана. Вот пример использования Clevis с 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
В этом примере мы шифруем сообщение «привет» с помощью PIN-кода Tang. Единственный параметр, необходимый в этом случае, — это URL-адрес сервера Tang. В процессе шифрования вывод Tang запрашивает объявление ключа с сервера и просит вас доверять ключам. Это работает аналогично SSH.
Альтернативно вы можете загрузить рекламу вручную, используя параметр adv
. Этот параметр принимает либо строку, ссылающуюся на файл, в котором хранится реклама, либо содержимое JSON самой рекламы. Когда объявление указывается вручную таким образом, Clevis предполагает, что этому объявлению доверяют.
Clevis обеспечивает поддержку шифрования ключа в чипе Trusted Platform Module 2.0 (TPM2). Криптографически стойкий случайный ключ, используемый для шифрования, шифруется с помощью чипа TPM2 и расшифровывается с помощью TPM2 во время расшифровки, что позволяет Clevis расшифровать секрет, хранящийся в JWE.
Например:
$ echo hi | clevis encrypt tpm2 ' {} ' > hi.jwe
Clevis хранит открытый и закрытый ключи зашифрованного ключа в объекте JWE, поэтому их можно получить при расшифровке и раскрыть ключ, зашифрованный с помощью TPM2.
Clevis может выполнять роль приложения PKCS#11, как описано в RFC 7512: Схема URI PKCS#11.
Протокол PKCS#11 определяет, что PIN-код (персональный идентификационный номер) должен быть настроен в аппаратном устройстве, чтобы процесс разблокировки прошел успешно. Clevis позволит пользователям разблокировать определенный зашифрованный диск и предоставит возможность получить PIN-код. Будет две возможности:
1. Введите PIN-код во время загрузки. В этом первом случае Clevis обнаружит устройство PKCS#11 и запросит его PIN-код. Если PIN-код неправильный, Clevis снова запросит PIN-код. Пользователь обязан знать о возможной блокировке/блокировке устройства в случае, если PIN-код неизвестен.
2. Введите PIN-код во время настройки Clevis: во втором случае Clevis будет настроен с использованием значения PIN-кода.
Первоначально RFC7512 определяет механизм указания специального типа URI (URI pkcs11
), который позволяет идентифицировать как устройство, так и информацию, необходимую для его разблокировки. Особого внимания заслуживают параметры pin-value
, которые позволяют указать значение ПИН-кода или расположение ПИН-кода соответственно. Первоначально Clevis понимает параметр «значение контакта». Ниже вы можете найти пример URI PKCS#11 с использованием предыдущего параметра:
pin-value
: pkcs11:token=Software%20PKCS%2311%20softtoken;manufacturer=Snake%20Oil,%20Inc.?pin-value=the-pin
В следующем разделе представлены примеры конфигурации Clevis, чтобы прояснить, каковы различные варианты привязки устройства PKCS#11 к зашифрованному диску.
Clevis предоставит пользователю механизм привязки конкретного устройства PKCS#11 к зашифрованному устройству. Имя нового вывода для Clevis будет pkcs11
, а способ его настройки будет таким же, как и сейчас:
$ 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
В качестве первого примера пользователь может предоставить информацию об устройстве, указав его 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"}'
Дополнительный вариант — предоставить Clevis такую конфигурацию, чтобы было привязано первое устройство PKCS#11, обнаруженное Clevis. Для этого можно указать пустой URI, как показано ниже:
$ clevis luks bind -d /dev/sda1 pkcs11 '{"uri": "pkcs11:"}'
Еще более короткая команда настройки, эквивалентная предыдущей, показана ниже:
$ clevis luks bind -d /dev/sda1 pkcs11 '{}'
В этом случае Clevis будет отвечать за обнаружение устройства и, если устройство не обнаружено, за сброс соответствующей ошибки.
Необходимо уточнить, что предоставление пустого URI заставит Clevis также предложить выбрать один из доступных ключей, совпадающих с токеном, чтобы избежать случайного шифрования нежелательными ключами.
Clevis может быть предоставлен путь к модулю, чтобы он использовал этот модуль для доступа к устройству. Это требуется только в том случае, если карта не поддерживается базовым программным обеспечением Clevis (OpenSC). По этой причине поле пути к модулю совершенно необязательно. Чтобы указать местоположение модуля, пользователь может указать «путь к модулю» к конфигурации 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"}'
Как и в случае с остальными устройствами, зашифрованные диски, привязанные к устройству PKCS#11, можно проверить командой 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"}'
На первом этапе разработки Clevis будет использоваться поверх OpenSC для обеспечения функциональности PKCS#11. OpenSC и, в частности, pkcs11-tool
предоставляют возможность указать механизм, который будет использоваться для расшифровки. В целях тестирования некоторые библиотеки, такие как SoftHSM), не работают с механизмом pkcs11-tool
по умолчанию, поэтому необходимо предоставить конкретный механизм для использования. По этой причине Clevis может быть снабжен механизмом, который можно использовать в случае, если механизм по умолчанию, RSA-PKCS-OAEP
, недействителен:
$ clevis luks bind -d /dev/sda1 pkcs11 '{"uri": "pkcs11:", "mechanism":"RSA-PKCS"}'
Чтобы проверить доступные механизмы для конкретного токена, можно использовать команду 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
В настоящее время Clevis поддерживает только механизмы RSA. Из-за ограничений остальных алгоритмов ни один другой асимметричный криптографический алгоритм не может легко выполнить шифрование. ECC поддерживает только подписи и получение ключей, но не шифрование. Операцию шифрования можно каким-то образом построить на основе получения ключа, но это непростая операция.
Следует подчеркнуть, что механизм RSA-PKCS (заполнение PKCS#1.5 для шифрования) считается небезопасным и в основном предусмотрен для совместимости, но использовать его в производстве не рекомендуется.
Clevis позволит указать слот, в котором находится устройство PKCS#11, с помощью параметров, предоставленных URI:
$ clevis luks bind -d /dev/sda1 pkcs11 '{"uri": "pkcs11:slot-id=0"}'
Необходимо пояснить, что предоставление только информации о слоте заставит Clevis угадать один из доступных ключей, совпадающих с токеном в выбранном слоте, что может привести к случайному шифрованию с использованием нежелательных ключей. Не рекомендуется использовать слот в качестве селектора устройства, поскольку идентификатор слота — это число, стабильность которого не гарантируется при инициализации модуля PKCS#11 . Однако существуют определенные библиотеки и модули, которые предоставляют стабильные идентификаторы слотов, поэтому их можно использовать для этих конкретных случаев.
Есть два лучших варианта различать разные устройства PKCS#11:
1 — Конфигурация нескольких устройств с объектом открытого ключа ( рекомендуется ):
В последних версиях OpenSC
(начиная с выпуска OpenSC 0.26.0), pkcs11-tool
, который используется Clevis для обработки большинства команд PKCS#11, URI PKCS#11 выгружается как для токенов, так и для объектов конкретный токен:
$ 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
В этом конкретном случае, когда существует несколько устройств PKCS#11, выберите открытый ключ конкретного устройства и привяжите его к 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"}'
Если вы используете путь к модулю, вам придется использовать тот, который возвращается при указании опции --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 — Конфигурация нескольких устройств с указанием последовательного порта и токена:
Для версий, в которых pkcs11-tool
не выгружает URI для токенов/объектов , Clevis «опробует» конкретную идентификацию с использованием пары serial
устройства + token label
. В сценариях такого типа идентификация может быть выполнена с помощью этих двух параметров, хотя model
также должна быть предоставлена для облегчения информирования Clevis об устройстве при запросе 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"}'
Помните, что специальные символы должны определяться в процентном режиме, как определено в RFC 7512: Схема URI PKCS#11.
Для установки и настройки функции вилки PKCS#11 необходимо выполнить следующие шаги:
1. Установите необходимые зависимости Clevis, включая зависимости PKCS#11:
$ sudo dnf install -y opensc pcsc-lite openssl socat
2. Устройство PKCS11 должно быть доступно с помощью «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. Настройте устройство для привязки к вилке:
$ sudo clevis luks bind -d /dev/sda5 pkcs11 '{"uri":"pkcs11:"}'
Если необходимо предоставить модуль для использования, это можно сделать с помощью параметра URI module-path
:
$ sudo clevis luks bind -d /dev/sda5 pkcs11 '{"uri":"pkcs11:module-path=/usr/lib64/libykcs11.so.2"}'
4 — Включить модуль clevis-luks-pkcs11-askpass.socket:
$ sudo systemctl enable --now clevis-luks-pkcs11-askpass.socket
5 — конфигурация /etc/crypttab:
Для правильной работы функции PKCS#11 файл /etc/crypttab
должен быть настроен так, чтобы systemd использовал сокет AF_UNIX для ожидания ключевой фразы, которая разблокирует диск, а не запрашивал ее через консоль.
Юнит-файл Clevis PKCS#11 настроит сокет по пути /run/systemd/clevis-pkcs11.sock
для отправки и получения информации о разблокировке диска. Для дисков, которые будут разблокированы с помощью штифта PKCS#11 Clevis, этот файл сокета должен быть настроен как файл ключа. Итак, для разблокировки необходимо внести следующее изменение в /etc/crypttab
:
$ 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
Настоятельно рекомендуется установить параметр keyfile-timeout
, чтобы настроить механизм обхода на случай, если произойдет какая-либо ошибка разблокировки и потребуется ввести парольную фразу вручную через консоль.
6 - Перезагрузитесь и проверьте:
Система должна загрузиться и запросить PIN-код устройства PKCS#11, а также расшифровать соответствующий настроенный зашифрованный диск только в том случае, если PIN-код верен.
7. Если нет необходимости тестировать процесс загрузки, зашифруйте и расшифруйте его с помощью следующей команды (обратите внимание, что для правильной работы необходимо указать значение PIN-кода) и проверьте, что шифрование/дешифрование строки может быть выполнено с помощью этой однострочной команды. , и никакой ошибки не происходит:
$ echo "top secret" | clevis encrypt pkcs11 '{"uri":"pkcs11:module-path=/usr/lib64/libykcs11.so.2?pin-value=123456"}' | clevis decrypt
Должна быть возвращена top secret
строка
Clevis предоставляет возможность смешивать контакты для обеспечения сложной политики разблокировки. Это достигается с помощью алгоритма Shamir Secret Sharing (SSS).
SSS — это схема определения порога. Он создает ключ и делит его на несколько частей. Каждая часть шифруется с помощью другого PIN-кода (возможно, даже рекурсивно SSS). Кроме того, вы определяете порог t
. Если можно расшифровать хотя бы t
частей, то ключ шифрования можно восстановить и расшифровка может быть успешной.
Вот пример, в котором мы используем вывод SSS одновременно с выводами Tang и TPM2:
$ echo hi | clevis encrypt sss
' {"t": 2, "pins": {"tpm2": {"pcr_ids": "0"}, "tang": {"url": "http://tang.local"}}} '
> hi.jwe
В приведенном выше примере мы определяем два дочерних контакта и устанавливаем пороговое значение 2. Это означает, что во время расшифровки оба дочерних контакта должны быть успешными, чтобы сам SSS завершился успешно.
Вот еще один пример, где мы используем только булавку Tang:
$ echo hi | clevis encrypt sss
' {"t": 1, "pins": {"tang": [{"url": "http://server1.local/key"}, {"url": "http://server2.local/key"}]}} '
> hi.jwe
В этом примере мы определяем два дочерних экземпляра вывода Tang — каждый со своей собственной конфигурацией. Поскольку у нас есть порог 1, если какой-либо из экземпляров вывода Tang увенчается успехом во время расшифровки, SSS будет успешным.
Clevis можно использовать для привязки тома LUKS с помощью булавки, чтобы его можно было автоматически разблокировать.
Как это работает, довольно просто. Мы генерируем новый, криптостойкий ключ. Этот ключ добавляется в LUKS в качестве дополнительной фразы-пароля. Затем мы шифруем этот ключ с помощью Clevis и сохраняем выходной JWE внутри заголовка LUKS с помощью LUKSMeta.
Вот пример, в котором мы привязываем /dev/sda1
с помощью вывода 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:
После успешного завершения процесса привязки диск можно будет разблокировать с помощью одного из предоставленных средств разблокировки.
Если вы хотите использовать разблокировку по сети, вам нужно будет указать rd.neednet=1
в качестве аргумента ядра или использовать --hostonly-cmdline
при создании с помощью dracut.
Если вы используете Tang с TLS (пример: '{"url": "https://tang.remote"}'
), папка /etc/ssl
должна быть включена в образ initramfs, --include /etc/ssl /etc/ssl --force
при создании с помощью dracut.
Программа разблокировки Dracut пытается автоматически разблокировать тома во время ранней загрузки. Это позволяет автоматически шифровать корневой том. Включить разблокировку Dracut очень просто. Просто пересоберите initramfs после установки Clevis:
$ sudo dracut -f
После перезагрузки вам будет предложено разблокировать том с помощью пароля. В фоновом режиме Clevis попытается автоматически разблокировать громкость. Если это удастся, запрос пароля будет отменен, и загрузка продолжится.
При использовании Clevis с инструментами initramfs, чтобы пересобрать initramfs, вам нужно будет запустить:
sudo update-initramfs -u -k ' all '
После перезагрузки он будет вести себя точно так же, как при использовании Dracut.
Наш разблокировщик UDisks2 работает в сеансе вашего рабочего стола. Вам не нужно включать его вручную; просто установите разблокировщик Clevis UDisks2 и перезапустите сеанс рабочего стола. Анлокер должен запуститься автоматически.
Этот разблокировщик работает почти так же, как и разблокировщик Dracut. Если вы вставите съемное запоминающее устройство, привязанное к Clevis, мы попытаемся автоматически разблокировать его параллельно с запросом пароля на рабочем столе. Если автоматическая разблокировка прошла успешно, запрос пароля будет закрыт без вмешательства пользователя.
Устройство LUKS, привязанное к политике Clevis, также можно разблокировать с помощью команды разблокировки clevis luks.
$ sudo clevis luks unlock -d /dev/sda1
Тома LUKS можно отвязать с помощью команды clevis luks unbind. Например:
$ sudo clevis luks unbind -d /dev/sda1 -s 1
Контакты, привязанные к данному тому LUKS, можно перечислить с помощью команды clevis luks list. Например:
$ sudo clevis luks list -d /dev/sda1
Пожалуйста, не устанавливайте Clevis напрямую. Вместо этого используйте пакеты предпочитаемого вами дистрибутива.
Эта команда устанавливает основные команды Clevis, разблокировщик Dracut и разблокировщик UDisks2 соответственно.
$ sudo dnf install clevis clevis-dracut clevis-udisks2
Как отмечалось в предыдущем разделе, рекомендуется не устанавливать Clevis напрямую . Однако, если для вашего дистрибутива Linux не существует пакетов Clevis, шаги по ручной компиляции и установке Clevis следующие:
$ 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
для настройки компиляции: $ meson setup ..
ninja
: $ ninja
ninja install
(для этого вам потребуются права root): $ sudo ninja install