- 👥 Пользователи — поиск, создание, редактирование, HWID устройства, статистика, массовые операции
- 🛰 Ноды — просмотр, включение/выключение, перезапуск, мониторинг трафика, статистика
- 🖥 Хосты — просмотр, создание, редактирование, массовые операции
- 🧰 Ресурсы — шаблоны подписок, сниппеты, API токены, конфиги
- 💰 Биллинг — история платежей, провайдеры, биллинг-ноды
- 📊 Система — здоровье системы, статистика, трафик
- 📊 Дашборд с обзором системы и графиками нарушений
- 👥 Управление пользователями, нодами, хостами
- 🛡 Просмотр нарушений с IP Lookup (провайдер, город, тип подключения)
- ⚙️ Настройки с автосохранением (приоритет: БД > .env > по умолчанию)
- 🔐 Авторизация через Telegram Login Widget + JWT
- 🎨 Тёмная тема, адаптивный дизайн
- 🔍 Многофакторный анализ подключений (временной, географический, ASN, профиль, устройства)
- 🌍 Детекция «невозможных путешествий», распознавание 60+ российских агломераций
- ⚡ Автоматические действия по порогам скоринга
- 📡 Интеграция с Node Agent для сбора данных
- 📤 Прямая MX-доставка без внешних SMTP-провайдеров
- 🔏 DKIM-подпись (RSA-2048) + автоматическая проверка SPF/DKIM/DMARC
- 📥 Приём входящих писем (встроенный SMTP-сервер)
- 📊 Очередь отправки с повторами, rate limiting и мониторингом
- ✍️ Встроенный compose-редактор + inbox-просмотрщик
- ⚙️ Динамические настройки без перезапуска (Telegram и веб-панель)
- 🔔 Webhook-уведомления с маршрутизацией по топикам
- 🌍 Русский и английский языки
- 🗄 PostgreSQL с graceful degradation (работает и без БД)
| Что | Где взять |
|---|---|
| 🐳 Docker + Docker Compose | docker.com |
| 🤖 Токен Telegram-бота | Создайте бота у @BotFather → /newbot → скопируйте токен |
| 🔑 API-токен Remnawave | Панель Remnawave → Настройки → API → скопируйте токен |
| 🆔 Ваш Telegram ID | Напишите @userinfobot → он пришлёт ваш числовой ID |
| 🆔 2 A-записи | Запись для Webhook (Bot) + Запись для Web |
git clone https://github.com/case211/remnawave-admin.git
cd remnawave-admincp .env.example .env
nano .env # или vim, или любой редакторЗаполните обязательные поля (без них бот не запустится):
# 🤖 Токен бота (из @BotFather)
BOT_TOKEN=1234567890:ABCdefGHIjklmNOPqrstUVWxyz
# 🌐 Адрес API Remnawave
# Если бот и панель в одной Docker-сети:
API_BASE_URL=http://remnawave:3000
# Если панель на другом сервере:
# API_BASE_URL=https://panel.yourdomain.com
# 🔑 API-токен из панели Remnawave
API_TOKEN=ваш_токен_из_панели
# 👤 Telegram ID администраторов (через запятую)
ADMINS=123456789Настройте базу данных (PostgreSQL поднимается автоматически в Docker):
# 🗄 PostgreSQL — придумайте пароль
POSTGRES_USER=remnawave
POSTGRES_PASSWORD=придумайте_надёжный_пароль
POSTGRES_DB=remnawave_bot
# ⚠️ Пароль тут должен совпадать с POSTGRES_PASSWORD выше!
DATABASE_URL=postgresql://remnawave:придумайте_надёжный_пароль@remnawave-admin-db:5432/remnawave_bot# Создайте Docker-сеть (один раз)
docker network create remnawave-network
# Скачайте образы и запустите
docker compose up -d
# Проверьте, что всё работает
docker compose logs -f bot✅ Готово! Откройте бота в Telegram и отправьте /start.
Если хотите веб-интерфейс — добавьте в .env:
# 🌐 Веб-панель
# Секретный ключ для JWT-сессий (сгенерируйте: openssl rand -hex 32)
WEB_SECRET_KEY=сгенерированный_ключ_минимум_32_символа
# Username бота (без @) — нужен для Telegram Login Widget
TELEGRAM_BOT_USERNAME=your_bot_username
# Домен веб-панели (для CORS)
WEB_CORS_ORIGINS=https://admin.yourdomain.comЗапустите с профилем web:
docker compose --profile web up -dВеб-панель будет доступна на портах: frontend :3000, backend :8081.
📖 Подробнее о настройке домена и реверс-прокси: web/README.md
Чтобы бот присылал уведомления при изменениях в панели — добавьте в .env:
# 🔔 Чат для уведомлений
NOTIFICATIONS_CHAT_ID=-1001234567890 # ID вашей группы/канала
# 🔐 Секрет для webhook (сгенерируйте: openssl rand -hex 64)
WEBHOOK_SECRET=ваш_секретный_ключЗатем в панели Remnawave укажите:
- WEBHOOK_URL =
http://bot:8080/webhook(если в одной Docker-сети) - WEBHOOK_SECRET_HEADER = тот же ключ, что и
WEBHOOK_SECRETв.envбота
📖 Подробная инструкция с примерами nginx/Caddy: WEBHOOK_SETUP.md
Если у вас группа-форум в Telegram, можно разделить уведомления по топикам:
NOTIFICATIONS_TOPIC_USERS=456 # 👥 События пользователей
NOTIFICATIONS_TOPIC_NODES=789 # 🛰 События нод
NOTIFICATIONS_TOPIC_SERVICE=101 # ⚙️ Сервисные события
NOTIFICATIONS_TOPIC_HWID=102 # 💻 HWID устройства
NOTIFICATIONS_TOPIC_CRM=103 # 💰 Биллинг
NOTIFICATIONS_TOPIC_ERRORS=104 # ❌ Ошибки
NOTIFICATIONS_TOPIC_VIOLATIONS=105 # 🛡 Нарушения💡 Если топик не указан — уведомление уйдёт в
NOTIFICATIONS_TOPIC_ID(общий fallback).
Веб-панель включает встроенный почтовый сервер с DKIM-подписью, прямой MX-доставкой и приёмом входящих писем — без внешних SMTP-провайдеров.
Перейдите в Settings в веб-панели → секция "Почтовый сервер" → включите "Почтовый сервер включён". Перезапустите контейнер.
Или через .env:
MAIL_SERVER_ENABLED=true
MAIL_INBOUND_PORT=2525 # Порт приёма входящих (по умолчанию 2525)
MAIL_SERVER_HOSTNAME=0.0.0.0 # IP для SMTP-сервера💡 Все настройки можно менять из веб-интерфейса (Settings),
.env— как fallback.
- Перейдите в Mail Server → вкладка Domains → Add Domain
- Введите ваш домен (например
example.com) - Система автоматически сгенерирует DKIM-ключи (RSA-2048)
Нажмите "DNS Records" у домена — система покажет 4 записи для добавления у DNS-провайдера:
| Тип | Хост | Назначение |
|---|---|---|
| MX | example.com |
Направляет входящую почту на ваш сервер |
| TXT | example.com |
SPF — разрешает вашему IP отправлять почту |
| TXT | rw._domainkey.example.com |
DKIM — подпись для верификации |
| TXT | _dmarc.example.com |
DMARC — политика для неверифицированных писем |
Значения можно скопировать из интерфейса. После добавления нажмите "Check DNS" для проверки.
Порт 25 — исходящий (для прямой доставки на MX-серверы получателей)
Порт 2525 — входящий (приём писем, настраивается)
В docker-compose.yml добавьте:
ports:
- "25:2525" # входящая почта
⚠️ Многие облачные хостинги (AWS, GCP, Azure) блокируют порт 25. Используйте VPS с открытым портом 25 (Hetzner, OVH, DigitalOcean).
Веб-панель (HTTP API) проходит через reverse proxy как обычно — эндпоинты /api/v2/mailserver/* работают без дополнительных настроек.
SMTP — отдельный протокол, он не может проксироваться через HTTP reverse proxy. Два варианта:
Вариант 1 — Прямой проброс порта (рекомендуется):
# docker-compose.yml — SMTP-порт минует proxy
services:
remnawave-admin:
ports:
- "25:2525" # входящая почта напрямуюВариант 2 — nginx stream proxy (TCP):
# Отдельный блок stream {}, НЕ внутри http {}
stream {
server {
listen 25;
proxy_pass remnawave-admin:2525;
}
}Вариант 3 — Caddy L4 (TCP proxy):
Для TCP-проксирования Caddy нужен плагин caddy-l4:
{
"apps": {
"layer4": {
"servers": {
"smtp": {
"listen": [":25"],
"routes": [{
"handle": [{
"handler": "proxy",
"upstreams": [{"dial": ["remnawave-admin:2525"]}]
}]
}]
}
}
}
}
}Или через Caddyfile (с caddy-l4):
:25 {
route {
proxy remnawave-admin:2525
}
}Схема подключения:
Интернет
│
├── :443 (HTTPS) → nginx/Caddy → :8081 (веб-панель API)
│ → :3000 (веб-панель frontend)
│
└── :25 (SMTP) → напрямую → :2525 (встроенный SMTP-сервер)
Важно:
- MX, SPF, PTR записи должны указывать на публичный IP вашего сервера
- PTR-запись (reverse DNS) настраивается у хостера — улучшает доставляемость
- Если proxy и приложение на одной машине — просто пробросьте порт 25/2525 в docker-compose мимо nginx
- Активируйте домен (переключатель в карточке домена)
- Перейдите на вкладку Compose → выберите домен → введите адрес → Send Test
- Проверьте вкладку Queue — статус должен стать
sent
📬 Если настроен активный домен, система уведомлений автоматически использует встроенный сервер (fallback на SMTP relay).
python -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
cp .env.example .env
# Отредактируйте .env: API_BASE_URL=https://ваш-домен-панели.com
python -m src.main| Переменная | Обяз. | По умолч. | Описание |
|---|---|---|---|
BOT_TOKEN |
✅ | — | Токен Telegram-бота |
API_BASE_URL |
✅ | — | URL API Remnawave |
API_TOKEN |
✅ | — | Токен аутентификации API |
ADMINS |
✅ | — | ID администраторов через запятую |
DEFAULT_LOCALE |
— | ru |
Язык (ru / en) |
LOG_LEVEL |
— | INFO |
Уровень логирования |
| Переменная | Обяз. | По умолч. | Описание |
|---|---|---|---|
POSTGRES_USER |
✅ | — | Пользователь PostgreSQL |
POSTGRES_PASSWORD |
✅ | — | Пароль PostgreSQL |
POSTGRES_DB |
✅ | — | Имя базы данных |
DATABASE_URL |
✅ | — | URL подключения к PostgreSQL |
SYNC_INTERVAL_SECONDS |
— | 300 |
Интервал синхронизации с API (сек) |
| Переменная | Описание |
|---|---|
NOTIFICATIONS_CHAT_ID |
ID группы/канала |
NOTIFICATIONS_TOPIC_ID |
Общий топик (fallback) |
NOTIFICATIONS_TOPIC_USERS |
Топик для пользователей |
NOTIFICATIONS_TOPIC_NODES |
Топик для нод |
NOTIFICATIONS_TOPIC_SERVICE |
Сервисные уведомления |
NOTIFICATIONS_TOPIC_HWID |
HWID уведомления |
NOTIFICATIONS_TOPIC_CRM |
Биллинг уведомления |
NOTIFICATIONS_TOPIC_ERRORS |
Ошибки |
NOTIFICATIONS_TOPIC_VIOLATIONS |
Нарушения |
| Переменная | По умолч. | Описание |
|---|---|---|
WEBHOOK_SECRET |
— | Ключ проверки webhook (HMAC-SHA256) |
WEBHOOK_PORT |
8080 |
Порт webhook сервера |
| Переменная | Обяз. | По умолч. | Описание |
|---|---|---|---|
MAXMIND_LICENSE_KEY |
— | — | Лицензионный ключ MaxMind (бесплатно). Если указан — базы скачиваются автоматически |
MAXMIND_CITY_DB |
— | /app/geoip/GeoLite2-City.mmdb |
Путь к базе GeoLite2-City |
MAXMIND_ASN_DB |
— | /app/geoip/GeoLite2-ASN.mmdb |
Путь к базе GeoLite2-ASN |
Без MaxMind — используется ip-api.com (бесплатный, но ограничен ~1000 запросов/день). С MaxMind — локальная база, мгновенные lookup'ы, без лимитов.
Как подключить:
- Зарегистрируйтесь на maxmind.com/en/geolite2/signup (бесплатно)
- Account → Manage License Keys → Generate New License Key
- Добавьте в
.env:MAXMIND_LICENSE_KEY=ваш_ключ- Базы скачаются автоматически при старте и обновляются каждые 24 часа
| Переменная | Обяз.* | По умолч. | Описание |
|---|---|---|---|
WEB_SECRET_KEY |
✅ | — | Секретный ключ JWT |
TELEGRAM_BOT_USERNAME |
✅ | — | Username бота (без @) |
WEB_CORS_ORIGINS |
— | — | Разрешённые домены (CORS) |
WEB_JWT_EXPIRE_MINUTES |
— | 30 |
Время жизни access token (мин) |
WEB_JWT_REFRESH_HOURS |
— | 6 |
Время жизни refresh token (ч) |
WEB_BACKEND_PORT |
— | 8081 |
Порт бэкенда |
WEB_FRONTEND_PORT |
— | 3000 |
Порт фронтенда |
WEB_ALLOWED_IPS |
— | — | Белый список IP (CIDR) |
* Обязательно только при запуске с --profile web
| Переменная | По умолч. | Описание |
|---|---|---|
MAIL_SERVER_ENABLED |
false |
Включить встроенный почтовый сервер |
MAIL_INBOUND_PORT |
2525 |
Порт входящего SMTP-сервера |
MAIL_SERVER_HOSTNAME |
0.0.0.0 |
IP для SMTP-сервера |
💡 Эти переменные — fallback. Настройки можно менять из веб-панели (Settings → Почтовый сервер).
| Команда | Описание |
|---|---|
/start |
Главное меню |
/help |
Справка |
/health |
Статус системы |
/stats |
Статистика панели |
/bandwidth |
Статистика трафика |
/config |
Динамические настройки |
/user <username|id> |
Информация о пользователе |
/node <uuid> |
Информация о ноде |
/host <uuid> |
Информация о хосте |
Двухуровневая система: файлы (полная история) и консоль (только WARNING+).
| Файл | Уровень | Содержимое |
|---|---|---|
adminbot_INFO.log |
INFO+ | Всё: API-вызовы, синхронизация, действия |
adminbot_WARNING.log |
WARNING+ | Проблемы: таймауты, ошибки |
web_INFO.log |
INFO+ | Логи веб-бэкенда |
web_WARNING.log |
WARNING+ | Проблемы веб-бэкенда |
Ротация: 50 MB на файл, 5 бэкапов (gzip). Файлы в ./logs/.
docker compose logs -f bot # Live-логи
tail -100 ./logs/adminbot_INFO.log # Последние 100 строкremnawave-admin/
├── src/ # Telegram-бот
│ ├── handlers/ # Обработчики (users, nodes, hosts, billing, ...)
│ ├── keyboards/ # Inline-клавиатуры
│ ├── services/ # API client, database, violation detector, webhook, ...
│ └── utils/ # i18n, логирование, форматирование
├── web/ # Веб-панель
│ ├── frontend/ # React + TypeScript + Tailwind
│ └── backend/ # FastAPI бэкенд
├── node-agent/ # Агент сбора данных с нод
├── alembic/ # Миграции БД
├── locales/ # Локализация (ru, en)
└── docker-compose.yml # Docker Compose (профили: bot, web)
| Документ | Описание |
|---|---|
| CHANGELOG.md | История версий |
| WEBHOOK_SETUP.md | Настройка webhook |
| docs/anti-abuse.md | Anti-Abuse система, база ASN, классификация провайдеров |
| web/README.md | Веб-панель: настройка, реверс-прокси, API |
| web/SECURITY_AUDIT.md | Аудит безопасности веб-панели |
| node-agent/README.md | Node Agent: установка, настройка, troubleshooting |
docker compose ps # Статус контейнеров
docker compose logs -f bot # Логи
docker compose config # Проверка конфигурации- Проверьте
API_BASE_URLиAPI_TOKEN - Docker-сеть существует:
docker network ls | grep remnawave-network
- Telegram ID в
ADMINS? Проверьте через @userinfobot
WEBHOOK_SECRETсовпадает сWEBHOOK_SECRET_HEADERв панели?- URL webhook доступен из панели?
- Подробнее: WEBHOOK_SETUP.md
Если вы забыли пароль, а Telegram-вход не работает — используйте CLI-утилиту scripts/admin_cli.py.
Сбросить пароль (будет сгенерирован новый):
docker exec -it <container_name> python3 scripts/admin_cli.py reset-passwordДля конкретного пользователя или с указанием пароля:
docker exec -it <container_name> python3 scripts/admin_cli.py reset-password --username myadmin
docker exec -it <container_name> python3 scripts/admin_cli.py reset-password --password 'MyNew$ecure1'Создать нового суперадмина:
docker exec -it <container_name> python3 scripts/admin_cli.py create-superadmin --username newadminПосмотреть список всех администраторов:
docker exec -it <container_name> python3 scripts/admin_cli.py list-adminsУтилита подключается напрямую к PostgreSQL (читает
DATABASE_URLиз.env), не требует запущенной веб-панели.
- Fork репозитория
- Создайте ветку:
git checkout -b feature/amazing-feature - Commit и push
- Откройте Pull Request
MIT License — см. LICENSE.
Поддержать автора:
- TON:
UQDDe-jyFTbQsPHqyojdFeO1_m7uPF-q1w0g_MfbSOd3l1sC - USDT TRC20:
TGyHJj2PsYSUwkBbWdc7BFfsAxsE6SGGJP - BTC:
bc1qusrj5rxd3kv6eepzpdn0muy6zsl3c24xunz2xn
Сделано с ❤️ для сообщества Remnawave