Предотвращение перебора паролей

From DD-WRT Wiki

Jump to: navigation, search

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