useradd vs adduser: Технические различия, варианты использования и когда применять каждую команду
`useradd` — это низкоуровневая бинарная утилита, доступная практически в каждом дистрибутиве Linux, которая создаёт учётные записи пользователей путём прямой записи в `/etc/passwd`, `/etc/shadow` и `/etc/group`. `adduser` — это высокоуровневый скрипт-обёртка, как правило написанный на Perl в системах на базе Debian, который вызывает `useradd` внутри себя, автоматизируя создание домашнего каталога, заполнение файлов-шаблонов, запрос пароля и сбор полей GECOS. Практическое различие заключается не только в удобстве использования: выбор неправильного инструмента в автоматизированном конвейере подготовки или в системе, не основанной на Debian, может незаметно привести к созданию неполных учётных записей пользователей.
Обе команды в конечном счёте регистрируют пользователя в базе данных аутентификации системы, однако их поведение существенно различается в части настроек по умолчанию, интерактивности, переносимости и возможности использования в скриптах. В этом руководстве рассматриваются все технические различия, необходимые администратору для принятия обоснованного решения.
Что на самом деле делает useradd под капотом
`useradd` входит в состав пакета shadow-utils (иногда называемого `passwd` в старых дистрибутивах). При вызове он выполняет ряд атомарных операций:
- Читает `/etc/login.defs` для определения диапазонов UID по умолчанию, политик устаревания паролей и того, создавать ли домашний каталог по умолчанию.
- Читает `/etc/default/useradd` для получения оболочки по умолчанию, пути к каталогу шаблонов и поведения групп.
- Записывает новую запись в `/etc/passwd` и `/etc/shadow`.
- При необходимости создаёт домашний каталог и копирует файлы из `/etc/skel`, если явно передан флаг `-m`.
- При необходимости создаёт приватную группу с именем пользователя, если в `/etc/login.defs` для `USERGROUPS_ENAB` установлено значение `yes`.
Важный момент, который многие руководства упускают: в дистрибутивах на базе Red Hat (RHEL, CentOS, Rocky Linux, AlmaLinux) `useradd` создаёт домашний каталог по умолчанию, поскольку в `/etc/login.defs` установлено `CREATE_HOME yes`. В Debian и Ubuntu этого не происходит — флаг `-m` является обязательным, если только вы не измените `/etc/default/useradd`. Эта асимметрия в поведении является частым источником путаницы при миграции администраторов между семействами дистрибутивов.
Ключевые флаги и их поведение
| Флаг | Назначение | Примечания |
|---|---|---|
| —— | ——— | ——- |
| `-m` | Создать домашний каталог | Обязателен в Debian/Ubuntu без изменения конфигурации |
| `-d /path` | Задать пользовательский путь к домашнему каталогу | Не создаёт каталог, если не используется также `-m` |
| `-s /bin/bash` | Задать оболочку входа | По умолчанию используется `/bin/sh` или значение из `/etc/default/useradd` |
| `-u UID` | Назначить конкретный UID | Должен быть уникальным; используйте `-o` для разрешения дубликатов |
| `-g GID` | Задать основную группу | Группа должна уже существовать |
| `-G group1,group2` | Добавить дополнительные группы | Через запятую, без пробелов |
| `-e YYYY-MM-DD` | Дата истечения срока действия учётной записи | Записывается в поле 8 `/etc/shadow` |
| `-f days` | Период неактивности пароля | Количество дней после истечения срока до блокировки учётной записи |
| `-r` | Создать системную учётную запись | UID ниже `SYS_UID_MAX` в `/etc/login.defs`, домашний каталог по умолчанию не создаётся |
| `-M` | Явно не создавать домашний каталог | Переопределяет настройки дистрибутива по умолчанию |
| `-N` | Не создавать приватную группу пользователя | Основной группой пользователя становится группа по умолчанию |
| `-k /path` | Указать альтернативный каталог шаблонов | Переопределяет `/etc/skel` |
Практический пример useradd с полным набором параметров
“`bash
useradd
-m
-d /srv/appuser
-s /bin/bash
-u 1500
-g developers
-G sudo,docker
-e 2025-12-31
-c "Application Service Account"
appuser
passwd appuser
“`
Пароль не устанавливается до вызова `passwd`. До этого момента учётная запись существует, но заблокирована — запись в shadow содержит `!` в качестве хэша пароля, что предотвращает вход с использованием парольной аутентификации. Однако вход по SSH-ключу не зависит от этого состояния.
Что на самом деле делает adduser под капотом
В Debian и Ubuntu `adduser` — это Perl-скрипт, расположенный по адресу `/usr/sbin/adduser`. Он считывает собственную конфигурацию из `/etc/adduser.conf` — отдельного файла от `/etc/login.defs` — а затем вызывает `useradd` с соответствующими флагами на основе этой конфигурации и пользовательского ввода.
Скрипт выполняет дополнительные шаги, которые `useradd` самостоятельно не выполняет:
- В интерактивном режиме запрашивает пароль и подтверждает его повторным вводом.
- Собирает поля GECOS (полное имя, номер комнаты, рабочий телефон, домашний телефон, прочее) с помощью пошаговых подсказок.
- Автоматически копирует файлы шаблонов из `/etc/skel` без необходимости указывать `-m`.
- Устанавливает правильные права владения и разрешения для домашнего каталога.
- При необходимости добавляет пользователя в дополнительные группы, определённые в `/etc/adduser.conf`.
В системах на базе Red Hat `adduser` обычно является символической ссылкой на `useradd`, то есть ведёт себя идентично низкоуровневому бинарному файлу — интерактивной обёртки нет. Это наиболее важная проблема переносимости при написании скриптов для разных дистрибутивов.
Файл конфигурации adduser: /etc/adduser.conf
Ключевые директивы в `/etc/adduser.conf`, влияющие на поведение:
“`
DSHELL=/bin/bash # Default shell
DHOME=/home # Parent directory for home directories
GROUPHOMES=no # Whether to create group-named subdirectories
LETTERHOMES=no # Whether to use first-letter subdirectories
USERGROUPS=yes # Create a group with the same name as the user
USERS_GID=100 # Default GID if USERGROUPS=no
DIR_MODE=0755 # Permissions on new home directories
SETGID_HOME=no
QUOTAUSER=""
SKEL=/etc/skel
SKEL_IGNORE_REGEX="dpkg-(old|new|dist|tmp)"
“`
Изменение этого файла позволяет стандартизировать создание пользователей на всём парке серверов Debian/Ubuntu без необходимости каждый раз передавать флаги.
Практический пример adduser
“`bash
adduser customuser
“`
Интерактивный сеанс выглядит следующим образом:
“`
Adding user 'customuser' …
Adding new group 'customuser' (1001) …
Adding new user 'customuser' (1001) with group 'customuser' …
Creating home directory '/home/customuser' …
Copying files from '/etc/skel' …
New password:
Retype new password:
passwd: password updated successfully
Changing the user information for customuser
Enter the new value, or press ENTER for the default
Full Name []: Jane Smith
Room Number []:
Work Phone []:
Home Phone []:
Other []:
Is the information correct? [Y/n] Y
“`
Чтобы добавить существующего пользователя в группу в неинтерактивном режиме с помощью `adduser`:
“`bash
adduser customuser sudo
“`
Это примечательная особенность: `adduser` также выступает инструментом управления членством в группах, что `useradd` не воспроизводит одной командой.
Сравнение по параметрам
| Параметр | `useradd` | `adduser` |
|---|---|---|
| — | — | — |
| Тип | Бинарный файл (программа на C) | Скрипт (Perl в Debian, символическая ссылка в RHEL) |
| Интерактивность | Неинтерактивный; все параметры задаются через флаги | Интерактивные подсказки по умолчанию |
| Домашний каталог | Не создаётся, если не передан `-m` (Debian) | Создаётся автоматически |
| Установка пароля | Требует отдельной команды `passwd` | Запрашивается при создании |
| Поля GECOS | Задаются через флаг `-c` в виде одной строки | Собираются поле за полем в интерактивном режиме |
| Файлы шаблонов | Копируются только с флагом `-m` | Копируются всегда |
| Файл конфигурации | `/etc/login.defs`, `/etc/default/useradd` | `/etc/adduser.conf` |
| Кросс-дистрибутивная доступность | Все дистрибутивы Linux | Только Debian/Ubuntu (в виде скрипта-обёртки) |
| Пригодность для скриптов | Отличная — полностью неинтерактивный | Низкая — требует флагов `–disabled-password` и `–gecos` для подавления подсказок |
| Системные учётные записи | Поддерживается через флаг `-r` | Поддерживается через флаг `–system` |
| Управление группами | Только во время создания | Может добавлять пользователя в существующую группу после создания |
| Гранулярность | Полный контроль над каждым параметром | Жёсткие настройки по умолчанию, меньше гранулярности |
Когда использовать useradd
Автоматизация и инфраструктура как код
`useradd` — правильный выбор в любом неинтерактивном контексте: плейбуки Ansible, провайдеры Terraform, инструкции `RUN` в Docker, скрипты cloud-init и конвейеры CI/CD. Он обеспечивает детерминированный вывод без зависимости от stdin.
“`bash
Ansible task equivalent
useradd -m -s /bin/bash -G sudo -c "Deploy User" deployuser
echo "deployuser:$(openssl passwd -6 'securepassword')" | chpasswd
“`
Кросс-дистрибутивная переносимость
Любой shell-скрипт, предназначенный для работы как в системах на базе Debian, так и в системах на базе RHEL, должен использовать `useradd`. Опора на поведение `adduser` приведёт к скрытым сбоям или неожиданному поведению в CentOS, Fedora, Rocky Linux или Alpine Linux.
Системные учётные записи и учётные записи служб
Создание заблокированных учётных записей служб без оболочки входа для демонов — это специализация `useradd`:
“`bash
useradd -r -s /usr/sbin/nologin -d /var/lib/myservice -m myservice
“`
Флаг `-r` назначает UID ниже порога системных учётных записей, сигнализирует администраторам, что это не учётная запись реального пользователя, и является стандартным шаблоном для развёртывания приложений в средах VPS Хостинга, где критически важна изоляция служб.
Точный контроль UID/GID
В средах NFS, при оркестрации контейнеров или при синхронизации баз данных пользователей между несколькими серверами согласованность UID и GID является обязательной. `useradd -u 1500 -g 1500` гарантирует это; `adduser` не обеспечивает такого же детерминированного контроля без значительной настройки.
Когда использовать adduser
Интерактивная настройка сервера
При ручной подготовке нового Выделенного сервера и добавлении первых нескольких учётных записей реальных пользователей `adduser` снижает риск неполной настройки. Пошаговые подсказки делают практически невозможным пропуск шага установки пароля.
Среды Debian/Ubuntu со стандартными настройками по умолчанию
Если вся ваша инфраструктура работает на Debian или Ubuntu и вы создаёте стандартных пользователей с домашними каталогами, `adduser` быстрее даёт правильный результат с меньшим количеством флагов для запоминания.
Управление группами после создания
Синтаксис `adduser username groupname` для добавления существующего пользователя в существующую группу чище, чем `usermod -aG groupname username`, хотя оба варианта допустимы.
Обучение младших администраторов
Интерактивная природа `adduser` делает его лучшим учебным инструментом. Он выводит на первый план важные поля (пароль, полное имя) и скрывает сложность диапазонов UID и каталогов шаблонов до тех пор, пока администратор не будет готов их изучить.
Критические граничные случаи и подводные камни
Ловушка отсутствующего домашнего каталога
В Debian/Ubuntu запуск `useradd username` без `-m` создаёт пользователя, но не домашний каталог. Пользователь может войти в систему (после установки пароля), но `$HOME` не будет существовать, что приведёт к сбоям в любом приложении, которое записывает в домашний каталог при первом входе — включая `.bash_history`, `.ssh/authorized_keys` и многие каталоги конфигурации приложений.
“`bash
Verify home directory existence after creation
ls -la /home/newuser || echo "Home directory missing — run: mkhomedir_helper newuser"
“`
Блокировка файла shadow
Обе команды блокируют `/etc/shadow` во время записи. В скриптах подготовки с высокой степенью параллелизма, создающих десятки пользователей одновременно, это вызывает состояния гонки. При массовом создании пользователей используйте очередь или последовательное выполнение.
Коллизия UID в контейнерных средах
При развёртывании приложений на VPS с cPanel или других средах с панелями управления сама панель управляет распределением UID. Ручной запуск `useradd` с жёстко заданным UID может привести к коллизии с UID, назначенными панелью, что вызовет ошибки разрешений для нескольких учётных записей. Всегда проверяйте `getent passwd | awk -F: '{print $3}' | sort -n` перед ручным указанием UID.
adduser –disabled-password для скриптов
Если вам необходимо использовать `adduser` в скрипте (например, чтобы воспользоваться его настройками `/etc/adduser.conf` по умолчанию), подавите интерактивные подсказки:
“`bash
adduser –disabled-password –gecos "Automated User,,," scriptuser
echo "scriptuser:$(openssl passwd -6 'password')" | chpasswd
“`
Флаг `–gecos` принимает строку с разделителями-запятыми, соответствующую полям GECOS, что устраняет все интерактивные подсказки.
Интеграция с PAM и NSS
Ни `useradd`, ни `adduser` не настраивают модули PAM или записи NSS (Name Service Switch) для LDAP, Active Directory или других централизованных систем аутентификации. На серверах, интегрированных с `sssd` или `winbind`, создание локальных пользователей любой из этих команд создаёт учётные записи, которые могут конфликтовать с учётными записями службы каталогов или быть ими замещены. Проверяйте `/etc/nsswitch.conf` перед созданием локальных пользователей на системах, подключённых к домену.
Настройка файлов шаблонов
Обе команды по умолчанию копируют из `/etc/skel`. Для команд, управляющих средами Общего веб-хостинга, где каждому пользователю нужен предварительно настроенный `.bashrc`, `.vimrc` или конфигурация SSH, правильный подход — заполнить `/etc/skel` перед запуском любой из команд, а не изменять файлы после создания учётной записи.
Проверка создания пользователя
Независимо от того, какую команду вы используете, проверьте результат:
“`bash
Check passwd entry
getent passwd newuser
Check shadow entry (requires root)
getent shadow newuser
Check group memberships
groups newuser
id newuser
Verify home directory and permissions
ls -la /home/newuser
Test login shell
su -s /bin/bash – newuser -c "echo login successful"
“`
Изменение и удаление пользователей
`useradd` и `adduser` только создают учётные записи. Для управления после создания используются другие команды:
- `usermod` — Изменение атрибутов существующего пользователя (оболочка, группы, домашний каталог, срок действия).
- `userdel` / `deluser` — Удаление учётных записей. `deluser –remove-home username` в Debian также удаляет домашний каталог и почтовый ящик.
- `passwd` — Установка или изменение паролей, блокировка/разблокировка учётных записей.
- `chage` — Управление политиками устаревания и истечения срока действия паролей.
“`bash
Lock an account without deleting it
usermod -L username
Unlock
usermod -U username
Force password change on next login
chage -d 0 username
“`
Практическая матрица принятия решений
Используйте этот контрольный список для выбора правильной команды:
- Скрипт выполняется в системе, не основанной на Debian, или должен быть переносимым? Используйте `useradd`.
- Это автоматизированная, неинтерактивная среда (CI/CD, Ansible, Docker)? Используйте `useradd`.
- Вам нужен конкретный UID/GID для согласованности NFS или контейнеров? Используйте `useradd -u -g`.
- Вы создаёте системную учётную запись или учётную запись службы без оболочки входа? Используйте `useradd -r -s /usr/sbin/nologin`.
- Вы работаете в Debian/Ubuntu и создаёте стандартную учётную запись реального пользователя в интерактивном режиме? Используйте `adduser`.
- Хотите добавить существующего пользователя в группу с помощью чистой однострочной команды? Используйте `adduser username groupname`.
- Вы пишете документацию или обучаете младших сотрудников в Debian? Используйте `adduser`.
- Вам нужно настроить расположение домашнего каталога, срок действия или оболочку неинтерактивно в масштабе? Используйте `useradd` с явными флагами.
Правильная гигиена учётных записей пользователей является основой безопасности сервера. Независимо от того, управляете ли вы одним VPS или парком Выделенных серверов, понимание того, что именно каждая команда записывает на диск — и что она оставляет незаданным — предотвращает класс ошибок повышения привилегий и сбоев аутентификации, возникающих из-за неполной подготовки учётных записей.
—
FAQ
Создаёт ли useradd домашний каталог по умолчанию?
Это зависит от дистрибутива. В системах на базе Red Hat (RHEL, CentOS, Rocky Linux) `CREATE_HOME yes` в `/etc/login.defs` заставляет `useradd` автоматически создавать домашний каталог. В Debian и Ubuntu домашний каталог не создаётся, если явно не передать флаг `-m`.
Доступен ли adduser в CentOS или Rocky Linux?
В дистрибутивах на базе RHEL `adduser` является символической ссылкой на `useradd`, а не интерактивной Perl-обёрткой, как в Debian/Ubuntu. Запуск `adduser username` в CentOS ведёт себя идентично `useradd username` — без подсказок, без автоматического создания домашнего каталога в стиле Debian.
Как использовать adduser неинтерактивно в скрипте?
Передайте `–disabled-password` для пропуска запроса пароля и `–gecos ""` для пропуска запросов полей GECOS: `adduser –disabled-password –gecos "" username`. Установите пароль после с помощью `echo "username:password" | chpasswd` или передав хэш `openssl passwd -6` через pipe.
В чём разница между /etc/login.defs и /etc/adduser.conf?
`/etc/login.defs` — это общесистемный файл конфигурации, считываемый `useradd`, `userdel` и `usermod` — он управляет диапазонами UID/GID, настройками устаревания паролей по умолчанию и поведением при создании домашнего каталога. `/etc/adduser.conf` считывается исключительно Perl-скриптами `adduser` и `deluser` в системах на базе Debian и управляет высокоуровневыми настройками по умолчанию, такими как оболочка по умолчанию, родительский путь домашнего каталога и каталог шаблонов.
Можно ли безопасно смешивать useradd и adduser на одном сервере Debian?
Да. Обе команды в конечном счёте записывают в одни и те же файлы `/etc/passwd`, `/etc/shadow` и `/etc/group`. Учётные записи, созданные любой из команд, неотличимы на системном уровне. Единственная практическая проблема — согласованность: если ваша команда использует `adduser` в интерактивном режиме, а скрипт автоматизации использует `useradd` без `-m`, у некоторых пользователей могут отсутствовать домашние каталоги. Стандартизируйте один подход для каждой среды и задокументируйте его.
