- Port Knocking — просто, безопасно и с централизованным обновлением.
- Утилита Port Knocking для всех платформ, шифрованием алгоритма, и возможность централизованного обновления конфигурации, без передачи конфига
- Для чего
- Как пользоваться
- Примеры
- Создание Knocking
- Доменное имя
- Централизованное хранение
- DNS запросы
- Шифрование данных
- Debug
- Мелочи
- Тестирование
- Планы на будущее
- Защита сервера при помощи Port Knocking
- Настройка Сервера
- Настройка Клиента
- Port Knocking в PuTTY
- Практические Моменты
- Продвинутый Port Knocking
- Итоги
Port Knocking — просто, безопасно и с централизованным обновлением.
Утилита Port Knocking для всех платформ, шифрованием алгоритма, и возможность централизованного обновления конфигурации, без передачи конфига
Данный проект появился, как рудимент, а точнее как часть большого проекта по оптимизации процедуры обновления адрес листов по требованию заказчика, мы его немного подпилили и добавили нормальный вывод, а не сырые данные.
Для чего
Port Knocking — необходим тогда, когда вам необходимо получить доступ к ресурсу, который не хотеться открывать всем подряд, а определить IP адреса нет возможности, так как они динамические.
Как пользоваться
Я хотел написать инструкцию, для каждого аргумента, но решил сделать чуть по другому и показать на примере, как можно использовать данную программку.
У программы есть несколько аргументов, запустите —help чтобы посмотреть короткие и длинные обозначения.
Примеры
Создание Knocking
Программе необходимо передать специально сформированную строку с определённым синтаксисом, что бы программа могла правильно выполнить процедуру Knocking
Пока программа умеет использовать только два протокола, это TCP и UDP, настоятельно рекомендую не использовать порты 53, так как некоторые ОПСОС-ы заворачивают трафик DNS на свои сервера.
Итак, поставим задачу: необходимо организовать Knocking на хост 5.19.245.3 по портам TCP 40000,111,443,77 и по протоколу UDP 777 и 9000
При формировании строки первым символом вы должны указать ОБЯЗАТЕЛЬНО заглавную букву H обозначающую, что далее через разделитель двоеточие : будет идти адрес на который необходимо сделать процедуру Knocking.
H:5.19.245.3 — далее вы указываете порты и протоколы заглавными буквами, где T — tcp, а U — udp
H:5.19.245.3,T:40000,T:111,T:443,T:77,U:777,U:9000 — параметры разделены запятыми, обратите внимание, что программа читает строку слева направо, и в таком же направлении производит Knocking.
Запустите программу с аргументом —command=»H:5.19.245.3,T:40000,T:111,T:443,T:77,U:777,U:9000″
И Knocking сразу начнётся.
Доменное имя
Вы можете указать вместо IP адреса доменное имя H:mikrotik.me,T:40000,T:111,T:443,T:77,U:777,U:9000
Если для данного IP адреса есть несколько записей типа A, то для каждого IP адреса будет произведена процедура Knocking.
Тем самым вы можете создать любой поддомен, например validhostme.mikrotik.me и указать все ваши хосты, как записи A для данного домена.
Централизованное хранение
Вы можете взять любой субдомен как пример testknk.mikrotik.me и создать TXT записи, где значение записей будет ваша строка Knocking, например, H:mikrotik.me,T:40000,T:111,T:443,T:77,U:777,U:9000 , записей может быть несколько и по каждой записи будет запущена процедура Knocking, технически мы не ограничивали, но и не проверяли на большом количестве записей.
В случае, если вы будете использовать DNS запросы, вам необходимо добавить параметр action со значением dns
Запуск будет выглядеть так —action=dns —command=»testknk.mikrotik.me»
DNS запросы
Обратите внимание, программа использует реализацию DOH (DNS over HTTPS), поэтому ей необходим выход в интернет. Причём используется несколько серверов и выберется самый быстрый из них относительно хоста. на котором запущена программа.
Шифрование данных
Да, конечно хранить в DNS в открытом виде строки Knocking не самая лучшая идея, хотя она имеет право на жизнь, но рано или поздно её обнаружат и сам процесс Knocking-a будет скомпрометирован.
Вы можете зашифровать вашу строку конфигурации, например, такой командой
-a=»encrypt» -p=»dondslk((» -c=»H:mikrotik.me,T:40000,T:111,T:443,T:77,U:777,U:9000″
Результатом выполнения будет вернувшаяся кодированная строка base64, а внутри неё byte код, результат шифрования строки конфигурации, с типом шифрования aes-cgm 128.
Чтобы убедиться, что всё работает вы можете и должны проверять обратное преобразование, выполните команду
-a=»decrypt» -p=»dondslk((» -c=»3OKtTRqg0h4Dl7xmLYfu/QCCWSx4ut9mMLCW4rcEZWRhncqly89bJFTe+CjuuOZnvs66OYyHmQady8nRyEdBmlByg1ceUe1o1IqKGNl3+g==»
Результатом выполнения данной команды должна быть строка, которую вы закодировали.
Теперь вы можете поместить данный результат в TXT запись домена, и в этом случае указать в аргументе пароль, которым был зашифрован конфиг.
Обратите внимание, пока можно использовать ТОЛЬКО один пароль для всех записей. Возможно в будущем мы это поправим.
Также вы можете указать данную зашифрованную строку непосредственно в аргумент Command, но тогда action должен быть либо со значением Knocking, либо не указан.
Обязательно укажите пароль
Если ваш хост, с которого вы запускаете Knocking, находится в таких условия, что ваш внешний IP адрес может поменяться, вы можете указать аргумент —loop= и указать число, с каким тайм-аутом повторять Knocking, значение указывается в минутах. Например —loop=1 будет повторять Knocking каждую минуту.
Также вы можете использовать данную процедуру для тех кейсов, когда у вас адрес листы с маленьким тайм-аутом.
Debug
Это пока мало похоже на debug, но всё же вы можете добавить аргумент —verbose и получить дополнительный вывод.
Мелочи
Программа не пытаеться установить соединение.
Если вы используете MikroTik, настоятельно рекомендую использовать при настройке Knocking таблицу raw.
Тестирование
Попробуйте, запустите программу со следующими параметрами и исследуйте вывод
-v -a=»dns» -p=»dondslk((» -c=»knocktest.mikrotik.me»
Планы на будущее
- Дать возможность пользователю принудительно отказаться от DoH
- Реализовать возможность также через DNS отправки сообщения пользователям, например если не смогли расшифровать ключей и есть определённая запись, вывести сообщение, что пароль изменён.
- Динамический ключ, ключ будет рассчитываться из даты или других параметров.
- Совсем не быстро, но реализовать напрямую расчёт общего ключа по алгоритму DH, но для это понадобиться веб сервис.
- Получение конфигурации по http.
- Мы используем данный софт и для своих целей, и как показала практика при большом количестве записей Knocking, уходит приличное время, например при 200 ростах, может потребоваться около 5 минут на прохождения всех списков, так как мы в самом начале заложили к код модульность выполнения Knocking, сейчас мы не можем реализовать распараллеливание Knocking, но для нас это приоритетная задача.
Программа пишется сразу с учётом множества операционных систем единым кодом, для Windows, Linux и MacOS а также других ОS.
Защита сервера при помощи Port Knocking
Port knocking — это сетевой защитный механизм, действие которого основано на следующем принципе: сетевой порт является по-умолчанию закрытым, но до тех пор, пока на него не поступит заранее определённая последовательность пакетов данных, которая «заставит» порт открыться. Например, вы можете сделать «невидимым» для внешнего мира порт SSH, и открытым только для тех, кто знает нужную последовательность.
Настройка Сервера
Наиболее популярным ПО для организации port knocking является knockd. Работая в режиме демона совместно с iptables, knockd прослушивает сетевой интерфейс, ожидая корректной последовательности запросов на подключение. Как только knockd отлавливает корректную последовательность, он выполняет команду, определённую в конфигурационном файле knockd для данной последовательности — как правило, это вызов iptables, разрешающий соединение на определённый сетевой порт.
Например, у вас запущен демон SSH, ожидающий входящих подключений на 22 порту. Однако, правилом iptables входящие соединения на 22-й порт запрещены. Knockd, прослушивающий интерфейс eth0, ожидает последовательности из TCP SYN-пакетов на порты 9000, 6501 и 1234. Как только эта последовательность соединений будет обнаружена, knockd при помощи вызова iptables, изменит правило сетевого фильтра таким образом, чтобы разрешить подключение извне к 22-му TCP-порту, на котором уже ожидает SSH-демон.
Вы можете собрать knockd из исходных кодов, полученных на сайте (также, на сайте имеются ссылки на готовые пакеты для различных систем) или же установить, используя менеджер пакетов вашей системы. После установки knockd, его конфигурационный файл можно найти в /etc/knockd.conf .
В начале конфигурационного файла находится раздел [options] , содержащий глобальные настройки демона. Например, строкой:
вы можете определить, какой интерфейс прослушивать в случае, если в вашей системе он не является единственным.
Далее, после раздела [options] , идут описания последовательностей. По-умолчанию их две:
Значение параметра sequence определяет последовательность. Числа являются номерами TCP-портов. Также, вы можете явно указать, TCP или UDP порт использовать, при помощи суффиксов :tcp и :udp . Например:
Значение параметра seq_timeout задаёт максимальное время в секундах, которое отводится на совершение клиентом последовательности подключений. Если клиент не укладывается в это время — подключение будет отклонено.
Значение параметра command определяет путь и параметры вызываемой программы в случае обнаружения корректной последовательности.
Параметром tcpflags вы можете определять, какие флаги должны иметь пакеты, участвующие в последовательности. Несколько флагов необходимо разделять запятой:
А для явного исключения отельных флагов нужно использовать восклицательный знак:
Другим интересным вариантом конфигурации knockd является использование параметров start_command , cmd_timeout и stop_command :
Параметр start_command по смыслу идентичен параметру command . Значение параметра cmd_timeout определяет временной интервал в секундах, по истечении которого запустится команда, определённая значением параметра stop_command . Таким образом, вы можете открывать определённый порт лишь на некоторый промежуток времени.
Как правило, чтобы демон knockd запускался автоматически при старте системы, достаточно в файле /etc/default/knockd установить:
Настройка Клиента
Протестировать соединение с вашим сервером вы можете обычным telnet-клиентом, последовательно подключившись к заданным портам.
При повседневном же использовании, естественно, не очень удобно запускать последовательные серии telnet-соединений перед тем, как вам необходимо подключиться к вашему SSH-серверу. В комплекте с демоном knockd поставляется утилита knock , которая и призвана осуществлять необходимые серии подключений. Например:
Обратите внимание на формат описания номеров и типов портов. Он такой же, как и в файле /etc/knockd.conf .
Если придуманные вами последовательности основаны, в том числе и на TCP-флагах пакетов, то вам понадобятся более продвинутые средства, нежели knock. Например, SendIP или packit, умеющие формировать сетевые пакеты с произвольным содержимым.
Если вы используете port knocking повсеместно, то вам, вероятно, могут понадобиться knock-клиенты для мобильных платформ.
Для iPhone вы можете попробовать пару knockd-совместимых клиента — Port Knock Lite и KnockOnD, для Android — knock-android.
Port Knocking в PuTTY
Под Windows вы можете использовать русскую сборку PuTTY. Начиная с версии 0.63-RU-15, в ней появилась возможность осуществлять последовательность подключений к закрытым портам по технологии Port Knocking:
Практические Моменты
Одна из причин, по которой не стоит использовать knock-клиенты, запоминающих секретную последовательность и воспроизводящих её без вашего участия — это очень «похожесть» на сохранение где-то пароля к вашей учётной записи в открытом виде. Секретная последовательность подключений к портам должна находиться лично у вас в памяти и больше нигде. Тогда метод port knocking’а будет на самом деле эффективным.
Также, port knocking критикуют за то, что всегда существует вероятность того, что ваш трафик перехватят и смогут вычленить из него последовательность, и, чем чаще вы используете port knocking, тем выше эта вероятность. Конечно, вы можете дополнять вашу последовательность псевдопоследовательностями для того, чтобы запутать злоумышленников, однако в первую очередь всегда заботьтесь о безопасности самого сервиса, открытый порт которого вы маскируете и рассматривайте port knocking как дополнение к безопасности сервиса, нежели как панацею.
Более сложный метод защиты от прослушивания port knocking состоит в использовании одноразовых секретных последовательностей. Для этого в knockd.conf нужно использовать параметр one_time_sequences , значением которого должен быть путь к файлу с определением последовательностей, по одной на строку. После использования каждой последовательности knockd комментирует строку с использованной последовательностью и переключается на следующую.
В том числе имейте ввиду некоторые недостатки использования knockd. Во-первых, если процесс knockd внезапно «упадёт», вы не сможете получить удалённый доступ к маскируемой службе. Во-вторых, помните, что IP-пакеты могут доставлять к вашему серверу разными путями и приходить вовсе не в той последовательности, в которой были отправлены. Именно поэтому не стоит использовать слишком маленькое значение параметра seq_timeout.
Само-собой разумеется, что knockd можно использовать не только для управления правилами сетевого фильтра посредством запуска iptables. Вы можете запускать всё, что вам угодно, начиная от запуска процесса резервного копирования, заканчивая удалением важных данных с сервера и отправкой заявления об увольнении вашему начальнику.
Продвинутый Port Knocking
Можно установить knockd на серверах, находящихся за «основным» сервером, создав целую цепочку knockd-серверов.
Некоторые проекты, реализующие port knocking, решают проблему «replay»-атак за счёт использования криптоалгоритмов аутентификации. К таким проектам относятся, например, cryptknock, COK, и tariq.
Конечно, более продвинутые механизмы port knocking’а не оставят вам возможности «просто помнить» последовательность номеров портов, однако присутствие массы полезных «фишек» с лихвой перекроет этот «недостаток».
Всем интересующимся технологией port knocking’а рекомендуется посетить страницу portknocking.org.
Итоги
Когда специалист по безопасности скажет вам что весь этот ваш port knocking — лишь ещё один тонкий слой безопасности — он будет прав. Всегда ответственно подходите к защите непосредственно сервисов, как таковых, и не рассматривайте port-knocking как панацею. Port knocking будет полезен, чтобы скрыть запущенные службы от «случайных прохожих» и, если вы регулярно меняете секретные последовательности вашего knock-демона, то, вероятно, и предотвратит bruteforce-атаки по словарю учётных записей SSH.