fbpx
Перейти к содержимому

Port knocking — дополнительная защита портов

Для дополнительной защиты сервера от злоумышленником, помимо файрвола, используется метод «простукивания портов». Принцип работы port knocking сводится к обращению в определенном порядке и за определенный период времени к цепочке заранее указаных портов. Если последовательность обращения верная и она была произведена в заданный промежуток времени то выполняется команда, к примеру правило файрвола, и открывается нужный порт, после чего вы можете к нему подключиться.

Port knocking можно использовать не только для предоставления доступа к конкретному порту, но также запускать любые команды либо скрипты, к примеру, таким образом вы можете запускать резервное копирование, запускать рассылку сообщений либо отправлять разнообразные уведомления.

Принцип работы

Для настройки на стороне сервера мы будем использовать утилиту knockd. Утилита knocd работает в режиме демона и совместно с iptables прослушивает сетевой трафик ожидая корректной последовательности запросов на подключение.

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

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

Утилита knockd доступна во всех современных дистрибудивах linux и установить вы можете ее одной командой

apt install knockd

Если же по каким-то причинам данная утилита недоступна в вашей системе вы можете скачать исходники которые доступны на официальном сайте и скомпилировать ее.

После установки установим автоматический запуск knockd, для этого откроем файл который находится по адресу /etc/default/knockd

nano /etc/default/knockd

Для автоматического запуска демона knockd необходимо изменить значение START_KNOCKD и установить его равным 1.

START_KNOCKD=1

Перейдем к настройке knock, файл конфиуграционный файл находится по адресу /etc/knockd.conf, откроем его и отредактируем.

nano /etc/knockd.conf

В секцию [options] нам необходимо добавить интерфейс который утилита knockd будет прослушивать. Чтобы узнать имя вашего интерфейса, выполните команду ifconfig, у меня один интерфейс с именем enp0s3.

enp0s3: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.1.98  netmask 255.255.255.0  broadcast 192.168.1.255
        inet6 fe80::a00:27ff:fede:11e0  prefixlen 64  scopeid 0x20<link>
        ether 08:00:27:de:11:e0  txqueuelen 1000  (Ethernet)
        RX packets 40043  bytes 45766404 (45.7 MB)
        RX errors 0  dropped 961  overruns 0  frame 0
        TX packets 3949  bytes 706255 (706.2 KB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

Приводим секцию [options] к следующему виду

[options]
        UseSyslog
        Interface = enp0s3

В стандартной конфигурации в качестве примера указаны две последовательности [openSSH] и [closeSSH] их мы с вами разберем подробнее.

[openSSH]
        sequence   = 7000,8000,9000
        seq_timeout= 5
        command    = /sbin/iptables -A INPUT -s %IP% -p tcp --dport 22 -j ACCEPT
        tcpflags   = syn

[closeSSH]
        sequence   = 9000,8000,7000
        seq_timeout= 5
        command    = /sbin/iptables -D INPUT -s %IP% -p tcp --dport 22 -j ACCEPT
        tcpflags   = syn

Последовательность [openSSH] у нас отвечает за «открытие» 22 порта, а последовательность [closeSSH] за его «закрытие» . Для того чтобы порт 22 был доступен необходим сделать запрос на порт 7000, 8000, 9000 , а для того чтобы закрыть доступ к порту 22 необходимо выполнить обратную последовательность на 9000, 8000 и 7000 порт.

Опция sequence содержит последовательность портов, по умолчанию используется протокол tcp, если вы необходимо использовать udp то необходимо задать его через двоеточие

sequence = 7000:tcp,8000:udp,9000:udp

В seq_timeout указывается значение в секундах за которое клиенту необходимо завершить всю последовательность обращения к портам. Устанавливая данный параметр нужно учитывать возможные задержки каналов связи.

seq_timeout= 5

В command задается путь и параметры вызываемой программы в случае обнаружения корректной последовательности.

command    = /sbin/iptables -A INPUT -s %IP% -p tcp --dport 22 -j ACCEPT

tcpflags — определяет TCP-флаги пакетов, которые будут участвовать в последовательности, syn рекомендуется использовать совместно с SSH, так как SSH-трафик может мешать knockd, делая последовательность недействительной.

tcpflags   = syn

Если же вам необходимо открыть порт на определенный промежуток времени то можно использовать опции start_command и stop_command которые определяют команды которые должен выполнить knoсkd с интервалом указанном в опции cmd_timeout. Принцип действия следующий — получив указанную последовательность выполняется команда из опции start_command, а по истечении заданного промежутка времени выполняется команда stop_command.

В примере ниже объединены последовательности [openSSH] и [closeSSH] в одну последовательность c именем [10minSSH] и интервалом предоставления доступа к порту равном 10 минут

[10minSSH]
sequence = 7000,8000,9000
seq_timeout = 5
start_command = /sbin/iptables -A INPUT -s %IP% -p tcp --dport 22 -j ACCEPT
stop_command = /sbin/iptables -D INPUT -s %IP% -p tcp --dport 22 -j ACCEPT
cmd_timeout = 600

tcpflags = syn

После внесения всех настроек, сохраняем файл и запускаем службу knockd

service knockd start 

После запуска проверяем статус службы и нет ли ошибок

service knockd status
● knockd.service - Port-Knock Daemon
     Loaded: loaded (/lib/systemd/system/knockd.service; disabled; vendor preset: enabled)
     Active: active (running) since Wed 2022-01-26 11:56:40 UTC; 2s ago
       Docs: man:knockd(1)
   Main PID: 6331
      Tasks: 1 (limit: 1066)
     Memory: 320.0K
     CGroup: /system.slice/knockd.service
             └─6331 /usr/sbin/knockd

Jan 26 11:56:40 unixhosttest1.example.com systemd[1]: Started Port-Knock Daemon.
Jan 26 11:56:40 unixhosttest1.example.com knockd[6331]: starting up, listening on enp0s3

Подключение к серверу

Для того чтобы «достучаться» к закрытому порту необходимо выполнить запрос на ту цепочку портов которая указана в конфигурационном файле и сделать это можно либо используя утилиту которая есть почти в любой системе — telnet либо специальный клиент knock.

Для открытия порта используя telnet последовательно выполняем следующие команды

telnet 192.168.1.98 7000
telnet 192.168.1.98 8000
telnet 192.168.1.98 9000

Если вы уложились в заданный промежуток времени seq_timeout то на сервере на который мы «стучались» в статусе службы вы статус успешного прохождения цепочки и команду которая была выполнена

service knockd status
Jan 27 09:35:33 unixhost knockd[6735]: 192.168.1.99: openSSH: Stage 1
Jan 27 09:35:36 unixhost knockd[6735]: 192.168.1.99: openSSH: Stage 2
Jan 27 09:35:39 unixhos knockd[6735]: 192.168.1.99: openSSH: Stage 3
Jan 27 09:35:39 unixhost knockd[6735]: 192.168.1.99: openSSH: OPEN SESAME
Jan 27 09:35:39 unixhost knockd[38167]: openSSH: running command: /sbin/iptables -A INPUT -s 192.168.1.99 -p tcp --dport 22 -j ACCEPT

Для закрытия порта выполняем команду в обратном порядке

telnet 192.168.1.98 9000
telnet 192.168.1.98 8000
telnet 192.168.1.98 7000

Утилита knock уменьшает количество вводимых команд до одной, достаточно перечислить все порты которые необходимо простучать. Для открытия порта необходимо выполнить

knock 192.168.1.98 7000 8000 9000

А для закрытия

knock 192.168.1.98 9000 8000 7000

Особенности

В подобном способе защиты есть пару нюансов которые необходимо знать перед тем как настраивать подобный способ защиты на своих серверах.

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