Como estender o LUKS2

Como estender o LUKS2

Eu li um guia há alguns anos sobre como o LUKS1 se estende para o espaço livre direito e adjacente sem perda de dados, mas não pode sair. Hoje em dia o LUKS2 chegou com muitas novidades, ele faz diferenciais na esquerda estendendo sem perda de dados ??

Responder1

dr.Não é realmente possível – ainda. O formato de metadados sugere que isso deveria ser viável, mas até agora não foi realmente implementado. Portanto, você deve seguir o bom e velho "realocar todos os dados" ou "criar uma nova partição e deixar o LVM se preocupar com isso". A mesma coisa que você faz com o LUKS1 e a maioria dos sistemas de arquivos.


OCabeçalho LUKS2tem um conceito desegmentos de dados:

O objeto Segments contém uma definição de áreas criptografadas no disco que contém dados do usuário (em LUKS1 mencionadas como carga útil de dados do usuário). Para um dispositivo LUKS normal, existe apenas um segmento de dados presente.

Durante a recriptografia dos dados, a área de dados é dividida internamente de acordo com a nova e a antiga chave, mas apenas uma área abstraída deve ser apresentada ao usuário.

Comsegmentos de dados, deve ser possível mover o cabeçalho LUKS para a esquerda, continuar apontando para os dados originais (primeiro segmento) e usar o espaço livre (entre o cabeçalho e o segmento de dados) como um novo segmento de dados, logicamente anexado ao final do dispositivo de criptografia. Assim como o LVM anexa grupos arbitrários de extensões físicas a um volume lógico.

Mas isso é apenas uma teoria.

Até o momento, não existe nenhum uso/ferramenta prática que implemente esse recurso e não tenho ideia se há planos para fazê-lo.


Tentei fazer funcionar de maneira não convencional (prova de conceito, mais ou menos):

# 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 criptografado com padrão sim. Como é o segmento de dados?

# 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}}

Este último é na verdade a aparência dos metadados LUKS2 brutos - é um formato JSON. Vamos editar isso mais tarde...

Vamos crescer - para a esquerda (em 100M):

# 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

Portanto, barfoo.img tem 100M de novo espaço vazio seguido por 100M de contêiner LUKS original.

Realoque o cabeçalho LUKS para um novo início do dispositivo:

# 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

Pode ser aberto agora, mas osegmento de dadosainda aponta para o deslocamento antigo (16MiB), mas é claro que não está lá - adicionamos 100M, então o deslocamento para estesegmento de dadosdeve ser 116MiB agora.

Edite-o (deslocamento 16777216 para deslocamento 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

Resultado:

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

Ah, mas é claro. LUKS2 também possui somas de verificação de metadados agora. Ele não quer que você edite coisas com nano e destrua o cabeçalho com dd. Nenhuma magia arcana para você, senhor. Bem, isso é até você corrigir a soma de verificação também ...

# 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).

... basicamente substitua a soma de verificação do disco pela da memória aqui.

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

Resultado (agora realmente):

# 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

Neste ponto, movemos com sucesso o cabeçalho LUKS 100M para a esquerda. Mas o tamanho do dispositivo ainda é o mesmo... agora, podemos adicionar outro segmento de dados? Há um segmento gratuito de 100 milhões de offset 16M a 116M. Vamos adicioná-lo ao 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...

Resultado:

# 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]

Infelizmente, neste ponto, o dispositivo abriu bem, tinha o tamanho aumentado correto (YAY!), mas os dados estavam errados (NÃO!). O byte lógico 0 foi mapeado para o byte físico 16MiB em vez dos 116MiB esperados.

Ei, esse é o segmento 1, não o segmento 0, seu bobo! O que deu errado?

Não sei. É quase como se você não devesse fazer modificações simples nos metadados para desbloquear recursos ocultos que ninguém testou ainda.

Talvez seja por minha falta de compreensão, mas mesmo colocando os segmentos ao contrário, continuaria abrindo-os na ordem errada. Algo está classificando isso por deslocamento físico? Mas por que?

Então, infelizmente, esta peça mágica em particular terminou em fracasso. Ou porque fiz algo errado ou simplesmente ainda não está pronto para uso. Ainda assim, a funcionalidade está lá - então ainda há esperança para o futuro.

Observe que, mesmo que funcionasse, seria desaconselhável usá-lo.

informação relacionada