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

Мониторинг портов (ожидаемое состояние)

Монитор портов периодически сканирует список TCP-портов на хосте и сравнивает фактическое состояние с ожидаемым. Алерт уходит не тогда, когда порт «недоступен», а тогда, когда состояние расходится с тем, что вы задали:

  • ожидаемо-открытый порт вдруг закрылся (упал сервис, отвалился firewall-rule);
  • порт, который должен быть закрыт, вдруг открылся (поднялся лишний сервис, кто-то выставил БД наружу, проброс остался после деплоя).

Это инструмент про постоянство конфигурации, а не про «жив ли сервис». Вы фиксируете эталон («22 и 443 открыты, 5432 закрыт снаружи») — Notifly сигналит при любом отклонении от него.

ИнструментВопрос, на который отвечаетКогда брать
Монитор портов«Эти конкретные порты в нужном состоянии?»следить за эталоном open/closed по списку портов
Монитор kind: "tcp"«Этот один порт открыт / отвечает?»проверить доступность одного сервиса (handshake)
Сканирование портов«А что вообще открыто на хосте?»разовое или периодическое обнаружение открытых портов

Грубо: kind: "tcp" — проверка одного порта на жизнь, port-scan — разведка («покажи всё открытое»), а port-monitor — контроль того, что заранее известный набор портов держит заранее известное состояние.

  1. Раз в intervalSec Notifly подключается (TCP-handshake) к каждому порту из expectedPorts на host, по таймауту timeoutSec на порт.
  2. Каждый порт классифицируется как открыт (соединение установилось) или закрыт (отказ/таймаут).
  3. Результат сравнивается с режимом alertMode:
    • alertMode: "closed" — порты из expectedPorts должны быть открыты; алерт, когда ожидаемо-открытый порт закрылся;
    • alertMode: "open" — порты из expectedPorts должны быть закрыты; алерт, когда такой порт открылся.
  4. Когда состояние возвращается к ожидаемому — уходит recovery-сообщение (если задан recoveryMessage; пусто = recovery не слать).

Текущий снимок состояния хранится в поле lastSeenPorts (CSV вида "22,443") и обновляется на каждой проверке — по нему видно, что монитор «видит» сейчас.

  • Веб-сервер должен слушать 80 и 443. expectedPorts: "80,443", alertMode: "closed" — алерт, если упал nginx или закрылся порт.
  • БД не должна торчать наружу. expectedPorts: "5432,6379,27017", alertMode: "open" — алерт, если Postgres/Redis/Mongo внезапно доступны с публичного адреса.
  • На проде не должно быть отладочных портов. expectedPorts: "9229,5005,8000", alertMode: "open" — ловим забытый debug-порт после релиза.
ПолеТипОбязательноеОписание
appidnumberдаID канала, куда слать алерты
namestringданазвание монитора, 1–200 символов
hoststringдахост или IP (без / и пробелов), например db.example.com или 203.0.113.10
expectedPortsstringдасписок портов через запятую: "22,80,443"; каждый порт 1–65535
alertModestringда"closed" (ждём открытые порты, алерт при закрытии) или "open" (ждём закрытые порты, алерт при открытии)
intervalSecnumberдапериод проверки в секундах, 60–86400
timeoutSecnumberнеттаймаут на порт в секундах, по умолчанию 5, максимум 10
alertTitlestringнетзаголовок алерта
alertMessagestringдатекст алерта, 1–2000 символов
alertMessageMarkdownboolнеттрактовать alertMessage как Markdown
alertPrioritynumberнетприоритет 0–10 (0 = взять defaultPriority канала)
recoveryTitlestringнетзаголовок recovery-сообщения
recoveryMessagestringнеттекст recovery; пусто = recovery не отправлять

Поле status в ответе — состояние монитора: pending (создан, проверок ещё не было), up (всё в ожидаемом состоянии), down (есть отклонение, алерт отправлен) или paused (проверки отключены).

  1. Откройте app.notifly.ruМониторинг портов.
  2. Нажмите «Создать», заполните хост, список портов, режим (open/closed), интервал и текст алерта.
  3. Кнопкой «Проверить» можно прямо в диалоге увидеть, какие порты сейчас открыты/закрыты (вызов POST /port-monitor/test).

Веб-сервер должен слушать 80 и 443 — алерт, если порт закрылся:

Окно терминала
curl -X POST "$NOTIFLY_URL/port-monitor" \
-H "Content-Type: application/json" \
-H "X-Notifly-Key: <client-token>" \
-d '{
"appid": 12345,
"name": "web-1 — 80/443 должны слушать",
"host": "web-1.example.com",
"expectedPorts": "80,443",
"alertMode": "closed",
"intervalSec": 300,
"timeoutSec": 5,
"alertTitle": "Порт закрылся на web-1",
"alertMessage": "Один из ожидаемо-открытых портов (80/443) недоступен.",
"alertPriority": 8,
"recoveryMessage": "Порты web-1 снова открыты."
}'

БД не должна быть доступна снаружи — алерт, если порт открылся:

Окно терминала
curl -X POST "$NOTIFLY_URL/port-monitor" \
-H "Content-Type: application/json" \
-H "X-Notifly-Key: <client-token>" \
-d '{
"appid": 12345,
"name": "Публичный IP — БД не должна торчать",
"host": "203.0.113.10",
"expectedPorts": "5432,6379,27017",
"alertMode": "open",
"intervalSec": 600,
"alertTitle": "База доступна из интернета!",
"alertMessage": "Один из портов БД (5432/6379/27017) открыт на публичном IP.",
"alertPriority": 10
}'

В ответе придёт сохранённый объект монитора (id, status: "pending", lastSeenPorts, nextCheckAt и т. д.).

POST /port-monitor/test сканирует хост прямо сейчас и возвращает фактическое состояние — без создания монитора. Удобно, чтобы свериться с эталоном перед созданием:

Окно терминала
curl -X POST "$NOTIFLY_URL/port-monitor/test" \
-H "Content-Type: application/json" \
-H "X-Notifly-Key: <client-token>" \
-d '{ "host": "web-1.example.com", "expectedPorts": "22,80,443,5432", "timeoutSec": 5 }'

Ответ:

{ "open": [22, 80, 443], "closed": [5432] }

Если разбирать нечего, вернётся {"open": [], "closed": [], "error": "no ports to scan"}.

  • POST /port-monitor/:id/pause — отключает проверки (статус paused, следующая проверка отодвигается далеко в будущее).
  • POST /port-monitor/:id/resume — возвращает монитор в работу (статус pending, проверка планируется «на сейчас»).
Метод и путьАвторизацияНазначение
GET /port-monitorclient-tokenсписок мониторов портов
POST /port-monitorclient-token (write)создание
POST /port-monitor/testclient-tokenразовое сканирование без сохранения
PUT /port-monitor/:idclient-token (write)обновление
DELETE /port-monitor/:idclient-token (write)удалить
POST /port-monitor/:id/pauseclient-token (write)поставить на паузу
POST /port-monitor/:id/resumeclient-token (write)возобновить

Заголовок авторизации — X-Notifly-Key: <client-token>; вместо него можно использовать Basic Auth (логин/пароль от админки) или MCP-код с правом записи.