Versão em vídeo desta seção pode estar disponível no canal do Guia Foca no YouTube: Criptografia com o DM Crypto.
Criptografia de dispositivo de blocos, simplesmente signifia que você encriptará
TODO o dispositivo que será montado (como o o /dev/sda1
).
Desta forma, todo e qualquer arquivo armazenado nessa partição, estará automaticamente criptografado.
Esta metodo é bastante utilizado pelos instaladores de distribuições Linux
e também por Smartphones que utilizam Android como sistema operacional.
Quando é utilizado a criptografia de um dispositivo como /dev/sda1
,
primeiro ele é decriptado e entregue como um outro
dispositivo como /dev/mapper/cripto
(o nome é de sua livre escolha),
e esse dispositivo que será formatado (com qualquer sistema de arquivos de sua escolha
usando o mkfs.*: ext4, reiserfs,XFS, Btrfs,
etc).
Como o device mapper entregará um dipsositivo de
blocos normal em /dev/mapper/cripto
, pouco importa qual sistema de
arquivos será usado na formação, podendo até mesmo usar VFAT :-)
A encriptação de dispositivos de blocos também tem benefícios, permitindo também que a a segurança seja aplicada a todos os arquivos na inicialização do sistema, assm todos os sistemas de arquivos estarão encriptados pela mesma chave, desta forma, se o dispositivo de bloco é encriptado, os sistemas de arquivos neste dispositivo também estarão automaticamente encriptados.
O uso de criptografia de blocos também nos garante um nível adicional de segurança, pois o invasor não terá qualquer aos arquivos, ou sequer os atributos (permissões, diretório, tamanho de arquivos) quando usamos o cryptsetup. Observe que cada sistema de criptografia possui suas vantagens e desavantagens, desta forma o uso do DM crypt/cryptsetup é interessante quando possui acesso completo a máquina e pode FORMATAR a partição que armazena dados, para criptografa-la.
Sistemas que usam a criptografia a nível de sistema de arquivos (como o EncfS ou o eCryptFS), não requer privilégios especiais ou perda de dados para sua implantação, baseado nisso, você poderá tomar suas decisões sobre qual melhor sistema de criptografia escolher e a diferença entre eles.
A ferramenta que utilizarmos para essa configuração é o cryptsetup,
que basicamente usa o DMCrypt com o Luks
(Luks significa
Linux Unified Key Setup) e com ele podemos criar, definir senhas de acesso
(DM-Crypt permite até 8 chaves diferentes) para gerenciar a encriptação do Device Mapper.
Como reforçado atneriormente, a criptografoa do em-crypto ocorre na camada de dispositivo de blocos, assim os arquivos estarão disponíveis imediatamente sem qualquer necessidade de comandos especiais após a montagem. Desta forma, o primeiro passo é isntalar o cryptsetup:
apt-get install cryptsetupApós isso, execute o seguinte comando no sistema de arquivos que será preparado para criptografia com o DM Crypto:
cryptsetup -y --cipher aes-xts-plain64 --hash sha512 --key-size 512 luksFormat /dev/sdc1
O comando acima diz para APAGAR e criar um sistema encriptado (luksFormat)
em /dev/sdc1
, usando o cipher aes-xts-plain64
, que
garante boa performance e alta segurança. Ele será criado usando o hash sha512
e tamanho da chave (key-size
) de 512 bits (veja “Listando limites e algoritmos suportados”).
Caso digite apenas cryptsetup -y luksFormat /dev/sdc1, serão utilizados os seguintes valores padrões:
--cipher - Usa o aes-xts-plain64
como padrão a partir da versão 1.6.
Pois o antigo aes-cbc-essiv
tem bugs e ataques conhecidos.
key-size 256 - O valor padrão usado é 256. Note que o XTS divide a chave por dois, assim
para usar um AES-256, configure o XTS key-size como 512
.
hash sha256 - Algoritmo usado para derivação de chave. O sha1 é considerado mais seguro, mas ele não é usado por padrão por causa de compatibilidade.
iter-time - Número de milisegundos para gastar com o processamento a frase senha PBKDF2. 2000 ms é o padrão, e o ideal é manter o número com um valor alto, e ainda aceitável para os usuários.
-y / --verify-passphrase yes - Pede a confirmação da frase senha. Este é o padrão para o
luksFormat
e luksAddKey
.
Após executar o comando, lhe será pedido para digitar YES
em maiúsculas para confirmar e depois uma
frase senha (veja “Senhas fáceis de adivinhar e a escolha de boas senhas”) para iniciar a formatação.
Após isso, a estrutura de criptografia está criada e pronta para ser usada como qualquer sistema de arquivos normal. Execute o comando abaixo para tornar o dispositivo de criptografia front-end acessível para montagem (descriptografado):
cryptsetup luksOpen /dev/sdc1 testecripto
Informe a frase-senha escolhida quando perguntado. Agora, você poderá formatar o dispositivo e iniciar o
armazenamento de arquivos, como faria com outro sistema de arquivos qualquer, e montaremos ele em
/data
:
# mkfs.ext4 /dev/mapper/testecripto # mount /dev/mapper/testecripto /data
Para mostrar o stauts do volume mapeado, incluindo cipher usado, tamanho da chave, o dispositivo, número de setores e modo do volume, digite:
cryptsetup -v status testecriptotype: LUKS1 cipher: aes-xts-plain64 keysize: 512 bits device: /dev/sdc1 offset: 4096 sectors size: 1044480 sectors mode: read/write
Para listar a hierarquia de blocos associados, digite: lsblk -p
Como temos um sistema de arquivos criptografado montado, precisamos desmonta-lo em duas etapas:
1 - Desmontar o dispositivo (como um sistema de arquivos qualquer), com o comando: umount /data
Note que o dispositivo ainda está acessível e pode ser montado por qualquer pessoa com um simples comando mount (ls /dev/mapper/testecripto ou cryptsetup -v status testecripto). Para encerrar o dispositivo de criptografia, digite o comando: cryptsetup luksClose dispositivo
Note que o parametro luksOpen
e luksClose
pode ser substituido respectivamente
por open
e close
.
Você pode verificar os ciphers suportados e seus limites (para configuração de tamanho mínimo e máximo de chave em bits),
visualizando o arquivo /proc/crypto
. Listamos abaixo um exemplo resumido de saída desse arquivo (note que
ele lista além do nome do cyper, o módulo do kernel, se é interno/externo, o tamanho mínimo/máximo de chaves, se é assincrono, etc):
name : __xts(aes) driver : cryptd(__xts-aes-aesni) module : cryptd priority : 451 refcnt : 2 selftest : passed internal : yes type : skcipher async : yes blocksize : 16 min keysize : 32 max keysize : 64 ivsize : 16 chunksize : 16 walksize : 16 name : cmac(aes) driver : cmac(aes-aesni) module : cmac priority : 300 refcnt : 2 selftest : passed internal : no type : shash blocksize : 16 digestsize : 16 name : pkcs1pad(rsa,sha256) driver : pkcs1pad(rsa-generic,sha256) module : kernel priority : 100 refcnt : 1 selftest : passed internal : no type : akcipher name : ecdh driver : ecdh-generic module : ecdh_generic priority : 100 refcnt : 2 selftest : passed internal : no type : kpp name : xts(aes) driver : xts-aes-aesni module : aesni_intel priority : 401 refcnt : 2 selftest : passed internal : no type : skcipher async : yes blocksize : 16 min keysize : 32 max keysize : 64 ivsize : 16 chunksize : 16 walksize : 16 name : __ctr(aes) driver : __ctr-aes-aesni module : aesni_intel priority : 400 refcnt : 1 selftest : passed internal : yes type : skcipher async : no blocksize : 1 min keysize : 16 max keysize : 32 ivsize : 16 chunksize : 16 walksize : 16 name : hmac(sha256) driver : hmac(sha256-generic) module : kernel priority : 100 refcnt : 9 selftest : passed internal : no type : shash blocksize : 64 digestsize : 32 name : hmac(sha1) driver : hmac(sha1-generic) module : kernel priority : 100 refcnt : 9 selftest : passed internal : no type : shash blocksize : 64 digestsize : 20 name : jitterentropy_rng driver : jitterentropy_rng module : kernel priority : 100 refcnt : 1 selftest : passed internal : no type : rng seedsize : 0 name : crc32c driver : crc32c-intel module : kernel priority : 200 refcnt : 16 selftest : passed internal : no type : shash blocksize : 1 digestsize : 4 name : stdrng driver : drbg_pr_hmac_sha512 module : kernel priority : 202 refcnt : 1 selftest : passed internal : no type : rng seedsize : 0 name : stdrng driver : drbg_pr_hmac_sha384 module : kernel priority : 201 refcnt : 1 selftest : passed internal : no type : rng seedsize : 0 name : lzo-rle driver : lzo-rle-scomp module : kernel priority : 0 refcnt : 1 selftest : passed internal : no type : scomp name : aes driver : aes-generic module : kernel priority : 100 refcnt : 1 selftest : passed internal : no type : cipher blocksize : 16 min keysize : 16 max keysize : 32 name : sha384 driver : sha384-generic module : kernel priority : 100 refcnt : 1 selftest : passed internal : no type : shash blocksize : 128 digestsize : 48 name : sha512 driver : sha512-generic module : kernel priority : 100 refcnt : 1 selftest : passed internal : no type : shash blocksize : 128 digestsize : 64 name : sha224 driver : sha224-generic module : kernel priority : 100 refcnt : 1 selftest : passed internal : no type : shash blocksize : 64 digestsize : 28 name : sha256 driver : sha256-generic module : kernel priority : 100 refcnt : 10 selftest : passed internal : no type : shash blocksize : 64 digestsize : 32 name : ecb(cipher_null) driver : ecb-cipher_null module : kernel priority : 100 refcnt : 1 selftest : passed internal : no type : skcipher async : no blocksize : 1 min keysize : 0 max keysize : 0 ivsize : 0 chunksize : 1 walksize : 1 name : rsa driver : rsa-generic module : kernel priority : 100 refcnt : 1 selftest : passed internal : no type : akcipher
O desempenho de cada algoritmo pode variar conforme cada sistema, alguns podem apresentar um excelente desempenho em aes enquanto outros podem desempenhar melhor com twofish. O cryptsetup possui uma excelente teste de performance interno que te ajudar a selecionar o melhor algoritmo que se adapte ao seu sistema:
Para executar o teste, digite o comando cryptsetup benchmark:
------------------------------------ PBKDF2-sha1 414129 iterations per second for 256-bit key PBKDF2-sha256 509017 iterations per second for 256-bit key PBKDF2-sha512 348595 iterations per second for 256-bit key PBKDF2-ripemd160 286183 iterations per second for 256-bit key PBKDF2-whirlpool 207721 iterations per second for 256-bit key # Algorithm | Key | Encryption | Decryption aes-cbc 128b 78,6 MiB/s 91,1 MiB/s serpent-cbc 128b 28,0 MiB/s 31,0 MiB/s twofish-cbc 128b 52,4 MiB/s 61,5 MiB/s aes-cbc 256b 60,9 MiB/s 68,0 MiB/s serpent-cbc 256b 28,2 MiB/s 28,4 MiB/s twofish-cbc 256b 54,7 MiB/s 62,0 MiB/s aes-xts 256b 92,4 MiB/s 91,2 MiB/s serpent-xts 256b 29,8 MiB/s 31,2 MiB/s twofish-xts 256b 60,3 MiB/s 61,8 MiB/s aes-xts 512b 70,3 MiB/s 68,8 MiB/s serpent-xts 512b 30,0 MiB/s 31,2 MiB/s twofish-xts 512b 61,2 MiB/s 61,9 MiB/s
Note que o teste é feito em Memória RAM e ele retornará os resultados máximos que pode serm alcançados em sua máquina em especial
O cryptsetup suporta diferentes modos de oepração de encriptação, que podem ser usados com o dm-crypt. A mais comum (e padrão) é a luks, mas as seguintes podem ser utilizadas:
luks - Padrão utilizado pelo cryptsetup
plain - Para usar o dm-crypt no modo plain
loopaes - Para usar o modo legado loopaes
tcrypt - Para usar o modo de compatibilidade com o TrueCrypt/Veracrypt
Para utilizar, use o seguinte parâmetro na criação do sistema de arquivos encriptado: --type luks
A visualização do cabeçalho é útil para determinar a versão usada pelo Luks, cipher, hash, payload e bits de criptografia. Também é possível ver quantos slots de frase-senhas estão usados pelo cryptsetup. Por padrão, são permitidos a utilização de até 8 frase-senhas para abertura de um dispositivo de blocos.
Para isso, digite: cryptsetup luksDump /dev/sdc1
LUKS header information for /de/sdc1 Version: 1 Cipher name: aes Cipher mode: xts-plain64 Hash spec: sha256 Payload offset: 4096 MK bits: 256 MK digest: ef 74 30 8d d2 2c 4f ec e7 d5 5d 09 4c e5 74 44 d3 53 1e 36 MK salt: ab 6c d1 a7 32 f5 6c be 23 c7 37 d2 8b bf b5 da 59 56 96 41 54 76 6f 26 62 a6 eb ec ef 20 c8 62 MK iterations: 124750 UUID: 61037615-84d0-48f1-b414-ed5efe86bc87 Key Slot 0: ENABLED Iterations: 978966 Salt: bc 22 5b 48 b5 55 8f 01 2d 49 b7 5b 70 61 81 c7 e1 11 e3 c4 3b a0 ae 69 f5 fe 1f a4 cc bf 8a 71 Key material offset: 8 AF stripes: 4000 Key Slot 1: DISABLED Key Slot 2: DISABLED Key Slot 3: DISABLED Key Slot 4: DISABLED Key Slot 5: DISABLED Key Slot 6: DISABLED Key Slot 7: DISABLED
Note no exemplo acima, o cipher usado (aes), bits da chave (256) e que existe apenas uma frase senha armazenada no Slot 0.
É possível ter até 8 chaves por dispositivo criptografado usando o padrão LUKs. Isto permite ao usuário usar um key escrow: Uma chave é usada para uso diário, outra mantida em escrow (garantia) no caso da primeira ser esquecida ou se o arquivo de chave for perdido/danificado, o acesso ao conteúdo da partição não será perdido.
Por padrão, o slot 0 é criado durante a formatção da chave.
Para adicionar uma chave, use o comando:
cryptsetup luksAddKey /dev/sdc1 [arquivo/de/chave]
O padrão é peguntar pela frase-senha na console, que será adicionada ao próximo slot livre. Caso
[arquivo/de/chave]
seja especificado esse será usado (sem perguntar pela senha).
Para usar um arquivo de chave atual para autorizar a ação, a opção
--key-file
ou -d
precisa ser seguida por uma frase senha
válida precisa ser digitada.
Para substituir uma chave, é possível usar a opção -S/--key-slot [num] para indicar um número de slot que será substituido:
cryptsetup luksAddKey /dev/sdc1 -S 3 cryptsetup luksDump /dev/sdc1 | grep 'Slot 6'
O retorno será algo parecido com:
Key Slot 6: ENABLED
Existem basicamente três formas de remover uma chave do cabeçalho do Luks:
luksRemoveKey - Usando a frase/senha ou arquivo de senhas. Note que é requerido uma frase-senha existente no Luks, ou seja: caso houver apenas uma senha, ela não poderá ser removida.
luksKillSlot [num] - Remove uma chave de um slot (usando outra chave). Este comando é bastante útil quando você perde ou esquece uma frase senha armazenada no Luks. Recomendável adicionar uma nova frase-senha (veja “Adicionando uma chave ao Luks” para detalhes).
Antigamente era usado o luksDelKey, mas ele era pouco intuitivo... por exemplo, para apagar
a primeira chave do chaveiro usando a sintaxe antiga, o comando era o seguinte:
luksDelKey 1 0
.
luksErase - Remove TODAS as chaves ativas. Ele não pergunta uma frase-senha qualquer! é como se fosse um format no cabeçalho de acessos. Encare isso como uma forma ideal para DESTRUIR o acesso a um dispositivo se preciso. Você somente erá acesso ao conteúdo, caso tiver feito um backup do cabeçalho, como explicado em “Backup e Restore de cabeçalho/chaves”
Exemplos:
# cryptsetup luksRemoveKey /dev/dispositivo Será pedida a frase/senha que deverá ser removida. # cryptsetup luksKillSlot /dev/dispositivo 6 Será pedida uma frase senha existente para remover a frase-senha do Slot
O backup do cabeçalho do LUKS é importante para recuperar o acesso a partição, caso necessite em uma situação de corrompimento (ou caso a tenha excluido propositalmente, dependendo da situação em que se encontra). Como regra, recomendo não deixar o backup do cabeçalho na mesma máquina em que a partição LUKS se encontra, e se possível criptografe-a, com GPG (veja “Encriptando Dados”).
Para fazer o backup, é fácil, execute o seguinte comando, para acria ro arquivo
backup-header-luks.img
em /backup
:
Note que a recomendação é que o backup seja armazenado fora da máquina, em local seguro, e se possível criptografado com GPG (veja “Encriptando Dados”).
Para fazer a restauração de um backup gerado com o procedimento de “Fazendo o Backup de chaves/cabeçalhos”,
primeiro copie o backup do cabeçalho para um diretório local na máquina (vamos assumir /backup
neste exemplo), execute uma validação do cabeçalho com:
E o sistema deverá retornar algo como:
Key slot 0 unlocked Command successful.
Agora fazemos a validação da montagem do dispositivo gerado após a validação do cabeçalho com:
mount /dev/mapper/teste /mnt/ && ls /mnt umount /mnt cryptsetup luksClose teste
Os comandos acima fazem respectivamente:
Monta o dispositivo gerado a partir do cabeçalho de validação. Se tudo ocorrer bem
(&&), lista o conteúdo da pasta /mnt
.
Desmonta o ponto de montagem /mnt
.
Fecha o dispositivo do Luks teste
, impedindo que ele seja novamente montado.
Agora que validamos que o cabeçalhos esta OK, a restauração pode ser feita, exectando o comando:
cryptsetup luksHeaderRestore /dev/sdc1 --header-backup-file /backup/backup-header-luks.imgAgora execute novamente o cryptsetup dump (veja “Fazendo dump do cabeçalho de dispositivos”) para confirmar a restauração do cabeçalho de criptografia.
Existe também a possibilidade de usar o dd para o backup e restore dos cabeçalhos. O cabeçalho sempre reside no inicio do dispositivo criptogravado e o backup pode ser realizado sem precisar de acesso a ferramenta cryptsetup. Siga o seguinte procedimento:
Usaremos a ferramenta cryptsetup apenas para pegar o OffSet (quantidade de blocos de setores) correspondentes ao cabeçalho do Luks que precisam ser lidos no inicio da partição:
cryptsetup luksDump /dev/device | grep "Payload offset"Teremos uma saída como:
Payload offset: 4040
Em um disco de 512 bytes por setor, a quantidade de bytes que serão copiados pelo dd é dada pela fórmula: bytes_por_setor x OffSet
Agora, obtenha o valor de setores da unidade de disco com o comando: fdisk -l /dev/device | grep "Sector size"
Agora que temos os valores de bytes por setor e do Offset, vamos inserir os valores para
realizar o backup com o poderoso comando dd (lendo essa quantidade de
bytes do inicio do disco (512 x 4040) e salvando no arquivo /backup/backup-luks-dd.img
):
Você verá uma saída como:
271+1 registros de entrada 271+1 registros de saída 138856 bytes (139 kB, 136 KiB) copiados, 0,00123232 s, 92,8 MB/s
OBS: Como sugerido anteriormente, armazene o backup em um local protegido e de preferencia em um outro computador e criptografado com GPG, para garantir dupla segurança e integridade dos dados armazenados (veja “Encriptando Dados”).
A partir desse ponto, a restauração do backup é bastante simples. Basta copiar o arquivo
contendo o backup do cabeçalho com /backup/backup-luks-dd.img
e
executar o comando:
O backup será integralmente restaurado e você poderá conferir se o cabeçalho está novamente íntegro com “Fazendo dump do cabeçalho de dispositivos” e acessando novamente o sistema ce arquivos criptografado.
O cryptsetup possui o comando cryptsetup-reencrypt que é usado para converter um sistema não encriptado para um sistema LUKS.
ATENÇÃO! É fortemente recomendável que faça um backup completo dos dados que serão criptografados sob risco de perda de dados durante o processo automatizado!
Supondo que desejamos converter o dispositivo /dev/sdc1
para criptografia,
executamos o seguinte procedimento:
Primeiro, rodar o fsck na partição, para assegurar que a mesma encontre-se totalmente íntegra:
e2fsck -f /dev/sdc1e2fsck 1.43-WIP (18-May-2015) Pass 1: Checking inodes, blocks, and sizes ... /dev/sdc1: 12/166320 files (0.0% non-contiguous), 28783/665062 blocks
Depois precisamos reduzir o tamanho do sistema de arquivos para o menor tamanho
possível (considerando os arquivos armazenados). Assumindo que o sistema de arquivos
atual é um EXT?
, para isso usaremos o resize2fs
com o -M
:
resize2fs 1.43-WIP (18-May-2015) Resizing the filesystem on /dev/sdc1 to 26347 (4k) blocks. The filesystem on /dev/sdc1 is now 26347 (4k) blocks long.
O objetivo disso é reservar 'espaço livre' na partição para que a mesma tenha espaço suficiente para armazenar os arquivos que estão sendo encriptados.
Por experiência própria, recomendo ter pelo menos 40% de espaço em disco livre, principalmente se estiver armazenando arquivos muito grandes, onde cada um ocupe pelo menos 1% de espaço em seu disco.
Agora rodaremos o comando de encriptação:
cryptsetup-reencrypt /dev/sdb1 --new --reduce-device-size 4096SWARNING: this is experimental code, it can completely break your data. Enter new passphrase: Progress: 100,0%, ETA 00:00, 2596 MiB written, speed 37,6 MiB/s
Agora abriremos o dispositivo após reencriptação inicial. Neste passo você especificará a senha de descriptografia/acesso ao sistema de arquivos:
cryptsetup open /dev/sdc1 recryptEnter passphrase for /dev/sdc1: ...
Agora o último passo será voltar o sistema de arquivos ao tamanho original, após a conversão para criptografia. Novamente usaremos o resize2fs:
resize2fs /dev/mapper/recryptVocê verá a seguinte saída do comando:
resize2fs 1.43-WIP (18-May-2015) Resizing the filesystem on /dev/mapper/recrypt to 664807 (4k) blocks. The filesystem on /dev/mapper/recrypt is now 664807 (4k) blocks long.
Pronto, a partir de agora, o sistema está pronto para uso, bastando montar o dispositivo (que já foi decriptado), com:
mount /dev/mapper/recrypt /mnt
Copyright © 1999-2020 - Gleydson Mazioli da Silva