LUKS: Encriptar físicamente tus particiones en Fedora Server


Hace mucho que no escribía por acá y la razón era que me encontraba ocupado remodelando los sitios web de Xenode Systems y reestructurando nuestra infraestructura. Parte de dicha reestructuración incluyó ciertas mejoras en los mecanismos de seguridad para cierta data sensible que manejamos, entre ellas la implementación de lo que yo llamo "cifrado físico" de nuestros servidores.

¿De qué va el cifrado físico?

Sencillo. La idea es tener una partición cifrada/encriptada en cada servidor que sea no solo bastante segura, sino también usable para varios aspectos. La mejor opción en nuestro caso de uso específico fue optar por el método de cifrado común que ofrece Fedora Server en su instalador para data sensible creando una partición LUKS especial donde contener dicha data. Tras montarse, una partición/volumen luks se comporta igual que una partición común (según el sistema de archivos que contenga bajo la capa de cifrado) y se pueden crear carpetas/jugar con permisos y owners dentro de ella sin mayor problema á la sistem-wide, con las ventajas de que, (sin saber la passphrase) un atacante no puede montar dicha partición por si mismo y dependiendo de la fuerza de dicha passphrase la data puede quedar irrecuperable bajo varios escenarios aún si el atacante usara herramientas y software especializado para intentar recuperar algo.

SIN EMBARGO, como todos los sysadmins sabemos, la idea de un servidor (sea web, de archivos, o prácticamente cualquiera) es que se mantenga con lo más cercano al 100% de uptime sin intervención humana, y en el caso de un servidor que tenga una partición cifrada (a menos de que alguien esté 24/7 monitoréandolo y/o no pueda apagarse/reiniciarse por ningún motivo sobre la tierra) esto no es posible, pues al re-arrancar requiere introducir la passphrase para continuar con el proceso de booteo.

¿No sería genial si tuviéramos una especie de token con el cual el servidor se desencriptara por sí solo y al no tenerlo disponible hiciera fallback al método por passphrase? (o en casos extremos, ¿no sería genial si, deshaciéndonos de dicho token la data quedara irrecuperable?) De eso va este tutorial. Veamos entonces:

NOTA: Las instrucciones aquí mostradas son específicamente para el sistema operativo Fedora Server. Si bien, en otros sistemas Linux pueden funcionar hay ciertos pasos que tienes que omitir y dado que estamos hablando de cuestiones delicadas, te recomiendo hacer tus pruebas en entornos virtuales primero. Personalmente no voy a explicar pasos para otros entornos fuera del setup ya mencionado en esta nota. También es importante mencionar que este setup no va a funcionar en sistemas RAID con particiones BTRFS.

1) Lo que necesitas

Necesitas tener una instalación de Fedora Server funcionando con una partición Crypto-LUKS ya implementada en el sistema para proteger tus datos. Si no la tienes (porque elegiste un setup sin cifrar al instalar), la puedes crear en un sistema ya instalado; En dado caso recuerda que Google/DuckDuckGo son un buen recurso para buscar algunos howtos sobre el procedimiento.

2) El token

En mi caso voy a utilizar una MicroSD de 512MB que tenía por ahí arrumbada, no se requiere más. Puedes usar una de éstas como token conectada a algún lector de SD estándar o a un puerto USB (usando los adaptadores correspondientes); Necesitarás formatear dicha SD en Ext4 (puedes usar alguna herramienta como Gparted para esto) y luego, (suponiendo que estés usando un lector SD como "puerto"), haremos lo siguiente tras conectarla al servidor:

1. su -
2. mkdir /media/sd
3. fdisk -l

El output del tercer comando te dirá cómo se llama tu dispositivo. En mi caso se llama /dev/sdb y obviamente la única partición que tiene hecha es la Ext4 que le hice tomando el espacio total del dispositivo, misma que entonces se llama /dev/sdb1.

Teniendo esta información en mano, procederemos a "forjar" nuestro token:

# mount /dev/sdb1 /media/sd
# e2label /dev/sdb1 luksSD

Donde luksSD es el nombre que le daremos al token en el sistema. Proseguimos:

# dd if=/dev/urandom of=/media/sd/usb.key bs=4096 count=1
# cryptsetup luksAddKey /dev/sda7 /media/sd/usb.key

NOTA: En los comandos de arriba, usb.key es el nombre de nuestro keyfile (el archivo que desbloqueará nuestra partición/dispositivo en lugar de la contraseña)... Éste puede llevar cualquier nombre que queramos y en sí no necesita una extensión. Por otro lado /dev/sda7 es nuestra partición cifrada a la cual le añadiremos como clave/passphrase el keyfile para desbloquearla en automático con el token después. Cabe destacar que nuestro keyfile puede ser un archivo oculto si así lo deseamos y también debo mencionar que si no sabes el mountpoint de tu partición cifrada puedes hacer uso de los comandos df -h y/o lvscan para obtenerlo.

El segundo comando nos pedirá introducir la passphrase de nuestra partición/volumen cifrado UNA SOLA VEZ, así que no puedes equivocarte. Hazlo con mucho cuidado.

3) Preparando el sistema

Ahora corremos en consola:

# nano /etc/crypttab

y en el archivo que nos saldrá, cambiaremos la palabra none por el nombre de nuestro keyfile con una diagonal, de manera que nos quede algo más o menos así:

luks-MY-LUKS-UUID /usb.key

Guardamos los cambios y ahora corremos el comando:

# nano /etc/default/grub

para quitar rhgb quiet de la variable GRUB_CMDLINE_LINUX y añadir en su lugar lo siguiente:

rd.luks.uuid=luks-MY-LUKS-UUID rd.luks.key=/usb.key:LABEL=luksSD

Reemplazando MY-LUKS-UUID por el UUID de tu dispositivo/partición cifrad@, mismo que puedes tomar del archivo /etc/crypttab que editamos anteriormente (además de poner el nombre de tu keyfile junto a la diagonal y la etiqueta/nombre de tu token según corresponda).

Acto seguido corremos:

# nano /etc/dracut.conf

para descomentar/establecer las siguientes variables (ambas se encuentran comentadas y vacías al principio del archivo):

omit_dracutmodules+="systemd"
add_dracutmodules+="crypt lvm"

Finalizando...

Ahora sólo queda correr:

# grub2-mkconfig -o /boot/grub2/grub.cfg
# dracut --force

Y en cuanto estos dos comandos terminen su trabajo reiniciamos y veremos cómo nuestro servidor inicia automáticamente sin pedir passphrase cuando tiene el token conectado mientras que si se lo quitamos hace fallback al método de introducción de frase de paso de siempre.

Hemos terminado, sólo falta asegurar nuestro token. Muchas SD tienen un "switch" para habilitar un modo de "sólo lectura", es recomendable habilitarlo... Si estás usando un adaptador o una USB probablemente no cuentes con ésta característica (y ultimadamente no está demás proteger el dispositivo a nivel sistema, independientemente del switch físico ¿verdad?) entonces para hacer tu token "sólo lectura" (y por ende protegerlo) añadiremos la siguiente línea a nuestro /etc/fstab:


Y eso sería todo.