Серверы в опасности!

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

Это может быть перебор портов с целью найти открытые от какой-то компании, которая позиционирует себя борцом за безопасность, но которая собирает статистику открытых портов на будущее по всем доступным IP (например Censys).

Может быть Shodan, который тоже собирает базу о том, где какие порты открыты, и отдаёт эту информацию любому заплатившему.

И могут быть менее известные компании, которые работают в тени. Представьте, кто-то ходит по всем домам и переписывает модели замков входных дверей, дергает за дверь и выкладывает это в публичный доступ. Дичь! Но тоже самое происходит в интернете тысячи раз в секунду. Кроме компаний могут быть бот-сети, перебирающие порты для поиска чего-то конкретного или для подготовки к целевым атакам.

Ну и собственно целевые атаки, во время которых ваши серверы в первую очередь тестируются на наличие открытых портов, а затем производятся атаки на найденные сервисы. Это может быть подбор эксплоитов для использования известных дыр или пока неизвестных 0-day, как и обычный DDoS.

Во всех этих сценариях используется предварительный перебор открытых портов. Скорее всего применение nmap или подобных утилит в каких-то скриптах.

Как защитить сервер без CloudFlare и подобных прослоек? Так как стать невидимым для Shodan, Censys и т.п.?

Противодействие

Во всех операционных системах есть фаирволы, которые позволяют использовать сложные правила и пополнять списки блокировок автоматически. Есть утилиты-надстройки вроде fail2ban, которые парсят логи и на основе сообщений от разных демонов блокируют злоумышленников, подбирающих пароли и т.п. Есть даже утилиты вроде Denyhosts, которые синхронизируют списки блокировок между юзерами, только почему-то давно не обновлялись.

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

А что, если блокировать всех, кто пытается достучаться на любой незанятый порт? Это можно сделать!

Для этого нам понадобятся:

  1. iptables (проверенный временем брандмауэр);

  2. ipset (чтобы оптимизировать работу iptables поддержкой списков);

  3. rsyslog (очень сомневаюсь, что его у вас нет).

Так какой у нас план?

  1. Настроить iptables так, чтобы он разрешал то, что должно работать, а остальное логировал с определённым тэгом.

  2. Настроить rsyslog так, чтобы он отфильтровывал сообщения по тэгу, вырезал из них адреса IP и писал их в файл/пайп.

  3. Создать список в ipset, куда мы будем наваливать адреса IP из пайпа, а iptables будет блокировать всё в этом списке.

  4. Написать софтинку, которая будет читать пайп и добавлять IP в список ipset'а.

Настройка iptables

#!/bin/bash

ipset create -exist whitelist hash:net comment
ipset create -exist blacklist hash:ip hashsize 32768 maxelem 1000000 timeout 86400

# Очищаем все правила
iptables -P INPUT ACCEPT
iptables -F INPUT

# Пропускаем все локальные соединения и уже установленные:
iptables -A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
iptables -A INPUT -i lo -j ACCEPT

# Например разрешить весь трафик из вашей корпоративной VPN и с определённых IP
iptables -A INPUT -s 10.0.0.0/24 -j ACCEPT
iptables -A INPUT -s 8.8.8.8 -j ACCEPT

# Разрешить все IP из whitelist
iptables -A INPUT -m set --match-set whitelist src -j ACCEPT

# Дропать все пакеты от IP из блэклиста
iptables -A INPUT -m set --match-set blacklist src -j DROP

# Разрешить пинги
iptables -A INPUT -p icmp --icmp-type echo-request  -j ACCEPT

# Разрешить подключения к вашему веб-серверу, так же настраиваете все остальные сервисы
iptables -A INPUT -p tcp --dport 443 -m comment --comment "nginx" -j ACCEPT

# А потом логируем всё остальное:
iptables -A INPUT -j LOG --log-prefix "iptables-log: "

Подобный скрипт надо добавить в автозагрузку любым вашим любимым способом.

Настройка rsyslog

Для того, чтобы отлавливать сообщения от брандмауэра надо настроить логгер.

Создаём файл /etc/rsyslog.d/10-iptables.conf со следующим содержанием:

$ActionQueueType Direct
$template SrcIp,"%msg:R,ERE,1:.* SRC=([0-9\.]+) --end%\n"
:msg, contains, "iptables-log: " |/var/log/iptables.pipe;SrcIp
& stop

Потом создаём пайп с помощью mkfifo /var/log/iptables.pipe и перезапускаем rsyslog (например с помощью systemctl restart rsyslog).

После этого вы можете запустить cat /var/log/iptables.pipe и ждать листинга айпи-адресов атакующих прямо в консоль. Такой вот способ медитации.

Настройка ipset

Внимательные читатели уже заметили настройку ipset в скрипте выше :)

Особое внимание только можно уделить части timeout 86400, это время в секундах, на которое у вас будут блокироваться адреса IP.

В данном примере это сутки, но можно поставить хоть час, хоть 24 дня.

Написание софтинки

Я уверен, что можно написать какой-то скрипт, перекладывающий адреса IP из пайпа в ipset хоть на баше, хоть на питоне.

Но в чём интерес защищать каждый сервер отдельно если можно защищать их все одновременно?

Если у вас несколько серверов, и на вашу инфраструктуру началась атака, то один сервер при первой же попытке сканирования сообщит всем остальным адрес злоумышленника!

Как происходит синхронизация?

Есть такая замечательная штука, называется NATS. С помощью этой системы можно организовать любую синхронизацию, обмен сообщениями между разными узлами и т.п.
Если сильно упростить, то вы выбираете канал (в терминах NATS это subject), на который подписываются все участники обмена. И так же все участники шлют в этот канал свои айпишники.

Если у вас одноранговая инфраструктура под вашим контролем, и вы доверяете всем узлам в этой сети, то всё будет работать как часы.

Но если к такой системе подключены совершенно разные клиенты, то кто-то в любом случае начнёт атаку на такую сеть. Например, с целью забанить адреса IP своих конкурентов или что-то подобное.

Мы не будем строить распределённую систему с блокчейном и консенсусом, а просто запустим центральный сервер, который будет рассылать всем клиентам IP адреса только со специально настроенных ханипотов. Конечно, мы разрешим разным серверам одного клиента обмениваться своими айпишниками без каких-либо ограничений, но остальное только от ханипотов.

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

Несколько слов о директоре и инициализации клиентов

При старте клиентов им надо откуда-то брать список активных сканеров, чтобы сразу защититься от происходящих атак.

Лучшим решением получается просто запросить список у директора через NATS, запросив по определённому каналу. Так список получится максимально актуальный.
Естественно, директор для этого хранит все айпишники в базе, привязывая их либо к клиенту, либо к ханипотам. То есть существуют списки айпишников по клиентам, и список глобальный.

Директор на запрос инициализации присылает оба списка в одном. Таким образом, когда сервер только загрузился он получает всю актуальную информацию для защиты.

Собираем всё вместе

Как оказалось, собрать всё вместе обойдясь простыми скриптами не получится. Пришлось написать полноценную программу на Rust. На данный момент это единственный эффективный способ защититься от массового скана.

Исходники, как водится, лежат на GitHub. Мы не уверены, что NATS выдержит хабра-эффект, поэтому выдаем к нему доступ по предварительной регистрации, просто по email, на который мы обещаем не слать ничего не связанного с непосредственной работой сервиса. Но адрес должен быть настоящим - на него придёт пароль для подключения к NATS.

В преимущества подключения к сервису можно добавить наличие у нас уже 13 ханипотов в разных регионах. Плюс, мы расширяем способы сбора атакующих - уже собираются IP атакующие SSH, SMTP и WordPress серверы.

На данный момент в базе уже находится свыше 570 тысяч атакующих адресов IP из совершенно разных стран. Примерно по 1800-2000 айпишников в час (включая повторяющиеся каждый час).

Статистика заблокированных IP
Статистика заблокированных IP

Планы на будущее

Очень скоро планируется закончить версию с поддержкой nftables. Чуть позже мы запустим удобный и красивый сервис для просмотра графиков атак по типам и т.п. И кроме этого, мы собираемся организовать рассылку "абузов" хостерам, чтобы они знали, что с их IP-адресов ведутся зловредные действия. Таким образом делая интернет несколько чище.

Если что-то не получается, или просто требуется дополнительная информация, добро пожаловать в наш чат в Telegram: https://t.me/diswall

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


  1. kiltum
    02.09.2022 16:39
    +1

    Совершенно бесполезная работа и трата ресурсов. Своих и чужих. Все проще.

    -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
    -A INPUT -p icmp --icmp-type echo-request -j ACCEPT
    -A INPUT -i lo -j ACCEPT
    -A INPUT -p tcp -m state --state NEW -m tcp --dport 22 -j ACCEPT
    # Что еще надо разрешить
    -A INPUT -p tcp -m state --state NEW -m tcp --dport 80 -j ACCEPT
    -A INPUT -p tcp -m state --state NEW -m tcp --dport 443 -j ACCEPT
    # Всё
    -A INPUT -j DROP
    

    Для совсем параноиков строчку 2 убрать


    1. maledog
      02.09.2022 17:21

      И будете наблюдать как по 22 порту ломятся какие-нибудь китайцы. Хоть количество новых соединений ssh ограничьте.

      можно как-то так любителей сканирования придавить
      -A INPUT -p tcp -m tcp --tcp-flags FIN,SYN,RST,ACK RST -m limit --limit 1/sec -j ACCEPT

      Между прочим любители сканировать и подбирать пароли еще не так достают, как некоторые краулеры и боты способные нехило напрячь сервер по процессору и оперативке. Потому лучше применять еще что-то вроде nginx-ultimate-bad-bot-blocker.


      1. kiltum
        02.09.2022 17:45
        +3

        Всякие лимитеры - это трата ресурсов, всякие таблицы которые могут переполниться, парсеры не туда посмотрят и так далее. Практика, которая как известно, критерий инстины, показывает, что никакой проблемы от китайцев и прочих сканеров на 22м не наблюдается. Поэтому хватает запретить логин root и логин по паролю, что бы спать спокойно и не обращать на это внимание.


        1. maledog
          02.09.2022 17:50
          +2

          Ровно до тех пор пока что-то действительно не произойдет и не понадобится разбирать логи, где будет куча "мусорных" записей.

          Попытки перебрать пароли и сканирование портов в несколько потоков по вашему не отбирает ресурсы?

          Или к примеру у вас web-приложение, которое открыто для клиентов, но совершенно не должно быть доступно ботам и злоумышленникам.


          1. kiltum
            02.09.2022 18:06
            -1

            Ровно до тех пор пока что-то действительно не произойдет и не понадобится разбирать логи, где будет куча "мусорных" записей.

            для этого есть всякие siem и прочие штуки. ну или grep на худой конец

            Попытки перебрать пароли и сканирование портов в несколько потоков по вашему не отбирает ресурсы?

            нет. пароли запрещены, а на все порты стоит DROP.

            Или к примеру у вас web-приложение, которое открыто для клиентов, но совершенно не должно быть доступно ботам и злоумышленникам.

            Для этого давно придумали кучу вариантов. Самый простой в реализации это использование сертификатов. Отстрел идет прямо на уровне ssl-stripping , не доходя до бизнес логики. Потом всякие логины, токены и прочие модные технологии. В общем, решения есть и все они работают не на уровне портов и айпи адресрв


            1. weirded
              05.09.2022 06:16

              А в софте где пароли запрещены багов не бывает, SIEM с SSL-стеком ресурсы не едят, выполняются на бесплатных ядрах которые Иисус чудом превратил из Cortex A53 в Xeon'ы, как воду в вино?:)


              1. kiltum
                05.09.2022 10:22

                все бывает. Но тут вопрос в месте траты ресурсов. Ресурсы внешнего канала и доступ по ssh гораздо критичнее ресурсов, которые жрут siem и остальные. Грубо говоря, если упадет ssh или забьется канал - то это заметят все. А если siem не попарсит логи - то только секьюрити, да и то если она есть :)


      1. kiltum
        02.09.2022 17:49
        +1

        $ sudo su -
        Last login: Mon Aug  8 17:40:41 MSK 2022 on pts/0
        Last failed login: Fri Sep  2 16:35:45 MSK 2022 from 183.250.249.170 on ssh:notty
        There were 5888 failed login attempts since the last successful login.
        

        Это с живого сервера, у которого 22й порт торчит в интернет без всяких лимитеров. За месяц 6 тыщ. У многих веб-сервер за секунду больше обрабатывает :)


  1. vilgeforce
    02.09.2022 16:44
    +2

    Не выставляйте голым портом в интернет то, что не нужно. Начинать, IMHO, нужно с этого


    1. Revertis Автор
      02.09.2022 16:47
      +1

      Тут скорее защита от такого:

      1. Бот сканит все порты, находит открытыми 80 и 443

      2. Начинает подбирать эксплоиты к http-серверу.


      1. vilgeforce
        02.09.2022 17:01

        Ну так если 80 и 443 не нужны - их не надо выставлять наружу. Если они нужны и выставлены специально - ничего не поможет


        1. SerjV
          02.09.2022 17:28
          +1

          Если они нужны и выставлены специально - ничего не поможет

          Не совсем не поможет - есть всякие IDS, IPS, WAF, UEBA и SIEM ("и много других страшных аббревиатур"). Можно, в принципе, в той же IPS сделать правило блокировки сканов портов... Можно WAF'ом защищать конкретно http/https.

          Причём в простом случае можно обойтись без колхозов, что-то из указанного выше доступно "искаропки" для большинства дистрибутивов Linux/FreeBSD или роутерных решений (при том что есть платные варианты, да, там базы побольше и пооперативнее обновляются).

          Трудно бороться с DDOS'ами. А уж с тётей SHODAN (Sentient Hyper-Optimized Data Access Network, если кто помнит :) ) уж как-нибудь можно.


      1. weirded
        03.09.2022 15:08

        Тут ведь прикол ещё что 80/443/22 проверят скорее всего первыми.


  1. maledog
    02.09.2022 17:35
    +1

    На данный момент в базе уже находится свыше 570 тысяч атакующих адресов IP из совершенно разных стран.

    Может стоит их периодически "забывать", как это делает fail2ban. Не думаю что кому-то будет интересно перебирать порты или пароли со скоростью 1 в час.


    1. Revertis Автор
      02.09.2022 17:39
      +1

      Если заглянете на сайт, то увидите, что на данный момент забанены 17к из всех.


  1. ernt
    02.09.2022 21:58

    (deleted)


  1. bdaring
    03.09.2022 09:25
    +2

    Я правильно понимаю, что любой, кто может отправить на ваш файрвол SYN-пакет с поддельным src IP, эффективно заблокирует вам любой IP, да хоть весь интернет?


    1. Revertis Автор
      03.09.2022 11:20

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


      1. weirded
        03.09.2022 15:02

        Увы, полно, недавно с этим сталкивался и это было больно. Расследовать, будучи представителем вендора, общающимся с админами провайдера, при том что бяку пропускает их вышестоящий было тяжело :)


      1. weirded
        03.09.2022 15:06

        По идее проблему IP спуфинга можно сгладить (не решить) несколькими очередями (отдельные ipset и правила -m set --match-set prev_queue -j SET --add-set next_queue) и отправлять в бан после 2-5 левых пакетов. При IP спуфинге, к слову, злоумышленник вряд ли получит ответ при сканировании. Но это отдельный вектор/цель атаки.


  1. weirded
    03.09.2022 15:00

    Замени -j LOG на -j SET --add-set blacklist и можно выкинуть сислог из схемы. А синхронизацию сделать на выхлопе ipset save blacklist. Сходу подводный камень можешь обойти – жми aggregate'ом до подсетей и префиксов, но так потребуется логика периодической перезаливки. И выстави hash:net. По maxelem и hashsize субъективный совет – лучше 1:1, в край 1:4. Коллизии в 30 штук при равномерном распределении и полном заполнении дешевле памятью закидать чем cpu, но 1 млн. счётчиков – это полужопка. 100-300к префиксов приемлемо будет, особенно вместе с аггрегейтом.

    Привет с лорша, кстати :)


  1. Alghazanth
    04.09.2022 12:46
    -1

    Полезно было бы дополнить статью конфигом nftables, идущему на замену iptables.


  1. 13werwolf13
    04.09.2022 16:09
    +1

    так вот к чему был этот опрос))


    1. Revertis Автор
      04.09.2022 16:16

      Не-не, вам показалось ;)