rpi: роутер HG8245X6 — скилл router, сторож устройств и трафика, алерты home-network, дашборд home-net
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
f9d027ba86
commit
60558dc4b3
+10
-1
@@ -96,8 +96,17 @@ OneDrive на внешний HDD. Мониторится с fr1 через pushg
|
|||||||
|
|
||||||
- Постоянная сессия и журнал Поли добавлены 2026-10-11, [astra-bot `8b3400a`](https://git.ruzzy.dev/ruzzy/astra-bot/commit/8b3400a). После авторизации её чат сохраняется в state.child_chats, тред возобновляется после перезапуска; служебные slash-команды не сбрасывают разговор и не показывают справку администратора. Бот передаёт возраст и текущий chat_id в контекст, отправляет только итоговый ответ. Входящие сообщения, метаданные/пути вложений и текстовые ответы пишутся в ~/.local/share/astra-bot/conversations/<chat_id>.jsonl (файл 600, каталог 700); PDF, отправленный отдельным скриптом, в этот журнал не записывается. Имя пользователя выбирает профиль только после проверки TG_ALLOWED_IDS и не предоставляет доступ. Проверка: 37 тестов; резервный код /opt/astra-bot/bot.py.bak-20261011-child-session. ⚠️ При невозможности resume бот создаёт новый тред; локальный журнал остаётся, автоматического импорта журнала в контекст нет.
|
- Постоянная сессия и журнал Поли добавлены 2026-10-11, [astra-bot `8b3400a`](https://git.ruzzy.dev/ruzzy/astra-bot/commit/8b3400a). После авторизации её чат сохраняется в state.child_chats, тред возобновляется после перезапуска; служебные slash-команды не сбрасывают разговор и не показывают справку администратора. Бот передаёт возраст и текущий chat_id в контекст, отправляет только итоговый ответ. Входящие сообщения, метаданные/пути вложений и текстовые ответы пишутся в ~/.local/share/astra-bot/conversations/<chat_id>.jsonl (файл 600, каталог 700); PDF, отправленный отдельным скриптом, в этот журнал не записывается. Имя пользователя выбирает профиль только после проверки TG_ALLOWED_IDS и не предоставляет доступ. Проверка: 37 тестов; резервный код /opt/astra-bot/bot.py.bak-20261011-child-session. ⚠️ При невозможности resume бот создаёт новый тред; локальный журнал остаётся, автоматического импорта журнала в контекст нет.
|
||||||
|
|
||||||
|
## Роутер Huawei HG8245X6 — скилл `router` (с 2026-10-11)
|
||||||
|
- Роутер — **OptiXstar HG8245X6-10**, оптический терминал Cyta (GPON), ПО V5R022C10S110, `192.168.10.254`. Интернет — PPPoE `1_INTERNET_R_VID_42` (публичный IP динамический, на 2026-10-11 — 46.199.208.45); ещё WAN TR069, VOIP, IPTV. За LAN3 — mesh-точки M15/E15 (Wi-Fi-клиенты за ними видны как `lan3`), на LAN4 — малина.
|
||||||
|
- Управление — Codex-скилл Astra `router`, код в `ruzzy/astra-bot` (`codex/skills/router/`), команда `/usr/local/bin/router`. Креды веб-интерфейса — `/etc/router.env` (root:astra 640), в git нет. Умеет: статус/WAN, клиенты (IPv4 из аренд DHCP, сигнал Wi-Fi), трафик по интерфейсам, DHCP static add/del, проброс портов add/del (через WAN INTERNET), Wi-Fi — только чтение. Изменения — только `--yes` и кнопкой (`codex/rules/router.rules` разрешает лишь чтение).
|
||||||
|
- ⚠️ **3 неудачных входа подряд блокируют вход в роутер** (`errloginlockNum = '3'`). `login.cgi` разбирает поля позиционно — порядок как у браузера (UserName, PassWord, Language, x.X_HW_Token), иначе вход «неудачный». login не ретраится. Веб-сервер однопоточный и рвёт соединения при частых запросах — чтение ретраится с паузой; выход (`logout.cgi`) всегда отвечает обрывом, это норма. После каждой операции — выход, чтобы не забивать лимит сессий и не выбивать человека из веб-интерфейса.
|
||||||
|
- ⚠️ Трафик **по устройствам прошивка не считает** (поля `TrafficRecvRate/SendRate` всегда 0) — только по интерфейсам: `wan` (сумма GEM Ethernet), `iptv`, `lan1..4`, `wifi-2.4`, `wifi-5`.
|
||||||
|
- ⚠️ Запись Wi-Fi не сделана сознательно: SSID 2.4/5 ГГц связаны (WifiCover/band steering), запрос — десятки полей; ошибка отключит весь дом. Делать отдельно, в согласованное окно.
|
||||||
|
- `router-watch.timer` (5 мин, root): снимок `/var/lib/router-watch/state.json` (читает astra без сети), `seen.json` (все MAC с первым появлением; база — 22 устройства на 2026-10-11 15:57), `known.json` (имена от пользователя), `events.log`. Новый MAC → Telegram ботом @rasp_contol_bot с флагами (случайный MAC, ночь, без имени, ≥3 новых за час). Метрики `router_*` → pushgateway (job `router`) → алерты группы `home-network`: `RouterWatchStale` (>20 мин), `RouterDownloadSpike`/`RouterUploadSpike` (WAN: 15-мин скорость >4× средней за неделю и >5 МБ/с ↓ / >1 МБ/с ↑, 30 мин). Дашборд https://mon.ruzzy.dev/d/home-net.
|
||||||
|
- Проверено на живом роутере 2026-10-11: чтение всех разделов; `dhcp add/del` (тестовая привязка 02:00:00:00:00:01 → .250 создана и удалена), `portmap add/del` (TCP 59999 → rpi создан и удалён).
|
||||||
|
- Статическая привязка DHCP `192.168.10.25` ↔ `dc:a6:32:db:b0:f9` (малина) на роутере уже есть; ещё одна — `192.168.10.101` ↔ `8e:a9:3a:4e:69:ba`.
|
||||||
|
|
||||||
## Открытые хвосты (на 2026-10-11)
|
## Открытые хвосты (на 2026-10-11)
|
||||||
- ⏳ Закрепить `192.168.10.25` за MAC `dc:a6:32:db:b0:f9` на роутере.
|
|
||||||
- ⏳ USB3-хаб с питанием → подключить и отформатировать WD Elements 1 ТБ (вторая копия архива — сейчас копия одна).
|
- ⏳ USB3-хаб с питанием → подключить и отформатировать WD Elements 1 ТБ (вторая копия архива — сейчас копия одна).
|
||||||
- Нет node-exporter (CPU/RAM/диск самой малины в Prometheus не видны) — пуш через pushgateway для node-метрик неудобен; решить, нужен ли.
|
- Нет node-exporter (CPU/RAM/диск самой малины в Prometheus не видны) — пуш через pushgateway для node-метрик неудобен; решить, нужен ли.
|
||||||
- Первый прогон бэкапа стартовал до появления `ExecStopPost` — его итог может не дойти в метрики; `backup_last_success_timestamp` появится с первого прогона по таймеру. До этого `BackupStale` молчит (серии нет).
|
- Первый прогон бэкапа стартовал до появления `ExecStopPost` — его итог может не дойти в метрики; `backup_last_success_timestamp` появится с первого прогона по таймеру. До этого `BackupStale` молчит (серии нет).
|
||||||
|
|||||||
@@ -0,0 +1,323 @@
|
|||||||
|
{
|
||||||
|
"uid": "home-net",
|
||||||
|
"title": "Домашняя сеть (роутер)",
|
||||||
|
"tags": [
|
||||||
|
"rpi",
|
||||||
|
"router"
|
||||||
|
],
|
||||||
|
"timezone": "browser",
|
||||||
|
"schemaVersion": 39,
|
||||||
|
"refresh": "5m",
|
||||||
|
"time": {
|
||||||
|
"from": "now-24h",
|
||||||
|
"to": "now"
|
||||||
|
},
|
||||||
|
"editable": true,
|
||||||
|
"templating": {
|
||||||
|
"list": [
|
||||||
|
{
|
||||||
|
"name": "iface",
|
||||||
|
"type": "query",
|
||||||
|
"datasource": {
|
||||||
|
"type": "prometheus",
|
||||||
|
"uid": "prometheus"
|
||||||
|
},
|
||||||
|
"query": {
|
||||||
|
"query": "label_values(router_iface_bytes_total, iface)",
|
||||||
|
"refId": "i"
|
||||||
|
},
|
||||||
|
"refresh": 2,
|
||||||
|
"includeAll": true,
|
||||||
|
"multi": true,
|
||||||
|
"current": {
|
||||||
|
"text": "wan",
|
||||||
|
"value": "wan"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"panels": [
|
||||||
|
{
|
||||||
|
"id": 1,
|
||||||
|
"type": "stat",
|
||||||
|
"title": "Клиентов онлайн",
|
||||||
|
"datasource": {
|
||||||
|
"type": "prometheus",
|
||||||
|
"uid": "prometheus"
|
||||||
|
},
|
||||||
|
"gridPos": {
|
||||||
|
"x": 0,
|
||||||
|
"y": 0,
|
||||||
|
"w": 6,
|
||||||
|
"h": 4
|
||||||
|
},
|
||||||
|
"description": "",
|
||||||
|
"targets": [
|
||||||
|
{
|
||||||
|
"refId": "A",
|
||||||
|
"expr": "router_clients_online",
|
||||||
|
"instant": true,
|
||||||
|
"range": false
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"fieldConfig": {
|
||||||
|
"defaults": {},
|
||||||
|
"overrides": []
|
||||||
|
},
|
||||||
|
"options": {
|
||||||
|
"reduceOptions": {
|
||||||
|
"calcs": [
|
||||||
|
"lastNotNull"
|
||||||
|
],
|
||||||
|
"fields": "",
|
||||||
|
"values": false
|
||||||
|
},
|
||||||
|
"colorMode": "none",
|
||||||
|
"graphMode": "area",
|
||||||
|
"textMode": "value"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 2,
|
||||||
|
"type": "stat",
|
||||||
|
"title": "Онлайн без имени (не в known.json)",
|
||||||
|
"datasource": {
|
||||||
|
"type": "prometheus",
|
||||||
|
"uid": "prometheus"
|
||||||
|
},
|
||||||
|
"gridPos": {
|
||||||
|
"x": 6,
|
||||||
|
"y": 0,
|
||||||
|
"w": 6,
|
||||||
|
"h": 4
|
||||||
|
},
|
||||||
|
"description": "Устройства, которым ещё не дали имя через `router known add`.",
|
||||||
|
"targets": [
|
||||||
|
{
|
||||||
|
"refId": "A",
|
||||||
|
"expr": "router_clients_unknown_online",
|
||||||
|
"instant": true,
|
||||||
|
"range": false
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"fieldConfig": {
|
||||||
|
"defaults": {},
|
||||||
|
"overrides": []
|
||||||
|
},
|
||||||
|
"options": {
|
||||||
|
"reduceOptions": {
|
||||||
|
"calcs": [
|
||||||
|
"lastNotNull"
|
||||||
|
],
|
||||||
|
"fields": "",
|
||||||
|
"values": false
|
||||||
|
},
|
||||||
|
"colorMode": "none",
|
||||||
|
"graphMode": "area",
|
||||||
|
"textMode": "value"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 3,
|
||||||
|
"type": "stat",
|
||||||
|
"title": "Wi-Fi 2.4 ГГц",
|
||||||
|
"datasource": {
|
||||||
|
"type": "prometheus",
|
||||||
|
"uid": "prometheus"
|
||||||
|
},
|
||||||
|
"gridPos": {
|
||||||
|
"x": 12,
|
||||||
|
"y": 0,
|
||||||
|
"w": 6,
|
||||||
|
"h": 4
|
||||||
|
},
|
||||||
|
"description": "",
|
||||||
|
"targets": [
|
||||||
|
{
|
||||||
|
"refId": "A",
|
||||||
|
"expr": "router_wifi_stations{band=\"wifi-2.4\"}",
|
||||||
|
"instant": true,
|
||||||
|
"range": false
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"fieldConfig": {
|
||||||
|
"defaults": {},
|
||||||
|
"overrides": []
|
||||||
|
},
|
||||||
|
"options": {
|
||||||
|
"reduceOptions": {
|
||||||
|
"calcs": [
|
||||||
|
"lastNotNull"
|
||||||
|
],
|
||||||
|
"fields": "",
|
||||||
|
"values": false
|
||||||
|
},
|
||||||
|
"colorMode": "none",
|
||||||
|
"graphMode": "area",
|
||||||
|
"textMode": "value"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 4,
|
||||||
|
"type": "stat",
|
||||||
|
"title": "Wi-Fi 5 ГГц",
|
||||||
|
"datasource": {
|
||||||
|
"type": "prometheus",
|
||||||
|
"uid": "prometheus"
|
||||||
|
},
|
||||||
|
"gridPos": {
|
||||||
|
"x": 18,
|
||||||
|
"y": 0,
|
||||||
|
"w": 6,
|
||||||
|
"h": 4
|
||||||
|
},
|
||||||
|
"description": "",
|
||||||
|
"targets": [
|
||||||
|
{
|
||||||
|
"refId": "A",
|
||||||
|
"expr": "router_wifi_stations{band=\"wifi-5\"}",
|
||||||
|
"instant": true,
|
||||||
|
"range": false
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"fieldConfig": {
|
||||||
|
"defaults": {},
|
||||||
|
"overrides": []
|
||||||
|
},
|
||||||
|
"options": {
|
||||||
|
"reduceOptions": {
|
||||||
|
"calcs": [
|
||||||
|
"lastNotNull"
|
||||||
|
],
|
||||||
|
"fields": "",
|
||||||
|
"values": false
|
||||||
|
},
|
||||||
|
"colorMode": "none",
|
||||||
|
"graphMode": "area",
|
||||||
|
"textMode": "value"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 5,
|
||||||
|
"type": "timeseries",
|
||||||
|
"title": "Загрузка (↓ rx) по интерфейсам",
|
||||||
|
"datasource": {
|
||||||
|
"type": "prometheus",
|
||||||
|
"uid": "prometheus"
|
||||||
|
},
|
||||||
|
"gridPos": {
|
||||||
|
"x": 0,
|
||||||
|
"y": 4,
|
||||||
|
"w": 12,
|
||||||
|
"h": 9
|
||||||
|
},
|
||||||
|
"targets": [
|
||||||
|
{
|
||||||
|
"refId": "A",
|
||||||
|
"expr": "rate(router_iface_bytes_total{iface=~\"$iface\",dir=\"rx\"}[5m])",
|
||||||
|
"legendFormat": "{{iface}}"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"fieldConfig": {
|
||||||
|
"defaults": {
|
||||||
|
"unit": "Bps",
|
||||||
|
"custom": {
|
||||||
|
"lineWidth": 2,
|
||||||
|
"fillOpacity": 10,
|
||||||
|
"spanNulls": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"overrides": []
|
||||||
|
},
|
||||||
|
"options": {
|
||||||
|
"legend": {
|
||||||
|
"displayMode": "list",
|
||||||
|
"placement": "bottom"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 6,
|
||||||
|
"type": "timeseries",
|
||||||
|
"title": "Отдача (↑ tx) по интерфейсам",
|
||||||
|
"datasource": {
|
||||||
|
"type": "prometheus",
|
||||||
|
"uid": "prometheus"
|
||||||
|
},
|
||||||
|
"gridPos": {
|
||||||
|
"x": 12,
|
||||||
|
"y": 4,
|
||||||
|
"w": 12,
|
||||||
|
"h": 9
|
||||||
|
},
|
||||||
|
"targets": [
|
||||||
|
{
|
||||||
|
"refId": "A",
|
||||||
|
"expr": "rate(router_iface_bytes_total{iface=~\"$iface\",dir=\"tx\"}[5m])",
|
||||||
|
"legendFormat": "{{iface}}"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"fieldConfig": {
|
||||||
|
"defaults": {
|
||||||
|
"unit": "Bps",
|
||||||
|
"custom": {
|
||||||
|
"lineWidth": 2,
|
||||||
|
"fillOpacity": 10,
|
||||||
|
"spanNulls": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"overrides": []
|
||||||
|
},
|
||||||
|
"options": {
|
||||||
|
"legend": {
|
||||||
|
"displayMode": "list",
|
||||||
|
"placement": "bottom"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 7,
|
||||||
|
"type": "timeseries",
|
||||||
|
"title": "Клиенты онлайн",
|
||||||
|
"datasource": {
|
||||||
|
"type": "prometheus",
|
||||||
|
"uid": "prometheus"
|
||||||
|
},
|
||||||
|
"gridPos": {
|
||||||
|
"x": 0,
|
||||||
|
"y": 13,
|
||||||
|
"w": 24,
|
||||||
|
"h": 7
|
||||||
|
},
|
||||||
|
"targets": [
|
||||||
|
{
|
||||||
|
"refId": "A",
|
||||||
|
"expr": "router_clients_online",
|
||||||
|
"legendFormat": "всего"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"refId": "B",
|
||||||
|
"expr": "router_clients_unknown_online",
|
||||||
|
"legendFormat": "без имени"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"fieldConfig": {
|
||||||
|
"defaults": {
|
||||||
|
"unit": "short",
|
||||||
|
"custom": {
|
||||||
|
"lineWidth": 2,
|
||||||
|
"fillOpacity": 10,
|
||||||
|
"spanNulls": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"overrides": []
|
||||||
|
},
|
||||||
|
"options": {
|
||||||
|
"legend": {
|
||||||
|
"displayMode": "list",
|
||||||
|
"placement": "bottom"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -157,3 +157,35 @@ groups:
|
|||||||
labels: {severity: warning, instance: rpi, job: backup_router_sample}
|
labels: {severity: warning, instance: rpi, job: backup_router_sample}
|
||||||
annotations:
|
annotations:
|
||||||
summary: "rpi: ежемесячная перечитка файлов с диска роутера не отчитывалась 35+ дней — проверь router-sample"
|
summary: "rpi: ежемесячная перечитка файлов с диска роутера не отчитывалась 35+ дней — проверь router-sample"
|
||||||
|
|
||||||
|
# Домашняя сеть: роутер Huawei HG8245X6 (ONT Cyta), сторож router-watch на rpi раз в 5 мин.
|
||||||
|
# По отдельным устройствам прошивка трафик не считает — только по интерфейсам (wan, lan*, wifi-*).
|
||||||
|
- name: home-network
|
||||||
|
rules:
|
||||||
|
- alert: RouterWatchStale
|
||||||
|
expr: time() - push_time_seconds{job="router"} > 20 * 60
|
||||||
|
for: 10m
|
||||||
|
labels: {severity: warning}
|
||||||
|
annotations:
|
||||||
|
summary: "rpi: сторож роутера не присылал данных {{ $value | humanizeDuration }} — router-watch или вход на роутер сломан"
|
||||||
|
|
||||||
|
# всплеск = скорость за 15 мин в 4+ раза выше средней за неделю И выше абсолютного порога
|
||||||
|
- alert: RouterDownloadSpike
|
||||||
|
expr: |
|
||||||
|
rate(router_iface_bytes_total{iface="wan",dir="rx"}[15m]) > 5e6
|
||||||
|
and rate(router_iface_bytes_total{iface="wan",dir="rx"}[15m])
|
||||||
|
> 4 * avg_over_time(rate(router_iface_bytes_total{iface="wan",dir="rx"}[1h])[7d:1h])
|
||||||
|
for: 30m
|
||||||
|
labels: {severity: warning}
|
||||||
|
annotations:
|
||||||
|
summary: "Дом: необычно большая загрузка из интернета — {{ $value | humanize1024 }}Б/с 30+ мин. Кто качает: `router traffic --live` (по портам/Wi-Fi). Сама малина качает OneDrive/бэкапы — сверь с их расписанием."
|
||||||
|
|
||||||
|
- alert: RouterUploadSpike
|
||||||
|
expr: |
|
||||||
|
rate(router_iface_bytes_total{iface="wan",dir="tx"}[15m]) > 1e6
|
||||||
|
and rate(router_iface_bytes_total{iface="wan",dir="tx"}[15m])
|
||||||
|
> 4 * avg_over_time(rate(router_iface_bytes_total{iface="wan",dir="tx"}[1h])[7d:1h])
|
||||||
|
for: 30m
|
||||||
|
labels: {severity: warning}
|
||||||
|
annotations:
|
||||||
|
summary: "Дом: необычно большая ОТДАЧА в интернет — {{ $value | humanize1024 }}Б/с 30+ мин (облачная синхронизация, торрент или что-то подозрительное). Кто: `router traffic --live`."
|
||||||
|
|||||||
Reference in New Issue
Block a user