.. _privilegios: Privilegios *********** En un principio (incluso históricamente hablando), en el sistema corren dos tipos de procesos: los **procesos privilegiados** y los **procesos sin privilegios**. Es, pues, una distinción dicotómica sin escala de grises: los primeros pueden hacer cualquier tipo de llamadas al *kernel*, mientras que para los segundos sólo es posible un conjunto de llamadas a nivel de usuario. Por ejemplo, manipular interfaces de red (crear interfaces virtuales, dar o borrar configuración a las interfaces, etc) son operaciones que requieren privilegio. .. note:: Téngase en cuenta que dentro de las llamadas no privilegiadas, también existen restricciones: las que se establecen a través de los permisos sobre archivos. Así, por ejemplo, no todos los procesos sin privilegios tienen la capacidad de formatear dispostivos; sino sólo aquellos cuyo ejecutante posea permisos para escribir sobre la :ref:`representación en forma de archivo del dispositivo `. Un proceso ejecutado por el usuario de |UID| **0**, esto es, por el administrador, es siempre un proceso privilegiado, de ahí que en un sistema *UNIX* pueda realizar cualquier acción. La pregunta entonces es, ¿existe alguna estrategia para que a un proceso iniciado por un usuario distinto a *root*, se le permita ejecutar una acción que requiera privilegios? Y la respuesta es sí, en concreto, hay dos estrategias a las que dedicaremos el resto del epígrafe. .. warning:: El núcleo de *Linux* se desentiende del *setuid* y las *capabilities* definidas en ejecutables interpretados (p.e. un *script* de :program:`bash`). Así pues, su definición sólo tiene sentido para programas compilados. Esta limitación, no obstante, no es común a todos los *UNIX*. .. _setuid: **setuid** La solución tradicional en los sistemas *Linux* para que los usuarios sin privilegios puedan realizar acciones privilegidas es el :ref:`setuid ` habilitado en un ejecutable cuyo propietario es el administrador. De este modo, el proceso corre como si fuera ejecutado por *root*. Basados en esta estrategia, hay cuatro maneras de que el usuario opere como administrador: #. Habilitar directamente el *setuid* sobre el archivo de un ejecutable que pertenece al administrador. De este modo, cualquier usuario con permisos de ejecución creará un proceso privilegiado al ejecutarlo. #. Utilizar :ref:`su ` (o :ref:`runuser `) que es un programa con el *setuid* habilitado, que permite la ejecución de cualquier otro programa. De este modo, cualquier usuario que conozca la contraseña del administrador\ [#]_, podrá ejecutar programas de forma privilegiada, incluida una *shell* interactiva. #. Como variante del anterior, utilizar :ref:`sudo `, que también tiene habilitado su *setuid* y cuya principal aportación es ser mucho más configurable que :command:`su`: + Para la *autenticación* permite la introducción de la propia contraseña del usuario, de la contraseña del administrador o ninguna. + Permite restringir, según cada usuario, cuáles son los *programas* que podrán ejecutarse en modo privilegiado. #. `Polkit `_ que es una herramienta que permite definir reglas de autorización para procesos sin privilegios. Este método permite limitar los privilegios que se conceden al proceso por lo que, a diferencia de los otros tres, no tendrá poderes omnímodos. Suele utilizarse en equipos de escritorio por ser la herramienta preferida por estos entornos para que el usuario habitual sea capaz de realizar acciones que en principio le están vedadas (como apagar la máquina). Por lo general, para que un usuario acceda a una consola interactiva con la identidad de *root*, se usan :command:`su` o :command:`sudo` dependiendo de la distribución: - :ref:`su ` viene de base en *Debian* y su uso ya se describió:: $ su - Esta orden requiere la introducción de la contraseña de administrador\ [#]_, tras lo cual conseguiremos una sesión interactiva en la que nos convertiremos en el administrador. - :ref:`sudo ` es la estrategia que han adoptado otras distribuciones como *Ubuntu*\ [#]_, y a cuya configuración y uso dedicaremos epígrafe aparte. Sea como sea, esta estrategia tiene un problema principal: viola el `principio de mínimo privilegio `_\ [#]_, lo cual propicia que cualquier programa se convierta en un peligro potencial de seguridad si contiene algún *bug* que permita a un usuario malintencionado explotarlo para escalar privilegios y hacer algo distinto para lo que originariamente fue diseñado. .. _capabilities: **Capacidades** Para no conculcar el *principio de mínimo privilegio*, *Linux* a partir de su versión *2.2* introdujo el concepto de :manpage:`capabilities(7)`, cuya filosofía es descomponer el poder para realizar acciones privilegiadas en múltiples capacidades independientes (unas 40 actualmente). cada una de las cuales habilita la realización de determinadas llamadas del núcleo, de modo que si, por ejemplo, se requiere que un proceso cree y configure alguna interfaz de red podemos, simplemente, deberá tener habilitada la capacidad *CAP_NET_ADMIN*, pero no las restantes. Desde el punto de vista de las capacidades, ejecutar un procesos como *root* (que es lo que hace utlizando el *setuid*) equivale a dotar al proceso de todas las capacidades. Profundizaremos en el estudio de las capacidades, también en un :ref:`epígrafe aparte `. .. rubric:: Profundización .. toctree:: :maxdepth: 1 :glob: 10.priv/[0-9]* .. rubric:: Notas al pie .. [#] En las últimas versiones de *Debian* (a partir de *Bookworm*), el instalador permite escoger si se instala :command:`sudo` o no. .. [#] Puede establecerse alguna condicional adicional como el que el usuario pertenezca a un determinado grupo (típicamente *wheel*). .. [#] En realidad, :ref:`su ` permite convertirse en cualquier otro usuario:: $ su - otro_usuario para la cual se requerirá la contraseña de ese otro usuario (a menos que ya seamos el administrador que cambiará de itentidad sin necesidad de contraseña alguna). .. [#] Con la excepción de :program:`polkit` en principio. Pero :program:`polkit` es capaz de conceder privilegios, porque tiene habilitado el *setuid* con lo que una vulnerabilidad en él puede provocar una escalada total de privilegios. Es el caso, por ejemplo, de la vulnerabilidad `CVE-2021-3560 `_ que permitía a un usuario sin privilegios obtener una terminal con privilegios de administrador. .. |UID| replace:: :abbr:`UID (User IDentifier)`