Firewall

firewalld, nftables, zóny, porty.

Firewall je vrátný tvého počítače — dívá se na každý síťový paket, co přichází nebo odchází, a podle pravidel rozhodne, jestli ho pustí dál, nebo zahodí. Pravidla se ptají na jednoduché věci: na jaký port to jde? jakým protokolem? odkud to přišlo? Základní filozofie, kterou uvidíš všude: co není výslovně povoleno, je zakázáno. Až pochopíš rozdíl mezi „runtime" a „permanent" pravidlem a proč se nikdy nesmíš zavřít z vlastního SSH, přestane pro tebe být firewall strašák.


Pár pojmů na úvod

  • Paket = malá porce dat putující po síti. Firewall se rozhoduje paket po paketu, ne „spojení jako celek" (i když umí sledovat i stav spojení — viz stateful).
  • Port = číslo (0–65535), které rozlišuje službu na jednom stroji. 22 = SSH, 80 = HTTP, 443 = HTTPS, 5432 = PostgreSQL. IP adresa řekne který stroj, port řekne která služba na něm.
  • Protokol = jak se data přenášejí. TCP (spolehlivé, s potvrzováním — web, SSH), UDP (rychlé, bez záruk — DNS, hry, VPN).
  • Default deny incoming = výchozí pravidlo „nikoho zvenku dovnitř nepouštěj, dokud to výslovně nepovolím". Standard pro každý bezpečný stroj.
  • Allow outgoing = odchozí provoz se většinou nechává volný (tvůj prohlížeč se potřebuje připojit ven). Firewall hlídá hlavně to, co jde dovnitř.
  • Stateful firewall = pamatuje si navázaná spojení. Když se sám připojíš ven, odpověď se automaticky pustí zpátky — nemusíš na ni psát pravidlo.
  • Zóna (firewalld) = pojmenovaná sada pravidel podle důvěryhodnosti sítě: public (kavárna, nedůvěřuj), home (domácí síť, uvolněnější), trusted (pusť všechno).

Co firewall vlastně dělá

Představ si stroj s běžícími službami. Každá služba naslouchá na nějakém portu. Bez firewallu je každý naslouchající port dostupný komukoli, kdo se k tobě dosáhne po síti. To je problém: často běží víc služeb, než tušíš (databáze, dev server, tiskový démon), a ne všechny mají být vidět z internetu.

Firewall se postaví před ně a filtruje provoz podle pravidel. Pravidlo je v jádru jednoduchá podmínka:

„Paket na port 443, protokolem TCP, ze kterékoli adresy → povol." „Cokoli jiného příchozího → zahoď."

Klíčová myšlenka je default deny incoming / allow outgoing:

  • Příchozí (incoming) — výchozí zahodit. Otevíráš jen to, co skutečně musí být zvenku vidět.
  • Odchozí (outgoing) — výchozí povolit. Tvůj počítač se běžně připojuje ven (updaty, web, DNS) a blokovat to bys musel s rozmyslem, jinak si rozbiješ půlku systému.

Tím pádem otevřený port = tvoje vědomé rozhodnutí, ne náhoda. To je celý smysl.


Vrstvy: kdo je pod kým

Tady začátečníky mate, že „firewall" v Linuxu není jedna věc, ale vrstvy nad sebou. Všechny nakonec sahají do stejného místa v jádře — liší se jen tím, jak pohodlně se ovládají.

  • nftables = moderní vrstva přímo v jádře, která provádí vlastní filtrování. Nahradila starší mechanismus. Většinou s ní nepracuješ ručně — sedí dole a poslouchá, co jí pošlou vrstvy nad ní.
  • firewalld = pohodlný nástroj nad tím (výchozí na distribucích z rodiny RHEL/Fedora a na openSUSE; na Ubuntu je populární obdoba ufw). Zavádí zóny a služby, takže místo psaní syrových pravidel řekneš „v zóně public povol službu ssh". Přeloží to dolů na nftables za tebe.
  • iptables = starší nástroj se syntaxí řetězců pravidel (INPUT, OUTPUT, FORWARD). Na moderních systémech často jen fasáda, která pod kapotou taky mluví s nftables. Potkáš ho ve starších návodech a na starších serverech.

💡 Nepleť si to s „která je nejlepší". Je to stack: nftables dělá práci, firewalld/iptables jsou jen dvě různá rozhraní k ní. Používej to, co má tvá distribuce jako výchozí (firewalld, nebo ufw na Ubuntu) a máš vystaráno — principy (default deny, povol jen co nabízíš) jsou všude stejné.


firewalld prakticky

Kde je firewalld výchozí, běží jako služba. Pár příkazů pokryje skoro vše. (Většina z nich chce sudo.)

Podívej se, co je aktuálně nastavené:

firewall-cmd --state              # běží vůbec firewall?
firewall-cmd --get-active-zones   # která zóna platí na kterém rozhraní
firewall-cmd --list-all           # kompletní výpis aktivní zóny: služby, porty, pravidla

--list-all je tvůj nejdůležitější příkaz — ukáže, co je otevřené. Než cokoli měníš, podívej se sem.

Povolování služeb a portů:

sudo firewall-cmd --add-service=ssh        # povol službu podle jména (firewalld zná její port)
sudo firewall-cmd --add-port=8080/tcp      # povol konkrétní port + protokol
sudo firewall-cmd --remove-service=ssh     # zase zavři

Rozdíl mezi službou a portem: služba je pojmenovaný balíček (ssh = TCP/22, http = TCP/80). Je čitelnější a odolnější. Port použij, když pro tvůj případ pojmenovaná služba neexistuje (vlastní aplikace na 8080 apod.).

Zóny — podle toho, jak moc síti věříš:

firewall-cmd --get-zones                              # seznam dostupných zón
firewall-cmd --zone=home --list-all                   # co dovoluje domácí zóna
sudo firewall-cmd --zone=public --add-service=https   # pravidlo do konkrétní zóny

public je výchozí nedůvěřivá zóna (default deny incoming). home bývá uvolněnější (důvěřuješ domácí síti). Rozhraní přiřadíš do zóny podle toho, kam jsi připojený.

⚠️ Runtime vs permanent — nejdůležitější věc v celé kapitole

Firewalld má dvě sady pravidel:

  • Runtime = to, co platí teď hned. Příkazy výše mění runtime — projeví se okamžitě, ale po rebootu (nebo --reload) zmizí.
  • Permanent = uložené na disk, přežije reboot. Přidáš je vlajkou --permanent, ale projeví se až po znovunačtení.

Bezpečný postup, jak pravidlo nastavit natrvalo i hned:

sudo firewall-cmd --add-port=8080/tcp --permanent   # zapiš na disk (zatím neplatí!)
sudo firewall-cmd --reload                            # načti permanent do runtime → teď platí

Proč tenhle dvojkrok? Protože chceš otestovat runtime pravidlo dřív, než ho uzamkneš natrvalo. Když se s runtime pravidlem omylem zavřeš z SSH, stačí reboot a jsi zpátky. Kdybys totéž špatné pravidlo hodil rovnou --permanent, přežije to i reboot a máš problém.

🚩 90 % „firewall mi nefunguje po restartu" je zapomenutý --permanent. A 90 % „nemůžu se připojit k serveru" je --permanent na špatné pravidlo bez testu. Obojí řeší disciplína: nejdřív runtime a otestuj, pak --permanent + --reload.


Kdy firewall stačí a kdy ne

Firewall je jedna vrstva obrany, ne kouzelný štít. Umí skvěle jednu věc: schová porty, které nemají být zvenku vidět. Ale:

  • Port, který musíš mít otevřený (třeba web na 443), firewall neochrání — provoz musí projít. O bezpečnost té služby se stará ona sama (aktualizace, hesla, TLS), ne firewall.
  • Firewall nevidí do obsahu běžného provozu. Nepozná, že přes povolený port teče útok na aplikaci.
  • Nechrání před tebou samotným — když si stáhneš a spustíš škodlivý program, ten se připojuje ven (což je defaultně povolené).

Proto firewall vždycky kombinuj: jen nutné otevřené porty + aktuální software + silná autentizace + SELinux/práva. Na tomhle stroji (viz poznámky k systému) je přesně tahle skladba: zavřený rozsah portů, otevřené jen ssh, kdeconnect, syncthing a pár dalších, plus SELinux enforcing.


Failure modes — časté omyly začátečníků

  • Zapomenutý --permanent. Pravidlo nastavíš, funguje, radost — a po rebootu je pryč. Runtime změny nepřežijí restart. Vždy --permanent + --reload, nebo to počítej s tím, že je dočasné.
  • Zavřel jsem se z vlastního SSH. Klasika na vzdáleném serveru: špatné pravidlo zablokuje port 22 a ty se odpojíš bez cesty zpět. Proto na dálku nejdřív runtime a otestuj z druhého okna, teprve pak --permanent. Pojistka: ssh povol dřív, než utáhneš zbytek.
  • Otevření portu na 0.0.0.0 bez rozmyslu. 0.0.0.0 znamená „naslouchej na všech rozhraních, komukoli". Dev server nebo databáze takhle nechtěně visí na internetu. Bindni službu na 127.0.0.1 (jen lokálně), pokud nemá být vidět zvenku — a v firewallu neotevírej, co nemusíš.
  • Spoléhání jen na firewall. „Mám firewall, jsem v bezpečí." Ne — otevřené porty musí být stejně ochráněné, provoz uvnitř povoleného portu firewall nefiltruje a odchozí malware ho obejde. Firewall je jedna vrstva.
  • Míchání iptables a firewalld. Ruční iptables pravidla vedle běžícího firewalldu se perou o stejné jádro a dají nepředvídatelný výsledek. Vyber si jeden nástroj (firewalld, ufw, nebo čisté nftables) a drž se ho.

🛠️ Cvičení

  1. Prohlídka bez zásahu. Zjisti, jestli firewall běží, která zóna je aktivní a co všechno má otevřené — aniž bys cokoli měnil. (Nápověda: --state, --get-active-zones, --list-all.) Vypiš si, které služby/porty jsou povolené, a u každé si řekni proč.
  2. Runtime vs permanent na vlastní kůži. Přidej port 8080/tcp bez --permanent, ověř --list-all, že tam je. Pak firewall reloadni a znovu zkontroluj. Kam se pravidlo podělo a proč?
  3. Uděláš to správně natrvalo. Teď tentýž port 8080/tcp přidej tak, aby přežil reboot a platil hned. Napiš oba příkazy ve správném pořadí a vysvětli, co dělá který.
  4. Služba vs port. Povol SSH dvěma způsoby — jednou přes --add-service, podruhé přes --add-port s odpovídajícím číslem. Který je čitelnější a proč bys v praxi volil službu?
  5. Bezpečné utažení na dálku. Popiš (klidně slovně) postup, jak na vzdáleném serveru zavřít všechny zbytečné porty a nezavřít se přitom z SSH. V jakém pořadí přidáváš a testuješ pravidla?
Náčrt řešení — rozbal, až si cvičení zkusíš sám
  1. Prohlídkafirewall-cmd --state (běží?), firewall-cmd --get-active-zones (aktivní zóna, typicky public na tvém rozhraní), firewall-cmd --list-all (kompletní výpis: services:, ports:, pravidla). U každé povolené služby si ověř, že ji fakt potřebuješ zvenku — co nepotřebuješ, patří pryč. Pozor: čti aktivní zónu, ne náhodnou jinou.
  2. Runtime vs permanentsudo firewall-cmd --add-port=8080/tcp → v --list-all port vidíš. Po sudo firewall-cmd --reload je pryč, protože reload načte jen permanent sadu a runtime změny bez --permanent zahodí. Ponaučení: runtime pravidla jsou dočasná, přežijí do prvního reloadu/rebootu.
  3. Správně natrvalosudo firewall-cmd --add-port=8080/tcp --permanent zapíše pravidlo na disk (zatím neplatí v runtime), sudo firewall-cmd --reload ho načte do runtime → teď platí a přežije reboot. Pořadí: nejdřív zápis, pak reload. Pozor: samotný --permanent bez reloadu se navenek „neděje" a lidi z toho panikaří.
  4. Služba vs portsudo firewall-cmd --add-service=ssh vs sudo firewall-cmd --add-port=22/tcp. Čitelnější je služba: ssh řekne co povoluješ, kdežto 22/tcp musíš znát zpaměti. Služba je i odolnější (je pojmenovaný záměr, ne magické číslo). Port ber tam, kde pojmenovaná služba neexistuje.
  5. Bezpečné utažení na dálku — pořadí je klíč: 1) nejdřív se ujisti, že ssh je povolené (--add-service=ssh), 2) změny dělej v runtime (bez --permanent) a hned je otestuj z druhého SSH okna, které necháš otevřené jako záchranu, 3) teprve když sedí, ulož je --permanent a --reload. Pojistka navíc: naplánuj automatický reboot za pár minut — když se zavřeš, restart tě vrátí do funkčního stavu. Pozor: nikdy neházej neotestované pravidlo rovnou permanent.

🧠 Otázky & odpovědi

Co znamená default deny incoming a proč se používá?

Je to výchozí pravidlo firewallu: veškerý příchozí provoz zahoď, dokud ho výslovně nepovolíš. Odchozí provoz se přitom většinou nechává volný, protože tvůj stroj se běžně připojuje ven (updaty, web, DNS). Smysl je, že otevřený port pak není náhoda, ale tvoje vědomé rozhodnutí — na stroji často naslouchá víc služeb, než tušíš, a default deny je automaticky všechny schová, dokud jednu ručně neodkryješ. Je to bezpečná výchozí pozice: raději omylem zavřít, než omylem nechat otevřené.

Jaký je rozdíl mezi nftables, firewalld a iptables?

Jsou to vrstvy nad sebou, ne konkurenti. Úplně dole sedí nftables — moderní filtr přímo v jádře, který dělá skutečnou práci. Nad ním jsou nástroje, jak ho ovládat: firewalld (pohodlný, se zónami a službami, výchozí na rodině RHEL/Fedora; na Ubuntu je obdoba ufw) a iptables (starší, se syntaxí řetězců pravidel, na moderních systémech často jen fasáda mluvící taky s nftables). Prakticky: používej výchozí nástroj své distribuce, iptables potkáš ve starších návodech. Nemíchej je — perou se o stejné jádro.

Proč mi pravidlo ve firewalldu zmizelo po restartu?

Skoro jistě proto, že jsi zapomněl na --permanent. Firewalld má dvě sady pravidel: runtime (platí okamžitě, ale nepřežije reboot ani reload) a permanent (uložená na disk, přežije reboot, ale projeví se až po --reload). Když přidáš pravidlo bez --permanent, žije jen v runtime a při restartu se zahodí. Správný postup je --add-... --permanent a pak firewall-cmd --reload, aby pravidlo platilo hned i natrvalo. Ten dvojkrok navíc umožňuje otestovat runtime dřív, než ho uzamkneš.

Jak se nezavřu z vlastního SSH, když utahuju firewall na dálku?

Pravidlem: na vzdáleném stroji nejdřív povol ssh, měň v runtime a testuj, teprve pak permanent. Konkrétně — ujisti se, že ssh (port 22) je povolené, změny prováděj bez --permanent a hned je ověř z druhého otevřeného SSH okna, které necháš jako záchranu. Když se něčím zablokuješ, runtime pravidlo zmizí po rebootu a jsi zpátky. Extra pojistka: naplánuj reboot za pár minut předem. Nikdy neházej neotestované pravidlo rovnou jako permanent — to přežije restart a zavře tě napevno.

Stačí firewall jako jediná ochrana serveru?

Ne. Firewall umí jednu věc výborně — schová porty, které nemají být zvenku vidět. Ale port, který musíš mít otevřený (třeba web na 443), neochrání, protože provoz jím musí projít; o bezpečnost té služby se stará ona sama. Firewall taky nevidí do obsahu povoleného provozu a odchozí škodlivý program obejde, protože odchozí je defaultně povolené. Proto ho kombinuj: jen nutné otevřené porty, aktuální software, silná autentizace a SELinux/práva. Firewall je jedna vrstva obrany, ne kouzelný štít.