Los espacios de nombres son una característica del núcleo de Linux que divide los recursos del núcleo de manera que un conjunto de procesos ve un conjunto de recursos, mientras que otro conjunto de procesos ve un conjunto de recursos diferente. La característica funciona al tener el mismo espacio de nombres para un conjunto de recursos y procesos, pero esos espacios de nombres hacen referencia a recursos distintos. Los recursos pueden existir en múltiples espacios de nombres. Algunos ejemplos de dichos recursos son los identificadores de procesos, los nombres de host, los identificadores de usuarios, los nombres de archivos, algunos nombres asociados con el acceso a la red y la comunicación entre procesos .
Los espacios de nombres son un aspecto necesario para el funcionamiento de los contenedores en Linux. El término "espacio de nombres" se utiliza a menudo para indicar un tipo específico de espacio de nombres (por ejemplo, el identificador de un proceso) así como un espacio de nombres en particular. [1]
Un sistema Linux comienza con un único espacio de nombres de cada tipo, utilizado por todos los procesos. Los procesos pueden crear espacios de nombres adicionales y también pueden unirse a diferentes espacios de nombres.
Los espacios de nombres de Linux se inspiraron en la funcionalidad de espacios de nombres más amplia que se usa ampliamente en Plan 9 de Bell Labs . [2] Los espacios de nombres de Linux se originaron en 2002 en el kernel 2.4.19 con el trabajo en el tipo de espacio de nombres mount. Se agregaron espacios de nombres adicionales a partir de 2006 [3] y se seguirán agregando en el futuro.
La funcionalidad de soporte de contenedores adecuados se completó en la versión 3.8 del kernel [4] [5] con la introducción de los espacios de nombres de usuario. [6]
Desde la versión 5.6 del kernel , existen 8 tipos de espacios de nombres. La funcionalidad de los espacios de nombres es la misma en todos los tipos: cada proceso está asociado a un espacio de nombres y solo puede ver o usar los recursos asociados a ese espacio de nombres y los espacios de nombres descendientes, cuando corresponda. De esta manera, cada proceso (o grupo de procesos del mismo) puede tener una vista única de los recursos. El recurso que se aísla depende del tipo de espacio de nombres que se haya creado para un grupo de procesos determinado.
Los espacios de nombres de montaje controlan los puntos de montaje . Al crearse, los montajes del espacio de nombres de montaje actual se copian al nuevo espacio de nombres, pero los puntos de montaje creados posteriormente no se propagan entre espacios de nombres (si se utilizan subárboles compartidos, es posible propagar puntos de montaje entre espacios de nombres [7] ).
El indicador de clonación que se utiliza para crear un nuevo espacio de nombres de este tipo es CLONE_NEWNS (abreviatura de "NEW NameSpace"). Este término no es descriptivo (no indica qué tipo de espacio de nombres se va a crear) porque los espacios de nombres de montaje fueron el primer tipo de espacio de nombres y los diseñadores no previeron que hubiera otros.
El espacio de nombres PID proporciona a los procesos un conjunto independiente de identificadores de proceso (PID) de otros espacios de nombres. Los espacios de nombres PID están anidados, lo que significa que cuando se crea un nuevo proceso, tendrá un PID para cada espacio de nombres desde su espacio de nombres actual hasta el espacio de nombres PID inicial. Por lo tanto, el espacio de nombres PID inicial puede ver todos los procesos, aunque con PID diferentes a los que verán los procesos otros espacios de nombres.
Al primer proceso creado en un espacio de nombres PID se le asigna el número de identificación de proceso 1 y recibe casi el mismo tratamiento especial que el proceso init normal , en particular que los procesos huérfanos dentro del espacio de nombres se le adjuntan. Esto también significa que la terminación de este proceso PID 1 terminará inmediatamente todos los procesos en su espacio de nombres PID y todos los descendientes. [8]
Los espacios de nombres de red virtualizan la pila de red . Al crearse, un espacio de nombres de red contiene solo una interfaz de bucle invertido . Cada interfaz de red (física o virtual) está presente en exactamente un espacio de nombres y se puede mover entre espacios de nombres.
Cada espacio de nombres tendrá un conjunto privado de direcciones IP , su propia tabla de enrutamiento , lista de sockets , tabla de seguimiento de conexiones, firewall y otros recursos relacionados con la red.
Al destruir un espacio de nombres de red se destruyen todas las interfaces virtuales dentro de él y se mueven todas las interfaces físicas dentro de él de nuevo al espacio de nombres de red inicial.
Los espacios de nombres IPC aíslan a los procesos de la comunicación entre procesos al estilo SysV . Esto evita que los procesos en diferentes espacios de nombres IPC utilicen, por ejemplo, la familia de funciones SHM para establecer un rango de memoria compartida entre los dos procesos. En cambio, cada proceso podrá utilizar los mismos identificadores para una región de memoria compartida y producir dos regiones distintas.
Los espacios de nombres UTS (UNIX Time-Sharing ) permiten que un único sistema parezca tener distintos nombres de host y de dominio para distintos procesos. Cuando un proceso crea un nuevo espacio de nombres UTS, el nombre de host y el dominio del nuevo espacio de nombres UTS se copian de los valores correspondientes en el espacio de nombres UTS del autor de la llamada. [9]
Los espacios de nombres de usuario son una característica que permite aislar privilegios y segregar la identificación de usuarios en varios conjuntos de procesos, y están disponibles desde el kernel 3.8. [10] Con la ayuda de un administrador, es posible crear un contenedor con aparentes derechos administrativos sin dar realmente privilegios elevados a los procesos de usuario. Al igual que el espacio de nombres PID, los espacios de nombres de usuario están anidados y cada nuevo espacio de nombres de usuario se considera un hijo del espacio de nombres de usuario que lo creó.
Un espacio de nombres de usuario contiene una tabla de mapeo que convierte los identificadores de usuario desde el punto de vista del contenedor al punto de vista del sistema. Esto permite, por ejemplo, que el usuario raíz tenga el identificador de usuario 0 en el contenedor, pero que el sistema lo trate como el identificador de usuario 1.400.000 para las comprobaciones de propiedad. Se utiliza una tabla similar para las asignaciones de identificadores de grupo y las comprobaciones de propiedad.
Para facilitar el aislamiento de privilegios de las acciones administrativas, cada tipo de espacio de nombres se considera propiedad de un espacio de nombres de usuario en función del espacio de nombres de usuario activo en el momento de la creación. Un usuario con privilegios administrativos en el espacio de nombres de usuario apropiado tendrá permitido realizar acciones administrativas dentro de ese otro tipo de espacio de nombres. Por ejemplo, si un proceso tiene permiso administrativo para cambiar la dirección IP de una interfaz de red, puede hacerlo siempre que su propio espacio de nombres de usuario sea el mismo que (o antecesor de) el espacio de nombres de usuario que posee el espacio de nombres de red. Por lo tanto, el espacio de nombres de usuario inicial tiene control administrativo sobre todos los tipos de espacios de nombres en el sistema. [11]
El tipo de espacio de nombres cgroup oculta la identidad del grupo de control del que es miembro el proceso. Un proceso en un espacio de nombres de este tipo, que verifique de qué grupo de control forma parte cualquier proceso, vería una ruta que en realidad es relativa al grupo de control establecido en el momento de la creación, ocultando su verdadera posición e identidad en el grupo de control. Este tipo de espacio de nombres existe desde marzo de 2016 en Linux 4.6. [12] [13]
El espacio de nombres de tiempo permite que los procesos vean diferentes horas del sistema de una manera similar al espacio de nombres UTS. Se propuso en 2018 y se lanzó en Linux 5.6, que se lanzó en marzo de 2020. [14]
El espacio de nombres syslog fue propuesto por Rui Xiang, un ingeniero de Huawei , pero no se fusionó con el kernel de Linux. [15] systemd implementó una función similar llamada "espacio de nombres de diario" en febrero de 2020. [16]
El núcleo asigna a cada proceso un enlace simbólico por tipo de espacio de nombres en /proc/<pid>/ns/
. El número de inodo al que apunta este enlace simbólico es el mismo para cada proceso en este espacio de nombres. Esto identifica de forma única cada espacio de nombres por el número de inodo al que apunta uno de sus enlaces simbólicos.
La lectura del enlace simbólico a través de readlink devuelve una cadena que contiene el nombre del tipo de espacio de nombres y el número de inodo del espacio de nombres.
Tres llamadas al sistema pueden manipular directamente los espacios de nombres:
Si ya no se hace referencia a un espacio de nombres, se eliminará; el manejo del recurso contenido depende del tipo de espacio de nombres. Se puede hacer referencia a los espacios de nombres de tres maneras:
/proc/<pid>/ns/<ns-kind>
)/proc/<pid>/ns/<ns-kind>
)Varios software de contenedores utilizan espacios de nombres de Linux en combinación con cgroups para aislar sus procesos, incluidos Docker [17] y LXC .
Otras aplicaciones, como Google Chrome, utilizan espacios de nombres para aislar sus propios procesos que corren el riesgo de sufrir ataques en Internet. [18]
También existe un contenedor para dejar de compartir en util-linux . Un ejemplo de su uso es:
SHELL = /bin/sh dejar de compartir --map-root-user --fork --pid chroot " ${ chrootdir } " " $@ "