Cómo instalar ArchLinux con Full Disk Encryption en un ODROID-C2

ODROID Magazine ArchLinux With Full Disk Encryption Dropbear ssh

La Full Disk Encryption (FDE) protege nuestros datos del acceso no autorizado en el caso de que alguien logre acceder físicamente a los medios de almacenamiento. En este artículo, voy a describir cómo instalar ArchLinux con Full Disk Encryption en el OROID-C2. El método de encriptación es LUKS con el tamaño de clave XTS 512 bit (AES-256).

En pocas palabras, Full Disk Encryption requiere lo siguiente:

  • Encriptar una partición y copiar el sistema de archivos root en ella.
  • El kernel para incluir el módulo dm_crypt. En nuestro caso, éate ya está incluido por defecto. De modo que, no necesitaremos volver a re-compilar el kernel.
  • Los initramfs para incluir el módulo del dm_crypt y el binario cryptsetup. Usamos una herramienta llamada dracut para generar los initramfs necesarios. Dracut soporta la funcionalidad requerida a través de los módulos adicionales crypt y lvm.
  • Pasar las opciones dracut para LUKS a los initramfs a través de la propiedad bootargs dentro de boot.ini. Por ejemplo, digamos que, en nuestro caso, queremos que los initramfs desbloqueen un volumen LUKS con UUID ae51db2d-0890-4b1b-abc5-8c10f01da353 y carguen el sistema de archivos root del dispositivo mapper/dev/mapper/vg-root. Para pasar estas opciones dracut configuramos lo siguiente:

sudo nano /boot/boot.ini
setenv bootargs "rd.luks.uuid=ae51db2d-0890-4b1b-abc5-8c10f01da353 root=/dev/mapper/vg-root rootwait < leave the rest as is >"

Note

Muchos de los pasos de este documento implican editar archivos de configuración. Para mantener las palabras al mínimo, usamos la notación anterior como una forma concisa de describir los pasos en los que hay que editar archivos. La notación anterior significa:

  • Debes editar el archivo /boot/boot.ini con privilegios root (sudo nano /boot/boot.ini). Nano es el editor de línea de comandos; sin embargo, puedes usar cualquier otro editor.
  • Busca la línea que comienza con setenv bootargs y añade o edite las opciones de configuración rd.luks.uuid=ae51db2d-0890-4b1b-abc5-8c10f01da353 root=/dev/mapper/vg-root rootwait. Es posible que algunos archivos mencionados en este documento tengan la correspondiente línea comentada o no presente en absoluto. Si ese es el caso, tendrá que descomentar o añadir la línea en el archivo, respectivamente.
  • Deja el resto de la línea después de rootwait como está.

Además, para una configuración sin monitor ni teclado, necesitarás habilitar el desbloqueo remoto mediante SSH como se describe en el artículo "Remotely unlock the LUKS rootfs during boot using Dropbear sshd" en http://bit.ly/2g6qjDv. Por último, pero no menos importante, si prefieres utilizar de inmediato esta funcionalidad, simplemente descárgate la imagen de sistema operativo en http://bit.ly/2xR8LDe. De cualquier modo, el documento actual te proporcionará más detalles técnicos sobre los componentes básicos y cómo trabajan conjuntamente en un entorno Full Disk Encryption.

Requisitos de hardware

  • ODROID-C2
  • Una maquina Linux desde donde garbar la imagen del SO e interactuar con el ODROID-C2
  • Disco USB con al menos 4GB de capacidad
  • Una tarjeta microSD o módulo eMMC con al menos 4GB de capacidad
  • (Opcional) Un kit módulo USB-UART para conectarse con la consola serie del ODROID-C2. Consulta la publicación de http://bit.ly/2fM29BB para obtener instrucciones sobre cómo conectarte y por qué la consola serie es muy recomendable en este caso.

Grabar la imagen del SO y arrancar ODROID-C2

Graba la imagen del SO en el disco USB siguiendo las instrucciones de http://bit.ly/2fGKEik Reemplaza /dev/mmcblk0 en las siguientes instrucciones por el nombre del dispositivo de la tarjeta microSD tal como aparece en tu ordenador. Si están montadas, desmonta las particiones de la tarjeta microSD

$ lsblk
$ umount /dev/mmcblk0p1
$ umount /dev/mmcblk0p2
Zero al principio de la tarjeta microSD:
$ sudo dd if=/dev/zero bs=1M count=8 of=/dev/mmcblk0
$ sync
Usando una herramienta como GParted, crea una tabla de particiomes MBR/msdos y dos particiones en la tarjeta microSD:

  • Partición ext4 con un tamaño de 128M
  • Partición lvm2 ocupando el resto del espacio (no es necesario formatearla todavía)

A continuación, copia el contenido del directorio /boot del disco USB en la primera partición de la tarjeta microSD:

$ sudo cp -R /media/user/usb-disk/boot/* /media/user/micro-sd-card-part1/
Crea un enlace simbólico para la ruta de acceso boot.ini codificada de alarm/uboot-odroid-c2 (http://bit.ly/2xbEdPo):
$ cd /media/user/micro-sd-card-part1
$ sudo ln -s . boot
Luego, graba los archivos del gestor de arranque:
$ sudo ./sd_fusing.sh /dev/mmcblk0
Determina el UUID del disco USB:
$ sudo lsblk -o name,uuid,mountpoint
NAME UUID MOUNTPOINT
sdb
└─sdb1 2b53696c-2e8e-4e61-a164-1a7463fd3785 /media/user/usb-disk
Ten en cuenta que, si hay UUID duplicados entre las particiones del disco USB y la tarjeta microSD, debes eliminar los duplicados para evitar futuros conflictos:
$ sudo tune2fs /dev/sda2 -U $(uuidgen)
Configura boot.ini para arrancar desde el disco USB. Para hacerlo, usa el UUID del paso anterior y configura el boot.ini de la tarjeta microSD:
$ sudo nano /media/user/micro-sd-card-part1/boot.ini
$ setenv bootargs "root=UUID=2b53696c-2e8e-4e61-a164-1a7463fd3785 rootwait "
Desmonta, ejecuta sync varias veces y retira la tarjeta microSD y el disco USB de la maquina Linux. Conecta la tarjeta microSD y el disco USB al ODROID-C2, luego inicia el ODROID-C2 y conéctate a su consola serie. Si necesitas instrucciones sobre cómo conectarte a la consola serie, consulte el artículo de http://bit.ly/2fM29BB.

Si todo va bien, deberías arrancar con el disco USB. Ten en cuenta que si root=UUID= 2b53696c-2e8e-4e61-a164-1a7463fd3785 no funciona, intenta root=/dev/sda1, root=/dev/ sdb1 o el nombre del dispositivo que veas en la consola antes de que falle el arranque (p. ej., [14.812393] sd 1:0:0:0: [sda] Attached SCSI removable disk). Si todavía tienes problemas, intenta reiniciar unas cuantas veces y/o reposiciona el disco USB en un puerto USB diferente en el ODROID-C2. No te preocupes sí parece que te está causando problemas, ya que no tendrá que arrancar de nuevo con el disco USB tras el primer arranque exitoso.

A continuación, verifica que el sistema de archivos root esté montado desde el disco USB:

$ df -h

Cambiar contraseñas

Cambia las contraseñas para el usuario root y alarm. Las credenciales predeterminadas son alarm/alarm y root/root.

$ passwd
$ su
$ passwd

Instalar los paquetes requeridos

$ su
$ pacman -Syu
$ pacman -S --needed sudo python git rsync lvm2 cryptsetup
(Opcional) Configura sudo sin contraseña para el usuario alarm:
$ echo 'alarm ALL=(ALL) NOPASSWD: ALL' > /etc/sudoers.d/010_alarm-nopasswd

Instalar dracut

Instala pacaur (http://bit.ly/2yEjAaY):

$ sudo pacman -S --needed base-devel cower
$ mkdir -p ~/.cache/pacaur && cd "$_"
$ cower -d pacaur
$ cd pacaur
$ makepkg -si --noconfirm --needed
Instala dracut usando la herramienta pacaur:
$ pacaur -S dracut
Verifica la instalación de dracut listando los módulos
$ dracut --list-modules
Si el comando "pacaur -S dracut" informa de un error en el que la arquitectura aarch64 no es compatible con el paquete, sigue estos pasos para configurar el soporte para aarch64:
$ cd ~/.cache/pacaur/dracut/
$ nano PKGBUILD # replace `arch=("i686" "x86_64")` with `arch=("aarch64")`
$ makepkg -si --noconfirm --needed
Si makepkg informa de un error así como dracut-046.tar ... FAILED (unknown public key 340F12141EA0994D), introduce estos comandos e inténtalo de nuevo:
$ gpg --full-gen-key
$ gpg --recv-key 340F12141EA0994D
Consulta la documentación de Makepkg para obtener más información en http://bit.ly/2wuuBe6.

Si el comando "gpg -full-gen-key" informa del error, Key generation failed: No pinentry, sigue los siguientes pasos para configurar gpg tal y como se describe en http://bit.ly/2yDAJBye e inténtalo de nuevo. El gpg-agent necesita saber cómo solicitar el usuario para la contraseña:

$ nano ~/.gnupg/gpg-agent.conf
$ pinentry-program /usr/bin/pinentry-curses
$ gpg-connect-agent reloadagent /bye
Si makepkg reportas errores sobre dependencias que faltan, actualiza los paquetes e inténtalo nuevamente.
$ sudo pacman -Syu
$ pacaur -Syua

Prepare los rootfs LUKS

Encripta la segunda partición de la tarjeta microSD (consulta también las opciones recomendadas para LUKS en http://bit.ly/2yF15D2):

$ sudo cryptsetup -v -y -c aes-xts-plain64 -s 512 -h sha512 -i 5000 --use-random luksFormat /dev/mmcblk0p2
-v = información detallada -y = verifica la contraseña, pregunta dos veces y reporta un error si no coinciden -c = especifica el cifrado utilizado -s = especifica el tamaño de la clave utilizada -h = especifica el hash utilizado -i = número de milisegundos para gastar en el procesamiento de contraseña (si usa algo más que sha1, debe ser mayor que 1000) –use-random = generador de números aleatorios para usar luksFormat = para activar la partición y fijar una contraseña /dev/mmcblk0p2 = la partición a encriptar

Desbloquea el dispositivo LUKS y móntalo en /dev/mapper/lvm:

$ sudo cryptsetup luksOpen /dev/mmcblk0p2 lvm
Crea el volumen primario, el grupo de volumen y volumen lógico:
$ sudo pvcreate /dev/mapper/lvm
$ sudo vgcreate vg /dev/mapper/lvm
$ sudo lvcreate -l 100%FREE -n root vg
Crea el sistema de archivos:
$ sudo mkfs.ext4 -O ^metadata_csum,^64bit /dev/mapper/vg-root
Monta el nuevo volumen root encriptado (volumen lógico):
$ sudo mount /dev/mapper/vg-root /mnt
Copia el volumen root existente al nuevo volumen root encriptado. Una instalación de 1.5 GB se completa en aproximadamente 6 minutos con una microSD de gama media:
$ sudo rsync -av \
--exclude=/boot \
--exclude=/mnt \
--exclude=/proc \
--exclude=/dev \
--exclude=/sys \
--exclude=/tmp \
--exclude=/run \
--exclude=/media \
--exclude=/var/log \
--exclude=/var/cache/pacman/pkg \
--exclude=/usr/src/linux-headers* \
--exclude=/home/*/.gvfs \
--exclude=/home/*/.local/share/Trash \
/ /mnt
Si las claves SSH del host están vacías, elimínalas para que se regeneren la próxima vez que se inicie sshd. Esto evitará el problema de la pérdida de memoria tal y como se describe en http://bit.ly/2xQxGqe.
$ sudo rm /mnt/etc/ssh/ssh_host*key*
Crea algunos directorios y monta la partición de arranque:
$ sudo mkdir -p /mnt/boot /mnt/mnt /mnt/proc /mnt/dev /mnt/sys /mnt/tmp
$ sudo mount -t ext4 /dev/mmcblk0p1 /mnt/boot
Registra el volumen encriptado en crypttab
$ sudo bash -c 'echo lvm UUID=$(cryptsetup luksUUID /dev/mmcblk0p2) none luks>> /mnt/etc/crypttab'
Configura fstab:
$ sudo nano /mnt/etc/fstab
$ /dev/mapper/vg-root / ext4 errors=remount-ro,noatime,discard 0 1
$ /dev/mmcblk0p1 /boot ext4 noatime,discard 0 2
Next, generate a new initramfs using dracut. The following commands will add the dracut modules crypt and lvm to the initramfs. These modules will prompt for LUKS password during boot and unlock the LUKS volume. Note that the order of the modules is important:

$ sudo dracut --force --hostonly -a "crypt lvm" /mnt/boot/initramfs-linux.img
A continuación, determina el UUID de LUKS:
$ sudo cryptsetup luksUUID /dev/mmcblk0p2
470cc9eb-f36b-40a2-98d8-7fce3285bb89
Configura las opciones root dracut  y rd.luks.uuid en bootargs. Estas desbloquearán el volumen LUKS y cargará los rootfs durante el arranque:
$ sudo nano /mnt/boot/boot.ini
$ setenv bootargs "rd.luks.uuid=470cc9eb-f36b-40a2-98d8-7fce3285bb89 root=/dev/mapper/vg-root rootwait "
Ten en cuenta que en el paso anterior, NO se elimina el resto de bootargs, básicamente reemplaza root = UUID = 2b53696c-2e8e-4e61-a164-1a7463fd3785 por rd.luks.uuid=470cc9eb-f36b-40a2-98d8-7fce3285bb89 root=/dev/mapper/vg-root y no toques el resto de bootargs. Luego, desmonta y reinicia los rootfs de LUKS:
$ sudo umount /mnt/boot
$ sudo umount /mnt
$ sudo reboot
Si todo va bien, se te pedirá que introduzcas la contraseña de LUKS durante el arranque. A continuación, verifica los rootfs de LUKS:
df -h
output
Filesystem Size Used Avail Use% Mounted on
devtmpfs 714M 0 714M 0% /dev
tmpfs 859M 0 859M 0% /dev/shm
tmpfs 859M 8.3M 851M 1% /run
tmpfs 859M 0 859M 0% /sys/fs/cgroup
/dev/mapper/vg-root 1.7G 1.4G 256M 85% /
tmpfs 859M 0 859M 0% /tmp
/dev/mmcblk0p1 120M 26M 86M 23% /boot
tmpfs 172M 0 172M 0% /run/user/1000
A continuación, desbloquea de forma remota los rootfs de LUKS durante el arranque usando Dropbear sshd. Reemplace 10.0.0.100 en las siguientes instrucciones por la dirección IP asignada al ODROID-C2 por tu servidor DHCP local. Usa la herramienta fing para encontrar la dirección IP asignada (por ejemplo, sudo fing 10.0.0.1/24). Luego, asegúrate de que el demonio SSH se está ejecutando:
$ sudo systemctl status sshd
$ journalctl -u sshd -n 100
Si los comandos anteriores informan que sshd falla con un error de asignación de memoria, introduce los siguientes comandos:
$ sudo rm /etc/ssh/ssh_host*key*
$ sudo systemctl start sshd
Consulta el artículo de http://bit.ly/2xQxGqe para obtener más información sobre las pérdidas de memoria en sshd.

Instalar y configurar Dropbear

Instala el módulo crypt-ssh de dracut:

$ pacaur -S dracut-crypt-ssh-git
Desde tu maquina Linux, copia la clave pública SSH al archivo appconf/dracut-crypt-ssh/authorized_keys en el servidor remoto ODROID-C2:
$ cat ~/.ssh/*.pub | ssh alarm@10.0.0.100 'umask 077; mkdir -p appconf/dracut-crypt-ssh; touch appconf/dracut-crypt-ssh/authorized_keys; cat >>appconf/dracut-crypt-ssh/authorized_keys'
Despues, configura el módulo crypt-ssh:
$ sudo nano /etc/dracut.conf.d/crypt-ssh.conf
$ dropbear_acl="/home/alarm/appconf/dracut-crypt-ssh/authorized_keys"
Genera un nuevo initramfs usando dracut. Los siguientes comandos añadirán la red de módulos dracut y crypt-ssh a initramfs. Ten en cuenta que el orden de los módulos es importante:
$ sudo dracut --force --hostonly -a "network crypt lvm crypt-ssh" /boot/initramfs-linux.img
Habilita el acceso a la red durante el arranque añadiendo las opciones ip y rd.neednet de dracut a bootargs:
$ sudo nano /boot/boot.ini
setenv bootargs "rd.neednet=1 ip=10.0.0.100::10.0.0.1:255.255.255.0:archlinux-luks-host:eth0:off rd.luks.uuid=ae51db2d-0890-4b1b-abc5-8c10f01da353 root=/dev/mapper/vg-root rootwait "
Si prefieres DHCP en lugar de una ip estática, simplemente reemplaza con ip=dhcp. Consulta la documentación de red de dracut en http://bit.ly/2g6XCXky  y las opciones dracut en   http://bit.ly/2yUBFT6 para obtener más opciones (man dracut.cmdline). Reinicia para que se inicie Dropbear, permitiendo el desbloqueo remoto:
$ sudo reboot
Desde tu maquina Linux, conéctate al servidor remoto Dropbear SSH que se ejecuta en el ODROID-C2:
$ ssh -p 222 root@10.0.0.100
Desbloquea el volumen (te pedirá la contraseña y enviarla a la consola):
$ console_auth
Passphrase:
Si el desbloqueo del dispositivo tuvo éxito, initramfs se limpiará por sí mismo y Dropbear finalizará por si sólo y tu conexión.

También puede escribir "console_peek" que muestra lo que hay en la consola. También existe el comando unlock, pero encontramos un problema cuando realizamos las pruebas, tal y como se describe en http://bit.ly/2fHB2nw.

En algunos casos se requiere alimentar la entrada de datos automáticamente con el comando interactivo console_auth. Desde tu maquina Linux, desbloquea el volumen:

$ ssh -p 222 root@10.0.0.100 console_auth < password-file
or
$ gpg2 --decrypt password-file.gpg | ssh -p 222 root@10.0.0.100 console_auth
For additional security, you might want to only allow the execution of the command console_auth and nothing else. To achieve this, you need to configure the SSH key with restricting options in the authorized_keys file. From your Linux box, copy the public SSH key, with restricting options, to the appconf/dracut-crypt-ssh/authorized_keys file on the remote ODROID-C2 server:
$ (printf 'command="console_auth",no-agent-forwarding,no-port-forwarding,no-pty,no-X11-forwarding ' && cat ~/.ssh/*.pub) | ssh alarm@10.0.0.100 'umask 077; mkdir -p appconf/dracut-crypt-ssh; touch appconf/dracut-crypt-ssh/authorized_keys; cat >appconf/dracut-crypt-ssh/authorized_keys'
Consulta la documentación de Dropbear para obtener una lista completa de las opciones restringentes. Antes de continuar, podría ser una buena idea crear una copia de initramfs:
$ sudo cp /boot/initramfs-linux.img /boot/initramfs-linux.img-`date +%y%m%d-%H%M%S`
En una configuración sin monitor y teclado, examina cuidadosamente las opciones restringentes para evitar bloquearte.

Finalmente, genera un nuevo initramfs usando dracut:

$ sudo dracut --force --hostonly -a "network crypt lvm crypt-ssh" /boot/initramfs-linux.img
En este caso, puede desbloquear el volumen de forma interactiva simplemente escribiendo el siguiente comando:
$ ssh -p 222 root@10.0.0.100
Ten en cuenta que, al escribir el comando anterior, el comando console_auth es activado automáticamente en el servidor remoto e inmediatamente solicita la contraseña, como si simplemente se escribiera ssh -p 222 root@10.0.0.100 console_auth. Mientras escribes la contraseña, se mostrará en la pantalla en texto plano. Por lo tanto, debe evitar desbloquear interactivamente cuando el acceso está restringido al comando console_auth. Cuando presiones enter, se desconectará sin importar si la contraseña era correcta o no. Mientras que con el inicio de sesión no restringido (ver http://bit.ly/2hHAGl0), solo se desconectaría si la contraseña es correcta, lo que significa que te aparecerán comentarios sobre si el desbloqueo ha tenido exito o no. Por otro lado, para desbloquear el volumen usando un archivo de contraseña, desde tu maquina Linux escriba el siguiente comando:
$ ssh -p 222 root@10.0.0.100 < password-file
o
$ gpg2 --decrypt password-file.gpg | ssh -p 222 root@10.0.0.100
Para comentarios, preguntas o sugerencias, visita la publicación original del blog en  http://bit.ly/2xMQE3I.

Referencias

ArchLinux dm-crypt/Encrypting an entire system (http://bit.ly/2xPaybR)

Cómo instalar Debian con Full Disk Encryption en ODROID-C2 (http://bit.ly/2g6JtcF)

Be the first to comment

Leave a Reply