Knockin' On Heaven's Door ...
(https://iforum.pp.ua/images/knock.jpg)
Knocking - динамическое oткрытие порта ssh на заданное время в iptables
Речь пойдет о борьбе с надоедливыми брутфорсами и сканерами портов, которые всячески норовят получить доступ к серверу.
В статье будет рассказано о технологии Port Knocking, позволяющей обезопасить доступ на сервер посредством скрытия портов.
Немного о самой технологии
В технологии Port Knocking есть интересная особенность. Она применяет несколько попыток подключения к закрытым портам. Вы спросите: «А зачем это нужно?» Давайте представим себе, что вы пришли на собеседование в какую-то организацию с пропускным режимом. Сначала вы попадаете на (1)пост охраны, где на вас выписывают пропуск, затем (2)вы попадаете в отдел кадров, где заполняете анкету и с вами беседуют, и в конечном итоге (3)вы попадаете в кабинет управляющего, который проводит завершающую беседу и принимает решение. А теперь давайте представим, что бы случилось, если бы все желающие напрямую шли к управляющему?
Технология Port Knocking осуществляет последовательность попыток подключения к закрытым портам. Даже не смотря на то, что все порты закрыты, вы можете отследить все попытки подключения в лог-файлах файрвола. Сервер, чаще всего, никак не отвечает на эти подключения, но он считывает и обрабатывает их. Но если же серия подключений была заранее обозначена пользователем, то выполнится определенное действие. Как пример, подключение к SSH-сервису на порту 22. Port Knocking позволяет осуществлять не только данное действие. триггер позволяет выполнять и другие действия (скажем, отключение питания, перезагрузку системы и т.д.).
Динамическое открытие порта ssh на заданное время при помощи iptables :
Небольшое правило для iptables помогающее лишний раз не держать порты открытыми.
Пример для доступа к SSH, хотя как сами понимаете можно использовать как угодно.
## Open SSH Port 22 by Knocking ports 6531-->7482-->8273-->9634
## создаем дополнительные цепочки
-N STAGE1
-N STAGE2
-N STAGE3
# Разрешить подключение, если ip есть в списке и последнее подключение осуществлялось не позднее часа (3600 секунд)
#-A INPUT -p tcp --syn -m conntrack --ctstate NEW --dport 22 -m recent --update --seconds 3600 --name ACCES -j ACCEPT
# Разрешить новое подключение, если ip есть в списке и только в течение 10 секунд и не секундой больше! :-)
-A INPUT -p tcp --syn -m conntrack --ctstate NEW --dport 22 -m recent --rcheck --seconds 10 --name ACCES -j ACCEPT
## Открытие SSH
-A INPUT -p tcp --syn -m conntrack --ctstate NEW -m recent --name ACCES --remove -j DROP
-A INPUT -p tcp --syn -m conntrack --ctstate NEW --dport 9634 -m recent --rcheck --name 3HIT -j STAGE3
-A INPUT -p tcp --syn -m conntrack --ctstate NEW -m recent --name 3HIT --remove -j DROP
-A INPUT -p tcp --syn -m conntrack --ctstate NEW --dport 8273 -m recent --rcheck --name 2HIT -j STAGE2
-A INPUT -p tcp --syn -m conntrack --ctstate NEW -m recent --name 2HIT --remove -j DROP
-A INPUT -p tcp --syn -m conntrack --ctstate NEW --dport 7482 -m recent --rcheck --name 1HIT -j STAGE1
-A INPUT -p tcp --syn -m conntrack --ctstate NEW -m recent --name 1HIT --remove -j DROP
-A INPUT -p tcp --syn -m conntrack --ctstate NEW --dport 6531 -m recent --name 1HIT --set -j DROP
-A STAGE1 -m recent --name 2HIT --set -j DROP
-A STAGE2 -m recent --name 3HIT --set -j DROP
-A STAGE3 -m recent --name ACCES --set -j DROP
Так же можно сделать и с любым портом любого сервиса, например, PPTP VPN ...
Извините, вам запрещён просмотр содержимого спойлеров.
Извините, вам запрещён просмотр содержимого спойлеров.
Извините, вам запрещён просмотр содержимого спойлеров.
Для микротиков в их RouterOS все просто. Делаем в Firewall записи цепочки:
add chain=input connection-state=new protocol=tcp dst-port=9634 in-interface-list=WAN action=add-src-to-address-list address-list=Knock_stage1 address-list-timeout=3s comment="Knock for SSH ACCESS"
add chain=input connection-state=new protocol=tcp dst-port=8273 in-interface-list=WAN action=add-src-to-address-list address-list=Knock_stage2 address-list-timeout=3s src-address-list=Knock_stage1
add chain=input connection-state=new protocol=tcp dst-port=7482 in-interface-list=WAN action=add-src-to-address-list address-list=Knock_stage3 address-list-timeout=3s src-address-list=Knock_stage2
add chain=input connection-state=new protocol=tcp dst-port=6531 in-interface-list=WAN action=add-src-to-address-list address-list=Knock_SSH address-list-timeout=1d src-address-list=Knock_stage3 log=yes log-prefix="By knocking added SSH"
и дальше делаем проброс порта SSH из списка Knock_SSH и за ним ниже сразу запрещаем его:
add chain=forward connection-state=new dst-port=22 protocol=tcp src-address-list=Knock_SSH action=accept comment="Accept Knocked to SSH"
add chain=forward connection-state=new dst-port=22 in-interface-list=WAN protocol=tcp action=drop
Суть правила проста, для того чтобы открыть доступ к ssh нужно сначала постучать на избранные порты
в определенной последовательности 6531-->7482-->8273-->9634
например, специальной программой knock (клиентской ее версией)
knock -v archlinux.sytes.net -d 500 6531 7482 8273 9634
где -d 500 это интервалы между стуками, чтобы заходило не через раз ;)
Для автоматизации в ssh можно настроить файл config в скрытой папе ./ssh
Host archlinux
HostName archlinux.sytes.net
Port 22
User admin
Match host archlinux.sytes.net exec "knock -v archlinux.sytes.net -d 500 6531 7482 8273 9634"
Ну и напоследок, что бы закрыть вопрос, сделаем вход на ssh только по ключу
и поменять настройку на вашем сервере: PasswordAuthentication no
правильно генерируем ключ:
ssh-keygen -o -a 100 -t rsa -b 4096 -C " admin@archlinux.sytes.net "
Менять пароль доспупа к приватному ключу так:
ssh-keygen -f ~/.ssh/id_rsa -p -o -a 100
Добавить на сайт, куда хотите ходить:
ssh-copy-id -i ~/.ssh/id_rsa.pub admin@archlinux.sytes.net -p 2200
Новый тип шифрования ed25519:
ssh-keygen -a 100 -t ed25519 -b 4096 -C " admin@archlinux.sytes.net "
Добавить пароль ключа в память навсегда:
ssh-add ~/.ssh/id_ed25519
ssh-add ~/.ssh/id_rsa
Так же есть способ автоматизации в файле config в ./ssh
Host archlinux archlinux.sytes.net
HostName archlinux.sytes.net
User admin
Port 2200
AddKeysToAgent yes
UseKeychain yes
IdentityFile ~/.ssh/id_rsa
# или другой тип
#IdentityFile ~/.ssh/id_ed2551
Match host archlinux.sytes.net exec "knock -v archlinux.sytes.net -d 500 6531 7482 8273 9634"
Для людей с правильной осью вспоминаем, что есть серверная knockd (https://www.freshports.org/security/knock)
При помощи ее мы так же делаем вход по стуку на FreeBSD, как описано в этой статье (https://habr.com/ru/post/179219/) :)
Еще один способ - это стук не по портам, а контентом на уже используемый другим сервисом, тем самым скрывая сервис вообще.
И тут всё зависит от вашей фантазии. Но, на мой взгляд, идеальным вариантом было бы стучаться на всё тот же 443 порт. Это сведёт к минимуму «подозрительность» данной активности.
RouterOS позволяет это сделать чрезвычайно простым путём (как всегда ;)). Забегаем в ip > firewall > Mangle и создаём правило:
/ip firewall mangle add chain=prerouting protocol=tcp dst-port=443 content="40324-gw.ourserver" action=add-src-to-address-list address-list="SSTP_Client" address-list-timeout="00:01:00"
Идея тут заключается в том, что так или иначе, из https запроса вполне легко вытаскивается sni заголовок. А вот то самое «кодовое слово» будет передаваться в качестве доменного имени (например 40324-gw.ourserver.net.ua). Как только наш тик получит GET запрос на это доменное имя, он создаст запись в src листе фаерволла. Её мы будем использовать в правиле netmap:
/ip firewall nat add chain=dstnat action=netmap dst-port=443 dst-address-list=WAN protocol=tcp src-address-list=!SSTP_Client to-addresses=192.168.1.80
Таким образом, мы натим все соединения на 443 порт на вебсервер 192.168.1.80, кроме тех, которые пришли от адресов из списка SSTP_Client. Для последних это правило не работает и пойдут прямиком на sstp сервер микротика.
Теперь на стороне клиента нужно добавить задачу в расписание, которая будет периодически стучаться, обновляя свой динамический адрес в src листе сервера. Кстати, записи туда добавляются с таймаутом в 1 минуту.
Самый простой вариант, это зайти в system > Sheduler и добавить задачу с интервалом в 1 минуту и командной строкой:
/tool fetch url=https://40324-gw.ourserver.net.ua/ mode=https keep-result=no
Важно знать, что указанное доменное имя должно либо быть реально существующим, либо хотя-бы локально прописанным в DNS клиента.
если вы не хотите отправлять лишние запросы, скрипт шедалера можно сделать таким: Knocking_T0_SSTP_VPN
{
:if ([/interface get sstp-vpn running]=true) do={
# Uncomment if u wanna read msg in log
#:log info "SSTP interface running... don't need knocking!"
} else={[/tool fetch url=https://40324-gw.ourserver.net.ua/ mode=https keep-result=no]}
}
Извините, вам запрещён просмотр содержимого спойлеров.
Нашел, что еще в далеком 2013 разработали дополнения XTABLES-ADDONS и там есть уже готовый модуль knocking :)
(дальше будет выдержка из статьи Хакер от 07 2013 года)
XTABLES-ADDONS
Наиболее известный набор дополнений к iptables, пожалуй, xtables-addons. Этот набор является своего рода «наследником» patch-o-matic — главное отличие от последнего заключается в том, что для установки xtables-addons не требуется патчить ядро и iptables. Перечислю наиболее интересные модули и возможности, которые он добавляет (описывается Ubuntu 12.04, поскольку в 12.10 на ядрах 3.5.* из-за добавления новых флагов в функцию ipv6_find_hdr() один из модулей не компилируется):
• xt_geoip — позволяет определять страну данного IP-адреса. Разумеется, это не панацея от различных ботнетов и базу адресов время от времени надо обновлять, но модуль тем не менее полезен;
• xt_ipp2p — позволяет производить действия над некоторым P2P-трафиком;
• xt_pknock — позволяет использовать port knocking. Этот механизм позволяет держать порты закрытыми и открывать их только после определенной последовательности подключений на (также закрытые) порты;
• xt_lscan — отслеживает попытки сканирования.
XT_PKNOCK
Модуль xt_pknock используется для port knocking’а. Что это такое? Допустим, у тебя на интерфейсе, который смотрит в интернет, есть только порт SSH. Но твоей паранойе и этого недостаточно. С другой стороны, тебе этим компьютером надо управлять, так что просто отключить SSH — не вариант. На помощь приходит port knocking. Ты закрываешь порт, но есть возможность его открыть с помощью последовательных соединений на определенные порты или используя SPA (Single Packet Authentication — метод криптографической аутентификации, в случае с xt_pknock берется HMAC от текущего времени и адреса аутентифицируемого). Xt_pknock поддерживает оба режима, однако второй мы рассматривать не будем — его при- менение довольно специфично.
Приведу пример для открытия порта SSH:
iptables -A INPUT -p tcp -m pknock --knockports 4002,31337,2195,34344 --strict --name SSH --time 30 --autoclose 5 --dport 22 -j ACCEPT
Разберем, что эти опции значат. Опция '--knockports' перечис- ляет порты, на которые необходимо «стучаться»; '--strict' означает, что на порты необходимо «стучаться» строго в определенной последовательности; '--name' присваивает имя данному правилу, через которое в /proc/net/xt_pknock/ можно получить информацию о попытках knocking’а; '--time 30' ограничивает максимальное время между «постукиваниями» в данной последовательности (в секундах); '--autoclose 5' закрывает порт через пять минут.
Но как же именно «стучаться»? Для этого имеется, например, утилита hping3, входящая (в случае Ubuntu) в одноименный пакет.
Для того чтобы открыть порт из указанного выше примера, выполни данные команды на клиенте:
$ sudo hping3 -c 1 -S 192.168.1.5 -p 4002
$ sudo hping3 -c 1 -S 192.168.1.5 -p 31337
$ sudo hping3 -c 1 -S 192.168.1.5 -p 2195
$ sudo hping3 -c 1 -S 192.168.1.5 -p 34344
Эти команды посылают один пакет с битом SYN на адрес 192.168.1.5 (в твоем случае, понятно, он будет другим) на порты 4002, 31337, 2195,34344. Все! Теперь в течение пяти минут SSH открыт.