# Nastavení Fail2ban pro webové servery

> Fail2ban pro Nginx a Apache: aktivovat vhodné jaily, vlastní filtry otestovat pomocí fail2ban-regex, blokovat recidivisty a vyhnout se vlastnímu vyloučení.

Zdroj: https://phpsos.de/cs/blog/fail2ban-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ě:** Fail2ban čte logovací soubory a ve firewallu blokuje adresy, které se v časovém okně objeví příliš často. Pro Nginx a Apache přináší hotové jaily jako `nginx-botsearch` nebo `apache-noscript`; vlastní filtry otestujte pomocí `fail2ban-regex`. Nastavení patří do `jail.local`, vaše vlastní adresy do `ignoreip`, recidivisty zachytí jail `recidive`. Proti jednotlivým cíleným útokům Fail2ban nepomůže, proti hromadným skenům ano.

## Když jsou logy plné skenerů

Kdo si v těchto dnech prohlédne přístupové protokoly svých webových serverů, najde je často plné požadavků na cesty, které vůbec neexistují: staré administrační rozhraní, testovací soubory, známé zranitelnosti jiných produktů. V situaci jako PHP2Shell přibývá cílené hledání zranitelných serverů: Cloudflare a Patchstack hlásily pokusy o útok, Unit 42 napočítala více než 22,6 milionu exponovaných, potenciálně zranitelných instancí.

Fail2ban je osvědčený nástroj proti této masě. Čte logovací soubory, pomocí filtrů rozpozná nápadné záznamy a adresu odesílatele na stanovenou dobu zablokuje ve firewallu. Server to odlehčí, sníží šum v lozích a systematické zkoušení z jednoho zdroje zpomalí.

Co Fail2ban neumí, je stejně důležité: jednotlivému požadavku, který zneužije zranitelnost, nezabrání. Proti PHP2Shell pomůže jen aktualizace PHP. Jak automatizované útoky probíhají, popisuje [Hromadné skeny po nezáplatovaném PHP](https://phpsos.de/cs/blog/automatisierte-massenscans/).

## Fail2ban pro Nginx a Apache: dodávané jaily

Jail spojuje filtr s logovacím souborem a akcí blokování. Dodávaný `jail.conf` už obsahuje jaily pro webové servery. Jsou standardně vypnuté a aktivují se jednotlivě.

| Jail | Webový server | Rozpozná |
|---|---|---|
| `nginx-http-auth` | Nginx | neúspěšná přihlášení HTTP Basic |
| `nginx-limit-req` | Nginx | požadavky překračující rate limit Nginx |
| `nginx-botsearch` | Nginx | hledání typických, neexistujících cest |
| `nginx-bad-request` | Nginx | chybné požadavky |
| `apache-auth` | Apache | neúspěšná přihlášení |
| `apache-badbots` | Apache | známé škodlivé identifikace botů |
| `apache-noscript` | Apache | volání neexistujících skriptů |
| `apache-overflows` | Apache | příliš dlouhé požadavky |
| `apache-botsearch` | Apache | hledání typických, neexistujících cest |
| `php-url-fopen` | oba | určité vzorce pokusů o vložení URL |
| `recidive` | oba | adresy, které Fail2ban opakovaně zablokoval |

Výchozí hodnoty dodávané konfigurace jsou spíše mírné: blokace na 10 minut po 5 nálezech za 10 minut. U webových serverů s velkým provozem skenů se vyplatí delší blokace a rostoucí faktor pro opakování.

## Základní konfigurace v jail.local

`jail.conf` sám říká, že se nemá měnit, protože ho aktualizace nahrazují. Vlastní hodnoty patří do `/etc/fail2ban/jail.local`. Následující příklad pro Nginx nastavuje rozumné výchozí hodnoty a aktivuje vhodné jaily:

```ini
# /etc/fail2ban/jail.local
[DEFAULT]
# Zapsat vlastní pevné adresy (ukázkovou adresu nahradit)
ignoreip = 127.0.0.1/8 ::1 203.0.113.10
bantime  = 1h
findtime = 10m
maxretry = 5
bantime.increment = true

[nginx-http-auth]
enabled = true

[nginx-botsearch]
enabled = true

[recidive]
enabled  = true
bantime  = 1w
findtime = 1d
```

Pro Apache místo toho aktivujte například `apache-auth`, `apache-noscript` a `apache-botsearch`. Cesty k logům Fail2ban dodává podle distribuce; pokud se vaše cesty liší, nastavte `logpath` v příslušném jailu. Pokud váš systém čte logy jen přes journal, pomůže `backend = systemd`.

## Vlastní filtr pro hromadné požadavky na soubory PHP

Typickým vzorcem v současné situaci je mnoho požadavků za krátkou dobu na soubory PHP, které neexistují. Vlastní filtr to pozná podle stavového kódu 404. Popisuje jen to, co stojí ve vašem vlastním logu:

```ini
# /etc/fail2ban/filter.d/nginx-php-404.conf
[Definition]
failregex = ^<HOST> -.*"(GET|POST|HEAD) [^"]*\.php[^"]*" 404
ignoreregex =
```

```ini
# Doplnění v /etc/fail2ban/jail.local
[nginx-php-404]
enabled  = true
port     = http,https
filter   = nginx-php-404
logpath  = /var/log/nginx/access.log
maxretry = 20
findtime = 1m
bantime  = 1h
```

Než filtr aktivujete, vyzkoušejte jej proti skutečnému logu. Uvidíte, kolik řádků zasahuje a zda mezi nimi nejsou legitimní přístupy:

```bash
fail2ban-regex /var/log/nginx/access.log /etc/fail2ban/filter.d/nginx-php-404.conf
sudo systemctl restart fail2ban
sudo fail2ban-client status
sudo fail2ban-client status nginx-php-404
# Uvolnit omylem zablokovanou adresu
sudo fail2ban-client set nginx-php-404 unbanip 203.0.113.25
```

Práh volte velkoryse. Crawler zpracovávající zastaralé odkazy nebo monitorovací služba nesmí skončit v blokaci.

## Nejčastější pasti

Fail2ban se nainstaluje rychle, ale snadno se použije špatně. Tyto body zkontrolujte před ostrým nasazením:

1. **Vlastní vyloučení:** Adresy kanceláře, VPN a monitoringu patří do `ignoreip`, dříve než se jaily aktivují.
2. **Předřazené služby:** Za CDN nebo load balancerem vidí Fail2ban bez úpravy jen jejich adresy. Více v průvodci [Ochrana administrátorských přihlášení proti brute force](https://phpsos.de/cs/ratgeber/brute-force-login-schutz/).
3. **Rotace logů:** Po změně logovacího souboru musí Fail2ban číst nový soubor. Po první rotaci zkontrolujte, zda jaily dál počítají nálezy.
4. **Souhra s firewallem:** Fail2ban zapisuje blokace do firewallu. Kdo spravuje firewall úplným opětovným načtením pravidel, může tyto záznamy smazat. Jak firewall sestavit, je v článku [Firewall pro webové servery: otevřít jen nutné porty](https://phpsos.de/cs/blog/firewall-fuer-webserver/).
5. **IPv6:** Útoky přicházejí i přes IPv6. Zkontrolujte, zda vaše akce blokování pokrývá oba protokoly.

> **Tip:**
> Seznamy blokací pravidelně vyhodnocujte. Pokud se blokace hromadí z určitých sítí nebo na určité cesty, je to známka cíleného hledání a důvod podívat se na dotčenou aplikaci podrobněji.

## Závěr: nástroj proti masám, ne proti všemu

Fail2ban se nastaví rychle a odlehčí webovým serverům část trvalé palby. Dodávané jaily pokrývají typické vzorce, vlastní filtry lze pomocí `fail2ban-regex` bezpečně otestovat proti skutečným logům a jail `recidive` zajistí, že houževnaté zdroje zůstanou venku déle.

Nepřeceňujte jej. Fail2ban reaguje na opakování, ne na první nález, a vidí jen to, co stojí v lozích. Proti zranitelnosti jako PHP2Shell pomůže jen aktualizace, proti distribuovaným útokům z mnoha adres Fail2ban pomáhá sotva. Svou hodnotu rozvíjí jako jedna vrstva z několika: vedle štíhlého firewallu, zpevněné konfigurace webového serveru, dvoufázového ověření a monitoringu, který nápadnosti nejen blokuje, ale také hlásí.

## Jak konkrétně pomáhá PHP SOS?

- **Vyhodnotit logy:** Prohlédneme, jaké vzorce se ve vašich přístupových protokolech objevují, a vybereme vhodné jaily.
- **Nastavit a otestovat:** Nastavíme Fail2ban s vlastními filtry, každý filtr otestujeme proti skutečným logům a vaše pevné adresy zapíšeme jako výjimku.
- **Vyjasnit souhru:** CDN, load balancer, firewall a rotaci logů sladíme tak, aby blokace zasáhly správné adresy.
- **Sledovat:** V rámci [bezpečnostního monitoringu](https://phpsos.de/cs/leistungen/security-monitoring/) průběžně vyhodnocujeme blokace a nápadnosti.


## Časté dotazy

**Chrání Fail2ban před PHP2Shell?**  
Ne. Fail2ban reaguje teprve poté, co se adresa v lozích opakovaně objeví. Jediný úspěšný útok tím nezabrání. Fail2ban ale snižuje zátěž od skenerů a opakované pokusy ze stejného zdroje činí nákladnějšími.

**Proč nemám měnit přímo jail.conf?**  
Soubor se při aktualizacích balíčků nahrazuje a sám to říká. Vlastní nastavení patří do jail.local nebo do souborů pod jail.d. Tam cíleně přepisují výchozí hodnoty.

**Co je jail recidive?**  
Jail, který vyhodnocuje protokol samotného Fail2ban. Kdo je opakovaně blokován, dostane výrazně delší blokaci. V dodávané konfiguraci činí týden.

**Funguje Fail2ban za Cloudflare nebo load balancerem?**  
Jen s dodatečnou konfigurací. Bez ní je v lozích adresa předřazené služby a blokace by zasáhla všechny návštěvníky. Webový server pak musí převzít skutečnou adresu návštěvníka a blokace se lépe nastavují u předřazené služby.

## Zdroje

- [Fail2ban: dodávaný jail.conf](https://github.com/fail2ban/fail2ban/blob/master/config/jail.conf)
- [BSI IT-Grundschutz](https://www.bsi.bund.de/DE/Themen/Unternehmen-und-Organisationen/Standards-und-Zertifizierung/IT-Grundschutz/it-grundschutz_node.html)
- [OWASP Cheat Sheets](https://cheatsheetseries.owasp.org/)
