КОПИПАСТА с сайта
https://spfng.com/post/hardened-ssh-with-ping-port-knocking-using-only-iptables/
Самая заветная цель любого хакера — получить root-доступ к компьютеру
через SSH. До тех пор, пока открыт 22 порт, его будут атаковать, и не
только его: не SSH единым. На компьютере работает множество сервисов,
публичных и не очень, которые так же могут быть подвержены взлому. Все
лишние сервисы должны быть выключены, а все лишние порты прикрыты.
Используя iptables возможно реализовать дополнительный уровень защиты,
так называемый «Port Knocking», технология которого заключается в том,
что прежде чем подключиться на какой-либо порт, необходимо сперва
«постучаться»: подключиться на другой порт, известный только владельцу
хоста, после чего основной порт становится доступен на короткий
промежуток времени. Можно пойти дальше, ограничиться не одним портом, а
несколькими, чтобы требовалось «стучаться» в каждый порт в отдельности и
строго в опредлённом порядке. Получается что-то вроде пароля состоящего
из отдельных PIN-кодов.
«Port Knocking» известная технология, но почему бы не использовать ICMP?
Только вместо номера порта — указывать размер пакета, а в остальном всё
тоже самое.
Скрипт реализует «Ping Knocking», чтобы «постучаться» на хост и iptables
открыл 22 порт на одну минуту, используя утилиту ping требуется
отправить шесть ICMP-пакетов определённого размера и в определённом
порядке, а именно:
4 8 15 16 23 42
...
Скрипт:
Открыть спойлер
#!/bin/bash
set -x
(
iptables -N ICMP_HELLO
iptables -N ICMP_WELCOME
iptables -N ICMP_4
iptables -N ICMP_8
iptables -N ICMP_15
iptables -N ICMP_16
iptables -N ICMP_23
iptables -N ICMP_42
iptables -A INPUT -p icmp --icmp-type echo-request -m conntrack --ctstate NEW -j ICMP_HELLO
iptables -A INPUT -p tcp --dport 22 -m conntrack --ctstate NEW -m recent --rcheck --seconds 60 --name SSH -j ACCEPT
iptables -A INPUT -p tcp --dport 22 -m conntrack --ctstate NEW -j DROP
iptables -A ICMP_HELLO -m recent --rcheck --seconds 60 --name ICMP_42 -j ICMP_WELCOME
iptables -A ICMP_HELLO -m recent --rcheck --name ICMP_23 -j ICMP_42
iptables -A ICMP_HELLO -m recent --rcheck --name ICMP_16 -j ICMP_23
iptables -A ICMP_HELLO -m recent --rcheck --name ICMP_15 -j ICMP_16
iptables -A ICMP_HELLO -m recent --rcheck --name ICMP_8 -j ICMP_15
iptables -A ICMP_HELLO -m recent --rcheck --name ICMP_4 -j ICMP_8
iptables -A ICMP_HELLO -j ICMP_4
iptables -A ICMP_4 -m length --length $((4 + 28)) -m recent --name ICMP_4 --set -j ACCEPT
iptables -A ICMP_8 -m recent --name ICMP_4 --remove
iptables -A ICMP_8 -m length --length $((8 + 28)) -m recent --name ICMP_8 --set -j ACCEPT
iptables -A ICMP_15 -m recent --name ICMP_8 --remove
iptables -A ICMP_15 -m length --length $((15 + 28)) -m recent --name ICMP_15 --set -j ACCEPT
iptables -A ICMP_16 -m recent --name ICMP_15 --remove
iptables -A ICMP_16 -m length --length $((16 + 28)) -m recent --name ICMP_16 --set -j ACCEPT
iptables -A ICMP_23 -m recent --name ICMP_16 --remove
iptables -A ICMP_23 -m length --length $((23 + 28)) -m recent --name ICMP_23 --set -j ACCEPT
iptables -A ICMP_42 -m recent --name ICMP_23 --remove
iptables -A ICMP_42 -m length --length $((42 + 28)) -m recent --name ICMP_42 --set -j ICMP_WELCOME
iptables -A ICMP_WELCOME -m recent --name ICMP_42 --remove
iptables -A ICMP_WELCOME -m recent --name SSH --set
iptables -A ICMP_WELCOME -j LOG --log-prefix "4 8 15 16 23 42 "
iptables -A ICMP_WELCOME -j ACCEPT
)
Можно вручную выполнить ping шесть раз, указав размер пакета, но удобнее воспользоваться однострочным скриптом, после выполнения которого 22 порт станет доступен на одну минуту, о чём iptables так же сообщит в логах dmesg — строка будет содержать «пароль».
# for n in 4 8 15 16 23 42; do ping -c 1 -s $n spfng.com; done
Никто не сможет подключиться к хосту по SSH не зная точную комбинацию цифр.