Knockd – удаленное управление портами в брандмауэре

KnockdKnockd - программа, которая запускает заранее заданную команду, если выполнено условие коннекта на определенные порты компьютера. Это если кратко и попонятней :) На самом деле коннекты должны идти в определенной последовательности и с определенным интервалом.
Есть серверная часть - демон knockd, в конфигурации которого задана команда выполнения и задан набор определенных портов компьютера. Также есть клиентская часть, с помощью которой и происходит открытие той двери, которая закрыта за knockd. Клиент программы есть для Unix и Windows систем.
В основном команды knockd управляют открытием или закрытием портов брандмауэра компьютера, но никто вам не запрещает исполнить любую другую команду.
В данной статье я разберу пример как защитить порт ssh от посторонних соединений.

Дополнительную информацию о программе и примерах конфигурационных файлов можно узнать на официальном сайте

Установка knockd и базовая настройка

Установка во всех дистрибутивах очень проста, в ubuntu (debian) она сводится к выполнению команды


#sudo aptitude install knockd

После установки knockd в /etc/knockd.conf находим конфиг программы следующего содержания, показать

В linux дистрибутивах этого конфига достаточно, чтобы уже запускать демон knockd и начинать работать. Перед запуском демона требуется сперва убрать доступ к 22 порту в брандмауэре и само собой на этом порту должен работать openssh сервер :)
Кто забыл как работать с брандмауэром в linux советую прочитать мои статьи iptables – полезные команды и настраиваем защищенный iptables
Итак, запускаем демон


#knockd -d

Переходим на машину, откуда будем пробовать соединиться с удаленным портом. В зависимости от ОС на этой машине ставим или скачиваем клиентскую команду knock.
Пробуем соединиться на 22 порт через ssh, пускать не должно. После выполнения команды knock с заветными номерами портов доступ к порту ssh будет предоставлен


mik@gw:~$ telnet m1k 22
Trying 192.168.0.17...
^C
mik@gw:~$ knock -v m1k 7000 8000 9000
hitting tcp 192.168.0.17:7000
hitting tcp 192.168.0.17:8000
hitting tcp 192.168.0.17:9000
mik@gw:~$ telnet m1k 22
Trying 192.168.0.17...
Connected to m1k.
Escape character is '^]'.
SSH-2.0-OpenSSH_5.2

Закрыть обратно доступ - выполним команду knock с портами закрытия


mik@gw:~$ knock -v m1k 9000 8000 7000
hitting tcp 192.168.0.17:9000
hitting tcp 192.168.0.17:8000
hitting tcp 192.168.0.17:7000
mik@gw:~$ telnet m1k 22
Trying 192.168.0.17...
^C

В логах на сервере /var/log/knockd.log можно всегда посмотреть с какого ip и в какое время выполнялись команды открытия/закрытия.

Если что-то не получается даже с этим простейшим примером, то дело скорей всего в брандмауэре. Нельзя сначала явно запретить доступ в брандмауэре а потом пытаться его открыть. В следующем листинге показана ситуация, когда я явно запретил правило в конфигах, а потом открыл доступ к порту через knockd команду.


12 720 DROP  tcp  --  * *  0.0.0.0/0        0.0.0.0/0        tcp dpt:22 state NEW
0 0 ACCEPT  tcp  --  * *  192.168.0.254     0.0.0.0/0        tcp dpt:22

По количеству байт и пакетов видно, что сначала отрабатывает правило запрета, а до разрешающего правила доступ не доходит. Выход тут только один "неявно" делать запрет. Как вариант в общей политике iptables прописывать


iptables -P INPUT DROP
iptables -P OUTPUT ACCEPT
iptables -P FORWARD DROP

а потом разрешать входящие только то, что требуется. Так что правило для входящих на 22 порт от knockd будет в этом случае очень кстати :)

Дополнительные настройки knockd

Конфигурационный файл /etc/knockd можно дополнить следующими опциями и командами


[options]
    #задать имя интерфейса на которое будет срабатывать команда
     interface = eth0

В параметрах открытия закрытия тонко указать использовать tcp или udp порты


sequence      = 1234:udp,5678:tcp,9101:udp

соответсвенно чтобы выполнить команду такой последовательности надо выполнять команду


$knock host 1234:udp 5678:tcp 9101:udp

Можно задавать время в секундах между выполнением команд открытия и закрытия портов.


start_command = открываем порт
cmd_timeout   = 600 #время между выполнением команд
stop_command  = закрываем порт

Для совсем помешанных на безопасности можно создать файл с уникальными последовательностями портов на каждой строчке и потом каждый раз входить по определенной последовательности портов. В /etc/knockd.conf файл последовательностей задается переменной


One_Time_Sequences = /path/to/one_time_sequences_file

В файле рекомендуется каждую последовательность начинать с пробела, т.к. после использования этой последовательности демон knockd комментирует строку символом #. Нельзя редактировать файл последовательностей портов пока демон работает!

Для выполнения команды knockd, где требуется открыть больше одного порта по заданию одной последовательности портов, создадим любой файл в котором опишем нужные команды. Вместо переменной %IP% требуется писать $1. Например для открытия одновременно 22 и 23 портов создаем файл с содержимым


/usr/sbin/iptables -A INPUT -s $1 -p tcp --dport 22 -j ACCEPT
/usr/sbin/iptables -A INPUT -s $1 -p tcp --dport 23 -j ACCEPT

Назовем файл open_22_23 и сделаем его исполняемым.
В конфиге knockd.conf вместо команды iptables пишем


command = /path/to/open_22_23 %IP%

Аналогично с командой закрытия, только для нее уже создадим другой файл команд.

Для брандмауэра ipfw в системе FreeBSD применяем следующие команды открытия/закрытия 22 порта. При добавлении-удалении используем номер правила.


/sbin/ipfw add 111 allow tcp from %IP% to me 22 keep-state
/sbin/ipfw delete 111

В дальнейшем не забыть поставить демон в автозагрузку при старте ОС. В ubuntu это можно сделать, изменив параметр START_KNOCKD=1 в файле /etc/default/knockd

Статья просмотрена 26 423 раз
Запись опубликована в рубрике Firewall, iptables с метками , , , . Добавьте в закладки постоянную ссылку.

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

Можно использовать следующие HTML-теги и атрибуты: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>