Серверы в опасности!
Вы знали, что каждый включенный и подключенный к сети сервер постоянно подвергается атакам? Это могут быть разные атаки и с разной целью.
Это может быть перебор портов с целью найти открытые от какой-то компании, которая позиционирует себя борцом за безопасность, но которая собирает статистику открытых портов на будущее по всем доступным IP (например Censys).
Может быть Shodan, который тоже собирает базу о том, где какие порты открыты, и отдаёт эту информацию любому заплатившему.
И могут быть менее известные компании, которые работают в тени. Представьте, кто-то ходит по всем домам и переписывает модели замков входных дверей, дергает за дверь и выкладывает это в публичный доступ. Дичь! Но тоже самое происходит в интернете тысячи раз в секунду. Кроме компаний могут быть бот-сети, перебирающие порты для поиска чего-то конкретного или для подготовки к целевым атакам.
Ну и собственно целевые атаки, во время которых ваши серверы в первую очередь тестируются на наличие открытых портов, а затем производятся атаки на найденные сервисы. Это может быть подбор эксплоитов для использования известных дыр или пока неизвестных 0-day, как и обычный DDoS.
Во всех этих сценариях используется предварительный перебор открытых портов. Скорее всего применение nmap
или подобных утилит в каких-то скриптах.
Как защитить сервер без CloudFlare и подобных прослоек? Так как стать невидимым для Shodan, Censys и т.п.?
Противодействие
Во всех операционных системах есть фаирволы, которые позволяют использовать сложные правила и пополнять списки блокировок автоматически. Есть утилиты-надстройки вроде fail2ban
, которые парсят логи и на основе сообщений от разных демонов блокируют злоумышленников, подбирающих пароли и т.п. Есть даже утилиты вроде Denyhosts
, которые синхронизируют списки блокировок между юзерами, только почему-то давно не обновлялись.
Проблема только в том, что это уже защита второго этапа атаки, когда открытые порты найдены.
А что, если блокировать всех, кто пытается достучаться на любой незанятый порт? Это можно сделать!
Для этого нам понадобятся:
iptables
(проверенный временем брандмауэр);ipset
(чтобы оптимизировать работуiptables
поддержкой списков);rsyslog
(очень сомневаюсь, что его у вас нет).
Так какой у нас план?
Настроить
iptables
так, чтобы он разрешал то, что должно работать, а остальное логировал с определённым тэгом.Настроить
rsyslog
так, чтобы он отфильтровывал сообщения по тэгу, вырезал из них адреса IP и писал их в файл/пайп.Создать список в
ipset
, куда мы будем наваливать адреса IP из пайпа, аiptables
будет блокировать всё в этом списке.Написать софтинку, которая будет читать пайп и добавлять 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 айпишников в час (включая повторяющиеся каждый час).
Планы на будущее
Очень скоро планируется закончить версию с поддержкой nftables
. Чуть позже мы запустим удобный и красивый сервис для просмотра графиков атак по типам и т.п. И кроме этого, мы собираемся организовать рассылку "абузов" хостерам, чтобы они знали, что с их IP-адресов ведутся зловредные действия. Таким образом делая интернет несколько чище.
Если что-то не получается, или просто требуется дополнительная информация, добро пожаловать в наш чат в Telegram: https://t.me/diswall
Комментарии (24)
vilgeforce
02.09.2022 16:44+2Не выставляйте голым портом в интернет то, что не нужно. Начинать, IMHO, нужно с этого
Revertis Автор
02.09.2022 16:47+1Тут скорее защита от такого:
Бот сканит все порты, находит открытыми 80 и 443
Начинает подбирать эксплоиты к http-серверу.
vilgeforce
02.09.2022 17:01Ну так если 80 и 443 не нужны - их не надо выставлять наружу. Если они нужны и выставлены специально - ничего не поможет
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, если кто помнит :) ) уж как-нибудь можно.
maledog
02.09.2022 17:35+1На данный момент в базе уже находится свыше 570 тысяч атакующих адресов IP из совершенно разных стран.
Может стоит их периодически "забывать", как это делает fail2ban. Не думаю что кому-то будет интересно перебирать порты или пароли со скоростью 1 в час.
bdaring
03.09.2022 09:25+2Я правильно понимаю, что любой, кто может отправить на ваш файрвол SYN-пакет с поддельным src IP, эффективно заблокирует вам любой IP, да хоть весь интернет?
Revertis Автор
03.09.2022 11:20Да, правильно. Только провайдеров, которые выпускают такие пакеты от себя почти не осталось в мире.
weirded
03.09.2022 15:02Увы, полно, недавно с этим сталкивался и это было больно. Расследовать, будучи представителем вендора, общающимся с админами провайдера, при том что бяку пропускает их вышестоящий было тяжело :)
weirded
03.09.2022 15:06По идее проблему IP спуфинга можно сгладить (не решить) несколькими очередями (отдельные ipset и правила -m set --match-set prev_queue -j SET --add-set next_queue) и отправлять в бан после 2-5 левых пакетов. При IP спуфинге, к слову, злоумышленник вряд ли получит ответ при сканировании. Но это отдельный вектор/цель атаки.
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к префиксов приемлемо будет, особенно вместе с аггрегейтом.
Привет с лорша, кстати :)
Alghazanth
04.09.2022 12:46-1Полезно было бы дополнить статью конфигом nftables, идущему на замену iptables.
kiltum
Совершенно бесполезная работа и трата ресурсов. Своих и чужих. Все проще.
Для совсем параноиков строчку 2 убрать
maledog
И будете наблюдать как по 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.
kiltum
Всякие лимитеры - это трата ресурсов, всякие таблицы которые могут переполниться, парсеры не туда посмотрят и так далее. Практика, которая как известно, критерий инстины, показывает, что никакой проблемы от китайцев и прочих сканеров на 22м не наблюдается. Поэтому хватает запретить логин root и логин по паролю, что бы спать спокойно и не обращать на это внимание.
maledog
Ровно до тех пор пока что-то действительно не произойдет и не понадобится разбирать логи, где будет куча "мусорных" записей.
Попытки перебрать пароли и сканирование портов в несколько потоков по вашему не отбирает ресурсы?
Или к примеру у вас web-приложение, которое открыто для клиентов, но совершенно не должно быть доступно ботам и злоумышленникам.
kiltum
для этого есть всякие siem и прочие штуки. ну или grep на худой конец
нет. пароли запрещены, а на все порты стоит DROP.
Для этого давно придумали кучу вариантов. Самый простой в реализации это использование сертификатов. Отстрел идет прямо на уровне ssl-stripping , не доходя до бизнес логики. Потом всякие логины, токены и прочие модные технологии. В общем, решения есть и все они работают не на уровне портов и айпи адресрв
weirded
А в софте где пароли запрещены багов не бывает, SIEM с SSL-стеком ресурсы не едят, выполняются на бесплатных ядрах которые Иисус чудом превратил из Cortex A53 в Xeon'ы, как воду в вино?:)
kiltum
все бывает. Но тут вопрос в месте траты ресурсов. Ресурсы внешнего канала и доступ по ssh гораздо критичнее ресурсов, которые жрут siem и остальные. Грубо говоря, если упадет ssh или забьется канал - то это заметят все. А если siem не попарсит логи - то только секьюрити, да и то если она есть :)
kiltum
Это с живого сервера, у которого 22й порт торчит в интернет без всяких лимитеров. За месяц 6 тыщ. У многих веб-сервер за секунду больше обрабатывает :)