¿Qué es flatpak?

Es conveniente y merecido que Flatpak tenga un post especialmente dedicado a él, más allá de su interacción con polkit que dejamos planteado en el post anterior.

Flatpak


Brevísimo repaso histórico

En agosto de 2007 el desarrollador sueco Alexander Larsson lanza su primer intento de empaquetar aplicaciones con todas sus dependencias. A fines de 2014 comienza a trabajar en el proyecto xdg-app, el cual cambia de nombre a Flatpak en 2016.

¿Qué es Flatpak?

Flatpak es un sistema para compilar, distribuir y ejecutar aplicaciones. Las aplicaciones se pueden compilar y distribuir independientemente del sistema en que se usan, y al ejecutarse están aisladas del mismo hasta cierto punto.

Cada aplicación está en un sandbox, de manera predeterminada solamente puede acceder al contenido del mismo. Cada programa en flatpak tiene acceso a

  • ~/.var/app/$FLATPAK_ID, y $XDG_RUNTIME_DIR/app/$FLATPAK_ID.
  • De manera limitada a llamadas del sistema.
  • De manera limitada a la instancia de D-BUS.

Aun así, para ser realistas, las aplicaciones en general necesitan más permisos, en este caso se insta a los empaquetadores a que adviertan qué accesos necesitará la aplicación para que el usuario esté conciente de ello, tal como cuando se instala una app desde el Play Store de Android.

Flatseal mostrando los permisos que usa cada una de las aplicaciones instaladas

Flatpak ofrece un repositorio llamado Flathub. Nada impide que cualquier persona o proyecto (como es el caso de Fedora) tenga el suyo propio.

Flatpak usa OSTree (Fedora usa OCI) para distribuir y desplegar datos. OSTree es similar a Git pero está diseñado para hacer control de versiones de binarios y archivos grandes de datos. El uso de OSTree permite además que un mismo archivo sea usado por más de una misma aplicación, ahorrando de esta manera espacio en disco. Cada aplicación que se instala es almacenada en un repositorio local de control de versiones, y luego se mapea en el sistema de archivos local.

Los cambios entre las diferentes versiones de una aplicación se aplican en el filesystem mediante enlaces duros.

Por ejemplo, con el comando siguiente podemos ver log del último commit de una aplicación flatpak (Logseq): .

 ostree log --repo=/var/lib/flatpak/repo  deploy/app/com.logseq.Logseq/x86_64/stable
commit a54ee70b0ec9047c2083f77b9f9175e8e8edcac998e3be8d395009255a6a03f6
Parent:  8c36feebe7ea23654917f542eb5419b71426359a42165f53496c9d82049a6806
ContentChecksum:  4d06f4e875d0335f2ff1c7a30ffa5b200c9a3eb3aeb0b608588eadb045994b22
Date:  2024-06-09 07:22:27 +0000

    Remove screenshot locale (8a160109)

    Name: com.logseq.Logseq
    Arch: x86_64
    Branch: stable
    Built with: Flatpak 1.14.8

<< History beyond this commit not fetched >>

En realidad el comando mostrado es de bajo nivel solamente a los efectos de mostrar ostree como software subyacente, para obtener información a más alto nivel, es conveniente usar directamente el comando flatpak para obtener información de la aplicación:

> flatpak info com.logseq.Logseq 

Logseq - Connect your notes and knowledge

                 ID: com.logseq.Logseq
         Referencia: app/com.logseq.Logseq/x86_64/stable
       Arquitectura: x86_64
               Rama: stable
            Versión: 0.10.9
           Licencia: AGPL-3.0-or-later
             Origen: flathub
          Colección: org.flathub.Stable
        Instalación: system
          Instalada: 437,7 MB
Tiempo de ejecución: org.freedesktop.Platform/x86_64/23.08
                Sdk: org.freedesktop.Sdk/x86_64/23.08

             Commit: a54ee70b0ec9047c2083f77b9f9175e8e8edcac998e3be8d395009255a6a03f6
              Padre: 8c36feebe7ea23654917f542eb5419b71426359a42165f53496c9d82049a6806
             Asunto: Remove screenshot locale (8a160109)
              Fecha: 2024-06-09 07:22:27 +0000

Comparación entre dnf, apt y flatpak

Flatpak está pensado para todo tipo de aplicaciones de escritorio y se esfuerza por ser tan neutral como sea posible en cuanto a los métodos que usa para compilar aplicaciones.

Además, flatpak proporciona actualizaciones atómicas, rollback y consistencia post-instalación.

El siguiente cuadro nos ayuda a ver las diferencias con los dos gestores populares de paquetes: dnf y apt.

Característica DNF APT Flatpak
Distribución Principal Fedora, RHEL, CentOS Debian, Ubuntu Varias distribuciones de Linux
Formato de Paquete RPM DEB OSTree, Flatpak Bundle
Gestión de Dependencias Manejo automático de dependencias Manejo automático de dependencias Manejo dentro del sandbox
Aislamiento No No Sí, aplicaciones ejecutadas en sandbox
Instalación de Aplicaciones Desde repositorios específicos del sistema Desde repositorios específicos del sistema Desde repositorios centralizados (Flathub) y repositorios personalizados
Actualizaciones dnf update apt update && apt upgrade flatpak update
Permisos de Instalación Requiere permisos de root Requiere permisos de root Puede instalarse sin permisos de root
Compatibilidad entre Distros Limitada a sistemas basados en RPM Limitada a sistemas basados en DEB Compatible con múltiples distribuciones
Seguridad Depende de la configuración del sistema Depende de la configuración del sistema Sandboxing y permisos controlados por portales
Facilidad de Uso Interfaz de línea de comandos Interfaz de línea de comandos Interfaz de línea de comandos y GUI
Espacio de Disco Compartido entre aplicaciones Compartido entre aplicaciones Deduplicación y compartición de runtimes
Formato de Archivo Individual No aplica No aplica Flatpak Bundle (.flatpak)
Desventajas Depende de la política de la distro Dependencia de la política de la distro Las aplicaciones pueden tener un mayor tamaño inicial
Compatibilidad con Aplicaciones Antiguas Sí, con soporte de versiones específicas Sí, con soporte de versiones específicas Generalmente más adecuado para nuevas aplicaciones
Desarrollo y Mantenimiento Desarrollado por el proyecto Fedora Desarrollado por el proyecto Debian Desarrollado por el proyecto Flatpak, con apoyo de Red Hat y GNOME
Adopción Usado por muchas distribuciones y entornos de escritorio Usado principalmente en Debian, Ubuntu y derivadas Usado en diversas distribuciones, especialmente para aplicaciones portátiles
Ejemplo de Comando de Instalación dnf install gedit apt install gedit flatpak install flathub org.gnome.Gedit

Inconvenientes para usuarios y desarrolladores de aplicaciones Linux

Si bien Linux mejoró significativamente en cuando a usabilidad y experiencia de usuario en los últimos años, hay obstáculos tanto para usuarios como para desarrolladores:

  • Una aplicación para un entorno de escritorio en Linux se debe empaquetar para que esté disponible (como Debian, Fedora, Ubuntu, Arch Linux, etc.), y asegurarse de que cumpla con los requisitos específicos de cada sistema de paquetes (deb, rpm, etc.). Esto requiere un esfuerzo considerable para mantener múltiples versiones y asegurarse de que cada paquete funcione correctamente en su respectiva distribución. Todo esto demanda o más tiempo o bien más gente idónea dedicada en la tarea de crear y mantener paquetes.

  • Si un usuario quiere usar aplicación que no está empaquetada en la distribución, tendrá que realizar algún paso extra, que van desde operaciones relativamente sencillas como bajar un ejecutable (darle permisos, ubicarlo en un directorio del PATH, etc.), hasta procedimientos bastante más complejos y fuera del interés y conocimiento de un usuario final como puede ser compilar el programa.

  • Una distribución de soporte a largo plazo como Debian Stable no posee versiones actualizadas de la mayoría de las aplicaciones. Por lo tanto un usuario tiene que elegir estabilidad a cambio de software un tanto anticuado.

Flatpak tiene como propósito justamente eliminar esas barreras. Gracias a Flatpak un usuario podrá instalar una aplicación como Logseq aun cuando no esté incluida en los repositorios de su distribución, o instalar una versión reciente de Kdenlive en Debian Stable.

En la actualidad existen distribuciones con la mirada puesta en la innovación que se benefician de Flatpak, por ejemplo:

Características de flatpak

Analicemos la app ONLYOFFICE en flatpak:

flatpak info org.onlyoffice.desktopeditors

ONLYOFFICE Desktop Editors - Office productivity suite

                 ID: org.onlyoffice.desktopeditors
         Referencia: app/org.onlyoffice.desktopeditors/x86_64/stable
       Arquitectura: x86_64
               Rama: stable
            Versión: 8.0.1
           Licencia: AGPL-3.0-only
             Origen: flathub
          Colección: org.flathub.Stable
        Instalación: system
          Instalada: 863,8 MB
Tiempo de ejecución: org.freedesktop.Platform/x86_64/23.08
                Sdk: org.freedesktop.Sdk/x86_64/23.08

             Commit: c9f73db43c9639df65e597108eb4c685025fe484fde05f73f650d05f9ea28512
              Padre: a38db7bbfaa18eda6d26e9d113ce850c077bf533d9ebf5aa7e34988a58b91b28
             Asunto: Update version to 8.0.1 (#117) (a88ad400)
              Fecha: 2024-03-04 15:34:56 +0000

La aplicación ONLYOFFICE usa como runtime org.freedesktop.Platform/x86_64/23.08. El runtime org.freedesktop.Platform/x86_64/23.08 es un entorno estandarizado y versionado que provee FreeDesktop.org para ejecutar aplicaciones de escritorio en Linux. Incluye una colección de librerías y servicios comunes, que aseguran la compatibilidad y la estabilidad entre las diferentes distribuciones de Linux. Este runtime está compilado específicamente para arquitecturas de 64-bit y fue actualizado o liberado en agosto de 2023.

Los runtimes no dependen ni de una distribución ni de una versión en particular de una distribución. Y una aplicación instalada en flatpak será exactamente igual no importa si se instala en Debian o en Fedora. Una aplicación como GIMP, empaquetada como Flatpak, debería proporcionar la misma funcionalidad principal y experiencia de usuario tanto en Debian como en Fedora, dado que todas las dependencias y configuraciones críticas se gestionan dentro del contenedor Flatpak. Desde luego, hay diferencias potenciales: Si una aplicación Flatpak utiliza características específicas del sistema, como integraciones con servicios de notificación de escritorio, la forma en que estas integraciones funcionan puede variar ligeramente entre GNOME en Fedora y KDE en Debian.

Existen diferentes runtimes para Flatpak, tales como freedesktop, GNOME, KDE y Elementary

Objeciones en cuanto a la seguridad

Han existido críticas severas a la seguridad de flatpak, en especial por el sitio anónimo Flatkill. El siguiente cuaddro es un resumen de los argumentos en contra y favor de Flatpak en cuanto a este tema:

Objeción de Seguridad Descripción Respuesta / Acción Tomada
Sandboxing Ineficaz Muchas aplicaciones en Flathub tienen permisos amplios como filesystem=host o filesystem=home, lo que permite acceso completo al sistema de archivos del usuario. Flatpak ha mejorado la transparencia sobre los permisos de las aplicaciones y trabaja en fortalecer el modelo de sandboxing. Se han introducido portales para permitir el acceso controlado a los recursos del sistema. Flatpak Documentation
Actualizaciones de Seguridad Retrasadas Algunas aplicaciones y runtimes en Flatpak no reciben actualizaciones de seguridad oportunas, lo que deja a los usuarios expuestos a vulnerabilidades conocidas. La herramienta flatpak-external-data-checker automatiza la verificación de fuentes externas y la generación de solicitudes de fusión cuando se encuentran actualizaciones. Al implementar f-e-d-c, los desarrolladores pueden asegurar que las aplicaciones en Flathub se mantengan actualizadas más fácilmente y de manera más eficiente, lo que reduce el tiempo de espera para las actualizaciones de los usuarios finales
Integración Limitada del Escritorio Problemas con la integración de aplicaciones Flatpak en escritorios Linux, como la falta de soporte para configuraciones de fuentes y temas de escritorio. Se han mejorado los mecanismos de integración de escritorio, incluyendo mejor soporte para fuentes y temas en KDE y GNOME. Flatpak sigue trabajando en mejorar la compatibilidad con configuraciones del sistema host.)
Explotación Local de Root Riesgo de explotación de root local debido a aplicaciones Flatpak instaladas con permisos suid. Flatpak utiliza nuevas APIs de libostree para rechazar cualquier archivo con permisos suid o de escritura mundial al instalar aplicaciones.
Gestión de Permisos Confusa para el Usuario Los usuarios pueden ser engañados por íconos y descripciones que indican un falso sentido de seguridad sobre las aplicaciones sandboxed. Flatpak ha mejorado la interfaz de usuario para mostrar de manera más clara los permisos que solicita cada aplicación, ayudando a los usuarios a tomar decisiones informadas sobre las aplicaciones que instalan.


Sitio de Flathub mostrando las advertencias pertinentes a una determinada aplicación

¿Cómo hace flatpak para no pedirle a un usuario de un grupo administrativo que se autentique nuevamente?

En el post anterior vimos como funciona polkit. Flatpak se vale de polkit para facilitar la instalación de paquetes por parte de usuarios con permisos administrativos. Basta con mirar el archivo /usr/share/polkit-1/rules.d/org.freedesktop.Flatpak.rules.

polkit.addRule(function(action, subject) {
    if ((action.id == "org.freedesktop.Flatpak.app-install" ||
         action.id == "org.freedesktop.Flatpak.runtime-install"||
         action.id == "org.freedesktop.Flatpak.app-uninstall" ||
         action.id == "org.freedesktop.Flatpak.runtime-uninstall" ||
         action.id == "org.freedesktop.Flatpak.modify-repo") &&
        subject.active == true && subject.local == true &&
        subject.isInGroup("wheel")) {
            return polkit.Result.YES;
    }

    return polkit.Result.NOT_HANDLED;
});

polkit.addRule(function(action, subject) {
    if (action.id == "org.freedesktop.Flatpak.override-parental-controls") {
            return polkit.Result.AUTH_ADMIN;
    }

    return polkit.Result.NOT_HANDLED;
});

Este archivo tiene dos reglas:

  • Permite a los usuarios del grupo "wheel", que están loogoueados localmente y tienen una sesión activa instalar, desinstalar, y modificar aplicaciones y repositorios sin autenticación adicional.
  • No se pueden pasar por arriba de los controles parentales sin autenticarse con una cuenta de usuario administrativa.

Para ambos casos, si las condiciones no se cumplen, el resultado dependerá de otras reglas o de la regla predeterminada.

Para terminar...

Flatpak elimina barreras y obstáculos tanto para desarrolladores como para usuarios finales. Para los primeros, significa les ofrece la posibilidad de poner aplicaciones disposición de cualquier distribución de Linux. Para los segundos representa una mayor facilidad para obtener los programas que están necesitando.

Discover mostrando aplicaciones disonibles en Flathub

Fuentes y Más Recursos

  1. Flatpak Documentation - Using Flatpak
  2. Flathub
  3. Flatkill - Flatpak, a security nightmare
  4. Respuestas a objecioones planteadas en Flatkill
  5. Flatpak en Fedora

Entendiendo Polkit

Introducción

El esquema de permisos en Linux es simple:

  • Un superusuario con todos los poderes para leer, modificar y ejecutar todo.

  • El resto de los usuarios con permisos limitados.

  • Es decir, la clasificación de usuarios en tres categorías, el famoso UGO (User, Group, Others) y el trío de permisos: rwx (read, write y execution).

Pero esa simpleza tiene sus limitaciones, como vimos ya anteriormente, con el paso del tiempo se han ideado maneras de hacer esos permisos más granulares y que superusuario root pueda delegar atribuciones.

Una herramienta muy importante en este sentido es polkit (antiguamente conocido como PolicyKit). En este post vamos a explorar para develar qué es polkit, como funciona, y como se diferencia de sudo. Además, en el próximo post, veremos la relación que tiene con flatpak.

¿Qué es polkit?

Polkit

Leer más…

¿Qué significa en Linux que todo es archivo?

En un viejo artículo, hay una presentación en la que mencioné una frase bastante habitual en el mundo Unix/Linux: «Todo es archivo». Vamos a explicar qué significa realmente esa frase.

Todo es archivo

¿Todo es Archivo?

En realidad, ese dicho no es del todo correcto. Sin embargo, proviene de lo que hoy tal vez podríamos llamar la filosofía Unix. Probablemente, nadie dijo esa frase de manera literal en los primeros años de esa familia de sistemas operativos. Aun así, ideas de ese estilo estaban en la mente desde los comienzos y en los trabajos de por ejemplo, Bill Joy (pionero de TCP/IP). Linus Torvalds, no estuvo ausente en esta discusión. Y mucho más cerca en el tiempo, Lennart Poettering, retoma esa idea una vez más para defender el trabajo realizado en systemd. Por si no se dieron cuenta dice Poettering la interfaz de cgroups están expuesta en un pseudo-sistema de archivos...

Sin embargo, es más apropiado decir que todo es un descriptor de archivo o que todo puede tener un descriptor de archivo. En Linux un descriptor de archivo es un identificador único de proceso para un archivo u otro recurso de entrada o salida. Por ejemplo, no existe necesariamente un archivo para una interfaz de red. Sin embargo, existen sockets relacionados con ellas.

En el siguiente ejemplo podemos ver los descriptores de archivos para la dirección ip 127.0.0.1 de la interfaz lo.

sudo lsof -n -i@127.0.0.1
COMMAND    PID   USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
chronyd   1337 chrony    5u  IPv4   8171      0t0  UDP 127.0.0.1:323 
cupsd     1538   root    7u  IPv4  14727      0t0  TCP 127.0.0.1:ipp (LISTEN)
qemu-syst 1774   qemu   32u  IPv4  19480      0t0  TCP 127.0.0.1:rfb (LISTEN)
syncthing 2620 sergio   19u  IPv4  22825      0t0  TCP 127.0.0.1:8384 (LISTEN)

En este caso, vemos los descriptores de archivos de lectura y escritura 5u, 7u, 32u y 19u.

Para ver la relación entre descriptores y sockets podemos hacer un ping a una determinada dirección ip:

ping -c 10000 9.9.9.9 &> /dev/null

Si buscamos los descriptores de archivos con lsfd, mostrará el siguiente resultado:

lsfd -p 914323 -Q '(FD >= 0)' 
COMMAND    PID   USER ASSOC  XMODE   TYPE SOURCE MNTID    INODE NAME
ping    914323 sergio     0 rw-D--    CHR  pts:6    36        9 /dev/pts/6 
ping    914323 sergio     1 -w----    CHR  mem:3    34        4 /dev/null
ping    914323 sergio     2 -w----    CHR  mem:3    34        4 /dev/null
ping    914323 sergio     3 rw---m   PING sockfs     9 30437500 state=close id=35 laddr=0.0.0.0
ping    914323 sergio     4 rw---- PINGv6 sockfs     9 30437501 socket:[30437501]

Analicemos cada descriptor de archivo:

  • 0: Es la "standard input" que apunta a una pseudoterminal (dispositivo de caracteres), al tratarlo como un archivo tiene permisos: de lectura y escritura. Usa un sistema de archivos y como tal también maneja inodos.
  • 1: Es la "standard output" que apunta a /dev/null. Solamente tiene permisos de escritura, el sistema de archivos proviene de la memoria principal y tiene permisos solamente de escritura.
  • 2: Es el "standard error" que apunta también a /dev/null.
  • 3: Apunta a un socket de tipo IPv4, y tiene permisos de lectura y además está siendo utilizado por un evento de multiplexación.
  • 4: Finalmente tenemos el descriptor de 5 que apunta a un tipo de socket que usa IPv6.

Dentro del directorio /proc podemos ver que los descriptores 1 (salida estándar) y 2 (error estándar) se redirigen al archivo /dev/null, mientras tanto, 3 y 4 apuntan a sockets:

ls -l /proc/914323/fd
total 0
lrwx------ 1 sergio sergio 64 may 19 17:33 0 -> '/dev/pts/6 (deleted)'
l-wx------ 1 sergio sergio 64 may 19 17:33 1 -> /dev/null
l-wx------ 1 sergio sergio 64 may 19 17:33 2 -> /dev/null
lrwx------ 1 sergio sergio 64 may 19 17:33 3 -> 'socket:[30437500]'
lrwx------ 1 sergio sergio 64 may 19 17:33 4 -> 'socket:[30437501]'

Podemos hacer otra prueba, en este caso usaremos solamente ping sobre ipv6 y en lugar de redireccionar a /dev/null, lo haremos redirigiendo stdin y stderr a archivos regulares distintos:

ping6 -c 10000 ::1 > out.txt 2> errors.txt &

Aquí solamente usará un socket (ya que no usa ipv4):

lsfd -p 926928 -Q '(FD >= 0)'
COMMAND    PID   USER ASSOC  XMODE   TYPE SOURCE MNTID    INODE NAME
ping6   926928 sergio     0 rw----    CHR  pts:7    36       10 /dev/pts/7
ping6   926928 sergio     1 -w----    REG   0:34    52 38207299 /tmp/out.txt
ping6   926928 sergio     2 -w----    REG   0:34    52 38207300 /tmp/errors.txt
ping6   926928 sergio     3 rw---- PINGv6 sockfs     9 31193485 state=close id=44 laddr=::

¿Qué sucede si se borra /tmp/errors.txt?

lsfd -p 926928 -Q '(FD >= 0)'
COMMAND    PID   USER ASSOC  XMODE   TYPE SOURCE MNTID    INODE NAME
ping6   926928 sergio     0 rw----    CHR  pts:7    36       10 /dev/pts/7
ping6   926928 sergio     1 -w----    REG   0:34    52 38207299 /tmp/out.txt
ping6   926928 sergio     2 -w-D--    REG   0:34    52 38207300 /tmp/errors.txt
ping6   926928 sergio     3 rw---- PINGv6 sockfs     9 31193485 state=close id=44 laddr=::

Bueno, veremos que el archivo aparece con el flag D indicando que borró del respectivo sistema de archivos.

Por lo tanto, si bien literalmente no todo es archivo, podemos afirmar que en general podríamos mediante los descriptores de archivos establecer un puente entre un proceso y los recursos a los que está accediendo. En definitiva, un descriptor de archivos, permite al proceso comunicarse con el recurso subyacente de manera eficiente y uniforme, independientemente de si el recurso es un archivo en el sistema de archivos, un dispositivo de hardware o un socket de red.

Enlaces útiles

Gestión de Contraseñas Usando Contenedores Podman

Podemos administrar nuestros datos personales también con estándares profesionales. En este contexto, vamos a explorar cómo llevar la gestión de contraseñas usando utilizando herramientas viejas y confiables como pass, gpg, git combinada con la potente solución de contenedores Podman. Será una experiencia desafiante.

Claves

Almacenamiento de Contraseñas Elevado

Para gestionar nuestras passwords usaremos pass. La herramienta pass no estra cosa que un potente script de bash de algo más de 720 líneas de wrapper principalemente para gpg y git.

Ahora, lo realmente interesante: configuraremos un repositorio dentro de un contenedor Podman. Este repositorio, administrado con git, puede ser compartido de manera segura y efectiva en todos tus dispositivos.

Acceso Simplificado desde Cualquier Lugar

La accesibilidad es clave en tu entorno profesional. Ya sea trabajando en sistemas Windows o Linux, puedes aprovechar QtPass, una interfaz gráfica para pass. Para usuarios de iPhone, passforios es una excelente opción, mientras que los dispositivos Android pueden beneficiarse de Password-Store, disponible en Google Play Store y F-Droid para mantener tus contraseñas siempre sincronizadas.

Esquema de podman con pass

Características Clave para Profesionales

  • Control Total: Somos nosotros quienes gestionan nuestros repositorios. Los datos sensibles están en tus dispositivos, evitando intermediarios y asegurando la confidencialidad.

  • Portabilidad Sin Esfuerzo: Se puede cambiar de dispositivos o realiza copias de seguridad con facilidad. Tu repositorio te seguirá sin problemas.

  • Seguridad de Alto Nivel: tus credenciales seguras con estándares de confiabilidad, integridad y disponibilidad.

  • Compartir con Confianza: Podrás compartirlo fácilmente en círculos de confianza.

Configuración Inicial y Uso Avanzado

En esta primera fase, te guiaremos a través de la configuración de tu repositorio en un contenedor Podman y las opciones para interactuar con él desde distintos dispositivos.

Nota 1:

El enfoque primordial es establecer un almacén personal de contraseñas. Además de utilizarlo en tus dispositivos, podrás extender su uso a usuarios de confianza. Aunque podría requerirse alguna asistencia técnica inicial para la configuración, las acciones esenciales son "actualizar desde el repositorio (pull)" y "enviar cambios al repositorio (push)".

Esta idea es adaptable a ambientes profesionales con para grupos reducidos de usuarios en una red corporativa, donde cada miembro tiene su copia del repositorio principal. El repositorio podría estar incluso en algún contenedor que esté disponible 24x7. Esto facilita la consulta, creación, modificación y eliminación colaborativa de contraseñas, consolidando luego los cambios en un repositorio compartido.

Nota 2:

Para aprovechar plenamente esta guía, asumimos que poseés conocimientos de:

  • Gestión de claves públicas ssh
  • Gestión de claves gpg
  • Uso básico de git
  • Uso básico de Podman
  • Conocimientos generales de Linux: bash, systemd, firewalld (iptables/nftables), etc.

¿Qué usaremos para lograr todo esto?

  • OS: Fedora 38
  • podman
  • pass

Se podría usar otra distribución, sin embargo es importante que cuente con una versión relativamente reciente de podman.

¿Por qué usamos podman? Porque tiene una gran similitud con docker, y además, posee la capacidad de correr contenedores de manera mucho más segura y sencilla. En este caso particular, crearemos un contenedor que alojará el repositorio compartido de passwords.

No será necesario crear servicios web y/o de bases de datos.

Instalación de paquetes

dnf install -y git pass

Inicialización de repositorio de passwords

En este ejemplo le pasamos los identificadores de las clave públicas gpg en el siguiente usamos 3 direcciones de mail correspondientes a la clave del host, la del celular y la de otra persona respectivamente.

pass init jkm@example.com fxi@example.com pyn@example.net

pass git init

pass generate puertablanca

Preparación del container

Creamos el siguiente Dockerfile

FROM fedora:38
RUN dnf update -y && dnf install -y git openssh-server
RUN useradd -ms /bin/bash git
RUN mkdir /home/git/.ssh
RUN ssh-keygen -A
COPY  ssh-pks /home/git/.ssh/authorized_keys
RUN echo "git ALL=(ALL:ALL) NOPASSWD: /usr/sbin/sshd" >> /etc/sudoers && git clone --bare /mnt/.password-store /home/git/.password-store && chown -R git:git /home/git  && chmod 700 /home/git/.ssh && chmod 600 /home/git/.ssh/authorized_keys
EXPOSE 22
CMD ["sudo","/usr/sbin/sshd", "-D"]

Esto nos permitirá crear un repositorio con las siguientes características:

  • Basado en Fedora 38
  • Un usuario llamado git que tendrá el único privilegio de correr el servicio ssh
  • Obtendrá una copia del repositorio git antes creado con pass

Crear la imagen de podman

podman build -v /home/sergio/.password-store:/mnt/.password-store -t passteiner .

Crear el container

podman run -d --name container-pass_git --user git -p 60003:22 passteiner

En este punto, ya estamos en condiciones de crear, editar, modificar nuestras passwords y subirlas al repo del contenedor de manera que esté disponible para otros dispostivos y/o usuarios.

Cabe aclarar que para usar Password Store en Android hace falta instalar OpenKeychain. Esa aplicación nos permitirá crear un el par de clave privada + clave pública GnuPG, como así también importar la clave pública del resto de los usuarios con quien compartiremos el llavero. Tener en cuenta que es muy importante la passphrase que usemos para cifrar nuestra clave privada: debe ser fácil de memorizar y a la vez robusta. Esa misma passphrase se nos pedirá cuando necesitamos acceder a las contraseñas:

Y luego con Password Store tendremos que:

  • Ingresar los parámetros de repositorio que está en el contenedor que hemos creado, tanto la url (por ejemplo ssh://git@10.0.0.10:60003/git/,password-store) y la branch (master).
  • Generar la clave pública ssh para autenticarse al repositorio. Esta clave tendrá que copiarse al archivo /home/git/.ssh/authorized_keys del contenedor.

podman exec ontainer-pass_git bash -c 'echo "clave_publica_ssh" /home/git/.ssh/authorized_keys'

(Si queremos que este archivo sea persistente, podríamos modiicar el Dockerfile para que use un volumen).

  • Clonar el repositorio del contenedor.

Una vez que hemos clonado el repositorio, obtendremos el listado de passwords y el menú para operar con él:

Menú de Password Store.

Actualizando nuestro repositorio

Hay varias configuraciones posibles, pero la que recomiendo es la siguiente:

pass git config pull.rebase false

Para bajar las actualizaciones del contenedor:

pass git pull

Para subir las propias modificaciones al contenedor:

pass git push

Comentario finales

Al finalizar habrás conseguido que:

  • El contenedor se ejecuta como un usuario sin privilegios dentro del sistema.

  • Todo - excepto el proceso sshd - se ejecutará como un usuario sin privilegios aun dentro del container. Salvo que explícitamente uses algo como docker run --user root..... . Pero ¿por qué lo harías?

  • Por fuera del contenedor en realidad, mapea a nuestro propio usuario.

Enlaces útiles

3 pasos para configurar unidad de systemd para VM de Virtualbox

Bonita imagen ilustrativa 😄

Foto de Ashutosh Dave en Unsplash

1. Encontrar el UUID de la VM, por ejemplo si tenemos una máquina llamada RHEL7, ejecutamos:

$ VBoxManage showvminfo RHEL7 | grep '^UUID' | awk '{ print $NF }'
f02a9f08-2ff2-4a92-b3cd-a8dfb17513c6

2. Crear el archivo template de servicio ~/.config/systemd/user/virtualbox_vm@.service:

[Unit]
Description=VirtualBox VM %i

[Service]
Type=simple
KillMode=mixed
ExecStart=/usr/lib/virtualbox/VBoxHeadless --comment RHEL7 --startvm f02a9f08-2ff2-4a92-b3cd-a8dfb17513c6 --vrde config

[Install]
WantedBy=default.target

3. Recargar systemd, Habilitar y arrancar el servicio

$ systemctl --user daemon reload && systemctl --user enable --now virtualbox_vm@RHEL7.service

¡Listo!

Tu propia nube

¿Qué es Syncthing?

Imaginemos el siguiente escenario: una aplicación de notas que usamos en nuestra computadora personal. ¿Cómo hacemos para mantener esas notas sincronizadas con el celuar? O por ejemplo queremos compartir esas notas con alguien de la familia. ¿No es demasiado recurrir a la Nube para eso? Es decir tenemos notas, fotos, etc. privadas que no queremos recurrir a un tercero para que se sitúe como mediador para que esos documentos estén sincronizados y compartidos. A fin de cuentas, la intimidad es un valor... ¿La intimidad es un valor? Bueno, muchos en pleno siglo XXI creemos que lo sigue siendo. De modo que si considerás la intimidad como un valor a cuidar, la aplicación Syncthing te resultará de mucha utilidad.

Foto de Dayne Topkin en Unsplash

¿Qué tecnología usa Syncthing?

Synthing usa BEP, un protocolo que se usa entre dos o más dispositivos para formar un cluster. Cada dispositivo intenta tener sus carpetas sincronizadas con la versión más reciente del cluster. Toda la comunicación se asegura mediante TLS con Perfect Forward Secrecy para impedir que los datos sean descifrados, sea en sesiones pasadas o futuras, aun si las claves privadas usadas en una sesión individual se roban en algún momento.

¿Qué necesitamos instalar?

En primer lugar el paquete syncthing, por ejemplo:

dnf install syncthing

Este paquete tiene el binario para lanzar el servidor.

Como usuario se puede habilitar y lanzar con:

systemctl --user enable --now syncthing.service

Se puede instalar en en teléfonos móviles con Android tanto desde el Play Store como desde el repositorio F-Droid.

¿Cómo realizamos la configuración?

La configuración se puede realizar mediante el acceso a la interfaz web que escucha de manera predeterminada en 127.0.0.1:8384.

Es muy importante elegir un dispositivo que funcione como presentador o introducer. El presentador es el encargado de agregar automáticamente otros dispositivos. Solamente debe haber un presentador por cluster.

Si usamos firewalld, se pueden habilitar los puertos que usa synthing:

firewall-cmd --add-service=syncthing --permanent && firewall --reload

Paquetes adicionales

Además, hay otros paquetes muy útiles que se puede instalar usando el repositorio home_mkittler:

syncthingfileitemaction

Opciones de syncthing en Dolphin Añade opciones al menú contextual en Dolphin.

syncthingplasmoid

Plasmoid de syncthing Es un módulo de plasma que permite visualizar, controlar y configurar Syncthing.

syncthingtray

Acceso a syncthing desde la bandeja del sistema Es similar a syncthingplasmoid pero solamente se ancla en la bandeja del sistema.

Conclusión

Si bien Synthing no debe entenderse como una solución de fileserver corporativa pero alcanza con creces para montar de manera rápida una nube personal, preservando principios fundamentales de seguridad.

Referencias y más información

Plan Táctico y Estratégico de la Memoria en Linux

La mitología en torno a la memoria en Linux ha producido una serie de relatos:

  • Linux puede funcionar con muy poca memoria RAM.
  • Linux consume mucha memoria.
  • Una partición SWAP debe tener entre 1 a 2 veces la memoria RAM.

Como vemos algunas historias son más recientes, otros más antiguas, pueden ser parcialmente ciertas y hasta contradictorias entre sí.

Este artículo tiene como propósitos:

  • Explicar de manera sencilla el funcionamiento de la memoria en Linux, desmitificando también algunos conceptos.
  • Enumerar y describir tácticas para que el uso de la memoria proporcione la mejor usabilidad y experiencia del usuario.
  • Ofrecer alternativas para que cada uno elija la mejor opción de acuerdo a sus necesidades.

Definiciones

Vamos a repasar algunos conceptos básicos que de manera más o menos frecuente usamos, usaremos metáforas en el camino. Ninguna metáfora es perfecta, pero nos ayudan a entender la realidad.

Memoria Virtual

Generalmente el adjetivo virtual en informática significa algo que provoca la ilusión de ser otra cosa. Por ejemplo, un archivo regular puede hacerse pasar por un disco físico. En el caso de la memoria virtual, el sistema operativo nos ofrece una cantidad de memoria mucho mayor a la que existe físicamente.

Si queremos comprar algo que sale $100000 pero solamente podemos pagar la décima parte, tal vez podamos pedir un crédito para que se financie la compra y pagar $10000 por mes. El sistema operativo hace algo parecido con la memoria.

De parte del hardware en particular la CPU necesita poder traducir las direcciones de memoria virtual a la memoria física.

Algo muy importante: Linux trata de usar la mayor cantidad de memoria posible, para poder ejecutar las aplicaciones y acceder a los archivos de la manera más rápida posible. De manera que si la memoria libre es baja no es necesariamente un indicativo de un problema.

Swap

Los usuarios ocasionales de Linux y aun muchos sysadmins tienen una idea negativa sobre "la swap". Simplificaciones extremas y conceptos anticuados la han convertido en le gran villana de la historia del sistema operativo.

Si comparamos a la memoria con un escritorio, sin swap podría lucir así:

Prescindir de swap no es una opción sana.

Photo by Ashim D’Silva on Unsplash

Así que primero vamos a decir lo que no es:

  • No es la memoria virtual sino que forma parte de la técnica que realiza el sistema operativo para administrar la memoria.
  • No es un espacio de reserva ni un último recurso.
  • No es algo que el sistema operativo pueda alegremente prescindir aun cuando la cantidad de memoria RAM física sea grande.

Nuestro escritorio con swap:

Analogía de Swap

Photo by Alexandru Acea (edited by me) on Unsplash

¿Los cajones de un escritorio los usamos cuando lo tenemos abarrotado de cosas? No, los usamos para guardar cosas que no son de alta prioridad. Aunque es cierto, si luego queremos usar esa tijera o aquel destornillador en algún momento requerirá un poco más de trabajo, tendremos que abrir el cajón, buscarlo, extraerlo, etc.

Ah, y la swap también sirve para hibernar, aunque honestamente no se cuanta gente mantiene esa práctica.

Page

Es un bloque de memoria virtual.

Page table

Podemos pensarlo como un índice usado por el hardware que refiere cada dirección de memoria virtual a una dirección de memoria física.

Page Fault

Una page fault ocurre cuando un programa intenta acceder a un bloque que está mapeado en el espacio de direcciones pero no está cargado en la RAM. Si bien no es un problema grave, implica que el programa tendrá que recuperar la información desde el disco, que es un proceso más lento.

Page cache

Es el espacio en que los archivos y metadatos utilizados suelen guardarse para poder acceder a ellos de manera más rápida.

Page cache

Tipos de memoria

File Memory

Es la memoria relacionada con el Page Cache.

Anonymous Memory

El adagio unixista (en su versión simplificada) que dice que todo es archivo parece tener influencia aquí. Tal vez es por eso que la memoria que no está asociada a un archivo o al sistema de archivos se la reduce con el adjetivo de anónima.

Thrashing

Es cuando el sistema agresivamente traduce direcciones físicas a direcciones virtuales y libera bloques de memoria que no se han usado de manera reciente. La ejecución normal de las tareas puede resentirse. En entornos de escritorio la usabilidad y la experiencia del usuario se ven fuertemente afectadas. La swap puede colaborar evitando al menos un poco el thrashing. A veces puede suceder cuando la memoria física (RAM) es insuficiente.

Memory Pressure

Memory pressure es el trabajo que tiene que hacer Linux cuando hay déficit de memoria. En ciertas situaciones puede haber demora en la ejecución de tareas, y que el rendimiento se vea seriamente afectado y llevado al extremo puede causar OOM (Out-of-Memory): el agotamiento total de la memoria para que el sistema operativo pueda continuar funcionando correctamente.

OOMKiller

El OOM killer es un proceso del kernel que se dispara solamente si la memoria disponible bajó a niveles críticos, en este escenario selecciona una o más tareas para finalizarla con la intención de que el sistema pueda seguir funcionando.

oom_score

A cada proceso se le asigna un puntaje, cuanto más alto es, más susceptible es a ser terminado por OOMKiller. El comando choom permite ver y/o ajustar dicho valor.

choom


Tuning

Ahora veremos diferentes tácticas que podemos usar para optimizar el uso de la memoria.

cgroupv2

cgroup es un mecanismo para organizar los procesos de manera jerárquica y distribuir los recursos del sistema a lo largo de la jerarquía en una manera controlada y configurada.

Un cgroup se compone de un núcleo que es responsable primariamente en organizar de manera jerárquica los procesos y controladores que comúnmente distribuyen un tipo específico de recurso del sistema a lo largo de la jerarquía.

En la versión 2 de cgroup un proceso no puede pertenecer a diferentes grupos para diferentes controladores. Si el proceso se uno al grupo alfa, todos los controladores para alfa tomarán control de ese proceso.

ps mostrando cgroup

Supongamos que los procesos de un cgroup (y todos los grupos hijos) usan poca memoria, podríamos decirle al kernel que reclame memoria de otros cgroups. Esto es precisamente lo que hace el parámetro memory.low.

el parámetro memory.low

Otro parámetro interesante para monitorear es memory.pressure, la primera línea tiene el tiempo físico de una o más tareas demoradas debido a la falta de memoria. La segunda sería lo mismo pero para todas las tareas del grupo, full es lo mismo pero para todas las tareas del grupo, Entonces si miramos el archivo /sys/fs/cgroup/user.slice/memory.pressure:

some avg10=0.00 avg60=0.13 avg300=0.12 total=1690238
full avg10=0.00 avg60=0.10 avg300=0.09 total=1394199

Significa que algunas tareas del grupo de control user.slice en los últimos 10 segundos no tuvo demoras, pero si tuvo un 0,13% de retraso en el último minuto y 0,12% en los últimos 5 minutos. En total estas tareas llevan acumulados casi 1,7 segundos. La segunda línea representa lo mismo pero para todas las tareas del grupo.

zram

zram es por así decirlo, una manera cool de usar swap gracias a un módulo del kernel. zram, swap pero cool

Photo by chuttersnap on Unsplash

En lugar de gastar espacio en un disco (sea rígido o sólido) usamos dispositivos de bloque en la propia RAM. Los bloques swapeados se guardan comprimidos. Esto discos virtuales son rápidos y ahorran memoria.

Una de las pocas desventajas que tiene esta metodología es la incapacidad para poder hibernar el sistema operativo, al no estar presente la partición en un almacenamiento de tipo persistente.

zram

Sistemas de archivos

El journal de ext4 puede ser lento, xfs puede ser una mejor alternativa o mejor aun btrfs.

EarlyOOM

El oom-killer del kernel solamente se dispara en situaciones extremas y le puede llevar mucho tiempo hasta que puede enviar SIGKILL a los procesos que sean necesarios para poder liberar memoria. Durante ese tiempo probablemente el usuario no pueda interactuar con el sistema operativo.

EarlyOOM trabaja en espacio de usuario y por lo tanto se puede anticipar y ser mucho más rápido.

El comportamiento predeterminado en Fedora es que si hay menos del 10% de RAM y/o SWAP libre, earlyoom envía una señal de terminación a todos los procesos con oom_score más alto. Si la RAM como SWAP libre bajan por debajo del 5%, earlyroom enviará una señal para matar todos los procesos con oom_score más elevado.

La idea es recuperar la usabilidad (especialmente en un entorno de escritorio) lo antes posible.

El problema es que EarlyOOM no soporta al momento la medición de la memory pressure como indicativo para tomar decisiones.

nohang

Este servicio es mucho más configurable y aporta una mejor solución que EarlyOOM.

Algunas funcionalidad son:

  • Se puede elegir la acción que realizará en una situación OOM.
  • Ofrece varios criterios para elegir los procesos a finalizar.
  • Soporta zram
  • Puede usar memory pressure para tomar una acción.
  • El archivo de configuración es medianamente sencillo

zswap

Con zswap no reemplazamos el espacio swap en el disco sino que usamos un caché comprimido en la RAM. Este método ahorra I/O, obteniendo entonces mejor rendimiento y alargando la vida útil de discos flash o sólidos. La única desventaja es usar algo de tiempo del procesador para realizar la compresión.

zswap

Photo by Pineapple Supply Co. on Unsplash

Mediante el caché se logra una diferenciación entre páginas más usadas (zswap) y menos usadas (swap).

oomd

El servicio oomd es un proyecto en el que están trabajando en Facebook para integrarlo con systemd. Por ahora es un proyecto para manejo de memoria a gran escala, y bastante más complejo de configurar.

Resumen

  • Swap no es la villana de la película
  • Si existe la opción de migrar a otros sistema de archivos aunque con características un tanto experimental, elegir btrfs. Una opción más moderada es xfs.
  • El tuning de cgroupv2 puede traer grandes beneficios, no obstante existen proyectos y distribuciones que no lo usan.
  • EarlyOOM es una solución rápida y aplicable a una amplia gama de sistemas Linux, aunque no siempre es la más exacta ni más elegante.
  • El servicio nohang (o no hang-desktop) es una opción más madura aunque algo más compleja que EarlyOOM.
  • El servicio oomd desarrollado por Facebook es seguramente la opción más adecuada para escenarios más complejos y de manejo de memoria a gran escala.
  • Si se desea ahorrar espacio en disco se puede reemplazar la swap por zram, sacrificando la opción de hibernar el sistema.
  • La opción zswap es más sofisticada, aunque dependemos del uso de swap en disco.

Photo by sk on Unsplash

Fuentes consultadas

Tutorial: Cifrar $HOME con gocryptfs

En un artículo anterior: Tutorial de fscrypt para cifrar archivos, habíamos visto como cifrar archivos con fscrypt y ext4. Ahora aprenderemos otro método independiente del sistema de archivos utilizado, se trata de una herramienta llamada gocryptfs.

Conocimientos previos necesarios:

  • Uso habitual de línea de comandos en Linux (incluyendo entre otros manejo de propietarios y permisos)
  • Instalación y desinstalación de paquetes

En el ejemplo en cuestión estoy usando Debian Buster (te recomiendo primero instalarla en una máquina virtual para hacer pruebas), de modo que los pasos a seguir pueden ser un poco diferentes en otras distribuciones, pero los principios generales se mantienen. Todos los pasos hasta que lo pruebes como usuario común deben hacerse con privilegios de superusuario.

Es muy importante contar espacio suficiente para copiar temporalmente los archivos del directorio que se desea cifrar.

He cambiado el shell del usuario sergio que es dash (predeterminado en Debian) por bash, ya que el primero no está pensado para un uso interactivo habitual además de ser menos potente.

Instalar grocryptfs

apt install grocryptfs

Crear el directorio para cifrar

mkdir /home/sergio_cifrado

Inicializar el directorio

Aquí seteamos la misma contraseña que la del usuario

gocryptfs --init /home/sergio_cifrado/
Choose a password for protecting your files.
Password: 
Repeat: 

Your master key is:

    9c43faf4-16a07508-42213628-50a5c55e-
    e0c17483-c41453a0-6355f9f0-897b3aa9

If the gocryptfs.conf file becomes corrupted or you ever forget your password,
there is only one hope for recovery: The master key. Print it to a piece of
paper and store it in a drawer. This message is only printed once.

The gocryptfs filesystem has been created successfully.
You can now mount it using: gocryptfs /home/sergio_cifrado MOUNTPOINT

Montar el directorio

mkdir /home/sergio_montaje_temporario && chmod 750 /home/sergio_montaje_temporario && chown sergio. /home/sergio_temporario &&
gocryptfs /home/sergio_cifrado/ /home/sergio_temporario/
Password: 
Decrypting master key
Filesystem mounted and ready.

Ajustamos los propietarios y permisos

chown -R sergio. /home/sergio{_cifrado} && chmod 750 /home/sergio_cifrado

Copiar todos los archivos del directorio del usuario al directorio temporal

cp -Tav /home/sergio /home/sergio_temporario

Borrar el contenido del directorio del usuario (por favor realizar previamente un backup)

rm -rf /home/sergio

Desmontar el directorio cifrado

fusermount -u /home/sergio_temporario

Le cambiamos el nombre al directorio temporario por el original

mv /home/sergio_temporario /home/sergio

Todo lo que viene a continuación es necesario cuando queremos que el directorio se monte de manera automática en el momento del login.

Instalamos el módulo de PAM para montaje de volúmenes

apt install -y libpam-mount

Ejecutamos el configurador de pam

pam-auth-update

pam-auth-update

y presionamos en Aceptar.

En otras distribuciones y configuraciones, puede ser necesario editar otros archivos del directorio /etc/pam.d.

Luego hay que editar el archivo /etc/security/pam_mount.conf.xml agregando lo siguiente antes de </pam_mount>:

<volume user="sergio" fstype="fuse" options="nodev,nosuid,quiet,nonempty,allow_other"
path="/usr/bin/gocryptfs#/home/%(USER)_cifrado" mountpoint="/home/%(USER)" />

Configuramos FUSE

# /etc/fuse.conf - Configuration file for Filesystem in Userspace (FUSE)

# Set the maximum number of FUSE mounts allowed to non-root users.
# The default is 1000.
#mount_max = 1000

# Allow non-root users to specify the allow_other or allow_root mount options.
# Modificamos aquí:
user_allow_other

Eso es todo, felicitaciones si llegaste hasta aquí 😀, podemos reiniciar y probar la configuración:

Para login gráfico:

Conclusión

De esta manera pudiste configurar el cifrado automática de un directorio $HOME de un usuario. Este método es principalmente útil para equipos donde trabaja un solo usuario (podría ser tu laptop de trabajo diario por ejemplo).

Fuentes y más recursos