Recientemente, el equipo de Podman recibió un informe de Bugzilla que afirmaba que no había forma de evitar que Podman sin root ejecutara contenedores. El reportero configuró una cuenta de usuario sin entradas en /etc/subuid
y /etc/subgid
e informó que Podman desarraigado aún podía ejecutar hello-world
contenedor.
Suposición errónea
Eliminando la información del usuario de /etc/subuid
no impide que los usuarios utilicen Podman. Analicemos más a fondo lo que sucede cuando alguien usa Podman sin raíz para ejecutar un contenedor.
Primero, tenga en cuenta que las imágenes de contenedor como hello-world
son solo tarballs junto con algún contenido JSON que se encuentra en un servidor web llamado registro de imágenes de contenedor. Cualquier aplicación que pueda hablar con un servidor web puede bajarlos utilizando protocolos web estándar y herramientas como curl
.
Cuando Podman baja una imagen, primero crea e ingresa un espacio de nombres de usuario. Este espacio de nombres de usuario generalmente asigna el UID del usuario a la raíz (UID =0) dentro del espacio de nombres de usuario. Luego busca en /etc/subuid
para el usuario y usa los UID enumerados allí para completar el resto de los UID disponibles dentro del espacio de nombres del usuario. Hace lo mismo para grupos a través de /etc/subgid
. Si no hay entradas en /etc/subuid
y /etc/subgid
, entonces el espacio de nombres del usuario consiste solo en el UID del usuario asignado como raíz. Una vez que se configura el espacio de nombres de usuario, Podman extrae el contenido tar de la imagen. Si la imagen tiene archivos que pertenecen a otros usuarios que no sean UID=0, Podman extrae e intenta chown
el contenido al usuario y grupo definidos. Si el usuario y el grupo no están definidos dentro del espacio de nombres de usuario, entonces el chown
falla y Podman falla.
En el ejemplo de Bugzilla, el reportero intentó ejecutar hello-world
.
$ podman run hello-world
Resolved "hello-world" as an alias (/etc/containers/registries.conf.d/000-shortnames.conf)
Trying to pull docker.io/library/hello-world:latest...
Getting image source signatures
Copying blob b8dfde127a29 done
Copying config d1165f2212 done
Writing manifest to image destination
Storing signatures
Hello from Docker!
…
Funcionó aunque el usuario no tenía entradas en /etc/subuid
y /etc/subgid
.
Ingresemos el espacio de nombres de usuario y veamos qué está pasando.
Podman unshare cat /proc/self/uid_map
0 3267
Aviso, mi cuenta está configurada sin acceso en /etc/subuid
. Podman está asignando mi UID 3267 a UID 0 para un rango de UID. Ahora veamos el contenido de la imagen del contenedor hello-world
. Ingrese el espacio de nombres de usuario, monte el hello-world
imagen y enumere los contenidos.
$ podman unshare
# mnt=$(podman image mount hello-world)
# ls -l $mnt
total 16
-rwxrwxr-x. 1 root root 13336 Mar 5 18:25 hello
Observe que el único contenido es el hello
dominio. Este es un binario GO enlazado estáticamente, propiedad de root dentro del espacio de nombres de usuario y UID=3267 en mi directorio de inicio.
Esta es la razón por la que el comando funcionó, incluso sin los UID y GID adicionales.
Intentemos ejecutar una imagen de contenedor con más de un UID.
$ podman run fedora echo hi
Resolved "fedora" as an alias (/etc/containers/registries.conf.d/000-shortnames.conf)
Trying to pull registry.fedoraproject.org/fedora:latest...
Getting image source signatures
Copying blob 7679c09af385 done
Copying config 3567369c67 done
Writing manifest to image destination
Storing signatures
Error: Error committing the finished image: error adding layer with blob "sha256:7679c09af3851a1622782c74864351c296a0d1886813862fd7116383aeba9f07": Error processing tar file(exit status 1): potentially insufficient UIDs or GIDs available in user namespace (requested 0:12 for /var/spool/mail): Check /etc/subuid and /etc/subgid: lchown /var/spool/mail: invalid argument
Observe que Podman puede extraer los tarballs (se refiere a ellos como blobs). Cuando intenta extraerlos, falla cuando intenta chown
el /var/spool/mail
directorio a un GID (12) no definido dentro del espacio de nombres de usuario, y el contenedor falla.
Conclusión
Ejecutar contenedores sin privilegios es seguro y realmente no puede afectar al sistema más que tener un inicio de sesión en el sistema. El usuario de Podman realiza tareas que los usuarios normales pueden hacer:extraer contenido de los servidores web y descomprimirlos. Finalmente, los usuarios pueden incluso ejecutar el contenido. Las únicas fallas ocurren cuando el usuario intenta cambiar a UID que el usuario no tiene permitido a través de comandos como chown
o su
.
En el ejemplo anterior, Podman no hizo nada que requiriera privilegios adicionales. Todos los procesos ejecutados a través de Podman por el usuario estaban bajo las mismas restricciones que cualquier proceso de usuario. En realidad, están más restringidos ya que están envueltos con SELinux, SECCOMP y otros mecanismos de seguridad.
El uso de Podman sin raíz para ejecutar una imagen de contenedor no es menos seguro que permitir que los usuarios descarguen archivos ejecutables de un servidor web y los ejecuten en su directorio de inicio.
Si aún desea evitar que ciertos usuarios de un sistema ejecuten Podman, debe cambiar los permisos en Podman.
# chmod 750 /usr/bin/podman
# groupadd podman
# chown root:podman /usr/bin/podman
Agregue los usuarios a los que desea permitir el acceso a Podman al grupo de podman. Solo tenga en cuenta que cuando Podman se actualice, deberá hacer chmod
y chown
comandos de nuevo, y rpm -qV podman
informará problemas con la instalación.
Crédito adicional
Para usuarios avanzados, específicamente personas en computación de alto rendimiento (HPC), agregamos un indicador especial, ignore_chown_errors
, al almacenamiento del contenedor.
man storage.conf
…
ignore_chown_errors = "false"
ignore_chown_errors can be set to allow a non privileged user running with a single UID within a user namespace to run containers. The user can pull and use any image, even those with multiple uids. Note multiple UIDs will be squashed down to the default uid in the container. These images will have no separation between the users in the container. (default: false)
Estableciendo esta bandera en /etc/containers/storage.conf
de $HOME/.config/containers/storage.conf
a verdadero, Podman puede ejecutar con éxito el contenedor de Fedora.
$ grep ignore_chown_err /etc/containers/storage.conf
# ignore_chown_errors can be set to allow a non privileged user running with
ignore_chown_errors = "true"
$ podman unshare cat /proc/self/uid_map
0 3267 1
$ podman run fedora echo hi
Resolved "fedora" as an alias (/etc/containers/registries.conf.d/000-shortnames.conf)
Trying to pull registry.fedoraproject.org/fedora:latest...
Getting image source signatures
Copying blob 7679c09af385 done
Copying config 3567369c67 done
Writing manifest to image destination
Storing signatures
hi
Esta vez, cuando Podman intentó chown
el /var/spool/mail
directorio y recibió un error, lo ignoró y continuó. HPC no quiere que los usuarios tengan más de un UID, por lo que esto les permite ejecutar imágenes OCI estándar sin tener que aflojar la configuración de seguridad en absoluto. Tenga en cuenta que esto funciona bien siempre que el único UID que ejecute dentro del contenedor sea la raíz del contenedor. Si, por algún motivo, el proceso intenta cambiar el UID a un UID no definido dentro del contenedor, fallará. Además, en la mayoría de los casos, todos los archivos de la imagen serán propiedad del usuario. Ese usuario del contenedor tiene permisos completos de lectura/escritura en todo el contenido.
[ ¿Empezando con los contenedores? Consulta este curso gratuito. Implementación de aplicaciones en contenedores:una descripción técnica general. ]
Resumir
Los administradores de Podman deben saber qué niveles de acceso se otorgan. Asegúrese de comprender la intención y la función de /etc/subuid
y /etc/subgid
y cómo afectarán a la seguridad de los contenedores.
Finalmente, use el ignore_chown_errors
opción con cuidado. Fue diseñado para escenarios de HPC.