
Para la protección de datos de tarjetas de pago durante su almacenamiento, PCI DSS permite el uso de cifrado de disco. A diferencia del cifrado a nivel de archivo o el cifrado a nivel de columna en bases de datos, en este modelo se emplea un cifrado completo de una unidad lógica o física, de tal forma que si un potencial atacante tiene acceso al medio de almacenamiento no podrá acceder a los datos guardados allí. Esta opción es particularmente útil cuando se almacenan datos de tarjetas de pago en medios removibles o en equipos móviles (ordenadores portátiles) para evitar incidentes asociados con el robo de equipos (ver un ejemplo aquí).
En esta oportunidad, Ariel Vásquez (experto en la implementación de controles de PCI DSS y colaborador de PCI Hispano) ha escrito un interesante artículo acerca de la gestión del cifrado en unidades LVM en Ubuntu 14 (aunque la técnica es extrapolable a otras distribuciones de GNU/Linux), concepto que se puede aplicar en el cumplimiento de PCI DSS enfocado al requerimiento 3.4.1:
«… Si se utiliza cifrado de disco (en lugar de un cifrado de base de datos por archivo o columna), se debe administrar un acceso lógico independientemente de los mecanismos de control de acceso del sistema operativo nativo (por ejemplo, no se deben utilizar bases de datos de cuentas de usuarios locales). Las claves de descifrado no deben estar vinculadas a cuentas de usuarios…»
La versión original del artículo se puede encontrar en inglés y en español en el sitio web del autor http://arich-notes.arich-net.com:8080/?lang=en. Se reproduce con su permiso.
Gestión de cifrado de unidades LVM
La unidades lógicas LVM nos permiten utilizar discos de almacenamiento de una forma más flexible en grupos de volúmenes, al gestionarlos de esta forma será posible el incrementarlos o reducirlos dinámicamente.
Crear las particiones LVM – Ubuntu 14
En este experimento, agregaremos un nuevo disco a un servidor, lo configuraremos en un LVM, y luego cifraremos la nueva partición creada. Este experimento será útil para particiones /home, /tmp o /swap. Luego guardaremos la llave en una memoria USB para descifrar la información desde y como método alternativo una contraseña maestra.
Nota: Toda la configuración generada se ejecuta en un entorno de root, lo propio y mas seguro sería agregar el prefijo de “sudo”.
Instalar los paquetes de soporte a LVM en el sistema
1 2 |
root@server:~# apt-get update root@server:~# apt-get install lvm2 |
Agregar el disco al sistema
Esto se puede conseguir agregando un disco a una máquina virtual con VirtualBox por ejemplo:

Verificamos que el kernel de linux ha detectado el nuevo disco utilizando dmesg:
1 2 3 4 5 6 7 |
root@server:~# dmesg | grep sdb [ 1.954468] sd 3:0:0:0: [sdb] 8388608 512-byte logical blocks: (4.29 GB/4.00 GiB) [ 1.955492] sd 3:0:0:0: [sdb] Write Protect is off [ 1.955980] sd 3:0:0:0: [sdb] Mode Sense: 00 3a 00 00 [ 1.956619] sd 3:0:0:0: [sdb] Write cache: enabled, read cache: enabled, doesn't support DPO or FUA [ 1.958773] sdb: unknown partition table [ 1.959531] sd 3:0:0:0: [sdb] Attached SCSI disk |
Dar formato a la nueva partición LVM
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
root@server:~# fdisk /dev/sdb Command (m for help): n Partition type: p primary (0 primary, 0 extended, 4 free) e extended Select (default p): p Partition number (1-4, default 1): Using default value 1 First sector (2048-8388607, default 2048): Using default value 2048 Last sector, +sectors or +size{K,M,G} (2048-8388607, default 8388607): Using default value 8388607 Command (m for help): t Hex code (type L to list codes): 8e Changed system type of partition 1 to 8e (Linux LVM) Command (m for help): w The partition table has been altered! Calling ioctl() to re-read partition table. Syncing disks. |
Configurar la nueva estructura LVM
-
Volumen Físico
-
Grupo de Volúmenes Físicos
-
Unidades Lógicas LVM (se creará del tamaño de 1GB)
1 2 3 4 5 6 |
root@server:~# pvcreate /dev/sdb1 Physical volume "/dev/sdb1" successfully created root@server:~# vgcreate NEW-VG /dev/sdb1 Volume group "NEW-VG" successfully created root@server:~# lvcreate -L 1GB -n "Home-LVM" NEW-VG Logical volume "Home-LVM" created |
Configurar el cifrado de LVM
En este punto ya tenemos creada la Unidad Lógica para la partición de Home, lo que haremos en cifrar el disco y configurarlo para ser montado durante el inicio del Sistema Operativo.
Instalar la utilidad de cryptsetup
1 |
root@server:~# apt-get install cryptsetup |
Escribir datos aleatorios en el LVM creado
1 |
root@server:~# badblocks -c 10240 -s -w -t random -v /dev/mapper/ |
Crear una llave aleatoria de 256 bits
Presionar la teclas “shift” y “space” unas cuantas veces para añadir entropía al sistema:
1 2 |
root@server:~# mkdir cryptokeys root@server:~# dd if=/dev/random of=/root/cryptokeys/home-key bs=1 count=256 |
Preparar el dispositivo cifrado utilizando luksFormat
1 2 3 4 5 6 7 8 |
root@server:~# cryptsetup --verbose -y --cipher aes-cbc-essiv:sha256 --key-size 256 luksFormat /dev/NEW-VG/Home-LVM /root/cryptokeys/home-key WARNING! ======== This will overwrite data on /dev/NEW-VG/Home-LVM irrevocably. Are you sure? (Type uppercase yes): YES Command successful. |
Abrir el dispositivo creado LUKS
1 2 3 |
root@server:~# cryptsetup --key-file /root/cryptokeys/home-key luksOpen /dev/NEW-VG/Home-LVM Encrypted-Home-LVM root@server:~# ls -l /dev/mapper/ | grep Encrypted lrwxrwxrwx 1 root root 7 Mar 18 05:56 Encrypted-Home-LVM -> ../dm-1 |
Agregar una frase a la partición LUKS
Agregamos una frase secreta en caso que la llave se pierda:
1 2 3 |
root@server:~# cryptsetup --key-file=/root/cryptokeys/home-key luksAddKey /dev/NEW-VG/Home-LVM Enter new passphrase for key slot: Verify passphrase: |
Cargar la partición LVM cifrada durante inicio del sistema
Hasta este punto se tiene la partición cifrada LVM, los siguientes pasos configurarán la mencionada partición para cargarse y montarse durante el inicio del Sistema Operativo.
Crear el script que exporte a “stdout” la llave
En este caso se exportará la llave del Sistema de Archivos local de la máquina, más tarde crearemos un script que exporte esta información desde una llave USB.
1 2 3 4 5 6 7 |
#!/bin/bash # Ariel Vasquez v1.0 # Add the driver to recognize the usb storage export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin KEY=/root/cryptokeys/home-key cat $KEY |
Configurar /etc/crypttab
Incluimos dos líneas, en la primera recuperamos el dispositivo LUKS utilizando el script y en la segunda línea utilizando una frase secreta.
1 2 3 |
# name> Encrypted-Home-LVM /dev/NEW-VG/Home-LVM none luks,keyscript=/root/cryptokeys/key.sh,retry=1 Encrypted-Home-LVM /dev/NEW-VG/Home-LVM none luks,retry=1 |
Configurar /etc/fstab
Configurar /etc/fstab para montar la partición cifrada en /home
1 2 3 |
root@server:~# cat /etc/fstab | grep Encrypted # Encrypted partition /dev/mapper/Encrypted-Home-LVM /home ext4 errors=remount-ro 0 1 |
Tareas de operación con particiones cifradas LVM
Cambiar el tamaño de un LVM cifrado
Una de las mejores razones de utilizar una partición LVM cifrada es que se pueden re-dimensionar de manera flexible. Los LVM cifrados deberían cumplir con este mismo requerimiento, a continuación explicamos cómo se realiza:
Estado de /home en el sistema de ficheros antes de la operación
1 2 |
root@server:~# df -h | grep home /dev/mapper/Encrypted-Home-LVM 990M 1.3M 922M 1% /home |
Incrementar el tamaño del disco físico
En el caso de máquinas virtuales se puede hacer a través de una consola de gestión, o también se podría incrementar este tamaño agregando un nuevo dispositivo al Grupo de Volúmenes. Después de agregar o incrementar el disco forzamos al Sistema Operativo a re-escanear el bus SCSI.
1 |
root@server:~# echo "- - -" > /sys/class/scsi_host/host2/scan |
Incrementar la unidad lógica con el tamaño deseado
1 2 3 |
root@server:~# lvresize -L +1GB /dev/NEW-VG/Home-LVM Extending logical volume Home-LVM to 2.00 GiB Logical volume Home-LVM successfully resized |
Re-dimensionar la partición cifrada
1 |
root@server:~# cryptsetup resize /dev/mapper/Encrypted-Home-LVM |
Re-dimensionar la estructura de ficheros
1 2 3 4 5 |
root@server:~# resize2fs /dev/mapper/Encrypted-Home-LVM resize2fs 1.42.9 (4-Feb-2014) Filesystem at /dev/mapper/Encrypted-Home-LVM is mounted on /home; on-line resizing required old_desc_blocks = 1, new_desc_blocks = 1 The filesystem on /dev/mapper/Encrypted-Home-LVM is now 523776 blocks long. |
Estado de /home en el sistema de ficheros después de la operación
1 2 |
root@server:~# df -h | grep home /dev/mapper/Encrypted-Home-LVM 2.0G 1.6M 1.9G 1% /home |
Descifrar el LVM desde una llave USB
A continuación encontramos el script para extraer la llave desde una llave USB. Es importante obtener el valor UUID del dispositivo USB donde se encuentre la llave. El script se podría colocar en la partición de /boot que es donde se encuentran los archivos que se ejecutan en primeras instancias de ejecución del Sistema Operativo.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
#!/bin/bash # Ariel Vasquez v1.0 # Add the driver to recognize the usb storage if [ "`lsmod | egrep usb_storage`" = "" ]; then modprobe usb_storage >/dev/null 2>&1 sleep 3 fi export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin # First detect if the USB is present if [ "`lsusb | egrep 'PNY'`" = "" ]; then exit 0 fi # Unmount it if it is already mounted if [ "`mount | egrep '\/dev\/sdb1'`" != "" ]; then umount /dev/sdb1 >/dev/null 2>&1 fi # Detects if the directory is present or not if [ -d "/boot/tmp/key" ]; then rm -rf /boot/tmp/key >/dev/null 2>&1 fi mkdir /boot/tmp/key >/dev/null 2>&1 # Mounting mount -t vfat -o ro,umask=077 UUID="F8AC-8EEF" /boot/tmp/key >/dev/null 2>&1 cat /boot/tmp/key/.key/keyfile #echo "Done it" umount /boot/tmp/key >/dev/null 2>&1 rm -rf /boot/tmp/key >/dev/null 2>&1 |
4 Comentarios en respuesta a "Cifrado de unidades LVM y el requerimiento 3.4.1 de PCI DSS"