Пространства имен — это функция ядра Linux , которая разделяет ресурсы ядра таким образом, что один набор процессов видит один набор ресурсов, в то время как другой набор процессов видит другой набор ресурсов. Функция работает, имея одно и то же пространство имен для набора ресурсов и процессов, но эти пространства имен ссылаются на разные ресурсы. Ресурсы могут существовать в нескольких пространствах имен. Примерами таких ресурсов являются идентификаторы процессов, имена хостов, идентификаторы пользователей, имена файлов, некоторые имена, связанные с сетевым доступом, и межпроцессное взаимодействие .
Пространства имен являются обязательным аспектом функционирования контейнеров в Linux. Термин «пространство имен» часто используется для обозначения определенного типа пространства имен (например, идентификатора процесса), а также для определенного пространства имен. [1]
Система Linux начинается с одного пространства имен каждого типа, используемого всеми процессами. Процессы могут создавать дополнительные пространства имен, а также могут присоединяться к различным пространствам имен.
Пространства имен Linux были вдохновлены более широкой функциональностью пространств имен, широко используемой в Plan 9 от Bell Labs . [2] Пространства имен Linux возникли в 2002 году в ядре 2.4.19 с работой над типом пространства имен mount. Дополнительные пространства имен были добавлены, начиная с 2006 года [3] и продолжались в будущем.
Адекватная функциональность поддержки контейнеров была завершена в версии ядра 3.8 [4] [5] с введением пространств имен пользователя. [6]
Начиная с версии ядра 5.6, существует 8 видов пространств имен. Функциональность пространств имен одинакова для всех видов: каждый процесс связан с пространством имен и может видеть или использовать только ресурсы, связанные с этим пространством имен, и дочерние пространства имен, где это применимо. Таким образом, каждый процесс (или его группа процессов) может иметь уникальный вид на ресурсы. Какой ресурс изолирован, зависит от вида пространства имен, созданного для данной группы процессов.
Пространства имен монтирования управляют точками монтирования . После создания монтирования из текущего пространства имен монтирования копируются в новое пространство имен, но созданные впоследствии точки монтирования не распространяются между пространствами имен (используя общие поддеревья, можно распространять точки монтирования между пространствами имен [7] ).
Флаг клонирования, используемый для создания нового пространства имен этого типа, — CLONE_NEWNS — сокращение от "NEW NameSpace". Этот термин не является описательным (он не говорит, какой тип пространства имен должен быть создан), поскольку пространства имен монтирования были первым типом пространства имен, и проектировщики не предполагали, что будут какие-либо другие.
Пространство имен PID предоставляет процессам независимый набор идентификаторов процессов (PID) из других пространств имен. Пространства имен PID являются вложенными, то есть при создании нового процесса у него будет PID для каждого пространства имен от текущего пространства имен до начального пространства имен PID. Следовательно, начальное пространство имен PID может видеть все процессы, хотя и с другими PID, чем те, с которыми будут видеть процессы другие пространства имен.
Первому процессу, созданному в пространстве имен PID, назначается номер идентификатора процесса 1, и он получает большую часть той же специальной обработки, что и обычный процесс init , в частности, к нему присоединяются осиротевшие процессы в пространстве имен. Это также означает, что завершение этого процесса PID 1 немедленно завершит все процессы в его пространстве имен PID и любых потомков. [8]
Сетевые пространства имен виртуализируют сетевой стек . При создании сетевое пространство имен содержит только интерфейс обратной связи . Каждый сетевой интерфейс (физический или виртуальный) присутствует ровно в 1 пространстве имен и может перемещаться между пространствами имен.
Каждое пространство имен будет иметь частный набор IP-адресов , собственную таблицу маршрутизации , список сокетов , таблицу отслеживания соединений, брандмауэр и другие сетевые ресурсы.
Уничтожение сетевого пространства имен уничтожает все виртуальные интерфейсы внутри него и перемещает все физические интерфейсы внутри него обратно в исходное сетевое пространство имен.
Пространства имен IPC изолируют процессы от межпроцессного взаимодействия в стиле SysV . Это не позволяет процессам в разных пространствах имен IPC использовать, например, семейство функций SHM для установления диапазона общей памяти между двумя процессами. Вместо этого каждый процесс сможет использовать одни и те же идентификаторы для области общей памяти и создавать две такие различные области.
Пространства имен UTS (UNIX Time-Sharing ) позволяют одной системе иметь разные имена хостов и доменов для разных процессов. Когда процесс создает новое пространство имен UTS, имя хоста и домен нового пространства имен UTS копируются из соответствующих значений в пространстве имен UTS вызывающего. [9]
Пространства имен пользователей — это функция, которая обеспечивает как изоляцию привилегий, так и сегрегацию идентификации пользователей по нескольким наборам процессов, доступная с версии ядра 3.8. [10] С помощью администратора можно создать контейнер с кажущимися административными правами, фактически не предоставляя повышенных привилегий пользовательским процессам. Как и пространство имен PID, пространства имен пользователей являются вложенными, и каждое новое пространство имен пользователей считается дочерним элементом пространства имен пользователей, которое его создало.
Пространство имен пользователя содержит таблицу сопоставления, преобразующую идентификаторы пользователей с точки зрения контейнера в точку зрения системы. Это позволяет, например, пользователю root иметь идентификатор пользователя 0 в контейнере, но фактически рассматривается системой как идентификатор пользователя 1 400 000 для проверки права собственности. Похожая таблица используется для сопоставления идентификаторов групп и проверки права собственности.
Для облегчения изоляции привилегий административных действий каждый тип пространства имен считается принадлежащим пользовательскому пространству имен на основе активного пользовательского пространства имен на момент создания. Пользователю с административными привилегиями в соответствующем пользовательском пространстве имен будет разрешено выполнять административные действия в пределах этого другого типа пространства имен. Например, если у процесса есть административное разрешение на изменение IP-адреса сетевого интерфейса, он может это сделать, пока его собственное пользовательское пространство имен совпадает с (или является предком) пользовательского пространства имен, которому принадлежит сетевое пространство имен. Следовательно, исходное пользовательское пространство имен имеет административный контроль над всеми типами пространств имен в системе. [11]
Тип пространства имен cgroup скрывает идентификацию контрольной группы , членом которой является процесс. Процесс в таком пространстве имен, проверяющий, к какой контрольной группе относится любой процесс, увидит путь, который на самом деле относится к контрольной группе, установленной во время создания, скрывая его истинную позицию и идентификацию контрольной группы. Этот тип пространства имен существует с марта 2016 года в Linux 4.6. [12] [13]
Пространство имен time позволяет процессам видеть различные системные времена аналогично пространству имен UTS. Оно было предложено в 2018 году и выпущено в Linux 5.6, который был выпущен в марте 2020 года. [14]
Пространство имен syslog было предложено Руи Сяном, инженером Huawei , но не было объединено с ядром Linux. [15] systemd реализовал похожую функцию под названием «пространство имен журнала» в феврале 2020 года. [16]
Ядро назначает каждому процессу символическую ссылку на тип пространства имен в /proc/<pid>/ns/
. Номер инода, на который указывает эта символическая ссылка, одинаков для каждого процесса в этом пространстве имен. Это уникально идентифицирует каждое пространство имен по номеру инода, на который указывает одна из его символических ссылок.
Чтение символической ссылки через readlink возвращает строку, содержащую имя типа пространства имен и номер инода пространства имен.
Три системных вызова могут напрямую манипулировать пространствами имен:
Если на пространство имен больше нет ссылок, оно будет удалено, обработка содержащегося ресурса зависит от типа пространства имен. На пространства имен можно ссылаться тремя способами:
/proc/<pid>/ns/<ns-kind>
)/proc/<pid>/ns/<ns-kind>
)Различные контейнерные программы используют пространства имен Linux в сочетании с контрольными группами для изоляции своих процессов, включая Docker [17] и LXC .
Другие приложения, такие как Google Chrome, используют пространства имен для изоляции собственных процессов, которые подвергаются риску атак в Интернете. [18]
Также есть unshare wrapper в util-linux . Пример его использования:
ОБОЛОЧКА = /bin/sh unshare --map-root-user --fork --pid chroot " ${ chrootdir } " " $@ "