useradd vs adduser: Techniczne różnice, przypadki użycia i kiedy używać każdego z nich
`useradd` to niskopoziomowe narzędzie binarne dostępne praktycznie w każdej dystrybucji Linux, które tworzy konta użytkowników poprzez bezpośredni zapis do `/etc/passwd`, `/etc/shadow` i `/etc/group`. `adduser` to skrypt opakowujący wyższego poziomu — zazwyczaj napisany w Perlu w systemach opartych na Debianie — który wywołuje `useradd` wewnętrznie, automatyzując tworzenie katalogu domowego, wypełnianie plików szkieletowych, monit o hasło i zbieranie pól GECOS. Praktyczna różnica to nie tylko ergonomia: wybranie niewłaściwego narzędzia w zautomatyzowanym potoku provisioningu lub w systemie innym niż Debian może po cichu tworzyć niekompletne konta użytkowników.
Oba polecenia ostatecznie rejestrują użytkownika w systemowej bazie danych uwierzytelniania, ale ich zachowanie znacznie się różni pod względem domyślnych ustawień, interaktywności, przenośności i skryptowalności. Ten przewodnik omawia każdą techniczną różnicę, której administrator potrzebuje, aby podjąć świadomą decyzję.
Co useradd faktycznie robi pod maską
`useradd` jest częścią pakietu shadow-utils (czasami nazywanego `passwd` w starszych dystrybucjach). Po wywołaniu wykonuje serię operacji atomowych:
- Odczytuje `/etc/login.defs` w celu określenia zakresów UID, zasad starzenia haseł i tego, czy domyślnie tworzyć katalog domowy.
- Odczytuje `/etc/default/useradd` dla domyślnej powłoki, ścieżki katalogu szkieletowego i zachowania grupy.
- Zapisuje nowy wpis do `/etc/passwd` i `/etc/shadow`.
- Opcjonalnie tworzy katalog domowy i kopiuje pliki z `/etc/skel`, jeśli `-m` jest jawnie przekazane.
- Opcjonalnie tworzy prywatną grupę odpowiadającą nazwie użytkownika, jeśli `USERGROUPS_ENAB` jest ustawione na `yes` w `/etc/login.defs`.
Kluczowa kwestia, którą wiele przewodników pomija: w dystrybucjach opartych na Red Hat (RHEL, CentOS, Rocky Linux, AlmaLinux), `useradd` tworzy katalog domowy domyślnie, ponieważ `/etc/login.defs` ustawia `CREATE_HOME yes`. W Debianie i Ubuntu nie robi tego — flaga `-m` jest obowiązkowa, chyba że zmodyfikujesz `/etc/default/useradd`. Ta asymetria zachowania jest częstym źródłem zamieszania, gdy administratorzy migrują między rodzinami dystrybucji.
Kluczowe flagi i ich zachowanie
| Flaga | Przeznaczenie | Uwagi |
|---|---|---|
| —— | ——— | ——- |
| `-m` | Utwórz katalog domowy | Wymagane w Debian/Ubuntu bez zmiany konfiguracji |
| `-d /path` | Ustaw niestandardową ścieżkę katalogu domowego | Nie tworzy katalogu, chyba że `-m` jest również użyte |
| `-s /bin/bash` | Ustaw powłokę logowania | Domyślnie `/bin/sh` lub wartość w `/etc/default/useradd` |
| `-u UID` | Przypisz konkretny UID | Musi być unikalny; użyj `-o` aby zezwolić na duplikaty |
| `-g GID` | Ustaw grupę podstawową | Grupa musi już istnieć |
| `-G group1,group2` | Dodaj grupy uzupełniające | Oddzielone przecinkami, bez spacji |
| `-e YYYY-MM-DD` | Data wygaśnięcia konta | Zapisywane w `/etc/shadow` pole 8 |
| `-f days` | Okres nieaktywności hasła | Dni po wygaśnięciu przed zablokowaniem konta |
| `-r` | Utwórz konto systemowe | UID poniżej `SYS_UID_MAX` w `/etc/login.defs`, domyślnie bez katalogu domowego |
| `-M` | Jawnie nie twórz katalogu domowego | Nadpisuje domyślne ustawienia dystrybucji |
| `-N` | Nie twórz prywatnej grupy użytkownika | Podstawową grupą użytkownika staje się grupa domyślna |
| `-k /path` | Określ alternatywny katalog szkieletowy | Nadpisuje `/etc/skel` |
Praktyczny przykład useradd z pełnymi opcjami
“`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
“`
Żadne hasło nie jest ustawiane, dopóki nie zostanie wywołane `passwd`. Do tego czasu konto istnieje, ale jest zablokowane — wpis shadow zawiera `!` jako skrót hasła, uniemożliwiając logowanie przez uwierzytelnianie hasłem. Logowanie oparte na kluczach SSH nie jest jednak przez ten stan dotknięte.
Co adduser faktycznie robi pod maską
W Debianie i Ubuntu `adduser` to skrypt Perl znajdujący się w `/usr/sbin/adduser`. Odczytuje własną konfigurację z `/etc/adduser.conf` — oddzielnego pliku od `/etc/login.defs` — a następnie wywołuje `useradd` z odpowiednimi flagami na podstawie tej konfiguracji i danych wejściowych użytkownika.
Skrypt wykonuje dodatkowe kroki, których sam `useradd` nie wykonuje:
- Interaktywnie pyta o hasło i potwierdza je drugim wpisem.
- Zbiera pola GECOS (imię i nazwisko, numer pokoju, telefon służbowy, telefon domowy, inne) za pomocą prowadzonych monitów.
- Automatycznie kopiuje pliki szkieletowe z `/etc/skel` bez konieczności użycia `-m`.
- Ustawia prawidłowe własności i uprawnienia katalogu domowego.
- Opcjonalnie dodaje użytkownika do grup uzupełniających zdefiniowanych w `/etc/adduser.conf`.
W systemach opartych na Red Hat, `adduser` jest zazwyczaj dowiązaniem symbolicznym do `useradd`, co oznacza, że zachowuje się identycznie jak niskopoziomowy plik binarny — nie ma interaktywnego opakowania. Jest to najważniejszy problem z przenośnością podczas pisania skryptów dla wielu dystrybucji.
Plik konfiguracyjny adduser: /etc/adduser.conf
Kluczowe dyrektywy w `/etc/adduser.conf` wpływające na zachowanie:
“`
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)"
“`
Modyfikacja tego pliku pozwala ustandaryzować tworzenie użytkowników w całej flocie serwerów Debian/Ubuntu bez każdorazowego przekazywania flag.
Praktyczny przykład adduser
“`bash
adduser customuser
“`
Sesja interaktywna wygląda następująco:
“`
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
“`
Aby dodać istniejącego użytkownika do grupy nieinteraktywnie za pomocą `adduser`:
“`bash
adduser customuser sudo
“`
To godna uwagi funkcja: `adduser` pełni podwójną rolę narzędzia do zarządzania członkostwem w grupach, czego `useradd` nie replikuje w jednym poleceniu.
Porównanie obok siebie
| Funkcja | `useradd` | `adduser` |
|---|---|---|
| — | — | — |
| Typ | Plik binarny (program C) | Skrypt (Perl na Debianie, dowiązanie symboliczne na RHEL) |
| Interaktywność | Nieinteraktywny; wszystkie opcje przez flagi | Interaktywne monity domyślnie |
| Katalog domowy | Nie tworzony, chyba że `-m` jest przekazane (Debian) | Tworzony automatycznie |
| Konfiguracja hasła | Wymaga oddzielnego polecenia `passwd` | Monit podczas tworzenia |
| Pola GECOS | Ustawiane przez flagę `-c` jako pojedynczy ciąg | Zbierane pole po polu interaktywnie |
| Pliki szkieletowe | Kopiowane tylko z flagą `-m` | Zawsze kopiowane |
| Plik konfiguracyjny | `/etc/login.defs`, `/etc/default/useradd` | `/etc/adduser.conf` |
| Dostępność między dystrybucjami | Wszystkie dystrybucje Linux | Tylko Debian/Ubuntu (jako skrypt opakowujący) |
| Przydatność do skryptowania | Doskonała — w pełni nieinteraktywna | Słaba — wymaga flag `–disabled-password` i `–gecos` aby uniknąć monitów |
| Konta systemowe | Obsługiwane przez flagę `-r` | Obsługiwane przez flagę `–system` |
| Zarządzanie grupami | Tylko podczas tworzenia | Może dodawać użytkownika do istniejącej grupy po utworzeniu |
| Szczegółowość | Pełna kontrola nad każdym parametrem | Opinionowane wartości domyślne, mniej szczegółowe |
Kiedy używać useradd
Automatyzacja i Infrastructure-as-Code
`useradd` to właściwy wybór w każdym nieinteraktywnym kontekście: playbooki Ansible, provisionery Terraform, instrukcje `RUN` Docker, skrypty cloud-init i potoki CI/CD. Produkuje deterministyczne wyniki bez zależności od stdin.
“`bash
Ansible task equivalent
useradd -m -s /bin/bash -G sudo -c "Deploy User" deployuser
echo "deployuser:$(openssl passwd -6 'securepassword')" | chpasswd
“`
Przenośność między dystrybucjami
Każdy skrypt powłoki przeznaczony do uruchamiania zarówno w systemach opartych na Debianie, jak i RHEL musi używać `useradd`. Poleganie na zachowaniu `adduser` spowoduje ciche błędy lub nieoczekiwane zachowanie w CentOS, Fedora, Rocky Linux lub Alpine Linux.
Konta systemowe i serwisowe
Tworzenie zablokowanych kont serwisowych bez powłoki logowania dla demonów to specjalność `useradd`:
“`bash
useradd -r -s /usr/sbin/nologin -d /var/lib/myservice -m myservice
“`
Flaga `-r` przypisuje UID poniżej progu kont systemowych, sygnalizuje administratorom, że nie jest to konto użytkownika ludzkiego, i jest standardowym wzorcem dla wdrożeń aplikacji w środowiskach VPS Hosting, gdzie izolacja usług jest krytyczna.
Precyzyjna kontrola UID/GID
W środowiskach NFS, orkiestracji kontenerów lub podczas synchronizacji baz danych użytkowników między wieloma serwerami, spójne UID i GID są obowiązkowe. `useradd -u 1500 -g 1500` to gwarantuje; `adduser` nie oferuje tej samej deterministycznej kontroli bez znaczącej konfiguracji.
Kiedy używać adduser
Interaktywna konfiguracja serwera
Podczas ręcznego provisioningu nowego Serwera Dedykowanego i dodawania pierwszych kilku kont użytkowników ludzkich, `adduser` zmniejsza ryzyko niekompletnej konfiguracji. Prowadzone monity sprawiają, że prawie niemożliwe jest zapomnienie o kroku z hasłem.
Środowiska Debian/Ubuntu ze standardowymi wartościami domyślnymi
Jeśli cała infrastruktura działa na Debianie lub Ubuntu i tworzysz standardowych użytkowników z katalogiem domowym, `adduser` szybciej produkuje poprawne wyniki przy mniejszej liczbie flag do zapamiętania.
Zarządzanie grupami po utworzeniu
Składnia `adduser username groupname` do dodawania istniejącego użytkownika do istniejącej grupy jest czystsza niż `usermod -aG groupname username`, choć obie są poprawne.
Wdrażanie młodszych administratorów
Interaktywny charakter `adduser` czyni go lepszym narzędziem dydaktycznym. Eksponuje pola, które mają znaczenie (hasło, pełne imię i nazwisko) i ukrywa złożoność zakresów UID i katalogów szkieletowych, dopóki administrator nie będzie gotowy, aby się ich nauczyć.
Krytyczne przypadki brzegowe i pułapki
Pułapka brakującego katalogu domowego
W Debianie/Ubuntu uruchomienie `useradd username` bez `-m` tworzy użytkownika, ale nie katalog domowy. Użytkownik może się zalogować (po ustawieniu hasła), ale `$HOME` nie będzie istnieć, powodując błędy w każdej aplikacji, która zapisuje do katalogu domowego przy pierwszym logowaniu — w tym `.bash_history`, `.ssh/authorized_keys` i wielu katalogach konfiguracyjnych aplikacji.
“`bash
Verify home directory existence after creation
ls -la /home/newuser || echo "Home directory missing — run: mkhomedir_helper newuser"
“`
Blokowanie pliku shadow
Oba polecenia blokują `/etc/shadow` podczas zapisów. W skryptach provisioningu o wysokiej współbieżności tworzących dziesiątki użytkowników jednocześnie, powoduje to wyścigi. Używaj kolejki lub sekwencyjnego wykonania podczas masowego tworzenia użytkowników.
Kolizja UID w środowiskach kontenerowych
Podczas wdrażania aplikacji na VPS z cPanel lub innych środowiskach paneli sterowania, panel sam zarządza przydzielaniem UID. Ręczne uruchomienie `useradd` z zakodowanym na stałe UID może kolidować z UID przypisanymi przez panel, powodując błędy uprawnień na wielu kontach. Zawsze sprawdzaj `getent passwd | awk -F: '{print $3}' | sort -n` przed ręcznym określaniem UID.
adduser –disabled-password do skryptowania
Jeśli musisz używać `adduser` w skrypcie (na przykład, aby wykorzystać jego domyślne ustawienia `/etc/adduser.conf`), wycisz interaktywne monity:
“`bash
adduser –disabled-password –gecos "Automated User,,," scriptuser
echo "scriptuser:$(openssl passwd -6 'password')" | chpasswd
“`
Flaga `–gecos` przyjmuje ciąg oddzielony przecinkami odpowiadający polom GECOS, eliminując wszystkie interaktywne monity.
Integracja PAM i NSS
Ani `useradd`, ani `adduser` nie konfiguruje modułów PAM ani wpisów NSS (Name Service Switch) dla LDAP, Active Directory lub innych scentralizowanych systemów uwierzytelniania. Na serwerach zintegrowanych z `sssd` lub `winbind`, lokalne tworzenie użytkowników za pomocą któregokolwiek polecenia tworzy konta, które mogą kolidować z kontami usług katalogowych lub być przez nie zastąpione. Sprawdź `/etc/nsswitch.conf` przed tworzeniem lokalnych użytkowników w systemach przyłączonych do domeny.
Dostosowywanie plików szkieletowych
Oba polecenia domyślnie kopiują z `/etc/skel`. Dla zespołów zarządzających środowiskami Shared Web Hosting, gdzie każdy użytkownik potrzebuje wstępnie skonfigurowanego `.bashrc`, `.vimrc` lub konfiguracji SSH, wypełnienie `/etc/skel` przed uruchomieniem któregokolwiek polecenia jest właściwym podejściem — nie modyfikowanie plików po utworzeniu konta.
Weryfikacja tworzenia użytkownika
Niezależnie od użytego polecenia, zweryfikuj wynik:
“`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"
“`
Modyfikowanie i usuwanie użytkowników
`useradd` i `adduser` tylko tworzą konta. Zarządzanie po utworzeniu używa innych poleceń:
- `usermod` — Modyfikuje istniejące atrybuty użytkownika (powłoka, grupy, katalog domowy, wygaśnięcie).
- `userdel` / `deluser` — Usuwa konta. `deluser –remove-home username` na Debianie usuwa również katalog domowy i kolejkę pocztową.
- `passwd` — Ustawia lub zmienia hasła, blokuje/odblokowuje konta.
- `chage` — Zarządza zasadami starzenia i wygasania haseł.
“`bash
Lock an account without deleting it
usermod -L username
Unlock
usermod -U username
Force password change on next login
chage -d 0 username
“`
Praktyczna macierz decyzyjna
Użyj tej listy kontrolnej, aby wybrać właściwe polecenie:
- Czy skrypt działa w systemie innym niż Debian lub musi być przenośny? Użyj `useradd`.
- Czy jest to zautomatyzowane, nieinteraktywne środowisko (CI/CD, Ansible, Docker)? Użyj `useradd`.
- Czy potrzebujesz konkretnego UID/GID dla spójności NFS lub kontenerów? Użyj `useradd -u -g`.
- Czy tworzysz konto systemowe/serwisowe bez powłoki logowania? Użyj `useradd -r -s /usr/sbin/nologin`.
- Czy jesteś w Debianie/Ubuntu i tworzysz standardowe konto użytkownika ludzkiego interaktywnie? Użyj `adduser`.
- Czy chcesz dodać istniejącego użytkownika do grupy za pomocą czystego one-linera? Użyj `adduser username groupname`.
- Czy piszesz dokumentację lub szkolisz młodszych pracowników na Debianie? Użyj `adduser`.
- Czy musisz dostosować lokalizację katalogu domowego, wygaśnięcie lub powłokę nieinteraktywnie na dużą skalę? Użyj `useradd` z jawnymi flagami.
Właściwa higiena kont użytkowników jest fundamentem bezpieczeństwa serwera. Niezależnie od tego, czy zarządzasz pojedynczym VPS, czy flotą Serwerów Dedykowanych, zrozumienie dokładnie tego, co każde polecenie zapisuje na dysku — i co pozostawia nieustawione — zapobiega klasie eskalacji uprawnień i błędów uwierzytelniania wynikających z niekompletnego provisioningu kont.
—
FAQ
Czy useradd domyślnie tworzy katalog domowy?
Zależy to od dystrybucji. W systemach opartych na Red Hat (RHEL, CentOS, Rocky Linux), `CREATE_HOME yes` w `/etc/login.defs` powoduje, że `useradd` automatycznie tworzy katalog domowy. W Debianie i Ubuntu żaden katalog domowy nie jest tworzony, chyba że jawnie przekażesz flagę `-m`.
Czy adduser jest dostępny w CentOS lub Rocky Linux?
W dystrybucjach opartych na RHEL, `adduser` jest dowiązaniem symbolicznym do `useradd`, a nie interaktywnym opakowaniem Perl znajdowanym w Debianie/Ubuntu. Uruchomienie `adduser username` w CentOS zachowuje się identycznie jak `useradd username` — bez monitów, bez automatycznego katalogu domowego w stylu Debiana.
Jak używać adduser nieinteraktywnie w skrypcie?
Przekaż `–disabled-password` aby pominąć monit o hasło i `–gecos ""` aby pominąć monity o pola GECOS: `adduser –disabled-password –gecos "" username`. Ustaw hasło później za pomocą `echo "username:password" | chpasswd` lub przez potokowanie skrótu `openssl passwd -6`.
Jaka jest różnica między /etc/login.defs a /etc/adduser.conf?
`/etc/login.defs` to ogólnosystemowy plik konfiguracyjny odczytywany przez `useradd`, `userdel` i `usermod` — kontroluje zakresy UID/GID, domyślne ustawienia starzenia haseł i zachowanie tworzenia katalogów domowych. `/etc/adduser.conf` jest odczytywany wyłącznie przez skrypty Perl `adduser` i `deluser` w systemach opartych na Debianie i kontroluje domyślne ustawienia wyższego poziomu, takie jak domyślna powłoka, nadrzędna ścieżka katalogu domowego i katalog szkieletowy.
Czy mogę bezpiecznie mieszać useradd i adduser na tym samym serwerze Debian?
Tak. Oba ostatecznie zapisują do tych samych plików `/etc/passwd`, `/etc/shadow` i `/etc/group`. Konta utworzone za pomocą któregokolwiek polecenia są nierozróżnialne na poziomie systemu. Jedyną praktyczną kwestią jest spójność: jeśli Twój zespół używa `adduser` interaktywnie, a skrypt automatyzacji używa `useradd` bez `-m`, możesz skończyć z niektórymi użytkownikami bez katalogów domowych. Ustandaryzuj jedno podejście na środowisko i udokumentuj je.
