 Autor: [Adam Nadolny](/autorzy/adam-nadolny) Ekspert DevOps i infrastruktury · Zweryfikowano Kwiecień 2026

1.  [Strona główna](/) ›
2.  [Baza wiedzy](/baza-wiedzy/) ›
3.  fail2ban — zaawansowana konfiguracja

# fail2ban — zaawansowana konfiguracja i własne filtry

Opublikowano: 9 kwietnia 2026 · Kategoria: Bezpieczeństwo / VPS

fail2ban to daemon monitorujący logi serwera i automatycznie blokujący IP wykazujące podejrzane zachowanie — zbyt wiele nieudanych logowań SSH, prób dostępu do panelu admina WordPress, skanowania podatności. W tym artykule wykroczymy poza domyślną konfigurację: stworzymy własne filtry regex, skonfigurujemy powiadomienia email i ustawimy jail recidive dla uporczywych atakujących.

## Architektura fail2ban: filter + jail + action

-   **Filter** (`/etc/fail2ban/filter.d/*.conf`) — definicja wyrażeń regularnych (failregex) wyszukujących podejrzane linie w logach. Np. `failregex = authentication failure.*rhost=<HOST>`.
-   **Jail** (`/etc/fail2ban/jail.local`) — łączy filter z plikiem logu, określa progi (maxretry, findtime) i akcję (banaction). Jeden jail = jedna usługa do ochrony.
-   **Action** (`/etc/fail2ban/action.d/*.conf`) — co zrobić gdy IP przekroczy próg: ban przez iptables/nftables, powiadomienie email, zapis do bazy, aktualizacja Cloudflare.

Zasada: **nigdy nie edytuj plików .conf** — nadpisuje je aktualizacja fail2ban. Zawsze twórz odpowiedniki `.local` (jail.local, filter.d/nazwa.local). Pliki .local nadpisują wartości z .conf.

## jail.local — konfiguracja globalna i SSH jail

\# /etc/fail2ban/jail.local
\[DEFAULT\]
# IP zawsze ignorowane (Twój serwer, monitoring, biuro)
ignoreip = 127.0.0.1/8 ::1 10.0.0.0/8

# Domyślne ustawienia (można nadpisać per jail)
bantime  = 1h          # czas bana (1h, 1d, 1w lub sekundy)
findtime = 10m         # okno zliczania prób
maxretry = 5           # ile prób przed banem

# Backend logów (auto = najlepszy dostępny)
backend = auto

# Domyślna akcja banu (iptables-multiport lub nftables-multiport)
banaction = iptables-multiport

# Powiadomienie email przy banie (wymaga działającego MTA)
# destemail = admin@twojadomena.pl
# sender = fail2ban@twojadomena.pl
# mta = sendmail
# action = %(action\_mwl)s  # ban + email z logami

# ---- SSH jail ----
\[sshd\]
enabled  = true
port     = ssh          # lub konkretny port: 22222
logpath  = %(sshd\_log)s
backend  = %(sshd\_backend)s
maxretry = 3            # SSH: restrykcyjniej niż default
bantime  = 1d           # dzień za próby SSH

\# Zastosuj zmiany i sprawdź status SSH jail
sudo systemctl restart fail2ban
sudo fail2ban-client status sshd

## Nginx HTTP Auth jail

\# W jail.local dodaj:
\[nginx-http-auth\]
enabled  = true
port     = http,https
logpath  = /var/log/nginx/error.log
maxretry = 5
findtime = 5m
bantime  = 30m

# Filtr jest wbudowany w fail2ban: /etc/fail2ban/filter.d/nginx-http-auth.conf
# Łapie linie: "no user/password was provided for basic authentication"
# i "user ... was not found in ..."

## Własny filtr: WordPress wp-login.php brute force

WordPress rejestruje nieudane logowania w access logu Nginx jako POST /wp-login.php z kodem 200 (WordPress zwraca 200 nawet przy błędnym haśle — walidacja po stronie PHP). Utwórz własny filtr:

\# /etc/fail2ban/filter.d/wordpress.conf
\[Definition\]

# Łapie: POST /wp-login.php (każde żądanie = próba logowania)
# <HOST> to placeholder który fail2ban zamienia na IP
failregex = ^<HOST> -.\*"POST /wp-login\\.php HTTP/.\*" (200|302)

# Ignoruj żądania GET (strona logowania, nie próba)
ignoreregex = ^<HOST> -.\*"GET /wp-login\\.php HTTP/.\*"

\# Przetestuj filtr na prawdziwym logu PRZED włączeniem
sudo fail2ban-regex /var/log/nginx/access.log /etc/fail2ban/filter.d/wordpress.conf

# Wynik powinien pokazać "Lines: X matched, Y missed"
# Sprawdź czy pasuje właściwe linie, a nie fałszywe alarmy

\# W jail.local dodaj WordPress jail:
\[wordpress\]
enabled  = true
port     = http,https
filter   = wordpress
logpath  = /var/log/nginx/access.log
maxretry = 5
findtime = 5m
bantime  = 24h

## Filtr na złośliwe boty (Nginx bad bots)

\# /etc/fail2ban/filter.d/nginx-badbots.conf
\[Definition\]
failregex = ^<HOST> -.\*"(GET|POST|HEAD).\*HTTP.\*" \\d+ \\d+ ".\*" "(sqlmap|nikto|masscan|nmap|zgrab|python-requests/2\\.2\[0-9\]|Go-http-client/1\\.1|curl/7\\.\[0-5\]).\*"$
ignoreregex =

\# jail.local:
\[nginx-badbots\]
enabled  = true
port     = http,https
filter   = nginx-badbots
logpath  = /var/log/nginx/access.log
maxretry = 1       # jeden raz = ban natychmiast
bantime  = 1w      # tydzień za skanery

## Action z powiadomieniem email

\# Zainstaluj MTA (mailutils + postfix lub sendmail)
sudo apt install mailutils postfix -y   # wybierz "Internet Site" w konfiguracji

# Przetestuj wysyłkę:
echo "Test fail2ban" | mail -s "Test" admin@twojadomena.pl

# W jail.local — włącz email dla konkretnego jaila:
\[sshd\]
enabled  = true
port     = ssh
logpath  = %(sshd\_log)s
maxretry = 3
bantime  = 1d
# action = %(action\_)s      # domyślnie: tylko ban
# action = %(action\_mw)s    # ban + email z WHOIS
action = %(action\_mwl)s     # ban + email z WHOIS + fragment loga

destemail = admin@twojadomena.pl
sender = fail2ban@twojadomena.pl
mta = sendmail

Dostępne akcje email:

-   `%(action_)s` — tylko ban (bez email)
-   `%(action_m)s` — ban + email z podstawową informacją
-   `%(action_mw)s` — ban + email + dane WHOIS zablokowanego IP
-   `%(action_mwl)s` — ban + email + WHOIS + fragment pasujących linii logu

## Recidive jail — długi ban dla recydywistów

Jail `recidive` monitoruje logi fail2ban i nakłada długi ban na IP które były wielokrotnie banowane przez inne jaile. Skuteczny przeciw botom które są banowane, czekają na odblokowanie i próbują ponownie.

\# W jail.local:
\[recidive\]
enabled  = true
logpath  = /var/log/fail2ban.log    # monitoruje logi samego fail2ban!
filter   = recidive                 # wbudowany filtr
banaction = iptables-allports       # ban na WSZYSTKICH portach (nie tylko konkretnych)
maxretry = 3                        # 3 bany w ciągu findtime
findtime = 1d                       # okno: 1 dzień
bantime  = 1w                       # tydzień bana za recydywę
# bantime = -1                      # permanentny ban za recydywę

## Zarządzanie fail2ban — przydatne polecenia

\# Status wszystkich jaili
sudo fail2ban-client status

# Status konkretnego jaila
sudo fail2ban-client status sshd

# Odblokuj IP
sudo fail2ban-client set sshd unbanip 1.2.3.4

# Zablokuj IP ręcznie
sudo fail2ban-client set sshd banip 1.2.3.4

# Przeładuj konfigurację (po zmianach w jail.local)
sudo fail2ban-client reload

# Sprawdź aktualnie zbanowane IP przez iptables
sudo iptables -L f2b-sshd -n --line-numbers

# Testowanie filtra (patrz też sekcja FAQ)
sudo fail2ban-regex /var/log/nginx/access.log /etc/fail2ban/filter.d/wordpress.conf --print-all-matched

## Najczęstsze pytania

Jak przetestować własny filtr fail2ban przed włączeniem? +

Użyj polecenia fail2ban-regex: fail2ban-regex /var/log/nginx/access.log /etc/fail2ban/filter.d/moj-filtr.conf Polecenie pokazuje ile linii pasuje do wzorca (failregex) i ile nie pasuje (ignoreregex). Jeśli wzorzec pasuje do za dużo lub za mało linii — dostosuj regex. Możesz też przetestować na konkretnym fragmencie loga: echo "1.2.3.4 - - \[09/Apr/2026:12:00:00 +0000\] "GET /wp-login.php HTTP/1.1" 200 1234" | fail2ban-regex - /etc/fail2ban/filter.d/wordpress.conf

Jak odblokować własne IP które przypadkowo zablokowałem przez fail2ban? +

Odblokuj przez fail2ban-client: sudo fail2ban-client set sshd unbanip TWOJE\_IP lub dla konkretnego jaila: sudo fail2ban-client set nginx-http-auth unbanip 1.2.3.4 Jeśli zablokowane jest IP przez które łączysz się SSH — musisz mieć dostęp przez konsolę VPS (panel dostawcy). Prewencja: dodaj swoje IP do ignoreip w jail.local: \[DEFAULT\] ignoreip = 127.0.0.1/8 ::1 TWOJE\_STALE\_IP

Jaka jest różnica między bantime w sekundach a bantime z przyrostkiem? +

fail2ban od wersji 0.10 obsługuje przyrostki czasowe: bantime = 1h (godzina), bantime = 1d (dzień), bantime = 1w (tydzień). Negatywna wartość bantime = -1 oznacza permamentny ban (bez automatycznego odblokowania). W starszych konfiguracjach bantime był podawany tylko w sekundach: bantime = 3600 (= 1h), bantime = 86400 (= 1d). Przyrostki są wygodniejsze i czytelniejsze — używaj ich w nowych konfiguracjach.

Czy fail2ban chroni przed rozproszonym atakiem DDoS z wielu IP? +

Nie — fail2ban jest zaprojektowany do blokowania pojedynczych IP po przekroczeniu progu błędów. Rozproszony atak (botnet) z setek/tysięcy IP omija fail2ban, bo każde IP generuje niewiele żądań. Do ochrony przed DDoS potrzebny jest Cloudflare (WAF + rate limiting + DDoS protection) lub dedykowane rozwiązania (Arbor, Akamai). fail2ban jest skuteczny dla: brute force SSH/FTP z jednego IP, skanowania portów, prób ataków na konkretne endpointy z jednego IP. Uzupełnij go Cloudflare WAF dla kompletnej ochrony.

## Sprawdź oferty pasujące do tego scenariusza

Poniżej masz szybkie przejścia do ofert i stron z kodami rabatowymi tam, gdzie są dostępne.

Contabo

VPS z pełnym dostępem root — zainstaluj fail2ban i skonfiguruj ochronę serwera

Root access

[Aktywuj rabat →](/out/contabo)

#Reklama · link partnerski

[Zobacz kod rabatowy →](/kody-rabatowe/contabo)

Mikrus

Tani VPS do nauki konfiguracji fail2ban i innych narzędzi bezpieczeństwa

Dev/Test

[Aktywuj rabat →](/out/mikrus)

#Reklama · link partnerski

[Zobacz kod rabatowy →](/kody-rabatowe/mikrus)

LH.pl

Hosting zarządzany — bezpieczeństwo po stronie dostawcy, bez konfiguracji fail2ban

Managed security

[Aktywuj rabat →](/out/lh-pl)

#Reklama · link partnerski

[Zobacz kod rabatowy →](/kody-rabatowe/lh-pl)

## Powiązane strony

-   [Cloudflare WAF — ochrona przed atakami](/baza-wiedzy/cloudflare-waf-konfiguracja)
-   [ModSecurity WAF — konfiguracja](/baza-wiedzy/modsecurity-waf-hosting)
-   [Bezpieczeństwo WordPress — przewodnik](/baza-wiedzy/bezpieczenstwo-wordpress-hosting)
-   [Nginx virtual host — konfiguracja](/baza-wiedzy/nginx-vhost-konfiguracja)
-   [Wszystkie artykuły](/baza-wiedzy/)