22 March 2010

Защищаем SSH от брутфорса на любом порту

System administration
Сегодня меня заинтересовал опрос надо ли перевешивать SSH на нестандартный порт. Сам опрос не так интересен как способ автора zivot_je_cudo защищать SSH от подбора пароля: после неверной попытки подключения блокировать новые попытки в течение 20 секунд. Задержка, видимо, выбрана эмпирически, исходя их двух противположных пожеланий: чтобы не заблокировать в случае опечатки себя надолго, и в тоже время усложнить жизнь подбиральщика. Я хочу поделиться своим способом противодействия брут-форсу, который применяю уже несколько лет. Он имеет два преимущества:
— дает мне больше попыток для набора правильного пароля
— но при этом блокирует брутфорсеров «навечно».

Как можно достичь этих двух противоположных целей?


Я использую модуль iptables под названием hashlimit, который умеет подсчитывать кол-во пакетов в определенный промежуток времени и через некоторое время сбрасывать счетчик.
Все делается тремя правилами:
iptables -A INPUT -p tcp -m tcp --dport 22 -m state --state NEW -m hashlimit --hashlimit 1/hour --hashlimit-burst 2 --hashlimit-mode srcip --hashlimit-name SSH --hashlimit-htable-expire 60000 -j ACCEPT

iptables -A INPUT -p tcp -m tcp --dport 22 --tcp-flags SYN,RST,ACK SYN -j DROP

iptables -A RH-Firewall-1-INPUT -p tcp -m state --state NEW -m tcp --dport 22 -j ACCEPT


Что делает второе и третье правило понятно. Все самое интересное в первом: оно разрешает 2 попытки подключения в течение часа. Как только вы превышаете 2 попытки за указанное время, правило с -j ACCEPT перестает работать, пользователь вместо этого попадает в следующее правило с -j DROP (точно также можно поставить TARPIT). После этого вы не сможете подключиться, и начинается обратный отсчет 60 000 миллисекунд, после которых информация о вашей попытке «протухает» (параметр --hashlimit-htable-expire). То есть реально вам придеся ждать не 1 час, а всего 1 минуту. Вся военная хитрость состоит в том, что если вы не дождетесь этого времени и попробуете еще раз подключиться, то пакет будет убит, а счетчик снова сброшен в начальное состояние — 1 минуту! Таким образом, если вы нетерпеливый брутфорсер и будете тупо долбать порт после блокировки, то вы с каждой попыткой будете продлевать свой бан! То есть забаните себя навечно!
Добропорядочный же пользователь наборот имеет несколько попыток подключения без ожидания между ними прежде чем попадет в «баню».
Модуль hashlimit сохраняет свое состояние в /proc — поначалу там пусто:
# cat /proc/net/ipt_hashlimit/SSH

после первой попытки подключения туда попадает инфа:
# cat /proc/net/ipt_hashlimit/SSH
55 ХХ.ХХ.ХХ.ХХ:0->0.0.0.0:0 11533000 230400000 115000000

первое число — кол-во оставшихся секунд, можно смотреть как оно равномерно тикает:
# cat /proc/net/ipt_hashlimit/SSH
20 ХХ.ХХ.ХХ.ХХ:0->0.0.0.0:0 117429000 230400000 115000000

После того как я это сделал, мне очень захотелось проверить. И надо же! На ловца зверь бежит! Меня тут же начал брутфорсить какой-то китаец. Первые 4 попытки прошли, а дальше он в течение часа (!) тупо долбился в закрытую дверь. За весь этот час ему удалось проверить всего 4 пароля! Дальше, видимо, надоело.

Таким образом решены две проблемы:
— если пользователь вдруг опечатался, ему не нужно долго ждать новых попыток
— брутфорсеры сами себя загоняют в «вечный» бан.

Что делать, если вы вдруг с нескольких попыток не смогли ввести пароль? Не суетиться — подождать спокойно минуту и попробовать еще несколько раз.
А если уж снова не смогли — то лучше пойти проспаться, в таком состоянии в консоль лучше не лазить :))

Успехов.

P.S. И да, чуть не забыл — у меня SSH на нестандартном порту :)

UPD: Немного про настройку hashlimit.
UPD2: Как достичь того же самого с помощью более распространенного модуля recent: раз, два.
UPD3: Само собой способ годится не только для защиты от подбора пароля по SSH, но может быть использован и для различных других сервисов, где слишком частое подключение сигнализирует о чем-то неладном.
UPD4: Ограничение подключений с помощью самого SSHD.
Tags:sshбезопасностьбрутфорсhashlimitip
Hubs: System administration
+98
98.4k 355
Comments 138