Jak założyć użytkownika z uprawnieniami sudo i przestać pracować jako root
adduser kontra useradd, grupy sudo i wheel, bezpieczna edycja sudoers przez visudo oraz test, który dowodzi, że nie odciąłeś sobie dostępu, zanim wyłączysz roota.
Po udostępnieniu serwera pracujesz jako root, a root może wszystko, bez pytania. Jedna literówka trafia od razu w cały system, a root to jedyna nazwa użytkownika, którą każdy atakujący zna na pewno. Ten poradnik przechodzi całą drogę: założenie użytkownika, dodanie go do właściwej grupy, rozszerzenie konfiguracji sudoers, przeniesienie klucza publicznego i dopiero na samym końcu wyłączenie roota. Najważniejsza część znajduje się tuż przed zakończeniem: dowód na to, że nie odciąłeś sam sobie dostępu.
Systemy odniesienia to Debian 13 (trixie), Debian 12 (bookworm), Ubuntu 24.04 LTS oraz Ubuntu 22.04 LTS. Tam, gdzie systemy z rodziny RHEL, czyli AlmaLinux i Rocky Linux, zachowują się inaczej, jest to zaznaczone. Polecenia napisano z myślą o pracy jako root; jako zwykły użytkownik dopisz przed każdym z nich sudo. Wersję skróconą znajdziesz w liście kontrolnej dla nowych serwerów root, tutaj następuje pogłębienie tematu.
Zanim cokolwiek zmienisz: droga powrotna
Dwie zmiany mogą tu kosztować cię dostęp: konfiguracja sudoers oraz, na samym końcu, zgoda na logowanie roota przez SSH. Uszkodzony plik sudoers odbiera ci uprawnienia, a za wcześnie wyłączone logowanie roota zabiera drogę zapasową. Dlatego trzy rzeczy wyjaśnij wcześniej.
Druga sesja. Otwórz drugie okno terminala z aktywnym połączeniem SSH jako root i nie zamykaj go, dopóki wszystko nie zostanie sprawdzone. Istniejąca sesja przeżywa zarówno restart usługi SSH, jak i błędny plik sudoers.
Droga z pominięciem SSH. Przy serwerach root KVM oraz serwerach dedykowanych KernelHost otwierasz konsolę VNC w panelu klienta. Jest podpięta do warstwy wirtualizacji względnie do samego łącza, działa więc niezależnie od SSH, firewalla i pliku sudoers. Zaloguj się tam raz zawczasu: droga ratunkowa, którą wypróbowujesz dopiero w sytuacji awaryjnej, nie jest żadną drogą ratunkową.
Hasło, które znasz. Konsola nie zna kluczy SSH, logujesz się w niej nazwą użytkownika i hasłem albo wcale. To tutaj powstaje większość przypadków odcięcia się od własnego serwera.
Zasada praktyczna: drogą ratunkową jest konsola, a konsola zna wyłącznie hasła. Zanim wyłączysz logowanie hasłem, przynajmniej jedno konto musi mieć hasło, które znasz.
Inwentaryzacja: czy sudo jest w ogóle zainstalowane?
Na obrazach serwerowych Ubuntu sudo jest obecne, na minimalnych obrazach Debiana często nie. Trzy wiersze wyjaśniają sytuację wyjściową:
command -v sudo || echo "brak sudo"
getent group sudo
awk -F: '$3 >= 1000 && $3 < 65534 {print $1, $3, $7}' /etc/passwd
Drugi wiersz pokazuje grupę wraz z jej członkami, trzeci wszystkie zwykłe konta z identyfikatorem i powłoką logowania. Na obrazach z cloud-init często istnieje już konto z uprawnieniami sudo. Jeśli sudo brakuje, doinstaluj je:
apt-get update
apt-get install -y sudo
sudo -V | head -n 1
adduser czy useradd: dwa narzędzia, dwa wyniki
Kto używa useradd, a oczekuje zachowania adduser, dostaje konto bez katalogu domowego i z powłoką, której się nie spodziewał.
| Cecha | adduser | useradd |
|---|---|---|
| Dostępność | Debian i Ubuntu | wszędzie, także w systemach z rodziny RHEL |
| Obsługa | interaktywna, pyta o hasło i pola z danymi osobowymi | robi tylko to, co stoi w przełącznikach |
| Katalog domowy | tworzony i wypełniany z /etc/skel | tylko z -m |
| Powłoka logowania | z /etc/adduser.conf | z /etc/default/useradd, często /bin/sh |
| Hasło | pytane, chyba że użyto --disabled-password | nigdy nie jest ustawiane |
| W systemach z rodziny RHEL | tylko inna nazwa dla useradd | właściwe narzędzie |
Na Debianie i Ubuntu właściwym wyborem jest adduser:
adduser --disabled-password --gecos "" kernel
--gecos "" pomija pytania o imię, nazwisko i numery telefonu, --disabled-password zakłada konto bez hasła. Tu czai się pierwsza pułapka: konto bez hasła nie zaloguje się do konsoli VNC, a na pytanie o hasło zadane przez sudo nigdy nie da się odpowiedzieć poprawnie. Dlatego zaraz potem ustaw hasło:
passwd kernel
W systemach z rodziny RHEL albo w skrypcie równoważna wersja wygląda tak:
useradd -m -s /bin/bash kernel
passwd kernel
Kontrola poprawności:
getent passwd kernel
ls -ld /home/kernel
passwd -S kernel
getent passwd kernel pokazuje katalog domowy i powłokę logowania; jeśli widnieje tam /bin/sh albo /usr/sbin/nologin, poprawi to usermod -s /bin/bash kernel. passwd -S kernel podaje w drugiej kolumnie stan hasła: P oznacza hasło używalne, L zablokowane, NP brak hasła. Po passwd kernel musi tam stać P.
Grupa administracyjna: sudo na Debianie i Ubuntu, wheel na RHEL
Częste nieporozumienie: sama grupa nie nadaje żadnych uprawnień. Działa tylko dlatego, że w /etc/sudoers stoi wiersz, który się do niej odnosi. Na Debianie i Ubuntu brzmi on z grubsza %sudo ALL=(ALL:ALL) ALL, w systemach z rodziny RHEL %wheel ALL=(ALL) ALL. Co jest zapisane u ciebie, pokaże:
grep -E '^[^#]*%' /etc/sudoers
Na Ubuntu pojawia się dodatkowo wiersz dla historycznej grupy admin. Ta grupa nie istnieje już na aktualnych obrazach, więc wiersz pozostaje bez skutku. Użytkownika dodajesz tak:
usermod -aG sudo kernel
Przełącznik -a nie jest opcjonalny. Bez niego usermod -G zastępuje wszystkie grupy dodatkowe podaną listą, bez słowa komentarza, a szkoda wychodzi na jaw często dopiero po tygodniach. Przełącznik działa wyłącznie razem z -G. Równoważne i mniej podatne na pomyłkę jest gpasswd -a kernel sudo.
Kontrola poprawności:
id -nG kernel
getent group sudo
sudo -l -U kernel
Ostatni wiersz mówi najwięcej, bo pyta samo sudo. Oczekiwany jest blok kończący się na (ALL : ALL) ALL. Jeśli zamiast tego pojawi się User kernel is not allowed to run sudo on srv01., żadna reguła nie działa.
Dlaczego nowa grupa zaczyna obowiązywać dopiero przy kolejnym logowaniu
Przynależność do grup proces dostaje przy logowaniu i później już nie. Dlatego id -nG kernel uruchomione jako root pokazuje grupę sudo, podczas gdy ta sama komenda w sesji użytkownika jej nie zawiera. Obie odpowiedzi są prawidłowe: jedno polecenie czyta bazę użytkowników, drugie bieżącą sesję. Rozwiązaniem jest nowe logowanie, a nie restart. newgrp sudo działa tylko w tej jednej powłoce, w której je wywołasz.
Bezpieczna edycja sudoers: visudo i /etc/sudoers.d
Nigdy nie otwieraj /etc/sudoers bezpośrednio w edytorze. Błąd składni czyni sudo bezużytecznym dla wszystkich użytkowników, a jeśli root jest już wyłączony, zostaje tylko konsola. visudo blokuje plik przed równoczesnymi zmianami i sprawdza składnię przed zapisem. Gdy znajdzie błąd, dopytuje:
>>> /etc/sudoers: syntax error near line 22 <<<
What now?
Options are:
(e)dit sudoers file again
e(x)it without saving changes to sudoers file
(Q)uit and save changes to sudoers file (DANGER!)
Prawidłowa odpowiedź to e; duże Q zapisuje wadliwy plik. O tym, który edytor uruchomi visudo, decyduje na Debianie i Ubuntu system alternatyw: na stałe przez update-alternatives --config editor, jednorazowo przez EDITOR=nano visudo.
Do własnych reguł nie tykaj jednak /etc/sudoers w ogóle. Na końcu pliku jeden wiersz dołącza cały katalog, zależnie od wieku systemu jako @includedir /etc/sudoers.d albo jako #includedir /etc/sudoers.d. Krzyżyk wygląda jak znak komentarza, ale nim nie jest. Ten plik również zakładasz przez visudo:
visudo -f /etc/sudoers.d/10-kernel
Dwie zasady, na których wykładają się pliki w tym katalogu
Nazwa pliku nie może zawierać kropki ani kończyć się tyldą. sudo pomija takie pliki po cichu, żeby kopie zapasowe przypadkiem nie nadawały uprawnień. 10-kernel.conf nigdy więc nie zostanie wczytany, i to bez żadnego komunikatu. Poprawna nazwa to 10-kernel.
Plik musi należeć do roota i nie może być zapisywalny dla grupy ani dla pozostałych, oczekiwany jest tryb 0440.
chown root:root /etc/sudoers.d/10-kernel
chmod 0440 /etc/sudoers.d/10-kernel
visudo -c
visudo -c sprawdza wszystkie dołączone pliki i dla każdego wypisuje jeden wiersz:
/etc/sudoers: parsed OK
/etc/sudoers.d/10-kernel: parsed OK
To jest zarazem najlepszy test pierwszej zasady: jeśli twojego pliku tu nie ma, nie jest on czytany, a przyczyną okazuje się wtedy niemal zawsze kropka w nazwie. Przy błędnych uprawnieniach visudo zgłasza natomiast /etc/sudoers.d/10-kernel: bad permissions, should be mode 0440.
NOPASSWD: ile to naprawdę kosztuje
Prędzej czy później każdy trafia na taki wiersz:
kernel ALL=(ALL) NOPASSWD: ALL
Jest on groźniejszy, niż wygląda. Pytanie o hasło to ostatnia przeszkoda między „ktoś ma powłokę jako kernel” a „ktoś jest rootem”. Kto dostanie się do tego konta przez podatną aplikację webową, skopiowany klucz prywatny albo pozostawioną bez nadzoru sesję, z takim wierszem jest rootem bez żadnego dodatkowego kroku. Przy NOPASSWD: ALL zysk bezpieczeństwa wobec bezpośredniego logowania roota kurczy się więc do nazwy użytkownika, której atakujący nie zna.
NOPASSWD ma uzasadnienie tam, gdzie nikt nie może nic wpisać: przebiegi Ansible, skrypty backupu, potoki wdrożeniowe. Ale wtedy wąsko ograniczone i nie dla człowieka przy terminalu:
deploy ALL=(root) NOPASSWD: /usr/bin/systemctl restart nginx
Trzy pułapki przy takich regułach:
- Ścieżki bezwzględne są obowiązkowe. Sama nazwa programu bez ścieżki nie pasuje do niczego.
- Bez wypisanych argumentów dozwolone są wszystkie argumenty.
deploy ALL=(root) NOPASSWD: /usr/bin/systemctlzezwala na każde wywołanie systemctl. Dopiero gdy dopiszesz argumenty, wiersz polecenia musi brzmieć dokładnie tak samo. Jeśli żaden argument nie ma być dozwolony, dopisz pustą parę cudzysłowów, na przykład/usr/bin/id "". - Symbole wieloznaczne rzadko są tak wąskie, jak się wydaje.
/usr/bin/*zezwala na każdy program w tym katalogu i w praktyce oznacza pełny dostęp roota.
Najważniejsze pytanie przy każdej ograniczonej regule: czy dozwolone polecenie może uruchomić inny program albo otworzyć powłokę? Edytory, menedżery pakietów, narzędzia do archiwów i interpretery potrafią to zrobić, a reguła, która dopuszcza edytor przez sudo, w praktyce dopuszcza wszystko.
Lepszym kompromisem jest czas zapamiętania: sudo przechowuje udane uwierzytelnienie domyślnie przez 15 minut, osobno dla każdego terminala. Dostosujesz to w katalogu /etc/sudoers.d/:
Defaults:kernel timestamp_timeout=5
sudo -k natychmiast odrzuca ten wpis, sudo -v odnawia go bez wykonywania żadnego polecenia.
Przeniesienie klucza publicznego na nowego użytkownika
Dopóki logowanie hasłem przez SSH jest aktywne, najwygodniej zrobisz to ze stacji roboczej poleceniem ssh-copy-id kernel@203.0.113.10. Jeśli jest już wyłączone, próba kończy się komunikatem Permission denied (publickey). Wtedy droga prowadzi przez wciąż otwartą sesję roota.
Nasuwa się tam cp -r /root/.ssh /home/kernel/.ssh, i jest to błąd: pliki należą potem do roota, serwer SSH je odrzuca, a polecenie zabiera przy okazji ewentualny klucz prywatny roota, który na drugim koncie nie ma czego szukać. Zamiast tego przenieś celowo wyłącznie klucze publiczne:
install -d -m 700 -o kernel -g kernel /home/kernel/.ssh
install -m 600 -o kernel -g kernel /root/.ssh/authorized_keys /home/kernel/.ssh/authorized_keys
install ustawia uprawnienia i właściciela za jednym zamachem, więc nie zostaje żadne zapomniane chown. Jeśli /root/.ssh/authorized_keys nie istnieje, załóż pusty plik docelowy i wpisz do niego klucz edytorem:
install -m 600 -o kernel -g kernel /dev/null /home/kernel/.ssh/authorized_keys
Kontrola poprawności:
ls -ld /home/kernel /home/kernel/.ssh
ls -l /home/kernel/.ssh/authorized_keys
ssh-keygen -l -f /home/kernel/.ssh/authorized_keys
Ostatni wiersz wypisuje odcisk palca każdego zapisanego klucza. Porównaj go z wynikiem ssh-keygen -l -f ~/.ssh/id_ed25519.pub na swojej stacji roboczej. Dzięki temu jeszcze przed pierwszą próbą logowania wiesz, że dotarł właściwy klucz.
Szczegół, który potrafi kosztować godziny: przy StrictModes yes serwer SSH sprawdza nie tylko .ssh i authorized_keys, ale też katalog domowy. Jeśli jest on zapisywalny dla grupy albo dla pozostałych, odrzuca logowanie kluczem, a klient zgłasza jedynie Permission denied (publickey). Jakie uprawnienia nadaje twój system, stoi w /etc/adduser.conf pod DIR_MODE. Wszystko o samym logowaniu kluczem znajdziesz w poradniku Zabezpieczenie SSH i konfiguracja logowania kluczem.
Test, zanim wyłączysz roota
Cztery sprawdzenia, a dopiero gdy wszystkie wypadną poprawnie, bierzesz się za konfigurację SSH. Stara sesja roota pozostaje otwarta.
Po pierwsze: nowa sesja SSH jako nowy użytkownik, w świeżo otwartym oknie, a nie w istniejącym połączeniu.
ssh kernel@203.0.113.10
Oczekiwana jest powłoka bez pytania o hasło. Jeśli zostaniesz zapytany o hasło, klucz nie zadziałał; ssh -v pokazuje, które klucze klient w ogóle oferuje. Jeśli zawodzi już samo nawiązanie połączenia, pomoże poradnik Połączenie z serwerem przez SSH.
Po drugie: sudo dokładnie w tej nowej sesji.
id
sudo -v
sudo id
id musi wymieniać grupę sudo, a sudo id musi zaczynać się od uid=0(root). Wywołanie sudo -l -U kernel z sesji roota nie zastąpi tego testu: pokazuje ono, na co sudo by pozwoliło, a nie to, czy logowanie użytkownika w ogóle działa.
Po trzecie: konsola. Zaloguj się przez konsolę VNC w panelu klienta jako kernel, podając nazwę użytkownika i hasło, a następnie wykonaj tam sudo -i. Ten test jest najważniejszy z czterech, bo konsola jest drogą ratunkową i zna wyłącznie hasła.
Po czwarte: stan haseł.
passwd -S root
passwd -S kernel
Przy co najmniej jednym z tych dwóch kont w drugiej kolumnie musi stać P. Dwa zablokowane konta plus wadliwa konfiguracja SSH dają system, do którego dostaniesz się już tylko przez system ratunkowy.
Wyłączenie roota, ale poprawnie
Trzy działania bywają wrzucane do jednego worka, choć ich skutki bardzo się różnią.
| Działanie | Skutek | Konsekwencja dla konsoli |
|---|---|---|
PermitRootLogin prohibit-password | root wchodzi przez SSH już tylko kluczem, nigdy hasłem | żadna, root nadal może się zalogować |
PermitRootLogin no | root nie wchodzi już przez SSH w ogóle | żadna, root nadal może się zalogować |
passwd -l root | root nie ma już używalnego hasła, logowanie kluczem i sudo -i pozostają nienaruszone | zalogować się może już tylko użytkownik z sudo |
Dla większości serwerów właściwym wyborem jest prohibit-password: root pozostaje dostępny kluczem jako koło ratunkowe, a zgadywanie haseł i tak nie ma szans. Ustawienie należy do własnego pliku w /etc/ssh/sshd_config.d/, a przed każdym restartem usługi stoi sprawdzenie składni:
sshd -t && systemctl restart ssh
sshd -T | grep -i permitrootlogin
passwd -l root to wariant ostrzejszy i do obrony tylko wtedy, gdy trzeci test powyżej wypadł pomyślnie. Polecenie blokuje wyłącznie logowanie hasłem: zapisany klucz SSH działa dalej, sudo -i również.
Czego odradzamy: odbierania rootowi powłoki logowania, na przykład przez usermod -s /usr/sbin/nologin root. Blokuje to nie tylko logowanie, lecz także sudo -i oraz awaryjną powłokę przy starcie systemu.
Typowe błędy i ich rozwiązania
kernel is not in the sudoers file.: użytkownik nie należy do żadnej grupy, dla której istnieje reguła, albo sesja jest starsza niż zmiana grup. Sprawdź id -nG kernel jako root, następnie getent group sudo, potem zaloguj się od nowa. Starsze wersje dopisują jeszcze zdanie o zgłoszonym incydencie.
sudo: 3 incorrect password attempts, mimo że wpisujesz poprawnie: konto nie ma w ogóle hasła, zwykle dlatego, że zostało założone z --disabled-password. passwd -S kernel pokazuje wtedy L albo NP, a passwd kernel rozwiązuje sprawę. Poza tym sudo pyta o hasło użytkownika wywołującego, a nie o hasło roota.
sudo: no tty present and no askpass program specified: nie ma terminala, na którym sudo mogłoby dopytać. Typowe przy ssh server 'sudo polecenie' oraz w cronjobach. Przy SSH pomaga ssh -t, w cronjobie wpis należy do crontaba roota.
sudo: /etc/sudoers.d/10-kernel is mode 0644, should be 0440: błędne uprawnienia pliku z regułą. chmod 0440 to naprawia; do tego czasu reguła nie działa.
/etc/sudoers.d/10-kernel: bad permissions, should be mode 0440: ta sama przyczyna, zgłoszona przez visudo -c. Używaj tego polecenia po każdej zmianie.
Plik z regułą w ogóle nie pojawia się w wyniku visudo -c: nazwa pliku zawiera kropkę albo kończy się tyldą. Zmień nazwę 10-kernel.conf na 10-kernel.
usermod: group 'sudo' does not exist: pracujesz na systemie z rodziny RHEL. Grupa administracyjna nazywa się tam wheel, co potwierdzi getent group wheel.
Permission denied (publickey) u nowego użytkownika, podczas gdy root loguje się dalej bez problemu: prawie zawsze chodzi o uprawnienia. /home/kernel/.ssh musi mieć 700, authorized_keys 600, oba muszą należeć do użytkownika, a katalog domowy nie może być zapisywalny dla grupy ani dla pozostałych. Przyczynę znajdziesz w journalu:
journalctl -t sshd -n 50 --no-pager
Szukasz wiersza, który zaczyna się od Authentication refused: bad ownership or modes for directory i wskazuje problematyczny katalog.
sudo: unable to resolve host srv01: Name or service not known: brakuje nazwy hosta w /etc/hosts. sudo mimo to działa, ale z zauważalnym opóźnieniem. Właściwy wpis znajdziesz w liście kontrolnej dla serwerów root.
A jeśli konto ma znowu zniknąć: gpasswd -d kernel sudo odbiera tylko uprawnienia, natomiast deluser --remove-home kernel względnie userdel -r kernel usuwa je razem z katalogiem domowym.
Różnice między dystrybucjami w skrócie
| System | Grupa | Cecha szczególna |
|---|---|---|
| Debian 13 (trixie) | sudo | w instalacjach minimalnych sudo często nie jest zainstalowane; adduser jest samodzielnym, interaktywnym narzędziem |
| Debian 12 (bookworm) | sudo | jak Debian 13 |
| Ubuntu 24.04 LTS | sudo | sudo obecne; przy cloud-init często istnieje już konto z uprawnieniami sudo; wiersz dla admin bez żadnego skutku |
| Ubuntu 22.04 LTS | sudo | jak Ubuntu 24.04 |
| AlmaLinux, Rocky, RHEL | wheel | grupa sudo nie istnieje; adduser to tylko inna nazwa dla useradd |
Wersja skrócona
- Zapewnij drogę powrotną: trzymaj otwartą drugą sesję roota, wypróbuj raz konsolę VNC w panelu klienta, znaj hasło roota.
apt-get install -y sudo, jeślicommand -v sudonic nie zwraca.adduser --disabled-password --gecos "" kernel, następniepasswd kernel, żeby konsola pozostała używalna.usermod -aG sudo kernel, w systemach z rodziny RHELwheel. Przełącznik-ajest obowiązkowy.- Przenieś klucz publiczny poleceniem
install: katalog 700, plik 600, właścicielem nowy użytkownik. - Własne reguły wyłącznie przez
visudo -fw/etc/sudoers.d/, nazwa pliku bez kropki, tryb 0440, na koniecvisudo -c. - Sprawdź:
sudo -l -U kernel, nowa sesja SSH,sudo id, logowanie w konsoli hasłem. - Dopiero potem bierz się za
PermitRootLogin.
Użytkownik z uprawnieniami sudo zdejmuje z ciebie ryzyko niezamierzonej katastrofy i usuwa najbardziej znaną nazwę użytkownika. Na otwarte porty pomaga firewall UFW, a na ataki, które wysycają łącze, wyłącznie filtrowanie w sieci przed serwerem, w przypadku KernelHost w centrum danych maincubes we Frankfurcie nad Menem. Na samym serwerze twoje zadanie pozostaje najmniejsze i zarazem najskuteczniejsze: żeby dokładnie jedno konto miało dokładnie te uprawnienia, których potrzebuje.
Najczęstsze pytania
Czy w ogóle potrzebuję osobnego użytkownika, jeśli pracuję na serwerze sam?
adduser czy useradd, co wybrać?
Czy grupa administracyjna nazywa się sudo, czy wheel?
Użytkownik jest w grupie, a sudo mimo to nie działa.
Czy NOPASSWD jest w porządku, jeśli tylko ja mam dostęp do serwera?
Mój plik w /etc/sudoers.d jest ignorowany. Z czego to wynika?
Czy nowy użytkownik potrzebuje hasła, jeśli loguję się wyłącznie kluczem?
Co zrobić, jeśli przy edycji sudoers odciąłem sobie dostęp?
2026 KernelHost GmbH. Wszelkie prawa zastrzeżone. Ten poradnik jest chroniony prawem autorskim. Publikowanie go w innych serwisach, w całości, we fragmentach lub w zmienionej formie, wymaga naszej pisemnej zgody. Cytaty z podaniem źródła i z linkiem są jak najbardziej mile widziane.

