Fail2ban – блокиране при грешна парола
Fail2Ban е програма за предотвратяване на нежелани прониквания от Интернет в Линукс сървъри, написана е на езика за програмиране Python. Тя работи като прочита логовете на SSH, FTP, HTTP и други хостинг услуги на Линукс сървъри. При определен брои неосъществени оторизирания Fail2ban ще блокира само тази услуга за определено време само за атакуващия IP адрес. Fail2Ban използва iptables профили да блокира опитите на груба сила (Brute Force) като следи логовете на Линукс услугите в /var/log/$service.log
Инсталиране
sudo apt-get install fail2ban |
Копиране на примерен конфигурационен файл
cd /etc/fail2ban sudo cp jail.conf jail.local |
Редактиране на конфигурациония файл
sudo nano jail.local |
Моят конфигурационен файл
[DEFAULT] mta = mail destemail = mymail@server.net sendername = Fail2Ban_your@server.net action = %(action_mwl)s [pureftpd] enabled = true port = ftp filter = pureftpd logpath = /var/log/syslog bantime = 3600 findtime = 600 maxretry = 3 [dovecot-pop3imap] enabled = true filter = dovecot-pop3imap action = iptables-multiport[name=dovecot-pop3imap, port="pop3,pop3s,imap,imaps", protocol=tcp] logpath = /var/log/mail.log maxretry = 3 [postfix] enabled = true port = smtp,ssmtp,submission filter = postfix logpath = /var/log/mail.log [postfix-sasl] enabled = true port = smtp filter = postfix-sasl logpath = /var/log/mail.log bantime = 3600 findtime = 600 maxretry = 3 [dropbear] enabled = true port = ssh filter = dropbear logpath = /var/log/auth.log maxretry = 3 [ssh-ddos] enabled = true port = ssh filter = sshd-ddos logpath = /var/log/auth.log maxretry = 3 [apache] enabled = true port = http,https filter = apache-auth logpath = /var/log/apache2/error.log maxretry = 3 [apache-multiport] enabled = true port = http,https filter = apache-auth logpath = /var/log/apache2/error.log maxretry = 3 [apache-noscript] enabled = true port = http,https filter = apache-noscript logpath = /var/log/apache2/error.log maxretry = 3 [apache-overflows] enabled = true port = http,https filter = apache-overflows logpath = /var/log/apache2/error.log maxretry = 2 [roundcube-auth] enabled = true filter = roundcube-auth port = http,https logpath = /var/log/roundcube/errors |
Както е видно от конфигурациония файл на тази машина има postfix майл сървър който ми изпраща на мейла всеки един блокиран неуспешен опит на услугите които следи със следната конфигурация:
mta = mail destemail = mymail@server.net sendername = Fail2Ban_your@server.net action = %(action_mwl)s |
Аз в моя мейл клиент получавам това:
Нека разгледаме един модул на услуга от този конфигурационен файл:
[postfix-sasl] – Това е оторизиращия механизъм на мейл сървъра
enabled = true – false няма да се изпълни, true ще се изпълни
port = smtp – Порта който използва
filter = postfix-sasl – iptables профила който ще използва
logpath = /var/log/mail.log – от къде взима историята за неуспешна ауторизация
bantime = 3600 – времето в секунди в което ще блокира услугата
findtime = 600 – времето в секунди в което ще брой неуспешните опити
maxretry = 3 – броя на опитите за ауторизация
След като опишем услугите които ползваме трябва да рестартираме fail2ban за да влязат промените в сила:
sudo service fail2ban restart |
За да придобием повече информация какво прави fail2ban освен от мейла ако е настроен можем да разгледаме логовете му.
sudo tail -f /var/log/fail2ban.log |
2016-12-31 06:45:08,756 fail2ban.actions: WARNING [postfix-sasl] Unban 65.83.46.99 2016-12-31 06:45:18,872 fail2ban.actions: WARNING [postfix-sasl] Ban 65.83.46.99 |
Unban и Ban всъщност означава – разблокиран и блокиран, за определен период от време, findtime = 600 ако не се оторизира 3 пъти maxretry = 3 ще бъде блокиран за bantime = 3600 секунди време.
ipset – хиляди правила в няколко реда
ipset също е модул в ядрото на Линукс което на практика е разширение в iptables. За да обясня как работи ipset трябва да се върна в началото и да обясня как работи iptables. Нека си представим (само за тест), че услугата SSH искам да я спра за всички и само определен брой мрежи и адреси да имат достъп до нея:
iptables -A INPUT -p tcp --dport 22 -s 93.155.130.0/23 -j ACCEPT iptables -A INPUT -p tcp --dport 22 -s 93.155.162.44 -j ACCEPT iptables -A INPUT -p tcp --dport 22 -s 93.155.169.55 -j ACCEPT iptables -A INPUT -p tcp --dport 22 -j DROP |
Първите три реда които завършват с ACCEPT разрешават пакети идващи от -s IP само на този порт -p tcp –dport 22 във веригата пристигащи INPUT добави правилото да е последно -A. Реда който завършва с DROP забранява на всички порт 22 (SSH) без горните три естествено. Логиката надявам се е ясна, разбира се с тези четири реда не научихме iptables – това е само една трошичка от нея. Fail2ban върши прекрасна работа но аз искам да си направя собствена верига с която да блокирам IP адреси и мрежи от публична листа като Spamhaus например.
Spamhaus държи списък с “лошите” мрежи http://www.spamhaus.org/drop/drop.lasso които аз искам да блокирам. Но тук аз срещам два проблема. Първият е, че в списъка има 827 мрежи което са си 827 правила в iptables. След като знаем как работи iptables знаем, че за всеки пакет се взима решение след като той премине през всички правила което на практика излиза, че всички пакети идващи към нашият сървър трябва да минат през тези правила. След Spamhaus аз искам да ползвам blacklist и на OpenBL където има 13191 IP адреса които са заразени или пращат спам.
Всъщност искам да блокирам и Китай, и Северна Кореа, защото те нямат работа в моя сървър, но така станаха над 20000 правила, ако всички пакети минават през тези правила едва ли моят сървър ще работи коректно (за да пиша това съм пробвал, не работи коректно !!!) Спасението е ipset който прави така, че в iptables 10000 правила може да изглеждат като 1. Тоест Spamhaus ще е едно правило, OpenBL 2, China 3 и с Кореа ще станат 4 правила но ще блокират някъде около 20000 мрежи в Интернет.
Инсталиране на ipset:
sudo apt-get install ipset |
Вторият проблем е как да извлеча 20000 мрежи да ги вкарам в ipset правила в комбинация с iptables и те да се обновяват периочно, например на 24 часа. Решението не може да бъде нищо друго освен прост скрипт на bash. В основата си кода трябва да извлече листата от Интернет в текстов файл, да я подреди в команди и да ги изпълни. Ето пример:
Създаване на ipset скрипта
Не всички дистрибуции имат модул на ipset в ядрото, в Ubuntu server 14.04/16.04 LTS той е в наличност но не е зареден. Ще го видите с командата lsmod едва когато изпълните за първи път ipset.
sudo nano firewall.sh |
#!/bin/bash # # Based ipset script block Spamhaus, OpenBL, China and Korea # # Require Ubuntu server 14.04/16.04 LTS and ipset # sudo apt-get install ipset # lsmod | grep ip_set # ip_set_hash_ip 32768 1 # ip_set_hash_net 32768 3 # ip_set 45056 3 ip_set_hash_net,ip_set_hash_ip,xt_set # nfnetlink 16384 1 ip_set # # Samuil Arsov <support@itservice-bg.net> # clear start() { echo "spamhaus" ipset create Spamhaus hash:net wget -qc www.spamhaus.org/drop/drop.lasso -O /tmp/drop.lasso for i in $(cat /tmp/drop.lasso | egrep -v '^;' | awk '{ print $1}'); do ipset -A Spamhaus $i done; unlink /tmp/drop.lasso iptables -A INPUT -m set --match-set Spamhaus src -j DROP echo "china" ipset create China hash:net wget -qc http://www.okean.com/chinacidr.txt -O /tmp/drop.china for i in $(cat /tmp/drop.china | egrep -v '^#' | awk '{ print $1}'); do ipset -A China $i done; unlink /tmp/drop.china iptables -A INPUT -m set --match-set China src -j DROP echo "korea" ipset create Korea hash:net wget -qc http://www.okean.com/koreacidr.txt -O /tmp/drop.korea for i in $(cat /tmp/drop.korea | egrep -v '^#' | awk '{ print $1}'); do ipset -A Korea $i done; unlink /tmp/drop.korea iptables -A INPUT -m set --match-set Korea src -j DROP echo "openbl" ipset create OpenBL hash:ip wget -qc http://www.openbl.org/lists/base.txt -O /tmp/drop.openbl for i in $(cat /tmp/drop.openbl | egrep -v '^#' | awk '{ print $1}'); do ipset -A OpenBL $i done; unlink /tmp/drop.openbl iptables -A INPUT -m set --match-set OpenBL src -j DROP } stop() { iptables -D INPUT -m set --match-set Spamhaus src -j DROP ipset destroy Spamhaus iptables -D INPUT -m set --match-set China src -j DROP ipset destroy China iptables -D INPUT -m set --match-set Korea src -j DROP ipset destroy Korea iptables -D INPUT -m set --match-set OpenBL src -j DROP ipset destroy OpenBL } status() { SPAMHAUS=$(ipset list Spamhaus | wc -l) CHINA=$(ipset list China | wc -l) KOREA=$(ipset list Korea | wc -l) OPENBL=$(ipset list OpenBL | wc -l) echo "-----------------------------------------------------------" iptables -nvL | grep match-set echo "-----------------------------------------------------------" echo " Spamhaus:$SPAMHAUS China:$CHINA Korea:$KOREA OpenBL:$OPENBL" echo "" } case "$1" in start) start ;; stop) stop ;; restart) stop start ;; status) status ;; *) echo $"Usage: $0 {start|stop|restart|status}" exit 1 esac exit 0 |
Правим, скрипта изпълним:
sudo chmod 755 firewall.sh |
И го изпълняваме със start
sudo ./firewall.sh start |
Като след това със status трябва получим подобен резултат:
sudo ./firewall.sh status |
От който виждаме, че DROP веригите се пълнят с пакети идващи от “лошите” мрежи а на последния ред колко хиляди правила на ipset има във всяка от четирите вериги Spamhaus, China, Korea и OpenBL на iptables.
Всяка следващо изполване на скрипта с опцията restart ше обновява нашата blacklist актуална като не влияе по никакъв начин на правилата във Fail2ban.
sudo ./firewall.sh restart |
Нека да направим така, че скрипта да се изпълнява всяка сутрин в 5 часа сутринта автоматично без човешка намеса. За целта трябва да редактираме /etc/crontab като добавим следния ред:
0 5 * * * root /home/samyil/firewall.sh |
И рестартираме cron демона за да влязат настройките в сила:
sudo service cron restart |
Изключително полезна статия. Благодаря на автора.
Здравейте бих искал да попитам как мога да блокирам (https://www.spamhaus.org/drop/asndrop.txt) след като списъка не е във вид на IP аддреси . За първи път ще пускам сървър . Използвам Дебиан 9 с Fail2ban (блокирах изходящия и входящия трафик и пропуснах IN–80,443 | OUT 53,80,443 Не позлвам SSH и Sendmail ! ), сега се опитвам да блокирам DDos UDP Атаките , но за жалост без успех . Преобърнах целия интернет . Моля за помощ .
Не можете, това са автономни системи – ASN (доставчици на Интернет). Те могат да се блокират само от BGP маршрутизатора на вашият Интернет доставчик. Друг е въпроса, че искате да блокирате спам а не цели мрежи на доставчици което са различни неща. Затова не намирам смисъл да правите това.
Но пък с малък скрипт можете от автономните системи да изваждате префиксите които те обявяват и да ги превръщате в правила за блокиране:
Ето и резултата 🙂
Здравейте при използването на горния скрипт съм задал echo 1 > /proc/sys/net/ipv4/ip_forward , но защо не мога да видя правилата като зададени с командата iptables -L FORWARD .
Разбрах скрипта , явно съм го чел между редовете . Сега идва другия момент , Има ли нещо повече което мога да направя за сървъра ??? След като ползвам скрипта на г-н Самуил Арсов и The_Admin заедно с Fail2ban , .htaccess-.htpasswd за phpmyadmin , mod_security , mod_qos . Нещо друго може ли да добавя за да повиша сигурноста ?