Как расширить LUKS2

Как расширить LUKS2

Я читал руководство несколько лет назад, в котором говорилось о том, как LUKS1 расширяется вправо и смежное свободное пространство без потери данных, но не мог выйти влево. В настоящее время LUKS2 прибыл со многими новыми функциями, делает ли он различия в расширении слева без потери данных?

решение1

вкратцеЭто пока не совсем возможно. Формат метаданных предполагает, что это должно быть осуществимо, но пока это фактически не реализовано. Так что вам следует придерживаться старого доброго "переместить все данные" или "создать новый раздел и позволить LVM позаботиться об этом". То же самое вы делаете с LUKS1 и большинством файловых систем.


TheЗаголовок LUKS2имеет концепциюсегменты данных:

Объект Segments содержит определение зашифрованных областей на диске, содержащих пользовательские данные (в LUKS1 упоминается как полезная нагрузка пользовательских данных). Для обычного устройства LUKS присутствует только один сегмент данных.

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

Ссегменты данных, должно быть возможно переместить заголовок LUKS влево, продолжая указывать на исходные данные (первый сегмент), и использовать свободное пространство (между заголовком и сегментом данных) как новый сегмент данных, логически присоединенный к концу криптографического устройства. Точно так же, как LVM присоединяет произвольные группы физических экстентов к логическому тому.

Но это всего лишь теория.

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


Я попытался сделать это нетрадиционным способом (что-то вроде проверки концепции):

# truncate -s 100M foobar.img
# cryptsetup luksFormat --type=luks2 foobar.img
# cryptsetup luksOpen foobar.img foobar
# yes > /dev/mapper/foobar
# sync
# hexdump -C /dev/mapper/foobar
00000000  79 0a 79 0a 79 0a 79 0a  79 0a 79 0a 79 0a 79 0a  |y.y.y.y.y.y.y.y.|
*
05400000

LUKS2 зашифрованный шаблон "да". Как выглядит сегмент данных?

# cryptsetup luksDump foobar.img
Data segments:
  0: crypt
    offset: 16777216 [bytes]
    length: (whole device)
    cipher: aes-xts-plain64
    sector: 512 [bytes]
# strings -n 100 foobar.img
"segments":{"0":{"type":"crypt","offset":"16777216","iv_tweak":"0","size":"dynamic","encryption":"aes-xts-plain64","sector_size":512}}

Последнее на самом деле то, как выглядят необработанные метаданные LUKS2 — это формат JSON. Мы отредактируем его позже...

Давайте увеличим его - влево (на 100М):

# truncate -s 100M barfoo.img
# cat foobar.img >> barfoo.img
# ls -lh *.img
-rw-r--r-- 1 root root 200M Jun  9 20:57 barfoo.img
-rw-r--r-- 1 root root 100M Jun  9 20:53 foobar.img

Таким образом, barfoo.img — это 100 М нового пустого пространства, за которым следует 100 М исходного контейнера LUKS.

Переместите заголовок LUKS в новое начало устройства:

# dd bs=1M count=16 if=foobar.img of=barfoo.img conv=notrunc
# cryptsetup luksOpen barfoo.img barfoo
# hexdump -C -n 16 /dev/mapper/barfoo
00000000  4e a6 39 e7 e0 e8 63 ae  81 72 29 81 5f 1b 08 c2  |N.9...c..r)._...|
00000010

Его можно открыть сейчас, носегмент данныхвсе еще указывает на старое смещение (16 МБ), но, конечно, его там нет - мы добавили 100 МБ, поэтому смещение для этогосегмент данныхСейчас должно быть 116 МБ.

Отредактируйте его (смещение 16777216 изменится на смещение 121634816):

# strings -n 100 barfoo.img | head -n 1 > barfoo.json
# nano -w barfoo.json
# dd if=barfoo.json of=barfoo.img bs=1 seek=4096 conv=notrunc
# dd if=barfoo.json of=barfoo.img bs=1 seek=20480 conv=notrunc

Результат:

# cryptsetup luksDump barfoo.img
Device barfoo.img is not a valid LUKS device.

О, конечно. У LUKS2 теперь тоже есть контрольные суммы метаданных. Он не хочет, чтобы вы редактировали что-то с помощью nano и искажали заголовок с помощью dd. Никакой вам тайной магии, сэр. Ну, это пока вы не исправите контрольную сумму...

# cryptsetup luksDump barfoo.img --debug
# LUKS2 header version 2 of size 16384 bytes, checksum sha256.
# Checksum:8552bf514ab70b53e63180e9fdd3bb59db1385e3dca87f792f8197b33b851aa1 (on-disk)
# Checksum:e6f322921feae0193bcbc4cddc23b87b7f192266b4a2ef34847580fd7ca18a3e (in-memory)
# LUKS2 header checksum error (offset 0).

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

# echo e6f322921feae0193bcbc4cddc23b87b7f192266b4a2ef34847580fd7ca18a3e |
  xxd -r -ps - |
  dd of=barfoo.img bs=1 seek=448 conv=notrunc

Результат (теперь уже действительно):

# cryptsetup luksDump barfoo.img
Data segments:
  0: crypt
    offset: 121634816 [bytes]
    length: (whole device)
    cipher: aes-xts-plain64
    sector: 512 [bytes]
# hexdump -C /dev/mapper/barfoo
00000000  79 0a 79 0a 79 0a 79 0a  79 0a 79 0a 79 0a 79 0a  |y.y.y.y.y.y.y.y.|
*
05400000

На этом этапе мы успешно переместили заголовок LUKS на 100 М влево. Но размер устройства остался прежним... теперь можем ли мы добавить еще один сегмент данных? Есть свободный сегмент 100 М от смещения 16 М до 116 М. Давайте добавим его в JSON.

# nano -w barfoo.json
man this is unreadable
# jq < barfoo.json > barfoo.pretty
# nano -w barfoo.pretty
...
  "segments": {
    "0": {
      "type": "crypt",
      "offset": "121634816",
      "iv_tweak": "0",
      "size": "88080384",
      "encryption": "aes-xts-plain64",
      "sector_size": 512
    },
    "1": {
      "type": "crypt",
      "offset": "16777216",
      "iv_tweak": "172032",
      "size": "104857600",
      "encryption": "aes-xts-plain64",
      "sector_size": 512
    }
  },
  "digests": {
    "0": {
      "type": "pbkdf2",
      "keyslots": [
        "0"
      ],
      "segments": [
        "0",
        "1"
      ],
...and so on and so forth...

Результат:

# cryptsetup luksDump barfoo.img
Data segments:
  0: crypt
    offset: 121634816 [bytes]
    length: 88080384 [bytes]
    cipher: aes-xts-plain64
    sector: 512 [bytes]

  1: crypt
    offset: 16777216 [bytes]
    length: 104857600 [bytes]
    cipher: aes-xts-plain65
    sector: 512 [bytes]

К сожалению, в этот момент устройство открылось нормально, имело правильный увеличенный размер (УРА!), но данные были неверными (НЕТ!). Логический байт 0 был сопоставлен с физическим байтом 16 МБ вместо ожидаемых 116 МБ.

Эй, это сегмент 1, а не сегмент 0, глупый Билли! Что пошло не так?

Я не знаю. Это почти как если бы вы не должны были делать простые изменения метаданных, чтобы разблокировать скрытые функции, которые еще никто не тестировал.

Может быть, это из-за моего непонимания, но даже если поставить сегменты наоборот, они все равно будут открываться в неправильном порядке. Что-то сортирует их по физическому смещению? Но почему?

Так что, к сожалению, эта конкретная магия закончилась неудачей. Либо я что-то сделал не так, либо она просто еще не готова к использованию. Тем не менее, функциональность есть, так что есть еще надежда на будущее.

Обратите внимание, что даже если бы это сработало, вам не рекомендовали бы его использовать.

Связанный контент