Partición cifrada con DMCRYPT

Este artículo explica cómo cifrar una partición de datos de forma que podamos alojar en ella datos sensibles, incluyendo el perfil de Firefox, la configuración de pidgin, documentos, etc.

Aunque un tercero lograra hacerse con acceso físico a nuestro disco duro, no tendría forma de leer los datos de la partición cifrada. No sólo resulta útil como almacen de datos "estáticos", sino que como veremos en este mismo "howto", podemos alojar en la partición cifrada los perfiles de Firefox, pidgin, etc (con sus bookmarks, contraseñas, caché…) y hacer que la partición cifrada se monte al hacer login mediante la introducción manual de la passphrase de desbloqueo del cifrado.

Utilizaremos dmcrypt, que viene con la mayoría de las distribuciones de GNU/Linux. En este caso, lo configuraremos sobre Ubuntu.


Cifrado de una partición

Instalamos el software necesario:

apt-get install cryptsetup hashalot

A continuación creamos una partición sin datos (importante, ya que la vamos a formatear). En el ejemplo he usado /dev/sdX, aunque lo normal es que la creemos en /dev/sda (primer disco) o en un disco USB que comunmente será /dev/sdb en adelante.

# fdisk /dev/sdX

Opcionalmente, si tenemos suficiente tiempo (este comando tardará mucho en ejecutarse, especialmente en discos USB o discos grandes), podemos rellenar el disco con datos aleatorios (más seguro que simplemente hacer un wipe de su contenido):

# badblocks -c 10240 -s -w -t random -v /dev/sdX1

Creamos el contenedor cifrado, le asignamos una passphrase y dentro de él creamos el filesystem. Este filesystem se puede montar siempre que el contenedor esté desbloqueado:

# cryptsetup --verbose --verify-passphrase luksFormat /dev/sdX1
# cryptsetup luksOpen /dev/sdX1 disco_cifrado
# mkfs.ext3 -j -m 1 -O dir_index,filetype,sparse_super /dev/mapper/disco_cifrado
# mkdir /mnt/disco
# mount /dev/mapper/disco_cifrado /mnt/disco

Tras desmontar el disco, no debemos olvidar el cerrar el contenedor de cifrado:

# umount /mnt/disco
# cryptsetup luksClose /dev/mapper/disco_cifrado

Si necesitaramos añadir un fichero de passphrase como método de autenticación válido introducimos una contraseña dentro de un fichero con permisos 0600 y ejecutamos:

# cryptsetup luksAddKey /dev/sdX1 /root/passwords/fichero_passwd


Script de montaje de disco cifrado en arranque de GNOME

En el caso de que el disco sea un disco de sistema (no USB) y sepamos de antemano el device a montar, y vayamos a hacer uso del disco para datos del sistema (por ejemplo, partes necesarias de funcionamiento de gnome o de aplicaciones como el perfil de firefox u otros programas), necesitaremos montar el disco cifrado en el arranque de GNOME, antes de lanzar el resto de aplicaciones.

Agregar lo siguiente en "Aplicaciones al inicio" de GNOME:

gksu /home/sromero/bin/monta_disco_cifrado.sh

El contenido de dicho script es:

$ cat bin/monta_disco_cifrado.sh 
#!/bin/sh

export DEVICE_DESTINO="/dev/mapper/disco_cifrado"
export DEVICE_DESTINO_RAW="/dev/sda1"
export MOUNT_POINT="/cifrado"
export LABEL_DESTINO="disco_cifrado"
export FICH_PW="/tmp/monta_cifrado"

COUNT="0"
TRY="4"

while /bin/true;
do

   # 3 intentos
   COUNT="`expr $COUNT + 1`"
   if [ "x${COUNT}" == "x${TRY}" ];
   then
      zenity --info --text="Error desbloqueando unidad cifrada."
      rm -f $FICH_PW
      exit
   fi

   zenity --entry --title="Add an Entry" \
   --text="Introduzca password para desbloquear cifrado:" \
   --entry-text "" --hide-text > $FICH_PW

   chown root:root $FICH_PW
   chmod 0600 $FICH_PW

   cryptsetup luksOpen $DEVICE_DESTINO_RAW $LABEL_DESTINO --key-file $FICH_PW

   # Si se pudo desbloquear el disco cifrado, montarlo
   if [ "$?" == "0" ];
   then
      rm -f $FICH_PW
      mount $DEVICE_DESTINO $MOUNT_POINT
   fi

   # Si el disco se monto correctamente, salimos
   if mount | grep -q $MOUNT_POINT ;
   then
      exit
   fi

done

Si colocamos el anterior script en el arranque de gnome, tras logarnos con nuestro usuario se nos pediría el password del mismo (por gksu) y luego el password de desbloqueo del contenedor de cifrado. Si se introduce correctamente, se desbloquearía el disco y se montaría en /cifrado.

El siguiente script permite desmontar el disco:

[sromero@compiler:~/bin]$ cat desmonta_disco_cifrado.sh 
#!/bin/sh

export DEVICE_DESTINO="/dev/mapper/disco_cifrado"

umount $DEVICE_DESTINO
sudo cryptsetup luksClose $DEVICE_DESTINO


Ubicar perfil de firefox y pidgin en disco cifrado

Una vez funcional el sistema de montaje del disco cifrado al arrancar sesión en gnome, bastará con mover y enlazar los directorios apropiados. Paramos las aplicaciones y ejecutamos:

mkdir -p /cifrado/home/usuario/
cd $HOME
mv .mozilla /cifrado/home/usuario/
ln -s /cifrado/home/usuario/.mozilla .
mv .purple/ /cifrado/home/usuario/
ln -s /cifrado/home/usuario/.purple/ .
mv .gaim .gaimrc /cifrado/usuario/sromero/
ln -s /cifrado/home/usuario/.gaim* .


Script de montar y desmontar disco USB

También existe la posibilidad de que el disco a montar sea un disco USB, por lo que no podemos saber de antemano el dispositivo /dev/sdX que se le va a asignar (a menos que lo establezcamos con reglas de udev).

A continuación se muestran 3 scripts para montar, desmontar y alternar el estado de montaje de un disco USB externo cuya partición 2 está cifrada (sdb2).

Según el orden en que pinchemos los discos en el PC, el dispositivo USB puede tener un /dev/sdx diferente, y nuestro script con un /dev/sdX fijo no funcionaría. Pero podemos hacer uso de udev y de los enlaces simbólicos en /dev/disk/by-id/ para, desreferenciando dicho enlace simbólico, utilizar readlink para obtener el /dev/sdX correcto:

$ readlink -e /dev/disk/by-id/usb-Verbatim_000000001DD2-0\:0-part2
/dev/sdb2

Podemos crear los scripts de gestión del disco USB cifrado (montar/desmontar/alternar) para que detecte así el dispositivo correcto para trabajar con el disco. Recordar que debéis cambiar la referencia /dev/disk/by-id de mis ejemplos por la de vuestro disco, pinchando este en el puerto USB y haciendo un ls -l /dev/disk/by-id/ para obtener el enlace a vuestro disco y partición cifrado correcto.

Montaje:

[sromero@compiler:~/bin]$ cat monta_USB_cifrado.sh 
#!/bin/sh

export DEVICE_DESTINO="/dev/mapper/HDD320GB"
export LABEL_DESTINO="HDD320GB"
export FICH_PW="/cifrado/root/scripts/passwd"

export DEVICE="`readlink -e /dev/disk/by-id/usb-Verbatim_000000001DD2-0\:0-part2`"

sudo cryptsetup luksOpen $DEVICE $LABEL_DESTINO \
   --key-file $FICH_PW | grep -v "unlocked"
mount $DEVICE_DESTINO

Desmontaje:

[sromero@compiler:~/bin]$ cat desmonta_USB_cifrado.sh 
#!/bin/sh

export DEVICE_DESTINO="/dev/mapper/HDD320GB"

umount $DEVICE_DESTINO
sudo cryptsetup luksClose $DEVICE_DESTINO

Alternar estado:

$ cat toggle_USB_cifrado.sh 
#!/bin/sh

MOUNT_SCRIPT="/home/sromero/bin/monta_USB_cifrado.sh"
DISMOUNT_SCRIPT="/home/sromero/bin/desmonta_USB_cifrado.sh"
export MOUNT_POINT="/mnt/HDD320GB"

SHOW_MEDIA="$1"

# Si el disco ya esta montado, lo desmontamos y salimos
if mount | grep -q $MOUNT_POINT ;
then
   sh $DISMOUNT_SCRIPT
   if [ "x${SHOW_MEDIA}" == "x1" ];
   then
      zenity --info --text="Unidad HDD320GB desmontada."
   fi
   exit
fi

# El disco no estaba montado, lo montamos
if [ "x${SHOW_MEDIA}" == "x1" ];
then
   sudo sh $MOUNT_SCRIPT && nautilus $MOUNT_POINT
else
   sudo sh $MOUNT_SCRIPT
fi

El valor de SIZE lo obtenemos con un fdisk -l del disco, tomando el valor del tamaño de la partición cifrada para que el bucle lo encuentre.

Finalmente, debemos editar el fichero de sudoers y permitir la ejecución de toggle_USB_cifrado.sh sin password:

sromero ALL=NOPASSWD:/bin/mount,\
                 NOPASSWD:/bin/umount,\
                 NOPASSWD:/sbin/fdisk,\
                 NOPASSWD:/usr/bin/truecrypt,\
                 NOPASSWD:/home/sromero/bin/toggle_USB_cifrado.sh

A continuación podemos asociar en la barra de iconos de GNOME/KDE un nuevo “elemento” que ejecute “sudo toggle_USB_cifrado_TC.sh 1” y que nos permita montar y desmontar nuestro disco cifrado.


Utilizar imágenes loopback cifradas en lugar de particiones

Si ya no tenemos espacio para crear particiones, es perfectamente posible cifrar imágenes de loopback (ficheros formateados), creando primero el dispositivo correspondiente (en el ejemplo, de 2GB) con:

# dd if=/dev/urandom of=container.loop bs=2048M count=10 
# losetup /dev/loop/0 container.loop 
# losetup -d /dev/loop0

A continuación podemos utilizar como dispositivo a cifrar / descifrar el device /dev/loop/0.


Añadir un keyfile para autenticar sin password

Podemos añadir un keyfile para autenticar sin necesidad de introducir un password:

# Crear un fichero keyfile:
$ dd if=/dev/urandom of=/root/keys/mi_keyfile bs=4k count=1

# Añadir el keyfile como clave valida:
$ cryptsetup luksAddKey /dev/sda1 /root/keys/mi_keyfile

Ahora podemos utilizar la keyfile para abrir el cifrado sin usar password:

$ cryptsetup luksOpen /dev/sda1 DISCOUSB --key-file /root/keys/mi_keyfile

Esto puede ser útil en la realización de scripts de montaje y desmontaje automático, por ejemplo para backups.



<Volver a la sección de GNU/Linux>