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.
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.
Krok 1: zjistit, co naslouchá
Než napíšete pravidla, udělejte si přehled. Následující příkazy jen čtou:
# 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.
#!/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.
Kdo to chce jednodušeji, použije v Ubuntu ufw. Důležité je pořadí: nejprve povolení SSH, poté zapnout.
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
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; jaké další stopy ukazují na průnik, je v článku Jsem už kompromitován?.
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.
Č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.