¿Debería usar el indicador --user en contenedores sin raíz?

En una reciente Problema de GitHub en libpod, un usuario de Podman sugirió que los contenedores sin raíz eliminan la necesidad de --user opción cuando se ejecutan contenedores. Asumieron que el --user La opción provino de Docker para poder ejecutar un contenedor como un usuario diferente. Dado que, para empezar, Podman sin root se ejecuta en modo sin root, la necesidad de la opción quedó obsoleta.

Ellos estaban equivocados.

Encuesta UID

Sin raíces y arraigado Podman cada medio trabajando con múltiples usuarios. Ambos, de forma predeterminada, ejecutan el proceso inicial como la raíz del espacio de nombres de usuario en el que se inician. Cuando ejecuta contenedores sin raíz, inicia el primer proceso como la raíz del espacio de nombres de usuario que está utilizando. En un blog anterior, Entendiendo la raíz dentro y fuera del contenedor, profundicé en lo que está pasando aquí.

Si observara el proceso desde fuera del contenedor, vería que se está ejecutando como UID.

$ podman run fedora cat /proc/self/uid_map
    0    3267      1
    1    100000    65536

Mi UID es 3267, y puede ver que la asignación de espacio de nombres de usuario asigna UID 0 a 3267 para un rango de 1 UID. Otra forma de ver esto es usar podman top para mostrar al usuario dentro del contenedor y al usuario host.

$ podman run -d fedora sleep 100
 41ad82a732526673299d6785105e1b4a0ef4397ed7ceb8b13b9218e2f3a77003

$ podman top -l user huser
 USER HUSER
 root 3267

Si desea ejecutar con otro usuario en el contenedor, utilice -u para seleccionar el usuario. Cuando se ejecuta en modo no rooteado, el contenedor raíz es más poderoso que el contenedor no raíz, por lo que siempre es recomendable ejecutar como no raíz en un contenedor sin raíz.

Incluso en contenedores sin raíz, la raíz del contenedor tiene un espacio de nombres de usuario. Estas capacidades son una subsección del poder de root sobre el espacio de nombres del usuario.

$ podman top -l capeff
EFFECTIVE CAPS
AUDIT_WRITE,CHOWN,DAC_OVERRIDE,FOWNER,FSETID,KILL,MKNOD,NET_BIND_SERVICE,NET_RAW,SETFCAP,SETGID,SETPCAP,SETUID,SYS_CHROOT

Como puede ver, el proceso sin raíz tiene muchas capacidades. Incluso puedes correr --privileged y obtener todas las características. Pero estas habilidades no son las mismas que obtienes como root; son habilidades. Tienen control total sobre los espacios de nombres mapeados en el contenedor, pero no tienen poder sobre otras partes del sistema operativo.

Por ejemplo, el contenedor tiene CAP_SETUID. Esto permite que el proceso raíz cambie su UID a cualquier otro UID dentro del contenedor. En el caso anterior, puede cambiar el UID del proceso a cualquier UID de 100000 a 165535, así como volver a 3267. No se permite que el proceso raíz cambie a uid(0) ni a ningún otro UID del sistema. Se eliminan algunas características como CAP_SYS_ADMIN. CAP_NET_ADMIN solo puede manipular el espacio de nombres de red de los contenedores, no de los hosts.

Ahora veamos qué sucede cuando ejecuto el contenedor con el --user bandera.

$ podman run --user 1000 -d fedora sleep 10
976d7f3f034d38657cfba60aef406e7f65eae9eef735619ca7c13f8a946a0122

$ podman top -l user huser
USER HUSER
1000 100999

Puede ver que el proceso del contenedor se ejecuta como UID 1000 dentro del contenedor, pero en realidad se ejecuta como UID 100999 en el host.

Ahora vemos que el contenedor no tiene capacidad y está bloqueado.

$ podman top -l capeff
EFFECTIVE CAPS
none

Siempre que su contenedor no necesite root, siempre recomiendo usar el --user oportunidad de mejorar aún más la seguridad.

Usando la marca --userns=keep-id

Como un apéndice, Podman sin root tiene otra opción interesante: --userns=keep-id.

el keep-id La opción le dice a Podman que cree un espacio de nombres de usuario donde el UID:GID sin raíz del usuario actual coincida con los mismos valores en el contenedor. Cuando se lanza el contenedor, se ejecuta como su UID dentro del contenedor y en el host. Muchos entornos de computación de alto rendimiento (HPC) usan este indicador y ejecutan todo el contenedor con un único UID no raíz.

$ podman run --userns keep-id -d fedora sleep 100
319813af33af1f54d2a6a4c00eeb1100dec36e8ba9d4bef76846d0e0dd54a6b8

$ podman top -l user huser
USER HUSER
3267 103266

Desafortunadamente, escribir este blog reveló un error en podman top, mostrando el usuario de host incorrecto (por ejemplo, HUSER). si uso el ps orden, veo que el sleep se está ejecutando en el host como UID. Abrí un tema para corregir el error. Gracias a Giuseppe Scrivano, el error se solucionó en la próxima versión de Podman.

$ ps -ef | grep sleep
dwalsh 198080 198069 1 10:57 ? 00:00:00 sleep 100

Dado que el proceso del contenedor principal es mi UID, ya no tiene capacidades de root.

$ podman top -l capeff
EFFECTIVE CAPS
none

Dependiendo de la configuración del contenedor, los procesos del contenedor pueden usar setuid y setfcap herramientas como su y sudo para obtener funcionalidad adicional, como una sesión de inicio de sesión normal. Caja de herramientas Fedora usar Podman con el keep-id opción oculta para dar acceso a los usuarios a diferentes entornos de sistemas operativos.

Uno de los posibles problemas que encuentran los usuarios es cuando especifican un UID grande en contenedores sin root. Recuerde que al usuario de Podman sin root solo se le asigna un número limitado de UID, como se define en el /etc/subuid archivar. Por lo general, solo puede usar 65536 UID. Esto significa que si intenta iniciar un contenedor sin root con UID > 65536, el contenedor fallará. Si necesita iniciar con un UID más grande, debe cambiar el /etc/subuid para incluir el UID que desea utilizar.

$ podman run --user 70000 fedora id -u
Error: container_linux.go:346: starting container process caused "setup user: invalid argument": OCI runtime error

$ podman run --user 65536 fedora id -u
65536

Conclusión

el --user La opción sigue siendo muy necesaria y agrega mucha seguridad incluso cuando se usa Podman sin root, y los usuarios siempre deben usarla para estar lo más seguros posible.

[ Getting started with containers? Check out this free course. Deploying containerized applications: A technical overview. ]

Artículos de interés

Subir