Системные администраторы часто стоят перед задачей: каким образом обеспечить доступ к своим системам из разных уголков планеты, не делая служебные порты общедоступными. Один из вариантов — это VPN, но такой метод не всегда доступен или уместен. Тем не менее, существует альтернативное решение, именуемое Port Knocking. Суть метода заключается в том, что для получения доступа необходимо «постучаться» на определённые порты в специфической последовательности. Словно говоря системе «стучи правильно, и дверь откроется».
Прежде чем приступить к рассмотрению данной технологии, стоит осветить несколько распространенных мифов о Port Knocking. Хотя и являясь дополнительным инструментом безопасности, он не делает сервис, за которым он скрывается, более безопасным. Это просто метод доступа, и, возможно, не самый стойкий перед угрозами.
Если вы планируете использовать Port Knocking для обеспечения доступа к, например, терминальному серверу с не самой надежной парольной политикой или приложению с открытым протоколом, это может быть ошибочным решением. Вместо этого лучше уделите внимание укреплению безопасности ваших основных систем.
Также стоит учитывать, что устройство, запрашивающее доступ, может находиться в общедоступной сети, за прокси-сервером или даже за NAT. В таком случае другие пользователи с тем же IP-адресом могут временно получить доступ к вашему сервису.
Не стоит забывать и о возможности перехвата трафика. Если злоумышленник анализирует ваш трафик, он может выявить правильную комбинацию портов для «стучания». И чем чаще вы используете этот метод, тем быстрее он может быть раскрыт.
Исходя из этого, мы не советуем использовать Port Knocking для критически важных сервисов. Несмотря на дополнительные сложности, такой метод предоставляет относительно слабую защиту. Однако как средство для скрытия служебных портов и временного доступа в чрезвычайных ситуациях он весьма уместен.
Port Knocking с применением разных портов
Данный подход считается традиционным. Он заключается в том, чтобы в определенной последовательности обращаться к нескольким закрытым портам в течение короткого промежутка времени. Выполнив заданные условия, мы получаем доступ.
При реализации этой концепции важно следить за корректной очередностью правил в цепочке INPUT вашего межсетевого экрана. Главным правилом, которое будет являться основой для нашей системы, будет разрешение уже установленных связанных соединений ESTABLISHED, RELATED. Если вы следовали нашей инструкции для настройки роутера, то это правило будет вторым после «правила-заглушки», которое разрешает доступ из внутренней сети.
Для нашего примера выберем порядок обращения к портам 7890 и 9870. Эти значения взяты для наглядности, но в реальной практике стоит выбирать порты, которые располагаются дальше друг от друга, чтобы избежать легкого сканирования сети. Но к этому аспекту мы вернемся позже. Теперь давайте добавим новое правило.
В разделе General указываем: Chain - input, Protocol - tcp, Dst. Port - 7890.На вкладке «Действие» устанавливаем параметры: Тип действия - добавить IP-источник в список, Название списка - KNOCK-1, Время истечения - 00:00:30
Это правило, при попытке доступа к порту 7890, внесёт IP-адрес источника в список KNOCK-1 на 30 секунд. В течение этого краткого периода необходимо произвести обращение к следующему порту для получения доступа. Не рекомендуется устанавливать слишком долгий таймаут, по нашему мнению, 30 секунд — это вполне достаточно для выполнения необходимых действий в терминале, хотя в некоторых случаях таймаут можно немного увеличить.
Теперь перейдём к добавлению следующего правила. На вкладке «Основные параметры» укажем: Цепочка - входящая, Протокол - tcp, Целевой порт - 9870. На вкладке «Дополнительно» укажем: Список исходящих адресов - KNOCK-1.
На вкладке Action укажем: Action - добавить источник в список адресов, Список адресов - KNOCK-ACCEPT, Таймаут - 00:01:00.
Этот инструктивный шаг дает возможность внести в список KNOCK-ACCEPT IP-адрес устройства, которое пытается подключиться к порту 9870 и одновременно присутствует в списке KNOCK-1. Запись в этом списке будет активна 1 минуту, и в течение этого времени необходимо будет установить соединение с нужным устройством.
Тоже самое в терминале:
/ip firewall filter
add action=add-src-to-address-list address-list=KNOCK-1 address-list-timeout=30s chain=input dst-port=7890 protocol=tcp
add action=add-src-to-address-list address-list=KNOCK-ACCEPT address-list-timeout=1m chain=input dst-port=9870 protocol=tcp src-address-list=KNOCK-1
Данные инструкции следует распределить выше того, что разрешает текущие активные соединения. После этого, мы добавляем правило для разрешения подключения к нужному нам порту, в этом примере это порт Winbox - 8291.
На вкладке «Основные настройки» задайте следующие параметры: Chain - input, Protocol - tcp, Dst. Port - 8291. На вкладке «Дополнительно» укажите: Список адресов источника - KNOCK-ACCEPT. Вкладку «Действие» оставьте без изменений, так как accept уже задано по умолчанию.
В терминале для этого выполните:
/ip firewall filter
add action=accept chain=input dst-port=8291 protocol=tcp src-address-list=KNOCK-ACCEPT
Это правило следует разместить после правила, которое разрешает активные и ассоциированные соединения.
Теперь давайте разберемся, как все это функционирует. Два первых правила формируют списки с IP-адресами источников. Для того чтобы попасть в список KNOCK-ACCEPT, вы должны обратиться к портам 7890 и 9870 в течение 30 секунд подряд. После этого у вас будет 1 минута, чтобы осуществить подключение к нужному порту, в данном контексте это Winbox. После этого все пакеты текущего соединения будут обрабатываться согласно правилу, которое разрешает активные соединения. Таким образом, спустя минуту новые соединения не будут установлены, а активные продолжат функционировать до момента их завершения.
Теперь, имея эти правила, давайте попробуем их в действии. В операционной системе Linux можно использовать инструмент netcat - nc для этой цели. Для «стука» в TCP-порт используйте следующую команду:
nc -zw 1 XXX.XXX.XXX.XXX 7890
nc -zw 1 XXX.XXX.XXX.XXX 9870
Где XXX.XXX.XXX.XXX — это IP-адрес вашего маршрутизатора. Параметр -z позволяет сканировать порт без отправки данных, а параметр -w устанавливает время ожидания в 1 секунду.
Для работы с UDP-портами применяйте следующую команду:
nc -zu XXX.XXX.XXX.XXX 7890
nc -zu XXX.XXX.XXX.XXX 9870
В Windows выполнение «стука» в порт может потребовать дополнительных шагов. Из доступных по умолчанию инструментов рекомендуется применять PowerShell.
Test-NetConnection XXX.XXX.XXX.XXX -Port 7890
Test-NetConnection XXX.XXX.XXX.XXX -Port 9870
Однако, эта команда может ожидать ответа от устройства до 20 секунд, и указанное время для обращения к следующему порту может быть недостаточным. В такой ситуации стоит рассмотреть возможность увеличения времени ожидания. Также стоит отметить, что данной методикой можно «стучаться» только в TCP-порт.
Альтернативный способ — применение утилиты tcping. Он более прост и удобен в обращении, но также ограничен только TCP-портами.
tcping -n 1 XXX.XXX.XXX.XXX 7890
tcping -n 1 XXX.XXX.XXX.XXX 9870
Параметр -n задаёт число отправляемых пакетов, в данном случае — один
Есть специальные утилиты, такие как PortKnock, предназначенные для автоматизации этой задачи. Данный инструмент поддерживает работу с TCP и UDP портами и способен последовательно обращаться к четырём портам.
В заключение можно сказать, что Port Knocking, основанный на использовании портов, представляет собой довольно прямолинейный метод безопасности, позволяя конфигурировать разнообразные комбинации портов и тайм-ауты. Однако у него есть свои ограничения. Особенно это касается Windows, где может потребоваться дополнительное программное обеспечение. Плюс, порты, которые расположены рядом друг с другом, легко обнаруживаются при сканировании.
Недавно мы провели тест с использованием утилиты Advanced Port Scanner. Она с лёгкостью определела комбинации 7890-9870 и 7890-9870-8790, однако оказалась бессильной перед 17890-9870. Это подчеркивает важность выбора непоследовательных портов и установки коротких тайм-аутов для списков адресов.
Также следует помнить, что подобные комбинации портов могут быть выявлены при мониторинге сетевого трафика, особенно в публичных сетях или при использовании VPN. Поэтому крайне важно уделять внимание защите основных сервисов, доступ к которым вы хотите ограничить с помощью этой техники.
Использование Port Knocking с применением ICMP
Этот метод отличается от традиционного подхода к Port Knocking, так как вместо использования конкретных портов он рассчитывает на ICMP-пакеты разной длины. Главное преимущество здесь - простота выполнения с помощью встроенных инструментов операционной системы и усиленная скрытность, так как необычные пакеты менее заметны при анализе сетевого трафика.
Необходимо учитывать стандартное значение MTU в 1500 байт. Однако, при работе в условиях VLAN, VPN и других подобных сетевых конфигураций, это значение может сокращаться. По этой причине рекомендуется не использовать пакеты, размер которых превышает 1000 байт. Также не забудьте про 28 байтов, занимаемых заголовками ICMP.
Для успешной реализации этого метода, выберите два или более числа в пределах до 1000, которые будут действовать как «ключи» для процедуры стука. В данном контексте, числа 250 и 209 являются примерами таких ключей. Структура правил будет схожа с предыдущим методом, и основана на принципе разрешения уже активных соединений.
Чтобы начать, создайте два правила для добавления исходных адресов в соответствующие списки. В первом из них на вкладке General укажите: Chain - input, Protocol - icmp. На вкладке Advanced установите Packet Size - 278 (250 + 28), что соответствует размеру выбранного пакета. Наконец, в разделе Action выберите: Action - add src to address list, указав Address List как KNOCK-1 с Timeout равным 30 секундам.
Во втором правиле устанавливаются следующие параметры:
Либо выполним в терминале:
/ip firewall filter
add action=add-src-to-address-list address-list=KNOCK-1 address-list-timeout=30s chain=input packet-size=278 protocol=icmp
add action=add-src-to-address-list address-list=KNOCK-ACCEPT address-list-timeout=1m chain=input packet-size=237 protocol=icmp src-address-list=KNOCK-1
Эти правила необходимо разместить перед правилом, которое разрешает уже существующие и связанные соединения. Остальные параметры аналогичны ранее описанному методу.
Для инициации «стука» из Linux, выполните следующую команду:
ping XXX.XXX.XXX.XXX -s 250 -c 1
ping XXX.XXX.XXX.XXX -s 209 -c 1
Для Linux, указание ключа -s определяет размер пакета (исключая заголовок), в то время как ключ -c определяет количество отправляемых пакетов — в данной ситуации это один пакет.
Для Windows команда будет выглядеть следующим образом:
ping XXX.XXX.XXX.XXX -l 250 -n 1
ping XXX.XXX.XXX.XXX -l 209 -n 1
В данном контексте ключ -l определяет размер пакета, а -n задает количество отправляемых пакетов.
Механизм функционирования схож с описанным ранее. Получив ICMP-пакет объемом 250 байт, исходный адрес попадает в начальный список. Далее, в пределах 30 секунд, необходимо отправить второй пакет объемом 209 байт. Если условия выполнены, адрес добавляется в список KNOCK-ACCEPT, предоставляя возможность установления соединения на протяжении одной минуты.
Лично мы считаем, что такой подход предпочтительнее. Он предлагает возможность работы с встроенными инструментами ОС и делает процесс сложнее для обнаружения при мониторинге сетевого трафика. Кроме того, можно комбинировать обе методики: сначала «стукнуть» по определенному порту, затем отправить ICMP-пакет заданного размера. В конечном итоге выбор зависит от вас, а рамки задаются только вашим воображением и рациональным подходом.