Сегодня мы будем установливать Linux на шифрованный корневой раздел, настроим авторазблокировку при старте с помощью модуля TPM и новой функции systemd-cryptsetup. И будем бекапить ключ восстановления в Active Directory. В моем случае будет использоваться Arch Linux, но вы можете проделать тоже самое в любом дистрибутиве.
Еще по теме: Создание VPN-туннеля в Linux и Windows
Установка Linux на шифрованный диск
Хотелось бы не вводить пароль при загрузке каждый раз. Для этого нужно настроить авторазблокировку LUKS с помощью чипа TPM.
Убедимся, что мы счастливые обладатели TPM. Необходимая версия TPM — 2.0.
1 2 3 4 5 6 7 |
$ test -e /dev/tpm0 && echo PASS || echo FAIL PASS $ cat /sys/class/tpm/tpm0/device/description TPM 2.0 Device or $ cat /sys/class/tpm/tpm0/tpm_version_major 2 |
Авторазблокировку сделаем с помощью относительно новой фичи systemd-cryptsetup.
Systemd-cryptsetup добавлена в systemd начиная с версии 248.
Для начала необходимо проверить нашу версию systemd:
1 2 3 |
$ systemctl --version systemd 249 (249.2-1-arch) +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 +BZIP2 +LZ4 +XZ +ZLIB +ZSTD +XKBCOMMON +UTMP -SYSVINIT default-hierarchy=unified |
Все отлично. Для работы с TPM нужно дополнительно установить пакет tpm2-tss:
1 |
$ pacman -Sy tpm2-tss |
Далее добавим ключ TPM в слот LUKS с помощью тулзы systemd-cryptenroll:
1 |
$ systemd-cryptenroll /dev/sda2 --tpm2-device=auto --tpm2-pcrs=0,4 |
Не забываем проверить:
1 2 3 4 5 |
$ systemd-cryptenroll /dev/sda2 SLOT TYPE --------- 0 password 1 tpm2 |
В команде выше мы указали параметр --tpm2-pcrs=0,4. Что такое PCR? Вот определение из Википедии:
PCR — это внутренние регистры памяти TPM, в которых в зашифрованном виде содержится вся информация о целостности метрик системы, начиная с загрузки BIOS до завершения работы системы. Информация, содержащаяся в PCR, формирует корень доверия для измерений (RTM). Могут храниться как в энергонезависимой, так и в энергозависимой памяти. Эти регистры сбрасываются при старте и при перезагрузке системы. Спецификация предписывает минимальное количество регистров (16), каждый регистр содержит 160 бит информации. Регистры 0–7 зарезервированы для нужд TPM. Регистры 8–15 доступны для использования операционной системой и приложениями. Изменения значений PCR необратимы, и их значения нельзя записать напрямую, их можно только расширить новыми значениями, которые зависят от предыдущих. Все изменения значений PCR записываются в лог изменений, который хранится в энергозависимой памяти.
PCR | Use |
---|---|
PCR0 | Core System Firmware executable code (aka Firmware) |
PCR1 | Core System Firmware data (aka UEFI settings) |
PCR2 | Extended or pluggable executable code |
PCR3 | Extended or pluggable firmware data |
PCR4 | Boot Manager |
PCR5 | GPT / Partition Table |
PCR6 | Resume from S4 and S5 Power State Events |
PCR7 | Secure Boot State |
PCR8 | Hash of the booted kernel |
PCR 9 to 10 | Reserved for Future Use |
PCR11 | BitLocker Access Control |
PCR12 | Data events and highly volatile events |
PCR13 | Boot Module Details |
PCR14 | Boot Authorities |
PCR 15 to 23 | Reserved for Future Use |
Для включения systemd-cryptsetup необходимо добавить в /etc/mkinicpio.conf хуки systemd и sd-encrypt.
1 2 |
HOOKS=(base systemd modconf block keyboard sd-encrypt filesystems fsck) $ mkinicpio -P |
Наконец, изменим строку загрузки, добавив параметры rd.luks.name и rd.luks.name.
1 2 3 4 5 6 7 8 9 10 11 12 |
$ blkid /dev/sda2 /dev/sda2: UUID="e04b5b87-6bfc-4f73-83b0-36f91d52f141" TYPE="crypto_LUKS" PARTLABEL="primary" PARTUUID="136ffe26-5569-4c76-a871-9025ea52dbd8" $ efibootmgr \ --create \ --bootnum=0001 \ --label "Arch Linux" \ --disk /dev/sda \ --part 1 \ --loader /vmlinuz-linux \ --unicode 'rd.luks.name=e04b5b87-6bfc-4f73-83b0-36f91d52f141=cryptroot rd.luks.options=tpm2-device=auto root=/dev/mapper/cryptroot rootflags=subvol=@root rw initrd=\initramfs-linux.img' \ --verbose |
Перезагружаемся и проверяем, что все работает как надо.
Для тех, кому systemd-cryptsetup по каким‑то причинам не подходит (например, версия systemd старая или вообще нет systemd), могу порекомендовать фреймворк Clevis. С его помощью можно реализовать следующие сценарии авторазблокировки LUKS:
- tpm2 — разблокировка с TPM;
- tang — разблокировка с сетевого сервера.
Вот как использовать Сlevis с TPM:
1 2 |
$ clevis luks bind -d /dev/sda2 tpm2 '{"pcr_bank":"sha1","pcr_ids":"0,4"}' Enter existing LUKS password: *************** |
Проверяем:
1 2 |
$ sudo clevis luks list -d /dev/sda2 1: tpm2 '{"hash":"sha256","key":"ecc","pcr_bank":"sha1","pcr_ids":"0,4"} |
Вариант с сервером tang настраивается не сложнее (разумеется, заранее разворачиваем tang и обеспечиваем сетевую доступность):
1 2 3 4 5 6 7 |
$ sudo clevis luks bind -d /dev/sda2 tang '{"url":"http://192.168.88.101:7500"}' The advertisement contains the following signing keys: QjvwIdUeor3gBqxLteIOKvWPRqM Do you wish to trust these keys? [ynYN] y Enter existing LUKS password: |
Проверяем:
1 2 3 |
$ sudo clevis luks list -d /dev/sda2 1: tpm2 '{"hash":"sha256","key":"ecc","pcr_bank":"sha1","pcr_ids":"0,4"}' 2: tang '{"url":"http://192.168.88.101:7500"}' |
В заключение темы авторазблокировки стоит упомянуть некоторые ограничения фреймворка Clevis:
- Clevis работает только с TPM 2.0; TPM 1.2 не поддерживается.
- В Tang не реализован механизм смены ключей.
- Для Tang необходима доступность сети на этапе загрузки, поэтому, например, для Wi-Fi-подключения требуется дополнительная настройка адаптера в initrd.
Создание ключей восстановления
Бэкапы ключей в таком деле, как шифрование, должны быть, об этом знает каждый.
Есть два варианта создания ключей восстановления:
- дамп заголовка и мастер‑ключа;
- запись пароля восстановления в Active Directory.
Создаем копию мастер-ключа
Сделать резервную копию заголовка и мастер‑ключа можно с помощью хорошо известной нам утилиты cryptsetup.
С помощью созданной копии можно будет получить доступ к разделу, не зная пароль, поэтому нас заботливо предупреждают, что хранить ее нужно в секрете!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
$ cryptsetup luksDump --dump-master-key /dev/sda2 --master-key-file mk.dump WARNING! ======== The header dump with volume key is sensitive information that allows access to encrypted partition without a passphrase. This dump should be stored encrypted in a safe place. Are you sure? (Type 'yes' in capital letters): YES Enter passphrase for /dev/sda2: LUKS header information for /dev/sda2 Cipher name: aes Cipher mode: xts-plain64 Payload offset: 32768 UUID: e04b5b87-6bfc-4f73-83b0-36f91d52f141 MK bits: 512 Key stored to file mk.dump $ xxd mk.dump 00000000: 1501 eccc 84fd 82f7 f53b 56ae 4ab8 5775 .........;V.J.Wu 00000010: 4968 ea61 8d01 1f29 985e 33af 5537 ba40 Ih.a...).3.U7.@ 00000020: af61 6aa2 b384 afe1 aff6 d4c9 ad95 1d67 .aj............g 00000030: 3a4f d64f 33ea 6f50 0a18 1139 9196 d694 :O.O3.oP...9.... |
При необходимости можно восстановить заголовок и установить новый пароль.
1 2 3 |
$ cryptsetup luksAddKey /dev/sda2 --master-key-file mk.dump Enter new passphrase for key slot: ******** Verify passphrase: ******** |
Добавление пароля восстановления в Active Directory
Другой интересный способ — это хранение пароля в AD.
Для начала нужно включить нашу Arch Linux в домен. Делать это буду с помощью System Security Services Daemon (SSSD) и realmd.
Устанавливаем sssd обычным способом:
1 |
$ pacman -Sy sssd |
А realmd ставим из AUR.
Убедимся, что домен доступен:
1 2 3 4 5 6 7 8 |
$ realm discover ad.localdomain ad.localdomain type: kerberos realm-name: AD.LOCALDOMAIN domain-name: ad.localdomain configured: no server-software: active-directory client-software: sssd |
Присоединяемся к домену, для этого понадобится учетная запись с правами ввода в домен (для простоты — administrator).
1 2 |
$ realm join ad.localdomain Password for Administrator: ******** |
Проверяем, что все прошло успешно и мы получили билеты Kerberos:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
$ realm list ad.localdomain type: kerberos realm-name: AD.LOCALDOMAIN domain-name: ad.localdomain configured: kerberos-member server-software: active-directory client-software: sssd login-formats: %U@ad.localdomain login-policy: allow-realm-logins $ klist -k Keytab name: FILE:/etc/krb5.keytab KVNO Principal ---- -------------------------------------------------------------------------- 2 ARCH$@AD.LOCALDOMAIN 2 ARCH$@AD.LOCALDOMAIN 2 ARCH$@AD.LOCALDOMAIN 2 host/ARCH@AD.LOCALDOMAIN 2 host/ARCH@AD.LOCALDOMAIN 2 host/ARCH@AD.LOCALDOMAIN 2 RestrictedKrbHost/ARCH@AD.LOCALDOMAIN 2 RestrictedKrbHost/ARCH@AD.LOCALDOMAIN 2 RestrictedKrbHost/ARCH@AD.LOCALDOMAIN |
Пароль восстановления будем хранить в учетной записи компьютера: это дочерний объект класса msFVE-RecoveryInformation. Так делает виндовый BitLocker, аналогично поступим и мы.
Записывать пароль в AD буду с помощью скрипта на Python:
1 2 3 |
$ git clone https://github.com/ambalabanov/lukscrow $ cd lukscrow/ $ pip install -r requirements.txt |
Запускаем утилиту, указав необходимые параметры и текущий ключ (пароль):
1 2 3 4 5 6 7 8 9 10 |
$ ./lukscrow --luks-device /dev/sda2 --ldap-url "ldap://ad.localdomain" --computers-base-dn "CN=Computers,DC=ad,DC=localdomain" --unlock-key ******** Using Kerberos credential cache /tmp/tmpcsdyn49r Connected to AD as 'u:AD\ARCH$' Generating recovery key... Adding recovery key to LUKS volume... New key added. Storing recovery key in Active Directory Recovery key saved to AD. Remove Kerberos credential cache /tmp/tmpcsdyn49r Removed cache file. |
Проверяем в AD, что пароль восстановления успешно записался.
Ну и напоследок проверяем сам пароль.
1 2 3 |
$ sudo cryptsetup --test-passphrase luksOpen /dev/sda2 && echo TRUE || echo FALSE Enter passphrase for /dev/sda2: 287781-171655-523297-666928-307170-072073-039516-177220 TRUE |
Заключение
Итак, мы установили Arch Linux на шифрованный корневой раздел, настроили авторазблокировку при старте и позаботились о резервировании ключей. Надеюсь, для вас это тоже было увлекательным приключением!
ПОЛЕЗНЫЕ ССЫЛКИ:
- Как взломать TPM BitLocker
- Быстрая установка виртуальных машин на Linux
- Установка Tails на флешку с возможностью сохранения данных