
Введение
Это вторая часть серии о Linux для DevOps и DevSecOps. В прошлой части мы разобрали файловую систему, навигацию и поиск — если вы только начинаете изучать Linux или хотите освежить память, загляните в «Linux: Файлы, навигация и поиск». В этой части я попытался расписать довольно кратко, т.к. информации и так много и тот же новичок может не сразу всё выучить. Приступаем.
Как Linux идентифицирует пользователя
Username vs UID
Ядро Linux работает исключительно с числами. UID (User Identifier) — числовой идентификатор пользователя (обычно 32-битный). Имя пользователя (username) — лишь человекочитаемый псевдоним, который инструменты вроде ls или ps подставляют при выводе, обращаясь к /etc/passwd.
Если удалить пользователя и создать нового с тем же именем, но другим UID — новый пользователь не получит доступ к старым файлам. Права привязаны к UID, а не к имени. А вот если вы привяжете к тому же UID — получит доступ к старым файлам. Вроде очевидно, но учитывайте этот момент.
Основные атрибуты пользователя
Атрибут | Описание | Пример |
|---|---|---|
username | Имя для входа и отображения |
|
UID | Числовой идентификатор |
|
GID | Первичная группа |
|
home | Домашний каталог |
|
shell | Интерактивная оболочка |
|
GECOS | Комментарий (имя, телефон, …) |
|
Быстрая диагностика
Первое, что можно сделать при входе на незнакомый сервер — проверить себя:
# Полная информация: uid, gid, все группы id # uid=1001(deployer) gid=1001(deployer) groups=1001(deployer),27(sudo),998(docker) # Только UID / GID id -u id -g # Только имя пользователя whoami # Полная запись из /etc/passwd getent passwd deployer # deployer:x:1001:1001:Deploy Bot,,:/home/deployer:/bin/bash # Группа getent group docker # docker:x:998:deployer,ci
getentпредпочтительнее прямого чтения/etc/passwd, потому что он учитывает LDAP, NIS и другие NSS-источники — корректно работает в корпоративной среде.
Модель доступа: пользователь → система
«Всё есть файл»
Каждый объект в Linux — файл, директория, устройство, сокет — имеет владельца (owner) и группу (group). Это метаданные хранятся прямо в inode.
ls -la /var/log/nginx/ # drwxr-xr-x 2 root adm 4096 Mar 26 09:00 . # -rw-r----- 1 www-data adm 187234 Mar 26 10:41 access.log # -rw-r----- 1 www-data adm 1204 Mar 26 07:22 error.log # # Структура строки: # тип+права links owner group size дата имя
Упрощённая модель проверки прав
процесс (UID/GID) → owner? → group? → others
Ядро идёт слева направо и останавливается на первом совпадении. Если UID процесса совпадает с owner файла — применяются только права owner, права group уже не проверяются.
Подробный разбор битов
rwx, SUID/SGID/Sticky bit и ACL — в следующей статье «Права доступа».
Виды пользователей
Диапазоны UID
Диапазон | Тип |
|---|---|
| root — суперпользователь. Обходит большинство проверок прав доступа, но не все |
| Системные пользователи — сервисы и демоны. Без интерактивного входа. |
| Обычные пользователи — реальные люди. |
| nobody — минимальное доверие. NFS, sshd, sandbox-изоляция. |
Диапазоны настраиваются в /etc/login.defs:
UID_MIN 1000 UID_MAX 60000 SYS_UID_MIN 201 SYS_UID_MAX 999 CREATE_HOME yes PASS_MIN_LEN 8
(обычно: системные <1000, обычные ≥1000)
Системные пользователи и nologin
Сервисы типа nginx, postgres, redis работают от имени собственного системного пользователя. У таких пользователей в качестве shell прописан /usr/sbin/nologin или /bin/false — интерактивный вход заблокирован.
# Посмотреть системных пользователей (UID < 1000) awk -F: '$3 < 1000 && $3 > 0 {print $1, $3, $7}' /etc/passwd # Специфические просмотры(для инструментов и др.) # daemon 1 /usr/sbin/nologin # www-data 33 /usr/sbin/nologin # postgres 117 /bin/bash ← исключение: нужен для psql # nginx 998 /sbin/nologin
root и nobody — крайности спектра
root (UID 0) — полный контроль над системой. Ядро не проверяет права доступа. Может монтировать ФС, загружать модули ядра, убивать любые процессы, читать любые файлы. При компрометации — полная потеря системы.
nobody (UID 65534) — минимальные привилегии. Не владеет ни одним файлом. Используется как «безопасный» контекст для untrusted-кода: NFS-маппинг, CGI-процессы, sandbox-изоляция.
nobody = 65534 — не всегда (может быть nfsnobody / UID может отличаться)
Группы
Зачем нужны группы
Группы — механизм коллективного доступа. Вместо раздачи прав каждому пользователю индивидуально, достаточно добавить нужных людей в группу и выдать права группе. Классический пример: группа docker открывает доступ к сокету Docker без sudo.
Первичная и дополнительные группы
Тип | Хранится в | Назначение |
|---|---|---|
Primary (GID) |
| GID новых создаваемых файлов. Одна на пользователя. |
Supplementary |
| Дополнительные права. Ограничение зависит от системы (обычно десятки тысяч). |
Проверка членства
# Все группы текущего пользователя groups # deployer sudo docker adm # То же с GID id # uid=1001(deployer) gid=1001(deployer) groups=1001(deployer),27(sudo),998(docker) # Группы конкретного пользователя groups maria # Все члены группы docker getent group docker # docker:x:998:deployer,maria,ci-bot
Где хранится информация
/etc/passwd — реестр пользователей
Читаемый всеми файл. Пароля здесь нет — поле пароля содержит x, хеш находится в /etc/shadow.
deployer : x : 1001 : 1001 : Deploy Bot,, : /home/deployer : /bin/bash 1 2 3 4 5 6 7
Поле | Содержимое |
|---|---|
1 | Username |
2 | Пароль — всегда |
3 | UID |
4 | GID (первичная группа) |
5 | GECOS — комментарий (имя, телефон, …) |
6 | Домашний каталог |
7 | Логин-шелл |
По поводу
x: когда-то давно пароль мог храниться здесь в зашифрованном виде, но такая концепция не была признана безопасной.
Раньше хеш пароля реально хранился прямо в /etc/passwd. Файл был:
читаем всеми — потому что нужен для работы системы (UID → username)
В итоге любой пользователь мог читать хеши и пытаться их брутфорсить офлайн. Поэтому позже была введена система shadow passwords: поле пароля в /etc/passwd заменили на x, а сами хеши перенесли в защищённый файл /etc/shadow, доступный только root.
/etc/shadow — хеши паролей
Доступен только root (и группе shadow). Содержит хеш пароля с солью и параметры устаревания.
deployer:$6$rounds=5000$xPwF...$kE9...hash...:19800:0:99999:7:::
Поле | Описание |
|---|---|
|
|
| Дата последней смены (дни с 1970-01-01) |
| Мин. дней до следующей смены |
| Макс. срок действия (99999 ≈ никогда) |
| Предупреждение за N дней до истечения |
| Заблокированный аккаунт |
Можно еще уточнить что формат хеша в /etc/shadow зависит от системы и настроек тк используется не везде(следует уточнять в зависимости от ОС)
/etc/group
docker : x : 998 : deployer,ci-bot 1 2 3 4
Поле | Содержимое |
|---|---|
1 | Название группы |
2 | Пароль группы (всегда |
3 | GID |
4 | Список supplementary-пользователей |
/etc/gshadow
Хеши паролей групп и список администраторов групп. Нужен ~редко — актуален при использовании newgrp с паролем.
Безопасное редактирование
Никогда не редактируйте
/etc/passwd,/etc/shadow,/etc/groupнапрямую через nano или vim. При параллельном изменении возможна гонка условий и повреждение файла.
vipw # редактировать /etc/passwd (с блокировкой и валидацией) vipw -s # редактировать /etc/shadow vigr # редактировать /etc/group vigr -s # редактировать /etc/gshadow # После ручного редактирования — проверить целостность pwck # проверка /etc/passwd и /etc/shadow grpck # проверка /etc/group и /etc/gshadow
Создание пользователей
useradd — параметры
Ключ | Описание | Пример |
|---|---|---|
| Создать домашний каталог |
|
| Логин-шелл |
|
| Дополнительные группы (через запятую) |
|
| Первичная группа (GID или имя) |
|
| Явно задать UID |
|
| Комментарий (GECOS) |
|
| Путь к home (если не стандартный) |
|
| Дата истечения аккаунта (YYYY-MM-DD) |
|
| Системный пользователь (UID из sys-диапазона) |
|
| Базовый каталог (вместо |
|
| Каталог-шаблон вместо |
|
| Дней неактивности после устаревания пароля до блокировки |
|
# Создать обычного пользователя с home и bash useradd -m -s /bin/bash ivan # Пользователь для CI/CD — без home, с nologin useradd -r -s /usr/sbin/nologin -c "CI Bot" ci-bot # Разработчик с несколькими группами useradd -m -s /bin/bash -G sudo,docker,adm -c "Maria Ivanova" maria # Сервисный пользователь с нестандартным home useradd -r -m -d /var/lib/prometheus -s /usr/sbin/nologin prometheus
Установка пароля
# Интерактивно (запросит дважды) passwd ivan # В скриптах — через chpasswd echo 'ivan:secretpass' | chpasswd # Сгенерировать случайный пароль NEW_PASS=$(openssl rand -base64 16) echo "ivan:${NEW_PASS}" | chpasswd echo "Пароль: ${NEW_PASS}" # сохрани в менеджер! # Принудить сменить пароль при первом входе passwd -e ivan
Что происходит под капотом при useradd -m
Запись в
/etc/passwdЗапись в
/etc/shadow(заблокирована до установки пароля)Запись в
/etc/group(создаётся одноимённая primary-группа)mkdir /home/usernamecp -r /etc/skel/* /home/usernamechown -R user:user /home/username
Окружение пользователя
/etc/skel — шаблонные файлы
При создании пользователя с флагом -m содержимое /etc/skel копируется в home. Удобный механизм для стандартизации окружения.
ls -la /etc/skel/ # .bash_logout .bashrc .profile # Добавить корпоративный .gitconfig для всех новых пользователей cat > /etc/skel/.gitconfig <<'EOF' [core] autocrlf = input editor = vim [pull] rebase = true EOF
Глобальные настройки
Файл | Описание |
|---|---|
| Дефолты для |
| Диапазоны UID/GID, политика паролей, umask, HOME_MODE |
| Env-переменные для всех пользователей при логин-сессии |
| Модульные скрипты из |
| Глобальный bashrc для интерактивных шеллов (Debian/Ubuntu) |
umask — права по умолчанию
umask — маска, вычитаемая из максимальных прав при создании файлов и директорий. Максимум для файлов — 666, для директорий — 777.
# Посмотреть текущую маску umask # 0022 # Расчёт: файл 666 & ~022 = 644 (rw-r--r--) # дирек 777 & ~022 = 755 (rwxr-xr-x) touch test.txt && ls -l test.txt # -rw-r--r-- 1 deployer deployer 0 Mar 26 12:00 test.txt # Поменять для текущей сессии umask 027 # файлы: 640, директории: 750 # Глобально — в /etc/login.defs: # UMASK 022 # Для PAM — в /etc/pam.d/common-session: # session optional pam_umask.so umask=002
ℹ️
umaskработает как побитовая маска исключения:666 & ~022 = 644. Простое вычитание при нестандартных значениях даст неверный результат.
Изменение пользователей
usermod
# Изменить логин-шелл usermod -s /bin/zsh ivan # Переименовать пользователя usermod -l ivan-petrov ivan # Изменить домашний каталог (с перемещением файлов) usermod -d /home/ivan-petrov -m ivan-petrov # Установить дату истечения usermod -e 2025-12-31 contractor # Сменить первичную группу usermod -g developers ivan-petrov # Добавить в дополнительную группу usermod -aG docker ivan-petrov # -a ОБЯЗАТЕЛЕН!
Флаг
-Gбез-aзаменяет все дополнительные группы. Пользователь потеряет все группы, включаяsudo. Всегда используй-aG.
chsh — смена оболочки
# Интерактивно (сам пользователь может сменить свою оболочку) chsh # New shell [/bin/bash]: /bin/zsh # Неинтерактивно (только root) chsh -s /bin/fish ivan # Доступные оболочки — только из /etc/shells cat /etc/shells
Блокировка и разблокировка
# Заблокировать (ставит ! перед хешем в shadow) passwd -l ivan usermod -L ivan # эквивалент # Разблокировать passwd -u ivan usermod -U ivan # Проверить статус пароля passwd -S ivan # ivan L 03/26/2026 0 99999 7 -1 # ^ L=Locked, P=Password set, NP=No Password
️ Блокировка через
passwd -lзапрещает вход по паролю, но не блокирует SSH по ключу. Для полной блокировки: дополнительноusermod -s /usr/sbin/nologin ivanилиusermod -e 1 ivan.
Удаление пользователей
userdel
# Удалить пользователя (home НЕ удаляется) userdel ivan # Удалить вместе с home-каталогом и почтовым ящиком userdel -r ivan # Предварительно сохранить данные tar -czf /backup/ivan-$(date +%F).tar.gz /home/ivan userdel -r ivan
Риски при удалении
Риск | Последствие | Защита |
|---|---|---|
Потеря данных | Файлы в home безвозвратно удалены | Бэкап перед |
Orphaned files | Файлы вне home с UID без пользователя |
|
UID reuse | Новый пользователь получает тот же UID → старые файлы | Явно задавать UID через |
Запущенные сессии |
|
|
# Найти «осиротевшие» файлы find / -nouser -nogroup -ls 2>/dev/null
Управление группами
groupadd / groupmod / groupdel
# Создать группу groupadd developers groupadd -g 5000 infra # с явным GID groupadd -r appservice # системная группа # Переименовать groupmod -n backend developers # Изменить GID (осторожно: файлы со старым GID станут orphaned) groupmod -g 5100 backend # Удалить groupdel backend
Добавление пользователя в группу
# Правильно: -aG (append + Groups) usermod -aG docker ivan # Сразу в несколько групп usermod -aG docker,sudo,adm maria
️ Изменения вступают в силу только при следующем входе. Для немедленного применения в текущей сессии:
newgrp docker # запускает subshell с активной группой docker # или exec su -l $USER # перезапускает логин-сессию без выхода
Проверка
getent group docker # docker:x:998:deployer,maria,ci-bot id maria groups maria
Привилегии: su vs sudo
su — переключение пользователя
su запускает новый шелл от имени другого пользователя, используя его пароль.
# Переключиться на root без загрузки окружения su # Переключиться на root с полным login shell (рекомендуется) su - su -l root # Переключиться на другого пользователя su - maria # Выполнить одну команду su -c "whoami; id" - maria
Разница su vs su -:
su— переключает UID, но сохраняет PATH и переменные текущего пользователяsu -— полный login shell: новый PATH, HOME, SHELL, выполняется~/.profileцелевого пользователя
️ На Ubuntu по умолчанию у root нет пароля. Используем
sudo -iилиsudo su -вместоsu.
sudo — точечное делегирование прав
sudo выполняет одну команду с повышенными привилегиями, авторизуясь паролем самого пользователя и логируя каждое действие.
# Выполнить команду от root sudo apt update # Получить root-шелл (login shell) sudo -i # Получить root-шелл (non-login) sudo -s # Выполнить от имени другого пользователя sudo -u www-data id # Посмотреть, что тебе разрешено sudo -l # Повторить последнюю команду с sudo sudo !! # Аудит: все sudo-действия grep sudo /var/log/auth.log | tail -20
Настройка /etc/sudoers
Редактировать только через
visudo. Синтаксическая ошибка без visudo заблокирует весь sudo на системе.
visudo
Синтаксис строки: КТО ОТКУДА=(ОТ_КОГО) [NOPASSWD:] ЧТО
# Группа sudo — полные права со своим паролем %sudo ALL=(ALL:ALL) ALL # Конкретный пользователь — только restart nginx без пароля deployer ALL=(root) NOPASSWD: /usr/sbin/service nginx restart # CI-бот — только docker ci-bot ALL=(root) NOPASSWD: /usr/bin/docker # Запретить конкретную команду для группы %developers ALL=(ALL) ALL, !/usr/sbin/visudo
Модульная организация через /etc/sudoers.d/:
visudo -f /etc/sudoers.d/ci-bot # Содержимое: # ci-bot ALL=(root) NOPASSWD: /usr/bin/docker pull *, /usr/bin/docker run * # Права файла обязательно 0440 chmod 0440 /etc/sudoers.d/ci-bot
su vs sudo — когда что использовать
Критерий |
|
|
|---|---|---|
Авторизация | Пароль целевого пользователя | Свой пароль |
Аудит | Нет гранулярного лога | Полный лог в syslog |
Гранулярность | Полная смена identity | Конкретные команды с |
Автоматизация | Неудобно | Удобно: |
Когда применять | Длительная сессия под другим пользователем | Production-серверы, разовые привилегированные операции |
Заключение
Мы разобрали как Linux идентифицирует пользователей через UID и GID, какие бывают виды пользователей и групп, где хранится информация о них, как создавать, изменять и удалять пользователей, и чем отличаются su и sudo. Это фундамент для понимания прав доступа, которые мы разберём в следующей части серии.
Ниже — шпаргалка по всем командам из статьи.
Шпаргалка
Диагностика
Команда | Описание |
|---|---|
| uid/gid/groups текущего пользователя |
| имя текущего пользователя |
| uid/gid/groups указанного пользователя |
| группы пользователя |
| запись из passwd (учитывает LDAP) |
| запись о группе |
| статус пароля |
| история входов |
| кто сейчас залогинен |
Управление пользователями
Команда | Описание |
|---|---|
| создать пользователя |
| установить пароль |
| добавить в группу |
| блокировать / разблокировать |
| удалить с home |
Управление группами
Команда | Описание |
|---|---|
| создать группу |
| переименовать |
| удалить |
| активировать группу в текущей сессии |
Безопасное редактирование системных файлов
Команда | Описание |
|---|---|
| /etc/sudoers |
| /etc/passwd |
| /etc/shadow |
| /etc/group |
| проверить целостность |

