Как защититься от сканирования портов и Shodan?

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

Вы знали, что каждый включенный и подключенный к сети сервер постоянно подвергается атакам? Это могут быть разные атаки и с разной целью.
Это может быть перебор портов с целью найти открытые от какой-то компании, которая позиционирует себя борцом за безопасность, но которая собирает статистику открытых портов на будущее по всем доступным 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

© Habrahabr.ru