Čerstvě naklikaný server je terčem dřív, než se stihnete rozkoukat. Automatizované skenery projíždějí celé rozsahy IP a nepřetržitě zkoušejí root a slovníková hesla na portu 22 — první pokusy obvykle dorazí během pár minut od prvního bootu. Nejde o to jestli, ale kdy. Dobrá zpráva: základní hardening, který tenhle šum spolehlivě odfiltruje, zvládnete za zhruba 20 minut a bez jediného externího nástroje. Všechno níže platí pro Debian 12 (Bookworm) a Ubuntu 22.04 LTS a novější; příkazy spouštíte jako root nebo přes sudo.

Než začnete, aktualizujte systém:

apt update && apt full-upgrade -y

1. Neprivilegovaný uživatel se sudo

Pod rootem se pracovat nemá. Chcete běžný účet a práva zvyšovat jen tam, kde je to potřeba — omezíte tím dopad překlepu i případného kompromitovaného procesu.

Na minimální instalaci Debianu 12 balíček sudo nemusí být přítomen, doinstalujte ho:

apt install -y sudo
adduser tomas
usermod -aG sudo tomas

adduser interaktivně nastaví heslo a domovský adresář. Na Debianu i Ubuntu uděluje práva sudo členství ve skupině sudo (ne wheel, jak to znáte z RHEL). Ověřte, že to funguje — přihlaste se jako nový uživatel a zkuste sudo whoami, mělo by vrátit root.

2. SSH klíče místo hesel

Heslo se dá uhodnout, klíč prakticky ne. Na svém počítači (ne na serveru) si vygenerujte pár klíčů:

ssh-keygen -t ed25519 -C "tomas@notebook"

Ed25519 je moderní, rychlý a krátký; pokud potřebujete kompatibilitu se starším HW, sáhněte po -t rsa -b 4096. Veřejný klíč nahrajte na server:

ssh-copy-id tomas@IP_SERVERU

Pokud ssh-copy-id nemáte, stačí obsah ~/.ssh/id_ed25519.pub vložit do ~/.ssh/authorized_keys nového uživatele na serveru. Pak zkontrolujte oprávnění. SSH má ve výchozím stavu (StrictModes yes je na Debianu 12 i Ubuntu 22.04+ zapnuté) přísné pravidlo: klíč odmítne, jakmile jsou ~/.ssh, authorized_keys nebo dokonce samotný domovský adresář zapisovatelné pro skupinu či ostatní, případně patří někomu jinému než danému uživateli. Hodnoty 700 a 600 tuhle podmínku spolehlivě splní:

chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys

Nejde o to trefit přesně tahle čísla — .ssh se 750 a authorized_keys se 640 SSH taky přijme. Rozhodující je, aby nic na cestě nebylo zapisovatelné pro skupinu ani ostatní. Nejčastější past je právě domovský adresář: i s dokonalými právy na .ssh přihlášení selže, když je ~ zapisovatelný pro skupinu.

Teď se v novém okně zkuste přihlásit klíčem. Funguje to bez zadání hesla? Skvěle, pokračujeme. Původní relaci nechte pro jistotu otevřenou.

3. Zákaz root loginu a přihlášení heslem

Tohle je nejúčinnější krok — když nejde přihlásit heslem, celé to bruteforce divadlo je zbytečné. Chcete nastavit tyhle čtyři direktivy:

PermitRootLogin no
PasswordAuthentication no
PubkeyAuthentication yes
KbdInteractiveAuthentication no

Kam je zapsat, je ale zrádnější, než vypadá. Debian 12 i Ubuntu 22.04 mají v /etc/ssh/sshd_config úplně nahoře řádek Include /etc/ssh/sshd_config.d/*.conf a v SSH konfiguraci vyhrává první nalezená hodnota. Drop-iny se tak načtou dřív než tělo hlavního souboru a mezi sebou v abecedním pořadí. Cloudové image Ubuntu do téhle složky běžně přibalí soubor (typicky 50-cloud-init.conf) s PasswordAuthentication yes — a ten vaši editaci hlavního souboru tiše přebije. Pouhá změna /etc/ssh/sshd_config pak PasswordAuthentication no reálně nezapne.

Nejjistější je konfliktní řádek zneškodnit přímo u zdroje: v 50-cloud-init.conf ho odstraňte nebo přepište na no. Pozor na pořadí — vlastní drop-in pojmenovaný 99-hardening.conf by 50-cloud-init.conf nepřebil (řadí se až za něj, a vyhrává první hodnota); musel by se jmenovat tak, aby se načetl dřív, třeba 00-hardening.conf. Ať zvolíte cokoli, nespoléhejte na to, co jste napsali, a ověřte, co server reálně používá:

sshd -t                       # kontrola syntaxe, musí být bez výstupu
sshd -T | grep -Ei 'passwordauthentication|permitrootlogin|pubkeyauthentication|kbdinteractive'

sshd -T vypíše efektivní konfiguraci se všemi drop-iny. Vidíte-li passwordauthentication yes, najděte viníka v /etc/ssh/sshd_config.d/ a opravte ho tam. Až hodnoty sedí, restartujte službu:

systemctl restart ssh

Nikdy se neodhlašujte z aktuální relace, dokud si druhým oknem neověříte, že se stále dostanete dovnitř.

4. Firewall ufw

ufw je jen přívětivá nadstavba nad nftables/iptables — smysl dává mít otevřené jen to, co skutečně používáte. Default deny na příchozím provozu je základ.

apt install -y ufw
ufw default deny incoming
ufw default allow outgoing
ufw allow OpenSSH
ufw enable
ufw status verbose

ufw allow OpenSSH používá aplikační profil, který otevře port 22/tcp; ekvivalent je ufw allow 22/tcp. Povolte SSH dřív, než firewall zapnete, jinak si sami zabouchnete dveře. Web server pak doplníte třeba přes ufw allow 'Nginx Full' nebo ufw allow 80,443/tcp.

5. fail2ban proti bruteforce

I s vypnutými hesly stojí za to zahazovat opakované pokusy — ušetříte logy i CPU a zablokujete otravné skenery. Nainstalujte ho:

apt install -y fail2ban

Na Debianu 12 je po instalaci jail sshd zapnutý automaticky přes /etc/fail2ban/jail.d/defaults-debian.conf, ale výchozí hodnoty jsou volné. Vlastní nastavení nikdy nepište do jail.conf (přepíše ho update) — vytvořte /etc/fail2ban/jail.local:

[sshd]
enabled  = true
backend  = systemd
maxretry = 5
findtime = 10m
bantime  = 1h

backend = systemd čte záznamy přímo z journalu — na Debianu 12, kde logování obstarává systemd-journald, se tím vyhnete situaci, kdy fail2ban nenajde /var/log/auth.log a jail spadne. fail2ban rozumí zkráceným časům jako 10m nebo 1h. Aktivujte a zkontrolujte:

systemctl enable --now fail2ban
fail2ban-client status sshd

Výstup ukáže počet nalezených a aktuálně zabanovaných IP. Pravidlo maxretry = 5 znamená pět chyb během findtime, poté ban na bantime.

6. Automatické bezpečnostní aktualizace

Neaktualizovaný server stárne každý den. unattended-upgrades umí bezpečnostní záplaty instalovat sám, takže nezáleží na tom, jestli se k serveru dostanete včas. Balíček nainstalujete takto:

apt install -y unattended-upgrades

Samotná instalace ale automatické aktualizace ještě nezapne — zejména na Debianu 12 je po ní funkce většinou vypnutá. Aktivuje ji až druhý krok:

dpkg-reconfigure --priority=low unattended-upgrades

Na dotaz odpovězte Yes. Reconfigure vytvoří /etc/apt/apt.conf.d/20auto-upgrades s dvojicí:

APT::Periodic::Update-Package-Lists "1";
APT::Periodic::Unattended-Upgrade "1";

Co se instaluje, řídí /etc/apt/apt.conf.d/50unattended-upgrades; ve výchozím stavu jsou povolené právě bezpečnostní zdroje (-security, resp. Debian-Security). Suchý běh si vyzkoušíte bez rizika:

unattended-upgrades --dry-run --debug

Některé aktualizace (jádro, knihovny) se projeví až po restartu. Pokud vám to provoz dovolí, povolte v 50unattended-upgrades automatický reboot v tichých hodinách:

Unattended-Upgrade::Automatic-Reboot "true";
Unattended-Upgrade::Automatic-Reboot-Time "03:00";

Shrnutí

Za dvacet minut jste odstranili drtivou většinu útočné plochy, kterou skenery zneužívají:

Krok Co řeší
sudo uživatel konec práce pod rootem
SSH klíče žádné hádatelné heslo
zákaz root/heslo loginu bruteforce nemá kam
ufw otevřené jen nutné porty
fail2ban zahazování zbytku šumu
unattended-upgrades záplaty bez lidského zásahu

Není to všechno, co se dá udělat — přidat můžete nestandardní SSH port, 2FA, centralizované logy nebo monitoring. Ale tohle je ten minimální základ, který má být na každém produkčním serveru, a bez něj nemá smysl řešit nic dalšího.

Klíčová zásada na závěr: měňte jednu věc, ověřte, že se pořád přihlásíte, a teprve pak pokračujte. Nejlepší server je totiž ten, ze kterého se sami nevyhodíte.