dm-crypt (Русский)/Swap encryption (Русский)
Шифрование подкачки при помощи dm-crypt. В зависимости от требований могут использоваться различные методы шифрования раздела подкачки (свопа), которые описаны ниже. Настройка, при которой шифрование подкачки пересоздаётся при каждой загрузке (с новым ключом), обеспечивает более высокую защиту данных, поскольку предотвращает утечку чувствительной информации, которая могла быть выгружена в подкачку и сколько угодно длительное время не была перезаписана случайным образом другими данными поверх данной информации. Однако такое перешифрование при каждом новом запуске системы также делает невозможным использование функции гибернации (suspend-to-disk). В данной статье рассмотрены способы шифрования свопа как с поддержкой гипернации так и без неё.
Без поддержки гибернации
В системах, где гибернация (suspend-to-disk) не требуется, можно настроить /etc/crypttab
так, чтобы при загрузке раздел подкачки расшифровывался с использованием случайного пароля и обычного dm-crypt. Случайный пароль удаляется при выключении, оставляя в разделе подкачки только зашифрованные, недоступные данные.
Чтобы включить эту функцию, просто раскомментируйте строку, начинающуюся с swap
в /etc/crypttab
. Замените параметр устройства на имя вашего раздела подкачки. Например, это будет выглядеть примерно так:
/etc/crypttab
# <name> <device> <password> <options> swap /dev/sdX# /dev/urandom swap,cipher=aes-xts-plain64,size=512,sector-size=4096
Это сопоставит /dev/sdX#
(параметр, который требуется отредактировать) с /dev/mapper/swap
как раздел подкачки, который можно добавить в /etc/fstab
как обычный swap. Если у вас ранее был незашифрованный раздел подкачки, не забудьте его отключить — или переиспользуйте соответствующую запись в fstab, изменив устройство на /dev/mapper/swap
. Значения по умолчанию подходят для большинства случаев. Другие параметры и объяснение колонок смотрите в crypttab(5), а также в FAQ cryptsetup, пункт 2.3.
/dev/nvme#n#p#
аналогичны /dev/sdX#
, а устройства вида /dev/nvme#n#
— /dev/sdX
.
/dev/sda
, /dev/sdb
) может изменяться при каждой загрузке. Возможные варианты:
- Использовать пути
by-id
иby-path
. Однако они тоже чувствительны к изменениям оборудования. См. Persistent block device naming (Русский)#by-id и by-path. - Использовать PARTLABEL.
- Использовать имя логического тома LVM.
- Использовать метод, описанный в #UUID и LABEL. Метки и UUID нельзя использовать напрямую, поскольку при каждом запуске устройство подкачки пересоздаётся и перешифровывается с помощью
mkswap
, см. FAQ cryptsetup.
Чтобы использовать постоянное имя устройства by-id
вместо простого имени ядра, сначала определите устройство подкачки:
# find -L /dev/disk -samefile /dev/sdaX
/dev/disk/by-id/ata-WDC_WD2500BEVT-22ZCT0_WD-WXE908VF0470-partX /dev/disk/by-id/wwn-0x60015ee0000b237f-partX
Затем используйте один из найденных путей в качестве постоянной ссылки на раздел (вместо /dev/sdX#
):
/etc/crypttab
# <name> <device> <password> <options> swap /dev/disk/by-id/ata-WDC_WD2500BEVT-22ZCT0_WD-WXE908VF0470-partX /dev/urandom swap,cipher=aes-xts-plain64,size=512,sector-size=4096
После перезагрузки, активировав зашифрованный swap, можно увидеть с помощью swapon -s
, что для него создано устройство типа /dev/dm-1
, а команда lsblk
покажет тип crypt в колонке FSTYPE
. Из-за нового шифрования при каждом запуске UUID для /dev/mapper/swap
будет постоянно меняться.
UUID и LABEL
Опасно использовать crypttab swap с простыми именами устройств, такими как /dev/sdX#
или даже /dev/disk/by-id/ata-SERIAL-partX
. Небольшое изменение в разметке или порядке устройств может привести к тому, что /etc/crypttab
при следующей загрузке отформатирует важные данные. То же самое касается PARTUUID, если вы решите использовать этот раздел для других целей, но забудете удалить запись из crypttab.
Надёжнее использовать UUID или LABEL. По умолчанию это не работает, потому что dm-crypt и mkswap
перезапишут содержимое раздела, включая UUID и LABEL. Однако можно задать смещение, чтобы создать небольшую фиктивную файловую систему, которая будет служить только для хранения постоянной метки.
Создайте файловую систему с нужной меткой:
# mkfs.ext2 -L cryptswap /dev/sdX# 1M
Нетипичный параметр после имени устройства ограничивает размер файловой системы до 1 MiB, оставляя место для зашифрованной подкачки позади неё.
# blkid /dev/sdX#
/dev/sdX#: LABEL="cryptswap" UUID="b72c384e-bd3c-49aa-b7a7-a28ea81a2605" TYPE="ext2"
Теперь /dev/sdX#
можно легко идентифицировать по UUID или LABEL, даже если имя устройства или номер раздела изменятся. Останется только указать записи в /etc/crypttab
и /etc/fstab
. Пример с другими параметрами шифрования:
/etc/crypttab
# <name> <device> <password> <options> swap LABEL=cryptswap /dev/urandom swap,offset=2048,cipher=aes-xts-plain64,size=512,sector-size=4096
Обратите внимание на смещение: оно составляет 2048 секторов по 512 байт (не зависит от сектора dm-crypt), то есть 1 MiB. Таким образом, шифрованный swap не повредит метку/UUID файловой системы, и соблюдается выравнивание данных.
/etc/fstab
# <filesystem> <dir> <type> <options> <dump> <pass> /dev/mapper/swap none swap defaults 0 0
С такой настройкой cryptswap будет использовать только раздел с указанной LABEL, независимо от его имени в системе. Если вы решите использовать этот раздел для других целей, форматирование удалит метку, и /etc/crypttab
больше не будет его использовать при загрузке.
Отключение гибернации в графических средах
Графические окружения могут не определять автоматически, что раздел подкачки зашифрован случайным образом и не может быть использован для гибернации.
В Xfce можно скрыть кнопки Гибернация и Гибридный сон следующими командами:
$ xfconf-query -c xfce4-session -np /shutdown/ShowHibernate -t bool -s false $ xfconf-query -c xfce4-session -np /shutdown/ShowHybridSleep -t bool -s false
С поддержкой гибернации
Ниже описаны три альтернативных метода настройки зашифрованной подкачки с возможностью гибернации. При использовании любого из них нужно учитывать, что важные данные, выгруженные в подкачку, могут сохраняться там длительное время (до случайной перезаписи новыми данными поверх старых). Если данный риск критичный, рассмотрите возможность настройки системного задания, которое будет повторно шифровать swap, например, при каждом выключении системы, наряду с выбранным методом.
Использование swap-файла
Файл подкачки может располагаться в файловой системе внутри зашифрованного устройства. Следуйте инструкциям по созданию swap-файла из Swap (Русский)#Файл подкачки и настройте гибернацию согласно Power management (Русский)/Suspend and hibernate (Русский)#Настройка initramfs.
При использовании initrd на базе systemd и зашифрованной корневой файловой системы это может быть очень простым и гибким способом шифрования swap. После настройки зашифрованной корневой файловой системы можно создать swap-файл, активировать его и добавить в /etc/fstab
— он будет работать с гибернацией без дополнительной настройки.
resume=
он должен указывать на уже расшифрованное/смонтированное устройство, содержащее файловую систему с файлом подкачки.Использование swap-раздела
swapoff /dev/device
от имени root и убедиться, что в /etc/crypttab отсутствует строка, ссылающаяся на это устройство.Используйте cryptsetup-luksFormat(8), чтобы создать зашифрованный контейнер для раздела подкачки:
# cryptsetup luksFormat --label swap /dev/device
Откройте контейнер под именем /dev/mapper/swap
:
# cryptsetup open /dev/disk/by-label/swap swap
Создайте файловую систему swap внутри отображённого раздела:
# mkswap /dev/mapper/swap
Если вы не используете systemd#GPT partition automounting, добавьте отображённый раздел в /etc/fstab
, добавив следующую строку:
/dev/mapper/swap none swap defaults 0 0
Чтобы настроить систему на восстановление из гибернации, используйте параметр ядра resume=/dev/mapper/swap
. Подробности см. в Power management/Suspend and hibernate#Pass hibernate location to initramfs.
Использование TPM
Далее описывается способ автоматической расшифровки swap с помощью ключа, хранящегося в TPM.
Вы можете использовать systemd-cryptenroll, чтобы записать ключ в LUKS-контейнер и TPM, а затем удалить ранее созданный слот с паролем:
# systemd-cryptenroll --tpm2-device auto /dev/device # systemd-cryptenroll --wipe-slot password /dev/device
Проверьте результат:
# systemd-cryptenroll /dev/device SLOT TYPE 0 tpm2
Использование дополнительной парольной фразы или ключевого файла
У основной настройки, приведённой выше, есть недостаток: требуется вручную вводить дополнительную парольную фразу для swap-раздела при каждой загрузке.
/boot
не зашифрован. См. информацию об уязвимости здесь. В качестве альтернативы используйте ключевой файл, зашифрованный через gnupg, как описано здесь: https://bbs.archlinux.org/viewtopic.php?id=120181Расшифровка раздела в initramfs
Для восстановления из гибернации с зашифрованного swap-раздела он должен быть расшифрован в initramfs.
mkinitcpio
initramfs на базе systemd
При использовании initramfs на базе systemd с хуком sd-encrypt из mkinitcpio, вы можете:
- указать соответствующий параметр ядра
rd.luks.uuid=
для расшифровки swap-раздела, см. Dm-crypt/System configuration#rd.luks.uuid, или - отредактировать
crypttab.initramfs
и пересобрать initramfs.
Пример для устройства swap, расшифровываемого через TPM:
/etc/crypttab.initramfs
swap UUID=56f8ee97-54b3-4a65-9282-688deb922527 none tpm2-device=auto
initramfs на базе busybox
При использовании стандартного initramfs на базе busybox с хуком encrypt следуйте приведённым ниже инструкциям.
Если swap-устройство находится на другом физическом диске, отличном от корневой файловой системы, хук encrypt
не сможет его открыть. В этом случае восстановление из гибернации произойдёт до того, как будет доступен /etc/crypttab
, поэтому необходимо создать собственный хук в /etc/mkinitcpio.conf
, чтобы открыть LUKS-устройство подкачки до момента восстановления.
encrypt
-хука, который может разблокировать только одно устройство (archlinux/mkinitcpio/mkinitcpio#231). При использовании sd-encrypt
можно разблокировать несколько устройств, см. dm-crypt/System configuration#Using systemd-cryptsetup-generator.Теперь нужно создать хук, который будет открывать swap при загрузке. Вы можете либо установить и настроить mkinitcpio-openswapAUR, либо выполнить следующие шаги вручную. Создайте файл хука со следующей функцией:
/etc/initcpio/hooks/openswap
run_hook () { cryptsetup open /dev/device swap }
Для открытия swap-устройства вручную с вводом пароля:
/etc/initcpio/hooks/openswap
run_hook () { ## Необязательно: защита от гонок x=0; while [ ! -b /dev/mapper/root-device ] && [ $x -le 10 ]; do x=$((x+1)) sleep .2 done ## Конец необязательного блока mkdir crypto_key_device mount /dev/mapper/root-device crypto_key_device cryptsetup open --key-file crypto_key_device/path-to-the-key /dev/device swap umount crypto_key_device }
для открытия swap-устройства с использованием ключевого файла, размещённого на зашифрованном корневом разделе.
На некоторых компьютерах возможны состояния гонки, при которых `mkinitcpio` пытается смонтировать устройство до завершения расшифровки или до появления устройства в `/dev`. Комментарии в блоке Optional добавляют задержку до 2 секунд, чтобы дождаться готовности корневого устройства.
--allow-discards
в команду `cryptsetup` в хуке `openswap`. См. Dm-crypt/Specialties#Discard/TRIM support for solid state drives (SSD) или SSD для подробностей. Также необходимо указать параметр `discard` в `fstab` для соответствующего устройства.Затем создайте и отредактируйте файл установки хука:
/etc/initcpio/install/openswap
build () { add_runscript } help () { cat<<HELPEOF Этот хук открывает зашифрованный раздел подкачки /dev/device в /dev/mapper/swap HELPEOF }
Добавьте хук openswap
в массив HOOKS
в файле /etc/mkinitcpio.conf
, перед filesystem
, но после encrypt
. Не забудьте также добавить хук resume
после openswap
:
HOOKS=(... encrypt openswap resume filesystems ...)
При следующей загрузке хук openswap
откроет раздел подкачки, и ядро сможет использовать его для восстановления. Если вы используете специальные хуки для гибернации, убедитесь, что они идут после openswap
в массиве HOOKS
. Обратите внимание, что если swap открывается в initrd, то запись о нём в /etc/crypttab
больше не требуется.
dracut
Создайте файл ключа:
# dd bs=512 count=4 if=/dev/random iflag=fullblock | install -m 0600 /dev/stdin /etc/cryptsetup-keys.d/swap.key
Добавьте ключ в LUKS:
# cryptsetup luksAddKey /dev/device /etc/cryptsetup-keys.d/swap.key
Настройте `dracut` так, чтобы он включал модуль resume
и добавлял ключ в initramfs (см. также dracut#Hibernation):
/etc/dracut.conf.d/resume-from-hibernate.conf
add_dracutmodules+=" resume " install_items+=" /etc/cryptsetup-keys.d/swap.key "
Добавьте параметры rd.luks.name
и rd.luks.key
(подставив UUID раздела swap) в командную строку ядра. Пример строки загрузки:
kernel /vmlinuz-linux cryptdevice=/dev/sda2:root root=/dev/mapper/root resume=/dev/mapper/swap rd.luks.name=fd839505-3213-4603-9a70-c5a96a24768f=swap rd.luks.key=/etc/cryptsetup-keys.d/swap.key ro
LVM внутри LUKS
Если том подкачки находится в группе томов, которая активируется в initramfs, просто следуйте инструкциям из Power management (Русский)/Suspend and hibernate (Русский)#Гибернация.
Известные проблемы
Stopped (with error) /dev/dm-1
в логах. См. systemd issue 1620.