Шифруем и перешифровываем LUKS без потери данных

Введение

Если вы когда-либо задумывались о шифровании данных на дисках уже после того, как у вас накопилось их приличное количество, вы, вероятно, расстраивались, прочитав о необходимости переноса данных перед созданием шифрованного раздела и после. Перенос 500 ГБ туда и обратно не представляет никакой особой трудности, такой объем можно временно загрузить даже в облако, но если речь идет о шифровании 6 винчестеров по 4 ТБ каждый, задача заметно усложняется. По какой-то причине, возможность шифрования и перешифровывания томов LUKS без потери данных (in-place re-encryption) слабо освещена в интернете, хотя для этого есть две утилиты: cryptsetup-reencrypt, входящая в состав cryptsetup с 2012 года, и сторонняя luksipc, появившаяся на год раньше. Обе утилиты выполняют, в общем-то, одно и то же — шифруют раздел, если он не был шифрован, либо перешифровывают уже существующий с другими параметрами. Для своих нужд я воспользовался первой, официальной.

Как это работает?

Предположим, у вас типичная разметка диска: один раздел, начинается с 1 МиБ (выравнивание для 4КиБ-секторов), заканчивается в конце диска.
image

Заголовок LUKS располагается в начале, перед зашифрованными данными. Для заголовка требуется минимум 2056 512-байтных секторов, т.е. чуть больше 1МиБ. Места перед началом раздела нам явно недостаточно, поэтому сначала нужно уменьшить размер файловой системы с ее конца, чтобы cryptsetup-reencrypt перенес блоки правее, в конец диска, освободив таким образом место в начале раздела для LUKS-заголовка. Конечный размер заголовка зависит от длины ключа, количества слотов для парольных фраз и прочих параметров, поэтому я рекомендую быть рачительным и отвести под заголовок 4 МиБ.
image

Шифруем!

Первым делом уменьшим размер файловой системы. В случае ext4, делается это следующим образом:

# e2fsck -f /dev/sdc1
e2fsck 1.42.12 (29-Aug-2014)
Pass 1: Checking inodes, blocks, and sizes
Pass 2: Checking directory structure
Pass 3: Checking directory connectivity
Pass 4: Checking reference counts
Pass 5: Checking group summary information
SAMS15TB: 17086/536592 files (0.4% non-contiguous), 341465037/366284385 blocks

# dumpe2fs /dev/sdc1|grep 'Block count'
dumpe2fs 1.42.12 (29-Aug-2014)
Block count:              366284385

# resize2fs /dev/sdc1 366283361       
resize2fs 1.42.12 (29-Aug-2014)
Resizing the filesystem on /dev/sdc1 to 366283361 (4k) blocks.
The filesystem on /dev/sdc1 is now 366283361 (4k) blocks long.


где 366283361 = 366284385–1024 (блоки по 4k), т.е. уменьшаем на 4 МиБ
Следует отметить, что это не уменьшит размер самого раздела, его и не нужно уменьшать!

Имеет смысл выполнить cryptsetup benchmark. Скорее всего, на вашем компьютере самым быстрым будет AES, т.к. современные процессоры ускоряют его аппаратно. На моем же компьютере самым быстрым алгоритмом оказался serpent.

Приступаем к самому процессу шифрования. Внимание! По заверениям разработчиков, cryptsetup-reencrypt — эксперементальное ПО, и может убить ваши данные, так что лучше сделайте бекап.

# cryptsetup-reencrypt -c serpent-xts-plain64 -s 256 -N --reduce-device-size 4M /dev/sdc1
WARNING: this is experimental code, it can completely break your data.
Enter new passphrase: 
Progress:   0.0%, ETA 1107:23,  168 MiB written, speed  21.5 MiB/s
…


Параметр -N сообщает о необходимости создания LUKS-раздела, а --reduce-device-size указывает пустое место после файловой системы.

Процесс шифрования небыстрый, придется подождать, у меня ушло около 3 суток на все про все. Убедитесь, что вы запускаете cryptsetup-reencrypt из директории, к которой у вас есть доступ на запись, так вы сможете остановить процесс шифрования через CTRL+C и продолжить его после, если что-то пошло не так.

По окончании шифрования выполняем подключение диска к device mapper и монтируем его:

# cryptsetup luksOpen /dev/sdc1 crypt
# mount /dev/mapper/crypt /media/hdd

Вот и все. Мы получили зашифрованный диск, который не потребовал переноса данных.

© Habrahabr.ru