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

Polkit es un conjunto de herramientas para administrar y manipular las autorizaciones en Linux. Está enfocada más en procesos que en usuarios. Es decir, permite que los procesos sin privilegios puedan comunicarse con procesos con privilegios, creando un control de acceso granular para tareas administrativas. Esto reduce la necesidad del acceso completo de root, con el fin de mejor la seguridad del sistema. Recordemos, como advertencia que la seguridad es algo dinámico y que no podemos descansar en una herramienta en particular. Como cualquier software que existe en el mundo real ha tenido en el pasado vulnerabilidades serias, por lo tanto es importante siempre mantener los sistemas actualizados en la medida de lo posible.

Cómo mínimo deberías ejecutar un comando como el siguiente:

rpm -q --changelog polkit | grep -i cve-2021-4034

Ejecutá el comando equivalente en tu distribución 😉.

¿Cómo funciona?

Para empezar, conviene entender 3 conceptos claves:

  • Acciones: Operaciones específicas que requieren autorización, definidas en archivos XML.

  • Políticas: Reglas escritas en JavaScript que determinan quién puede realizar una acción y bajo qué condiciones.

  • Agentes de autenticación: Programas que les solicitan a los usuarios autenticación cuando es necesario.

Cuando un usuario intenta llevar a cabo una acción privilegiada, polkit verifica la política involucrada y, si se requiere, solicita autenticación.

Ejemplo ilustrativo: Un usuario intenta desinstalar un programa

El usuario sergio, ejecuta el programa pkcon (parte del sujeto (1)) para desinstalar un paquete (acción). El agente de polkit de KDE Plasma (2) de ser necesario le pedirá al usuario sergio que se autentique. La autoridad, es decir polkitd tomará decidirá de acuerdo a como está configurada la acción y a sus políticas (4) basadas en las reglas existentes. En particular, esta acción solicitada es llevada acabo por el mecanismo packagekitd (5). El programa pkcon, polkit-kde-authentication-agent-1 y packagekitd se comunican con polkitd mediante el bus del sistema (3*).

Ejemplo de procesos en el cual polkit está involucrado

¿Dónde están las acciones en el filesystem?

Las acciones están almacenadas en /usr/share/polkit-1/actions/:

Ranger mostrando el directorio de acciones y el contenido un archivo de acciones en XML

Por ejemplo, en el archivo /usr/share/polkit-1/actions/org.freedesktop.systemd1.policy podemos ver la acción org.freedesktop.login1.reboot:

<action id="org.freedesktop.login1.reboot">
        <description gettext-domain="systemd">Reboot the system</description>
        <message gettext-domain="systemd">Authentication is required to reboot the system.</message>
        <defaults>
                <allow_any>auth_admin_keep</allow_any>
                <allow_inactive>auth_admin_keep</allow_inactive>
                <allow_active>yes</allow_active>
        </defaults>
        <annotate key="org.freedesktop.policykit.imply">org.freedesktop.login1.set-wall-message</annotate>
</action>

¿Qué significa cada autorización y sus valores?

Autorización Explicación
allow_any Autorizaciones para cualquier proceso o aplicación
allow_inactive Autorizaciones que aplican a procesos o aplicaciones en  sesiones inactivas
allow_active Autorizaciones que aplican a procesos o aplicaciones en sesiones activas

Cada autorización tiene un determinado valor:

Valor Explicación
no Sin autorización
yes Con autorización
auth_self Se necesita autenticación por parte del  dueño de  la sesión que  origina el proceso o aplicación
auth_admin Se necesita autenticación de una cuenta de usuaria administrativa
auth_self_keep Es igual que auth_self pero la autorización se mantiene por unos minutos
auth_admin_keep Es igual que auth_admin pero la autenticación se mantiene por unos minutos

Acciones de polkit

Suelen haber cientos de acciones en una instalación de Linux actual, es especial si posee GUI. Esas acciones se pueden listar con el comando pkaction. Si queremos ver en detalle una acción podemos hacerlo como se muestra a continuación:

pkaction -v -a  org.freedesktop.login1.reboot
org.freedesktop.login1.reboot:
  description:       Reboot the system
  message:           Authentication is required to reboot the system.
  vendor:            The systemd Project
  vendor_url:        https://systemd.io
  icon:              
  implicit any:      auth_admin_keep
  implicit inactive: auth_admin_keep
  implicit active:   yes
  annotation:        org.freedesktop.policykit.imply -> org.freedesktop.login1.set-wall-message

Podemos deducir que para esta acción:

  • Para cualquier estado de sesión, se pedirá autenticación administrativa y se mantendrá por un tiempo.
  • Para cualquier acción en una sesión inactiva, igualmente se pedirá una autenticación administrativa y se mantendrá por un tiempo.
  • Si la sesión está activa, se permitirá la acción sin pedir autenticación adicional.
  • El resultado de la autorización determinará si se podrá imprimir un mensaje en el sistema para todos los usuarios.

¿Qué son las anotaciones?

La acción detallada arriba menciona "annotation". ¿Qué es una anotación? Es un elemento de metadatos utilizado para proporcionar información adicional sobre una acción de política. Las siguiente son anotaciones conocidas:

  • org.freedesktop.policykit.imply: Si la autorización es exitosa, también se autorizarán otras acciones determinadas.
  • org.freedesktop.policykit.owner: Sirve para definir los usuarios que pueden consultar si un usuario puede realizar la acción.
  • org.freedesktop.policykit.exec.path: Es utilizada por el programa pkexec para especificar la ruta del ejecutable que requiere privilegios elevados.

Reglas de autorización

Las reglas sirven para:

  • Agregar reglas ante una determinada acción y sujeto.
  • Definir condiciones para la autenticación administrativa y otros tipos de autorizaciones.
  • Llamar a una aplicación externa.
  • Generar mensajes de logs.
  • Examinar tanto la acción como sus argumentos.
  • Examinar el sujeto (usuario, grupo al que pertenece, tipo de sesión, privilegios, etc.)

¿Dónde estan las reglas de polkit en el sistema?

Están en los directorios /usr/share/polkit-1/rules.d/ y /etc/polkit-1/rules.d/. El último directorio es el se debería usar para reglas personalizadas. No es necesario reiniciar el servicio al crear, modificar y borrarlas.

¿Cómo se puede hacer troubleshooting de polkit?

Agreando un archivo de reglas como el siguiente:

// /etc/polkit-1/rules.d/00-all-debug.rules 
polkit.addRule(function(action, subject) {
    polkit.log("action=" + action);
    polkit.log("subject=" + subject);
});

Importante: Deshabilitar antes la opción --no-debug del servicio polkitd, sino dicha regla será ignorada

En general esta regla conviene deshabilitarla luego de examinar y solucionar el problema, ya que escribe muchas líneas de logs:

Logs de polkit con debug habilitado

Ahora, vamos a ver un par de ejemplos concretos 😉.

Permitir a ciertos usuarios el reinicio de servicios

polkit.addRule(function(action, subject) {
    if (action.id == "org.freedesktop.systemd1.manage-units" &&
        action.lookup("verb") == "restart" &&
        subject.isInGroup("wheel")) {
        return polkit.Result.YES;
    }
    return polkit.Result.NOT_HANDLED;
});

Esta regla utiliza el método addRule para evaluar la acción que corresponde a la gestión de usuarios. Luego busca que el parámetro que se le pasa a systemctl sea restart y verifica que el usuario sea miembro del grupo wheel.

Permitir a un usuario la administración limitada de paquetes

polkit.addRule(function(action, subject) {
    var currentTime = new Date();
    var targetDate = new Date(2024, 9, 16); // Octubre es el mes 9, ya que enero es 0

    // Comparar solo el año, mes y día
    if ((action.id == "org.freedesktop.packagekit.package-install" ||
         action.id == "org.freedesktop.packagekit.package-remove" ||
         action.id == "org.freedesktop.packagekit.upgrade-system") &&
        subject.user == "obiwan" &&
        currentTime.getFullYear() == targetDate.getFullYear() &&
        currentTime.getMonth() == targetDate.getMonth() &&
        currentTime.getDate() == targetDate.getDate()) {
        return polkit.Result.YES;
    }
    //return polkit.Result.NOT_HANDLED;
});
  • Crea variables para poder evaluar la fecha, por ejemplo, 16 de octubre de 2024.
  • Permite la instalación, desinstalación y actualización de paquetes, si la fecha es la estipulada.
  • El usuario obiwan será el beneficiario de estos permisos.
  • Solamente podrá usar herramientas que sean front-ends de Packagekit, es decir no podrá usar herramientas como yum, dnf,etc.

El comando pkexec

El comando pkexec sirve para ejecutar aplicaciones con privilegios de otro usuario, por ejemplo:

pkexec wireshark

Ejemplo de uso de pkexec

Diferencias entre Polkit y Sudo

Más allá de lo expuesto hasta este momento, uno se puede preguntar cuál es la diferencia entre polkit y sudo, ya que parecen tener la misma finalidad. Sin embargo tienen unas cuantas diferencias, las cuales se pueden apreciar en el siguiente cuadro:

sudo polkit
Propósito Permitir que determinados usuarios ejecuten comandos como root u otro usuario Proporcionar un mecanismo para controlar los privilegios en el sistema para distintas operciones en aplicaciones y servicios
Casos de uso Operaciones de línea de comandos que requieren mayores privilegios Gestionar permisos de aplicaciones gráficas y servicios del sistema sin necesidad de acceso completo de root
Configuración Archivos /etc/sudoers y /etc/sudoers.d/* Archivos de políticas en XML en /usr/share/polkit-1/actions, reglas predefinidas en /usr/share/polkit-1/rules.d/ y reglas personalizadas en JavaScript en/etc/polkit-1/rules.d/
Granularidad Otorga amplio acceso de root para ejecutar cualquier comando (comandos específicos con privilegios de root. Control basado en usuarios y grupos. Control basado en host. Permite ejecutar comandos como root u otro usuario. Control basado en acciones. Control basado en usuarios y grupos. Control basado en el estado de la sesión. Proporciona contexto que puede ser utilizado para la toma de decisiones
Autenticación Puede pedirle al usuario que ingrese su propia, la de root u otra password para ejecutar comandos Puede pedirle o no al usuario que se autentique de manera dinámica de acuerdo a reglas
Interacción con el usuario Requiere la preconfiguración en el archivo sudoers Polkit puede solicitar autenticación cuando sea necesario y puede permitir o denegar acciones basadas en políticas

¿Puede polkit reemplazar a sudo?

Polkit no puede reemplazar completamente a sudo ya que desempeñan funciones complementarias. Sudo es ideal para operaciones por línea de comandos, mientras que polkit está mejor preparado para manejar permisos dentro de aplicaciones y servicios. Se pueden usar combinadas para mejorar la seguridad del sistema.

Conclusión

Utilizar Polkit y sudo de manera complementaria permite aprovechar las fortalezas únicas de cada herramienta, gestionando permisos en un entorno Linux de forma segura y eficiente. Mientras que sudo es ideal para ejecutar tareas en la línea de comandos que requieren privilegios elevados, Polkit proporciona un control detallado sobre los permisos en aplicaciones y servicios, convirtiéndola en una herramienta indispensable para la administración de sistemas Linux modernos.

Es crucial dominar estas herramientas tanto para administradores de sistemas como para desarrolladores. Cualquier aplicación que requiera privilegios elevados para realizar ciertas operaciones interactuará con Polkit, haciendo esencial comprender su funcionamiento para mantener un entorno seguro y bien gestionado.

Más Recursos

  1. Proyecto Polkit en freedesktop
  2. Proyecto Polkit en github
  3. RHSB-2022-001 Polkit Privilege Escalation - (CVE-2021-4034)

Comentarios

Comments powered by Disqus