root uid 0 что это
Все, что вам нужно знать о UID в Linux
Главное меню » Операционная система Linux » Все, что вам нужно знать о UID в Linux
Что такое UID в Linux?
UID обозначает идентификатор пользователя. UID – это номер, назначенный каждому пользователю Linux. Это представление пользователя в ядре Linux.
UID используется для идентификации пользователя в системе и для определения того, к каким системным ресурсам пользователь может получить доступ. Вот почему идентификатор пользователя должен быть уникальным.
Вы можете найти UID в файле /etc/passwd. Это тот же файл, который можно использовать для составления списка всех пользователей в системе Linux.
Используйте команду Linux для просмотра текстового файла, и вы увидите различную информацию о пользователях, присутствующих в вашей системе.
Третье поле здесь представляет идентификатор пользователя или UID.
Обратите внимание, что в большинстве дистрибутивов Linux UID 1-500 обычно зарезервирован для системных пользователей. В Ubuntu и Fedora UID для новых пользователей начинаются с 1000.
Например, если вы используете команду useradd или adduser для создания нового пользователя, он получит следующий доступный номер после 1000 в качестве своего UID.
Как найти UID пользователя в Linux?
Вы всегда можете положиться на файл /etc/passwd, чтобы получить UID пользователя. Это не единственный способ получить информацию UID в Linux.
Команда id в Linux отобразит UID, GID и группы, к которым принадлежит ваш текущий пользователь:
Вы также можете указать имена пользователей с помощью команды id, чтобы получить UID любого пользователя Linux:
Как изменить UID пользователя в Linux?
Предположим, у вас было несколько пользователей в вашей системе Linux. Вы должны были удалить пользователя, потому что он/она покинул организацию. Теперь вы хотите, чтобы его UID был занят другим пользователем, уже находящимся в системе.
Вы можете изменить UID, изменив пользователя с помощью команды usermod следующим образом:
Вы должны иметь привилегию суперпользователя для выполнения вышеуказанной команды.
Вы помните концепцию прав доступа и владения файлами в Linux? Право собственности на файл определяется UID пользователя-владельца.
Когда вы обновляете UID пользователя, что происходит с файлами, принадлежащими этому пользователю? В то время как все файлы в домашнем каталоге user_2 изменят свой связанный UID, вам придется вручную обновить связанный UID других файлов вне домашний каталог.
Что вы можете сделать, это вручную обновить владельца файлов, связанных со старым UID пользователя_2.
Вот и все. Мы надеемся, что теперь у вас есть лучшее представление об UID в Linux. Не стесняйтесь задавать свои вопросы, если таковые имеются.
Как профессиональный пользователь Linux, если вы думаете, что мы пропустили какое-то важное понятие об UID, пожалуйста, дайте мне знать в разделе комментариев.
Если вы нашли ошибку, пожалуйста, выделите фрагмент текста и нажмите Ctrl+Enter.
Записки IT специалиста
Технический блог специалистов ООО»Интерфейс»
У каждого файла обязательно есть владелец и группа, которой он принадлежит. На этой схеме строится классическая система прав в Linux и UNIX: владелец, группа и остальные. Более подробно о ней вы можете прочитать в предыдущих частях нашего цикла:
Таким образом пользователи и группы определяют доступ не только к файлам в привычном нам понимании, но и ко всему спектру объектов операционной системы: процессам, устройствам, сокетам. Просто запомните, что все есть файл, а каждый файл имеет владельца и группу.
Давайте рассмотрим его структуру подробнее. Каждая строка соответствует одному пользователю и имеет следующий формат:
С именем пользователя все понятно, а вот второй параметр может вызвать некоторое недоумение. Когда-то давно пароли хранились в открытом виде, о чем намекает само название файла, но затем от этой практики отказались и современные системы не хранят пароли в каком-либо виде вообще, хранится только сформированный по специальному алгоритму хеш, такие пароли в Linux называются затененными ( shadow). Для такого пароля во втором поле всегда ставится символ x.
Этим часто пользуются злоумышленники, один из типовых сценариев проникновения предусматривает создание пользователя с неприметным именем, но идентификаторами root, что позволяет действовать в системе от имени суперпользователя не привлекая ненужного внимания.
В реальных сценариях данную возможность использовать не следует, так как наличие таких пользователей может вызвать конфликты в системе. Например, Gnome 3 в Debian 10 просто отказался загружаться после того, как мы создали такого пользователя.
В поле комментарий можно написать все что угодно, определенного формата в современных системах нет, но исторически данное поле называется GECOS и подразумевает перечисление через запятую следующих опций:
Следующие два поля указывают на домашнюю директорию пользователя и его командную оболочку. Разным пользователям можно назначить разные командные оболочки, скажем, ваш коллега предпочитает zsh, то вы можете без проблем назначить ему любимую оболочку.
Рассмотрение командных оболочек Linux выходит за рамки данной статьи, поэтому мы оставим эту тему, но расскажем о двух специализированных «оболочках», которые указывают, когда пользователю запрещен интерактивный вход в систему. Это обычно применяется для служб и пользователей от имени которых исполняются некоторые скрипты. Даже если такая учетная запись будет скомпрометирована войти в консоль с ней не удастся.
Обычно для этой цели используется:
В современных системах директория /sbin является символической ссылкой на /usr/sbin. Реже используется «оболочка»:
Разница между ними заключается в том, что /bin/false просто запрещает вход в систему, а /sbin/nologin выдает сообщение:
Предупреждение! Данная команда уничтожает корневую файловую систему, что приводит к ее полной неработоспособности и потере всех данных. Приведена сугубо в качестве примера.
Современные дистрибутивы по умолчанию блокируют выполнение явно деструктивных команд, но не запрещают их, все это выглядит как предупреждение: «так делать опасно, но если ты настаиваешь. «
С учетом вышесказанного есть ряд сложившихся правил работы с этим пользователем. Во-первых, не следует выполнять из-под учетной записи суперпользователя повседневную работу. Для разовых действий используйте sudo, для административных работ допустимо временно повышать привилегии с последующим обязательным выходом. Во-вторых, доступ к данной учетной записи должен быть тщательно ограничен, потому как утеря контроля над root равносильно полной потере контроля над системой.
Существует соглашение, что этот диапазон идентификаторов используется только системными службами и в нем не должно быть обычных пользователей. Однако никто не мешает назначить службе UID выше 1000, а пользователю менее 999, но никаких последствий это иметь не будет и никак не скажется на привилегиях. Это разделение чисто условное и предназначено для повышения удобства администрирования. Встретив в незнакомой системе пользователя с UID до 999, вы будете с большой долей вероятности предполагать, что это служба.
Но это тоже условность, скажем в отсутствии установленного веб-сервера мы можем назначить «зарезервированный» UID другому пользователю без каких-либо последствий, веб-сервер при установке возьмет ближайший свободный UID, но такие действия безусловно являются дурным тоном.
Многое стороннее ПО, например, сервер 1С и сборки PostgresPro занимают ближайшие свободные идентификаторы с верхнего конца диапазона: 999, 998 и т.д.
Из всего изложенного выше вы должны понимать, что система определяет пользователей по идентификаторам, а не по именам, а присвоение идентификаторов регулируется определенными правилами, но никакие из них, кроме двух специальных (0 для root и 65534 для nobody), не дают каких-либо дополнительных прав или привилегий.
Для более гибкого управления пользователями предназначены группы, они позволяют объединять пользователей по любому произвольному принципу и назначать им дополнительные права. Если мы хотим разрешить пользователю повышение прав, то мы включаем его в группу sudo, при этом мы всегда можем легко узнать, кто именно обладает такой возможностью, достаточно посмотреть участников группы.
Посмотреть список групп можно в файле /etc/group
Он имеет следующий формат:
После того как мы добавим пользователей в группу они будут перечислены в последнем поле через запятую.
Давайте внимательно посмотрим на скриншот и проанализируем членство созданного при установке пользователя andrey в дополнительных группах. Практически все они связанны с доступом к оборудованию или дают возможность использовать некоторые системные механизмы, скажем группа plugdev предоставляет возможность монтировать съемные устройства.
В современных системах, при работе в графических средах доступ к оборудованию часто предоставляется механизмами рабочей среды, которые не используют разделение прав на основе членства пользователя в соответствующих группах. Поэтому, если вы используете стандартные механизмы дистрибутива, то для полноценного использования оборудования вам нет необходимости включать пользователя в дополнительные группы. Однако это может потребоваться при работе в консоли или при использовании нестандартных или специализированных устройств в графической среде.
Синтаксис этого файла предусматривает девять полей, содержащих следующую информацию:
Наибольший интерес представляет второе поле, содержащее хеш пароля, оно имеет структуру:
В современных системах используется наиболее стойкий хеш SHA-512.
Соль позволяет исключить атаки при помощи заранее вычисленных значений и при ее случайном значении позволяет скрыть наличие у пользователей одинаковых паролей. На скриншоте выше пользователям ivan и maria были установлены одинаковые пароли, но за счет различной соли они имеют различный хеш.
Для групп используется аналогичный по назначению файл /etc/gshadow
Его структура более проста, а поля имеют следующее назначение:
Поле пароля также может содержать спецсимволы и также как для пользователей символ * используется преимущественно для системных групп, а ! для групп пользователей. По умолчанию пароли групп отсутствуют и вход в них заблокирован, т.е. никто, кроме членов группы, не может войти в группу, а членам пароль не нужен.
Так как данные о пользователях являются критичными для системы, то указанные выше файлы крайне не рекомендуется изменять вручную, а для управления пользователями и группами следует использовать специальные утилиты, о которых мы поговорим в следующей части. При любом изменении информации в них штатными инструментами система создает резервную копию предыдущей версии файла с добавлением в конце имени символа
Поэтому даже если что-то пойдет не так, всегда есть возможность (при условии физического доступа к системе) восстановить состояние этих файлов на момент перед внесением изменений в конфигурацию. В качестве примера приведем следующую ситуацию: вы случайно удалили единственного пользователя с административными правами из группы sudo, root при этом заблокирован, после завершения сеанса в системе не останется ни одного привилегированного пользователя.
Дополнительные материалы:
Помогла статья? Поддержи автора и новые статьи будут выходить чаще:
Или подпишись на наш Телеграм-канал:
Does the root account always have UID/GID 0?
On all the Linux systems I’ve managed, the root account has a GID and UID of 0. Is this guaranteed, or is it possible that the system will give root a different ID?
4 Answers 4
There are actually two parts to your question.
Does the superuser account always have uid/gid 0/0 on Linux?
Yes. As is pointed out by Rich Homolka in a comment, there’s code in the kernel which explicitly checks for uid 0 when needing to check for the root user, which means that root always has at least uid 0.
It’s also worth noting that, as pointed out by Simon Richter, on BSDs there often exists a second uid 0 account, by convention named toor (which is «root» spelled backwards, and also lexically comes after root in a list sorted alphabetically). For example, FreeBSD uses it to provide a root user with a customized shell setting, leaving the root user with a default shell which is guaranteed to exist on the system’s root partition (useful for recovery purposes).
1) the administrator is always uid == 0. This is coded in the kernel. It would take some coding in the kernel to change this. There’s not much point to this, so it’s not done. For example, it would be inconsistent for other unixes sharing the same NFS for example.
2) uid 0 does not necessarily map to root. The best example is FreeBSD. It has two uid == 0 accounts, the difference being the shell. root has shell /bin/sh, which is a simple shell, useful for when your disks are bad and you need fsck /usr. toor uses tcsh, which is much more useful in non-emergency situations,since it has things like history, etc.
Another, more personal example; one job I had where they had a root equiv (i.e. uid=0) account over NIS. The password, blank! Because the new sysadmin couldn’t remember the root password on the machines. I yelled about this for obvious reasons (NIS passwords by definition can not hide their blankness). I was not happy about this account.
And it really isn’t the system that gives uid 0 is root, it’s you. You change this my using passwd files, or other naming directories (NIS, ldap) but it’s not compiled in. Though you should have at least one uid 0 account in /etc/passwd, since you may not have networking when you really need it.
So root is always uid 0, but uid 0 is not necessarily always root.
Основы безопасности операционной системы Android. Native user space, ч.2
Вступление
Сегодня я продолжу рассматривать безопасность на уровне немного выше ядра. Во второй части мы рассмотрим, откуда появляются system.img, userdata.img и cache.img, а также как обеспечивается безопасность в Native user space.
Всем кому интересно, добро пожаловать!
Список статей
Что подразумевается под Native user space
Под Native user space подразумеваются все компоненты пространства пользователя, которые выполняются вне Dalvik Virtual Machine, и которые не являются частью Linux kernel. Native user space — это исполняемые файлы, скомпилированные под определенную архитектуру. К ним относятся исполняемые файлы, которые запускаются из init скрипта автоматически или в случае наступления какого-либо события, toolbox утилиты, а также некоторые исполняемые файлы, которые пользователь может запустить из-под shell.
Начало
Как я уже рассказывал в первой части, в основе Android лежит Linux kernel. Как и во всех Linux системах, в основе безопасности Android лежит access control. Т.е. каждый ресурс (например, файл) содержит мета-информацию о том, кто создал этот файл — owner (владелец) — и к какой основной группе (owner group) принадлежит owner (владелец). Каждый процесс запускается от имени какого-то user (пользователя). У каждого пользователя есть основная группа. Кроме того он может являться членом других групп. Таким образом, если к каждому ресурсу прикрепить информацию (в формате rwxrwxrwx) о том, кто может читать/писать/исполнять ресурс (например, файл), то можно контролировать доступ к этому файлу. Например, файлу можно назначить разрешения: что может делать с этим файлом owner (владелец) этого файла; что могут делать пользователи, которые входят в состав owner group; что могут творить все остальные. Здесь об этом можно почитать подробнее.
Но у Android есть некоторые отличия. Во-первых, изначально Android — это операционная система для телефонов, которые, как известно, относятся к очень личным вещам и которые мы не любим давать в чужие руки. То есть она была задумана как операционная система, у которой только один пользователь. Поэтому было принято решение использовать различных Linux users для обеспечения безопасности (для каждого приложения — отдельный пользователь, как я уже рассказывал в первой статье). Во-вторых, в Android некоторые user (пользователи) и их UID (идентификаторы) были жестко запрограммированы в систему, что вызывает очень много нареканий людей связанных с безопасностью (хотя я, если честно, не очень понимаю, почему критикуется такой подход). Мы уже видели этих пользователей в файле system/core/include/private/android_filesystem_config.h Например, root имеет идентификатор 0, а system — 1000.
Как я уже отмечал, процесс запускается от имени того же пользователя (UID), что и процесс, который запускает этот новый процесс, т.е. UID(calling_process) == UID (called_process). Первый процесс, который запускается в Android — init — запускается от имени root (UID == 0). Таким образом, по-идее, все процессы также должны быть запущены от имени того же пользователи. Так оно, наверное, бы и было. Но, во-первых, процессы, запущенные от имени привилегированного пользователя (а так же те, кто обладает определенными capabilities), могут изменять свой UID на менее привилегированный. А во-вторых, в Android при запуске демонов в init.rc скрипте так же можно указать, с привилегиями какого пользователя и каких групп запускать данный процесс.
Все процессы, которые будут запущены через этих демонов, уже не будут иметь root привилегии.
System, data и cache
Я столько раз анонсировал эту тему, что можно было подумать, что она очень сложная и запутанная. На самом деле, это не так. System.img, userdata.img и cache.img — то, что получается в результате компиляции операционной системы Android. То есть в результате сборки системы получаются эти три файла, которые мы и записываем на наше устройство.
Но самое важно здесь не это. Благодаря тому, что в Android системе user name и UID системных пользователей жестко запрограммированы, уже на этапе компиляции мы можем определить права доступа различных системных пользователей к различным директориям в данных образах. Эти права доступа указаны в файле system/core/include/private/android_filesystem_config.h, который мы уже рассматривали в первой статье. Права доступа определяются отдельно для директорий (android_dirs[]) и отдельно для файлов (android_files[]) следующим образом:
А функция static inline void fs_config(const char *path, int dir, unsigned *uid, unsigned *gid, unsigned *mode, uint64_t *capabilities), которая определена дальше в этом файле отвечает за выставление owner, owner group, capabilities и прав доступа. Эта функция вызывается во время сборки образа.
В общем здесь всё должно быть более-менее понятно, за исключением установки флагов прав доступа (setuid и setgid) для некоторых файлов (например, для «system/xbin/su» права доступа определены как 06755, где первая 6 означает, что выставлен флаг установки ID пользователя (4) и флаг установки ID группы (2)). Установка этих флагов означает, что пользователь может повысить права запускаемого процесса до уровня owner (владельца) файла или owner group (группы владельца). В случае Android, каждое приложение — это пользователь со своими UID и GID. Таким образом, по умолчанию если вы из своего приложения запускаете какой-нибудь native executable, он исполняется с теми же UID и GID, как и приложение его вызвавшее. Установка данных флагов прав доступа позволяет выполнить native executable с правами владельца. В нашем случае, владелец — AID_ROOT (root). Происходит это следующим обрзазом system/extras/su/su.c:
Т.е. вызываются функции setuid и setgid. В этом случае, если данные функции выполнились успешно, то процесс начинает работать от имени owner и owner group данного файла. В нашем примере, данный процесс получает права суперпользователя, т.е. он может делать всё, что ему пожелается 🙂 Подобная анархия не всегда оправдана, поэтому в Linux ввели понятие capabilities. Так приложению «run-as» не нужны всё права суперпользователя, ему достаточно иметь возможность только менять свой идентификатор, чтобы запускать приложения от имени различных пользователей. Кстати, capabilities похоже появились недавно — в Android 2.3.x я их не встречал.
Безопасность
В случае привилегированных программ (типа, su) необходимо ограничивать круг приложений, которые могут вызывать эти программы. В противном случае любое приложение может получить права суперпользователя. Поэтому очень часто в такие программы встраивают проверку по UID:
Т.е. программа вначале проверяет, от чьего имени запущен вызывающий процесс, используя функцию getuid(). А потом сравнивает эти значения со значениями, которые жестко запрограммированы в систему. В данном случае, только процессы запущенные от имени пользователей «system» и «root» имеют право использовать su.
Заключение
В данной статье мы закончили разбирать, как обеспечивается безопасность на уровне Native user space. В следующих статьях я планирую разобрать, как работают permission (разрешения), но в связи с большой текущей загрузкой не знаю, когда приступлю к их написанию. Как всегда, буду очень рад дополнениям и исправлениям.
Глубокое погружение в Linux namespaces, часть 2
В предыдущей части мы только окунули пальцы ног в воды namespace и при этом увидели, как это было просто — запустить процесс в изолированном UTS namespace. В этом посте мы осветим User namespace.
Среди прочих ресурсов, связанных с безопасностью, User namespaces изолирует идентификаторы пользователей и групп в системе. В этом посте мы сосредоточимся исключительно на ресурсах user и group ID (UID и GID соответственно), поскольку они играют фундаментальную роль в проведении проверок разрешений и других действий во всей системе, связанных с безопасностью.
В Linux эти ID — просто целые числа, которые идентифицируют пользователей и группы в системе. И каждому процессу назначаются какие-то из них, чтобы задать к каким операциями/ресурсам этот процесс может и не может получить доступ. Способность процесса нанести ущерб зависит от разрешений, связанных с назначенными ID.
User Namespaces
Мы проиллюстрируем возможности user namespaces, используя только пользовательские ID. Точно такие же действия применимы к групповым ID, к которым мы обратимся далее в этому посте.
User spaces могут быть вложенными! Это означает, что экземпляр пользовательского namespace (родительский) может иметь ноль и больше дочерних пространств имён, и каждое дочернее пространство имён может, в свою очередь, иметь свои собственные дочерние пространства имён и так далее… (до достижения предела в 32 уровня вложенности). Когда создаётся новый namespace C, Linux устанавливает текущий User namespace процесса P, создающего C, как родительский для C и это не может быть изменено впоследствии. В результате все user namespaces имеют ровно одного родителя, образуя древовидную структуру пространств имён. И, как и в случае с деревьями, исключение из этого правила находится наверху, где у нас есть корневой (или начальный, дефолтный) namespace. Это, если вы еще не делаете какую-то контейнерную магию, скорее всего user namespace, к которому принадлежат все ваши процессы, поскольку это единственный user namespace с момента запуска системы.
В этом посте мы будем использовать приглашения командной строки P$ и C$ для обозначения шела, который в настоящее время работает в родительском P и дочернем C user namespace соответственно.
Маппинги User ID
User namespace, по сути, содержит набор идентификаторов и некоторую информацию, связывающую эти ID с набором ID других user namespace — этот дуэт определяет полное представление о ID процессов, доступных в системе. Давайте посмотрим, как это может выглядеть:
Информация, связывающая UID из одного user namespace с другим, называется маппингом user ID. Он представляет из себя таблицы поиска соответствия ID в текущем user namespace для ID в других namespace и каждый user namespace связан ровно одним маппингом UID (в дополнение еще к одному маппингу GID для group ID).
Map-файлы
Давайте это попробуем:
Хорошо, это было не очень захватывающе, так как это были два крайних случая, но это говорит там о нескольких вещах:
Написание UID Map файлов
Чтобы исправить наш вновь созданный user namespace C, нам просто нужно предоставить наши нужные маппинги, записав их содержимое в map-файлы для любого процесса, который принадлежит C (мы не можем обновить этот файл после записи в него). Запись в этот файл говорит Linux две вещи:
Например, если мы из родительского user namespace P запишем следующее в map-файл для дочернего пространства имён C:
мы по существу говорим Linux, что:
Владелец пространств имён и привилегии
В предыдущем посте мы упомянули, что при создании новых пространств имён требуется доступ с уровнем суперпользователя. User namespaces не налагают этого требования. На самом деле, еще одной их особенностью является то, что они могут владеть другими пространствами имён.
Владелец пространств имён важен потому, что процесс, запрашивающий выполнения привилегированного действия над ресурсом, задействованным не user namespace, будет иметь свои UID привилегии, проверенные в отношении владельца этого user namespace, а не корневого user namespace. Например, скажем, что P является родительским user namespace дочернего C, а P и C владеют собственными network namespace M и N соответственно. Процесс может не иметь привилегий для создания сетевых устройств, включенных в M, но может быть в состоянии это делать для N.
К сожалению, мы повторно применим требование прав суперпользователя в следующем посте, так как isolate нуждается в привилегиях root в корневом user namespace, чтобы корректно настроить Mount и Network namespace. Но мы обязательно отбросим привилегии командного процесса, чтобы убедиться, что команда не имеет ненужных разрешений.
Как разрешаются ID
Групповые ID
Реализация
Как вы можете видеть, есть много сложностей, связанных с управлением user namespaces, но реализация довольно проста. Всё, что нам нужно сделать, это написать кучу строк в файл — муторно было узнать, что и где писать. Без дальнейших церемоний, вот наши цели:
И вызовем его из основного процесса в родительском user namespace прямо перед тем, как мы подадим сигнал командному процессу.
И это всё! isolate теперь запускает процесс в изолированном user namespace.
В этом посте было довольно много подробностей о том, как работают User namespaces, но в конце концов настройка экземпляра была относительно безболезненной. В следующем посте мы рассмотрим возможность запуска команды в своём собственном Mount namespace с помощью isolate (раскрывая тайну, стоящую за инструкцией FROM из Dockerfile ). Там нам потребуется немного больше помочь Linux, чтобы правильно настроить инстанс.