Menu
Szybki wybór
Hosting Domeny VPS SSL Kalkulator Porównania FAQ
Aktywne kody
Wszystkie kody rabatowe

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 = [email protected]
# sender = [email protected]
# 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" [email protected]

# 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 = [email protected]
sender = [email protected]
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.