Después de leer sobre los espacios de nombres de Linux, tuve la impresión de que son, entre muchas otras características, una alternativa al chroot. Por ejemplo, en este artículo :
Otros usos [de los espacios de nombres] incluyen [...] el estilo de aislamiento chroot () de un proceso a una parte de la jerarquía de directorio único.
Sin embargo, cuando clono el espacio de nombres de montaje, por ejemplo con el siguiente comando, todavía veo todo el árbol raíz original.
unshare --mount -- /bin/bash
Entiendo que ahora puedo realizar montajes adicionales en el nuevo espacio de nombres que no se comparten con el espacio de nombres original y, por lo tanto, esto proporciona aislamiento, pero sigue siendo la misma raíz, por ejemplo, /etc
sigue siendo la misma para ambos espacios de nombres. ¿Todavía necesito chroot
cambiar la raíz o hay una alternativa?
Esperaba que esta pregunta proporcionara una respuesta, pero la respuesta solo usa chroot
, nuevamente.
EDITAR # 1
Hubo un comentario ahora eliminado que menciona pivot_root
. Como esto es realmente parte de linux/fs/namespace.c
, de hecho es parte de la implementación de espacios de nombres. Esto sugiere que cambiar el directorio raíz solo con unshare
y mount
no es posible, pero los espacios de nombres proporcionan una versión propia, más inteligente chroot
. Aún así, no entiendo la idea principal de este enfoque que lo hace fundamentalmente diferente chroot
, incluso después de leer el código fuente (en el sentido de, por ejemplo, seguridad o mejor aislamiento).
EDITAR # 2
Este no es un duplicado de esta pregunta . Después de ejecutar todos los comandos de la respuesta, tengo /tmp/tmp.vyM9IwnKuY (o similar) por separado, ¡pero el directorio raíz sigue siendo el mismo!
pivot_root
ychroot
: eché un vistazo a las fuentes de Docker y descubrí que si falla la ejecuciónpivot_root
, recurre achroot
, es decir, estos mecanismos se consideran al menos similares en funcionalidad para fines de contenedorización.Respuestas:
Ingresar un espacio de nombres de montaje antes de configurar a
chroot
, le permite evitar abarrotar el espacio de nombres de host con montajes adicionales, por ejemplo para/proc
. Puede usarchroot
dentro de un espacio de nombres de montaje como un truco agradable y simple.Creo que la comprensión tiene ventajas
pivot_root
, pero tiene una pequeña curva de aprendizaje. La documentación no explica todo ... aunque hay un ejemplo de uso enman 8 pivot_root
(para el comando de shell).man 2 pivot_root
(para la llamada al sistema) podría ser más claro si hiciera lo mismo e incluyera un programa C de ejemplo.Cómo usar pivot_root
Inmediatamente después de ingresar al espacio de nombres de montaje, también necesita
mount --make-rslave /
o equivalente. De lo contrario, todos los cambios de montaje se propagan a los montajes en el espacio de nombres original, incluido elpivot_root
. No quieres eso :).Si usaste el
unshare --mount
comando, tenga en cuenta que está documentado para aplicarmount --make-rprivate
de manera predeterminada. AFAICS este es un mal valor por defecto y no desea esto en el código de producción. Por ejemplo, en este punto, dejaríaeject
de funcionar en un DVD o USB montado en el espacio de nombres del host. El DVD o USB permanecería montado dentro del árbol de montaje privado, y el núcleo no le permitiría expulsar el DVD.Una vez que haya hecho eso, puede montar, por ejemplo, el
/proc
directorio que usará. De la misma manera que lo harías parachroot
.A diferencia de cuando usas
chroot
,pivot_root
requiere que su nuevo sistema de archivos raíz sea un punto de montaje. Si no lo es ya, puede satisfacer este mediante la simple aplicación de montaje en un aprieto:mount --rbind new_root new_root
.Use
pivot_root
- y luegoumount
el antiguo sistema de archivos raíz, con la opción-l
/MNT_DETACH
. ( No necesitasumount -R
, lo que puede llevar más tiempo ).Técnicamente, usando
pivot_root
generalmente requiere involucrar el usochroot
también; no es "uno u otro".Según
man 2 pivot_root
, solo se define como el intercambio de la raíz del espacio de nombres de montaje. No está definido para cambiar a qué directorio físico apunta la raíz del proceso. O el directorio de trabajo actual (/proc/self/cwd
). Sucede que hace , pero este es un truco para manejar hilos de kernel. La página de manual dice que eso podría cambiar en el futuro.Usualmente quieres esta secuencia:
La posición de la
chroot
en esta secuencia es otro detalle sutil . Aunque el punto depivot_root
es reorganizar el espacio de nombres de montaje, el código del núcleo parece encontrar el sistema de archivos raíz para moverse mirando la raíz por proceso, que es lo quechroot
establece.Por qué usar pivot_root
En principio, tiene sentido usarlo
pivot_root
para seguridad y aislamiento. Me gusta pensar en la teoría de la seguridad basada en capacidades . Usted pasa una lista de los recursos específicos necesarios, y el proceso no puede acceder a otros recursos. En este caso, estamos hablando de los sistemas de archivos pasados a un espacio de nombres de montaje. Esta idea se aplica generalmente a la función de "espacios de nombres" de Linux, aunque probablemente no la estoy expresando muy bien.chroot
solo establece la raíz del proceso, pero el proceso aún se refiere al espacio de nombres de montaje completo. Si un proceso conserva el privilegio de realizarchroot
, puede realizar una copia de seguridad del espacio de nombres del sistema de archivos. Como se detalla enman 2 chroot
, "el superusuario puede escapar de una 'cárcel chroot' por ...".Otra forma de deshacer la reflexión
chroot
esnsenter --mount=/proc/self/ns/mnt
. Este es quizás un argumento más fuerte para el principio.nsenter
/setns()
necesariamente vuelve a cargar la raíz del proceso, desde la raíz del espacio de nombres de montaje ... aunque el hecho de que esto funcione cuando los dos se refieren a directorios físicos diferentes, podría considerarse un error del kernel. (Nota técnica: podría haber varios sistemas de archivos montados uno encima del otro en la raíz;setns()
usa el superior, el más reciente).Esto ilustra una ventaja de combinar un espacio de nombres de montaje con un "espacio de nombres PID". Estar dentro de un espacio de nombres PID le impediría ingresar al espacio de nombres de montaje de un proceso no confinado. También evita que ingrese a la raíz de un proceso no confinado (
/proc/$PID/root
). Y, por supuesto, un espacio de nombres PID también evita que elimine cualquier proceso que esté fuera de él :-).fuente
mount(NULL, "/", NULL, MS_REC|MS_PRIVATE, NULL)
umount -l ./oldroot
pivot_root(".", ".")
truco, que en realidad es la forma más fácil de usarpivot_root
en la mayoría de las circunstancias (no eschroot
necesario).