Uno de los mecanismos más eficaces para proteger nuestra información es el cifrado. Hoy no se me pasa por la cabeza tener un portátil sin el disco cifrado. Lo grave no sería la pérdida física del mismo, sino la de la información que lleve y en las manos que pueda acabar. Pero esto no es sólo aplicable a portátiles, discos USB o pendrives con información sensible también deberían estar cifrados para evitar que dicha información sea accesible por terceros no autorizados.
En GNU/Linux tenemos múltiples opciones a la hora de cifrar nuestra información. GPG sobre ficheros, eCryptfs o EncFS sobre directorios, TrueCrypt o dm-crypt sobre dispositivos, loop-AES para ficheros loop, etc. De todas las opciones mi preferida es LUKS (Linux Unified Key Setup), que podemos usar sobre discos, particiones, volúmenes lógicos (LVs) o ficheros loop. Entre sus ventajas están: su sencillez de uso, incluido en el propio kernel y la capacidad de asignar, cambiar y revocar varias claves para un mismo dispositivo.
La instalación de muchas distribuciones actuales hace muy sencillo incorporar el cifrado del sistema completo desde el principio. Mi recomendación en un portátil es: crear una pequeña partición para /boot (que no irá cifrada) y dejar el resto del disco para ser cifrado con LUKS. Sobre dicho cifrado crear un PV para LVM y todo lo que vaya sobre el LVM ya estará cifrado.
Pero en la entrada de hoy veremos como usar LUKS en un sistema que ya está corriendo, por ejemplo para cifrar un nuevo volumen lógico, un fichero loop donde guardar información sensible, o un dispositivo USB donde realizar backups.
Ingredientes
Tener instalado el paquete cryptsetup (también llamado cryptsetup-luks en algunas distribuciones). Tener un dispositivo sin usar (su información será reescrita al cifrarlo inicialmente), por ejemplo /dev/sdc, /dev/vgpruebas/cifrado, /dev/sdb2,… En el caso de querer user un fichero (loop) podemos crearlo con este comando:
## En este ejemplo 50 bloques de 1MB ~ 50MB ## Aunque es posible crecer el fichero posteriormente es ## algo enrevesado, mejor afinar con el tamaño que necesitemos ## Podemos usar /dev/zero como origen de datos en la creación ## del fichero también, pero facilitaría un posible criptoanálisis $ dd if=/dev/urandom of=fichero_cifrado bs=1M count=50
Inicialización del cifrado
El primer paso será dar el formato LUKS al dispositivo. Para ello usaremos el comando cryptsetup con argumento luksFormat. Entre las diversas opciones que podemos especificar está el algoritmo de cifrado, el tamaño de la clave o la función hash (resumen) o el fichero clave.
Veamos algunos ejemplos:
## Cifrar el fichero creado en el ejemplo anterior con una ## contraseña, pidiéndola dos veces (para confirmar que ## se tecleó correctamente). Usando valores por defecto ## para el cifrado: $ cryptsetup --verify-passphrase luksFormat fichero_cifrado ## Podemos averiguar el algoritmo, tamaño de clave y función ## hash que se usan por defecto con este comando: $ cryptsetup --help | grep LUKS.*Key LUKS1: aes-xts-plain64, Key: 256 bits, LUKS header hashing: sha1, RNG: /dev/urandom ## Si los valores por defecto no nos convencen, podemos ## especificar otros, por ejemplo un tamaño de clave de ## cifrado mayor (de 256 bits) y una función hash que no ## haya sido declarada insegura (como es el caso de SHA1): cryptsetup --hash=sha256 --key-size=512 --verify-passphrase \ luksFormat fichero_cifrado ## Cifrar un dispositivo (p.e. un disco USB) usando un fichero ## como contraseña. ## Primero creamos el fichero de contraseña (podemos hacerlo ## a mano, o usar /dev/random o /dev/urandom para rellenarlo) $ dd if=/dev/urandom of=mi_secreto bs=1M count=1 ## Un megabyte de contraseña! ## ¿Qué tamaño máximo de contraseña (tecleada o en fichero) ## podemos usar? El siguiente comando lo aclara: $ cryptsetup --help | grep Maximum Maximum keyfile size: 8192kB, Maximum interactive passphrase length 512 (characters) ## Una vez tenemos el fichero de contraseña, podemos dar el ## formato LUKS usando éste, en vez de tecleando una contraseña ## de forma interactiva ## El siguiente comando lo ejecutamos como root, al tratarse ## de un dispositivo (/dev/sdc) y no un fichero de usuario: # cryptsetup luksFormat /dev/sdc /path/al/fichero/mi_secreto ## o # cryptsetup --key-file=/path/al/fichero/mi_secreto luksFormat /dev/sdc ## Por supuesto también podríamos modificar el tamaño de clave ## de cifrado o la función hash.
Clave de cifrado, contraseña y cabecera LUKS
Llegados a este punto debo (intentar) esclarecer algún término. Cuando damos formato LUKS a un dispositivo/fichero hablamos de dos términos similares, pero diferentes:
- Contraseña. Ya sea una tecleada en el momento, o un fichero usado como tal, es la que nos permite acceder al dispositivo LUKS. Esta contraseña no es usada para cifrar los datos. De hecho, una de las ventajas de usar LUKS es que podemos usar varias contraseñas/ficheros contraseña para un mismo dispositivo. Más adelante daré un ejemplo.
- Clave de cifrado. Esta clave se genera automáticamente cuando damos el formato LUKS al dispositivo. Se genera de forma aleatoria (por defecto usando /dev/urandom) y con el tamaño por defecto (256 bits) o el que se especifique con la opción –key-size. Si bien es posible especificar una clave de cifrado de forma manual (–master-key-file) no es recomendable hacerlo salvo que sepas exactamente que estás haciendo.
El formato LUKS se caracteriza por una cabecera que incluye la información del algoritmo de cifrado, tamaño de clave, contraseñas en uso, etc. Podemos consultar dicha cabecera (que no las contraseñas!) con el siguiente comando:
$ cryptsetup luksDump fichero_cifrado LUKS header information for fichero_cifrado Version: 1 Cipher name: aes Cipher mode: xts-plain64 Hash spec: sha256 Payload offset: 4096 MK bits: 512 MK digest: ca cb 7e f6 20 fa 42 8a 7e 0a 92 66 86 bd 20 46 77 28 a5 25 MK salt: a1 e5 54 8d c2 4d db af 3d 72 73 4d f6 0b 9f b7 41 d7 46 31 ce dc f8 11 21 86 8c 22 d9 cf e5 ca MK iterations: 95125 UUID: d58132bd-ea6b-4879-aa73-c8d444300545 Key Slot 0: ENABLED Iterations: 378697 Salt: 1a 54 1a cd 92 74 13 78 5d 72 f4 00 60 b4 69 85 c7 8a a9 fa 50 65 6b 32 f4 13 a4 e2 b6 3b c3 69 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
En este ejemplo vemos que se está usando AES como algoritmo de cifrado, que el tamaño de clave es de 512 bits, la función hash es SHA256 y que hay una contraseña (de las 8 posibles) en uno (Key Slot 0: ENABLED). El resto de posibles contraseñas no están establecidas (DISABLED).
Usando el dispositivo cifrado
Una vez tenemos el formato LUKS en el dispositivo, para acceder a los datos en claro habrá que «abrir el contenedor cifrado». Es decir, antes de poder usarlo (montarlo o formatearlo) hay que descifrarlo:
## Si vamos a abrir un fichero protegido con ## contraseña "tecleada": # cryptsetup luksOpen fichero_cifrado dispositivo_descifrado ## Si el fichero o dispositivo está protegido con un fichero ## contraseña, se lo indicamos como opción: # cryptsetup --key-file=mi_secreto luksOpen /dev/sdc dispositivo_descifrado ## Unos comentarios sobre estos ejemplos: ## 1.- "dispositivo_descifrado" es el nombre que queremos para el ## dispositivo que se creará trás ejecutar este comando ## y que será el que ya usemos para formatear o montar de forma ## normal ## 2.- Si la contraseña es válida, desde este momento podremos acceder ## al dispositivo "en claro" como /dev/mapper/dispositivo_descifrado ## 3.- Estos comandos se ejecutan con el usuario "root" ya que crean ## un dispositivo nuevo. (Sí, seguro que hay interfaces de usuario ## que permiten estas tareas a un usuario corriente)
Por supuesto, la primera vez que lo abrimos lo más frecuente será formatearlo, como con cualquier dispositivo nuevo:
mkfs.ext4 /dev/mapper/dispositivo_descifrado
Desde ese momento, y después de abrirlo con «luksOpen«, simplemente lo montaremos como el resto de dispositivos de almacenamiento:
mount /dev/mapper/dispositivo_descifrado /media/mis_datos_secretos
Cerrar después de usar
Cuando ya no necesitemos acceso a los datos, y después de desmontar como con cualquier otro dispositivo de almacenamiento, debemos «cerrar» el acceso al dispositivo sin cifrar. O como decía Mamá – deja las cosas como las encontraste:
## Desmontar antes de cerrar el acceso # umount /media/mis_datos_secretos ## Eliminar el acceso al dispositivo descifrado # cryptsetup luksClose dispositivo_descifrado
¿Varias contraseñas?
Para terminar comentaré una de las características que más me gustan de LUKS y que en un principio puede sonar extraña: la capacidad de tener varias contraseñas/ficheros contraseña.
Insistir en que las contraseñas no son las que se usan para cifrar, eso se hace con la clave de cifrado, sino para dar acceso a ésta y poder abrir el dispositivo. Poder usar más de una (y ser capaces de revocarlas, cambiarlas o añadirlas) permite:
- Tener una contraseña por usuario para un mismo dispositivo. De forma que cada uno sabe la suya y si un día se decide evitar el acceso de uno de ellos basta con eliminar su contraseña, lo que no afecta al resto de usuarios.
- Tener una contraseña para nosotros (que tecleamos cuando queremos acceso al dispositivo) y tener un fichero contraseña para tareas automatizadas (por ejemplo backups). Yo tengo un disco USB donde se hacen backups de mi portátil de forma automática. Para no tener que teclear la contraseña (y estar delante del ordenador) cuando se realiza el backup, en el disco del portátil tengo un fichero contraseña que le permite descifrar el USB y realizar el backup. Por supuesto este fichero contraseña sólo puede leerlo el usuario root y el disco de mi portátil está cifrado. Pero ¿qué pasaría si el disco de mi portátil muere? Ya no tendría el fichero contraseña para descifrar el disco USB de backup. Estúpida situación ésta… Salvo que el USB con LUKS tiene una segunda contraseña (que puedo teclear) y que me permitiría acceder a él aunque el disco de mi portátil muriera.
Sobra decir que hay que tener sumo cuidado con los ficheros usados como contraseña, su acceso debería estar extremadamente limitado (permisos, acceso al dispositivo donde se almacenan, etc..).
¿Cómo gestionamos las contraseñas de un dispositivo con LUKS?
Como vimos anteriormente, podemos ver la información de la cabecera LUKS con el comando «cryptsetup luksDump DISPOSITIVO«. En el veremos los «slots» («contraseñas») que están en uso. Normalmente el slot-0 siempre lo está, porque es donde se guarda la contraseña inicial. Podemos añadir una nueva contraseña con el siguiente comando:
## Si queremos una contraseña "tecleada" # cryptsetup luksAddKey /dev/sdc ## Primero nos pedirá una contraseña ya existente ## en alguno de los slots, si no hay contraseña ## sino "fichero contraseña" deberemos usar la ## opción --key-file: # cryptsetup --key-file=/etc/mi_secreto luksAddKey /dev/sdc ## Si queremos añadir un "fichero contraseña" # cryptsetup luksAddKey /dev/sdc /etc/mi_nuevo_secreto ## Al igual que antes, si no hay una contraseña en ## algún slot, sino que son todo ficheros contraseña ## le indicamos alguno de los actuales con --key-file # cryptsetup --key-file=/etc/mi_secreto \ luksAddKey /dev/sdc /etc/mi_nuevo_secreto
También podemos borrar o cambiar contraseñas (o ficheros contraseña) existentes:
## Para borrar un "slot" tenemos dos opciones: ## Teclear (o especificar el fichero contraseña ## después del nombre de dispositivo) $ cryptsetup luksRemoveKey /dev/sdc $ cryptsetup luksRemoveKey /dev/sdc /etc/secreto_a_eliminar ## O si no tenemos/recordamos la contraseña, especificar ## el slot que queremos eliminar (nos pedirá alguna de las ## contraseñas (o ficheros contraseña con --key-file) ## restantes en otro slot $ cryptsetup luksKillSlot /dev/sdc 2 $ cryptsetup --key-file /etc/secreto_valido /dev/sdc 2
Copia de seguridad
El punto más débil de nuestro dispositivo cifrado es la cabecera LUKS. Sin ésta sería imposible acceder a los datos que contiene. Es recomendable por tanto, realizar una copia de seguridad de ella que nos permita acceder a los datos cifrados en el caso de que la cabecera LUKS quede dañada (por error en su gestión, o daño físico en el dispositivo de almacenamiento).
## Podemos sacar una copia de la cabecera con el siguiente comando $ cryptsetup luksHeaderBackup /dev/sdc --header-backup-file cabecera_backup ## O restaurar una cabecera dañada desde un backup $ cryptsetup luksHeaderRestore /dev/sdc --header-backup-file cabecera_backup
No metas cosas en criptas, cogen humedad
Cada vez que alguien dice «encriptar» o «encriptado» Dios mata un gatito. FYI.
$ exit
Muy interesante este articulo, muy completo y me ha sido de gran ayuda, tengo un par de preguntas:
1- Cuales son las funciones hash que soporta LUKS? cual es la mas recomendada y segura?
2- He cifrado una partición de mi usb con LUKS y todo marcha bastante bien, el problema es cuando ingreso mi dispositivo en un sistema Windows, sencillamente no reconoce dicha particion (supongo que es por el formato crypt-luks), me he estado documentando sobre el tema y recomiendan que desde windows se habran dichas particiones con el programa FreeOTFE el problema es que no se si es impresion mia, pero al parecer no le dan soporte desde el 2013, hay otra forma de que yo pueda abrir este tipo de particiones en windows? amm no se de una forma mas limpia sin necesidad de instalar nada? y que pasa exactamente con los sistemas operativos Mac OS? pasa igual que windows? o puede leer y escribir sin problema en la particion?
muchas gracias.
Hola Juano,
1.- Las funciones hash posibles son las soportadas por el kernel, en /proc/crypto tienes la info. Una forma de listarlas:
awk ' BEGIN { RS="\n\n" ; FS="\n" } $7 ~ "hash" { print $1 }' < /proc/crypto
Cargando módulos adicionales se podrían aumentar. Por ejemplo:
# modprobe sha512_generic
2.- Sobre Windows y OSX no puedo ayudarte mucho, no soy usuario de ninguno de los dos. Aunque sí sabía de la existencia de FreeOTFE, no sé de su funcionamiento en los diferentes Windows.
Gracias por tu comentario. Alberto
Hola, tengo un problema, al montar la unidad en un directorio, éste aparece con permisos de root. Como hago para que todos los usuarios accedan al dispositivo?
Hola Raúl, cuando montas un sistema de ficheros (que está en un dispositivo) la raíz de dicho sistema de ficheros suele ser propiedad de root. Es por esto que, después del montaje, el directorio donde se montón es de propiedad de root. Tienes dos opciones, cambiar el propietario de la raiz del sistema de ficheros (es decir del punto de montaje una vez montado), o crear un directorio bajo el punto del montaje y cambiarle el propietario a éste (dejando el punto de montaje bajo la propiedad de root). Yo soy más amigo de la segunda solución, aunque para gustos están los colores (y los permisos).
> No metas cosas en criptas, cogen humedad
> Cada vez que alguien dice “encriptar” o “encriptado” Dios mata un gatito. FYI.
Lamento decirte que «encriptar» no tiene nada que ver con criptas. Según el libraco ese llamado Diccionario de la RAE «encriptar» significa… CIFRAR.
Parece que los gatitos están sanos y salvos. FYI.
Que un barbarismo acabe en el libraco de la RAE no hace que deje de ser un barbarismo. La RAE también contiene «cederrón» o «jonrón» y no por ello dejan de ser una burrada, en mi opinión por supuesto. Así que los gatitos mejor los encriptamos, es decir los metemos en criptas, a ver si así pasan desapercibidos y se libran de la ira del Señor. 🙂
Solo me pregunto ¿cuantas vidas gatunas perecieron con esta discusión?
Saludos raza.
M.
Hola notee,
Como anecdota graciosa, comentarte que «toballa» tambien aparece en la RAE jajaja
Un saludo.
Vaya, otro articulo que me parece mas que interesante. He llegado a tu blog buscando un articulo sobre LVM, y tras ver tu genial explicacion, me he puesto a ojear el resto de articulos, y la verdad es que me gustan mucho la mayoria de temas que tratas, y que abarcas el tema de la seguridad. Definitivamente, creo que me quedare por aqui, y te animo a que sigas publicando mas articulos y a que pongas un apartado de enlaces a otras paginas que creas son interesantes.
Y acerca del tema de este articulo.. como afecta el cifrado al rendimiento de un portatil, por ejemplo? Se nota mucho? Supongo que tu hablas de cifrar alguna particion donde guardes los datos sensibles, y no el disco entero, lo cual suena bastante logico.
Un saludo y gracias por compartir.
Hola Alejandro,
Gracias por tus comentarios. Sobre el rendimiento del portátil no tengo números concretos. Yo cifro el disco completo, de los portátiles, de algunos servidores y del móvil, y no creo que represente un impacto importante en el rendimiento de las máquinas. No «sale gratis», pero la CPU no suele ser el cuello de botellas en mis máquinas, y salvo que tengas una E/S muy intensa (¿servidor de BBDD o ficheros?) no creo que sea apreciable la degradación por el cifrado.
Saludos.
Hola, te felicito por tu post. Tengo una pregunta, en caso de que cifremos todo el disco de nuestro pc por ejemplo, incluyendo el sistema operativo, ¿qué proceso tendríamos que realizar para poder iniciar sesión y desbloquear el acceso? He realizado una prueba en una máquina virtual y al iniciar la máquina obtengo: «Fatal: no booteable medium found! system halted».
Saludos
Si quieres cifrar todo, tienes que dejar la partición /boot fuera del cifrado (en una partición normal). Allí reside el kernel que en el arranque se encargará de descifrar el resto. Saludos.
¿Sería posible realizar el cifrado sobre un disco duro que tiene el sistema operativo ya instalado, sin tener que mover los datos de un disco duro a otro y después recuperarlos? Es decir saltarnos el paso de formatear la partición después de aplicar el cifrado.
Un saludo y gracias.
Hola, mucho me temo que no es posible. Al menos no que yo sepa.
Saludos.
Hola, la verdad no entiendo muy bien todo esto, quisiera saber como puedo usar Cryptsetup igual como lo hacia Truecrypt que me crea un solo archivo contenedor para poder colocar ahí otros archivos como programas, documentos, etc.
hola muy bueno tu post, genial me sirvio bastante, tengo una duda solo puedo hacer el cifrado con LVM? , o tambien podria hacerlo con particiones primarias, de ser asi? hay alguna desventaja con esto?
Gracias por tus comentarios.
Hola Luka, también se puede hacer con particiones. De hecho yo el LVM lo uso «encima/despúes» del cifrado. Lo que cifro es la partición del disco. Saludos!
Pingback: LINUX – Software Free Box