Fail2ban:
#failregex = ([w-.^_]+).*] "(CONNECT.*|GET http:.*|POST http:.*|GET /airtel/channels-sized-transparent/.*|GET /(.env|vendor/phpunit/).*|POST (/heartbeat/heartbeat|/cgi-bin/).*|GET.*(AhrefsBot|ineedthispage=yes|/wp-includes/wlwmanifest.xml).*|.*(YandexBot|SemrushBot|serpstatbot|BLEXBot|Adsbot|Barkrowler|MegaIndex.ru|Go-http-client|DotBot|python-requests|aiohttp|um-IC|SentiBot|ias-va|magpie-crawler|Sogou web spider)/.*|.* FUp/.*|.*(PetalBot;|IndeedBot |Keybot Translation-Search-Machine|ALittle Client|wp_is_mobile|Mediatoolkitbot|SEOkicks|CheckMarkNetwork|CensysInspect|woorankreview|FirmoGraph|Mail.RU_Bot|DataForSeoBot|ZoominfoBot|zgrab/0|expanseinc.com|seoscanners.info|binance.com).*|.*/../../../.*|GET /__media__/js/netsoltrademark.*|GET /shell?.*|.*Palo Alto Networks.*|GET /(v1|v2|v5|v6|v7|play|foc|tools|dts|ctadx|interface|api|fpupdate|TV_Update|ecom_mobile|axis2-admin)/.*|.*"-" "Dalvik/.*|GET /.golangci..*)
# Lepší varianta je tahle. Aspoň nemusí Fail2ban zjišťovat mnoho podmínek i několikrát za sekundu. Hlavně není potřeba kontrolovat logy každý den. Tohle blokuje prostě vše. A zatížení systému je téměř nulové - ale pouze do 20000 zablokovaných IP adres - potom je nutné vše smazat a jet znovu. Je to na port 80.
failregex = ^([0-9.:]*:80.*] "(CONNECT|GET|POST|HEAD) /((?!yes.txt|favicon.ico|server-status|munin|info.php|index.php|benchmark.php|opcache|robots.txt|ads.txt).)*)$ ignoreregex = ^.*Googlebot.*$
[apache-lj]
enabled = true
port = http,https
filter = apache-lj
logpath = %(apache_access_log)s tail
maxretry = 1
findtime = 30
bantime = -1 # každého to zablokuje navždy, funguje to mnohem rychleji a lépe
Aby se pořád neplnil disk, je dobré čas od času pustit tohle:
#/etc/init.d/fail2ban stop
#rm -f /var/lib/fail2ban/fail2ban.sqlite3
#rm -f /var/log/fail2ban.*
#/etc/init.d/fail2ban restart
A ještě jedno blokovací nastavení:
failregex = ^([a-z.:]*:80.*] "(CONNECT|GET|POST|HEAD) /[a-z0-9A-Z.:]*/.*(.1|.bak|.old|.tmp|.backup|.dist|.save|.cfc|config|credentials|.rar|.gz|.sql|.zip|PHP/|.php|.txt) HTTP.*)$
Dodatečný skript na blokování IP rozsahů (zároveň v tomto případě není nutné mazat výše uvedené soubory, protože se nebude plnit disk):
#!/bin/bash
source /root/scripts/sql_connect ted=`date --date='2 minutes ago' '+%Y-%m-%d %H:%M:'`; datum=$(date +%Y.%m.%d-%H:%M:%S); echo $ted; echo "apache:"; i=1; for ip in `cat /var/log/fail2ban.log |grep "$ted"|grep -v "0/16"|grep -v "0/24"|grep -v "[0-9]:[0-9]:[0-9]" |grep -v ERROR|grep "\[apache-lj\] Ban "|awk {'print $8'} |grep '[0-9]'|sort|uniq`; do echo "c"; continent=`./scripts/continent $ip`; hostnamee=`timeout 5s host $ip |awk '{print $5}'`; country=`./scripts/country $ip|awk {'print $1'}|tr '[a-z]' '[A-Z]'`; if [ "$hostnamee" == "cache.google.com" ]; then fail2ban-client set dovecot unbanip $ip; elif [ "$country" != "CZ" ] && [ "$country" != "SK" ] && [ "$country" != "AT" ] && [ "$country" != "IT" ] && [ "$country" != "ES" ] && [ "$country" != "DE" ] && [ "$country" != "HR" ] || [ "$country" == "GB" ; then echo "!!!!!!!!!!!! $ip - $country - !!!!!!!!!!!!!!!!"; if [[ $ip != *":"* ]]; then blockip=`echo $ip | tr "." " "|awk {'print $1"."$2".0.0/16"'}`; echo "unban $ip - $continent - $country - $blockip"; echo "ban $blockip, unban:"; fail2ban-client set apache-lj unbanip $ip echo "blockip⬇ "; fail2ban-client set apache-lj banip $blockip; mysql -h $hostname -u $user --password=$pass -D vsevjednom -e "INSERT INTO pocet(co,pocet) VALUES('$country', '1') ON DUPLICATE KEY UPDATE pocet=pocet+1"; fi; #elif [ "$continent" == "Asia" ] || [ "$continent" == "Asia/Hong_Kong" ] || [ "$continent" == "Asia/Shanghai" ] || [ "$continent" == "Asia/Bangkok" ] || [ "$continent" == "AS" ] || [ "$continent" == "NA" ] || [ "$continent" == "Asia/Kolkata" ] || [ "$continent" == "Asia/ else echo "$ip - $continent (? - $country) - IP odblokována"; echo "$ip - $continent ($country) - IP ODBLOKOVÁNA, protože $country" | mail -s "$datum" podpora@vsevjednom.cz; fail2ban-client set apache-lj unbanip $ip fi; echo $i; if [ "$i" == "20" ]; then break; fi (( i++ )) done;
V případě útoku na emaily (Dovecot) pomůže ve Fail2ban filtr dovecot. A následný skript vypadá takto:
echo "dovecot:"; for ip in `cat /var/log/fail2ban.log |grep "$ted" |grep -v "0/16"|grep -v "0/24"|grep -v "[0-9]:[0-9]:[0-9]" |grep -v ERROR|grep "\[dovecot\] Ban "|awk {'print $8'} |grep '[0-9]'|sort|uniq`; do country=`./scripts/country $ip|awk {'print $1'}`; echo " $ip - $country - $hostname"; if [ "$country" != "CZ" ] && [ "$country" != "SK" ] && [ "$country" != "AT" ] && [ "$country" != "IT" ] && [ "$country" != "ES" ] && [ "$country" != "DE" ] && [ "$country" != "HR" ]; then # blockip=`echo $ip | tr "." " "|awk {'print $1"."$2"."$3".0/24"'}`; blockip=`echo $ip | tr "." " "|awk {'print $1"."$2".0.0/16"'}`; mysql -h $hostname -u $user --password=$pass -D vsevjednom -e "INSERT INTO pocet(co,pocet) VALUES('$country', '1') ON DUPLICATE KEY UPDATE pocet=pocet+1"; echo "$ip - $country - $blockip"; fail2ban-client set dovecot unbanip $ip echo "!!!"$blockip; fail2ban-client set dovecot banip $blockip; else fail2ban-client set dovecot unbanip $ip echo "$ip - $country (? - $country)"; fi; done
Velmi rychlé řešení
Pokud je útok na port 80, stačí ho v Apache úplně vypnout, ale zároveň je nutné vypnout i Fail2ban (pokud ne, server bude přetížený kvůli Fail2ban). Ani nevím, jak jsem to celé udělal. Fail2ban bez problému používám. Asi po vypnutí portu 80 pomohl restart serveru.