Clevis
Clevis — это фреймворк автоматической расшифровки данных с использованием внешних источников ключей (PIN). Он интегрируется с LUKS, systemd и другими системами шифрования, позволяя расшифровывать тома без ввода пароля при выполнении определённых условий.
Clevis поддерживает несколько типов PIN-модулей:
- tpm2 — привязка ключа к модулю доверенной платформы TPM 2.0 с использованием регистров конфигурации платформы (PCR);
- tang — удалённый сервер аутентификации Tang для автоматической расшифровки по сети;
- sss — схема разделения секрета (Shamir's Secret Sharing) между несколькими источниками ключей.
При использовании с LUKS2 clevis записывает в дополнительный слот ключ, зашифрованный с помощью выбранного PIN-модуля. При загрузке система автоматически пытается расшифровать том, используя указанный источник ключа. Если автоматическая расшифровка невозможна (например, сервер Tang недоступен, изменены PCR TPM или недоступен один из узлов SSS), пользователю предлагается ввести пароль вручную.
Основные возможности:
- автоматическая расшифровка без вмешательства пользователя;
- поддержка удалённых и аппаратных источников ключей;
- интеграция с dracut и initramfs для расшифровки корневых томов на этапе загрузки.
Установка
Установить пакет clevis:
# apt-get install clevis
Команда clevis
Синтаксис команды clevis:
clevis <команда> [ОПЦИИ]
где команда может принимать одно из следующих значений:
- decrypt — расшифровывает данные с использованием политики, заданной при шифровании;
- decrypt tpm2plus — расшифровывает с использованием политики привязки к чипу TPM 2.0;
- encrypt sss — шифрует с использованием политики разделения секрета (Shamir's Secret Sharing);
- encrypt tang — шифрует с использованием политики привязки к серверу Tang;
- encrypt tpm2plus — шифрует с использованием политики привязки к чипу TPM 2.0;
- luks bind — привязывает устройство LUKS с использованием указанной политики;
- luks edit — редактирует привязку в слоте LUKS, настроенном через clevis;
- luks list — показывает PIN-модули, привязанные к устройству LUKSv1 или LUKSv2;
- luks pass — возвращает пароль LUKS, использованный при привязке конкретного слота;
- luks regen — перегенерирует привязку clevis;
- luks report — показывает отчёт о ротации ключей на сервере Tang;
- luks unbind — удаляет привязку PIN-модуля от тома LUKS;
- luks unlock — разблокирует том LUKS;
- pin tpm2 — шифрует с использованием политики привязки к чипу TPM 2.0.
Использование
Базовые функции Clevis
Шифрование с использованием Tang
Tang — это сервер для сетевой привязки данных, позволяющий разблокировать зашифрованные ресурсы при подключении к доверенной сети. Он обеспечивает безопасный доступ без необходимости хранения ключей на сервере.
Основные особенности:
- не требует TLS или аутентификации;
- в отличие от эскроу-серверов (где сервер хранит и знает все ключи), Tang никогда не видит клиентские ключи и не получает от клиента никакой идентифицирующей информации;
- клиент и сервер используют библиотеку JWK (JSON Web Key) и операции JWE (JSON Web Encryption) через библиотеку jose.
- Установить пакеты tang и jose:
# apt-get install tang jose
- Создать пользователя tang и каталог /var/db/tang:
# useradd tang -d /dev/null -s /sbin/nologin # mkdir -p /var/db/tang
- Запустить службу tangd:
# systemctl enable --now tangd.socket
Проверка порта:
# systemctl show tangd.socket -p Listen
Listen=[::]:80 (Stream)
По умолчанию сервер Tang использует порт 80.
Проверка ключей
$ tang-show-keys
QhZ1UpB6AvonXY0O6CWHCB4gKGG-TaJEk99ZWsWdVMQ
Проверить доступность сервера Tang можно с помощью тестового шифрования/расшифрования:
$ echo test | clevis encrypt tang '{"url":"http://tang.srv:port"}' -y | clevis decrypt
test
Например:
$ echo test | clevis encrypt tang '{"url":"192.168.0.178:80"}' -y | clevis decrypt
test
Шифрование файла:
$ clevis encrypt tang '{"url":"192.168.0.178:80"}' < test.txt > encrypt.jwe
The advertisement contains the following signing keys:
QhZ1UpB6AvonXY0O6CWHCB4gKGG-TaJEk99ZWsWdVMQ
Do you wish to trust these keys? [ynYN] y
Расшифровка файла:
$ clevis decrypt < encrypt.jwe > decrypt.txt
Если клиент не может подключиться к серверу Tang по сети (например, при автономной работе), можно загрузить рекламацию (advertisement) заранее:
$ curl -sfg http://192.168.0.178:80/adv -o adv.jws
Загруженный файл можно использовать для шифрования:
$ echo 'hello' | clevis encrypt tang '{"url":"http://192.168.0.178:80","adv":"adv.jws"}'
Шифрование с использованием TPM 2.0
Для шифрования данных с использованием TPM 2.0 используется подкоманда clevis encrypt tpm2:
# clevis encrypt tpm2 '{}' < test.txt > encrypt.jwe
где '{}' — JSON-объект с параметрами шифрования.
Пример с указанием алгоритмов:
# clevis encrypt tpm2 '{"hash":"sha256","key":"rsa"}' < test.txt > encrypt.jwe
Пример с указанием PCR индексов:
# clevis encrypt tpm2 '{"pcr_bank":"sha256","pcr_ids":"0,7"}' < test.txt > encrypt.jwe
Расшифровка файла:
# clevis decrypt < encrypt.jwe > newfile.txt
Использование с LUKS2
В примерах ниже используется блочное устройство /dev/sdb1.
- Инициализация LUKS2 на устройстве:
# cryptsetup luksFormat --type luks2 /dev/sdb1
- Создание файловой системы:
# cryptsetup open /dev/sdb1 sdb1_encrypted # mkfs.ext4 /dev/mapper/sdb1_encrypted # cryptsetup close sdb1_encrypted
Привязка тома LUKS2 к серверу Tang
Привязка LUKS2 к серверу Tang:
# clevis luks bind -d /dev/sdb1 tang '{"url":"192.168.0.178:80"}'
Enter existing LUKS password:
The advertisement contains the following signing keys:
QhZ1UpB6AvonXY0O6CWHCB4gKGG-TaJEk99ZWsWdVMQ
Do you wish to trust these keys? [ynYN] Y
Эта команда выполняет четыре шага:
- Генерирует новый ключ с той же энтропией, что и главный ключ LUKS.
- Шифрует ключ с помощью Clevis.
- Сохраняет объект Clevis JWE в токене заголовка LUKS2.
- Добавляет ключ в свободный слот LUKS.
После привязки том можно разблокировать:
- с помощью существующего пароля;
- автоматически — при доступе к серверу Tang.
Проверка привязки:
# clevis luks list -d /dev/sdb1
1: tang '{"url":"192.168.0.178:80"}
Ручная разблокировка:
# clevis luks unlock -d /dev/sdb1
Привязка тома LUKS2 к TPM 2.0
Привязка LUKS-раздела к TPM 2.0:
# clevis luks bind -d /dev/sdb1 tpm2 '{}'
Данная команда:
- Генерирует случайный ключ.
- Добавляет ключ в свободный слот LUKS2.
- Шифрует ключ с помощью TPM.
- Сохраняет зашифрованный ключ в заголовке LUKS2.
- Включает новый ключ для использования с LUKS.
В команде clevis luks bind можно указать алгоритм хеширования и ключ шифрования:
# clevis luks bind -d /dev/sda2 tpm2 '{"hash":"sha256","key":"rsa"}'
Если необходимо привязать данные к определенным состояниям регистров конфигурации платформы (PCR), в команду можно добавить значения pcr_bank и pcr_ids:
# clevis luks bind -d /dev/sdb2 tpm2 '{
"key": "rsa",
"pcr_bank": "sha256",
"pcr_ids": "0,4,7"
}'
Разблокировка возможна только при совпадении текущих значений PCR с политикой. Изменение загрузочной цепочки (например, обновление GRUB или ядра)может нарушить совпадение.
Рекомендуется сохранить резервный пароль, чтобы иметь возможность вручную разблокировать том при изменении состояния системы.
Просмотреть, какие политики привязаны к зашифрованному тому LUKS, а также узнать параметры, которые используются для защиты ключа расшифровки, можно, выполнив команду:
# clevis luks list -d /dev/sdb2
1: tpm2 '{"hash":"sha256","key":"ecc"}'
Ручная разблокировка тома, привязанного к TPM:
# clevis luks unlock -d /dev/sdb1
Настройка автоматической разблокировки с помощью TPM:
- Получить UUID зашифрованного диска:
# cryptsetup luksUUID /dev/sdb1 cec42bd7-861f-4993-92c6-42be634af1a5
- Добавить запись в /etc/crypttab:
sdb1_encrypted UUID=b27f138c-25e9-4d5d-9ac2-0d89ecb4fcd9 none luks,discard
- Обновить initramfs:
# dracut --force
- Включить службу подсказки пароля:
# systemctl enable clevis-luks-askpass.path
- Перезагрузить узел.
После перезагрузки появится запрос на ввод фразы-пароля. Если не вводить пароль вручную, через некоторый период времени (~ 1 минута) TPM автоматически разблокирует диск (если PCR совпадают).
Удаление привязки
Чтобы удалить привязку Clevis, следует выполнить:
# clevis luks unbind -d /dev/sdb1 -s keyslot
cryptsetup luksDump /dev/sdb1
Tokens:
0: clevis
Keyslot: 1