# Firewall pro webový server: otevřít jen nutné porty

> Firewall pro webový server: zkontrolovat otevřené porty, povolit jen 80 a 443, omezit SSH a zúžit odchozí spojení. S nftables a ufw.

Zdroj: https://phpsos.de/cs/blog/firewall-fuer-webserver/  
Stav: 25.10.2026  
Poskytovatel: PHP SOS, Nouzová pomoc pro PHP a bezpečnost serverů. Okamžitá pomoc přes WhatsApp: https://wa.me/491736494914?text=Dobr%C3%BD%20den%2C%20PHP%20SOS%2C%20pot%C5%99ebujeme%20pomoc%20s%20na%C5%A1%C3%ADm%20PHP%20serverem.%20Firma%3A%20%E2%80%A6%20Web%3A%20%E2%80%A6

**Stručně:** Firewall pro webový server povoluje příchozí jen TCP 80 a 443, u HTTP/3 navíc UDP 443, a SSH jen ze známých sítí. Vše ostatní se zahazuje: databáze, cache, PHP-FPM a správcovská rozhraní do internetu nepatří. Nejprve pomocí `ss -tulpn` zjistěte, co naslouchá, poté sestavte sadu pravidel s výchozím „zahodit“ a výsledek otestujte zvenčí. Omezení odchozích spojení navíc zmenšuje následky průniku.

## Zapomenuté dveře vedle vchodových

U PHP2Shell se pozornost soustředila na samotný webový server, na porty 80 a 443. Ty musí být otevřené, jinak nebude web. Při inventurách po takových zranitelnostech se ale často ukáže něco jiného: vedle vchodových dveří stojí dokořán další dveře. Databáze naslouchá na všech síťových rozhraních, pool PHP-FPM na portu 9000, cache bez hesla, správcovské rozhraní z fáze zřizování.

Každé z těchto dveří je samostatnou plochou pro útok s vlastními zranitelnostmi. Firewall, který povoluje jen nutné, je několika pravidly uzavře. Je to jedno z nejúčinnějších opatření při zabezpečení vlastního serveru, jak popisuje i stránka [Zabezpečení root serveru a vServeru vlastními silami](https://phpsos.de/cs/server/root-server-vserver/).

## Co patří mezi otevřené a co ne

Zásadou je seznam povolených: vše je zavřeno a dostupné jsou jen vědomě uvolněné služby. Následující přehled pomáhá se zařazením.

| Služba | Typický port | Dostupná zvenčí? |
|---|---|---|
| HTTP a HTTPS | TCP 80, TCP 443 | ano |
| HTTP/3 (QUIC) | UDP 443 | jen pokud se používá |
| SSH | TCP 22 | jen ze známých sítí nebo přes VPN |
| Hostingový panel | podle produktu | jen ze známých sítí |
| MySQL/MariaDB, PostgreSQL | TCP 3306, TCP 5432 | ne |
| Redis, Memcached | TCP 6379, TCP 11211 | ne |
| PHP-FPM | TCP 9000 nebo socket Unix | ne, lépe jen socket |
| Poštovní server | TCP 25, 465, 587, 993 | jen pokud server poštu přijímá nebo poskytuje |

Služba, která nemusí navenek, by měla navíc naslouchat jen na `127.0.0.1` nebo na socketu Unix. Pak zůstane nedostupná i při poruše firewallu. Pro správcovské přístupy se hodí povolení podle IP nebo VPN; podrobnosti jsou v článku [Odstínění administrátorských oblastí pomocí IP, VPN nebo dodatečné ochrany](https://phpsos.de/cs/blog/admin-bereiche-abschirmen/).

## Krok 1: zjistit, co naslouchá

Než napíšete pravidla, udělejte si přehled. Následující příkazy jen čtou:

```bash
# Všechny naslouchající porty TCP a UDP s procesem
sudo ss -tulpn
# Aktuální sada pravidel nftables
sudo nft list ruleset
# Stav ufw, pokud se používá
sudo ufw status verbose
```

Ve výstupu `ss` si všímejte adresy před portem. `0.0.0.0` nebo `[::]` znamená: služba naslouchá na všech rozhraních. `127.0.0.1` znamená: jen lokálně. U každé služby si zapište, zda musí být dostupná zvenčí. Tento seznam je zároveň součástí soupisu vašeho serveru.

## Firewall pro webový server s nftables

nftables je aktuální paketový filtr v Linuxu. Následující sada pravidel vychází z příkladu v oficiální wiki nftables a doplňuje povolení SSH jen ze správcovské sítě. Adresy jsou dokumentační příklady a je třeba je nahradit.

```nft
#!/usr/sbin/nft -f
flush ruleset

table inet filter {
    set verwaltung_v4 {
        type ipv4_addr
        flags interval
        elements = { 203.0.113.0/28 }
    }

    chain input {
        type filter hook input priority 0; policy drop;

        ct state vmap { established : accept, related : accept, invalid : drop }
        iifname lo accept

        # IPv6 potřebuje zjišťování sousedů
        icmpv6 type { nd-neighbor-solicit, nd-router-advert, nd-neighbor-advert } accept
        icmp type echo-request limit rate 5/second accept
        icmpv6 type echo-request limit rate 5/second accept

        # Web
        tcp dport { 80, 443 } accept
        # jen u HTTP/3:
        # udp dport 443 accept

        # SSH jen ze správcovské sítě
        ip saddr @verwaltung_v4 tcp dport 22 accept
    }

    chain forward {
        type filter hook forward priority 0; policy drop;
    }
}
```

Sadu pravidel před načtením zkontrolujte pomocí `nft -c -f /etc/nftables.conf`. První řádek `flush ruleset` smaže všechna stávající pravidla, i ta, která zapsal Docker nebo Fail2ban. Na serverech s Dockerem nebo jinými službami, které nastavují vlastní pravidla, proto sadu upravte, místo abyste ji plošně nahrazovali. Jak Fail2ban s firewallem spolupracuje, je v článku [Nastavení Fail2ban pro webové servery](https://phpsos.de/cs/blog/fail2ban-fuer-webserver/).

Kdo to chce jednodušeji, použije v Ubuntu `ufw`. Důležité je pořadí: nejprve povolení SSH, poté zapnout.

```bash
sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow proto tcp from 203.0.113.0/28 to any port 22
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw enable
sudo ufw status verbose
```

> **Důležité:**
> Pravidla firewallu na vzdálených serverech měňte jen s druhou přístupovou cestou, například konzolí svého poskytovatele. Chybné pravidlo SSH vás jinak vyloučí samotné.

## Odchozí spojení: podceňovaná polovina

Většina firewallů povoluje odchozí provoz zcela. Pro webový server je to velkorysé. Po průniku útočníci využívají odchozí spojení ke stahování nástrojů, odtahování dat nebo příjmu příkazů. Procesy webového serveru nebo PHP, které navazují neočekávaná spojení, proto platí za varovný signál.

Omezení odchozích spojení je pracnější, protože musí být známo každé legitimní spojení: zdroje balíčků pro aktualizace, platební služby, rozhraní, odesílání pošty, časové servery. Pragmatickým postupem je nejprve odchozí spojení protokolovat, poté vytvořit seznam povolených a teprve potom blokovat. Jak stávající spojení zkontrolovat, popisuje [Kontrola odchozích spojení serveru](https://phpsos.de/cs/blog/ausgehende-verbindungen-pruefen/); jaké další stopy ukazují na průnik, je v článku [Jsem už kompromitován?](https://phpsos.de/cs/php2shell/bin-ich-gehackt-anzeichen/).

Nakonec zvenčí, z jiného počítače a jen proti vlastním systémům, otestujte, které porty jsou skutečně dostupné. Teprve tento test ukáže, zda Docker, firewall poskytovatele a pravidla serveru dohromady dávají požadovaný obraz.

## Závěr: málo pravidel, velký účinek

Firewall webového serveru nemusí být složitý. Webové porty otevřené, správa jen ze známých sítí, vše ostatní zahozeno: s těmito základními pravidly zmizí databáze, cache a zapomenuté služby z internetu. Je to jedno z opatření s nejlepším poměrem pracnosti a užitku.

Proti zranitelnostem ve webovém serveru nebo v samotném PHP firewall nepomáhá, protože právě tyto porty musí zůstat otevřené. Jeho síla spočívá v udržení malé zbývající plochy pro útok a v omezení následků průniku pomocí limitu odchozích spojení.

Rozhodující je péče. Každá nová služba, každý kontejner a každá změna u poskytovatele může obraz posunout. Kontrolu zvenčí proto opakujte po každé větší změně a v pevných intervalech, například jednou za čtvrtletí.

## Jak konkrétně pomáhá PHP SOS?

- **Zjistit stav:** Zmapujeme všechny naslouchající služby a zvenčí ověříme, co je skutečně dostupné.
- **Sestavit sadu pravidel:** Vytvoříme seznam povolených pro příchozí a tam, kde to má smysl, i odchozí spojení, sladěný s Dockerem, Fail2ban a firewallem poskytovatele.
- **Bezpečně přepnout:** Změny provádíme s druhou přístupovou cestou a záložním plánem.
- **Zdokumentovat:** Porty, povolení a důvody zaznamenáme v rámci [zpevnění serveru](https://phpsos.de/cs/leistungen/server-haertung/).


## Časté dotazy

**Jaké porty potřebuje webový server?**  
Pro návštěvníky zpravidla jen TCP 80 a 443, u HTTP/3 navíc UDP 443. SSH a správcovská rozhraní by měla být dostupná jen ze známých sítí nebo přes VPN. Porty databází, cache a PHP-FPM do internetu nepatří.

**Chrání firewall před PHP2Shell?**  
Ne. PHP2Shell se zneužívá přes webový server, tedy právě přes porty, které musí být otevřené. Firewall ale zmenšuje zbývající plochu pro útok a omezení odchozích spojení může zmírnit následky průniku.

**Proč ufw ukazuje porty jako zavřené, které jsou přesto dostupné?**  
Známým případem jsou kontejnery Dockeru: Docker zapisuje zveřejněné porty přímo do pravidel paketového filtru, mimo ufw. Otevřené porty proto vždy navíc zkontrolujte zvenčí.

**Stačí firewall mého hostingového poskytovatele?**  
Předřazený firewall poskytovatele je dobrá druhá vrstva. Firewall na serveru ale nenahrazuje, protože při chybě v konfiguraci poskytovatele nebo u interních spojení nezabere. Nejlépe používejte oba se stejnými základními pravidly.

## Zdroje

- [Wiki nftables: jednoduchá sada pravidel pro server](https://wiki.nftables.org/wiki-nftables/index.php/Simple_ruleset_for_a_server)
- [Ubuntu Server: firewall (ufw)](https://ubuntu.com/server/docs/how-to/security/firewalls/)
- [BSI IT-Grundschutz](https://www.bsi.bund.de/DE/Themen/Unternehmen-und-Organisationen/Standards-und-Zertifizierung/IT-Grundschutz/it-grundschutz_node.html)
- [CIS Benchmarks](https://www.cisecurity.org/cis-benchmarks)
