diff --git a/.env.example b/.env.example index fe39057..9b84fa3 100644 --- a/.env.example +++ b/.env.example @@ -9,12 +9,20 @@ MIKROTIK_PORT=8728 MIKROTIK_USER=monitor MIKROTIK_PASSWORD=your_password +# Имя address-list из /ip firewall address-list на MikroTik +ADDRESS_LIST_NAME=monitor + # ─── Telegram ───────────────────────────────────────────────────────────────── TELEGRAM_BOT_TOKEN=123456789:AABBccDDeeFFggHH TELEGRAM_CHAT_ID=-1001234567890 +# URL API (замените на прокси если api.telegram.org заблокирован) +TELEGRAM_API_URL=https://api.telegram.org -# Имя address-list из /ip firewall address-list на MikroTik -ADDRESS_LIST_NAME=monitor +# ─── MAX (VK Teams) — опционально ──────────────────────────────────────────── +# Если не заполнены — уведомления в MAX не отправляются +MAX_BOT_TOKEN=your_max_bot_token +MAX_CHAT_ID=123456789 +MAX_API_URL=https://platform-api.max.ru # ─── Параметры мониторинга ──────────────────────────────────────────────────── CHECK_INTERVAL=60 diff --git a/README.md b/README.md index 9760e8b..a307858 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,7 @@ # 🔍 MikroTik Monitor -Мониторинг IP-адресов через MikroTik API с уведомлениями в Telegram. +Мониторинг IP-адресов через MikroTik API с уведомлениями в Telegram и MAX (VK Teams). +Список адресов берётся прямо с MikroTik из `/ip firewall address-list`. Деплой через Portainer Stack — без лишних зависимостей. --- @@ -11,11 +12,17 @@ [Docker Container] │ ├─→ Подключается к MikroTik по API (порт 8728) - │ └─→ Выполняет /ping для каждого IP из списка + │ ├─→ Читает адреса из /ip firewall address-list + │ └─→ Выполняет /ping для каждого IP │ - └─→ Если хост не отвечает N раз подряд → Telegram уведомление + ├─→ Если хост не отвечает N раз подряд → уведомление DOWN + └─→ Когда хост восстановился → уведомление UP ``` +**Уведомления отправляются параллельно в:** +- 📱 Telegram +- 💬 MAX (VK Teams) — опционально + **Логика уведомлений:** - 🔴 `DOWN` — хост не ответил `FAILURE_THRESHOLD` раз подряд - ✅ `UP` — хост восстановился после даунтайма @@ -27,7 +34,7 @@ ``` . -├── Dockerfile # Образ с встроенным скриптом +├── Dockerfile # Docker-образ ├── monitor.py # Основной скрипт мониторинга ├── stack.yml # Portainer Stack ├── .env.example # Шаблон переменных окружения @@ -40,6 +47,8 @@ ### 1. Настройте MikroTik +Включите API и создайте пользователя с минимальными правами: + ```routeros /ip service enable api @@ -47,6 +56,14 @@ /user add name=monitor password=StrongPass group=monitor ``` +Добавьте адреса для мониторинга в address-list: + +```routeros +/ip firewall address-list +add list=monitor address=192.168.1.1 comment="Роутер" +add list=monitor address=192.168.1.10 comment="Камера 1" +``` + ### 2. Создайте Telegram-бота 1. [@BotFather](https://t.me/BotFather) → `/newbot` → скопируйте токен @@ -56,7 +73,15 @@ https://api.telegram.org/bot/getUpdates ``` -### 3. Соберите Docker-образ на сервере +### 3. Создайте бота в MAX (опционально) + +1. Зайдите на [dev.max.ru](https://dev.max.ru) → создайте бота → скопируйте токен +2. Получите `chat_id` списка чатов бота: + ``` + https://platform-api.max.ru/chats?access_token= + ``` + +### 4. Соберите Docker-образ на сервере ```bash git clone https://gitea.example.com/yourname/mikrotik-monitor.git @@ -64,7 +89,7 @@ cd mikrotik-monitor docker build -t mikrotik-monitor:latest . ``` -### 4. Задеплойте через Portainer +### 5. Задеплойте через Portainer 1. **Stacks** → **Add Stack** 2. Имя: `mikrotik-monitor` @@ -76,38 +101,50 @@ docker build -t mikrotik-monitor:latest . ## Переменные окружения +### MikroTik + | Переменная | Обязательная | По умолчанию | Описание | |---|:---:|---|---| | `MIKROTIK_HOST` | ✅ | — | IP или hostname MikroTik | | `MIKROTIK_PORT` | | `8728` | API-порт (8729 для SSL) | | `MIKROTIK_USER` | ✅ | — | Логин | | `MIKROTIK_PASSWORD` | ✅ | — | Пароль | +| `ADDRESS_LIST_NAME` | ✅ | — | Имя списка в `/ip firewall address-list` | + +### Telegram + +| Переменная | Обязательная | По умолчанию | Описание | +|---|:---:|---|---| | `TELEGRAM_BOT_TOKEN` | ✅ | — | Токен бота от @BotFather | | `TELEGRAM_CHAT_ID` | ✅ | — | ID чата/группы/канала | -| `IP_LIST` | ✅ | — | Адреса через запятую | +| `TELEGRAM_API_URL` | | `https://api.telegram.org` | URL API (замените на прокси если заблокирован) | + +### MAX (VK Teams) + +| Переменная | Обязательная | По умолчанию | Описание | +|---|:---:|---|---| +| `MAX_BOT_TOKEN` | | — | Токен бота MAX | +| `MAX_CHAT_ID` | | — | ID чата в MAX | +| `MAX_API_URL` | | `https://platform-api.max.ru` | URL API MAX | + +> Если `MAX_BOT_TOKEN` или `MAX_CHAT_ID` не заданы — уведомления в MAX не отправляются. + +### Мониторинг + +| Переменная | Обязательная | По умолчанию | Описание | +|---|:---:|---|---| | `CHECK_INTERVAL` | | `60` | Интервал проверок (сек) | | `PING_COUNT` | | `3` | Кол-во пинг-пакетов | | `PING_TIMEOUT_MS` | | `1000` | Таймаут пинга (мс) | | `FAILURE_THRESHOLD` | | `2` | Провалов подряд → DOWN | | `TZ` | | `Europe/Moscow` | Временная зона | -### Рекомендуемый способ: переменные Portainer - -В `stack.yml` используйте синтаксис `${VAR}`: -```yaml -environment: - - MIKROTIK_PASSWORD=${MIKROTIK_PASSWORD} - - TELEGRAM_BOT_TOKEN=${TELEGRAM_BOT_TOKEN} -``` -Значения добавляйте в раздел **Environment variables** в UI Portainer — они хранятся зашифрованно. - --- ## Обновление ```bash -# Пересобрать образ -cd mikrotik-monitor +cd /opt/mikrotik-monitor git pull docker build -t mikrotik-monitor:latest . ``` @@ -124,9 +161,10 @@ docker logs -f mikrotik-monitor Пример вывода: ``` -2024-01-15 14:30:00 [INFO] === MikroTik Monitor запущен === -2024-01-15 14:30:00 [INFO] Хосты: ['192.168.1.1', '192.168.1.10'] -2024-01-15 14:30:01 [INFO] Подключено к MikroTik -2024-01-15 14:30:02 [INFO] ✅ 192.168.1.1 avg-rtt=0.8 ms -2024-01-15 14:30:03 [WARNING] ❌ 192.168.1.10 не отвечает (1/2) +2026-05-18 12:42:28 [INFO] === MikroTik Monitor запущен === +2026-05-18 12:42:28 [INFO] Подключено к MikroTik +2026-05-18 12:42:28 [INFO] Адресов для проверки: 3 +2026-05-18 12:42:28 [INFO] ✅ 192.168.1.1 (Роутер) avg-rtt=0.8 ms +2026-05-18 12:42:29 [INFO] ✅ 192.168.1.10 (Камера 1) avg-rtt=1.2 ms +2026-05-18 12:42:30 [WARNING] ❌ 192.168.1.20 (Камера 2) не отвечает (1/2) ```