Manera confiable de encarcelar procesos secundarios usando `nsenter:`

15

Sé que los espacios de nombres de Linux, entre muchas otras cosas, se pueden aprovechar para manejar los procesos secundarios de restricción y encarcelamiento de forma segura sin ninguna posibilidad de que se conviertan en zombis y que se los abandone init. Pero tengo dudas sobre los detalles de implementación. ¿Cómo podría usar las herramientas proporcionadas por util-linuxtales como mounty nsenterpara observar, monitorear y asegurar que todos los procesos iniciados sean descendientes directos del espacio de nombres de otro proceso?

mikeserv
fuente

Respuestas:

19

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 en 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 padre (sistema). Sin embargo, dentro del nuevo espacio de nombres, tendrá un PID 1junto con algunas de las características especiales del initproceso. Quizás la característica más relevante desde una perspectiva de monitoreo es que si alguno de sus descendientes queda huérfano, se volverá a criar en este proceso en lugar del initproceso real .

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 padre, 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 seguir 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 cree que tiene. Para hacer esto, y en particular para poder usar el pscomando dentro del nuevo espacio de nombres, debe montar un procfssistema de archivos separado para el espacio de nombres. Esto a su vez conduce a otro problema ya que la única ubicación que psacepta procfses /proc. Una solución sería crear una chrootcárcel y montar la nueva procfsallí. Pero este es un enfoque engorroso ya que, como mínimo, tendríamos que copiar (o al menos un enlace rígido) cualquier binario que pretendamos usar junto con cualquier biblioteca de la que dependan en la nueva raíz.

La solución es utilizar también un nuevo espacio de nombres de montaje . Dentro de esto, podemos montar el nuevo procfsde una manera que use el /procdirectorio raíz verdadero , pueda usarse dentro del espacio de nombres PID y no interfiera con nada más. Para simplificar este proceso, el unsharecomando ofrece la --mount-procopción:

sudo unshare -fp --mount-proc some_command

Ahora ejecutándose psdentro de los espacios de nombres combinados mostrará solo los procesos con el espacio de nombres PID y mostrará que el proceso de nivel superior tiene un PID de 1.

¿Qué hay de nsenter?

Como su nombre lo indica, nsenterse puede usar para ingresar un espacio de nombres que ya se ha creado con unshare. Esto es útil si queremos obtener información solo disponible dentro del espacio de nombres de un script que de otro modo no estaría relacionado. La forma más simple es acceder a dar el PID de cualquier programa que se ejecute dentro del espacio de nombres. Para que quede claro, este debe ser el PID del programa de destino dentro del espacio de nombres desde el que nsenterse ejecuta (dado que los espacios de nombres pueden estar anidados, es posible que un solo proceso tenga muchos PID). Para ejecutar un shell en el espacio de nombres PID / mount de destino, simplemente haga lo siguiente:

sudo nsenter -t $PID -m -p

Si este espacio de nombres está configurado como anteriormente, psahora solo se enumerarán los procesos dentro de ese espacio de nombres.

Graeme
fuente
Gracias Graeme. Esto ya ha respondido la pregunta y más. Lo que realmente me hizo preguntar fue leer las notas de la página de manual de procfs en los diversos archivos en / proc / pid / ns / * que dice: "Enlazar el montaje de este archivo (ver mount (2)) en otro lugar del sistema de archivos mantiene el ... espacio de nombres del proceso especificado por pid vivo incluso si todos los procesos actualmente en el espacio de nombres terminan ". Difícilmente la misma pregunta, lo sé, pero esto ya es tan bueno que pensé que si creías que era relevante, querrás agregarlo. Linux.die.net/man/5/proc
mikeserv
Esto está cubierto en la última sección del artículo LWN (solo busque el montaje de enlace). Sin embargo, no estoy realmente seguro de qué se trata, ya que mantiene vivo el espacio de nombres PID, pero después de que el initproceso de estilo de nivel superior muere, no puedes crear más.
Graeme
Sí, tampoco estoy muy seguro del resto. Pero con esta respuesta y manun fin de semana para mí, quiero familiarizarme un poco más. Gracias de nuevo. Quizás tenga más relevancia en el --user espacio de nombres.
mikeserv