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 usar chroot
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 en man 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 el pivot_root
. No quieres eso :).
Si usaste el unshare --mount
comando, tenga en cuenta que está documentado para aplicar mount --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ía eject
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 para chroot
.
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 luego umount
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 uso chroot
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:
chdir(new_root); // cd new_root
pivot_root(".", put_old); // pivot_root . put_old
chroot("."); // chroot .
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 que chroot
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 realizar chroot
, puede realizar una copia de seguridad del espacio de nombres del sistema de archivos. Como se detalla en man 2 chroot
, "el superusuario puede escapar de una 'cárcel chroot' por ...".
Otra forma de deshacer la reflexión chroot
es nsenter --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 :-).
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.