BanDe câteva zile tot mă anunță plugin-ul de sucuri de pe wordpress că am gramezi de încercări de bruteforce pe wp-login.php, toate cu IP-uri din Rusia. Și pentru că mi-a fost lene să stau să fac config în nginx prin care să permit doar ip-ul meu de acasă (și încă vreo 2-3) m-am gândit să încerc să rezolv problema mai elegant folosind fail2ban care este deja instalat pe server. Avantajul principal mai este și că mă lasă să mă loghez din altă parte dacă nu greșesc parola de prea multe ori față de metoda prin care aș bana tot mai puțin 1-2 ip-uri pe care le utilizez.

Folosesc fail2ban pe servere de aproape 1-2 ani, înainte eram “prieten” mult mai bun cu denyhosts. Dar ăla a cam fost abandonat și nici nu funcționa decât pe serviciile care aveau suport pentru tcp wrappers.  Trecând forțat la fail2ban am descoperit că începe să-mi placă încet, încet. Pe lângă faptul că există comenzi de “debanare” a unui IP fără să stai să dai sintaxa de iptables, mai pot să fac și chestiuțe de genul ăsta pe diverse loguri. Totul e să reușesc să regulez expresia aia cum trebuie.

(btw, sintaxa pentru debanare este “fail2ban-client set <jail-name> unbanip <ip-address>” )

Buun, primul pas este să ne uităm în logurile serverului de web să vedem cum arată liniile de încercare de login. Adică cam așa :

77.41.227.31 – – [21/Jun/2015:19:34:07 +0300] “POST /wp-login.php HTTP/1.1” 200 4024 “https://lazyadmin.ro/wp-login.php” “Mozilla/5.0 (Windows NT 6.0; rv:34.0) Gecko/20100101 Firefox/34.0”

Fail2ban are conceptul de filtre și jails. Definim niște filtre care trebuie să faca match pe linii din log iar apoi creăm un jail în care unim un filtru cu o acțiune. Exemple de filtre găsiți în /etc/fail2ban/filter.d/. De acolo m-am inspirat și eu pentru crearea filtrului pentru wp-login. Am creat un filtru nou denumit wp-login.conf în filter.d cu următoarele linii :

#
[Definition]
failregex = ^<HOST> .* “POST /wp-login.php.*$
ignoreregex =

Mai precis, ca să disecăm expresia regulată de mai sus, avem așa :

  • “^” – ancora de început de linie (marchează începutul liniei din log)
  • “<HOST>” – e sintaxa IP-ului pe care îl vom marca pentru banare
  • “.*” – “.” este orice 1 caracter, “*” înseamnă de 0 (zero) sau mai multe ori (până la infinit) ceea ce este înainte. Adică avem orice mai multe caractere, până la întâlnirea cuvântului “POST”.
  • “POST /wp-login.php” – este bucata relevantă din linia de log, cea care ne indică faptul că se trimite o încercare de logare pe wp-login.php
  • Mai avem un “.*” însemnând orice altceva până la “$” care este ancora de final de linie (marchează capătul liniei din log).

 Următorul pas este să testăm expresia regulată pe fișierul de log al serverului web. În cazul meu, pe logul nginx-ului :

fail2ban-regex /var/log/nginx/access.log /etc/fail2ban/filter.d/wp-login.conf

Dacă face match pe liniile din log veți vedea un rezultat similar cu acesta :

……………………………………………………………..
Failregex: 2240 total
|-  #) [# of hits] regular expression
|   1) [2240] ^<HOST> .* “POST /wp-login.php.*$

……………………………………………………………..

Următorul pas este să punem filtrul într-un jail și să îi spunem ce să facă cu match-urile respective. Declarațiile de jail-uri sunt în /etc/fail2ban/jail.conf și în /etc/fail2ban/jail.local. Nu faceți greșeala să editați jail.conf, există riscul să fie suprascris la update-ul pachetului fail2ban, mai bine adăugați declarațiile în jail.local undeva la final :

[wp-login]
enabled = true
filter = wp-login
action = iptables-multiport[name=NoAuthFailures, port=”http,https”]
logpath = /var/log/nginx/access.log
findtime = 7200
bantime = 86400
maxretry = 5

Adică dacă există mai mult de 5 încercări de logare în 7200 de secunde (2h) de la aceeași adresă IP, va fi adăugată acea adresă IP într-o regulă de iptables care filtrează porturile http si https pentru 86400 de secunde (24h). Vă jucați cum vreți cu valorile astea. Pentru mine sunt relativ ok.

Restartați serviciul de fail2ban și bucurați-vă de liniște :

2015-06-21 21:16:37,361 fail2ban.actions: WARNING [wp-login] Ban 37.122.69.229