nineap 583682f330 Админка: страницы Тикеты + Мониторинг, роль support в навигации
TicketsPage.tsx — список open/closed тикетов + тред сообщений + ответ +
закрытие (owner/moderator/support). ObservabilityPage.tsx — вкладки
дашбордов Grafana через iframe за auth-гейтом Caddy, URL берётся из
GET /api/v1/config (grafana_url), страница просто не показывает
дашборды, пока GRAFANA_PUBLIC_URL не задан на сервере. StaffPage.tsx —
форма создания support-аккаунта (только Owner).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-09 23:20:59 +07:00
2026-06-29 18:05:33 +07:00
2026-04-25 14:56:48 +07:00
2026-06-29 18:05:33 +07:00
2026-07-02 23:13:13 +07:00
2026-06-29 18:05:33 +07:00

Netrunner Control Plane

Бэкенд VPN-сервиса «Netrunner»: авторизация (Telegram / анонимный «Ghost Protocol»), биллинг подписок через TON, реферальная программа, оркестрация VPN-нод по SSH, Telegram-бот как второй канал входа и встроенная раздача SPA-фронтенда.

Стек: Rust (axum, sqlx/Postgres, teloxide, tokio) + React/TypeScript (Vite) фронтенд, собранные в единый Docker-образ.

Структура репозитория

Путь Что там Подробнее
src/ Rust-бэкенд (control plane) см. ниже
src/modules/ Бизнес-модули (auth, billing, nodes, referrals, users) README
src/db/ Модели и репозиторий (доступ к Postgres) README
frontend/ React/Vite SPA (личный кабинет, игра, админка нод) README
migrations/ SQL-миграции (sqlx)
templates/init_node.sh Bash-скрипт инициализации новой VPN-ноды, исполняется по SSH
tests/ Интеграционные тесты репозитория (sqlx::test, требуют Postgres)

Инфраструктура и процесс деплоя подробно описаны в DEPLOYMENT.md; список закрытых и остаточных угроз безопасности — в SECURITY_AUDIT.md.

Архитектура бэкенда

Слоями, сверху вниз:

  1. main.rs — точка входа: поднимает пул Postgres, собирает ApiState (репозиторий + сервисы всех модулей) и параллельно запускает HTTP API, Telegram-бота и фоновые задачи биллинга до общего сигнала остановки (Ctrl+C / SIGTERM).
  2. api.rs — сборка axum-роутера: монтирует контроллеры модулей, rate-limiting (tower_governor), CORS, Prometheus-метрики (/metrics), health-пробы (/health, /health/ready) и раздачу статики фронтенда как SPA-фолбэк.
  3. modules/*/controller.rs — HTTP-контракты (axum-роуты, JSON DTO), тонкий слой без бизнес-логики.
  4. modules/*/service.rs — бизнес-логика модуля.
  5. db::repository::AppRepository — трейт доступа к БД; единственная реализация — PgRepository (Postgres/sqlx). Сервисы знают только о трейте, поэтому теоретически подменяемы в тестах без реальной БД.
  6. bot.rs — Telegram-бот (teloxide), использует те же сервисы, что и HTTP API; кнопки «Личный Кабинет»/«Тарифы»/«Синдикат» ведут в ЛК через общий WebApp-мост (короткоживущий bootstrap-токен в URL, фронт меняет его на cookie-сессию через POST /auth/exchange).
  7. tasks.rs — два фоновых цикла: сброс просроченных подписок + сверка блокчейна на предмет потерянных платежей, и health-check VPN-нод (TCP-пинг раз в 60с, переоценка online/offline).
  8. error.rs — единый AppError с IntoResponse: маппинг в HTTP-статус, безопасное сообщение наружу и подробности только в логи/метрики.

Один способ входа (Telegram Login Widget / анонимный Ghost Protocol / bootstrap-мост из бота) выдаёт одну и ту же пару cookie: короткий access-JWT (nrxp_token, 15 мин) и ротируемый непрозрачный refresh-токен (nrxp_refresh, 30 дней, хеш хранится в refresh_sessions, путь строго /api/v1/auth/refresh). Обе — HttpOnly; Secure; SameSite=Lax; в проде дополнительно Domain=.netrunner-vpn.com, поэтому одна и та же сессия работает и на лендинге (netrunner-vpn.com), и на ЛК (account.netrunner-vpn.com) без единого байта в localStorage или JS-читаемых cookie. Подробности — в src/modules/auth/README.md.

Быстрый старт (локальная разработка)

cp .env.example .env   # заполнить секреты (JWT_SECRET, ARGON_SALT, TELOXIDE_TOKEN, ...)
make dev                # docker compose: db + redis + app с hot-reload (cargo watch)

Приложение поднимется на http://localhost:8080 (/health, /health/ready). Остальные команды — make help.

Nodes, Cyberhack, биллинг — текущее состояние

  • GET /nodes/routing отдаёт полный TunnelConfig: tunnel_*-поля, public_key/sni_domain ноды и одноразовый (60с) session-токен, который выдаётся только при активной подписке юзера.
  • Health-check VPN-нод — фоновая задача (src/tasks.rs, TCP-пинг раз в 60с) переоценивает online/offline сама; ручной POST /admin/nodes/{id}/restart перезапускает прокси-контейнер на ноде по SSH-ключу.
  • Провижининг ноды асинхронный: POST /admin/nodes сразу отвечает 202 Accepted со статусом provisioning, SSH-деплой идёт в фоне.
  • Курс TON кешируется в Redis (ton_rate:<currency>, TTL 60с) — BillingService::initiate_payment бьёт TonAPI только на промах кеша.
  • Cyberhack — server-authoritative. Доску генерирует и хранит сервер (src/modules/users/cyberhack.rs, порт алгоритма из Cyberhack/src/lib.rs); клиент присылает не итоговый счёт, а сырой путь кликов, который сервер сам реплеит и валидирует (POST /users/hack/startPOST /users/hack/result).
  • Telegram-бот: «Тарифы» и «Синдикат» ведут в тот же ЛК, что и «Личный Кабинет» — единый WebApp-мост (см. выше).
  • AdminDashboard.tsx: кнопки «Force Restart» и удаления ноды подключены к соответствующим ручкам бэкенда.
S
Description
No description provided
Readme 955 KiB
Languages
Rust 74.5%
TypeScript 22.6%
Shell 1.1%
Dockerfile 0.7%
Makefile 0.6%
Other 0.4%