# Konfiguracja Fail2ban dla serwerów WWW

> Fail2ban dla Nginx i Apache: aktywować jaile, testować własne filtry za pomocą fail2ban-regex, blokować recydywistów i unikać zablokowania samego siebie.

Źródło: https://phpsos.de/pl/blog/fail2ban-fuer-webserver/  
Stan: 25.10.2026  
Dostawca: PHP SOS, Pomoc awaryjna PHP i bezpieczeństwo serwerów. Natychmiastowa pomoc przez WhatsApp: https://wa.me/491736494914?text=Dzie%C5%84%20dobry%2C%20PHP%20SOS%2C%20potrzebujemy%20pomocy%20z%20naszym%20serwerem%20PHP.%20Firma%3A%20%E2%80%A6%20Strona%20internetowa%3A%20%E2%80%A6

**Krótko:** Fail2ban czyta pliki logów i blokuje w zaporze adresy, które w określonym przedziale czasu zbyt często rzucają się w oczy. Dla Nginx i Apache ma gotowe jaile, takie jak `nginx-botsearch` czy `apache-noscript`; własne filtry testują Państwo za pomocą `fail2ban-regex`. Ustawienia należą do `jail.local`, własne adresy do `ignoreip`, recydywistów wyłapuje jail `recidive`. Przeciw pojedynczym celowanym atakom Fail2ban nie pomaga, przeciw masowym skanom tak.

## Gdy logi są pełne skanerów

Kto w tych dniach przegląda dzienniki dostępu swoich serwerów WWW, często znajduje je pełne żądań do ścieżek, które w ogóle nie istnieją: stare panele administracyjne, pliki testowe, znane słabe punkty innych produktów. W sytuacji takiej jak PHP2Shell dochodzi celowe poszukiwanie podatnych serwerów: Cloudflare i Patchstack donosiły o próbach ataków, Unit 42 naliczył ponad 22,6 mln wystawionych, potencjalnie podatnych instancji.

Fail2ban jest sprawdzonym narzędziem przeciw tej masie. Czyta pliki logów, za pomocą filtrów rozpoznaje podejrzane wpisy i blokuje adres nadawcy na określony czas w zaporze. Odciąża to serwer, zmniejsza szum w logach i utrudnia systematyczne próbowanie z jednego źródła.

Czego Fail2ban nie potrafi, jest równie ważne: pojedynczego żądania wykorzystującego lukę nie zapobiega. Przeciw PHP2Shell pomaga wyłącznie aktualizacja PHP. Jak przebiegają zautomatyzowane ataki, opisuje artykuł [Masowe skany w poszukiwaniu niezałatanego PHP](https://phpsos.de/pl/blog/automatisierte-massenscans/).

## Fail2ban dla Nginx i Apache: dołączone jaile

Jail łączy filtr z plikiem logu i akcją blokowania. Dołączony `jail.conf` zawiera już jaile dla serwerów WWW. Są domyślnie wyłączone i aktywuje się je pojedynczo.

| Jail | Serwer WWW | Rozpoznaje |
|---|---|---|
| `nginx-http-auth` | Nginx | nieudane logowania HTTP Basic |
| `nginx-limit-req` | Nginx | żądania przekraczające limit szybkości Nginx |
| `nginx-botsearch` | Nginx | poszukiwanie typowych, nieistniejących ścieżek |
| `nginx-bad-request` | Nginx | błędne żądania |
| `apache-auth` | Apache | nieudane logowania |
| `apache-badbots` | Apache | znane szkodliwe identyfikatory botów |
| `apache-noscript` | Apache | wywołania nieistniejących skryptów |
| `apache-overflows` | Apache | zbyt długie żądania |
| `apache-botsearch` | Apache | poszukiwanie typowych, nieistniejących ścieżek |
| `php-url-fopen` | oba | określone wzorce prób dołączania URL |
| `recidive` | oba | adresy, które Fail2ban zablokował wielokrotnie |

Wartości domyślne dołączonej konfiguracji są raczej łagodne: blokada na 10 minut po 5 trafieniach w ciągu 10 minut. Dla serwerów WWW z dużym ruchem skanerów warto ustawić dłuższą blokadę i rosnący współczynnik dla powtórzeń.

## Konfiguracja podstawowa w jail.local

`jail.conf` sam mówi, że nie należy go zmieniać, ponieważ aktualizacje go zastępują. Własne wartości należą do `/etc/fail2ban/jail.local`. Poniższy przykład dla Nginx ustawia sensowne wartości domyślne i aktywuje odpowiednie jaile:

```ini
# /etc/fail2ban/jail.local
[DEFAULT]
# Wpisać własne stałe adresy (zastąpić adres przykładowy)
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
```

Dla Apache aktywują Państwo zamiast tego na przykład `apache-auth`, `apache-noscript` i `apache-botsearch`. Ścieżki logów Fail2ban dostarcza zależnie od dystrybucji; jeśli Państwa ścieżki się różnią, proszę ustawić `logpath` w danym jailu. Jeśli system czyta logi tylko przez dziennik systemowy, pomaga `backend = systemd`.

## Własny filtr dla masowych żądań do plików PHP

Typowym wzorcem w obecnej sytuacji są liczne żądania w krótkim czasie do plików PHP, które nie istnieją. Własny filtr rozpoznaje to po kodzie statusu 404. Opisuje wyłącznie to, co znajduje się w Państwa własnym logu:

```ini
# /etc/fail2ban/filter.d/nginx-php-404.conf
[Definition]
failregex = ^<HOST> -.*"(GET|POST|HEAD) [^"]*\.php[^"]*" 404
ignoreregex =
```

```ini
# Uzupełnienie w /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
```

Zanim aktywują Państwo filtr, proszę sprawdzić go względem prawdziwego logu. Dzięki temu widać, ile wierszy trafia i czy są wśród nich uzasadnione wywołania:

```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
# Odblokować przypadkowo zablokowany adres
sudo fail2ban-client set nginx-php-404 unbanip 203.0.113.25
```

Próg proszę wybrać hojnie. Crawler przetwarzający nieaktualne linki lub usługa monitoringu nie może trafić na blokadę.

## Najczęstsze pułapki

Fail2ban instaluje się szybko, ale łatwo go błędnie użyć. Te punkty warto sprawdzić przed użyciem produkcyjnym:

1. **Zablokowanie samego siebie:** adresy biura, VPN i monitoringu należą do `ignoreip`, zanim jaile staną się aktywne.
2. **Usługi poprzedzające:** za CDN lub load balancerem Fail2ban bez dostosowania widzi tylko ich adresy. Więcej w poradniku [Ochrona logowań administratora przed brute force](https://phpsos.de/pl/ratgeber/brute-force-login-schutz/).
3. **Rotacja logów:** po zmianie pliku logu Fail2ban musi czytać nowy plik. Po pierwszej rotacji proszę sprawdzić, czy jaile nadal zliczają trafienia.
4. **Współdziałanie z zaporą:** Fail2ban wpisuje blokady do zapory. Kto zarządza zaporą przez pełne przeładowanie zestawu reguł, może przy tym usunąć te wpisy. Jak zbudować samą zaporę, opisuje artykuł [Zapora dla serwera WWW: otwierać tylko niezbędne porty](https://phpsos.de/pl/blog/firewall-fuer-webserver/).
5. **IPv6:** ataki przychodzą także przez IPv6. Proszę sprawdzić, czy akcja blokowania obejmuje oba protokoły.

> **Wskazówka:**
> Proszę regularnie analizować listy blokad. Jeśli blokady z określonych sieci lub do określonych ścieżek się kumulują, jest to wskazówka celowego poszukiwania i powód, by dokładniej przyjrzeć się dotkniętej aplikacji.

## Wniosek: narzędzie przeciw masie, nie przeciw wszystkiemu

Fail2ban konfiguruje się szybko i zdejmuje z serwerów WWW część ciągłego ostrzału. Dołączone jaile pokrywają typowe wzorce, własne filtry można bezpiecznie testować za pomocą `fail2ban-regex` na prawdziwych logach, a jail `recidive` sprawia, że uparte źródła pozostają na zewnątrz dłużej.

Nie należy go przeceniać. Fail2ban reaguje na powtórzenia, a nie na pierwsze trafienie, i widzi tylko to, co jest w logach. Przeciw luce takiej jak PHP2Shell pomaga wyłącznie aktualizacja, przeciw rozproszonym atakom z wielu adresów Fail2ban pomaga niewiele. Swoją wartość pokazuje jako jedna warstwa spośród kilku: obok szczupłej zapory, utwardzonej konfiguracji serwera WWW, uwierzytelniania dwuskładnikowego i monitoringu, który nieprawidłowości nie tylko blokuje, lecz także zgłasza.

## Jak konkretnie pomaga PHP SOS?

- **Analiza logów:** przyglądamy się wzorcom pojawiającym się w Państwa dziennikach dostępu i wybieramy odpowiednie jaile.
- **Konfiguracja i testy:** konfigurujemy Fail2ban z własnymi filtrami, testujemy każdy filtr na prawdziwych logach i wpisujemy Państwa stałe adresy jako wyjątek.
- **Wyjaśnienie współdziałania:** CDN, load balancer, zaporę i rotację logów uzgadniamy tak, aby blokady trafiały we właściwe adresy.
- **Obserwacja:** w ramach [monitoringu bezpieczeństwa](https://phpsos.de/pl/leistungen/security-monitoring/) na bieżąco analizujemy blokady i nieprawidłowości.


## Częste pytania

**Czy Fail2ban chroni przed PHP2Shell?**  
Nie. Fail2ban reaguje dopiero po tym, jak adres kilkakrotnie rzucił się w oczy w logach. Pojedynczego udanego ataku to nie zapobiega. Fail2ban zmniejsza jednak obciążenie ze strony skanerów i podnosi koszt powtarzanych prób z tego samego źródła.

**Dlaczego nie powinienem zmieniać jail.conf bezpośrednio?**  
Plik jest zastępowany przy aktualizacjach pakietów i sam o tym informuje. Własne ustawienia należą do jail.local lub do plików w jail.d. Tam celowo nadpisują wartości domyślne.

**Czym jest jail recidive?**  
To jail, który analizuje sam dziennik Fail2ban. Kto jest blokowany wciąż na nowo, otrzymuje wyraźnie dłuższą blokadę. W dołączonej konfiguracji wynosi ona tydzień.

**Czy Fail2ban działa za Cloudflare lub load balancerem?**  
Tylko z dodatkową konfiguracją. Bez niej w logach widnieje adres usługi poprzedzającej, a blokada dotknęłaby wszystkich odwiedzających. Serwer WWW musi wtedy przejmować prawdziwy adres odwiedzającego, a blokady lepiej ustawiać w usłudze poprzedzającej.

## Źródła

- [Fail2ban: dołączony jail.conf](https://github.com/fail2ban/fail2ban/blob/master/config/jail.conf)
- [BSI (niemiecki Federalny Urząd ds. Bezpieczeństwa w Technice Informatycznej): 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/)
