{"id":37364793,"url":"https://github.com/case211/remnawave-admin","last_synced_at":"2026-04-29T06:02:37.106Z","repository":{"id":327922117,"uuid":"1112832439","full_name":"Case211/remnawave-admin","owner":"Case211","description":"Admin Web + Bot for Remnawave Panel v.2.7.0+","archived":false,"fork":false,"pushed_at":"2026-04-28T18:48:54.000Z","size":6088,"stargazers_count":188,"open_issues_count":2,"forks_count":18,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-04-28T20:27:21.872Z","etag":null,"topics":["python","remnawave","remnawave-bot","telegrambot"],"latest_commit_sha":null,"homepage":"https://t.me/remnawave_admin","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Case211.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-12-09T06:51:12.000Z","updated_at":"2026-04-28T15:22:03.000Z","dependencies_parsed_at":"2026-03-03T20:01:18.926Z","dependency_job_id":null,"html_url":"https://github.com/Case211/remnawave-admin","commit_stats":null,"previous_names":["case211/remnawave-admin"],"tags_count":54,"template":false,"template_full_name":null,"purl":"pkg:github/Case211/remnawave-admin","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Case211%2Fremnawave-admin","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Case211%2Fremnawave-admin/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Case211%2Fremnawave-admin/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Case211%2Fremnawave-admin/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Case211","download_url":"https://codeload.github.com/Case211/remnawave-admin/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Case211%2Fremnawave-admin/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32412890,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-29T05:20:56.964Z","status":"ssl_error","status_checked_at":"2026-04-29T05:19:54.749Z","response_time":110,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["python","remnawave","remnawave-bot","telegrambot"],"created_at":"2026-01-16T04:49:57.538Z","updated_at":"2026-04-29T06:02:37.069Z","avatar_url":"https://github.com/Case211.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# 🤖 Remnawave Admin Web + Bot\n\n\u003cdiv align=\"center\"\u003e\n\n\u003cimg src=\"remnawave-admin.webp\" alt=\"Remnawave Admin\" width=\"100%\" /\u003e\n\n**Telegram-бот и веб-панель для управления панелью Remnawave**\n\n[![Docker](https://img.shields.io/badge/Docker-Ready-blue)](https://www.docker.com/)\n[![Python](https://img.shields.io/badge/Python-3.11+-green)](https://www.python.org/)\n[![License](https://img.shields.io/badge/License-MIT-yellow)](LICENSE)\n\n[English](README_EN.md) | [Русский](README.md)\n\n\u003c/div\u003e\n\n---\n\n## ✨ Возможности\n\n### 🤖 Telegram-бот\n- **👥 Пользователи** — поиск, создание, редактирование, HWID устройства, статистика, массовые операции\n- **🛰 Ноды** — просмотр, включение/выключение, перезапуск, мониторинг трафика, статистика\n- **🖥 Хосты** — просмотр, создание, редактирование, массовые операции\n- **🧰 Ресурсы** — шаблоны подписок, сниппеты, API токены, конфиги\n- **💰 Биллинг** — история платежей, провайдеры, биллинг-ноды\n- **📊 Система** — здоровье системы, статистика, трафик\n\n### 🌐 Веб-панель\n- 📊 Дашборд с обзором системы, графиками нарушений и очередью коллектора\n- 👥 Управление пользователями, нодами, хостами\n- 🛡 Просмотр нарушений с IP Lookup, inline-действиями (блокировка, сброс трафика, whitelist)\n- 🗺 Интерактивная гео-карта с детализацией по пользователям и городам\n- 📈 Расширенная аналитика — топ юзеров, тренды, трафик по нодам, P2P/Torrent детекция\n- ⚙️ Настройки с автосохранением (приоритет: БД \u003e .env \u003e по умолчанию)\n- 🔐 Авторизация: Telegram Login Widget, пароль, 2FA (TOTP) + RBAC (роли и права)\n- 🤖 Автоматизации — конструктор правил с шаблонами, расписанием и логами выполнения\n- 🚫 Управление заблокированными IP — bulk-импорт/экспорт, срок действия\n- 🖥 Терминал — удалённое выполнение команд на нодах через xterm.js\n- 📜 Каталог скриптов — выполнение на нодах через Agent v2 WebSocket\n- 🗄 Бэкапы базы данных — создание, восстановление, управление из UI\n- 📋 Аудит-лог — полная история действий администраторов\n- 🔑 API-ключи — генерация долгоживущих токенов для внешних интеграций\n- 🎨 6 тёмных тем + 1 светлая, адаптивный дизайн\n- 🌍 Полная интернационализация (русский / английский)\n- 🔔 Система уведомлений с настраиваемой маршрутизацией по топикам\n\n### 🛡 Anti-Abuse система\n- 🔍 Многофакторный анализ подключений (временной, географический, ASN, профиль, устройства)\n- 🌍 Детекция «невозможных путешествий», распознавание 60+ российских агломераций\n- ⚡ Автоматические действия по порогам скоринга\n- 🔥 Мониторинг скорости потребления трафика с настраиваемыми порогами\n- 🧲 P2P/Torrent детекция и аналитика (интеграция с torrent-blocker)\n- 📡 Интеграция с [Node Agent](node-agent/README.md) для сбора данных\n\n### 📧 Встроенный почтовый сервер\n- 📤 Прямая MX-доставка без внешних SMTP-провайдеров\n- 🔏 DKIM-подпись (RSA-2048) + автоматическая проверка SPF/DKIM/DMARC\n- 📥 Приём входящих писем (встроенный SMTP-сервер)\n- 📊 Очередь отправки с повторами, rate limiting и мониторингом\n- ✍️ Встроенный compose-редактор + inbox-просмотрщик\n\n### 💰 Интеграция с Bedolaga Bot\n- 📊 Дашборд с метриками CRM\n- 👥 Управление клиентами и подписками\n- 🎫 Промокоды и реферальная система\n- 📈 Маркетинговая аналитика\n\n### 🔧 Дополнительно\n- 🏗 Поддержка ARM64 (aarch64) — Docker-образы для `linux/amd64` и `linux/arm64`\n- ⚙️ Динамические настройки без перезапуска (Telegram и веб-панель)\n- 🔔 Webhook-уведомления с маршрутизацией по топикам\n- 📝 Динамическое логирование: смена уровня, ротация, настройка размера файлов\n- 🌍 Русский и английский языки\n- 🗄 PostgreSQL с graceful degradation (работает и без БД)\n- 🧪 Тестовая инфраструктура: Playwright E2E, CI/CD workflows\n- 🔌 Внешний API (`/api/v3`) для сторонних интеграций\n\n---\n\n## 💻 Системные требования\n\n| Параметр | До 1 000 юзеров | 1 000–5 000 | 5 000–20 000 | 20 000+ |\n|----------|----------------|-------------|--------------|---------|\n| **CPU** | 1 vCPU | 2 vCPU | 4 vCPU | 4–8 vCPU |\n| **RAM** | 1 GB | 2 GB | 4 GB | 8+ GB |\n| **Диск** | 10 GB SSD | 20 GB SSD | 40 GB NVMe | 80+ GB NVMe |\n| **PostgreSQL** | По умолч. | Tuning рекомендуется | Tuning обязателен | Dedicated DB |\n\n\u003e **Примечания:**\n\u003e - Указаны требования для бота + веб-панели + PostgreSQL на одном сервере\n\u003e - При 5 000+ юзерах рекомендуется включить MaxMind GeoIP (локальная БД вместо ip-api.com)\n\u003e - При 20 000+ юзерах рекомендуется вынести PostgreSQL на отдельный сервер\n\u003e - Node Agent на каждой ноде потребляет ~50 MB RAM\n\n---\n\n## 🚀 Быстрый старт\n\n### 📋 Что понадобится перед началом\n\n| Что | Где взять |\n|-----|-----------|\n| 🐳 **Docker** + **Docker Compose** | [docker.com](https://www.docker.com/) |\n| 🤖 **Токен Telegram-бота** | Создайте бота у [@BotFather](https://t.me/BotFather) → `/newbot` → скопируйте токен |\n| 🔑 **API-токен Remnawave** | Панель Remnawave → Настройки → API → скопируйте токен |\n| 🆔 **Ваш Telegram ID** | Напишите [@userinfobot](https://t.me/userinfobot) → он пришлёт ваш числовой ID |\n| 🆔 **2 A-записи** | Запись для Webhook (Bot) + Запись для Web |\n\n---\n\n### Шаг 1️⃣ — Клонируйте репозиторий\n\n```bash\ngit clone https://github.com/case211/remnawave-admin.git\ncd remnawave-admin\n```\n\n### Шаг 2️⃣ — Создайте файл `.env`\n\n```bash\ncp .env.example .env\nnano .env          # или vim, или любой редактор\n```\n\nЗаполните **обязательные** поля (без них бот не запустится):\n\n```env\n# 🤖 Токен бота (из @BotFather)\nBOT_TOKEN=1234567890:ABCdefGHIjklmNOPqrstUVWxyz\n\n# 🌐 Адрес API Remnawave\n# Если бот и панель в одной Docker-сети:\nAPI_BASE_URL=http://remnawave:3000\n# Если панель на другом сервере:\n# API_BASE_URL=https://panel.yourdomain.com\n\n# 🔑 API-токен из панели Remnawave\nAPI_TOKEN=ваш_токен_из_панели\n\n# 👤 Telegram ID администраторов (через запятую)\nADMINS=123456789\n```\n\nНастройте **базу данных** (PostgreSQL поднимается автоматически в Docker):\n\n```env\n# 🗄 PostgreSQL — придумайте пароль\nPOSTGRES_USER=remnawave\nPOSTGRES_PASSWORD=придумайте_надёжный_пароль\nPOSTGRES_DB=remnawave_bot\n\n# ⚠️ Пароль тут должен совпадать с POSTGRES_PASSWORD выше!\nDATABASE_URL=postgresql://remnawave:придумайте_надёжный_пароль@remnawave-admin-db:5432/remnawave_bot\n```\n\n### Шаг 3️⃣ — Запустите бота\n\n```bash\n# Создайте Docker-сеть (один раз)\ndocker network create remnawave-network\n\n# Скачайте образы и запустите\ndocker compose up -d\n\n# Проверьте, что всё работает\ndocker compose logs -f bot\n```\n\n✅ **Готово!** Откройте бота в Telegram и отправьте `/start`.\n\n---\n\n### Шаг 4️⃣ — Веб-панель\n\nДобавьте в `.env`:\n\n```env\n# 🌐 Веб-панель\n# Секретный ключ для JWT-сессий (сгенерируйте: openssl rand -hex 32)\nWEB_SECRET_KEY=сгенерированный_ключ_минимум_32_символа\n\n# Username бота (без @) — нужен для Telegram Login Widget\nTELEGRAM_BOT_USERNAME=your_bot_username\n\n# Домен веб-панели (для CORS)\nWEB_CORS_ORIGINS=https://admin.yourdomain.com\n\n# (Опционально) Секретный путь — панель будет доступна по /ваш-путь/\n# WEB_SECRET_PATH=my-secret-path\n```\n\n\u003e 💡 **Авторизация**: При первом входе создайте аккаунт администратора. Поддерживается вход через Telegram Login Widget и по паролю. Можно включить 2FA (TOTP). Система RBAC позволяет создавать роли с гранулярными правами доступа.\n\nВеб-панель запускается вместе с ботом:\n\n```bash\ndocker compose up -d\n```\n\nПорты: **frontend :3000**, **backend :8081**.\n\n\u003e 📖 Подробнее о настройке домена и реверс-прокси: [web/README.md](web/README.md)\n\n---\n\n### Шаг 5️⃣ — Webhook-уведомления (опционально)\n\nЧтобы бот присылал уведомления при изменениях в панели — добавьте в `.env`:\n\n```env\n# 🔔 Чат для уведомлений\nNOTIFICATIONS_CHAT_ID=-1001234567890    # ID вашей группы/канала\n\n# 🔐 Секрет для webhook (сгенерируйте: openssl rand -hex 64)\nWEBHOOK_SECRET=ваш_секретный_ключ\n```\n\nЗатем в **панели Remnawave** укажите:\n- **WEBHOOK_URL** = `http://bot:8080/webhook` (если в одной Docker-сети)\n- **WEBHOOK_SECRET_HEADER** = тот же ключ, что и `WEBHOOK_SECRET` в `.env` бота\n\n\u003e 📖 Подробная инструкция с примерами nginx/Caddy: [WEBHOOK_SETUP.md](WEBHOOK_SETUP.md)\n\n---\n\n### Шаг 6️⃣ — Уведомления по топикам (опционально)\n\nЕсли у вас группа-форум в Telegram, можно разделить уведомления по топикам:\n\n```env\nNOTIFICATIONS_TOPIC_USERS=456       # 👥 События пользователей\nNOTIFICATIONS_TOPIC_NODES=789       # 🛰 События нод\nNOTIFICATIONS_TOPIC_SERVICE=101     # ⚙️ Сервисные события\nNOTIFICATIONS_TOPIC_HWID=102        # 💻 HWID устройства\nNOTIFICATIONS_TOPIC_CRM=103         # 💰 Биллинг\nNOTIFICATIONS_TOPIC_ERRORS=104      # ❌ Ошибки\nNOTIFICATIONS_TOPIC_VIOLATIONS=105  # 🛡 Нарушения\n```\n\n\u003e 💡 Если топик не указан — уведомление уйдёт в `NOTIFICATIONS_TOPIC_ID` (общий fallback).\n\n---\n\n### Шаг 7️⃣ — Встроенный почтовый сервер (опционально)\n\nВеб-панель включает встроенный почтовый сервер с DKIM-подписью, прямой MX-доставкой и приёмом входящих писем — без внешних SMTP-провайдеров.\n\n#### Включение\n\nПерейдите в **Settings** в веб-панели → секция **\"Почтовый сервер\"** → включите **\"Почтовый сервер включён\"**. Перезапустите контейнер.\n\nИли через `.env`:\n\n```env\nMAIL_SERVER_ENABLED=true\nMAIL_INBOUND_PORT=2525          # Порт приёма входящих (по умолчанию 2525)\nMAIL_SERVER_HOSTNAME=0.0.0.0    # IP для SMTP-сервера\n```\n\n\u003e 💡 Все настройки можно менять из веб-интерфейса (Settings), `.env` — как fallback.\n\n#### Добавление домена\n\n1. Перейдите в **Mail Server** → вкладка **Domains** → **Add Domain**\n2. Введите ваш домен (например `example.com`)\n3. Система автоматически сгенерирует DKIM-ключи (RSA-2048)\n\n#### Настройка DNS\n\nНажмите **\"DNS Records\"** у домена — система покажет 4 записи для добавления у DNS-провайдера:\n\n| Тип | Хост | Назначение |\n|-----|------|-----------|\n| **MX** | `example.com` | Направляет входящую почту на ваш сервер |\n| **TXT** | `example.com` | SPF — разрешает вашему IP отправлять почту |\n| **TXT** | `rw._domainkey.example.com` | DKIM — подпись для верификации |\n| **TXT** | `_dmarc.example.com` | DMARC — политика для неверифицированных писем |\n\nЗначения можно скопировать из интерфейса. После добавления нажмите **\"Check DNS\"** для проверки.\n\n#### Сетевые порты\n\n```\nПорт 25  — исходящий (для прямой доставки на MX-серверы получателей)\nПорт 2525 — входящий (приём писем, настраивается)\n```\n\nВ `docker-compose.yml` добавьте:\n\n```yaml\nports:\n  - \"25:2525\"    # входящая почта\n```\n\n\u003e ⚠️ Многие облачные хостинги (AWS, GCP, Azure) блокируют порт 25. Используйте VPS с открытым портом 25 (Hetzner, OVH, DigitalOcean).\n\n#### За reverse proxy (nginx, Caddy, Traefik)\n\nВеб-панель (HTTP API) проходит через reverse proxy как обычно — эндпоинты `/api/v2/mailserver/*` работают без дополнительных настроек.\n\n**SMTP — отдельный протокол**, он **не может** проксироваться через HTTP reverse proxy. Два варианта:\n\n**Вариант 1 — Прямой проброс порта (рекомендуется):**\n\n```yaml\n# docker-compose.yml — SMTP-порт минует proxy\nservices:\n  remnawave-admin:\n    ports:\n      - \"25:2525\"    # входящая почта напрямую\n```\n\n**Вариант 2 — nginx stream proxy (TCP):**\n\n```nginx\n# Отдельный блок stream {}, НЕ внутри http {}\nstream {\n    server {\n        listen 25;\n        proxy_pass remnawave-admin:2525;\n    }\n}\n```\n\n**Вариант 3 — Caddy L4 (TCP proxy):**\n\nДля TCP-проксирования Caddy нужен плагин [caddy-l4](https://github.com/mholt/caddy-l4):\n\n```json\n{\n  \"apps\": {\n    \"layer4\": {\n      \"servers\": {\n        \"smtp\": {\n          \"listen\": [\":25\"],\n          \"routes\": [{\n            \"handle\": [{\n              \"handler\": \"proxy\",\n              \"upstreams\": [{\"dial\": [\"remnawave-admin:2525\"]}]\n            }]\n          }]\n        }\n      }\n    }\n  }\n}\n```\n\nИли через Caddyfile (с `caddy-l4`):\n\n```caddyfile\n:25 {\n    route {\n        proxy remnawave-admin:2525\n    }\n}\n```\n\n**Схема подключения:**\n\n```\nИнтернет\n  │\n  ├── :443 (HTTPS) → nginx/Caddy → :8081 (веб-панель API)\n  │                              → :3000 (веб-панель frontend)\n  │\n  └── :25  (SMTP)  → напрямую   → :2525 (встроенный SMTP-сервер)\n```\n\n**Важно:**\n- MX, SPF, PTR записи должны указывать на **публичный IP** вашего сервера\n- PTR-запись (reverse DNS) настраивается у хостера — улучшает доставляемость\n- Если proxy и приложение на одной машине — просто пробросьте порт 25/2525 в docker-compose мимо nginx\n\n#### Проверка\n\n1. Активируйте домен (переключатель в карточке домена)\n2. Перейдите на вкладку **Compose** → выберите домен → введите адрес → **Send Test**\n3. Проверьте вкладку **Queue** — статус должен стать `sent`\n\n\u003e 📬 Если настроен активный домен, система уведомлений автоматически использует встроенный сервер (fallback на SMTP relay).\n\n---\n\n### Шаг 8️⃣ — Node Agent (опционально)\n\nДля работы Anti-Abuse системы необходимо установить **Node Agent** на каждую ноду. Агент собирает данные о подключениях из логов Xray и отправляет их в Web Backend. Также поддерживает Command Channel (удалённый терминал и выполнение скриптов).\n\n**Быстрая установка (одна команда):**\n\n1. Откройте веб-панель → **Ноды** → выберите ноду → **Токен агента** → **Установить агент**\n2. Скопируйте готовую команду и выполните на ноде:\n\n```bash\ncurl -sSL https://raw.githubusercontent.com/Case211/remnawave-admin/main/node-agent/install.sh | bash -s -- --uuid UUID --url URL --token TOKEN\n```\n\nСкрипт автоматически создаст директорию, скачает `docker-compose.yml`, сгенерирует `.env` и запустит агент.\n\n**Ручная установка:**\n\n```bash\nmkdir -p /opt/remnawave-node-agent \u0026\u0026 cd /opt/remnawave-node-agent\ncurl -sLO https://raw.githubusercontent.com/Case211/remnawave-admin/main/node-agent/docker-compose.yml\nnano .env  # Вставьте переменные из веб-панели\ndocker compose up -d\n```\n\n\u003e 📖 Подробная документация: [node-agent/README.md](node-agent/README.md) — режимы парсинга, Command Channel (терминал/скрипты), миграция, troubleshooting.\n\n---\n\n## 💻 Локальная разработка\n\n```bash\npython -m venv .venv\nsource .venv/bin/activate\npip install -r requirements.txt\ncp .env.example .env\n# Отредактируйте .env: API_BASE_URL=https://ваш-домен-панели.com\npython -m src.main\n```\n\n---\n\n## ⚙️ Справочник переменных окружения\n\n### Основные\n\n| Переменная | Обяз. | По умолч. | Описание |\n|------------|-------|-----------|----------|\n| `BOT_TOKEN` | ✅ | — | Токен Telegram-бота |\n| `API_BASE_URL` | ✅ | — | URL API Remnawave |\n| `API_TOKEN` | ✅ | — | Токен аутентификации API |\n| `ADMINS` | ✅ | — | ID администраторов через запятую |\n| `DEFAULT_LOCALE` | — | `ru` | Язык (`ru` / `en`) |\n| `LOG_LEVEL` | — | `INFO` | Уровень логирования |\n\n### 🗄 База данных\n\n| Переменная | Обяз. | По умолч. | Описание |\n|------------|-------|-----------|----------|\n| `POSTGRES_USER` | ✅ | — | Пользователь PostgreSQL |\n| `POSTGRES_PASSWORD` | ✅ | — | Пароль PostgreSQL |\n| `POSTGRES_DB` | ✅ | — | Имя базы данных |\n| `DATABASE_URL` | ✅ | — | URL подключения к PostgreSQL |\n| `SYNC_INTERVAL_SECONDS` | — | `300` | Интервал синхронизации с API (сек) |\n\n### 🔔 Уведомления\n\n| Переменная | Описание |\n|------------|----------|\n| `NOTIFICATIONS_CHAT_ID` | ID группы/канала |\n| `NOTIFICATIONS_TOPIC_ID` | Общий топик (fallback) |\n| `NOTIFICATIONS_TOPIC_USERS` | Топик для пользователей |\n| `NOTIFICATIONS_TOPIC_NODES` | Топик для нод |\n| `NOTIFICATIONS_TOPIC_SERVICE` | Сервисные уведомления |\n| `NOTIFICATIONS_TOPIC_HWID` | HWID уведомления |\n| `NOTIFICATIONS_TOPIC_CRM` | Биллинг уведомления |\n| `NOTIFICATIONS_TOPIC_ERRORS` | Ошибки |\n| `NOTIFICATIONS_TOPIC_VIOLATIONS` | Нарушения |\n\n### 🔗 Webhook\n\n| Переменная | По умолч. | Описание |\n|------------|-----------|----------|\n| `WEBHOOK_SECRET` | — | Ключ проверки webhook (HMAC-SHA256) |\n| `WEBHOOK_PORT` | `8080` | Порт webhook сервера |\n\n### 🌍 GeoIP (MaxMind GeoLite2)\n\n| Переменная | Обяз. | По умолч. | Описание |\n|------------|-------|-----------|----------|\n| `MAXMIND_LICENSE_KEY` | — | — | Лицензионный ключ MaxMind (бесплатно). Если указан — базы скачиваются автоматически |\n| `MAXMIND_CITY_DB` | — | `/app/geoip/GeoLite2-City.mmdb` | Путь к базе GeoLite2-City |\n| `MAXMIND_ASN_DB` | — | `/app/geoip/GeoLite2-ASN.mmdb` | Путь к базе GeoLite2-ASN |\n\n\u003e **Без MaxMind** — используется ip-api.com (бесплатный, но ограничен ~1000 запросов/день).\n\u003e **С MaxMind** — локальная база, мгновенные lookup'ы, без лимитов.\n\u003e\n\u003e Как подключить:\n\u003e 1. Зарегистрируйтесь на [maxmind.com/en/geolite2/signup](https://www.maxmind.com/en/geolite2/signup) (бесплатно)\n\u003e 2. Account → Manage License Keys → Generate New License Key\n\u003e 3. Добавьте в `.env`: `MAXMIND_LICENSE_KEY=ваш_ключ`\n\u003e 4. Базы скачаются автоматически при старте и обновляются каждые 24 часа\n\n### 🌐 Веб-панель\n\n| Переменная | Обяз.* | По умолч. | Описание |\n|------------|--------|-----------|----------|\n| `WEB_SECRET_KEY` | ✅ | — | Секретный ключ JWT |\n| `TELEGRAM_BOT_USERNAME` | ✅ | — | Username бота (без @) |\n| `WEB_CORS_ORIGINS` | — | — | Разрешённые домены (CORS) |\n| `WEB_JWT_EXPIRE_MINUTES` | — | `30` | Время жизни access token (мин) |\n| `WEB_JWT_REFRESH_HOURS` | — | `6` | Время жизни refresh token (ч) |\n| `WEB_BACKEND_PORT` | — | `8081` | Порт бэкенда |\n| `WEB_FRONTEND_PORT` | — | `3000` | Порт фронтенда |\n| `WEB_ALLOWED_IPS` | — | — | Белый список IP (CIDR) |\n| `WEB_SECRET_PATH` | — | — | Секретный префикс URL панели |\n| `WEB_ADMIN_LOGIN` | — | — | Логин администратора (fallback) |\n| `WEB_ADMIN_PASSWORD` | — | — | Пароль администратора (fallback) |\n| `EXTERNAL_API_ENABLED` | — | `false` | Включить внешний API (`/api/v3`) |\n| `EXTERNAL_API_DOCS` | — | `false` | Swagger UI для внешнего API |\n\n### 💰 Bedolaga Bot (опционально)\n\n| Переменная | По умолч. | Описание |\n|------------|-----------|----------|\n| `BEDOLAGA_API_URL` | — | URL API Bedolaga Bot |\n| `BEDOLAGA_API_TOKEN` | — | Токен аутентификации Bedolaga |\n\n*\\* Обязательно для работы веб-панели*\n\n### 📧 Почтовый сервер\n\n| Переменная | По умолч. | Описание |\n|------------|-----------|----------|\n| `MAIL_SERVER_ENABLED` | `false` | Включить встроенный почтовый сервер |\n| `MAIL_INBOUND_PORT` | `2525` | Порт входящего SMTP-сервера |\n| `MAIL_SUBMISSION_PORT` | `587` | Порт SMTP submission |\n| `MAIL_SERVER_HOSTNAME` | `0.0.0.0` | IP для SMTP-сервера |\n\n\u003e 💡 Эти переменные — fallback. Настройки можно менять из веб-панели (Settings → Почтовый сервер).\n\n---\n\n## 🤖 Команды бота\n\n| Команда | Описание |\n|---------|----------|\n| `/start` | Главное меню |\n| `/help` | Справка |\n| `/health` | Статус системы |\n| `/stats` | Статистика панели |\n| `/bandwidth` | Статистика трафика |\n| `/config` | Динамические настройки |\n| `/user \u003cusername\\|id\u003e` | Информация о пользователе |\n| `/node \u003cuuid\u003e` | Информация о ноде |\n| `/host \u003cuuid\u003e` | Информация о хосте |\n\n---\n\n## 📝 Логирование\n\nДвухуровневая система: **файлы** (полная история) и **консоль** (только WARNING+).\n\n| Файл | Уровень | Содержимое |\n|------|---------|------------|\n| `adminbot_INFO.log` | INFO+ | Всё: API-вызовы, синхронизация, действия |\n| `adminbot_WARNING.log` | WARNING+ | Проблемы: таймауты, ошибки |\n| `web_INFO.log` | INFO+ | Логи веб-бэкенда |\n| `web_WARNING.log` | WARNING+ | Проблемы веб-бэкенда |\n\nРотация: 50 MB на файл, 5 бэкапов (gzip). Файлы в `./logs/`.\n\n```bash\ndocker compose logs -f bot                    # Live-логи\ntail -100 ./logs/adminbot_INFO.log            # Последние 100 строк\n```\n\n---\n\n## 📂 Структура проекта\n\n```\nremnawave-admin/\n├── src/                        # Telegram-бот\n│   ├── handlers/               # Обработчики (users, nodes, hosts, billing, violations, blocked_ips, ...)\n│   ├── keyboards/              # Inline-клавиатуры\n│   ├── services/               # Webhook, report scheduler, health check\n│   └── utils/                  # i18n, логирование, форматирование\n├── shared/                     # Общий код (бот + веб)\n│   ├── database.py             # AsyncPG, все DB-операции\n│   ├── api_client.py           # HTTP-клиент Panel API\n│   ├── config_service.py       # Динамическая конфигурация\n│   ├── sync.py                 # Фоновая синхронизация Panel → DB\n│   ├── violation_detector.py   # Многофакторный анализ нарушений\n│   └── connection_monitor.py   # Мониторинг подключений\n├── web/                        # Веб-панель\n│   ├── frontend/               # React + TypeScript + Tailwind + shadcn/ui\n│   └── backend/                # FastAPI бэкенд (RBAC, аналитика, автоматизации)\n├── node-agent/                 # Агент сбора данных с нод (Command Channel, скрипты)\n├── alembic/                    # Миграции БД\n├── locales/                    # Локализация (ru, en)\n└── docker-compose.yml          # Docker Compose (бот + веб-панель + БД)\n```\n\n---\n\n## 📚 Документация\n\n| Документ | Описание |\n|----------|----------|\n| [WEBHOOK_SETUP.md](WEBHOOK_SETUP.md) | Настройка webhook |\n| [web/README.md](web/README.md) | Веб-панель: настройка, реверс-прокси, API |\n| [web/SECURITY_AUDIT.md](web/SECURITY_AUDIT.md) | Аудит безопасности веб-панели |\n| [node-agent/README.md](node-agent/README.md) | Node Agent: установка, настройка, troubleshooting |\n\n---\n\n## 🔧 Решение проблем\n\n### Бот не отвечает\n\n```bash\ndocker compose ps                    # Статус контейнеров\ndocker compose logs -f bot           # Логи\ndocker compose config                # Проверка конфигурации\n```\n\n### Проблемы с API\n\n- Проверьте `API_BASE_URL` и `API_TOKEN`\n- Docker-сеть существует: `docker network ls | grep remnawave-network`\n\n### Отказано в доступе\n\n- Telegram ID в `ADMINS`? Проверьте через [@userinfobot](https://t.me/userinfobot)\n\n### Webhook не работает\n\n- `WEBHOOK_SECRET` совпадает с `WEBHOOK_SECRET_HEADER` в панели?\n- URL webhook доступен из панели?\n- Подробнее: [WEBHOOK_SETUP.md](WEBHOOK_SETUP.md)\n\n### Потерян доступ к веб-панели\n\nЕсли вы забыли пароль, а Telegram-вход не работает — используйте CLI-утилиту `scripts/admin_cli.py`.\n\n**Сбросить пароль** (будет сгенерирован новый):\n\n```bash\ndocker exec -it \u003ccontainer_name\u003e python3 scripts/admin_cli.py reset-password\n```\n\nДля конкретного пользователя или с указанием пароля:\n\n```bash\ndocker exec -it \u003ccontainer_name\u003e python3 scripts/admin_cli.py reset-password --username myadmin\ndocker exec -it \u003ccontainer_name\u003e python3 scripts/admin_cli.py reset-password --password 'MyNew$ecure1'\n```\n\n**Создать нового суперадмина:**\n\n```bash\ndocker exec -it \u003ccontainer_name\u003e python3 scripts/admin_cli.py create-superadmin --username newadmin\n```\n\n**Посмотреть список всех администраторов:**\n\n```bash\ndocker exec -it \u003ccontainer_name\u003e python3 scripts/admin_cli.py list-admins\n```\n\n\u003e Утилита подключается напрямую к PostgreSQL (читает `DATABASE_URL` из `.env`), не требует запущенной веб-панели.\n\n---\n\n## 🤝 Вклад в проект\n\n1. Fork репозитория\n2. Создайте ветку: `git checkout -b feature/amazing-feature`\n3. Commit и push\n4. Откройте Pull Request\n\n---\n\n## 📄 Лицензия\n\nMIT License — см. [LICENSE](LICENSE).\n\n---\n\n## 💖 Поддержка\n\n- [Issues на GitHub](https://github.com/case211/remnawave-admin/issues)\n- [Telegram-чат](https://t.me/remnawave_admin)\n\nПоддержать автора:\n- TON: `UQDDe-jyFTbQsPHqyojdFeO1_m7uPF-q1w0g_MfbSOd3l1sC`\n- USDT TRC20: `TGyHJj2PsYSUwkBbWdc7BFfsAxsE6SGGJP`\n- BTC: `1J6Zz7XcrpFkchwFmuU5WTFYTxziBdSwRz`\n\n---\n\n\u003cdiv align=\"center\"\u003e\n\nСделано с ❤️ для сообщества Remnawave\n\n\u003c/div\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcase211%2Fremnawave-admin","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcase211%2Fremnawave-admin","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcase211%2Fremnawave-admin/lists"}