Compartir grupos adicionales con contenedores Podman

Desarraigado Podman Contenedores es una función realmente genial que permite a los usuarios ejecutar casi cualquier contenedor en su directorio de inicio sin necesidad de privilegios adicionales.
Los contenedores sin root aprovechan el espacio de nombres del usuario, como expliqué en este blog.
A veces, el espacio de nombres de usuario y otras capas de seguridad del contenedor como SELinux hacen que sea más difícil compartir contenido dentro del contenedor. Hemos visto muchos usuarios que quieren compartir directorios del sistema en sus contenedores, pero fallan con errores de permisos. Estos directorios generalmente se comparten a través del acceso grupal, lo que permite al usuario leer/escribir contenido en los directorios.
Por ejemplo, el usuario puede tener un directorio /mnt/engineering
en su sistema, que pertenece a root
y grupo eng
y con permisos establecidos en 770.
Echemos un vistazo a un ejemplo.
Añade el eng
grupo:
# groupadd eng
Cree el directorio compartido:
# mkdir /var/lib/mycontainers/
Cambie el acceso de grupo para el directorio:
# chown root:eng /var/lib/mycontainers/
Cambie los permisos para que el grupo pueda escribir en el directorio:
# chmod 770 /mnt/engineering
Cambie el tipo SELinux del directorio para que los contenedores puedan usarlo:
# chcon -t container_file_t /mnt/engineering
A continuación, veamos los permisos en el directorio:
# ls -lZ /mnt/engineering/ -d
drwxrwx---. 2 root eng unconfined_u:object_r:user_tmp_t:s0 40 Feb 9 07:24 /mnt/engineering/
El usuario ahora se puede agregar a la eng
grupo:
$ grep eng /etc/group
Eng:x:14905:dwalsh
Inicie sesión en el sistema y asegúrese de que el usuario esté en el eng
grupo:
$ id
uid=3267(dwalsh) gid=3267(dwalsh) groups=3267(dwalsh),10(wheel),14905(eng) context=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023
Asegúrese de que el usuario pueda leer/escribir contenido en el directorio:
$ touch /mnt/engineering/test
$ ls -l /mnt/engineering/
total 0
-rw-------. 1 dwalsh dwalsh 0 Feb 9 07:36 test
Ahora ejecute un contenedor usando este volumen, pero se deniega el permiso del contenedor:
$ podman run --userns=keep-id -v /mnt/engineering/:/mnt/engineering ubi8 ls /mnt/engineering/
ls: cannot open directory '/mnt/engineering/': Permission denied
Como sabemos que SELinux no está bloqueando ya que hemos definido correctamente la etiqueta, ¿qué pasó?
espacio de nombre de usuario
El problema es el espacio del nombre de usuario.
$ podman run --userns=keep-id -v /mnt/engineering/:/mnt/engineering ubi8 id
uid=3267(dwalsh) gid=3267(dwalsh) groups=3267(dwalsh)
Tenga en cuenta que el --userns=keep-id
bandera se utiliza para garantizar que el UID dentro del contenedor no sea root sino el UID normal del usuario. Note arriba que cuando ejecuto el id
pedido fuera del contenedor, mis grupos incluyen el eng
grupo, pero cuando se ejecuta el contenedor, el eng
el grupo no se muestra. Desde una perspectiva de seguridad, esto es bueno porque si los procesos del contenedor escaparan, no tendrían acceso a los directorios a los que tengo acceso de grupo. Si los usuarios quieren otorgar acceso, tienen un problema.
El problema es que es difícil otorgar acceso de contenedor a estos directorios. creación de un eng
grupo dentro del contenedor no coincidiría con el eng
group en el host porque el espacio de nombres del usuario compensa el UID real del grupo.
Afortunadamente, el tiempo de ejecución de OCI crun
admite una función especial para asustar a esos grupos adicionales en el contenedor. Esta capacidad está cubierta por la podman run
página man:
man podman run
...
Note: if the user only has access rights via a group, accessing the de‐
vice from inside a rootless container will fail. The crun(1) runtime
offers a workaround for this by adding the option --annotation
run.oci.keep_original_groups=1.
Y explicado con más detalle en el crun
página man:
man crun
…
run.oci.keep_original_groups=1
If the annotation run.oci.keep_original_groups is present, then crun
will skip the setgroups syscall that is used to either set the addi‐
tional groups specified in the OCI configuration, or to reset the list
of additional groups if none is specified.
Si configuro esta anotación, mi Podman sin root ahora tiene acceso al volumen como se muestra a continuación:
$ podman run -ti --annotation run.oci.keep_original_groups=1 --userns=keep-id -v /mnt/engineering/:/mnt/engineering ubi8 ls /mnt/engineering/
-rw-------. 1 dwalsh dwalsh 0 Feb 9 12:36 test
Usamos una anotación porque la especificación de OCI actualmente no tiene forma de indicar el entorno de tiempo de ejecución de OCI. Sugerimos agregarlo a las especificaciones. Por el momento, ningún otro OCI Runtime que no sea crun
puede manejar esto incluyendo runc
. Tal vez en el futuro esta función se agregue al OIC.
contenedores.conf
Si el usuario desea que todos sus contenedores compartan grupos de usuarios, puede agregar esta anotación al Contenedores.conf
en sus directorios de inicio.
$ cat ~/.config/Contenedores/Contenedores.conf
[containers]
annotations=["run.oci.keep_original_groups=1",]
Ahora, incluso el Podman predeterminado puede crear contenido en el volumen y los procesos de usuario fuera del contenedor ven el contenido correcto.
$ podman run -ti --userns=keep-id -v /mnt/engineering/:/mnt/engineering ubi8 touch /mnt/engineering/test2
$ ls -l /mnt/engineering/
total 0
-rw-------. 1 dwalsh dwalsh 0 Feb 9 07:36 test
-rw-r--r--. 1 dwalsh dwalsh 0 Feb 9 13:36 test2
Conclusión
Algunas funciones de seguridad del contenedor pueden bloquear el uso compartido del contenido del host en un contenedor mediante el montaje de un volumen. Afortunadamente Podman y crun
tener una funcionalidad avanzada para permitir que contenedores específicos compartan este contenido y Contenedores.conf
permite a los usuarios configurar su sistema en todos los contenedores para acceder a estos volúmenes.
Artículos de interés