Uso de archivos y dispositivos en contenedores Podman Rootless

Un problema clave Podman Los usuarios acceden a archivos y dispositivos que pueden usar desde el host, pero que no pueden usar mientras están en un contenedor, incluso si toman el volumen de los objetos en el contenedor.

En este caso, veremos el acceso de grupo adicional. A menudo, los sistemas están configurados con archivos y dispositivos a los que solo pueden acceder grupos de usuarios específicos. Por ejemplo, estoy en el rueda en mi sistema, lo que permite a mi usuario acceder a algunos controles administrativos. Los administradores pueden configurar un directorio para que lo compartan varios usuarios en el sistema creando el fra grupo, agregando usuarios a fra grupo, luego autorizando al fra grupo para tener un directorio rwx permisos Ahora todos los usuarios de fra puede leer y escribir el directorio.

Recientemente recibimos un problema en el que un usuario tenía problemas para dar acceso a un dispositivo GPU en su sistema.

Agregaría el dispositivo usando un comando como:

$ podman run --device /dev/video0 …

Notar: En contenedores sin raíz, los usuarios sin raíz no pueden crear nuevos dispositivos al agregar un dispositivo a un contenedor. Por lo tanto, Podman solo vincula el dispositivo contenedor al host. En modo rootfull, se crea un nuevo dispositivo al que tienen acceso los procesos dentro del contenedor.

El volumen de Podman se asienta /dev/video0, pero cada vez que el usuario intenta usar el dispositivo en el contenedor, falla. Sin embargo, cuando revisó el dispositivo en el host y los grupos de los que era miembro, todo parecía correcto. Por ejemplo:

$ ls -l /dev/video0
crw-rw----+ 1 root video 81, 0 May  3 14:06 /dev/video0
$ groups
dwalsh video

Puede hacer pleno uso del dispositivo fuera de los contenedores. Darse cuenta de que el proceso del contenedor no está en el video grupo, luego pensó en agregar el video grupo al contenedor para obtener acceso. Intentó este comando:

$ podman run --group-add video --device /dev/video0 …

Pero siempre fallaba con eso.

Índice

    Qué pasó?

    cuando usas --group-add video, agrega el video grupo definido dentro de la imagen del contenedor al proceso principal del contenedor, así:

    $ grep video /etc/group
    video: 39:  
    
$ podman run --group-add video fedora id
uid=0(root) gid=0(root) groups=0(root),39(video)


    Dentro del contenedor, el proceso tiene un grupo 39, pero es lo mismo que el grupo 39 en el anfitrión. Cuando ejecuta contenedores sin raíz, utiliza el espacio de nombres de usuario para que el grupo se compense con el espacio de nombres de usuario al que se unió. Aquí está el espacio de nombres:

    $ podman unshare cat /proc/self/gid_map
0 3267 1
1 100000 65536


    Esto significa que el video el grupo dentro del contenedor será GID 100038 en el anfitrión. Echale un vistazo a éste ejemplo:

    $ ctr=$(podman run -d --group-add video fedora sleep 100)
    $ pid=$(podman top -l hpid | tail -1)
    $ grep Groups /proc/$pid/status
     Groups:    100038

    Para acceder al dispositivo de video en el host, el proceso necesita una ID = 39, por lo que falla. Los usuarios sin root no pueden forzar el acceso a real ID = 39 en el host ya que las protecciones estándar de Linux lo bloquean.

    Podman al rescate

    Desde Podman 3.2, hemos agregado una nueva característica, --group-add keep-groups, que funciona con el entorno de tiempo de ejecución de OCI crun. Normalmente, cuando inicia un contenedor Podman, el entorno de tiempo de ejecución de OCI ejecuta el establecer grupos llamada al sistema; esto cambia el proceso principal dentro del contenedor para obtener los grupos definidos en el contenedor y también elimina el acceso a los grupos de procesos principales. Normalmente, esto es lo que desea hacer, ya que no desea que un proceso escapado de un contenedor tenga acceso a su rueda grupo, por ejemplo.

    cuando corres con --group-add keep-groups, el entorno de tiempo de ejecución del contenedor OCI (crun) no llama al establecer grupos, para que el nuevo proceso contenedor mantenga los grupos de su proceso padre. Si el proceso principal tiene acceso a ID = 39, los procesos dentro del contenedor aún tendrán este grupo y podrán usar el dispositivo.

    
$ podman run --device /dev/video0 --group-add keep-group …

    ¡Y todo funciona!

    Apéndice

    Tenga en cuenta que dentro del contenedor, el GID 39 no está mapeado, por lo que los procesos en el contenedor lo verán como el cualquiera grupo. Se parece a esto:

    $ ./bin/podman run --group-add keep-groups fedora groups
    root nobody

    Las versiones anteriores de Podman tienen una interfaz menos fácil de usar para activar este comportamiento en crun. Al agregar el --annotation run.oci.keep_original_groups=1, crun no correrá setgroups.

    $ podman run --annotation run.oci.keep_original_groups=1 --device /dev/video0

    Si está utilizando el --group-add keep-groups llamada, no puede definir otros grupos en el contenedor. En cambio, el contenedor solo puede heredar grupos del padre. La razón es que Podman necesita el setgroups llame para definir grupos adicionales en el contenedor y perderá el acceso a los grupos principales. Giuseppe Scrivano propuso dos parches permitir setgroups en esta situación. Este enfoque aún está en discusión. Giuseppe también abrió una publicar con el especificaciones de tiempo de ejecución para convertirlo en una parte formal de la especificación e integrarlo en otros entornos de tiempo de ejecución de oci como runc, pero aún no se ha fusionado.

    Conclusión

    Los usuarios de Podman tienen problemas para acceder a archivos y dispositivos en un contenedor incluso cuando tienen acceso a esos recursos en el host. Hemos analizado casos de uso en los que se expone este problema y discutido algunas de las correcciones ofrecidas para resolver el problema.

    Artículos de interés

    Subir