Открыть порт ssh по стуку с IPtables в Linux

Одно из очень простых решений — открывать ssh порт ( стандартный 22-й порт) после того как постучишься в заданный, «высокий» порт.

Есть несколько способов сделать стук, чтобы открылся нужный порт. Сейчас я расскажу о нескольких из них.

-===Способ 1 (самый простой), стук на 1 порт===-

И так, я сейчас выполню ряд действий с IPtables. И так, первое что необходимо сделать — это создать новую цепочку чтобы выполнять проверку на попытки соединенится на защищаемый порт:

Далее, чтобы не ломились на определенный порт, я сейчас задам правило. Суть заключается в следующем, если кто-то будет производить стук на порт более 2-х раз за одну минуту ( 60 секунд), попадает в бан:

Следующим правилом создается исключение, которое говорит

Если производился стук в нужный порт ( за последние 10 секунд), то разрешаем соединение:

Очистим  INPUT цепочку:

Разрешаем прохождение пакетов на установленные соединения:

Все попытки открыть новое SSH соединение, будут проверяться:

Сейчас, собственно  прописываем правило для стука на заданный порт:

Закрываем соседние порты ( чтобы не стучались):

Остальное, запретим:

Для удобства использования, я создал баш скрипт:

И прописал в него:

Запускаем:

PS: Может понадобится выставить права на исполнение ( chmod +x knock.sh).

Выполним проверку iptables:

Реализация довольно простая, но на практике — выполняем защиту: После стука на 27520 порт, будет производиться открытие SSH порта ( в этом примере, 22-й порт используется). Если за минуту будет произведено более 1 стука, порт не будет открыт и вы получите бан. Соседние порты были закрыты с целью защиты и от предотвращения подбора стука.

Чтобы постучаться, используем команду:

PS: Можно заюзать любую другую тулзу — telnet, nc hping.

И после чего, выполняем подключение на сервер:

Так не есть удобно! По этому, создаем баш-скрипт:

И прописывам в него:

PS: Не забываем выставить права на использование (chmod +x knock_ssh_connection.sh).

А сейчас я, расскажу более сложный стук, с использованием 3-х стуков на разные порты.

-===Способ 2 (более продвинутый, сложный), стук на 3 порта===-

Можно сохранить любое количество отдельных именованных списков. В этом случае будет три:

  • KNOCK1 — идентифицирует исходные адреса, которые выполнили первый стук ( но не второй или третий).
  • KNOCK2 — определяет адреса источника, которые выполнили первый и второй стук ( но не третий).
  • KNOCK3 — идентифицирует исходные адреса, которые выполнили первый, второй и третий стуки ( но еще не установили соединение).

Т.е, чтобы подключиться на 22-й SSH порт, нужно постучаться на 3 разных порта, и после чего выполнить подключение на сервер.

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

Как и в случае с большинством конфигураций брандмауэра, после принятия решения о принятии первого пакета соединения все дальнейшие пакеты, входящие в одно и то же соединение, должны проходить беспрепятственно:

Обычно, нецелесообразно блокировать трафик с интерфейса loopback, по этому, создаем правило:

Блокировка ICMP-трафика может обеспечить некоторые незначительные преимущества в безопасности, но в большинстве случаев она может причинить больше неудобств, по этому, не блокируем его, а разрешаем прохождение ICMP пакетов:

Разрешаем прохождения трафика на порту 80:

Когда сервер ожидает первый стук:

  • Если пакет является первым стуком, то переход в состояние 1 (STATE 1);
  • Иначе остаются в состоянии 0 (STATE 0).
  • В любом случае, любой полученный трафик должен быть удален

Когда первый удар получен, и сервер ждет второго удара:

  • Если пакет является вторым стуком, то переходом в состояние 2 (STATE 2);
  • Если пакет является еще первым стуком, то остаемся в состоянии 1 (STATE 1);
  • В противном случае выполните возврат к состоянию 0 (STATE 0).
  • Как и выше, любой полученный трафик должен быть удален.

Цепь состояния 0 уже содержит правила обработки первого удара. Повторное использование этой цепочки позволяет избежать указания номера порта в нескольких местах в наборе правил:

Когда первый и второй удары были получены, и сервер ожидает третий стук:

  • Если пакет является третьим ударом, то переход в состояние 3 (STATE 3);
  • Если пакет является первым стуком, то регресс переходит в состояние 1 (STATE 1);
  • В противном случае выполните возврат к состоянию 0 (STATE 0).
  • Как и выше, любой полученный трафик должен быть удален.

Когда все три удара были получены, и сервер ожидает соединения:

  • Если пакет является началом входящего TCP-соединения с соответствующим портом, то принимайте его;
  • Если пакет является первым стуком, то регресс переходит в состояние 1 (STATE 1);
  • В противном случае выполните возврат к состоянию 0 (STATE 0).
  • Необходимо только принять первый пакет соединения таким образом, потому что уже существует правило принимать трафик, который является частью установленного соединения. Как и выше, другой трафик следует отбросить.

Определив цепи обработчика для всех четырех состояний (3 стука + подключение), необходимо поместить правила во входящую цепочку, чтобы вызвать соответствующую цепочку обработчика. Это можно сделать, проверив, находится ли адрес источника текущего пакета в любом из трех списков:

И так. Я все рассказал, но для удобства, я вынесу все эти правила в отдельный bash-скрипт:

И вставляем его:

Ну, переходим к тестированию!

Теперь чтобы выполнить подключение (я создам скрипт для подключение), открываем файл:

И прописывам в него: