Расшифровка диска при загрузке по ключу

Материал из База знаний проекта Russian Fedora

Перейти к: навигация, поиск

Настоящая статья описывает, как добиться монтирования зашифрованного раздела (будь то root или /home) системы при загрузке без необходимости ввода пароля (по ключу, сохранённому на usb-flash накопителе). Если накопитель отсутствует, потребуется ввод пароля на разблокировку. Предполагается, что у вас уже есть зашифрованный LUKS раздел (см. Монтируемый при загрузке зашифрованный раздел, или, лучше, статью на Fedoraproject, как более актуальную и точную).

Несмотря на то, что автор считает методы, описанные в данной статье, в целом безопасными для данных, настоятельно рекомендуется пробовать и экспериментировать только на тестовых полигонах. Например, на специально созданных виртуальных машинах

Содержание

Выбор постоянного наименования носителя

Для передачи информации о носителе с ключем есть несколько способов. Вы можете выбрать тот, который больше всего вам подойдёт. Для достижения высокой скорости загрузки желательно использовать функции udev, а не обычные наименования устройств, как '/dev/sdb1', так как наименования могут смениться при подключении или отключении устройств.

Постоянные ссылки на устройства

Простейшими способами (по сравнению с настройкой правил udev) для указания носителя являются ссылки на его id (информацию о железе и серийный номер), метке тома файловой системы и UUID. Вставьте устройство, на котором планируете разместить ключ, и ознакомьтесь с разными типами ссылок на него:

# ls -lR /dev/disk/
/dev/disk/:
total 0
drwxr-xr-x 2 root root 180 Feb 12 10:11 by-id
drwxr-xr-x 2 root root  60 Feb 12 10:11 by-label
drwxr-xr-x 2 root root 100 Feb 12 10:11 by-path
drwxr-xr-x 2 root root 180 Feb 12 10:11 by-uuid
/dev/disk/by-id:
total 0
lrwxrwxrwx 1 root root  9 Feb 12 10:11 usb-Generic_STORAGE_DEVICE_000000014583-0:0 -> ../../sdb
lrwxrwxrwx 1 root root 10 Feb 12 10:11 usb-Generic_STORAGE_DEVICE_000000014583-0:0-part1 -> ../../sdb1
/dev/disk/by-label:
total 0
lrwxrwxrwx 1 root root 10 Feb 12 10:11 Keys -> ../../sdb1
/dev/disk/by-path:
total 0
lrwxrwxrwx 1 root root  9 Feb 12 10:11 pci-0000:00:1d.7-usb-0:1:1.0-scsi-0:0:0:0 -> ../../sdb
lrwxrwxrwx 1 root root 10 Feb 12 10:11 pci-0000:00:1d.7-usb-0:1:1.0-scsi-0:0:0:0-part1 -> ../../sdb1
/dev/disk/by-uuid:
total 0
lrwxrwxrwx 1 root root 10 Feb 12 10:11 baa07781-2a10-43a7-b876-c1715aba9d54 -> ../../sdb1

UUID

Использование UUID даёт наибольшую достоверность идентичности устройства. UUID сохраняется непосредственно в файловой системе устройства, что означает, что эта метка будет той же самой в любое время и в любом компьютере. Это позволяет, например, использовать dd для сохранения и восстановления образа устройства с сохранением его UUID, без необходимости перенастраивать систему шифрования. В то же время, накопитель с данным UUID будет существовать только в единственном числе (без применения недокументированных возможностей).

UUID всегда будет иметь символьную ссылку на файл устройства (в нашем случае /dev/sdb1). Символьные ссылки могут использоваться загрузчиком для передачи пути к ключу ядру, или в любом другом случае.

Устаревшие файловые системы типа FAT имеют короткий UUID, что в редких случаях может приводить к коллизиям.

Метки

В нашем примере раздел FAT имеет метку "Keys" и будет всегда иметь ссылку с /dev/disk/by-label/Keys:

#mkdosfs -n >volume-name< /dev/sdb1
#blkid -o list
device     fs_type label    mount point    UUID
-------------------------------------------------------
/dev/sdb1  vfat    Keys     (not mounted)  221E-09C0
Если вы планируете хранить ключ между MBR и первым разделом, вы не можете использовать этот метод, потому что он даёт доступ только к разделам (sdb1, sdb2, ...), а не к самому устройству (sdb). Используйте /dev/disk/by-id/* или правила udev, как описано ниже.


Постоянное правило udev

Возможно, будет описано позже. Можете посмотреть в комментарии к данной статье.

Создание ключа

Вы можете примонтировать tmpfs для временного хранения файла ключа:

# mkdir ./mytmpfs
# mount tmpfs ./mytmpfs -t tmpfs -o size=32m
# cd ./mytmpfs

Ключ при этом сохранится в ОЗУ, а не на диске, и после размонтирования или удаления от него не останется следов. Так что перед отключением tmpfs не забудьте скопировать ключ туда, где он будет у вас храниться. Если вы планируете хранить ключ как обычный файл на накопителе, можете просто выполнить следующую комманду в желаемой папке накопителя, например, /run/media/<user>/sdb1

Основные характеристики ключа - это его содержимое и размер. Ключ тем устойчивее к атакам, чем случайнее его содержимое и больше размер. Сгенерируем ключ размером 2048 байт с помощью генератора случайных чисел (этого более, чем достаточно для большинства случаев).

# dd if=/dev/urandom of=secretkey bs=512 count=4

Вместо /dev/urandom можно использовать /dev/random, он генерирует более случайные значения, но вам потребуется много терпения.

Если вы разместили ваш ключ на физическом устройстве временно для того, чтобы скопировать на накопитель позднее, не забудьте стереть его следы, например, так:

cp secretkey /destination/path
shred --remove --zero secretkey

Однако, при использовании журналируемых файловых систем, накопителях flash и т. п. этот способ не подходит. Используйте, например:

mv secretkey /destination/path
# dd if=/dev/null of=wipe.tmp
# rm wipe.tmp

Это долго и неудобно, поэтому предпочтительнее использовать tmpfs или сразу писать ключ на целевой накопитель.

Добавим слот в раздел LUKS, внесём в него наш ключ (будет запрошен текущий пароль):

# cryptsetup luksAddKey /dev/sda2 secretkey
Enter any LUKS passphrase:
key slot 0 unlocked.
Command successful.

Хранение ключа на носителе

Существует два способа хранить ключ на носителе: непосредвтвенно в файловой системе и между MBR и первым разделом. Второй способ, теоретически, более устойчив, потому что ключ не «светится» при стандартном использовании накопителя, но имеет проблемы, связанные с использованием этой области загрузчиком GRUB2 и UEFI, поэтому будет описан при успешном исследовании.

Хранение ключа в виде файла на разделе

На всякий присвойте файлу, содержащему ключ, имя, не связанное с ключами и криптографией. Не используйте скрытие файла (.filename): это может вызвать проблемы при поиске его во время загрузки.

Для доступа к ключу на внешнем носителе, воспользуемся функционалом, дарованным нам системой загрузки dracut.

Для этого отредактируем конфигурационный файл GRUB2, находящийся по пути /etc/default/grub. В строку GRUB_CMDLINE_LINUX добавим параметр

rd.luks.key=<keypath>:<keydev>:<luksdev>

где <keypath> - путь к файлу ключа относительно корня раздела <keydev> - сам раздел, <luksdev> - раздел с зашифрованным томом LUKS.

В keydev можно использовать непосредственный путь к устройству (/dev/sdb2), или, что более предпочтительно, его UUID (UUID=baa07781-2a10-43a7-b876-c1715aba9d54) или метку (LABEL=Keys) (см. выше).

luksdev предопределяет использование ключа только для данного устройства LUKS. Правила обозначения те же, что и в keydev.

keydev можно вообще не использовать, но это увеличит время загрузки для поиска ключа на носителях. luksdev можно не использовать, тогда ключ будет подбираться для всех зашифрованных разделов.

Пример: ключ сохранён в файле command.com, находящемся в корне раздела с меткой Keys на usb-flash накопителе. Добавим к параметру GRUB_CMDLINE_LINUX в /etc/default/grub описание:

rd.luks.key=/command.com:LABEL=Keys

Создадим конфиг загрузчика:

# grub2-mkconfig -o /boot/grub2/grub.cfg

Вставляем накопитель с ключём, перезагружаемся, наслаждаемся.

В Fedora 18 существует ошибка, при которой rd.luks.keys не распознаётся скриптом systemd-cryptsetup-generator. До тех пор, пока она не будет исправлена, существует временная затычка (см. ниже). При этом необходимо учесть, что если ключ не найден, вам будет выведено предложение о вводе пароля в текстовом режиме.
# echo 'omit_dracutmodules+=" systemd "' > /etc/dracut.conf.d/luks-workaround.conf
# dracut -f
Если что-то не работает, для отладки удалите параметр ядра quiet из раздела GRUB_CMDLINE_LINUX файла /etc/default/grub, тогда сможете видеть полный журнал. Не обращайте внимание на то, что ключ находится со второй-третьей ошибки: это связано с невозможностью мгновенного подключения usb-flash.


Ссылки

[1] Статья на ArchWiki про связку dm-crypt и LUKS, нам бы такую wiki!

[2] Тема на форуме fedoraforum.org про то же самое

[3] Описание dracut

[4] Ошибка в Fedora, ждём, когда исправят, и удаляем костыль (/etc/dracut.conf.f/luks-workaround.conf)