README.md

Описание и область применения.

Программа PortsSpotter осуществляет сбор информации о заданном наборe адресов с отслеживанием их состояния путем периодического сканирования. Результаты сканирования сохраняются в базе данных.

Предназначена для инвентаризации опубликованных сетевых служб WAN/LAN с целью учета, уведомления и хранения.

Установка

  • На примере Debian-12. Ставим пакеты:
apt install -y python3-xmltodict python3-psycopg2 python3-yaml postgresql-15 nmap tcpdump
  • Авторизоваться с правами пользователя postgres, создать базу данных и пользователя для нее:
sudo -u postgres psql
postgres=# create database portsspotter;
postgres=# create user psu with encrypted password 'mypass';
postgres=# grant all privileges on database portsspotter to psu;
  • Далее необходимо переключиться в созданную базу, создать таблицы и сменить владельца на созданного пользователя (psu):
sudo -u postgres psql -d portsspotter
(выполнить команды из файла misc/db/postgres.sql)
  • Скопировать конфиг поправить пароль пользователя СУБД (если надо то и остальное) cp config.yml.example config.yml

Запуск планировщика производится командой:

root@portsspotter:~/portsspotter# ./portsspotter.py
[NOTICE] Loadingi yaml: config.yml
[NOTICE|dbconnect] База данных 'portsspotter' подключена

При необходимости запуск можно вынести под systemd используя поставляемый в комплекте unit-файл misc/portsspotter.service.

Из полезных аргументов:

  • –target CIDR - в задания будут попадать только адреса из указанной сети (полезно при отладке если адресов много)

применение

Для постановки под наблюдение необходимо добавить адреса в таблицу targets и указать поле expired равное или меньше текущего времени. Годится как прямая работа с psql так и утилита ctl.py с ключем --add

./ctl.py --add 1.1.2.0/24

Аргумент прожуется как в виде cidr так и отдельным адресом. Если указана сеть (внимание, адрес должен быть корректным адресом сети, а не произвольным адресом в ней) то она будет сконвертирована в список адресов и влит в таблицу отдельной записью на каждый адрес, при этом поле expired будет проставлено в текущее время, что вызовет немедленный запуск процедуры сбора информации.

По умолчанию планировщик раз в минуту выдает строку статистики:

scanned: 101 , error: 0 , queued: 22 , running/max: 6/20
scanned: 223 , error: 0 , queued: 23 , running/max: 4/20
scanned: 246 , error: 0 , queued: 20 , running/max: 7/20
scanned: 239 , error: 0 , queued: 22 , running/max: 6/20
scanned: 262 , error: 0 , queued: 20 , running/max: 11/20

Для большей детализации можно использовать ключ --verbose или --debug если прям по настоящему.

Если требуется повторить сканирование, можно использовать ctl.py --rescan CIDR который сбросит поле expired для адресов из сети в текущее и соответственно произведет повторный скан.

выборка результатов

Утилита report.py с параметрами –show TARGET|–audit TARGET выводит результаты последнего сканирования для адреса либо выбирает события связанные с адресом из таблицы событий. К таковым относятся переходы адреса из offline в online и обратно, а также открытие или закрытие портов. Параметр --debug выдаст в т.ч. сформатированный json последней проверки из БД. Параметр --monitor производит выборку из бд в реальном времени и выводит изменения по факту возникновения.

./report.py --monitor --monitor-delay 1
[NOTICE] Loadingi yaml: config.yml
[NOTICE|dbconnect] База данных 'portsspotter' подключена
[NOTICE|NOTICE] Monitoring with starting event id: 171848
[NOTICE|NOTICE|NOTICE] Starting with target id: 66313
MSG IP: x.x.x.43 status: online
MSG IP: x.x.x.43 New port: tcp_22
MSG IP: x.x.x.43 New port: tcp_80
MSG IP: x.x.x.43 New port: tcp_427

кастомизаия настроек по адресам

Для подмены параметров сканирования или хуков для какого-то адреса, достаточно загрузить в поле options адреса json соответствуюего формата. Например:

psql=# pupdate targets set options = '{ "scanner": { "cmd": "nmap -sS -p1-65 --min-rate 200 -oX - TARGET" } }' where ip = '1.1.1.7';

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

Распределенное сканирование

Архитектурно предусмотрено что планировщиков может быть запущено несколько на разных машинах т.к. логика выборки целей подразумевает конкурентный доступ, но на практике не проверялось так как не было такой необходимости, а без нее лень.

Работа в локальных сетях

В отличии от работы с WAN, при наблюдении локальных сетей есть возможность подсесть на ARP запросы. Для этого предназначен модуль watcher.py настраиваемый соответствующей секцией конфига. Необходимо учитывать, что свитчи могут не бросать броадкасты по всем портам и подход может потребовать доп. настроек на уровне активного оборудования.

Параметры:

  • cmd: команда выводящая arp-запросы включая mac-адреса. Желательно на уровне этой команды отфильтровать адреса которые могут порождать поток arp-запросов (в частности хост на котором запущен watcher) для снижения нагрузки на сценарий.
  • filter: фильтр сети. Только адреса попадающие в данную сеть будут рассматриваться в качестве рабочих
  • collect: False|True - заполнение базы адресов на основе arp-запросов.
  • rescan_on_mac_change: True|False - в процессе работы процесс собирает соответствие mac/ip и если зафиксированы изменения мак-адреса, это становится поводом для рескана (например dhcp-пулы)

Запуск:

root@portsspotter:~/portsspotter# ./watcher.py  
[NOTICE] Loadingi yaml: config.yml
...
[WARNING|] mac changed b6:42:6f -> dd:9c:3f for IP: x.x.x.112
[NOTICE|x.x.x.112] IP x.x.x.112 rescan performed with mac changed
[NOTICE|x.x.x.3] Arp from offline ip detected. Forcing rescan.
[NOTICE|x.x.x.1] Arp from offline ip detected. Forcing rescan.

Кроме пассивного наблюдения, при раскомментировании секции fastscan добваляется возможность инициировать быстрый опрос локальной сети на предмет живости адресов. При этом процесс с заданным интервалом будет производить опрос заданных сетей и заполнять свою базу соответствий ip/mac, а так-же инициировать процесс рескана адреса если мак на адресе сменился.

Побочным эффектом является возможность отлова дубликатов адресов если arp-reply пришел с нескольких MAC. Запись об этом будет иметь следующий вид:

[WARNING|mac_track] x.x.x.49 duplicated with dd:cc:4a

производительность

Ввиду достаточно тяжелого способа сбора информации (каждое сканирование - запуск nmap), на больших сетях (класс B) это может давать существенную нагрузку как на машину так и на сеть.

что под капотом

  • Процесс portsspotter с интервалом scheduler/idle_interval опрашивает таблицу targets на предмет записей с полем expired > текущее время.
  • Если такие записи есть, из списка выбирается случайная для которой запрашивается словарь из поля options и накладывается на поля scanner и hooks конфига. Эти настройки применяются при запуске задачи сканирования.
  • Перед запуском выполнения поле expired выбранного адреса увеличивается на scanner->timeout+60 что бы запись больше не выбиралась другими планировщиками.
  • Команда сканирования берется из scanner/cmd, где TARGET замещается адресом цели. Сам процесс запускается под утилитой timeout которая прекращает выполнение через заданное в scanner/timeout время.
  • Вывод nmap в xml конвертируется в json и грузится в таблицу events. Если хост был в сети, то expired адреса в таблице targets увеличивается на scheduler/online_refresh. В противном случае на offline_refresh.
Описание

network discovery and audit tool

Конвейеры
0 успешных
0 с ошибкой