ICMP открывашка портов для сервера

от автора

Имею парочку VDSок для различных нужд (почта, веб-сервер, хранилка и т.п.) так вот, возникла необходимость скрывать порты (22, 443 и т.п.) от посторонних глаз. Немного подумав (идея уже не новая), решил написать простенький, так сказать, ICMP knocker, то есть открытие портов по пингу. Но пингу не простому, а с определенным размером сообщения/пакета. Пример для линукс:

ping -s 999 -c1 mysrv.com

Где -s — размер отправляемого сообщения, -с количество. Если совпадает размер сообщения, то для IP-адреса отправителя открываются указанные порты на некоторое время и отравляется сообщение об открытие портов в Телеграмм. Так для реализации данной поделки понадобятся: ufw, curl, tcpdump:

apt install ufw curl tcpdump

и сам скрипт:

nano /opt/port-knocker.sh

#!/bin/bash PING_SIZE=999 PORTS='tcp/22 tcp/443' TIMEOUT=3600  TOKEN="121212XXXX:XXXXZZZZAAAAEEEERRRRQQQQGGGGTTTTHHHH" CHATID="55555XXXX"  PACKAGE_SIZE=$(( $PING_SIZE + 28 ))  function allow_access {     RESULT=`ufw allow proto $PROTO from $SRC to $DST port $PORT`     echo "`date` _ PORT-knocker _ $SRC -> $DST:$PORT :  $RESULT"     MESS="<b>`uname -n`</b> %0A`date` %0Aufw allow proto tcp from $SRC to $DST PORT $PORT %0A$RESULT"     curl -s "https://api.telegram.org/bot${TOKEN}/sendMessage?chat_id=${CHATID}&text=$MESS&parse_mode=HTML" >/dev/null & }  function deny_access {     sleep ${TIMEOUT} && RES=$(`ufw show added | grep "$DST" | grep "$SRC" | grep "port $PORT" | grep "proto $PROTO" | sed 's|ufw |ufw delete |g'`) && echo "`date` _ PORT-knocker _ $SRC -> $DST:$PORT : $RES" & }  while true do         LINE=`timeout 3600 tcpdump -n -c1 -i any icmp[icmptype] == icmp-echo and ip[2:2] == $PACKAGE_SIZE 2>/dev/null`          if [ -n "$LINE" ]         then             IP=`echo $LINE | sed 's|^.*IP ||' | tr ':' ' ' | awk '{print $1" "$3 }'`             SRC=`echo $IP | awk {'print $1'}`             DST=`echo $IP | awk {'print $2'}`             if [ -n "$SRC" ] && [ -n "$DST" ]             then                 for PPORT in ${PORTS}                 do                     PROTO=`echo $PPORT | sed 's|/| |g' | awk '{print $1}'`                     PORT=`echo $PPORT | sed 's|/| |g' | awk '{print $2}'`                     if ufw show added | grep "$DST" | grep "$SRC" | grep " $PORT"                     then                         deny_access                     else                         allow_access                         deny_access                     fi                 done             fi         else             echo "`date` - Timeout, reload sniffer"         fi  done

Где,

PING_SIZE — размер сообщения
PORTS=’tcp/22 tcp/443′ — протокол и порт
TIMEOUT=3600 — таймаут открытия порта в секундах

TOKEN — Телеграмме BotFather подскажет по запросу «/mybots» -> «API Token»
CHATID — Телеграмме IDBot подскажет по запросу «/getid»

Делаем скрипт исполняемым:

chmod +x /opt/port-knocker.sh

Чтобы скрипт работал как сервис:

nano /etc/systemd/system/pk.service

[Unit] Description=Start port-knocker  [Service] StandardOutput=syslog StandardError=syslog WorkingDirectory=/opt/ Type=simple ExecStart=/bin/bash /opt/port-knocker.sh KillMode=process Restart=on-failure RestartSec=5s  [Install] WantedBy=multi-user.target

Запускаем скрипт:

systemctl start pk

systemctl enable pk

Проверяем:

ping -s 999 -c1 mysrv.com

Должно пройти сообщение в телегу, о том порты открыты для такого-то IP

Если все ОК, то можно активировать UFW:

ufw enable

ufw show added

Повторить:

ping -s 999 -c1 mysrv.com

и глянуть опять:

ufw show added

ufw allow from XXX.XXX.XXX.XXX to YYY.YYY.YYY.YYY port 22 proto tcp  ufw allow from XXX.XXX.XXX.XXX to YYY.YYY.YYY.YYY port 443 proto tcp

Значит всё ОК, у меня всё!)))

P.S. Уже есть заготовка на Python3, если будет востребована, то перепишу)


ссылка на оригинал статьи https://habr.com/ru/post/673790/


Комментарии

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

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