Meterse en la maleza con Buildah: el comando buildah no compartir

A veces, los usuarios se preguntan acerca de las limitaciones del modo sin raíz para los motores de contenedores Buildah y Podman. Con el modo sin raíz, estamos ampliando los límites de lo que puede hacer un usuario sin privilegios. Uno de mis trabajos es trabajar con los equipos del kernel y los equipos del sistema de archivos para mejorar el rootless. En este artículo, explico por qué editar imágenes es más difícil en modo no root.

Índice

Montaje sin raíz

Un usuario normal no puede montar un sistema de archivos a menos que esté en uno propio. Un espacio de nombres de montaje permite que los procesos que contiene monten sistemas de archivos que el espacio de nombres de montaje del host no ve. Esta restricción del kernel protege el sistema operativo host de posibles ataques en los que un usuario podría montar contenido. /tmp o incluso en su directorio de inicio y luego engañar a otros procesos en el sistema o administradores para usar puntos de montaje.

Después de que el proceso de usuario se une al espacio de nombres de usuario y al nuevo espacio de nombres de montaje, el kernel permite que solo se monten ciertos sistemas de archivos. A partir de este escrito, el kernel permite los sistemas de archivos sysfs, procfs, tmpfs, bind mount y fuse. Recientemente recibimos un parche en el kernel upstream para admitir sistemas de archivos superpuestos, lo que será una gran mejora, pero actualmente la mayoría de las distribuciones no tienen este soporte. Me gustaría obtener soporte NFS, pero tiene riesgos de seguridad. Con suerte, el kernel soluciona estos problemas y finalmente obtiene algún soporte.

Los motores de contenedores sin raíz como Podman y Buildah crean automáticamente su propio espacio de nombres de usuario y montan el espacio de nombres cuando se ejecutan. Cuando finaliza el proceso del motor del contenedor, los espacios de nombres de montaje y de usuario desaparecen y el proceso de usuario vuelve al espacio de nombres de montaje del host. En este punto, los montajes creados mientras se ejecutan las herramientas ya no son visibles ni utilizables por otros procesos en el host.

¿Porque es esto importante?

Una de las características interesantes de Buildah es que permite a los usuarios acceder a la semántica de bajo nivel de la construcción de contenedores. La mayoría de los creadores de imágenes de contenedores solo tienen una forma de crear contenedores, principalmente usando Containerfiles o Dockerfiles. Construido bud admite la construcción con estos archivos. Buildah también permite a los usuarios crear contenedores utilizando primitivas de bajo nivel. Los usuarios pueden usarlo para crear un directorio, llenar el directorio con contenido, crear una imagen y enviarla a un registro.

# ctr=$(buildah from scratch)
# mnt=$buildah mount $ctr)
# dnf -y --install-root $mnt httpd 
# buildah config --entrypoint .... $ctr
# buildah commit $ctr IMAGE
# buildah push IMAGE REGISTRY

Todo esto funciona muy bien cuando se ejecuta como root, pero cuando los usuarios intentan ejecutarlo en modo no root, sus scripts explotan.

$ mnt=$(buildah mount $ctr)
cannot mount using driver overlay in rootless mode. You need to run it in a `buildah unshare` session

El problema es mnt=$(buildah mount $ctr) negarse a montar la imagen con el controlador de superposición si no ha ejecutado buildah unshare.

para mirar más de cerca

cuando corres buildah comandos, como bud y run, en modo rootless, el buildah El comando ingresa los espacios de nombres de usuario y montaje. Monta correctamente el sistema de archivos del contenedor y ejecuta los comandos. Cuando el pedido esté completo, buildah termina, lo que hace que se destruyan los espacios de nombres. Cuando haces esto con el mount comando, el sistema de archivos montado nunca se vio en el espacio de nombres de montaje del host. Buildah ahora verifica esta situación y le indica al usuario que emita un buildah unshare primero.

buildah dejar de compartir

Buildah y Podman tienen un comando especial, unshare. Este comando crea e ingresa el espacio de nombres del usuario sin crear ni interactuar con un contenedor. En realidad, es bastante interesante explorar este modo para comprender completamente lo que hace el espacio de nombres del usuario. ejecutar el buildah unshare El comando ejecutará un comando de shell en espacios de nombres que se ejecutan como raíz en el espacio de nombre de usuario. Ahora puede ejecutar cualquier comando, incluido el buildah comandos descritos anteriormente. Dado que estos comandos ya están en espacios de nombres, el buildah mount El comando funcionará igual que en modo root. Todo sucede dentro de los espacios de nombres y el usuario obtiene lo que espera.

Ahora el usuario puede tomar los comandos enumerados anteriormente y crear un script de shell. Este script de shell se ejecuta directamente con el buildah unshare pedido.

$ cat > buildahimage.sh < _EOF
ctr=$(buildah from scratch)
mnt=$buildah mount $ctr)
dnf -y --install-root $mnt httpd 
buildah config --entrypoint .... $ctr
buildah commit $ctr IMAGE
buildah push IMAGE REGISTRY
 < _EOF
chmod +x /buildahimage.sh
buildah unshare ./buildimage.sh

Conclusión

Desafortunadamente, no podemos arreglar todo en el kernel para brindar a los usuarios la experiencia sin root que esperan, principalmente debido a problemas de seguridad. Pero podemos acercarnos bastante. Y, por supuesto, siempre puede trabajar en modo raíz si necesita la funcionalidad adicional.

Artículos de interés

Subir