Перейти к содержимому

Сканирование портов (discovery)

Сканирование портов (port discovery) отвечает на вопрос «какие TCP-порты вообще открыты на этом хосте?». Notifly перебирает указанный диапазон портов, параллельно дёргает каждый и собирает список открытых. В отличие от порт-монитора, который непрерывно следит за известным набором портов, скан — это разовая (или периодическая) инвентаризация: вы ещё не знаете, что слушает на хосте, и хотите это выяснить.

Типичный путь: запустили скан → посмотрели найденные порты → одним запросом превратили результат в непрерывный порт-монитор, который будет алёртить, если какой-то из этих портов вдруг закроется.

создаёте задачу скана → status=pending
└─▶ Cloud Function port-monitor берёт задачу
└─▶ батчами продвигает cursor по диапазону [rangeFrom..rangeTo]
параллельный TCP-dial с per-port таймаутом timeoutSec
открытые порты накапливаются в foundPorts (CSV) live
└─▶ дошли до rangeTo → status=completed, push с отчётом
  • Скан выполняется serverless-функцией Notifly из Yandex Cloud, поэтому хост должен быть доступен из публичного интернета (или из приватной сети YC).
  • cursor показывает прогресс — последний просканированный порт; по нему в админке видно, на сколько процентов диапазон уже пройден.
  • foundPorts (CSV открытых портов) накапливается на лету — частичный результат виден ещё до завершения скана.
  • При повторном запуске прежний результат сохраняется в prevFoundPorts, что позволяет увидеть diff (появившиеся/исчезнувшие порты).
  • По завершении приходит обычное push-уведомление Notifly с отчётом — через тот канал (appid), который вы указали при создании.

Диапазон портов можно задать профилем (profile) — пресетом — либо вручную через rangeFrom/rangeTo. Если профиль не указан, он выводится автоматически: полный диапазон 1–65535full, иначе → quick.

profileЧто сканируетПортов
quicknmap top-100 наиболее частых TCP-портов100
standardпорты 1–1024 + популярные порты выше 1024~1080
fullвесь диапазон 1–6553565535
customпроизвольный rangeFromrangeTo (по умолчанию 1–65535)задаёте сами

Для custom диапазон берётся из ваших rangeFrom/rangeTo; для пресетных профилей сервер сам подставит нужные порты, и переданный диапазон будет переопределён.

  • name — название задачи, 1–200 символов (обязательно).
  • appid — канал/приложение, через которое придёт отчёт (обязательно).
  • host — имя хоста или IP (обязательно), без / и пробелов.
  • rangeFrom / rangeTo — границы диапазона, каждая в [1, 65535], rangeFrom ≤ rangeTo. По умолчанию 1 и 65535.
  • timeoutSec — per-port таймаут TCP-dial, по умолчанию 2, максимум 10.
  • repeatIntervalSec0 = одноразовый скан; > 0 = повторять каждые N секунд, минимум 3600 (1 час).
  • alertTitle / alertMessage / alertMessageMarkdown / alertPriority — оформление push-отчёта; alertPriority в [0, 10].

Число скан-задач в сутки ограничено вашим тарифом (portScansPerDay). Когда суточный счётчик исчерпан, создание нового скана возвращает 429:

ПланСканов в день
Free10
Pro100
Business1000

Подробнее о квотах и тарифах — Квоты и тарифы.

  1. Откройте app.notifly.ruМониторыСканирование портов.
  2. Нажмите «Просканировать хост», заполните название, хост, профиль (или ручной диапазон), таймаут и канал для отчёта.
  3. Запустите — прогресс (cursor) и найденные порты (foundPorts) обновляются в реальном времени.
Окно терминала
# Быстрый скан (top-100 портов), одноразовый
curl -X POST "$NOTIFLY_URL/port-scan" \
-H "Content-Type: application/json" \
-H "X-Notifly-Key: <client-token>" \
-d '{
"appid": 12345,
"name": "Инвентаризация prod-хоста",
"host": "prod.example.com",
"profile": "quick",
"timeoutSec": 2,
"alertTitle": "Скан завершён",
"alertMessage": "Найдены открытые порты на prod.example.com",
"alertPriority": 5
}'
Окно терминала
# Произвольный диапазон, повторять раз в сутки
curl -X POST "$NOTIFLY_URL/port-scan" \
-H "Content-Type: application/json" \
-H "X-Notifly-Key: <client-token>" \
-d '{
"appid": 12345,
"name": "Веб-порты db-хоста",
"host": "db.internal",
"profile": "custom",
"rangeFrom": 8000,
"rangeTo": 9000,
"timeoutSec": 3,
"repeatIntervalSec": 86400,
"alertMessage": "Диапазон 8000–9000 на db.internal просканирован"
}'

Ответ — созданный объект скана со status: "pending", cursor, foundPorts (пока пусто) и присвоенным id.

Окно терминала
# Список всех скан-задач
curl "$NOTIFLY_URL/port-scan" -H "X-Notifly-Key: <client-token>"
# Один скан — прогресс и найденные порты
curl "$NOTIFLY_URL/port-scan/777" -H "X-Notifly-Key: <client-token>"

В ответе смотрите status (pendingrunningcompleted/failed/cancelled), cursor (докуда дошли), foundPorts (CSV открытых портов) и prevFoundPorts (результат прошлого запуска для diff). При failed причина — в lastError.

Окно терминала
# Отменить ещё не завершённый скан (pending/running)
curl -X POST "$NOTIFLY_URL/port-scan/777/cancel" \
-H "X-Notifly-Key: <client-token>"
# Перезапустить завершённый/отменённый/упавший скан заново
curl -X POST "$NOTIFLY_URL/port-scan/777/restart" \
-H "X-Notifly-Key: <client-token>"
  • Отмена доступна только для активного скана; уже completed/cancelled скан отменить нельзя (400).
  • Перезапуск доступен для завершённого скана: предыдущий foundPorts уезжает в prevFoundPorts, cursor сбрасывается, скан стартует заново. Если скан ещё активен (running/pending) — сначала отмените его (400); если по этому хосту уже идёт другой скан — 409.
  • Редактировать настройки скана (PATCH) можно, только пока он не в статусе running.

Главная фишка discovery: завершённый скан можно одним запросом превратить в непрерывный порт-монитор. Найденные порты (foundPorts) становятся expectedPorts нового монитора в режиме closed — он будет алёртить, если любой из обнаруженных портов закроется.

Окно терминала
curl -X POST "$NOTIFLY_URL/port-scan/777/to-monitor" \
-H "Content-Type: application/json" \
-H "X-Notifly-Key: <client-token>" \
-d '{
"name": "Порты prod.example.com",
"intervalSec": 300,
"timeoutSec": 5,
"alertTitle": "Port alert: prod.example.com",
"alertMessage": "Закрылся ожидаемый порт на prod.example.com",
"alertPriority": 7
}'

Тело запроса необязательно — у каждого поля есть значение по умолчанию: name = Monitor <host>, intervalSec = 300, timeoutSec = 5, alertTitle = Port alert: <host>, alertMessage = Port closed on <host>. Монитор наследует appid и host исходного скана.

Ограничения:

  • Скан должен быть completed (иначе 400).
  • В скане должны быть найдены открытые порты — пустой foundPorts даст 400.
  • Для хоста не должно быть уже активного порт-монитора — иначе 409.

Все endpoints требуют клиентский токен (или MCP-токен с правом write); Basic Auth тоже принимается.

МетодПутьОписание
GET/port-scanСписок скан-задач пользователя
GET/port-scan/:idОдин скан: статус, прогресс (cursor), foundPorts
POST/port-scanСоздать скан (429 при превышении дневной квоты или 24ч-cooldown полного скана; 409 если для хоста уже идёт скан)
PATCH/port-scan/:idИзменить настройки (нельзя для running-скана)
DELETE/port-scan/:idУдалить скан-задачу
POST/port-scan/:id/cancelОтменить активный (pending/running) скан
POST/port-scan/:id/restartПерезапустить завершённый скан заново
POST/port-scan/:id/to-monitorСоздать порт-монитор из найденных портов