Sé que los espacios de nombres de Linux, entre muchas otras cosas, se pueden aprovechar para manejar la restricción y el encarcelamiento de procesos secundarios de forma segura sin ninguna posibilidad de que se conviertan en zombis y se descarguen en init
. Pero estoy confuso en los detalles de implementación. ¿Cómo puedo usar las herramientas provistas por util-linux
? como mount
y nsenter
para observar, monitorear y asegurarse de que todos los procesos lanzados sean descendientes directos del espacio de nombres de otro proceso?
Respuesta aceptada:
Crear un espacio de nombres PID
El comando correcto para usar aquí es unshare
. Tenga en cuenta que las opciones necesarias para hacer esto solo están disponibles desde util-linux 2.23
. La idea es crear un nuevo espacio de nombres PID para el programa que está ejecutando, de modo que todos sus hijos también se creen en este espacio de nombres. Puede ejecutar un comando en un nuevo espacio de nombres PID simplemente haciendo:
sudo unshare -fp some_command
Para ejecutar un shell, simplemente omita el comando. Esto creará un proceso que, junto con cualquiera de sus elementos secundarios, tendrá un PID como de costumbre dentro del espacio de nombres principal (sistema). Sin embargo, dentro del nuevo espacio de nombres, tendrá un PID de 1
junto con algunas de las características especiales del init
proceso. Quizás la característica más relevante desde la perspectiva de la supervisión es que si alguno de sus descendientes queda huérfano, se volverán a vincular a este proceso en lugar del verdadero init
proceso.
Simplemente hacer esto puede ser suficiente para la mayoría de los casos de monitoreo. Como se mencionó anteriormente, todos los procesos dentro del espacio de nombres tienen PID dentro del espacio de nombres principal, por lo que se pueden usar comandos regulares para monitorear su actividad. También estamos seguros de que si algún proceso en el espacio de nombres queda huérfano, no se caerá de las ramas del árbol de procesos debajo del PID del programa de nivel superior, lo que significa que aún se puede rastrear fácilmente.
Combinar con un espacio de nombres de montaje
Sin embargo, lo que no podemos hacer es monitorear el proceso con respecto al PID que piensa eso es tiene. Para ello, y en particular para poder utilizar el ps
comando dentro del nuevo espacio de nombres, necesita montar un procfs
separado sistema de archivos para el espacio de nombres. Esto a su vez conduce a otro problema ya que la única ubicación que ps
acepta para procfs
es /proc
. Una solución sería crear un chroot
jail y montar el nuevo procfs
allí. Pero este es un enfoque engorroso ya que, como mínimo, necesitaríamos copiar (o al menos vincular) cualquier archivo binario que pretendamos usar junto con las bibliotecas de las que dependen en la nueva raíz.
La solución es usar también un nuevo espacio de nombres de montaje . Dentro de esto podemos montar el nuevo procfs
de una manera que utiliza la verdadera raíz /proc
directorio, se puede utilizar dentro del espacio de nombres PID y no interfiere con nada más. Para hacer este proceso muy simple, el unshare
comando da el --mount-proc
opción:
sudo unshare -fp --mount-proc some_command
Ahora ejecutando ps
dentro de los espacios de nombres combinados, solo se mostrarán los procesos con el espacio de nombres PID y se mostrará que el proceso de nivel superior tiene un PID de 1
.
¿Qué pasa con nsenter
? ?
Como sugiere el nombre, nsenter
se puede usar para ingresar un espacio de nombres que ya se ha creado con unshare
. Esto es útil si queremos obtener información que solo está disponible desde dentro del espacio de nombres de un script que de otro modo no estaría relacionado. La forma más sencilla es acceder al PID de cualquier programa que se ejecute dentro del espacio de nombres. Para que quede claro, debe ser el PID del programa de destino dentro del espacio de nombres desde el que nsenter
se está ejecutando (dado que los espacios de nombres se pueden anidar, es posible que un solo proceso tenga muchos PID). Para ejecutar un shell en el PID de destino/espacio de nombres de montaje, simplemente haga lo siguiente:
sudo nsenter -t $PID -m -p
Si este espacio de nombres está configurado como arriba, ps
ahora enumerará solo los procesos dentro de ese espacio de nombres.