Copyright ©2003.-2017. CARNet. Sva prava pridržana.
Mail to portal-team(at)CARNet.hr
Brute-force [2] i DDOS [3] mrežni napadi na razne servise su svakodnevica svakog sistem-inženjera već dulji niz godina. Postoji niz rješenja koji pokušavaju riještiti taj problem, bilo hardverskim bilo softverskim putem. Fail2ban je softverski alat koji prati sumnjive unose u logovima, te nakon predefiniranog broja ilegalnih akcija jednostavno izolira napadača preko nekog od firewall mehanizama.
Fail2ban je dostupan i kao CARNet paket fail2ban-cn.
Slušajući zahtjeve kolega sistem-inženjera, u CARNetovu ponudu paketa uvrstili smo fail2ban-cn. Riječ je o jednostavnom i efikasnom sustavu zaštite koji prati logove i na određene učestale pojave blokira napadača.
Ovo čini uporabom iptables pravila, te tako blokira sve IP adrese s kojih dolaze napadi. Napadi najčešće dolaze od strane slabo upućenih korisnika, koji pokreću skripte i programe koje pronađu na Internetu (takozvani script-kiddies). Uspješnost provala preko ovih skripti je izuzetno niska, ali resurse utrošene s naše strane na ove napade, kao i mogućnost upada na sustav ne treba zanemariti.
Iako postoje drugi sustavi zaštite zasnovani na ovom principu, fail2ban je jedan od najjednostavnijih. On štiti odmah nakon instalacije, i ne traži više nikakvo konfiguriranje. Automatski štiti od SSH napada, iako je moguće zaštititi i druge servise bazirane na PAM-u.
Odmah ćemo se osvrnuti na mane fail2ban pristupa. Fail2ban je često kritiziran kao nepotreban servis, jer troši sistemske resurse (doduše, jako male), a ista se stvar može postići s recent mehanizmom [5] ugrađenim preko modula ipt_recent (http://www.snowman.net/projects/ipt_recent [6]) u iptablesima.
Najopasnije što se može dogoditi s fail2ban pristupom je da bilo tko na sustavu može uspješno zaustaviti rad bilo kojeg servisa krivotvorenjem unosa u logovima. Zapisati nesto u logove mogu i programski jezici, primjerice PHP, pa stoga treba pripaziti na to tko može pisati u logove. Možda bi bilo dobro zaštititi /dev/log device tako da se promijeni grupa, a sve servise potom upišemo u tu grupu.
Da ti napadi nisu rijetkost, pokazat će sljedeća naredba, odnosno niz naredbi:
zcat /var/log/auth.log*gz | grep 'Failed password' | grep sshd | \
awk '{print $1,$2}' | sort | uniq -c | sort -n -k 3
Nakon instalacije, sustav automatski postaje aktivan i podrazumijevano je sustav zaštićen od SSH brute force napada. Pogledajmo te podrazumijevane vrijednosti, i lokacije konfiguracijskih datoteka.
Glavna konfiguracijska datoteka je /etc/fail2ban/fail2ban.conf. Ostale konfiguracijske datoteke se, kako je to već uobičajeno na Debianu, nalaze u conf.d direktorijima action.d, filter.d, te u dodatnoj konfiguracijskoj datoteci jail.conf. Ove konfiguracijske datoteke odražavaju interni način rada fail2ban-a:
filter - određuje što će izazvati "okidanje" akcije, uporabom regularnih izraza
action - određuje jednu ili više odgovora na "okidanje"
jail - skupina filtera i jedne (ili više) akcija
Navest ćemo primjer za SSH. U datoteci jail.conf se nalazi unos:
[ssh]
enabled = true
port = ssh
filter = sshd
logpath = /var/log/auth.log
maxretry = 6
U datoteci action.d/sshd.conf možemo naići na unose poput ovoga:
[INCLUDES]
before = common.conf
[Definition]
_daemon = sshd
failregex = ^%(__prefix_line)s(?:error: PAM: )?Authentication failure for .* from <HOST>\s*$
^%(__prefix_line)srefused connect from \S+ \(<HOST>\)\s*$
^%(__prefix_line)sAddress <HOST> .* POSSIBLE BREAK-IN ATTEMPT\s*$
ignoreregex =
I na kraju, u datotekama akcija (podsjetimo se, može ih biti više za jedan jail) možemo naći iptables pravila. Primjerice:
[Definition]
actionstart = iptables -N fail2ban-<name>
iptables -A fail2ban-<name> -j RETURN
iptables -I INPUT -p <protocol> --dport <port> -j fail2ban-<name>
actionstop = iptables -D INPUT -p <protocol> --dport <port> -j fail2ban-<name>
iptables -F fail2ban-<name>
iptables -X fail2ban-<name>
actioncheck = iptables -n -L INPUT | grep -q fail2ban-<name>
actionban = iptables -I fail2ban-<name> 1 -s <ip> -j DROP
actionunban = iptables -D fail2ban-<name> -s <ip> -j DROP
[Init]
name = default
port = ssh
protocol = tcp
Iptables pravilima se nećemo u ovom članku baviti, samo ćemo reći da fail2ban prilikom starta pokreće akciju "actionstart", prilikom gašenja "actionstop", a i ostalim akcijama samo ime govori prilikom čega se pokreću.
U prvom nastavku [8] iz serije članaka o fail2ban sustavu zaštite uveli smo vas u osnovne postavke i način rada fail2ban sustava. U ovom nastavku ćemo malo više obratiti pažnju na ono što se zbiva “ispod haube”.
Fail2ban rabi standardni način rada, putem daemona i klijentskog programa. S daemon programom ne bismo trebali imati nikakav direktan kontakt, jer se sve poruke daemonu mogu navesti preko klijenta. Daemon, ipak, kod starta prima određene opcije, pa ćemo ih navesti.
-b start in background
-f start in foreground
-s <FILE> socket path
-x force execution of the server (remove socket file)
-h, --help display this help message
-V, --version print the version
Kao što se može vidjeti, opcije su iskoristive praktički samo kod debugiranja i testiranja, pa se nećemo na njima zadržavati, jer je opis samorazumljiv. S druge strane, klijent prima sljedeće naredbe:
-c <DIR> configuration directory
-s <FILE> socket path
-d dump configuration. For debugging
-i interactive mode
-v increase verbosity
-q decrease verbosity
-x force execution of the server (remove socket file)
-h, --help display this help message
-V, --version print the version
I ovdje možemo vidjeti da opcije prije svega služe za razna testiranja prije puštanja u produkciju. Najzanimljivije su opcije za smanjivanje i povećavanje razine zapisa u logovima (verbosity). Razina 1 je minimalna razina, a razina 4 se rabi samo u postupku eventualnog debugiranja.
No, najsnažnija karakteristika klijenta je direktna mogućnost konfiguriranja cijelog sustava, baš kao da smo rabili konfiguracijske datoteke. Naredbi je mnogo, pa ćemo opisati najkorisnije, a druge ćemo samo spomenuti. Za daljnje informacije pogledajte dokumentaciju na adresi http://www.fail2ban.org/wiki/index.php/MANUAL_0_8 [9].
Naredbe koje fail2ban-client podržava:
start pokreće se daemon i svi "zatvori" (jailovi)
reload ponovno se učitava konfiguracija
reload <JAIL> ponovo se učitava samo zatvor pod imenom <JAIL>
stop zaustavlja se daemon i svi zatvori
status dobija se informacija o trenutnom stanju daemona
ping provjerava se je li daemon uopće pokrenut
set loglevel <LEVEL> postavlja se razina informativnosti (verbosity) na razinu <LEVEL>.
get loglevel ispisuje razinu informativnosti
get/set …
Opcija iza get/set naredbi ima mnogo, primjerice addignoreip, addlogpath, addfailregex, findtime i tako dalje. No, vjerojatno je besmisleno na ovaj način učiti konfigurirati fail2ban, i držati se konfiguriranja preko standardnih konfiguracijskih datoteka. Ipak, neke naredbe bi bilo dobro znati, primjerice:
# fail2ban-client get loglevel
Current logging level is INFO
Dakle, trenutna razina je INFO (razina 3). Ostale razine su: ERROR (1), WARN (2) i DEBUG (4).
Fail2ban ima i interaktivni način, pa ćemo ostale opcije demonstarirati na taj način. Ulazak u interaktivni način je pomoću opcije "-i".
# fail2ban-client -i
fail2ban> get logtarget
Current logging target is:
`- /var/log/fail2ban.log
Dakle, ova naredba se isto mogla izvršiti i direktno iz naredbene linije, a prikazuje u koju datoteku se zapisuju logovi.
fail2ban> ping
Server replied: pong
Slično kao i standardna naredba "ping" koja daje osnovnu informaciju je li mrežni uređaj aktivan, i ovdje ona samo daje potvrdu da je daemon "živ", bez dodatnih informacija.
fail2ban> status
Status
|- Number of jail: 2
`- Jail list: pam-generic, ssh
Naredba "status" bez dodatnih opcija daje samo popis trenutno aktivnih zatvora.
fail2ban> status ssh
Status for the jail: ssh
|- filter
| |- File list: /var/log/auth.log
| |- Currently failed: 8
| `- Total failed: 6143
`- action
|- Currently banned: 0
| `- IP list:
`- Total banned: 17
Nešto izdašniji ispis daje naredba "status <JAIL>", gdje ćemo dobiti statističke podatke o tome koliko je adresa trenutno na "čekanju", te koliko ih je trenutno na crnoj listi. Adresa će na crnu listu doći kad prekorači zadane parametre.
fail2ban> stop ssh
Jail stopped
Sa naredbom "stop" možemo određene zatvore zaustaviti, bilo radi dodatne konfiguracije, bilo radi pogrešnog rada, (pre)opeterećenja sustava i slično.
Kad smo se upoznali s osnovama i načinom rada, dalje je prilično jednostavno. Nakon instalacije paketa, automatski miate zaštitu od SSH i PAM napada (a autentikaciju preko PAM-a rabi većina servisa, primjerice login). Neki za autentikaciju ne rabe PAM, primjerice Apache može rabiti direktno LDAP, ili vlastiti htpasswd mehanizam. U tom slučaju, sve što trebate učiniti je uključiti odgovrajući zatvor u jail.conf:
[apache]
enabled = false
port = http,https
filter = apache-auth
logpath = /var/log/apache*/*error.log
maxretry = 6
Za uključivanje je dovoljno promijeniti prvi redak u:
enabled = true
Nakon toga samo treba napraviti reload:
# fail2ban-client reload
i provjeriti je li zatvor uključen:
# fail2ban-client status
Status
|- Number of jail: 3
`- Jail list: apache, pam-generic, ssh
Od tog trenutka je aktivna i zaštita definirana s parametrom failregex unutar datoteke /etc/fail2ban/filter.d/apache-auth.conf.
Slična stvar je i sa drugim servisima, jedino kod mail servisa (kod nas je standardan Postfix), možda će trebati promijeniti putanju do logova:
[postfix]
enabled = true
port = smtp,ssmtp
filter = postfix
logpath = /var/log/mail.log
u
logpath = /var/log/mail/mail.log
U sljedećem, zadnjem, nastavku, pokazat ćemo vam kako prilagoditi fail2ban svojim potrebama, te napraviti vlastite filtere i akcije, u slučaju da ne postoje odgovarajuće u postojećoj distribuciji.
U prethodna dva nastavka [12] smo vam pokazali način rada, te osnovnu konfiguraciju i uporabu programa fail2ban. U ovom nastavku zaokružit ćemo priču, i objasniti kako napraviti svoj, odnosno prilagoditi neki postojeći filter svojim potrebama.
Kako sam fail2ban donosi filtere za većinu servisa koji će vam ikada trebati, bio nam je problem osmisliti neki novi filter. No, ipak smo se dosjetili jedne svima poznate pojave u apache logovima: tragovi potrage za bugovitim skriptama na sustavu.
Obično se traže stare inačice PHP skripti, a najčešće je to phpmyadmin. PhpMyAdmin je PHP skripta za jednostavan rad s MySql bazama podataka na vašem sustavu, ali je poznat po mnogobrojnim sigurnosnim rupama.
U vašim logovim često možete vidjeti unose slične ovima:
XX.YY.128.146 - - [18/Sep/2009:15:04:52 +0200] "GET
/phpmyadmin/main.php HTTP/1.0" 404 361 "-" "-"
XX.YY.128.146 - - [18/Sep/2009:15:04:17 +0200] "GET
/setup/phpmyadmin/main.php HTTP/1.0" 404 367 "-" "-"
XX.YY.128.146 - - [18/Sep/2009:15:04:31 +0200] "GET
/administrator/phpmyadmin/main.php HTTP/1.0" 404 375 "-" "-"
XX.YY.128.146 - - [18/Sep/2009:15:04:31 +0200] "GET
/admin/phpMyAdmin-2.5.6-rc2/main.php HTTP/1.0" 404 375 "-" "-"
Napadači žele "ispipati" imate li PhpMyAdmin, i koje je inačice. Naravno, obično se radi o script-kiddies korisnicima, ali koji ipak uz pomoć određenih programa mogu upasti na vaš stroj. Iz tog razloga je najbolje preventivno onemogućiti napadačevu IP adresu. Pa, krenimo redom.
U direktoriju /etc/fail2ban/filter.d napravimo novu datoteku apache-php.conf (izostavili smo komentare radi kratkoće, vi ih slobodno ostavite):
[Definition]
failregex = [[]client <HOST>[]] .*phpmyadmin.*$
[[]client <HOST>[]] .*PhpMyAdmin.*$
ignoreregex = 161\.53\.XX\.\d
161\.53\.\d\.YY
Umjesto XX i YY upišite IP adrese i adrese mreže svog LAN-a, i adrese vaših suradnika koji trebaju pristu PhpMyAdminu. Slično možete i za bilo koji dio IP adrese, s napomenom da oznaka '\d' označava regex [13]klasu '[0-9]', dakle obuhvaća sve brojeve od 0 do 9. Ovu sintaksu, među ostalim, rabi programski jezik Python u kojem je napisan fail2ban.
U datoteku jail.conf dodamo retke:
[apache-php]
enabled = true
port = http,https
filter = apache-php
action = iptables[name=apache-php, protocol=tcp]
logpath = /var/log/apache*/*error.log
maxretry = 5
i napravimo
# fail2ban-client reload
Što smo ovime napravili? Rezultat će biti zabrana pristupa bilo kojem klijentu (koji nije u varijabli ignoreregex), a koji pokuša više od 5 puta pristupiti PhpMyAdmin programu. Ovo će odraditi iptables.conf, no vi možete birati i između nekoliko drugih načina zaštite (primjerice preko tcp_wrappera).
Sami regularni izrazi su case-sensitive, i morat ćete pripaziti na velika i mala slova, što uopće nije loše kako slučajno ne bi onemogućili previše stvari odjednom.
Umjesto zabrane, možete jednostavno poslati mail sebi ili drugim kolegama da se nešto događa. U iptables.conf upišite:
actionban = iptables -I fail2ban-<name> 1 -s <ip> -j DROP
printf %%b "Pozdrav,\n
Klijent <ip> je blokiran zbog <failures> pokusaja\n
pristupa po pravilu <name>.\n
\n
Vas Fail2Ban" | mail -s "[Fail2Ban] <name>: <ip> blokiran" pero@domena.hr
Uz zabranu, fail2ban će poslati mail s osnovnim informacijama na neku adresu. Oprezno s ovom funkcijom, kako pretjerani broj mailova ne bi napravio DDoS sam po sebi!
Na kraju, samo ćemo navesti konfigurabilne parametre koje možete rabiti u svojim "zatvorima". Iako su im imena samoobjašnjiva, radi potpunosti navest ćemo ih, zajedno s pretpostavljenim vrijednostima:
maxretry 3
Broj pokušaja, točnije, broj puta kada je neki redak u logovima odgovorao regexu koji smo postavili. Radi se o
individualnim brojevima za svaku IP adresu.
filter Ime filtera (u našem slučaju apache-php).
Filter se nalazi u direktoriju /etc/fail2ban/filters.d, u našem slučaju bi to bio apache-php.conf. Vrijedi napomenuti da svako pravilo unutar filtera povećava brojač (maxretry) za jedan, naravno ukoliko se redak u logu poklapa sa zadanim regularnim izrazima.
findtime 600 sec
Brojač će se vratiti na nulu, ukoliko unutar ovog vremena s iste adrese ne bude nikakve dodatne aktivnosti. Neki programi pokušavaju proći "ispod radara" i svoje pokušaje smanjuju na jedva primjetnu razinu. Neke pak treba što prije detektirati i onemogućiti, pa je namještanje ove vrijednosti individualna potreba svakog sistemca i stroja.
bantime 600 sec
Vremenski period koliko će određena IP adresa biti zabranjena.
logpath /var/log/messages
Jednostavno, putanja do log datoteku koju ćemo nadzirati. Može biti /var/log/syslog, ili bilo što drugo, pa čak i izvan /var/log.
Obavezno istestirajte nova pravila prvo na neprodukcijskom stroju, a ukoliko zapnete konzultirajte Wiki dokumentaciju na http://www.fail2ban.com/wiki [14], a pomoć za Python regularne izraze možete naći na http://docs.python.org/dev/howto/regex.html [15].
Za općenite regularne izraze, jako dobar izvor informacija je web sjedište http://www.regular-expressions.info/ [16].
Sretno u uporabi fail2ban sustava!
Links
[1] https://sysportal.carnet.hr./sysportallogin
[2] http://en.wikipedia.org/wiki/Brute_force_attack
[3] http://en.wikipedia.org/wiki/Ddos#Distributed_attack
[4] https://sysportal.carnet.hr./taxonomy/term/33
[5] https://sysportal.carnet.hr./node/71
[6] http://www.snowman.net/projects/ipt_recent
[7] https://sysportal.carnet.hr./taxonomy/term/25
[8] https://sysportal.carnet.hr./node/544
[9] http://www.fail2ban.org/wiki/index.php/MANUAL_0_8
[10] https://sysportal.carnet.hr./taxonomy/term/17
[11] https://sysportal.carnet.hr./taxonomy/term/28
[12] https://sysportal.carnet.hr./node/542
[13] https://sysportal.carnet.hr./system/files/RegExNew.ppt
[14] http://www.fail2ban.org/wiki
[15] http://docs.python.org/dev/howto/regex.html
[16] http://www.regular-expressions.info/