Trabajar con el Sandbox

Uno de los objetivos principales de Flatpak es incrementar la seguridad en los sistemas de escritorio, aislando a las aplicaciones de las demás. Esto se logra usando sandboxing y significa que, por defecto, un Flatpak tiene un acceso extremadamente limitado al entorno del host. Esto incluye:

  • Sin acceso a ningún archivo del host con excepción del runtime, de la app y de ~/.var/app/$APPID. Sólo se permite acceso de escritura al último de estos.

  • Sin acceso a la red.

  • Sin acceso a ningún nodo de dispositivo (aparte de /dev/null, etc).

  • Sin acceso a los procesos por fuera del sandbox.

  • Llamadas al sistema limitadas. Por ejemplo, las apps no pueden usar tipos de socket de red no estándar, o hacer ptrace de otros procesos.

  • Acceso limitado a la instancia del D-Bus de sesión - una app puede ser dueña sólo su propio nombre en el bus.

  • Sin acceso a los servicios del host como X, el D-Bus del sistema, o PulseAudio.

La mayoría de las aplicaciones necesitarán acceso a algunos de estos recursos para poder ser usadas, y Flatpak proporciona una cantidad de formas de dar a una aplicación acceso a los mismos.

Si bien no hay restricciones a cuáles permisos del sandbox una aplicación puede acceder, como buena práctica, se recomienda usar el mínimo número de permisos posible. Ciertos permisos, tales como el acceso total al bus del sistema (usando la opción --socket=system-bus ) deberían ser evitados a toda costa.

Configurar los permisos del sandbox

Usar el comando build-finish es la manera más simple de configurar los permisos del sandbox. Como se vio en un ejemplo anterior, esto puede ser usado para dar acceso a los sockets de gráficos y a la red:

$ flatpak build-finish dictionary2 --socket=x11 --share=network --command=gnome-dictionary

Estos argumentos se traducen a varias propiedades dentro del archivo de metadatos de la aplicación:

[Application]
name=org.gnome.Dictionary
runtime=org.gnome.Platform/x86_64/3.22
sdk=org.gnome.Sdk/x86_64/3.22
command=gnome-dictionary

[Context]
shared=network;
sockets=x11;

build-finish permite agregar un amplio rango de recursos en una aplicación. Estas opciones también pueden pasarse a flatpak-builder como propiedades finish-args.

La tabla de abajo proporciona una vista general de varios permisos del sandbox. La lista completa también puede verse usando flatpak build-finish --help.

Nota

Hasta que exista un backend compatible con el sandbox, el acceso a dconf necesita activarse usando las siguientes opciones:

--filesystem=xdg-run/dconf
--filesystem=~/.config/dconf:ro
--talk-name=ca.desrt.dconf
--env=DCONF_USER_CONFIG_DIR=.config/dconf

Portales

Los portales son un mecanismo a través del cual las aplicaciones pueden interactuar con el entorno del host desde adentro de un sandbox. De esta forma, se dan utilidades adicionales para interactuar con datos, archivos y servicios sin necesidad de agregar permisos de sandbox.

Los toolkits de interfaces pueden implementar soporte para portales. Si una aplicación usa uno de estos toolkits, no se requiere ningún trabajo adicional para acceder a los mismos.

Ejemplos de capacidades a las que se puede acceder a través de portales incluyen:

  • Inhabilitar la sesión del usuario para cerrarla, suspenderla, o cambiar de usuario.

  • Información del estado de la red

  • Notificaciones

  • Abrir una URI

  • Abrir archivos con un diálogo selector de archivos nativo

  • Imprimir

  • Tomar capturas de pantalla

Las aplicaciones que no usen un toolkit con soporte para portales pueden dirigirse a la documentación de la API de xdg-desktop-portal para información de cómo acceder a los mismos.

Sobreescribir los permisos del sandbox

Cuando se desarrolla una aplicación, puede ser útil sobreescribir la configuración de un sandbox de Flatpak. Hay varias maneras de hacerlo. Una es sobreescribirla usando flatpak run, que acepta los mismos parámetros que build-finish. Por ejemplo, esto hará que la aplicación Diccionario vea su directorio home:

$ flatpak run --filesystem=home --command=ls org.gnome.Dictionary ~/

También puede usarse flatpak override para sobreescribir permanentemente los permisos de una aplicación:

$ flatpak --user override --filesystem=home org.gnome.Dictionary
$ flatpak run --command=ls org.gnome.Dictionary ~/

Además es posible quitar permisos usando el mismo método. Puede usar el siguiente comando para ver qué ocurre si se elimina el acceso al sistema de archivos, por ejemplo:

$ flatpak run --nofilesystem=home --command=ls org.gnome.Dictionary ~/

Permisos útiles del sandbox

Flatpak proporciona una lista de opciones para controlar los permisos del sandbox. Los siguientes son algunos de los más útiles:

–filesystem=host

Acceso a todos los archivos

–filesystem=home

Acceso al directorio home

–filesystem=home:ro

Acceso al directorio home, de sólo lectura

–filesystem=/some/dir –filesystem=~/other/dir

Acceso a directorios específicos

–filesystem=xdg-download

Acceso al directorio Descargas de XDG

–nofilesystem=...

Hacer una excepción para alguna de las anteriores

–socket=x11 –share=ipc

Mostrar ventanas usando X11 [1]

–device=dri

Renderizado OpenGL

–socket=wayland

Mostrar ventanas usando Wayland

–socket=pulseaudio

Reproducir sonidos usando PulseAudio

–share=network

Acceso a la red [2]

–talk-name=org.freedesktop.secrets

Comunicarse con un servicio por nombre en el bus de sesión

–system-talk-name=org.freedesktop.GeoClue2

Comunicarse con un servicio por nombre en el bus del sistema

–socket=system-bus

Acceso ilimitado a todos los D-Bus

Notas al pie

[1]

–share=ipc significa que cada sandbox comparte un espacio de nombres IPC con el host. Esto no es necesariamente requerido, pero sin esto no funcionará la memoria compartidad de la extensión X, lo cual es muy malo para la performance de X.

[2]

Dar acceso a la red también garantiza acceso a todos los servicios que escuchan en sockets abstractos de Unix (dada la forma en que los espacios de nombre de red funcionan), y estos no tienen chequeos de permisos. Esto desafortunadamente afecta por ej. al servidor X y al bus de la sesión, quienes escuchan en sockets abstractos por defecto. Una distribución segura debería desactivarlos y usar sólo sockets regulares.