Предотвращение перебора паролей
From DD-WRT Wiki
English • Deutsch • Español • Français • Italiano • 日本語 • Polski • Português • Русский • Svenska • 中文(中国大陆) • 中文(台灣) • |
Contents |
[edit] Введение
Полный перебор (или метод "грубой силы" от англ. brute-force) - метод угадывания пароля путем перебора всех возможных вариантов. Атака перебором - самая медленная. Для предотвращения указанной атаки примените базовую защиту SSH или перейдите к расширенному разделу для более элегантного и гибкого способа реализации защиты.
Благодаря предложению пользователя JoFa, а также трудоемкой работе, тестированию и коду пользователя jbarbieri, теперь вы можете легко использовать SSH и другие порты, открытые со стороны сети WAN маршрутизатора, серьезно мешая попыткам попыткам взлома перебором паролей (атака "грубой силой"). Помните, всегда используйте уникальные и длинные пароли!
[edit] Предварительные требования
- Версия: теоретически любая версия DD-WRT, протестировано на v24sp1+.
- Сборки: VPN, VoIP, Standard, Mega, Mini. В основном все, кроме Micro и Micro+.
[edit] Первый метод: базовая защита
[edit] Реализация базовой защиты для SSH (устарело)
Это было включено во все сборки (кроме Micro), начиная с января 2011. См. страницу брандмауэра.
ОБНОВЛЕНИЕ. Начиная со сборки K26 с декабря 2010 г., было реализовано лучшее решение с использованием модуля 'recent'. Его можно развернуть двумя различными способами: либо с помощью сценария rc_firewall, либо через Optware с использованием сценария 'fixtables' пользователя Frater. Если запущен OTRW, обновлять не нужно, т.к. брандмауэр DD-WRT netfilter все время имел эту опцию, просто не скомпилирован как модуль.
Если сценарий "fixtables" не запущен, правильная процедура выглядит следующим образом, как указано в rc_firewall:
iptables -N bruteprotect iptables -A bruteprotect -m recent --set --name BRUTEFORCE --rsource iptables -A bruteprotect -m recent ! --update --seconds 60 --hitcount 4 --name BRUTEFORCE --rsource -j RETURN iptables -A bruteprotect -j LOG --log-prefix "[DROP BRUTEFORCE] : " --log-tcp-options --log-ip-options iptables -A bruteprotect -j DROP
iptables -I FORWARD 4 -i vlan2 -p tcp -m tcp --dport 22 -j bruteprotect iptables -I INPUT 3 -i vlan2 -p tcp -m tcp --dport 21:23 -j bruteprotect
ПРИМЕЧАНИЕ. Для защиты нескольких открытых портов необходимо использовать многопортовое сопоставление -m (если оно поддерживается ядром, это так по состоянию на 17.01.2011).
Пример для защиты порта 3389:
iptables -I INPUT 2 -i vlan2 -p tcp -m multiport --dports 21,22,23,3389 -j bruteprotect
Вот как это выглядит:
Цепочка INPUT:
-A INPUT -i vlan2 -p tcp -m tcp --dport 22 -j bruteprotect -A INPUT -d 192.168.10.1 -p tcp -m tcp --dport 22 -j logaccept
Цепочка FORWARD:
-A FORWARD -i vlan2 -p tcp -m tcp --dport 5900 -j bruteprotect -A FORWARD -i vlan2 -p tcp -m tcp --dport 3389 -j bruteprotect -A FORWARD -i vlan2 -p tcp -m tcp --dport 22 -j bruteprotect -A FORWARD -i vlan2 -p tcp -m tcp --dport 21 -j bruteprotect
Цепочка bruteprotect:
-A bruteprotect -m recent --set --name BRUTEFORCE --rsource -A bruteprotect -m recent ! --update --seconds 60 --hitcount 4 --name BRUTEFORCE --rsource -j RETURN -A bruteprotect -j LOG --log-prefix "[DROP BRUTEFORCE] : " --log-tcp-options --log-ip-options -A bruteprotect -j DROP
Более подробную информацию можно найти здесь: http://www.debian-administration.org/articles/187
Предупреждение! Это немного устаревший метод. Он будет работать, но попробуйте более элегантное решение в последнем разделе.
Обратите внимание, что этот пример защиты предназначен для предотвращения соединений через порт 22 (SSH). Он не распространяется ни на Telnet (лучше отключить его), ни на VPN (PPTP или OpenVPN). Он не будет работать на сборках Micro(+) (по состоянию на ревизию SVN 10431).
Перейдите на страницу Administration → Commands веб-интерфейса маршрутизатора. Вставьте следующий код в поле сценария Script и нажмите кнопку Save Firewall:
iptables -I INPUT 2 -p tcp --dport 22 -m state --state NEW -m limit --limit 3/min --limit-burst 3 -j ACCEPT iptables -I INPUT 3 -p tcp --dport 22 -j logreject
Этот код предназначен для ограничения попыток подключения к порту 22 (SSH) - только 3 в минуту. Вы можете отредактировать этот код для других портов, изменения количества попыток до истечения времени ожидания, изменения продолжительности времени ожидания и т.д.
[edit] Защита Telnet в дополнение к SSH
Приведенный выше код может быть расширен для защиты других портов. Например, если вы хотите защитить SSH и Telnet, вы можете использовать следующий код:
iptables -I INPUT 2 -p tcp --dport 22 -m state --state NEW -m limit --limit 3/min --limit-burst 3 -j ACCEPT iptables -I INPUT 3 -p tcp --dport 23 -m state --state NEW -m limit --limit 3/min --limit-burst 3 -j ACCEPT iptables -I INPUT 4 -p tcp --dport 22 -j logreject iptables -I INPUT 5 -p tcp --dport 23 -j logreject
Как видите, расширение скрипта не сложно. Всё, что нужно сделать, это убедиться, что сначала идут строки, содержащие RELATED, затем содержащие NEW, а затем logreject.
[edit] Применение концепции к перенаправленным портам
Скажем, у вас есть FTP-сервер, работающий на компьютере локальной сети. Вы можете перенаправить порт 21 на внутренний сервер, защитив его, используя вышеуказанную концепцию.
iptables -t nat -I PREROUTING -p tcp -d $(nvram get wan_ipaddr) --dport 21 -j DNAT --to 192.168.1.101:21 iptables -I FORWARD -p tcp -d 192.168.1.101 --dport 21 -m state --state RELATED,ESTABLISHED -j ACCEPT iptables -I FORWARD 2 -p tcp -d 192.168.1.101 --dport 21 -m state --state NEW -m limit --limit 3/min --limit-burst 3 -j ACCEPT iptables -I FORWARD 3 -p tcp -d 192.168.1.101 --dport 21 -j logreject
Примечание. В этом примере 192.168.1.101 - это IP-адрес компьютера локальной сети, на котором работает FTP-сервер.
[edit] Расширенный метод: защита любого открытого порта
[edit] Элегантный способ реализации защиты
Сначала нужно создать цепочку rate_limit и ввести в нее следующие правила:
iptables -N rate_limit iptables -F rate_limit iptables -A rate_limit -p tcp --dport 22 -m limit --limit 3/min --limit-burst 3 -j ACCEPT iptables -A rate_limit -p udp --dport 1194 -m limit --limit 3/min --limit-burst 3 -j ACCEPT iptables -A rate_limit -p ICMP --icmp-type echo-request -m limit --limit 3/sec -j ACCEPT iptables -A rate_limit -p <protocol> --dport <port> -m limit --limit <x/sec/min/hr> --limit-burst X -j ACCEPT iptables -A rate_limit -p ! ICMP -j LOG --log-prefix " Connection dropped!! " iptables -A rate_limit -p tcp -j REJECT --reject-with tcp-reset iptables -A rate_limit -p udp -j REJECT --reject-with icmp-port-unreachable iptables -A rate_limit -j DROP
Чтобы использовать эту цепочку, нужно просто добавить правила в цепочку INPUT, которая заставляет любое новое соединение переходить в цепочку rate_limit:
iptables -I INPUT -p ICMP --icmp-type echo-request -j rate_limit iptables -I INPUT -p tcp --dport 22 -m state --state NEW -j rate_limit iptables -I INPUT -p udp --dport 1194 -m state --state NEW -j rate_limit iptables -I INPUT -p <protocol> --dport <port> -m state --state NEW -j rate_limit
Это отправляет любое новое соединение для SSH или OpenVPN в цепочку rate_limit. Вы можете заменить параметры <...> фактическим протоколом, портом и принятой скоростью, чтобы они также проходили через rate_limit. Этот сценарий также ограничивает пинги ICMP до 3 в секунду... если чаще - блокирует их. Поскольку пакеты команды ping очень распространены, оператор LOG был изменен так, что если протокол является ICMP, он НЕ будет регистрироваться, чтобы это не привело к торможению и зависанию маршрутизатора.
[edit] Окончательная блокировка
Если вышеперечисленное не имеет желаемого эффекта, вы можете навсегда заблокировать IP-адреса с помощью следующего сценария, который сканирует файл /var/log/messages на наличие неудачных попыток входа в систему. Затем он берет последнюю запись и блокирует соответствующий IP-адрес. Просто поместите его в crontab и запускайте каждые несколько минут.
#!/bin/sh ############################################################ # # check_brute_force # Checks for failed logins and blocks IP addresses # ############################################################ IP=`awk -F'[ :]' '/login attempt/ {print $(NF-1)}' /var/log/messages | tail -1` rc=0 # Do nothing if there is an existing rule for this IP address if `iptables -L -n | grep $IP > /dev/null 2>&1`; then exit 0 fi case $IP in "") # Do nothing with empty IP ;; 192.168*) # Exclude local LAN ;; *) # Add rule against intruding IP iptables -I INPUT -s $IP -j DROP RC=$? ;; esac exit $RC # EOF
Вы можете проверить наличие насовсем заблокированных IP-адресов с помощью следующего сценария:
#!/bin/sh ############################################################ # # show_blocked_ip # # Shows explicitly blocked IP addresses # ############################################################ IP=`iptables -L -n | awk '$4~/[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}/ && $4!~/0\.0\.0\.0/ && $1~/DROP/ {print $4}'` if [ "$IP" == "" ]; then echo "No blocked IP addresses found." else echo "Blocked IP addresses:" for n in $IP; do echo $n done fi exit 0 # EOF