T1mbo 07.01.2011 00:36
How-to`s — Port Knocking на примере защиты ssh от брутфорса.
Доброй ночи! В данном посте я расскажу как просто защитить ssh сервер от брутфорса. Данный пост использует правило для iptables с использованием механизма port knocking.Технология port knocking позволяет выполнять любые действия на сервере, даже если все порты на нем закрыты. В общем случае, Вам достаточно соедениться с определенными портами, в определенной последовательности, которую знаете только Вы и на сервере выполнятся определенные действия, в последствии которых, нужный порт откроется.
Приступим к практике:
В данном примере я использую дистрибутив Debian и ip 192.168.11.1.
Создадим скрипт с правилом и дадим права на запуск:
t1mbo:~# touch /etc/portknock.sh && chmod 775 /etc/portknock.sh
Теперь задействуем наше правило в файле portknock.sh:
t1mbo:~# nano /etc/portknock.sh
Правило:
# Создаем цепочку правил sshprotect
iptables -N sshprotect
# Если адрес в списке, то подключение разрешено
iptables -A sshprotect -m state --state NEW -m recent --rcheck --name SSH -j ACCEPT
# Разрешить пакеты для уже установленных соединений
iptables -A sshprotect -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A sshprotect -j DROP
# Заносит адрес в список
iptables -A INPUT -m state --state NEW -m tcp -p tcp --dport 1500 -m recent --name SSH --set -j DROP
# Удаляет адрес из списка
iptables -A INPUT -m state --state NEW -m tcp -p tcp --dport 1499 -m recent --name SSH --remove -j DROP
# Применение для трафика ssh цепочку sshprotect
iptables -A INPUT -p tcp --dport 22 -j sshprotect
Запустим скрипт с правилом:
t1mbo:~# cd /etc/ && ./portknock.sh
Что бы добавить правило в автозагрузку, можно поместить скрипт, например в rc.local.
Теперь, чтобы получить доступ к серверу по ssh, нужно постучать на порт 1500, сделать это можно как и по telnet так и простым http запросом. Например:
Telnet:
telnet 192.168.11.1 1500
HTTP:
http://192.168.11.1:1500
Соответственно, чтобы закрыть порт, нужно постучать на порт 1499.
Вот таким способом можно избавиться от толпы желающих получить доступ к вашему серверу.
Возможно синтаксис немного запутанный, но при таком порядке все работает правильно.
Ключевой момент как-раз в
А дропы стоят для того, чтоб при сканировании не отдетектились.
--name SSH --set -j DROP
--name SSH --remove -j DROP
--name SSH --remove -j DROP
А дропы стоят для того, чтоб при сканировании не отдетектились.
А как сделать последовательность портов? В смысле, чтоб SSH открывался, если я постучу на определённые порты, в определённом порядке? А то в приведённом примере нужный порт можно открыть простым сканированием (перебором) портов... :(
ну так а кто мешает? сначала разблокировать не ssh, а например порт 1777, потом постучался на него - разблокировал 2555 и уж постучался на него - разблокировал ssh.
Можно узнать, как сделать подобное для http протокола? фишка будет полезная, а времени сейчас разгребаться нет. Может кто поможет?))
Я так понимаю это был ответ на верхний комментарий, а не на пост, и в этом контексте это правильно.
Этот способ мне нравится больше, спасибо.
В качестве благодарности зарегистрировался на сайте :).
Долго пытался настроить knockd, ничего не получалось, в логах пусто и не знаю куда копать. Наткнулся на эту статью и желание настраивать knockd пропало :). Причин этому несколько. Во-первых ограничивать доступ сразу фаерволом не так костыльно. Во-вторых ресурсов потеря будет меньше ведь не запущен лишний демон. В-третьих.. Зачем быться в закрытые ворота, когда рядом открытая дверь? :)
Испробовал несколько вариантов стучаться к портам и решил, что самый лучший - воспользоваться knock (хотя на Win возможно таких клиентов нет или дорогие):
knock -v ip 1500
Прелесть этой программы в том, что в отличии от telnet не нужно долго ждать её завершения.
В качестве благодарности зарегистрировался на сайте :).
Долго пытался настроить knockd, ничего не получалось, в логах пусто и не знаю куда копать. Наткнулся на эту статью и желание настраивать knockd пропало :). Причин этому несколько. Во-первых ограничивать доступ сразу фаерволом не так костыльно. Во-вторых ресурсов потеря будет меньше ведь не запущен лишний демон. В-третьих.. Зачем быться в закрытые ворота, когда рядом открытая дверь? :)
Испробовал несколько вариантов стучаться к портам и решил, что самый лучший - воспользоваться knock (хотя на Win возможно таких клиентов нет или дорогие):
knock -v ip 1500
Прелесть этой программы в том, что в отличии от telnet не нужно долго ждать её завершения.
--dport 1499 -m recent --name SSH --remove -j DROP
Соответственно, чтобы закрыть порт, нужно постучать на порт 1499.
А не наоборот?.. Может я чего путаю, но --set -j DROP как раз заблокирует доступ..