Очень простой способ прикрыть от посторонних сканеров и брутфорсеров важные сетевые порты такие как:

  • SSH
  • RDP
  • ...

Например, я сталкивался с тем, что брутфорсеры постоянно блокировали учетки в домене windows, долбясь по RDP и передавая пары логин/пароль валидных пользователей. Разумеется, DC блокирует такие учетки, пресекая брутфорс.

Можно придумать еще кучу подобных уязвимостей. И просто неприятно видеть когда на важных портах висят не понятные ESTABLISHED соединения.

Избежать таких ситуаций можно следующим образом:

iptables -A INPUT -p tcp --dport 65432 -m recent --set --name tuktuk
iptables -A INPUT -p tcp --syn --dport 22 -m recent --rcheck --seconds 160 --name tuktuk -j ACCEPT
iptables -A INPUT -p tcp --syn --dport 22 -j DROP

Вот и все!

Кто бы ни попробовал просканировать порт SSH, будет дропнут без разговоров.

Для установки соединения нужно предварительно постучаться на порт 65432.
Например из браузера (http://ваш_адрес:65432)
Или telnet ваш_адрес 65432
Или putty ваш_адрес -p 65432

И потом уже putty ваш_адрес -p 22

Мы же можем осуществлять попытки подключения из откуда угодно и при этом не хотим чтобы кто угодно мог установить соединение по Вашему важному порту?

Пользуйтесь!

Комментарии (32)


  1. tmnhy
    03.08.2017 13:14
    +10

    Пользуйтесь )))


    С разморозкой… Вы переоткрыли «Port knocking»?


  1. aaalllsss
    03.08.2017 13:16
    +1

    но ведь есть fail2ban от брутфорса? или я не прав?


    1. Ernillgeek
      03.08.2017 16:01

      Тоже зашел сказать человеку про fail2ban. Очевидно человек только из школы, сел за родительский комп, прочитал про iptables и решил поведать нам, как это круто. А что есть против брутфорса нормальные инструменты, а не засовывание головы в песок он не знает.


      1. subvillion
        04.08.2017 06:30
        -2

        А с чего вы, внезапно, решили что fail2ban может быть установлен везде? А вы в курсе, что оно на python? Это простое решение на базе нативного iptables. Что же касается школы — осталось 27 дней… Хохохо!


        1. grossws
          04.08.2017 12:35

          На python, иии? Какая разница, на чём control plane? Оно стандартно рулит iptables/firewalld и ipset


          1. subvillion
            04.08.2017 12:43

            Разница в потреблении ресурсов, особенно если это «IoT»


            1. grossws
              04.08.2017 12:51

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


              Для port knocking уже упоминали knockd (он, если что вообще на си) и вполне может быть пригоден для embedded/IoT, если нужна защита такого рода.


              1. subvillion
                04.08.2017 15:23

                А про knockd речи не было, перечитайте ветку, тут предлагали fail2ban как панацею, на очевидные недостатки которого я и указал. Честно говоря не очень понимаю в чем корявость решения? Оно может быть недостаточно гибким конкретно для Вас — а для моих задач более чем достаточное. Кстати ниже привожу 4(!) способа как блокировать подбор (на самом деле частые подключения с одного IP на порт) пароля для любого порта без использования стороннего ПО.

                1
                # iptables -A INPUT -p tcp --dport 22 -m state --state NEW -m recent --name BLOCK --update --seconds 60 --rttl --hitcount 3 -j DROP
                # iptables -A INPUT -p tcp --syn --dport 22 -j ACCEPT
                
                2
                # iptables -A INPUT -p tcp --dport 22 -m state --state NEW -m hashlimit --hashlimit-name BLOCK --hashlimit-mode srcip --hashlimit-above 2/m --hashlimit-burst 2 -j DROP
                # iptables -A INPUT -p tcp --syn --dport 22 -j ACCEPT
                
                3
                # iptables -A INPUT -p tcp --dport 22 -m state --state NEW -m connlimit ! --connlimit-above 1 -m limit --limit 2/m --limit-burst 2 -j ACCEPT
                
                4
                # iptables -A INPUT -p tcp --dport 22 -m state --state NEW -m recent --name BLOCK --rcheck --seconds 600 -j DROP
                # iptables -A INPUT -p tcp --dport 22 -m state --state NEW -m hashlimit --hashlimit-name BLOCK --hashlimit-mode srcip --hashlimit-above 2/m --hashlimit-burst 2 -m recent --name BLOCK --set -j DROP
                


                1. grossws
                  04.08.2017 16:04

                  Т. е. вполне легитимный скрипт, который что-то выполняет по ssh (например, дёргает пробники для nagios'а или что-нибудь ещё) больше условных трёх раз в минуту получает бан. Напомню, что fail2ban парсит логи, чтобы отличить легитимные ipшники от тех, с которых идёт перебор.


    1. susnake
      05.08.2017 03:00

      Я у себя настроил fail2ban + 2 Factor Authorization на рута и своего пользователя.


  1. skymal4ik
    03.08.2017 13:20
    +2

    Да, технология старая и известная :) ещё есть более безопасный вариант стучаться не на один порт, а на несколько в определённом порядке — это поможет избежать случайного открытия порта при скане портов, например.


    1. Oberon812
      04.08.2017 16:22

      Еще вариант — пинг, только меняем размер пакета и количество запросов в зависимости от, скажем, дня недели и времени суток. Собственно, в этом и прелесть порткнокинга: простор для больной фантазии творчества при минимальных затратах.


  1. freejoins
    03.08.2017 13:22
    +2

    Port Knocking, велосипедов и готовых решений на эту тему много… И даже на хабре… Да и nmap умеет определять дропнутый порт, помечая его — open|filtered, отсюда начнется сканирование всего диапазоны портов. Что при вашем решении приведет к тому что они все таки получат доступ к ssh порту и в конечном итоге будут брутфорсить. В продвинутых системах же используется последовательность портов. Причем при подключении она должна быть соблюдена.


  1. AntonCheloshkin Автор
    03.08.2017 13:25
    -5

    городить огород из последовательности — не очень удобная идея.
    и это не защита от продвинутых атак.
    весь диапазон портов ни кто не будет сканировать.


    1. Print
      03.08.2017 15:17
      +2

      Я Вам больше скажу: как только не обнаружат открытых «интересных» портов, то следующим шагом просканируют сразу все TCP, а затем и UDP порты.
      Обычная практика пентеста.


      1. AntonCheloshkin Автор
        03.08.2017 16:04

        Сколько это займет времени?
        Порт в реале шарится секунд на 10-15.
        Просканировали остальные — ни чего интересного и "окошка" уже нет.


        1. bano-notit
          03.08.2017 23:37

          Если атака целенаправленная, то время найдётся. Даже к брутфорсу прибегают, когда уже просто интересно становится узнать, что там за стеной такой неприступной.


    1. Ernillgeek
      03.08.2017 16:05
      +1

      > весь диапазон портов ни кто не будет сканировать.

      Сканируют только так.
      Почитайте про Zmap, узнаете много такого о чем вам в школе не рассказали.


  1. ifaustrue
    03.08.2017 14:43

    Вот бы была бы система, блокирующая доступ для учётной записи* (при многократных попытках доступа) более адресно (а не как это сделано в AD по умолчанию): вначале на уровне хоста\сервиса (например для RDP и только через RDP GW), потом на уровне группы сервисов\хостов (RDP+все удалённые доступы, оставляя работать почту, например), потом уже на уровне всего домена.

    Есть что-то такое в природе? Или все вынуждены выкручиваются как могут?
    *именно для учётной записи, а не для IP


    1. freejoins
      03.08.2017 15:15
      +2

      :) лучше всего вообще не вывешивать RDP голым задом в наружу. Тогда его и брутфорсить не будут! Чаще всего его прячут в DMZ, а доступ по средствам ВПН и прочих туннелей.


      1. ifaustrue
        03.08.2017 15:17

        выставить RDP через RDP GW — кажется стандартной практикой. (про ваше замечание согласен)
        Однако (даже если убрать из уравнения RDP как сервис в принципе), современные системы блокируют учётку полностью, никак не управляя вектором противодействия атаке.


        1. VitalKoshalew
          03.08.2017 15:57
          +1

          Какие именно «современные системы»? RRAS/ADFS WAP с версии 2012 R2 имеет свой отдельный lockout, RRAS VPN сто лет как свой имеет, а больше ничего в неограниченный Internet выставлять и не стоит. В мире Linux вообще уйма средств для этого.


          1. ifaustrue
            03.08.2017 16:01

            RRAS/ADFS WAP с версии 2012 R2
            — отлично, пропустил (справедливости ради, на хабре не так уж много статей на эту тему, хотя какая разница). Век живи век учись.

            Linux вообще уйма средств для этого
            — напишите плиз, с какими ключевыми словами идти в поисковик?


            1. VitalKoshalew
              04.08.2017 01:27

              fail2ban, knockd, iptables, nginix. В том числе на Хабре были статьи и обсуждения. От задачи зависит…


  1. ALexhha
    03.08.2017 22:11
    +1

    > городить огород из последовательности — не очень удобная идея.
    > и это не защита от продвинутых атак.

    ну как сказать, в том же knockd, насколько я помню, можно было сделать так, что порт открывался только если сначала было обращения на tcp/12345, а затем в течение 3 секунд на udp 54321. Подобрать такую комбинацию будет на порядок сложнее вашего примера. И да, портов может быть больше 2х.

    > весь диапазон портов ни кто не будет сканировать.

    первая ошибка админа — самоуверенность в том, что это никогда не случится. Ничего со временем проходит, как правило


  1. fugasio
    04.08.2017 16:22

    Автору, кхе-кхе, спасибо.
    Господа комментаторы, покритикуйте мой способ пожалуйста:
    Я меняю порт SSH, использую длиннющий случайный пароль и ключ для всех пользователей, поднимаю OpenVPN и закрываю ssh-порт от всех, кроме VPN-подсети. Таким образом наружу только vpn-порт(ну и пользовательские, http/https в основном). Понимаю, что таким образом начинаю зависеть от OpenVPN, потому и сомнения.


    1. grossws
      04.08.2017 17:30

      Прочитайте https://stribika.github.io/2015/01/04/secure-secure-shell.html, настройте аутентификацию по ключам и отключите password и keyboard-interactive. Менять порт необязательно, ставить security updates — обязательно.


    1. Ernillgeek
      04.08.2017 19:07
      +1

      Смена порта глупость и security through obscurity. Не надо так. Достаточно использовать авторизацию только по ключу, отключить парольную и желательно использовать логины которые не являются очевидными(но это уже не так обязательно, хватает и ключа).
      Переход на исключительно парольный ауф позволяет полностью исключить возможность брутфорса, уже нет нужды ограничивать сетями или IPшниками, главное беречь свой ключ, как самого себя.
      Детские методы с «а я сменил порт, я — кулхацкер» советуют только люди прочитавшие пару статей в сети и не понимающие что именно делают.

      Да, порт-кнокинг для ssh это такое же секурити фроуг засовывание головы в песок. Безопасности не добавляет, а неудобств да.

      При этом я поверх авторизации только по ключу еще баню всех левых используя fail2ban+ipset, но это уже просто что бы в логи не гадили.

      А! Да. И поверх всего этого у меня еще

      /etc/ssh/sshrc

      # save it as /etc/profile.d/ssh-telegram.sh
      # use sed to parse JSON from ipinfo.io
      # you can get your user_id by writing to @get_id_bot
      USERID="<target_user_id>"
      KEY="<bot_private_key>"
      TIMEOUT="10"
      URL="https://api.telegram.org/bot$KEY/sendMessage"
      DATE_EXEC="$(date "+%d %b %Y %H:%M")"
      TMPFILE='/tmp/ipinfo-$DATE_EXEC.txt'
      if [ -n "$SSH_CLIENT" ] && [ -z "$TMUX" ]; then
      	IP=$(echo $SSH_CLIENT | awk '{print $1}')
      	PORT=$(echo $SSH_CLIENT | awk '{print $3}')
      	HOSTNAME=$(hostname -f)
      	IPADDR=$(hostname -I | awk '{print $1}')
      	curl http://ipinfo.io/$IP -s -o $TMPFILE
              CITY=$(cat $TMPFILE | sed -n 's/^  "city":[[:space:]]*//p' | sed 's/"//g')
              REGION=$(cat $TMPFILE | sed -n 's/^  "region":[[:space:]]*//p' | sed 's/"//g')
              COUNTRY=$(cat $TMPFILE | sed -n 's/^  "country":[[:space:]]*//p' | sed 's/"//g')
              ORG=$(cat $TMPFILE | sed -n 's/^  "org":[[:space:]]*//p' | sed 's/"//g')
      	TEXT="$DATE_EXEC: ${USER} logged in to $HOSTNAME ($IPADDR) from $IP - $ORG - $CITY, $REGION, $COUNTRY port $PORT"
      	curl -s --max-time $TIMEOUT -d "chat_id=$USERID&disable_web_page_preview=1&text=$TEXT" $URL > /dev/null
      	rm $TMPFILE
      fi
      


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


  1. Fiery_Ice
    10.08.2017 00:26

    Все надо делать с умом, и тчательностью. Особенно закрашивать важную информацию: в нашем случае — IP адрес сервера. Собственно отправил бы в личку айпишник — чтобы понятно было — но такой опции, Хабр мне не предоставляет. Рекомендую сменить картинку по-быстрее, пока кулхацкеры не начали ваш сервер на зуб пробовать.


    1. Fiery_Ice
      10.08.2017 00:32

      И да, полагаться на авось, в IT (не закрашивать данные нормально ибо "и тааак сойдет", или верить что никто не сканирует весь диапазон портов) — очень плохой подход.


    1. AntonCheloshkin Автор
      10.08.2017 11:37

      уже все было


  1. AntonCheloshkin Автор
    10.08.2017 11:43

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