UFW vzniklo proto, aby se firewall nastavil třemi příkazy, a to zvládá. Problém je jinde: ufw status ukazuje záměry, ne výsledek. Pravidlo může být v seznamu a přitom nezavírat vůbec nic — ze tří různých důvodů, a všechny tři se na skutečných serverech vyskytují pravidelně.

Začátek, při kterém se nezamknete

Na pořadí příkazů záleží. Nejdřív povolit SSH, potom zapínat:

sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow OpenSSH
sudo ufw enable

ufw enable před povolením SSH přeruší vaše vlastní sezení a dál zbývá jen konzole poskytovatele. Pokud je server už nastavený a nejste si jistí, držte otevřené druhé spojení, přežije nepovedenou úpravu.

Dívat se je třeba na podrobný stav, krátký skrývá výchozí politiku:

sudo ufw status verbose

Chyba první: pravidlo je, ale port je otevřený celému světu

Nejčastější řádek v cizích konfiguracích:

sudo ufw allow 3306

Takhle se otevírá MySQL „aby se dalo připojit z domova“ — a otevře se celému internetu. Správné varianty jsou dvě a obě jsou lepší:

sudo ufw allow from 203.0.113.25 to any port 3306

nebo, což je spolehlivější, službu vůbec ven nepouštět: bind-address = 127.0.0.1 v konfiguraci MySQL a přístup zvenčí přes SSH tunel. Firewall je druhá linie; první je to, aby služba nenaslouchala na veřejné adrese. Pravidlo v UFW lze omylem smazat, kdežto bind-address se sám nezmění.

Chyba druhá: IPv6

Pravidlo typu ufw allow from 203.0.113.25 se týká jen IPv4. Pokud má server adresu IPv6 — a většina VPS ji má a zapnutou — služba po ní zůstává dostupná. Poskytovatel adresu přidělil, vy si na ni nevzpomenete, skener o ní ví.

Ověřte, že je filtrace v6 vůbec zapnutá (IPV6=yes v /etc/default/ufw) a že služba nenaslouchá na :: zbytečně:

ss -tulpn | grep ':::'

Pravidla s výslovně uvedenou adresou je nutné zakládat pro obě verze protokolu zvlášť.

Chyba třetí: Docker

Nejmrzutější. Docker publikuje porty tak, že si dopisuje vlastní pravidla do řetězců iptables dřív než tam, kam zapisuje UFW. Výsledkem je, že kontejner spuštěný jako -p 5432:5432 je dostupný z internetu, i když UFW hlásí Status: active a politiku deny incoming. Firewall přitom není rozbitý — jen na něj nepřijde řada.

Neléčí se to v UFW, ale ve způsobu, jakým se port publikuje:

ports:
  - "127.0.0.1:5432:5432"

Navázání na lokální adresu je nejjednodušší a nejspolehlivější řešení. Ven má mířit jen to, co skutečně obsluhuje návštěvníky: obvykle porty 80 a 443 reverzní proxy.

Pořadí pravidel

UFW použije první vyhovující pravidlo a tím končí. Proto zákaz přidaný po povolení nezabere: na něj už řada nepřijde. Podíváme se na číslování a vložíme na správné místo:

sudo ufw status numbered
sudo ufw insert 1 deny from 198.51.100.0/24
sudo ufw delete 7

Pravidla se mažou podle čísla, ale čísla se po každém smazání posouvají — mažte po jednom a seznam si znovu načtěte.

Kontrola zvenčí

Místní příkazy ukazují, co je nastaveno. Co z toho skutečně vzešlo, je vidět jen z jiného stroje:

nmap -Pn -p- 203.0.113.25
nc -zv 203.0.113.25 3306

Postačí jakýkoli jiný server nebo domácí počítač. Je to jediná kontrola, která nelže, a stojí za to ji dělat po každé výraznější změně konfigurace — zvlášť po instalaci něčeho, co si „samo nastaví síť“: Docker, ovládací panely, VPN.

Logy

Ve výchozím stavu UFW nezapisuje téměř nic. Zapíná se to takto:

sudo ufw logging low

Záznamy putují do /var/log/ufw.log — ale jen pokud je v systému rsyslog. Na Debianu 12 a Ubuntu 24.04 tam být nemusí, a pak vše jde do žurnálu systemd:

sudo journalctl -k | grep -i '\[UFW'

Prázdný /var/log/ufw.log sám o sobě nic neznamená — podívejte se nejdřív do žurnálu.

Co od firewallu čekat

UFW zavírá to, co nemá být dostupné. Nezkoumá obsah požadavků na to, co je otevřené: port 443 je otevřený všem a vše, co na web přijde, přijde bez překážek. To je práce jiných nástrojů — WAF na úrovni aplikace, IDS na úrovni provozu. Úkol firewallu je skromnější a důležitější: aby seznam otevřených portů odpovídal tomu, co si o něm myslíte. Jak tento seznam vypadá spolu s aktivními pravidly na jedné stránce, ukazuje ukázka níže.