domingo, 23 de junio de 2013

Hacer copia de seguridad cifrada con LUKS y crontab

Tras un tiempo haciendo copias de seguridad en un disco duro externo (WD Elements 500GB) usando "rsync", me he puesto con algo que quería hacer desde que lo compré: cifrar los datos de dicha copia con LUKS, hacer la copia con rsync y programarla con crontab.

Empecemos pues a preparar la partición cifrada con LUKS.

Lo primero de todo es instalar "cryptsetup":

root@cain:~# apt-get install cryptsetup

Una vez tengamos decidido la partición que vamos a usar tenemos que prepararla, lo primero es formatear la partición:

cryptsetup luksFormat /dev/[partición]

root@cain:~# cryptsetup luksFormat /dev/sdd2

Nos pedirá que metamos una passphrase que será la que usemos para montar manualmente dicha partición.

Luego tenemos que "abrir" o "activar" la partición LUKS para poder trabajar con ella. Podremos acceder a través de "/dev/mapper".

cryptsetup luksOpen /dev/disk/by-uuid/[uuid] [nombre lógico]

root@cain:~# cryptsetup luksOpen /dev/media/by-uuid/b272b0cd-bc71-4d7f-83a5-796e7agbea3d Backups

Ahora debemos crear el sistema de ficheros, en mi caso he usado ext4.

mkfs.ext4 /dev/mapper/[nombre lógico]

root@cain:~# mkfs.ext4 /dev/mapper/Backups

Al finalizar podremos montarla como cualquier otro dispositivo, recuerda que si no existe, debes crear la carpeta de [ruta montaje].

mount /dev/mapper/[nombre lógico] [ruta montaje]

root@cain:~# mount /dev/mapper/Backups /media/Backups

Ya podemos almacenar nuestros datos de una forma segura. Cuando acabemos de trabajar con la partición, la desmontaremos de la siguiente forma y orden:

umount /media/Backups

root@cain:~# umount /media/Backups

Y luego:

cryptsetup luksClose /dev/mapper/[nombre logico]

root@cain:~# cryptsetup luksClose /dev/mapper/Backups

Lo anterior es muy útil para trabajar con la partición manualmente, pero nuestro objetivo es automatizar el proceso, por eso vamos a crear un "keyfile", que usaremos más adelante, para evitar tener que introducir la "passphrase" cada vez.

El fichero o su contenido puede ser el que queramos, pero ese fichero será el único con el que podremos acceder a la partición, a menos que configuremos más (podemos configurar hasta 10 distintos entre keyfiles y passphrases), aparte del passphrase mencionado anteriormente.

Creamos un fichero de 8192 bytes aleatorios de la siguiente forma:

root@cain:~# dd if=/dev/urandom of=/home/sink/key bs=1024 count=8

Luego añadimos dicho fichero como clave para LUKS:

cryptsetup luksAddKey /dev/[partición] [nombre fichero llave]

root@cain:~# cryptsetup luksAddKey /dev/sdd2 /home/sink/key

Volvemos a cerrar la partición:

root@cain:~# cryptsetup luksClose /dev/mapper/Backups

Y podéis hacer la comprobación abriendo la partición con el fichero que acabamos de crear en lugar de usar el passphrase.

cryptsetup luksOpen /dev/[partición] [nombre lógico] --key-file [ruta al fichero llave]

root@cain:~# cryptsetup luksOpen /dev/sdd2 Backups --key-file /home/sink/key

Con esto acabamos la primera parte: el cifrado de datos.

Pasamos a usar rsync, aquí solo mostraré el comando y los parámetros que uso actualmente.

rsync -aur [ruta a copiar] /media/Backups

Os invito a leer la página man y seleccionar los parámetros que mejor se adapten a vuestro entorno.

Finalmente llegamos a crontab, nos encontramos con varios problemas:

1. cryptsetup necesita privilegios de root para poder montar/desmontar, etc.
2. mount también necesita esos privilegios.
3. Quiero lanzar la copia con mi usuario y desde mi crontab.
4. Son varios comandos y nos puede resultar incómodo hacerlo todo desde crontab.

Solución:

1. Crearemos un script con todos los comandos que necesiten privilegios de root.
2. Crearemos un segundo script que no requerirá de privilegios que llamará al primero.
3. Modificaremos /etc/sudoers para que no nos pida contraseña de sudo.
4. Programaremos crontab.

1.El primer script:

----------
#!/bin/bash

# Alberto A. (Sink) 06/2013
# http://elmagodelosbits.blogspot.com.es/
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.

# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.

# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>
 
# Abre la partición con el fichero llave
cryptsetup luksOpen /dev
/disk/by-uuid/xxxx-xxxx Backups --key-file /root/key
# Monta la partición
mount
/dev/mapper/Backups /media/Backups
# Realiza la copia de seguridad
rsync -aur [...] && rsync -aur [...]
# Desmonta la partición
umount
/media/Backups
# Cierra la partición
cryptsetup luksClose Backups
----------

Dónde "xxxx-xxxx" corresponde al UUID de tu partición cifrada. Si no sabes cómo, puedes usar el comando:

ls -al /dev/disk/by-uuid

Recomiendo usar el montaje mediante UUID para evitar líos cuando añadamos nuevos dispositivos de almacenamiento.

Podéis observar que es muy sencillo. Guardamos el fichero.

Copiamos el script y el fichero llave en un directorio bajo /root, acordaos de modificar la partición y demás para ajustarlo a vuestra configuración.

En mi caso éstos son los permisos que he asignado:


-rwx------ 1 root root  765 jun 23 20:07 crypt.sh
-r--r--r-- 1 root root 4096 jun 23 20:03 key

Ahora creamos el segundo script que simplemente llama al primero.

 ----------
#!/bin/bash

sudo "/root/crypt.sh"

exit 0
----------

Este lo dejamos en el sitio que queramos, bajo nuestro usuario.

Toca modificar el fichero /etc/sudoers para que no nos pida la contraseña cuando se ejecute el crontab:

root@cain:~# nano /etc/sudoers

Buscamos la línea que pone:

%sudo   ALL=(ALL:ALL) ALL

y DEBAJO añadimos:

tu_usuario    ALL=(ALL) NOPASSWD:/root/crypt.sh

Evidentemente, cambiando "tu_usuario" por el usuario real que uses.

Grabamos los cambios y programamos el crontab:

sink@cain:~$ crontab -e

Añadimos la hora, frecuencia y demás información necesaria y listo, ya tenemos nuestra copia de seguridad cifrada.

En mi caso lo he programado que haga dos copias al día, una a las 18:30 y otra a las 01:45.

30 18 * * * sh /home/sink/backup.sh
45 01 * * * sh /home/sink/backup.sh

No he realizado ningún cambio en /etc/crypttab, ni en /etc/fstab, puesto que solo me interesa que la partición esté montada durante la copia. Si quieres que te pida la passphrase o se monte automáticamente usando un fichero llave en el arranque (por ejemplo si tienes cifrada tu partición del portátil), debes añadir una línea a /etc/crypttab

[nombre lógico] [/dev/partición] [fichero llave] [options]

Que, en mi caso, si quiero que me pida la passphrase, traducido resulta:

Backups /dev/sdd2 none luks

Y si, en cambio, quiero usar el fichero llave (recordad que el fichero llave debe estar fuera de una partición cifrada, por ejemplo, un pendrive).

Backups /dev/sdd2 /media/pendrive/key luks

Si tienes alguna duda, plantéala en los comentarios.

¡Eso es todo por hoy!

No hay comentarios:

Publicar un comentario