Konfiguracja nowego serwera root: lista kontrolna na pierwsze 30 minut

Opublikowano 14 min czytania

Pierwsze 30 minut na nowym serwerze root przesądza o reszcie. Dziewięć kroków we właściwej kolejności, wraz z pułapkami Debiana 13 i Ubuntu 24.04, których brakuje w większości poradników.

Nowy serwer root jest osiągalny od pierwszej sekundy i skanowany od pierwszej minuty. Automatyczne próby logowania na porcie 22 zaczynają się z doświadczenia wcześniej, niż zdążysz zalogować się po raz pierwszy. Ta lista doprowadza świeżo postawiony serwer w jakieś pół godziny do stanu, w którym możesz zostawić go działającego ze spokojnym sumieniem.

Wszystkie polecenia zakładają, że pracujesz jako root, dokładnie tak jak zaraz po udostępnieniu serwera. Gdy tylko zalogujesz się na swojego nowego użytkownika, dopisuj przed każdym poleceniem sudo. Kolejność została sprawdzona na Debianie 13 (trixie), Debianie 12 (bookworm), Ubuntu 24.04 LTS i Ubuntu 22.04 LTS. Tam, gdzie te cztery systemy się różnią, jest to zaznaczone.

Krok 0: zabezpiecz drogę odwrotu, zanim cokolwiek zmienisz

Jedyny błąd z tej listy, którego nie naprawisz przez SSH, to ten, który odbiera ci SSH. Dlatego przez najbliższe 30 minut obowiązuje jedna żelazna zasada: otwórz drugie okno terminala z aktywnym połączeniem SSH i nie zamykaj go. Istniejąca sesja SSH przeżywa zarówno restart usługi SSH, jak i włączenie firewalla. Jeśli po jakiejś zmianie nowe połączenie przestaje dochodzić do skutku, cofnij tę zmianę w sesji, która wciąż jest otwarta.

Powinieneś też wiedzieć, gdzie znajdziesz dostęp do konsoli swojego serwera, zanim naprawdę będzie ci potrzebny. W KernelHoście dotrzesz do niej w panelu klienta, niezależnie od SSH i niezależnie od firewalla. Kto szuka tej drogi dopiero wtedy, gdy już się zablokował, traci czas.

Dwa komunikaty błędów warto umieć od siebie odróżnić, bo wskazują na zupełnie różne przyczyny:

  • ssh: connect to host 203.0.113.10 port 22: Connection refused oznacza, że pakiet dotarł, ale nikt nie nasłuchuje na tym porcie. Usługa SSH nie działa albo nasłuchuje na innym porcie.
  • ssh: connect to host 203.0.113.10 port 22: Connection timed out oznacza, że pakiet został odrzucony. To prawie zawsze firewall.
  • Permission denied (publickey) oznacza, że usługa działa i firewall cię przepuszcza, tylko twój klucz nie pasuje.

Krok 1: aktualizacja systemu

Świeżo zainstalowany obraz rzadko bywa aktualny. Między zbudowaniem obrazu a twoim zamówieniem mija często kilka tygodni, w czasie których ukazały się aktualizacje bezpieczeństwa.

cat /etc/os-release
apt update
apt full-upgrade -y

full-upgrade zamiast upgrade to tutaj świadomy wybór: na świeżym systemie apt może usuwać pakiety, jeśli wymaga tego jakaś zależność. Na działającym systemie produkcyjnym najpierw sprawdziłbyś, co ma zostać usunięte.

Na Ubuntu 22.04 i 24.04 pakiet needrestart jest zainstalowany fabrycznie i przerywa aktualizację kolorowym pytaniem na pełnym ekranie o to, które usługi mają zostać zrestartowane. Jeśli tego nie chcesz, na przykład w skrypcie:

NEEDRESTART_MODE=a DEBIAN_FRONTEND=noninteractive apt full-upgrade -y

Potem posprzątaj i sprawdź, czy potrzebny jest restart:

apt autoremove --purge -y
apt list --upgradable
test -f /var/run/reboot-required && echo "restart wymagany" || echo "restart niewymagany"

Różnica między dystrybucjami: plik /var/run/reboot-required niezawodnie zakłada tylko Ubuntu, pochodzi on z pakietu update-notifier-common. Debian domyślnie w ogóle nie sygnalizuje potrzeby restartu. Na Debianie doinstaluj w tym celu needrestart: przy wywołaniu powie ci, czy czeka nowy kernel. Debian 13 przynosi dodatkowo nowszą generację apt, z kolorowym wyjściem ułożonym w kolumny, i to nie jest błąd, tylko kwestia przyzwyczajenia.

Kontrola skuteczności: apt list --upgradable nie wypisuje już nic poza nagłówkiem Listing.... Jeśli przy aktualizacji pojawia się komunikat Release file for ... is not valid yet, zegar twojego serwera chodzi źle: przeskocz do kroku 5, a potem powtórz krok 1.

Więcej na ten temat, także o postępowaniu z wstrzymanymi pakietami i zewnętrznymi źródłami: Aktualizacja serwera Linux przez apt.

Krok 2: załóż użytkownika, zamiast pracować jako root

Jako root się nie pracuje, bo każda literówka trafia od razu w cały system, a nazwę użytkownika root każdy atakujący i tak już zna. Na minimalnych obrazach Debiana sudo często nie jest nawet zainstalowane:

apt install -y sudo
adduser --disabled-password --gecos "" kernel
usermod -aG sudo kernel

Przełącznik --disabled-password zakłada użytkownika bez hasła, co przy logowaniu wyłącznie kluczem jest dokładnie tym, o co chodzi. Jeśli chcesz dodatkowo ustawić hasło, na przykład do sudo z konsoli, zrobisz to poleceniem passwd kernel.

Różnica między dystrybucjami: na Debianie i Ubuntu grupa administracyjna nazywa się sudo. Tylko jeśli przychodzisz z systemu z rodziny RHEL, szukasz wheel, a tej grupy tutaj nie ma.

Teraz klucz publiczny. Załóż katalog od razu z właściwymi uprawnieniami, bo błędne uprawnienia to najczęstsza przyczyna odrzucenia logowania kluczem:

mkdir -p /home/kernel/.ssh
chmod 700 /home/kernel/.ssh
touch /home/kernel/.ssh/authorized_keys
chmod 600 /home/kernel/.ssh/authorized_keys
chown -R kernel:kernel /home/kernel/.ssh

Zawartość swojego klucza publicznego wpisujesz do authorized_keys, a wygodniej zrobisz to ze swojej stacji roboczej poleceniem ssh-copy-id kernel@203.0.113.10.

Kontrola skuteczności, i to zanim przestawisz SSH:

id kernel
sudo -l -U kernel

Druga linijka musi zawierać (ALL : ALL) ALL. Zaloguj się potem w trzecim oknie jako kernel i wykonaj raz sudo -v. Dopiero gdy to zadziała, idziesz dalej. Szczegóły: Zakładanie użytkownika i konfiguracja sudo oraz Tworzenie i wgrywanie kluczy SSH.

Krok 3: zabezpieczenie SSH

Na bardzo odchudzonych obrazach Debiana serwer SSH nie jest nawet zainstalowany, wtedy najpierw go doinstaluj:

apt install -y openssh-server

Wszystkie cztery omawiane tu systemy czytają dodatkową konfigurację z /etc/ssh/sshd_config.d/. Nie edytuj więc wielkiego sshd_config, tylko załóż własny plik. Ten przeżyje aktualizacje pakietów bez żadnego pytania.

Szczegół, który niemal wszystkie poradniki podają błędnie: w konfiguracji SSH wygrywa pierwsza znaleziona wartość, a nie ostatnia. Wiersz Include /etc/ssh/sshd_config.d/*.conf stoi na Debianie i Ubuntu zupełnie na górze, a pliki z tego katalogu są czytane w kolejności alfabetycznej. Na obrazach Ubuntu leży tam często już 50-cloud-init.conf z wpisem PasswordAuthentication yes. Plik o nazwie 99-... pozostałby więc bez efektu. Sprawdź najpierw, co już tam jest:

ls -l /etc/ssh/sshd_config.d/
cat > /etc/ssh/sshd_config.d/10-kernelhost.conf <<'EOF'
PermitRootLogin prohibit-password
PasswordAuthentication no
KbdInteractiveAuthentication no
PubkeyAuthentication yes
X11Forwarding no
MaxAuthTries 3
EOF

prohibit-password zamiast no to świadoma decyzja: root nadal może zalogować się kluczem, ale nigdy hasłem. To ratuje sytuację, gdy coś pójdzie nie tak z użytkownikiem od sudo. Kto chce zabezpieczyć się ostrzej, ustawia no, ale powinien wtedy naprawdę przetestować dostęp przez konsolę.

Przed każdym restartem usługi sprawdź składnię:

ssh-keygen -A
sshd -t && echo "konfiguracja ok"
sshd -T | grep -E "^(permitrootlogin|passwordauthentication|pubkeyauthentication|port) "

sshd -T pokazuje wartości faktycznie obowiązujące, po rozwinięciu wszystkich plików dołączanych. To jedyny wiarygodny dowód, że twoja zmiana doszła do skutku. Jeśli polecenie zgłosi sshd: no hostkeys available -- exiting, brakuje kluczy hosta, a ssh-keygen -A je wygeneruje. Jeśli natomiast sprawdzenie przerwie się komunikatem Missing privilege separation directory: /run/sshd, usługa od startu systemu nie działała ani razu i brakuje katalogu czasu wykonania. Zakłada go mkdir -p /run/sshd albo systemctl restart ssh, po czym sshd -t znowu ocenia twoją konfigurację.

Jedna z odpowiedzi regularnie wprowadza w błąd: dla ustawienia PermitRootLogin prohibit-password polecenie sshd -T wypisuje wiersz permitrootlogin without-password. To ta sama wartość pod swoją starszą nazwą, a nie sygnał, że twoje ustawienie nie zadziałało.

Dopiero potem:

systemctl restart ssh

Pułapka socketu na Ubuntu 24.04 i Debianie 13

Od Ubuntu 22.10, a więc także w 24.04, SSH startuje przez aktywację socketem. Skutek: wiersz Port w konfiguracji sshd zostaje zignorowany, port bierze się z ssh.socket. Kto chce zmienić port, potrzebuje nakładki systemd:

systemctl edit ssh.socket

A do środka trafia to, co poniżej, przy czym pusty pierwszy wiersz kasuje ustawienie domyślne:

[Socket]
ListenStream=
ListenStream=0.0.0.0:2222
ListenStream=[::]:2222

Następnie systemctl daemon-reloadsystemctl restart ssh.socket. Ubuntu 22.04 jeszcze tego nie zna, tam wystarczy wiersz Port w konfiguracji.

Na Debianie 13 pojawia się pokrewna osobliwość. Część świeżych obrazów ma aktywny ssh.socket, a systemy podniesione z Debiana 12 już nie. Jeśli oba są aktywne naraz, przeładowanie kończy się błędem fatal: Cannot bind any address., bo usługa i socket biją się o port 22. Sprawdź to i w razie wątpliwości zdecyduj:

systemctl is-enabled ssh.socket
systemctl disable --now ssh.socket
systemctl enable --now ssh.service

Kontrola skuteczności: ss -tlnp | grep ssh pokazuje oczekiwany port, a nowa próba połączenia ze świeżego okna dochodzi do skutku. Obszernie: Zabezpieczanie SSH i wyłączanie logowania na roota oraz Zmiana portu SSH.

Krok 4: włączenie firewalla

Na Ubuntu ufw jest zainstalowany, ale nieaktywny. Na minimalnych obrazach Debiana brakuje go w ogóle. Kolejność ma tu znaczenie życiowe: najpierw zezwól na SSH, dopiero potem włączaj.

apt install -y ufw
ufw default deny incoming
ufw default allow outgoing
ufw allow 22/tcp
ufw allow 80/tcp
ufw allow 443/tcp
ufw enable

Ostatnie polecenie jest najważniejsze z całej listy. Same reguły i polityki domyślne niczego nie filtrują, dopiero ufw enable uzbraja firewall. Kto je pominie, ma na koniec w pełni skonfigurowany, ale całkowicie bezużyteczny firewall.

Przy włączaniu ufw pyta: Command may disrupt existing ssh connections. Proceed with operation (y|n)?. To ostrzeżenie jest poważne, ale jeśli reguła dla portu 22 (albo twojego zmienionego portu) stoi wcześniej, nic się nie stanie, i właśnie dlatego ufw allow 22/tcp figuruje na liście powyżej ufw enable. Jeśli w kroku 3 zmieniłeś port, musi tu stać ufw allow 2222/tcp, inaczej sam się zablokujesz. W skrypcie albo w sesji nieinteraktywnej użyj ufw --force enable, co pomija pytanie.

Kontrola skuteczności:

ufw status verbose

Oczekiwany jest Status: active, pod spodem Default: deny (incoming), allow (outgoing), a na liście reguł wiersz 22/tcp ALLOW IN dla twojego portu SSH. Jeśli nadal stoi tam Status: inactive, zabrakło ufw enable i nic nie jest chronione, niezależnie od tego, jak kompletnie wyglądają reguły. Otwórz potem nowe okno i połącz się, zanim zamkniesz stare.

Do kompletu dochodzi jeszcze mechanizm blokujący powtarzane próby logowania:

apt install -y fail2ban python3-systemd
cat > /etc/fail2ban/jail.local <<'EOF'
[DEFAULT]
backend = systemd
bantime = 1h
findtime = 10m
maxretry = 5

[sshd]
enabled = true
EOF

Dlaczego backend = systemd: Debian od wersji 12 nie instaluje już razem rsysloga, nie ma więc pliku /var/log/auth.log. Domyślny backend = auto szuka dokładnie tego pliku, a fail2ban wtedy w ogóle nie startuje, z komunikatem Failed during configuration: Have not found any log file for sshd jail. Pakiet python3-systemd jest warunkiem tego, żeby dostęp do journala w ogóle działał. Na Ubuntu 22.04 i 24.04 plik jeszcze istnieje dzięki rsyslogowi, ale wariant z systemd działa tam równie dobrze i jest wyborem na przyszłość. Sprawdzisz to tak:

test -f /var/log/auth.log && echo "auth.log istnieje" || echo "brak auth.log, potrzebny backend systemd"
fail2ban-client -t

Kontrola skuteczności: fail2ban-client status sshd pokazuje wiersz Currently banned. Jeśli zamiast tego pojawia się Sorry but the jail 'sshd' does not exist, konfiguracja nie została wczytana. Więcej w artykułach Konfiguracja firewalla UFW oraz Konfiguracja Fail2ban.

Krok 5: strefa czasowa i godzina

Źle chodzący zegar czyni logi bezwartościowymi, wywraca sprawdzanie certyfikatów i potrafi zablokować apt komunikatem Release file is not valid yet. Na prawdziwym serwerze:

timedatectl set-timezone Europe/Vienna
timedatectl status

W wyniku muszą zgadzać się dwa wiersze: Time zone: Europe/Vienna oraz System clock synchronized: yes, a do tego NTP service: active. Jeśli stoi tam NTP service: inactive, nie działa żadna synchronizacja czasu. Ubuntu przynosi systemd-timesyncd domyślnie, minimalne obrazy Debiana często nie:

DEBIAN_FRONTEND=noninteractive apt install -y systemd-timesyncd tzdata
date

Wielu operatorów świadomie trzyma serwery na UTC, żeby logi z różnych lokalizacji dawały się porównywać. Oba podejścia da się obronić, kluczowe jest to, żebyś o tym wiedział. Jeśli timedatectl nie jest dostępne w środowisku kontenerowym, da się to zrobić także klasycznie:

ln -sf /usr/share/zoneinfo/Europe/Vienna /etc/localtime
dpkg-reconfigure -f noninteractive tzdata

Pogłębienie tematu: Konfiguracja strefy czasowej i synchronizacji czasu.

Krok 6: ustawienie nazwy hosta

Nazwa hosta pojawia się w logach, w wychodzących e-mailach i w komunikatach monitoringu. Ustaw ją wcześnie, inaczej wszystkie twoje serwery będą później nazywać się tak samo.

hostnamectl set-hostname srv01.twoja-domena.pl
hostname -f

Do tego należy jeszcze pasujący wpis w /etc/hosts, inaczej przy każdym wywołaniu sudo przywita cię komunikat sudo: unable to resolve host srv01: Name or service not known, i to z wyraźnym opóźnieniem. Wiersz wygląda mniej więcej tak: 127.0.1.1 srv01.twoja-domena.pl srv01.

Pułapka: na obrazach z cloud-init, co przy Ubuntu jest regułą, nazwa hosta zostaje przy następnym restarcie przestawiona z powrotem. Przełącznik, który temu zapobiega:

command -v cloud-init || echo "cloud-init nie jest zainstalowany"
mkdir -p /etc/cloud/cloud.cfg.d
printf 'preserve_hostname: true\n' > /etc/cloud/cloud.cfg.d/99_hostname.cfg

Kontrola skuteczności: po restarcie hostnamectl nadal podaje twoją nazwę. Szczegóły: Trwała zmiana nazwy hosta w Linuksie.

Krok 7: automatyczne aktualizacje bezpieczeństwa

Najniebezpieczniejszy jest ten serwer, którego nikt już nie dotyka. Automatyczne aktualizacje bezpieczeństwa to najskuteczniejszy pojedynczy krok z tej listy.

apt install -y unattended-upgrades
cat > /etc/apt/apt.conf.d/20auto-upgrades <<'EOF'
APT::Periodic::Update-Package-Lists "1";
APT::Periodic::Unattended-Upgrade "1";
EOF

Sama instalacja pakietu nie wszędzie wystarcza, dopiero ten plik uzbraja codzienny przebieg. Własne dostrojenia trafiają do pliku o wyższym numerze niż dostarczony 50unattended-upgrades, żeby wygrywały i nie zostały nadpisane przy aktualizacji pakietu:

cat > /etc/apt/apt.conf.d/52unattended-upgrades-local <<'EOF'
Unattended-Upgrade::Automatic-Reboot "false";
Unattended-Upgrade::Remove-Unused-Kernel-Packages "true";
Unattended-Upgrade::MinimalSteps "true";
EOF

Domyślnie narzędzie na obu dystrybucjach ciągnie tylko ze źródła bezpieczeństwa, a nie zwykłe aktualizacje. To zamierzone i dla systemów produkcyjnych zwykle dokładnie właściwe. Jeśli ustawisz Automatic-Reboot "true", koniecznie ustaw też godzinę, inaczej serwer zrestartuje się wtedy, kiedy będzie pasowało zegarowi zadań.

Kontrola skuteczności: próbny przebieg pokazuje, które pakiety wchodziłyby w grę, bez instalowania czegokolwiek. Zwróć uwagę na liczbę pojedynczą w nazwie polecenia:

unattended-upgrade --dry-run --debug
apt-config dump | grep -iE "unattended|periodic"

W logu pod /var/log/unattended-upgrades/ musi po pierwszym przebiegu coś stać. Jeśli pozostaje pusty, konfiguracja nie działa. Obszernie: Konfiguracja automatycznych aktualizacji bezpieczeństwa.

Krok 8: monitoring

Monitoring w pierwszych 30 minutach nie oznacza budowania Grafany. Oznacza tyle, że dowiesz się, gdy serwer stanie albo gdy zapełni się dysk.

apt install -y htop tmux curl
df -h /
free -m

Na początek wystarczą trzy rzeczy. Po pierwsze zewnętrzny test osiągalności, który sprawdza serwer z zewnątrz i powiadamia cię, bo serwer, który padł, nie wyśle już ostrzeżenia o samym sobie. Po drugie ostrzeżenie o kończącym się miejscu na dysku, bo pełny system plików to najczęstsza przyczyna awarii, których nikt nie widział nadchodzących. Po trzecie zajrzenie do journala, gdy coś wygląda dziwnie:

journalctl -p 3 -b --no-pager | tail -n 30
systemctl --failed

systemctl --failed powinno wypisać 0 loaded units listed. Każdy wiersz w tym miejscu to usługa, która nie startuje i którą chcesz naprawić teraz, a nie za trzy miesiące. Więcej na ten temat: Konfiguracja monitoringu serwera.

Krok 9: kopia zapasowa, zanim będzie co tracić

Najlepszy moment na pierwszą kopię zapasową jest wtedy, gdy nie ma jeszcze danych. Wtedy ćwiczysz cały przebieg bez presji. Dwie rzeczy warto zapisać na bok od razu, bo ich odtworzenie kosztuje najwięcej czasu: konfigurację z /etc oraz listę zainstalowanych pakietów.

tar -czf /root/etc-backup-$(date +%F).tar.gz /etc
dpkg --get-selections > /root/pakiety.txt
tar -tzf /root/etc-backup-$(date +%F).tar.gz | wc -l

To jeszcze nie jest kopia zapasowa, tylko kopia na tym samym nośniku. Kopia zapasowa leży na innym systemie, najlepiej w innym miejscu. Narzędzie z szyfrowaniem i deduplikacją powtarzających się bloków opłaca się od pierwszego dnia:

apt install -y borgbackup
borg --version

Niewygodna prawda: kopia zapasowa, z której nigdy niczego nie odtworzono, jest tylko przypuszczeniem. Zarezerwuj sobie termin na pierwsze odtworzenie i przywróć pojedynczy plik. Drogę do tego opisuje Strategia kopii zapasowych dla serwerów root.

Jeśli sam się zablokujesz

To się zdarza, najczęściej w kroku 3 albo 4. Droga powrotna jest zawsze ta sama: zaloguj się przez konsolę w panelu klienta, tam nazwą użytkownika i hasłem zamiast kluczem. Potem, zależnie od przyczyny:

  • Firewall zbyt surowy: ufw disable, popraw regułę, ufw enable.
  • Zepsuta konfiguracja SSH: rm /etc/ssh/sshd_config.d/10-kernelhost.conf, potem sshd -t oraz systemctl restart ssh.
  • Zły port po zmianie socketu: systemctl revert ssh.socket cofa nakładkę, następnie systemctl daemon-reloadsystemctl restart ssh.socket.
  • Zablokowany przez fail2ban: fail2ban-client set sshd unbanip 203.0.113.10. Żeby to się nie powtórzyło, wpisz swój stały adres pod ignoreip w pliku jail.local.
  • Klucz jest odrzucany: prawie zawsze chodzi o uprawnienia. chmod 700 na katalog, chmod 600 na plik, a jedno i drugie musi należeć do użytkownika, nie do roota.

Kontrola końcowa

To, że polecenie nie zwróciło błędu, nie znaczy jeszcze, że zadziałało. Te sześć sprawdzeń pokazuje faktyczny stan:

  1. sshd -T | grep -E "^(permitrootlogin|passwordauthentication|port) " pokazuje wartości obowiązujące, a nie te, których sobie życzysz.
  2. ufw status verbose zgłasza Status: active wraz z regułą dla twojego portu SSH.
  3. timedatectl status zgłasza System clock synchronized: yes.
  4. systemctl --failed nie wypisuje niczego.
  5. unattended-upgrade --dry-run --debug przechodzi bez komunikatu o błędzie.
  6. Nowe połączenie SSH ze świeżo otwartego okna dochodzi do skutku, kluczem, bez pytania o hasło.

Dopiero gdy punkt szósty siedzi, wolno ci zamknąć stare okno terminala.

Co dalej

Słowo o wyborze dystrybucji, bo decyduje on o najbliższych latach. Debian 12 od lipca 2026 jest poza regularnym wsparciem i do połowy 2028 roku będzie utrzymywany przez zespół LTS, z ograniczonym zakresem pakietów. Kto stawia system dzisiaj, bierze Debiana 13 albo Ubuntu 24.04 LTS. Ubuntu 22.04 LTS ma standardowe wsparcie jeszcze do 2027 roku, ale dla serwera, który ma działać latami, nie jest już pierwszym wyborem. Debian 10 i Ubuntu 20.04 skończyły się ostatecznie odpowiednio w czerwcu 2024 i maju 2025 roku, i nie mają czego szukać na nowym serwerze.

Praktyczne znaczenie mają też różnice wersji w repozytoriach. Debian zasadniczo nie dostarcza mysql-server, standardem jest tam MariaDB. Kto potrzebuje konkretnej wersji PHP, Node albo Javy, lepiej sprawdzi wcześniej, co przynosi dystrybucja, zamiast później podpinać zewnętrzne źródła. A jeśli już podpinasz zewnętrzne źródła: apt-key jest wycofany, klucze należą do /etc/apt/keyrings/ i są wskazywane we wpisie źródła przez signed-by.

W ten sposób stoi serwer, który jest zaktualizowany, sam się aktualizuje, wpuszcza tylko ciebie i zgłasza się, gdy coś jest nie tak. Wszystko dalsze, serwer WWW, baza danych, certyfikaty, buduje się na tym, a nie obok.

Najczęstsze pytania

W jakiej kolejności konfigurować nowy serwer root?
Najpierw zaktualizuj system, potem załóż użytkownika z uprawnieniami sudo i wgranym kluczem SSH, następnie zabezpiecz SSH, a na końcu włącz firewall. Dopiero po tym przychodzą strefa czasowa, nazwa hosta, automatyczne aktualizacje bezpieczeństwa, monitoring i kopia zapasowa. Ważne jest tylko jedno: użytkownik i klucz muszą działać, zanim wyłączysz logowanie hasłem, a reguła dla SSH musi stać w firewallu, zanim go włączysz.
Dlaczego moja zmiana w sshd_config nie działa?
Na Debianie i Ubuntu wiersz Include /etc/ssh/sshd_config.d/*.conf stoi zupełnie na górze pliku sshd_config, a w konfiguracji SSH wygrywa pierwsza znaleziona wartość. Plik taki jak 50-cloud-init.conf bije więc zarówno plik główny, jak i twój własny plik o wyższym numerze. Sprawdź poleceniem sshd -T, które wartości faktycznie obowiązują, i nazwij swój plik niższym numerem, na przykład 10-kernelhost.conf.
Dlaczego port SSH na Ubuntu 24.04 się nie zmienia?
Od Ubuntu 22.10 SSH startuje przez aktywację socketem. Port bierze się wtedy z ssh.socket, a wiersz Port w konfiguracji sshd zostaje zignorowany. Potrzebujesz nakładki systemd przez systemctl edit ssh.socket, z pustym wierszem ListenStream kasującym ustawienie domyślne, a dopiero za nim z wartością, której chcesz. Na Ubuntu 22.04 nadal wystarczy wiersz Port.
Fail2ban nie startuje i zgłasza, że nie znalazł pliku logu dla jaila sshd. Co robić?
Debian od wersji 12 nie instaluje już razem rsysloga, dlatego plik /var/log/auth.log nie istnieje. Ustaw w /etc/fail2ban/jail.local pod [DEFAULT] wpis backend = systemd i doinstaluj pakiet python3-systemd. Wtedy fail2ban czyta bezpośrednio z journala. Sprawdzisz to poleceniem fail2ban-client -t, a następnie fail2ban-client status sshd.
Dlaczego po restarcie nazwa hosta znowu znika?
Na obrazach z cloud-init, co przy Ubuntu jest regułą, nazwa hosta jest ustawiana od nowa przy każdym starcie. Załóż plik /etc/cloud/cloud.cfg.d/99_hostname.cfg z wierszem preserve_hostname: true, a twoje ustawienie zostanie zachowane. Uzupełnij dodatkowo pasujący wpis w /etc/hosts, inaczej sudo przy każdym wywołaniu zgłosi, że nie potrafi rozwiązać nazwy hosta.
Czy wystarczy apt upgrade, czy potrzebuję apt full-upgrade?
Na świeżo udostępnionym serwerze lepszym wyborem jest full-upgrade, bo wgrywa także aktualizacje, dla których trzeba usunąć albo zastąpić pakiety. Na działającym systemie produkcyjnym najpierw sprawdź przez apt list --upgradable oraz symulację, co by się stało, a dopiero potem uruchom full-upgrade.

Serwer root Konfiguracja serwera Linux SSH Firewall Debian Ubuntu Bezpieczeństwo serwera Lista kontrolna