Trumpai: Fail2ban skaito žurnalo failus ir ugniasienėje blokuoja adresus, kurie per laiko langą pasirodo per dažnai. Nginx ir Apache jis turi paruoštus jail, tokius kaip nginx-botsearch ar apache-noscript; savus filtrus išbandykite su fail2ban-regex. Nustatymai priklauso jail.local, jūsų pačių adresai ignoreip, pasikartojančius pažeidėjus sugauna recidive jail. Nuo pavienių tikslinių atakų Fail2ban nepadeda, nuo masinių skenavimų padeda.
Kai žurnalai pilni skenerių
Kas šiomis dienomis peržiūri savo žiniatinklio serverių prieigos žurnalus, dažnai randa juos pilnus užklausų į kelius, kurių nėra: senos administravimo sąsajos, testiniai failai, kitų produktų žinomi pažeidžiamumai. Tokioje padėtyje kaip PHP2Shell prisideda tikslinė pažeidžiamų serverių paieška: Cloudflare ir Patchstack pranešė apie atakos bandymus, Unit 42 suskaičiavo daugiau nei 22,6 mln. viešai pasiekiamų, potencialiai pažeidžiamų instancijų.
Fail2ban yra patikrintas įrankis nuo šios masės. Jis skaito žurnalo failus, filtrais atpažįsta įtartinus įrašus ir siuntėjo adresą nustatytam laikui užblokuoja ugniasienėje. Tai atlaisvina serverį, sumažina žurnalų triukšmą ir apsunkina sistemingą bandymų perrinkimą iš vieno šaltinio.
Ko Fail2ban negali, yra taip pat svarbu: pavienė užklausa, išnaudojanti spragą, nesustabdoma. Nuo PHP2Shell padeda tik PHP atnaujinimas. Kaip vyksta automatizuotos atakos, aprašo Masiniai skenavimai dėl nepataisyto PHP.
Fail2ban Nginx ir Apache: pateikti jail
Jail sujungia filtrą su žurnalo failu ir blokavimo veiksmu. Pateiktas jail.conf jau turi jail žiniatinklio serveriams. Numatytai jie išjungti ir aktyvuojami po vieną.
| Jail | Žiniatinklio serveris | Atpažįsta |
|---|---|---|
nginx-http-auth |
Nginx | nepavykusius HTTP Basic prisijungimus |
nginx-limit-req |
Nginx | užklausas, viršijančias Nginx greičio ribą (rate limit) |
nginx-botsearch |
Nginx | tipinių, neegzistuojančių kelių paiešką |
nginx-bad-request |
Nginx | klaidingas užklausas |
apache-auth |
Apache | nepavykusius prisijungimus |
apache-badbots |
Apache | žinomas kenkėjiškų botų žymes |
apache-noscript |
Apache | neegzistuojančių scenarijų iškvietimus |
apache-overflows |
Apache | pernelyg ilgas užklausas |
apache-botsearch |
Apache | tipinių, neegzistuojančių kelių paiešką |
php-url-fopen |
abu | tam tikrus URL įtraukimo bandymų šablonus |
recidive |
abu | adresus, kuriuos Fail2ban pakartotinai užblokavo |
Pateiktos konfigūracijos numatytosios reikšmės gana švelnios: užblokavimas 10 minučių po 5 atitikmenų per 10 minučių. Žiniatinklio serveriams su dideliu skenavimo srautu verta ilgesnio užblokavimo ir didėjančio pakartojimų koeficiento.
Bazinė konfigūracija faile jail.local
jail.conf pats sako, kad jo keisti nereikia, nes atnaujinimai jį pakeičia. Savos reikšmės priklauso /etc/fail2ban/jail.local. Toliau pateiktas Nginx pavyzdys nustato prasmingus standartus ir aktyvuoja tinkamus jail:
# /etc/fail2ban/jail.local
[DEFAULT]
# Įrašyti savus pastovius adresus (pakeisti pavyzdinį adresą)
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
Apache vietoj to aktyvuokite, pavyzdžiui, apache-auth, apache-noscript ir apache-botsearch. Žurnalų kelius Fail2ban pateikia pagal distribuciją; jei jūsų keliai skiriasi, nustatykite logpath atitinkamame jail. Jei jūsų sistema žurnalus skaito tik per journal, padeda backend = systemd.
Savas filtras masinėms užklausoms į PHP failus
Tipiškas šablonas dabartinėje padėtyje yra daug užklausų per trumpą laiką į PHP failus, kurių nėra. Savas filtras tai atpažįsta pagal būsenos kodą 404. Jis aprašo tik tai, kas yra jūsų pačių žurnale:
# /etc/fail2ban/filter.d/nginx-php-404.conf
[Definition]
failregex = ^<HOST> -.*"(GET|POST|HEAD) [^"]*\.php[^"]*" 404
ignoreregex =
# Papildymas faile /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
Prieš aktyvuodami filtrą, išbandykite jį su tikru žurnalu. Taip pamatysite, kiek eilučių jis atitinka ir ar tarp jų yra teisėtų kreipinių:
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
# Atblokuoti netyčia užblokuotą adresą
sudo fail2ban-client set nginx-php-404 unbanip 203.0.113.25
Slenkstį pasirinkite dosniai. Robotas (crawler), kuris perėjinėja pasenusias nuorodas, ar stebėsenos paslauga neturi patekti į užblokavimą.
Dažniausios spąstai
Fail2ban įdiegiamas greitai, bet lengvai naudojamas neteisingai. Šiuos punktus patikrinkite prieš produkcinį naudojimą:
- Savęs užblokavimas: biuro, VPN ir stebėsenos adresai priklauso
ignoreip, kol jail dar neaktyvūs. - Prieš tai esančios paslaugos: už CDN ar apkrovos paskirstytuvo (load balancer) Fail2ban be pritaikymo mato tik jų adresus. Daugiau apie tai gide Administravimo prisijungimų apsauga nuo Brute Force.
- Žurnalų rotacija: pasikeitus žurnalo failui, Fail2ban turi skaityti naująjį failą. Po pirmos rotacijos patikrinkite, ar jail toliau skaičiuoja atitikmenis.
- Sąveika su ugniasiene: Fail2ban užblokavimus įrašo į ugniasienę. Kas savo ugniasienę valdo pilnai iš naujo įkeldamas taisyklių rinkinį, tuo metu gali šiuos įrašus ištrinti. Kaip pačiai ugniasienei sukurti, aprašyta skyriuje Ugniasienė žiniatinklio serveriui: atverti tik reikalingus prievadus.
- IPv6: atakos ateina ir per IPv6. Patikrinkite, ar jūsų blokavimo veiksmas apima abu protokolus.
Reguliariai analizuokite blokavimo sąrašus. Jei užblokavimai kaupiasi iš tam tikrų tinklų ar į tam tikrus kelius, tai užuomina apie tikslinę paiešką ir priežastis atidžiau pažvelgti į paveiktą programą.
Išvada: įrankis nuo masės, ne nuo visko
Fail2ban įrengiamas greitai ir nuima nuo žiniatinklio serverių dalį nuolatinio apšaudymo. Pateikti jail apima tipinius šablonus, savus filtrus galima be pavojaus išbandyti su tikrais žurnalais per fail2ban-regex, o recidive jail užtikrina, kad atkaklūs šaltiniai liktų išorėje ilgiau.
Neviršykite jo vertės. Fail2ban reaguoja į pasikartojimą, o ne į pirmą atitikmenį, ir mato tik tai, kas yra žurnaluose. Nuo tokios spragos kaip PHP2Shell padeda tik atnaujinimas, nuo paskirstytų atakų iš daugelio adresų Fail2ban beveik nepadeda. Savo vertę jis atskleidžia kaip vienas sluoksnis tarp kelių: šalia liesos ugniasienės, sutvirtintos žiniatinklio serverio konfigūracijos, dviejų veiksnių prisijungimo ir stebėsenos, kuri įtartinus atvejus ne tik blokuoja, bet ir praneša.
Kaip PHP SOS padeda konkrečiai?
- Analizuoti žurnalus: pažiūrime, kokie šablonai pasirodo jūsų prieigos žurnaluose, ir parenkame tinkamus jail.
- Įrengti ir išbandyti: įrengiame Fail2ban su savais filtrais, kiekvieną filtrą išbandome su tikrais žurnalais ir jūsų pastovius adresus įrašome kaip išimtį.
- Išsiaiškinti sąveiką: CDN, apkrovos paskirstytuvą, ugniasienę ir žurnalų rotaciją suderiname taip, kad užblokavimai pataikytų į teisingus adresus.
- Stebėti: saugumo stebėsenos rėmuose nuolat analizuojame užblokavimus ir įtartinus atvejus.
Dažni klausimai
Ar Fail2ban apsaugo nuo PHP2Shell?
Ne. Fail2ban reaguoja tik tada, kai adresas žurnaluose pasirodo kelis kartus. Pavienės sėkmingos atakos tai nesustabdo. Tačiau Fail2ban sumažina skenerių keliamą apkrovą ir pabrangina pasikartojančius bandymus iš to paties šaltinio.
Kodėl jail.conf neturėčiau keisti tiesiogiai?
Failas pakeičiamas per paketų atnaujinimus, ir jis pats tai sako. Savi nustatymai priklauso jail.local arba failams po jail.d. Ten jie tikslingai perrašo numatytąsias reikšmes.
Kas yra recidive jail?
Jail, kuris vertina paties Fail2ban žurnalą. Kas vis iš naujo užblokuojamas, gauna gerokai ilgesnį užblokavimą. Pateiktoje konfigūracijoje jis trunka savaitę.
Ar Fail2ban veikia už Cloudflare ar apkrovos paskirstytuvo (load balancer)?
Tik su papildoma konfigūracija. Be jos žurnaluose rašomas prieš tai esančios paslaugos adresas, ir užblokavimas paliestų visus lankytojus. Tada žiniatinklio serveris turi perimti tikrąjį lankytojo adresą, o užblokavimus geriau nustatyti prieš tai esančioje paslaugoje.