El cifrado en reposo protege los datos almacenados en disco: si alguien obtiene una copia del disco, una instantánea o un volumen retirado, solo verá datos ilegibles sin la clave. En Linux la forma estándar de hacerlo es LUKS (Linux Unified Key Setup) sobre dm-crypt, que cifra un dispositivo de bloques completo con AES. En este tutorial cifrarás un disco secundario (o, si tu servidor solo tiene un disco, un archivo contenedor) con LUKS2 en Ubuntu 24.04, lo montarás automáticamente al arrancar y harás una copia de seguridad de su cabecera.

Requisitos previos

  • Un servidor con Ubuntu 24.04 LTS, por ejemplo un VPS de CubePath. Los comandos son idénticos en Debian 12.
  • Un usuario no root con privilegios sudo.
  • Un disco o partición vacía dedicada a los datos cifrados. Si no tienes ninguno, usa la opción de archivo contenedor del paso 2.
  • Una copia de seguridad de cualquier dato que vayas a mover al volumen cifrado.

Qué protege y qué no

LUKS protege los datos cuando el volumen está cerrado: discos retirados, copias o instantáneas del disco, o acceso físico al almacenamiento. Mientras el volumen está abierto y montado, cualquier proceso o usuario con permisos en el sistema lee los datos en claro, así que no sustituye a los permisos, a las actualizaciones ni al control de accesos. Además, la protección real depende de dónde guardes la clave, algo que verás en el paso 5.

Paso 1: Instalar cryptsetup

cryptsetup es la herramienta que crea y gestiona volúmenes LUKS. Instálala:

sudo apt update
sudo apt install cryptsetup

Comprueba la versión:

cryptsetup --version
cryptsetup 2.7.0

Comprueba también que la CPU acelera AES por hardware (AES-NI en x86_64). Sin esa aceleración el cifrado funciona igual, pero con más consumo de CPU:

grep -m1 -o -w aes /proc/cpuinfo
aes

Paso 2: Elegir el dispositivo

Opción A: un disco o partición dedicada

Lista los dispositivos de bloques con su sistema de archivos y punto de montaje:

lsblk -f
NAME    FSTYPE FSVER LABEL UUID                                 FSAVAIL FSUSE% MOUNTPOINTS
vda
├─vda1  ext4   1.0         0d6c2f3e-8b0a-4d5e-9c1f-2a7b3c4d5e6f   31.2G    18% /
└─vda15 vfat   FAT32       6A1B-2C3D                              98.3M     6% /boot/efi
vdb

En este ejemplo vdb es un disco sin sistema de archivos ni punto de montaje: es el candidato. En los pasos siguientes sustituye /dev/vdb por tu dispositivo.

Opción B: un archivo contenedor

Si el servidor solo tiene el disco del sistema, puedes crear un archivo de tamaño fijo y cifrarlo. cryptsetup lo asocia automáticamente a un dispositivo loop al abrirlo. Crea un contenedor de 10 GB con permisos solo para root:

sudo fallocate -l 10G /srv/datos.luks
sudo chmod 600 /srv/datos.luks

Si usas esta opción, sustituye /dev/vdb por /srv/datos.luks en los pasos 3 a 5.

Paso 3: Crear el volumen LUKS

Formatea el dispositivo con LUKS2. Por defecto cryptsetup 2.7 usa AES-XTS con clave de 512 bits (AES-256) y Argon2id para derivar la clave de la frase de paso, así que no necesitas indicar más opciones:

sudo cryptsetup luksFormat --type luks2 /dev/vdb

Confirma escribiendo YES en mayúsculas e introduce una frase de paso larga. Esta frase es la clave de recuperación del volumen: guárdala en un gestor de contraseñas, porque si la pierdes (y no hay otra clave) los datos son irrecuperables.

WARNING!
========
This will overwrite data on /dev/vdb irrevocably.

Are you sure? (Type 'yes' in capital letters): YES
Enter passphrase for /dev/vdb:
Verify passphrase:

Comprueba la cabecera creada:

sudo cryptsetup luksDump /dev/vdb

La salida es larga; estas son las líneas que te interesan:

LUKS header information
Version:       	2
...
Keyslots:
  0: luks2
	Key:        512 bits
	PBKDF:      argon2id
...
Data segments:
  0: crypt
	cipher: aes-xts-plain64

Paso 4: Abrir, formatear y montar el volumen

Abre el volumen. La opción final es el nombre del dispositivo descifrado, que aparecerá en /dev/mapper/datos:

sudo cryptsetup open /dev/vdb datos

Crea un sistema de archivos ext4 sobre el dispositivo descifrado, nunca sobre /dev/vdb directamente:

sudo mkfs.ext4 -L datos /dev/mapper/datos

Crea el punto de montaje y monta el volumen:

sudo mkdir -p /srv/datos
sudo mount /dev/mapper/datos /srv/datos

Comprueba el resultado:

lsblk -f /dev/vdb
NAME      FSTYPE      FSVER LABEL UUID                                 FSAVAIL FSUSE% MOUNTPOINTS
vdb       crypto_LUKS 2           3f9a1c52-7d4e-4b8a-a6e1-9b2c0d7f4e81
└─datos   ext4        1.0   datos 8e2d4b6a-1c3f-4a5e-9d7b-0f1e2a3b4c5d    9.2G     0% /srv/datos

vdb aparece como crypto_LUKS y el sistema de archivos está en el dispositivo mapeado datos. Anota el UUID de la línea crypto_LUKS; lo necesitarás en el paso siguiente. Puedes obtenerlo en cualquier momento con:

sudo cryptsetup luksUUID /dev/vdb

Para cerrar el volumen a mano, desmonta primero y después ciérralo:

sudo umount /srv/datos
sudo cryptsetup close datos

Paso 5: Configurar el desbloqueo al arrancar

Hay dos formas de abrir el volumen después de un reinicio. Elige según tu modelo de amenaza.

MétodoProtege frente aInconveniente
Frase de paso manualCopia de todos los discos del servidorTras cada reinicio hay que entrar y desbloquear; los servicios que dependen de los datos no arrancan solos
Archivo de clave en el disco del sistemaCopia o retirada del disco de datos por separadoQuien obtenga el disco del sistema tiene también la clave

Opción 1: desbloqueo manual

Añade el volumen a /etc/crypttab con la opción noauto, para que el arranque no se detenga pidiendo la frase de paso. Abre el archivo:

sudo nano /etc/crypttab

Añade esta línea, con el UUID de tu volumen (para un archivo contenedor, pon la ruta /srv/datos.luks en lugar de UUID=...):

datos UUID=3f9a1c52-7d4e-4b8a-a6e1-9b2c0d7f4e81 none luks,noauto

Añade el montaje a /etc/fstab también con noauto:

sudo nano /etc/fstab
/dev/mapper/datos /srv/datos ext4 defaults,noauto 0 2

Tras cada reinicio, desbloquea y monta el volumen:

sudo cryptdisks_start datos
sudo mount /srv/datos

Opción 2: archivo de clave

Genera una clave aleatoria de 4096 bytes en un directorio accesible solo para root:

sudo mkdir -m 700 -p /etc/cryptsetup-keys.d
sudo dd if=/dev/urandom of=/etc/cryptsetup-keys.d/datos.key bs=4096 count=1
sudo chmod 400 /etc/cryptsetup-keys.d/datos.key

Añádela a un segundo keyslot del volumen. Te pedirá la frase de paso actual, que sigue funcionando como clave de recuperación:

sudo cryptsetup luksAddKey /dev/vdb /etc/cryptsetup-keys.d/datos.key

Comprueba que el archivo abre el volumen sin pedir nada (hazlo con el volumen cerrado):

sudo cryptsetup open --test-passphrase --key-file /etc/cryptsetup-keys.d/datos.key /dev/vdb && echo "clave correcta"
clave correcta

Edita /etc/crypttab:

sudo nano /etc/crypttab
datos UUID=3f9a1c52-7d4e-4b8a-a6e1-9b2c0d7f4e81 /etc/cryptsetup-keys.d/datos.key luks

Y /etc/fstab. La opción nofail evita que el servidor se quede en modo de emergencia si el volumen no se puede abrir:

sudo nano /etc/fstab
/dev/mapper/datos /srv/datos ext4 defaults,nofail 0 2

Recarga la configuración de systemd, que genera las unidades a partir de crypttab y fstab, y prueba el montaje sin reiniciar:

sudo systemctl daemon-reload
sudo cryptdisks_start datos
sudo mount -a
findmnt /srv/datos
TARGET     SOURCE            FSTYPE OPTIONS
/srv/datos /dev/mapper/datos ext4   rw,relatime

Por último, reinicia el servidor y comprueba con findmnt /srv/datos que el volumen se monta solo.

Paso 6: Hacer una copia de la cabecera LUKS

La cabecera LUKS contiene los keyslots. Si se corrompe (un error de disco, un mkfs sobre el dispositivo equivocado), los datos son irrecuperables aunque conozcas la frase de paso. Guarda una copia:

sudo cryptsetup luksHeaderBackup /dev/vdb --header-backup-file /root/datos-luks-header.img

Descarga el archivo a un lugar seguro fuera del servidor y después bórralo del servidor. Quien tenga esa copia y una frase de paso antigua podría abrir el volumen incluso tras cambiarla, así que trátala como una clave.

Para restaurarla en caso de corrupción:

sudo cryptsetup luksHeaderRestore /dev/vdb --header-backup-file datos-luks-header.img

Paso 7: Gestionar las claves

Consulta qué keyslots están en uso:

sudo cryptsetup luksDump /dev/vdb | grep -A1 -E '^\s+[0-9]+: luks2'

Para cambiar la frase de paso de un keyslot (por ejemplo, cuando alguien que la conocía deja el equipo):

sudo cryptsetup luksChangeKey /dev/vdb

Para eliminar una clave, indica el keyslot. No borres nunca la última clave válida:

sudo cryptsetup luksKillSlot /dev/vdb 1

Cambiar o eliminar claves no vuelve a cifrar los datos: la clave maestra del volumen sigue siendo la misma. Si sospechas que la clave maestra se ha filtrado, crea un volumen nuevo y copia los datos.

Solución de problemas

Device /dev/vdb is in use al ejecutar luksFormat. El disco está montado o forma parte de otro dispositivo. Comprueba con lsblk y findmnt y desmóntalo antes.

El servidor arranca en modo de emergencia tras editar fstab. Falta nofail o el nombre en /dev/mapper/ no coincide con el de crypttab. Accede por la consola del panel, comenta la línea en /etc/fstab y revisa journalctl -b -u [email protected].

No key available with this passphrase. La frase de paso o el archivo de clave no corresponden a ningún keyslot. Revisa la distribución del teclado si escribes en la consola y verifica el archivo con --test-passphrase.

Conclusión

Has cifrado un volumen con LUKS2, lo has configurado para abrirse al arrancar y has guardado una copia de su cabecera. Recuerda que el cifrado en reposo solo es tan fuerte como la custodia de sus claves: guarda la frase de paso y la copia de la cabecera fuera del servidor. Como siguientes pasos, mueve a /srv/datos los directorios con datos sensibles (bases de datos, subidas de usuarios), cifra también las copias de seguridad que salen del servidor y protege los datos en movimiento con TLS.