Мониторинг портов (ожидаемое состояние)
Монитор портов периодически проверяет список TCP-портов на хосте и сравнивает фактическое состояние с ожидаемым. Алерт уходит не тогда, когда порт «недоступен», а тогда, когда состояние расходится с тем, что вы задали:
- ожидаемо-открытый порт вдруг закрылся (упал сервис, отвалился firewall-rule);
- порт, который должен быть закрыт, вдруг открылся (поднялся лишний сервис, кто-то выставил БД наружу, проброс остался после деплоя).
Это инструмент про постоянство конфигурации, а не про «жив ли сервис». Вы фиксируете эталон («22 и 443 открыты» или «5432 снаружи закрыт») — Notifly сигналит при любом отклонении от него.
Чем отличается от соседних проверок
Заголовок раздела «Чем отличается от соседних проверок»| Инструмент | Вопрос, на который отвечает | Когда брать |
|---|---|---|
| Монитор портов | «Эти конкретные порты в нужном состоянии?» | следить за эталоном open/closed по списку портов |
Монитор kind: "tcp" | «Этот один порт открыт / отвечает?» | проверить доступность одного сервиса (handshake) |
| Сканирование портов | «А что вообще открыто на хосте?» | разовое или периодическое обнаружение открытых портов |
Грубо: kind: "tcp" — проверка одного порта на жизнь, port-scan — разведка
(«покажи всё открытое»), а port-monitor — контроль того, что заранее
известный набор портов держит заранее известное состояние.
Как это работает
Заголовок раздела «Как это работает»- Раз в
intervalSecNotifly открывает TCP-соединение (handshake) с каждым портом изexpectedPortsнаhost— до 16 портов параллельно, с таймаутомtimeoutSecна порт. - Порт считается открытым, если соединение установилось, и закрытым, если пришёл отказ или истёк таймаут.
- Результат сравнивается с режимом
alertMode:alertMode: "closed"— порты изexpectedPortsдолжны быть открыты; алерт, когда ожидаемо-открытый порт закрылся;alertMode: "open"— порты изexpectedPortsдолжны быть закрыты; алерт, когда такой порт открылся.
- Когда все порты возвращаются в ожидаемое состояние, монитор снова
upи (если заданrecoveryMessage) уходит сообщение о восстановлении.
Текущий снимок открытых портов хранится в поле lastSeenPorts (CSV вида
"22,443") и обновляется на каждой проверке — по нему видно, что монитор
«видит» сейчас.
Алерт и восстановление
Заголовок раздела «Алерт и восстановление»- Алерт уходит в канал
appidс заголовкомalertTitleи приоритетомalertPriority. К текстуalertMessageсервер дописывает, что именно случилось — «Закрылись ожидаемые порты: 443» или «Обнаружены открытые порты: 5432», — и строку «Хост: …». - Один алерт на падение. Пока монитор в
downи алерт уже отправлен (полеalertedAt), повторных алертов нет. Если вы измените черезPUTпараметры проверки (host,expectedPorts,alertMode,intervalSec,timeoutSec), монитор проверится сразу, а отметкаalertedAtснимется — если проблема не ушла, придёт свежий алерт. - Восстановление отправляется, только если задан
recoveryMessageи о падении действительно был отправлен алерт. Заголовок —recoveryTitle, а если он пуст —Порты восстановлены: <host>; приоритет тот же, что у алерта.
Алерты — обычные сообщения канала, поэтому на них действуют правила канала:
в тихие часы их эскалация во внешние методы доставки
подавляется, если alertPriority ниже порога прорыва (по умолчанию 8). В
активном окне обслуживания проверки идут и пишутся
в историю, но алерт о падении не отправляется — если после окна порты всё ещё
не в том состоянии, алерт придёт первой же проверкой.
Монитор портов — источник с историей проверок, поэтому он появляется на
статус-странице своего канала, а переходы up ↔ down
открывают и закрывают там авто-инциденты.
Типичные сценарии
Заголовок раздела «Типичные сценарии»- Веб-сервер должен слушать 80 и 443.
expectedPorts: "80,443",alertMode: "closed"— алерт, если упал nginx или закрылся порт. - БД не должна торчать наружу.
expectedPorts: "5432,6379,27017",alertMode: "open"— алерт, если Postgres/Redis/Mongo внезапно доступны с публичного адреса. - На проде не должно быть отладочных портов.
expectedPorts: "9229,5005,8000",alertMode: "open"— ловим забытый debug-порт после релиза.
Ограничения
Заголовок раздела «Ограничения»- Только публичные адреса. Хост, который резолвится в приватный,
loopback- или link-local-адрес (
10.x,192.168.x,127.0.0.1,169.254.xи т. п.), при создании и обновлении отклоняется с400. Та же проверка повторяется при каждом подключении: если DNS-имя позже начнёт указывать на приватный адрес, соединение будет заблокировано. - Квота. Каждая проверка монитора — одно событие дневной квоты
dailyEvents(независимо от числа портов в списке). Когда квота исчерпана, проверки откладываются до следующих суток — подробнее в Квотах и тарифах.
| Поле | Тип | Обязательное | Описание |
|---|---|---|---|
appid | number | да | ID канала, куда слать алерты (свой или расшаренный с правом отправки) |
name | string | да | название монитора, 1–200 символов |
host | string | да | хост или IP (без / и пробелов), например db.example.com или 203.0.113.10 |
expectedPorts | string | да | список портов через запятую: "22,80,443"; каждый порт 1–65535 |
alertMode | string | да | "closed" (ждём открытые порты, алерт при закрытии) или "open" (ждём закрытые порты, алерт при открытии) |
intervalSec | number | да | период проверки в секундах, 60–86400 |
timeoutSec | number | нет | таймаут на порт в секундах, по умолчанию 5, максимум 10 |
alertTitle | string | нет | заголовок алерта |
alertMessage | string | да | текст алерта, 1–2000 символов |
alertMessageMarkdown | bool | нет | трактовать текст алерта и восстановления как Markdown |
alertPriority | number | нет | приоритет алерта и восстановления, 0–10 (по умолчанию 0) |
recoveryTitle | string | нет | заголовок сообщения о восстановлении |
recoveryMessage | string | нет | текст восстановления; пусто = не отправлять |
Кроме этих полей, ответ содержит состояние монитора:
status—pending(создан или возобновлён, проверок ещё не было),up(всё в ожидаемом состоянии),down(есть отклонение или ошибка проверки) илиpaused(проверки отключены);lastSeenPorts— открытые порты на последней проверке (CSV);lastError— описание проблемы на последней проверке (пусто, если всё в порядке);lastCheckAt,nextCheckAt— время последней и следующей проверки;alertedAt— когда отправлен алерт о текущем падении (null, если алерта не было);id,created.
Создание
Заголовок раздела «Создание»Через админку
Заголовок раздела «Через админку»- Откройте app.notifly.ru → Мониторы → вкладка Порты → подвкладка Мониторы.
- Нажмите «Добавить монитор портов» (или «Создать» на странице мониторов → карточка «Открытые порты хоста»).
- Укажите название и хост, добавьте порты по одному (ввод + Enter), выберите
«Уведомлять когда»: «Порт закрыт» (
closed) или «Порт открыт» (open), таймаут на порт, интервал, канал и текст уведомления; при желании включите сообщение о восстановлении. - Кнопкой «Тест» можно прямо в диалоге увидеть, какие порты сейчас
открыты/закрыты (вызов
POST /port-monitor/test).
Монитор из админки создаётся с приоритетом 5; другой alertPriority задаётся
через API. В строке монитора есть кнопка «Просканировать все порты хоста
(Discovery)» — она открывает сканирование портов с уже
подставленным хостом. Эталон удобно получать и в обратную сторону: завершённый
скан превращается в монитор одним запросом
POST /port-scan/:id/to-monitor.
Через REST API
Заголовок раздела «Через REST API»Веб-сервер должен слушать 80 и 443 — алерт, если порт закрылся:
curl -X POST "$NOTIFLY_URL/port-monitor" \ -H "Content-Type: application/json" \ -H "X-Notifly-Key: <api-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: <api-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",
nextCheckAt и т. д.); первая проверка запланирована «на сейчас».
PUT /port-monitor/:id принимает тот же полный набор полей, что и создание
(включая appid), но канал монитора при обновлении не меняется.
Проверка без сохранения
Заголовок раздела «Проверка без сохранения»POST /port-monitor/test проверяет порты хоста прямо сейчас и возвращает
фактическое состояние — без создания монитора. Удобно, чтобы свериться с
эталоном перед созданием:
curl -X POST "$NOTIFLY_URL/port-monitor/test" \ -H "Content-Type: application/json" \ -H "X-Notifly-Key: <api-token>" \ -d '{ "host": "web-1.example.com", "expectedPorts": "22,80,443,5432", "timeoutSec": 5 }'Ответ:
{"open": [22, 80, 443], "closed": [5432]}Здесь таймаут и отказ одинаково попадают в closed, а timeoutSec вне
диапазона 1–10 заменяется на 5. Если в expectedPorts нет ни одного
корректного порта, вернётся {"open": [], "closed": [], "error": "no ports to scan"}.
История проверок
Заголовок раздела «История проверок»Каждая проверка пишется в историю: успех, длительность, текст ошибки и
метаданные — openPorts, expectedPorts, alertMode, а при отклонении ещё
missing (закрывшиеся ожидаемые порты, режим closed) или opened (открывшиеся
порты, режим open). В админке история видна в диалоге редактирования монитора:
график проверок и сетка «порт × время», где каждая клетка показывает, был ли
порт в нужном состоянии.
Через API: GET /monitor-history/port_monitor/:id — агрегированная история,
GET /monitor-history/port_monitor/:id/log?limit=50 — последние записи
(до 200) с полем metadata.
Пауза и возобновление
Заголовок раздела «Пауза и возобновление»POST /port-monitor/:id/pause— отключает проверки (статусpaused).POST /port-monitor/:id/resume— возвращает монитор в работу (статусpending, проверка планируется «на сейчас»).
REST API
Заголовок раздела «REST API»| Метод и путь | Назначение |
|---|---|
GET /port-monitor | список мониторов портов |
POST /port-monitor | создание |
POST /port-monitor/test | разовая проверка без сохранения |
PUT /port-monitor/:id | обновление |
DELETE /port-monitor/:id | удаление |
POST /port-monitor/:id/pause | поставить на паузу |
POST /port-monitor/:id/resume | возобновить |
Авторизация — заголовок X-Notifly-Key с API-токеном.
Для создания, изменения, удаления и паузы нужен токен с уровнем write
(токен read получит 403); токен со скоупом по каналам видит и меняет только
мониторы своих каналов. Токены каналов и share-токены на этих ручках не
принимаются (403).
См. также
Заголовок раздела «См. также»- Сканирование портов — обнаружение всех открытых портов на хосте.
- Мониторы — проверка доступности одного порта (
kind: "tcp") и других протоколов. - Окна обслуживания и тихие часы — когда алерты не будят.