Estou usando o Almalinux, caso isso seja relevante aqui.
Usamos LUKS2 no disco local, com LVM no topo - então /dev/sda1 e 2 não são criptografados, mas /dev/sda3 é criptografado e usado para o sistema operacional.
Também usamos clevis/tang para fazer a descriptografia automática (e isso está funcionando bem).
Quando construímos via kickstart, definimos uma senha temporária ao criptografar e construir - e então, quando terminamos a construção inicial, usamos o ansible para definir senhas de boa qualidade, de acordo com nossas práticas de proteção/segurança.
Então isso envolve um script que faz o equivalente a:
cryptsetup luksOpen -S 0 --test-passphrase /dev/sda3 && cryptsetup luksChangeKey -S0 --force-password --batch-mode
(E, claro, a senha de compilação 'padrão' é testada e substituída por uma do nosso sistema de gerenciamento de chaves).
Isso começou a falhar recentemente e estou um pouco perplexo sobre o que pode estar dando errado.
Definitivamente funciona em nossa 'compilação' inicial, que usa uma imagem de compilação um pouco desatualizada, mas depois mudamos dnf update
para a revisão atual e agora não conseguimos mais usar luksChangeKey ou luksAddkey.
# Adding new keyslot 2 by passphrase, volume key provided by passphrase (-1).
# Selected keyslot 2.
# Keyslot 0 priority 1 != 2 (required), skipped.
# Keyslot 1 priority 1 != 2 (required), skipped.
# Trying to open LUKS2 keyslot 0.
# Running keyslot key derivation.
# Reading keyslot area [0x8000].
# Acquiring read lock for device /dev/sda3.
# Opening lock resource file /run/cryptsetup/L_8:3
# Verifying lock handle for /dev/sda3.
# Device /dev/sda3 READ lock taken.
# Reusing open ro fd on device /dev/sda3
# Device /dev/sda3 READ lock released.
# Verifying key from keyslot 0, digest 0.
# Keyslot 2 assigned to digest 0.
# Trying to allocate LUKS2 keyslot 2.
# Found area 548864 -> 806912
# Running argon2id() benchmark.
# PBKDF benchmark: memory cost = 65536, iterations = 4, threads = 4 (took 72 ms)
# PBKDF benchmark: memory cost = 227555, iterations = 4, threads = 4 (took 264 ms)
# PBKDF benchmark: memory cost = 1048576, iterations = 6, threads = 4 (took 1982 ms)
# Benchmark returns argon2id() 6 iterations, 1048576 memory, 4 threads (for 512-bits key).
# JSON does not fit in the designated area.
# Not enough space in header json area for new keyslot.
# Rolling back in-memory LUKS2 json metadata.
# Releasing crypt device /dev/sda3 context.
# Releasing device-mapper backend.
# Closing read only fd for /dev/sda3.
Command failed with code -1 (wrong or missing parameters).
Gostaria de saber se alguém pode me ajudar a entender o que está errado aqui e o que preciso fazer para remediar.
Existe uma opção de 'tamanho do cabeçalho inicial' que eu possa especificar em nossas compilações? Ou um parâmetro para cryptsetup? Ou estou "apenas" encontrando um bug? (Mas não estou convencido de que algo tão amplamente usado como cryptsetup
vai ter um bug do tipo 'ninguém pode mudar suas senhas')
É assim que o cabeçalho LUKs aparece em um host de exemplo.
LUKS header information
Version: 2
Epoch: 5
Metadata area: 16384 [bytes]
Keyslots area: 16744448 [bytes]
UUID:
Label: (no label)
Subsystem: (no subsystem)
Flags: (no flags)
Data segments:
0: crypt
offset: 16777216 [bytes]
length: (whole device)
cipher: aes-xts-plain64
sector: 512 [bytes]
Keyslots:
0: luks2
Key: 512 bits
Priority: normal
Cipher: aes-xts-plain64
Cipher key: 512 bits
PBKDF: argon2id
Time cost: 9
Memory: 1048576
Threads: 4
Salt:
AF stripes: 4000
AF hash: sha256
Area offset:32768 [bytes]
Area length:258048 [bytes]
Digest ID: 0
1: luks2
Key: 512 bits
Priority: normal
Cipher: aes-xts-plain64
Cipher key: 512 bits
PBKDF: pbkdf2
Hash: sha256
Iterations: 1000
Salt:
AF stripes: 4000
AF hash: sha256
Area offset:290816 [bytes]
Area length:258048 [bytes]
Digest ID: 0
Tokens:
0: clevis
Keyslot: 1
Digests:
0: pbkdf2
Hash: sha256
Iterations: 105025
Salt:
Digest:
Estou esquecendo de algo profundo? Como dito, tenho certeza de que isso funciona se eu não "atualizar" a caixa para um kernel mais novo, então minha solução alternativa atual é construí-la, recodificar manualmente e então continuar a atualizá-la, mas isso parece... abaixo do ideal.
cryptsetup versões 2.6.0 e 2.7.2
head -c 1M /dev/sda3 | strings -n 128
reformatado:
{
"keyslots": {
"0": {
"type": "luks2",
"key_size": 64,
"af": {
"type": "luks1",
"stripes": 4000,
"hash": "sha256"
},
"area": {
"type": "raw",
"offset": "32768",
"size": "258048",
"encryption": "aes-xts-plain64",
"key_size": 64
},
"kdf": {
"type": "argon2id",
"time": 7,
"memory": 1048576,
"cpus": 4,
"salt": "(removed)"
}
},
"1": {
"type": "luks2",
"key_size": 64,
"af": {
"type": "luks1",
"stripes": 4000,
"hash": "sha256"
},
"area": {
"type": "raw",
"offset": "290816",
"size": "258048",
"encryption": "aes-xts-plain64",
"key_size": 64
},
"kdf": {
"type": "pbkdf2",
"hash": "sha256",
"iterations": 1000,
"salt": "(removed)"
}
}
},
"tokens": {
"0": {
"type": "clevis",
"keyslots": [
"1"
],
"jwe": {
"ciphertext": "(removed)",
"encrypted_key": "",
"iv": "(removed)",
"protected": "",
"tag": "(removed)"
}
}
},
"segments": {
"0": {
"type": "crypt",
"offset": "16777216",
"size": "dynamic",
"iv_tweak": "0",
"encryption": "aes-xts-plain64",
"sector_size": 512
}
},
"digests": {
"0": {
"type": "pbkdf2",
"keyslots": [
"0",
"1"
],
"segments": [
"0"
],
"hash": "sha256",
"iterations": 88086,
"salt": "(removed)",
"digest": "(removed)"
}
},
"config": {
"json_size": "12288",
"keyslots_size": "16744448"
}
}
Edição 2: A história se complica: luksHeaderBackup e depois uma restauração falha.
Mas matar o 'slot 0' e adicionar uma chave ainda funciona. (Supondo que o 'slot 1' você pode extrair, mas nos meus casos clevis-luks-pass
funciona bem o suficiente)