Uso de fs-verity en kernel 5.7

A partir de la versión 5.5 del kernel de linux se incluye la opción de verificación de integridad y protección de autenticidad transparente para ficheros de solo lectura. Como tengo la versión 5.4 instalada lo primero que vamos a hacer es instalar la última versión estable del kernel, en el momento que escribo esto es la 5.7.

Para instalar la última versión del kernel en Ubuntu 20.04 LTS vamos a usar los paquetes principales del kernel 5.7 que podemos encontrar disponibles para descargar en la web del Ubuntu Kernel Team.

Voy a utilizar una máquina virtual para la instalación del kernel. Este tipo de kernel no esta ajustado ni parametrizado específicamente, por tanto no están soportados ni recomendados para su uso en producción

Para este caso voy a descargar e instalar los 4 paquetes generic para amd64:

mkdir kernel
cd kernel
wget https://kernel.ubuntu.com/~kernel-ppa/mainline/v5.7/linux-headers-5.7.0-050700_5.7.0-050700.202005312130_all.deb
wget https://kernel.ubuntu.com/~kernel-ppa/mainline/v5.7/linux-headers-5.7.0-050700-generic_5.7.0-050700.202005312130_amd64.deb
wget https://kernel.ubuntu.com/~kernel-ppa/mainline/v5.7/linux-image-unsigned-5.7.0-050700-generic_5.7.0-050700.202005312130_amd64.deb
wget https://kernel.ubuntu.com/~kernel-ppa/mainline/v5.7/linux-modules-5.7.0-050700-generic_5.7.0-050700.202005312130_amd64.deb
sudo dpkg -i *.deb

Reiniciamos el equipo (máquina virtual) y comprobamos:

$ uname -a
Linux udesk20gcc 5.7.0-050700-generic #202005312130 SMP Mon Jun 1 01:33:12 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux

Podemos comprobar que tenemos disponible la opción STATX_ATTR_VERITY con infofile, el código que incluía en la entrada anterior que nos mostraba los permisos usando la función statx. La lanzamos contra cualquier fichero y en la opción de atributos extra soportados tenemos ahora lo que llamábamos: (V):No se puede escribir y lectura verificada que corresponde a STATX_ATTR_VERITY 0x00100000:

[+] Atributos extra soportados:  (0x00100874)
(c):Contenido comprimido
(i):Inmutable, no están permitidos los cambios
(a):Solo permite añadir
(d):No hacer backup
(E):Encriptado
(V):No se puede escribir y lectura verificada

Esta es la opción que queremos probar, llamada en el kernel fs-verity y descrita como la capa de soporte que los sistemas de archivos pueden enganchar para soportar la integridad transparente y la protección de autenticidad de los archivos de solo lectura. Actualmente, es compatible con los sistemas de archivos ext4 y f2fs y se indica que no se necesita demasiado código específico del sistema de archivos para admitir fs-verity.

fs-verity es esencialmente una forma de hacer un hash de un archivo en tiempo constante, sujeto a la advertencia de que las lecturas que violarían el hash fallarán en tiempo de ejecución.

Para trabajar con esta opción vamos a usar la utilidad fsverify, que podemos obtener en: fsverity-utils-1.0.tar.gz

Siguiendo los pasos que describen en la información de esta utilidad, descargamos e instalamos (instalamos también la librería libssl-dev necesaria para la aplicación):

wget https://git.kernel.org/pub/scm/linux/kernel/git/ebiggers/fsverity-utils.git/snapshot/fsverity-utils-1.0.tar.gz
tar xvfz fsverity-utils-1.0.tar.gz
cd fsverity-utils-1.0/
sudo apt install libssl-dev
make
sudo make install

Para probar fsverify tenemos que tener una unidad con formato ext4 con la opción verity activada. Podemos añadir un disco a la máquina virtual, en mi caso /dev/vda y lo montamos en el sistema:

sudo mkfs.ext4 -O verity /dev/vda
sudo mkdir /vda
sudo mount /dev/vda /vda
sudo chown :david vda -R
sudo chmod g+rwx vda -R

Creamos un fichero de prueba y habilitamos verity con fsverify:

$ cd /vda 
$ head -c 1000000 /dev/urandom > fichero.txt
$ fsverity enable fichero.txt
$ fsverity measure fichero.txt
sha256:d9f44e17a71515e4a622c666fbcaf600821aaf109b616923d4e34fbf05ccc28a fichero.txt

Podemos ver que tenemos el atributo verity activo:

$ infofile /vda/fichero.txt 
[+] Tipo de fichero: fichero regular
Número de hard links: 1
ID del dispositivo que contiene el i-node: fc:00
Número de I-node: 15
Tamaño total: 1000000 bytes
Tamaño optimo de bloque I/O: 4096 bytes
Bloques de 512B blocks asignados: 1992
[+] Permisos absoluto/simbólico: 100664 (rw-|rw-|r--)
Propietario: UID=1000 | GID=1000
[+] Atributos extra soportados: (0x00100874)
(c):Contenido comprimido
(i):Inmutable, no están permitidos los cambios
(a):Solo permite añadir
(d):No hacer backup
(E):Encriptado
(V):No se puede escribir y lectura verificada
[+] Atributos extra activos: (0x00100000)
(V):No se puede escribir y lectura verificada
[+] i-node flags: (0x00180000)
(e):Extensiones
(V):No se puede escribir y lectura verificada
[+] Fechas
Ultimo acceso: dom 24 may 2020 19:33:45.936581836+0200
Ultima modificación: dom 24 may 2020 19:33:57.640627753+0200
Ultimo cambio de status: dom 24 may 2020 19:33:57.640627753+0200
Fecha de creación: dom 24 may 2020 19:33:45.936581836+0200
[+] Atributos extendidos:

Tenemos por tanto activada la comprobación de integridad de nuestro fichero, pero no así la comprobación de autenticidad. Para poder habilitar la comprobación de autenticidad necesitamos firmar el fichero.

Para poder firmar el fichero vamos a generar un certificado X.509 e incluirlo en el conjunto de claves del núcleo ".fs-verity".

Con `CONFIG_FS_VERITY_BUILTIN_SIGNATURES = y`, el sistema de archivos admite la verificación automática de una medición de archivo firmado que se ha incluido en los metadatos de verity. La firma se verifica con el conjunto de certificados X.509 que se han cargado en el conjunto de claves del núcleo ".fs-verity".

Generamos un certificado nuevo y una clave privada y convertimos el certificado a formato DER:

mkdir cert
cd cert/
openssl req -newkey rsa:4096 -nodes -keyout key.pem -x509 -out cert.pem
openssl x509 -in cert.pem -out cert.der -outform der

Cargamos el certificado en el keyring de fs-verity (keyctl está en keyutils, a si que lo instalamos):

sudo apt install keyutils
keyctl padd asymmetric '' %keyring:.fs-verity < cert.der

Habilitamos la opción para que todos los ficheros con verity activado tengan que estar firmados:

sudo sysctl fs.verity.require_signatures=1

Y ahora vamos a habilitar verity en otro fichero, primero firmamos el fichero y luego le indicamos a fsverity enable la firma que queremos usar:

echo "ComunidadLibre SoftwareLibre" > /vda/file4.txt
fsverity sign /vda/file4.txt file4.txt.sig --key=key.pem --cert=cert.pem
fsverity enable /vda/file4.txt --signature=file4.txt.sig
rm -f file4.txt.sig

Cuando accedemos ahora a el fichero el sistema realiza las comprobaciones de integridad y también de autenticidad, comprobando la firma del fichero.

Si reiniciamos la máquina, y no cargamos el certificado en llavero de fs-verity el acceso al fichero fallará:

$ cat /vda/file4.txt
cat: /vda/file4.txt: La clave requerida no está disponible

Podemos ver que no tenemos el certificado cargado:

$ sudo keyctl show %keyring:.fs-verity
Keyring
918211912 --a-swrv 0 0 keyring: .fs-verity

Es interesante ver que en este momento al no poder acceder al fichero no podemos ver los atributos i-node flags (llamada a ioctl) que nos indican que el fichero tiene activada la opción verity, pero si podemos ver los atributos extra con la llamada a statx:

$ infofile /vda/file4.txt 
[+] Tipo de fichero: fichero regular
Número de hard links: 1
ID del dispositivo que contiene el i-node: fc:00
Número de I-node: 20
Tamaño total: 20 bytes
Tamaño optimo de bloque I/O: 4096 bytes
Bloques de 512B blocks asignados: 16
[+] Permisos absoluto/simbólico: 100664 (rw-|rw-|r--)
Propietario: UID=1000 | GID=1000
[+] Atributos extra soportados: (0x00100874)
(c):Contenido comprimido
(i):Inmutable, no están permitidos los cambios
(a):Solo permite añadir
(d):No hacer backup
(E):Encriptado
(V):No se puede escribir y lectura verificada
[+] Atributos extra activos: (0x00100000)
(V):No se puede escribir y lectura verificada
[infofile.c:255]:
[+] Error al recuperar los i-node flags
[+] errno: [La clave requerida no está disponible]
[+] Fechas
Ultimo acceso: lun 25 may 2020 11:58:25.725634771+0200
Ultima modificación: lun 25 may 2020 11:57:30.975377505+0200
Ultimo cambio de status: lun 25 may 2020 11:57:30.975377505+0200
Fecha de creación: lun 25 may 2020 11:57:02.960377661+0200
[+] Atributos extendidos:

Cargamos el certificado y comprobamos:

$ sudo keyctl padd asymmetric '' %keyring:.fs-verity < cert.der
279715851
$ sudo keyctl show %keyring:.fs-verity
Keyring
918211912 --a-swrv 0 0 keyring: .fs-verity
279715851 --als--v 0 0 \_ asymmetric: clibre: david: 4280127722210ae3c014aa9e68f949dfab0ad4f0

Ahora podemos acceder al fichero sin problemas:

$ cat /vda/file4.txt 
ComunidadLibre SoftwareLibre
Modificado por última vez enViernes, 14 Agosto 2020 20:40
(1 Voto)
Etiquetado como :

Deja un comentario

Asegúrese de introducir toda la información requerida, indicada por un asterisco (*). No se permite código HTML.