Files
netrunner-backend/README.md
T
Kirill d4a57c0b6a docs
2026-07-02 23:13:13 +07:00

8.0 KiB
Raw Blame History

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. Неструктурированный бэклог идей и задач — в things.txt.

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

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

  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.
  7. tasks.rs — фоновый цикл: сброс просроченных подписок и сверка блокчейна на предмет потерянных платежей.
  8. error.rs — единый AppError с IntoResponse: маппинг в HTTP-статус, безопасное сообщение наружу и подробности только в логи/метрики.

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

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.

Известные незавершённые места (недоделки)

Ниже — то, что явно недоделано или является временной заглушкой в текущем коде. В самих файлах эти места помечены комментариями // TODO: — см. также SECURITY_AUDIT.md для рисков безопасности отдельно.

  • Cyberhack без анти-чита. POST /users/hack/result принимает score от клиента и лишь клампит его в 0..=500 — сервер не проверяет, что игра реально была сыграна честно. Пока не эксплуатируемо (баланс E$ нигде не тратится), но станет дырой, как только появится трата баланса. См. src/modules/users/controller.rs.
  • GET /nodes/routing возвращает неполный конфиг. Отдаёт только ip/port/region/supported_protocols (последнее — статичная заглушка). Реальному VPN-клиенту нужны ещё tunnel_*-поля (уже есть в модели VpnNode, но не сериализуются), public_key/sni_domain (их нет даже в схеме БД) и одноразовый session-токен. См. src/modules/nodes/controller.rs.
  • GET /nodes/stats отдаёт фейковый uptime: "99.9%" для всех нод — не реальная метрика.
  • Нет health-check воркера для VPN-нод. Статус ноды в БД не переоценивается сам: если физический сервер лёг, control plane продолжит считать его online и выдавать клиентам. См. src/tasks.rs.
  • Провижининг ноды — синхронный. POST /admin/nodes держит HTTP-запрос открытым на всё время SSH-провижининга (может занимать минуты) вместо немедленного 202 Accepted + фоновой задачи. См. src/modules/nodes/service.rs.
  • Курс TON запрашивается синхронно на каждый инвойс (BillingService::initiate_payment) — не кешируется, хотя Redis в проекте уже подключён.
  • Таблица auth_sessions объявлена в миграции, но нигде не используется — заброшенный черновик флоу авторизации через Magic Link из бота. Либо доделать, либо убрать из схемы.
  • Telegram-бот: разделы «Тарифы» и «Синдикат» в inline-меню — заглушка «В разработке...» (src/bot.rs, handle_callbacks).
  • Фронтенд, AdminDashboard.tsx: кнопка «Force Restart» ничего не делает (нет onClick); UI для удаления ноды тоже отсутствует, хотя бэкенд уже умеет DELETE /api/v1/admin/nodes/{id}.
  • Фронтенд, Auth.tsx: искусственные задержки (setTimeout 800мс/6000мс) чисто ради вида терминала; при генерации Ghost-seed нет кнопки «скачать ключ» — если юзер не успеет скопировать seed за 6 секунд до авто-редиректа, доступ к анонимному аккаунту теряется безвозвратно (seed невосстановим).
  • frontend/README.md был шаблоном Vite по умолчанию (сейчас заменён на специфичный для проекта).