opened image

Защита от сканеров портов в Linux

Практическое руководство, как сделать так, чтобы большинство портов выглядели «filtered», легитимный трафик проходил, а попытки разведки фиксировались в логах. Основной стек — iptables + Snort

 

Зачем это нужно

 

Сканирование портов — обязательный этап разведки перед атакой. Чем меньше информации отдаёт хост (статус «filtered» вместо «open/closed»), тем сложнее злоумышленнику. При этом нам важно не сломать доступ к легитимным сервисам и получать сигналы о подозрительной активности.

 

Цель статьи:

  • Скрыть по максимуму «поверхность» хоста от сканеров.

  • Ограничить «бурст» новых соединений.

  • Логировать и быстро замечать попытки скана.

 

Что используем: iptables (classic netfilter), nmap для проверки, Snort для детектирования.

Примечание: в ряде дистрибутивов по умолчанию уже стоит nftables/firewalld. В этой статье — конфигурация на iptables. Если у вас nft, можно применить те же идеи эквивалентными правилами.

 

 

Исходные данные и допущения

 

  • Внешний интерфейс: eth0

  • Внутренний (опционально): eth1

  • Хост: 10.10.20.5

  • Админский SSH слушает порт 2222/tcp

  • Вход в SSH разрешён только из офисной сети 203.0.113.0/24

Все значения взяты «с потолка» для примеров — подставьте свои.

 

 

Базовый профиль iptables

# Очистка текущих правил (осторожно!)
iptables -F
iptables -X
iptables -t nat -F
iptables -t mangle -F

# Политики по умолчанию — сначала осторожно ACCEPT, затем ужесточим по месту
iptables -P INPUT ACCEPT
iptables -P FORWARD ACCEPT
iptables -P OUTPUT ACCEPT

# Разрешаем loopback
iptables -A INPUT -i lo -j ACCEPT
iptables -A OUTPUT -o lo -j ACCEPT

# Разрешаем ответы на исходящие (ESTABLISHED, RELATED)
iptables -A INPUT  -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
iptables -A OUTPUT -m conntrack --ctstate ESTABLISHED         -j ACCEPT

# Отбрасываем «битый» трафик
iptables -A INPUT -m conntrack --ctstate INVALID -j DROP

Если хост роутирует трафик между интерфейсами (не всем нужно):

iptables -A FORWARD -i eth1 -o eth0 -j ACCEPT
iptables -A FORWARD -i eth0 -o eth1 -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT

 

 

Анти‑скан правила по TCP‑флагам

 

Блокируем «нестандартные» комбинации (NULL/FIN/XMAS и др.), которые любят использовать сканеры.

# NULL scan
iptables -A INPUT -p tcp --tcp-flags ALL NONE -j DROP

# FIN+…
iptables -A INPUT -p tcp --tcp-flags FIN,ACK FIN -j DROP
iptables -A INPUT -p tcp --tcp-flags FIN,RST FIN,RST -j DROP

# Xmas scan (FPU)
iptables -A INPUT -p tcp --tcp-flags ALL FIN,PSH,URG -j DROP

# Комбинации SYN с RST/FIN (подозрительно)
iptables -A INPUT -p tcp --tcp-flags SYN,RST SYN,RST -j DROP
iptables -A INPUT -p tcp --tcp-flags SYN,FIN SYN,FIN -j DROP

 

 

Ограничение скорости «новых» подключений

 

Снижаем частоту создания новых TCP‑сессий с одного источника — полезно против агрессивного сканирования.

# Помечаем все новые
iptables -A INPUT -p tcp -i eth0 -m state --state NEW -m recent --set

# Если от одного IP >6 новых коннектов за 20 сек — дропаем
iptables -A INPUT -p tcp -i eth0 -m state --state NEW -m recent --update \
  --seconds 20 --hitcount 6 -j DROP

Числа 6/20 — пример. Подберите под свой профиль трафика.

 

 

Разрешения и запреты «пойнт‑ту‑пойнт»

 

Оставим доступ к SSH только из офисной сети, всё прочее — закрываем.

# Разрешаем SSH на порту 2222 из корпоративной сети
iptables -A INPUT -p tcp -s 203.0.113.0/24 --dport 2222 -i eth0 -j ACCEPT

# Остальным — нельзя
iptables -A INPUT -p tcp --dport 2222 -j DROP

 

Теперь ужесточаем политики по умолчанию:

iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -P OUTPUT ACCEPT

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

 

 

Проверяем себя nmap

 

С внешней машины (не с самого хоста):

nmap -Pn 10.10.20.5
nmap -sS 10.10.20.5
nmap -sX -p 2222 10.10.20.5   # Xmas
nmap -sN -p 2222 10.10.20.5   # Null
nmap -sF -p 2222 10.10.20.5   # Fin

Ожидания: большинство портов — filtered, SSH (2222/tcp) — open только для разрешённой подсети.

 

 

Сохранение правил после перезагрузки

 

Вариант A (Debian/Ubuntu): iptables-persistent

apt-get update && apt-get install -y iptables-persistent netfilter-persistent

 

 

 

 

netfilter-persistent save
netfilter-persistent reload

 

 

 

Вариант B: вручную

iptables-save > /etc/iptables/rules.v4
# …и затем подхватывать их в init/systemd (если настроено)

Для RHEL/Alma/Rocky можно выразить ту же логику через firewalld/rich rules или переключиться на nftables.

 

 

Детектирование сканов с помощью Snort

 

Установка (Ubuntu/Debian)

apt-get update && apt-get install -y snort
snort --version

 

Минимальные локальные правила

 

Создайте файл local.rules (путь зависит от сборки; часто /etc/snort/rules/local.rules или /usr/local/etc/rules/local.rules). Добавим базовые алерты на наш хост 10.10.20.5 и порт SSH 2222:

alert tcp any any -> 10.10.20.5 2222 (msg:"TCP Scan to SSH-alt"; flags:S; sid:1001001; rev:1;)
alert tcp any any -> 10.10.20.5 2222 (msg:"XMAS Scan"; flags:FPU; sid:1001002; rev:1;)
alert tcp any any -> 10.10.20.5 2222 (msg:"FIN Scan";  flags:F;   sid:1001003; rev:1;)
alert tcp any any -> 10.10.20.5 any  (msg:"Possible UDP Scan"; sid:1001004; rev:1;)

 

Запуск в консоль

snort -A console -q -c /etc/snort/snort.conf -i eth0

 

При срабатывании увидите сообщения в консоли/логах. Дальше можно настроить вывод в syslog и интеграции (см. ниже).

 

 

Оповещения: syslog → Telegram/Email

 

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

 

План такой:

  1. Настроить Snort на вывод в /var/log/snort/alert или syslog (/var/log/syslog).

  2. Использовать tail -F + небольшой Python/Bash‑скрипт‑парсер.

  3. Отправлять в Telegram (бот‑токен + chat_id) или email (sendmail/SMTP).

  4. Ввести порог: например, не слать алерты, пока < 3 совпадений одного источника за 60 секунд.

Бонус: можно завести fail2ban фильтр, который по определённым алертам на короткий срок банит IP (аккуратно с false positive).

 

 

 

Альтернатива: Suricata

 

Если предпочтительнее YAML‑конфиг, многопоточность «из коробки» и формат EVE JSON — используйте Suricata. Логика та же.

 

Установка (Ubuntu/Debian)

apt-get update && apt-get install -y suricata
suricata --build-info

 

Пример 1: простое правило на сканы TCP к SSH‑порту 2222 /etc/suricata/rules/local.rules:

alert tcp any any -> 10.10.20.5 2222 (msg:"SURICATA TCP scan to SSH-alt"; flags:S; sid:2001001; rev:1;)

 

Перезапуск и проверка:

suricata -T -c /etc/suricata/suricata.yaml
systemctl restart suricata
# события ищите в /var/log/suricata/eve.json

 

Пример 2: алерт на XMAS‑скан

alert tcp any any -> 10.10.20.5 2222 (msg:"SURICATA XMAS scan"; flags:FPU; sid:2001002; rev:1;)

Suricata удобно интегрируется с SIEM (EVE JSON), легко писать jq‑парсеры и метрики в Prometheus/ELK.

 

 

Чек‑лист после внедрения

 

  • Вы не отрезали себе SSH (проверить из разрешённой подсети).

  • Легитимные сервисы (HTTP/HTTPS/VPN) доступны извне.

  • nmap извне показывает filtered для ненужных портов.

  • Правила переживают перезагрузку (проверить netfilter-persistent).

  • Snort/Suricata пишет в логи и вы получаете оповещения.

  • Есть резервная копия правил firewall и базовый план отката.

 

 

Частые проблемы

 

  • Перестарались с DROP: разбираем цепочки сверху вниз, временно ставим -P INPUT ACCEPT, подключаемся по out‑of‑band доступу, правим правила, затем снова ужесточаем.

  • Включили rate‑limit и «уронили» приложение: адаптируйте --seconds/--hitcount под свой профиль трафика или отключите матчинг -m recent для нужного сервиса.

  • Не вижу алертов: проверьте интерфейс (-i eth0), пути к правилам, права на файлы, и что трафик действительно достигает хоста.

 

 

Вывод

 

Минимальный набор из iptables‑жёсткостей + Snort даёт хороший «порог боли» для порт‑сканеров и базовую наблюдаемость. Если удобнее YAML и EVE JSON — берите Suricata.

Ключевое — бережно тестировать, сохранять правила и держать под рукой план отката.