Иногда возникает необходимость в организации защиты критических данных на виртуальной машине: выходом является использование зашифрованного хранилища. Ранее для реализации подобного функционала приходилось прибегать к сторонним инструментам, но, начиная с Proxmox VE v6.0, появилась поддержка шифрования наборов данных ZFS из коробки.
В общем случае набор данных создается поверх существующего пула командой:
После ввода ключа шифрования созданный набор данных станет корнем шифрования. Все наборы данных-потомки по умолчанию наследуют свой ключ шифрования от корня шифрования, что означает, что загрузка, выгрузка или изменение ключа для корня шифрования будет неявно делать то же самое для всех наследующих наборов данных.
Если это наследование нежелательно, просто введите
Обратите внимание, что дочерний формат ключа может совпадать с родительским при создании нового корня шифрования, и что изменение свойства шифрования само по себе не создает новый корень шифрования; это просто будет использовать другой набор шифров с тем же ключом, что и его корень шифрования. Единственное исключение состоит в том, что клоны всегда будут использовать ключ шифрования своего источника. В результате этого исключения некоторые свойства, связанные с шифрованием (а именно
В общем случае набор данных создается поверх существующего пула командой:
zfs create <pool>/<new_dataset>
Для включения шифрования набора данных необходимо при его создании указать ряд опций (указываются с ключом -o):
Из man:
Создание зашифрованного набора данных требует указания свойств шифрования и keyformat во время создания, а также дополнительного расположения ключей и pbkdf2iters.После ввода ключа шифрования созданный набор данных станет корнем шифрования. Все наборы данных-потомки по умолчанию наследуют свой ключ шифрования от корня шифрования, что означает, что загрузка, выгрузка или изменение ключа для корня шифрования будет неявно делать то же самое для всех наследующих наборов данных.
Если это наследование нежелательно, просто введите
keyformat
при создании дочернего набора данных или используйте ZFS change-key
для разрыва существующей связи, создавая новый корень шифрования на дочернем наборе данных.Обратите внимание, что дочерний формат ключа может совпадать с родительским при создании нового корня шифрования, и что изменение свойства шифрования само по себе не создает новый корень шифрования; это просто будет использовать другой набор шифров с тем же ключом, что и его корень шифрования. Единственное исключение состоит в том, что клоны всегда будут использовать ключ шифрования своего источника. В результате этого исключения некоторые свойства, связанные с шифрованием (а именно
keystatus, keyformat, keylocation
и pbkdf2iters
), не наследуются подобно другим свойствам ZFS и вместо этого используют значение, определенное их корневым ключом шифрования. Наследование корня шифрования можно отслеживать с помощью свойства encryptionroot
, доступного только для чтения.- encryption=off|on|aes-128-ccm|aes-192-ccm|aes-256-ccm|aes-128-gcm|aes-192-gcm|aes-256-gcm
- Управляет набором шифров шифрования (блочный шифр, длина ключа и режим), используемым для этого набора данных. Требует, чтобы функция шифрования была включена в пуле. Требует, чтобы во время создания набора данных был установлен формат ключа.
Выбор encryption=on при создании набора данных означает, что будет выбран набор шифрования по умолчанию, который в настоящее время является aes-256-ccm. Чтобы обеспечить согласованную защиту данных, шифрование должно быть задано во время создания набора данных и не может быть изменено впоследствии.
- keyformat=raw|hex|passphrase
- Определяет, в каком формате будет предоставляться ключ шифрования пользователя. Это свойство устанавливается только при шифровании набора данных.
Необработанные ключи и шестнадцатеричные ключи должны иметь длину 32 байта (независимо от выбранного набора шифрования) и генерироваться случайным образом. Необработанный ключ может быть создан с помощью следующей команды:
Длина парольных фраз должна составлять от 8 до 512 байт, и они будут обработаны через PBKDF2 перед использованием (см. свойство pbkdf2iters). Несмотря на то, что набор шифрования не может быть изменен после создания набора данных, keyformat может быть изменен с помощью ZFS change-key.# dd if=/dev/urandom of=/path/to/output/key bs=32 count=1
- keylocation=prompt|file://</absolute/file/path>
- Определяет, откуда будет загружен ключ шифрования пользователя по умолчанию для таких команд, как
zfs load-key
иzfs mount-l
. Это свойство задается только для зашифрованных наборов данных, являющихся корнями шифрования. Если не указано, то по умолчанию используется prompt.
Несмотря на то, что набор шифрования не может быть изменен после создания набора данных, keyformat может быть изменен с помощьюZFS change-key
. Если выбран параметр prompt, ZFS запросит ключ в командной строке, когда потребуется получить доступ к зашифрованным данным. Этот параметр также позволяет передавать ключ через STDIN, но пользователи должны быть осторожны, чтобы не размещать ключи, которые должны храниться в секрете в командной строке. Если выбран URI файла, то ключ будет загружен из указанного абсолютного пути к файлу.
- pbkdf2iters=iterations
- Определяет количество итераций PBKDF2, через которые должен быть выполнен ключ шифрования парольной фразы при его обработке в ключ шифрования. Это свойство определяется только в том случае, если включено шифрование и выбран формат ключа парольной фразы. Цель PBKDF2-значительно увеличить вычислительную сложность, необходимую для перебора парольной фразы пользователя. Это достигается путем принудительного выполнения злоумышленником каждой парольной фразы через вычислительно-дорогостоящую функцию хэширования много раз, прежде чем они получат ключ. Пользователь, который действительно знает пароль, должен будет заплатить эту цену только один раз. Поскольку процессоры становятся мощнее, это число должно быть достаточно большим, чтобы гарантировать, что атака перебором все еще невозможна. Текущее значение по умолчанию-350000, а минимальное-100000. Это свойство может быть изменено с помощью
zfs change-key
.
На практике это выглядит следующим образом:
- Создаем пул на свободном диске (можно использовать существующий пул, так же это может быть любой тип ZFS рэйда)
zpool create -f <PoolName> /dev/sd[x]
- Внимание!
- Следует помнить, что для обеспечения возможности репликации виртуальных машин, следует обеспечить наличие общего для нод кластера именования ресурсов (соглашение об именах).
- Поверх пула создается набор данных с включенным шифрованием
Зашифрованный набор данных создается и сразу монтируется, для того, чтоб он был доступен в дальнейшем, его следует подключать командойzfs create -o encryption=on -o keyformat=passphrase <PoolName>/<DatasetName> Enter passphrase: Re-enter passphrase:
zfs load-key
:
а отключатьzfs load-key <PoolName>/<DatasetName> zfs mount <PoolName>/<DatasetName>
zfs unload-key
:umount /<PoolName>/<DatasetName> zfs unload-key <PoolName>/<DatasetName>
- Добавляем в кластер наше защищенное хранилище (выполняется 1 раз для кластера):
pvesm add zfspool <StorageName> -pool <PoolName>/<DatasetName> --sparse
- P.S.
- В большинстве случаев нет необходимости шифровать всю виртуальную машину: на мой взгляд достаточно создать виртуалке дополнительный диск на зашифрованном хранилище и монтировать его средствами операционной системы в нужное место.
Александр, спасибо за новую статью, прошу поправить опечатки:
ОтветитьУдалитьнаписано "а отключать zfs load-key" вместо "а отключать zfs unload-key"
написано "системы в нудное место" вместо "системы в нужное место"
вдогонку:
ОтветитьУдалитьнаписано "он был поступен" вместо "он был доступен"
Спасибо, исправил.
УдалитьНу уж тогда стоит вспомнить правило правописание "о" и "ё" после шипящих. Всё-таки "ключом". А за статью спасибо.
ОтветитьУдалить