Скажи “Нет!” взломщику
Защищаем компьютер от проникновения путём подбора пароля
Устав от того, что ко мне на компьютер ломятся всякие придурки юные кулхацкеры, я решил принять меры.
Товарищи кулхацкеры лезут в систему с трёх сторон:
- Путем подбора пароля на SSH.
- Путем подбора пароля на FTP.
- Пытаясь использовать компьютер в качестве релея (это уже спамеры).
Есть и другие поползновения (например, попытки достучаться до MySQL, к которому снаружи добраться в принципе невозможно; или пытаясь навести "злобные пинги"), но три вышеописанных метода меня раздражают больше всего.
Стратегия защиты:
- SSH: после трех неудачных паролей в течение минуты — в бан.
- FTP: после трех неудачных паролей в течение минуты — в бан.
- Mail: после первой же попытки использовать компьютер в качестве релея — в бан (и в блэклист, в идеале).
Итак, приступим. Сразу оговорюсь, что все действия нужно выполнять из-под root'а
Прежде всего нам понадобится замечательный пакет swatch:
Теперь некоторые предположения о системе:
sshdзаписывает неудачные попытки входа в систему в файл/var/log/auth.logvsftpdзаписывает неудачные попытки входа в систему в файл/var/log/vsftpd.logcourierзаписывает неудачные попытки релея в файл/var/log/mail.errpostfixзаписывает неудачные попытки релея в файл/var/log/mail.log
У меня до вчерашнего вечера стоял courier, потом я поставил postfix, поэтому привожу варианты и для одного агента, и для другого.
Блокировку нехороших товарищей будем осуществлять при помощи iptables.
Начнём с предварительной настройки iptables:
touch /etc/hosts.badftp
touch /etc/hosts.badrelay
iptables -N swatch_ssh_rejects
for ip in `cat /etc/hosts.badssh`; do
iptables -I INPUT -p tcp --dport 22 -s $ip -j DROP
done
iptables -N swatch_ftp_rejects
for ip in `cat /etc/hosts.badftp`; do
iptables -I INPUT -p tcp --dport 21:22 -s $ip -j REJECT --reject-with tcp-reset
done
iptables -N swatch_relay_rejects
for ip in `cat /etc/hosts.badrelay`; do
iptables -I INPUT -p tcp --dport 25 -s $ip -j REJECT --reject-with tcp-reset
done
iptables -I INPUT -j swatch_ssh_rejects
iptables -I INPUT -j swatch_ftp_rejects
iptables -I INPUT -j swatch_relay_rejects
Данные о нарушителях будут помещаться в один из следующих файлов: /etc/hosts.badssh, /etc/hosts.badftp, /etc/hosts.badrelay. Можно было запросто обойтись только одним файлом, но я веду свою статистику. В принципе, банить можно жестче:
Но я добрый
Пока.
Теперь создаём конфигурационные файлы для swatch.
/etc/swatch_ssh.conf:
watchfor /: Invalid user / threshold track_by=$1,type=both,count=3,seconds=60 mail addresses=security\@example.org,subject="SSH:\ Invalid\ User\ Access-Banned" exec "/sbin/iptables -A swatch_ssh_rejects -p tcp --dport 22 -s $10 -j DROP" exec "echo $10 >> /etc/hosts.badssh" continue
/etc/swatch_vsftpd.conf:
watchfor / FAIL LOGIN: Client / threshold track_by=$1,type=both,count=3,seconds=60 mail addresses=security\@example.org,subject="FTP:\ Invalid\ User\ Access-Banned" exec "/usr/local/sbin/ban_ftp.sh '$_'" continue
/etc/swatch_smtp.conf для Courier:
watchfor /: error,relay=/ mail addresses=security\@example.org,subject="Mail:\ Relaying\ Attempt-Banned" exec "/usr/local/sbin/ban_relay_courier.sh $6" continue
/etc/swatch_smtp.conf для Postfix:
watchfor /: Relay access denied;/ mail addresses=security\@example.org,subject="Mail:\ Relaying\ Attempt-Banned" exec "/usr/local/sbin/ban_relay_postfix.sh $10" continue
Теперь дополнительные файлы (у меня не получилось интегрировать их непосредственно в конфиги swatch).
/usr/local/sbin/ban_ftp.sh:
IP=`echo $1 | grep -E -o 'FAIL LOGIN: Client "[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+"' | awk '{ print $4 }' | sed 's/"//g'`
/sbin/iptables -A swatch_ftp_rejects -p tcp --dport 21:22 -s $IP -j REJECT --reject-with tcp-reset
echo $IP >> /etc/hosts.badftp
/usr/local/sbin/ban_relay_courier.sh:
IP=`echo $1 | sed s/error,relay=::ffff:// | sed "s/,.*//"`
/sbin/iptables -A swatch_relay_rejects -p tcp --dport 25 -s $IP -j REJECT --reject-with tcp-reset
echo $IP >> /etc/hosts.badrelay
/usr/local/sbin/ban_relay_postfix.sh:
IP=`echo $1 | grep -o -E '\[[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+\]:' | grep -o -E '[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+'`
/sbin/iptables -A swatch_relay_rejects -p tcp --dport 25 -s $IP -j REJECT --reject-with tcp-reset
echo $IP >> /etc/hosts.badrelay
Теперь файл для запуска swatch (/etc/init.d/swatchrc):
kill -9 `cat /var/run/swatch_ssh.pid`
kill -9 `cat /var/run/swatch_smtp.pid`
kill -9 `cat /var/run/swatch_vsftpd.pid`
rm -f /var/run/swatch*.pid
swatch --tail-file=/var/log/auth.log --config-file=/etc/swatch_ssh.conf --awk-field-syntax --pid-file=/var/run/swatch_ssh.pid --tail-args='--follow=name -n 0' --daemon
# Для Courier
swatch --tail-file=/var/log/mail.err --config-file=/etc/swatch_smtp.conf --awk-field-syntax --pid-file=/var/run/swatch_smtp.pid --tail-args='--follow=name -n 0' --daemon
# Для Postfix
swatch --tail-file=/var/log/mail.log --config-file=/etc/swatch_smtp.conf --awk-field-syntax --pid-file=/var/run/swatch_smtp.pid --tail-args='--follow=name -n 0' --daemon
swatch --tail-file=/var/log/vsftpd.log --config-file=/etc/swatch_vsftpd.conf --awk-field-syntax --pid-file=/var/run/swatch_vsftpd.pid --tail-args='--follow=name -n 0' --daemon
Делаем файлы исполняемыми:
chmod a+x /usr/local/sbin/ban_ftp.sh
chmod a+x /usr/local/sbin/ban_relay*.sh
И запускаем swatch:
Ждём гостей


Бонус: парочка скриптов для анализа логов.
if [ x$1 = x ]; then
FILE=/var/log/auth.log
else
FILE=$1
fi
cat $FILE | grep " sshd\[" > /tmp/sshd.log
# Левые пользователи
cat /tmp/sshd.log | grep "Invalid user " | awk '{ print $10 }' | sort | uniq > /tmp/sshd_user
# Неверные пароли для существующих пользователей
cat /tmp/sshd.log | grep -E "Failed password for [a-zA-Z0-9_-]+ from " | awk '{ print $11 }' | sort | uniq > /tmp/sshd_pass
# Кто нас проверял на наличие SSH
cat /tmp/sshd.log | grep "Did not receive" | awk '{ print $12 }' | sort | uniq > /tmp/sshd_noident
[ -s /tmp/sshd_user ] && echo "Intruders" && cat /tmp/sshd_user
[ -s /tmp/sshd_pass ] && echo "Wrong password" && cat /tmp/sshd_pass
[ -s /tmp/sshd_noident ] && echo "No identification string" && cat /tmp/sshd_noident
rm -f /tmp/sshd.log /tmp/sshd_user /tmp/sshd_pass /tmp/sshd_name /tmp/sshd_noident
exit 0
vsftpd):if [ x$1 = x ]; then
FILE=/var/log/vsftpd.log
else
FILE=$1
fi
# cat $FILE | grep "FAIL LOGIN: Client" | awk '{ print $12 }' | sed s/\"//g | sort | uniq
cat $FILE | grep -E -o 'FAIL LOGIN: Client "[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+"' | awk '{ print $4 }' | sed 's/"//g' | sort | uniq
exit 0
Courier):if [ x$1 = x ]; then
FILE=/var/log/mail.err
else
FILE=$1
fi
cat $FILE | grep relay | awk '{ print $6 }' | sed s/error,relay=::ffff:// | sed s/,.*// | sort | uniq
exit 0
Postfix):if [ x$1 = x ]; then
FILE=/var/log/mail.log
else
FILE=$1
fi
cat $FILE | grep -o -E '\[[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+\]:' | grep -o -E '[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+' | sort | uniq
exit 0
Надеюсь, кому-нибудь пригодится.
scripts.tar.bz2
[...] Пример подобного скрипта я уже приводил в статье “Скажи “Нет!” взломщику”. Вся почта хранилась на рабочих станциях сотрудников, [...]
как вариант против кул-хацкеров из рецептов от одного знакомого админа: запускаем sshd на каком-то другом порту 1234, а за коннект в 22му сразу в blacklist. очень помагает
Это да, главное самому номер порта помнить
А вообще — аутентификация по ключу, а за попытку логина по паролю в бан.