Files

9.4 KiB

ZernProxy Manager (Py-3XUI-multiserver)

Объединение нескольких серверов 3x-UI в единую VPN-подписку. Soft-tariff система с веб-панелью, донатной оплатой, Happ и WDTT совместимостью.

Architecture

servers.conf ──→ 3x-UI сервера (API + sub URL + status URL)
settings.conf ──→ тарифы, платежи, админка, auto-propagate
users.db ───────→ пользователи (SQLite)
     ↓
aggregator.py ──→ FastAPI сервер
     ↓
  /sub/{id} ────→ подписка для клиента (VLESS / Trojan / VMess / Shadowsocks)
  /admin/* ─────→ веб-панель управления
  /admin/api/propagate/{server} → синхронизация пользователей между серверами
  / ────────────→ статус-пейдж с health-check серверов

Soft-tariff: пользователь создаётся на всех inbounds один раз, tier (free/test/paid) меняется локально в БД, без дёргания 3x-UI API.

Features

  • Multi-server: объединение любого количества 3x-UI серверов
  • Multi-inbound: поддержка нескольких inbound на сервере (разные протоколы)
  • Soft-tariff: free / test / paid tier без пересоздания клиентов
  • Propagate: синхронизация пользователей между серверами по strict majority (>50%)
  • Auto-propagate: фоновая синхронизация по расписанию (по умолчанию 30 мин)
  • DonationAlerts: приём платежей с поиском донатера по ID/username
  • Веб-панель: дашборд со статистикой, CRUD пользователей, просмотр трафика, QR-коды
  • Статус-пейдж: публичная страница с health-check серверов (CPU/RAM/Disk/Net/I/O)
  • Happ.su / WDTT совместимость: заголовки profile-title, sub-expire, announce, hide-settings
  • Абсолютный expire: tariff_end_at (Unix timestamp) — дни считаются динамически, автопонижение tier при истечении
  • In-memory кеш: ссылки кешируются на 7 дней, трафик — на 2 минуты
  • ShortID ротация: автоматическая смена shortId на серверах каждые N часов
  • MOTD: объявления из motd.txt или settings
  • Health scoring: взвешенная оценка здоровья сервера (CPU 30%, RAM 25%, Disk 20%, Net 15%, I/O 10%)
  • Trojan support: создание клиентов на Trojan инбаундах (password вместо uuid)

wdtt (Zern-BlackOut) Compatibility

Проект полностью совместим с клиентом Zern-BlackOut (форк wdtt), доступным по адресу: https://git.swe.zernmc.ru/sasheg/Zern-BlackOut

Важно: Клиент wdtt был модифицирован для совместимости с данным агрегатором. Использование оригинального wdtt без модификаций может привести к некорректной работе. Репозиторий Zern-BlackOut находится в активной разработке для полной интеграции.

Поддерживаемые возможности:

  • VLESS + XTLS Vision / Reality
  • Trojan + HTTP + Reality
  • Автообновление подписки
  • Отображение expire-даты и лимитов трафика
  • Hide-settings, announce, support-url через subscription-заголовки

Quick Start

pip install fastapi uvicorn httpx py3xui qrcode[pil] Pillow
git clone ssh://git@git.swe.zernmc.ru:2222/sasheg/Py-3XUI-multiserver.git
cd Py-3XUI-multiserver
# настроить servers.conf, settings.conf (см. ниже)
python3 aggregator.py

Для production: screen -S aggregator python3 aggregator.py

Configuration

servers.conf

{
  "servers": [
    {
      "name": "ru-1",
      "subscription_url": "http://panel.domain.com:2096",
      "sub_path": "/sub/{sub_id}",
      "country": "RU",
      "status_url": "http://domain.com:18765/status?secret=...",
      "inbounds": [
        {
          "id": 1,
          "name": "Reality",
          "api_host": "http://panel.domain.com:22881/PATH",
          "api_user": "admin",
          "api_pass": "password",
          "is_free": true
        },
        {
          "id": 2,
          "name": "Trojan-Inbound",
          "protocol": "trojan",
          "api_host": "http://panel.domain.com:22881/PATH",
          "api_user": "admin",
          "api_pass": "password",
          "is_free": false
        }
      ]
    }
  ]
}
Field Type Description
name string Unique server name
subscription_url string Base URL for subscription links
sub_path string Sub endpoint path (/sub/{sub_id})
country string 2-letter country code (RU, DE, PL, SE...)
status_url string URL for server health data (3x-UI status endpoint)
inbounds[].id int Inbound ID in 3x-UI
inbounds[].name string Display name
inbounds[].protocol string (optional) protocol type (trojan)
inbounds[].api_host string 3x-UI API URL for this inbound
inbounds[].api_user string API login
inbounds[].api_pass string API password
inbounds[].is_free bool Доступен ли inbound для free-тарифа

settings.conf

{
  "general": {
    "title": "MyVPN",
    "host": "conn.example.com",
    "support_url": "https://t.me/support"
  },
  "announcement": "base64 enc or plain text",
  "shortid_rotation_hours": 11,
  "tiers": {
    "free": {
      "name": "Free",
      "traffic_limit_gb": 0
    },
    "test": {
      "name": "Test",
      "traffic_limit_gb": 5,
      "prices": {
        "test": 50
      },
      "days": {
        "test": 7
      }
    },
    "paid": {
      "name": "Premium",
      "traffic_limit_gb": 0,
      "prices": {
        "monthly": 150,
        "yearly": 990
      },
      "days": {
        "monthly": 30,
        "yearly": 365
      }
    }
  },
  "payments": {
    "donationalerts": {
      "enabled": true,
      "api_token": "...",
      "webhook_secret": "...",
      "url": "https://www.donationalerts.com/r/you"
    }
  },
  "admin": {
    "username": "admin",
    "password": "secure_password"
  },
  "auto_propagate": {
    "enabled": true,
    "interval_minutes": 30
  }
}

Tiers

Tier Servers Traffic Price Duration
free inbounds with is_free: true unlimited (0 = ∞) free forever
test all inbounds 5 GB 50₽ 7 days
paid all inbounds unlimited 150₽/30d, 990₽/365d configurable

Propagate

При добавлении нового сервера или инбаунда пользователи НЕ создаются автоматически на нём. Для синхронизации используется strict majority: пользователь добавляется на целевой сервер только если он существует на >50% других активных серверов.

curl -X POST http://localhost:8000/admin/api/propagate/{server_name} -b "admin_token=..."

В админ-панели кнопка 🔄 на каждом сервере. Auto-propagate запускается фоном каждые N минут.

Endpoints

Path Method Description
/sub/{id} GET Subscription (format: base64/json/raw)
/sub/{id} GET (HTML) Web page with QR and info
/admin/login GET/POST Admin auth
/admin/users GET User management panel
/admin/dashboard GET Stats dashboard with server health
/admin/api/users POST Create user
/admin/api/users/update POST Update user
/admin/api/users/delete POST Delete user (with 3x-UI)
/admin/api/reload POST Reload configs + clear cache
/admin/api/propagate/{server} POST Sync users to server
/admin/api/rotate-shortids GET Rotate short IDs on all servers
/ GET Landing page with server status

DonationAlerts

Polling-based (every ~2 seconds). Amount mapping from settings.conf → tiers → prices:

  • Any configured amount → corresponding tier + days
  • Donor identified by id or username from donation message
  • tariff_end_at extends dynamically (MAX of current end, now + days)

Happ.su / WDTT Support

Subscription response includes compatible headers:

  • Profile-Title, Profile-Update-Interval, Profile-Web-Page-Url
  • Subscription-Userinfo (upload/download/total/expire)
  • Announce, Support-Url, Hide-Settings
  • Sub-Expire, Sub-Expire-Button-Link

Tech

  • FastAPI + uvicorn
  • SQLite (users only)
  • py3xui — 3x-UI API client
  • httpx — async HTTP for sub links
  • qrcode — QR generation
  • Plus Jakarta Sans / JetBrains Mono — UI typography
  • Glassmorphism — design system