Skip to content

Repository files navigation

🕷️ Spider Panel

VLESS / XHTTP / WS‑TLS subscription & proxy‑relay panel FastAPI panel for Railway + Cloudflare Workers. Manage users, inbounds, Reality / WS‑TLS configs, browser‑side IP scanning and a multi‑location Cloudflare Worker proxy — all from one dashboard.

فارسی: پنل مدیریتی و فروش سرویس VLESS با قابلیت ساخت سابسکریپشن، مدیریت کاربران و اینباندها، اسکنر آیپی (سمت مرورگر) و مدیریت Worker کلادفلر برای پروکسی چندمنطقهای.


✨ Features

  • VLESS Reality — keys (x25519 + ML‑DSA‑65 post‑quantum) generated by the Xray binary itself, never by Python crypto. Fresh pbk / sid / spx per inbound.
  • VLESS + WS + TLS — the config always points address / host / sni at the real panel domain automatically (no manual domain entry, no localhost).
  • XHTTP (packet‑up / stream‑up / stream‑one) — 3x‑UI style XHTTP transports.
  • Multi‑inbound per user — one user can belong to several inbounds → each produces its own config in the subscription.
  • Sub page — clean black + teal page, iOS system font, status config always first, main configs on top and custom‑IP configs below with a labeled separator.
  • Custom‑IP (scanner) configs — up to 10 extra WS‑TLS configs whose address is a scanned CF/Railway IP, while host/sni stay on the real domain.
  • Browser‑side IP scanner — Cloudflare / Railway / TCP. Pings run from the user's own internet via fetch(..., { mode: 'no-cors' }) — no server bandwidth, works on mobile. Cleared results stay cleared (seq‑guarded writes).
  • Cloudflare Worker manager — connect the panel to your Cloudflare account, deploy a proxy worker, manage a country → proxy‑IP pool, and route only the users who opt in through Worker Domain + /route/{code}. Railway is never in the VPN data path.
  • Map + proxy IP selector — pick up to 3 proxy IPs per user with live ping.
  • Full dashboard — users, inbounds, groups, live traffic/CPU/RAM, panel music, light/dark mode, FA/EN (sidebar stays put on language switch), SVG‑only icons.

🧭 Architecture

 ┌─────────────────────────┐
│ Railway (this panel) │ Panel / API / user mgmt / config generator / worker manager
└────────────┬────────────┘
│ (only management + config serving — NOT in the VPN path)
│
┌─────────┐ ┌────▼──────────┐ ┌──────────────────┐ ┌───────────┐
│ Client │ ───▶ │ Worker Domain │ ───▶ │ Cloudflare Worker │ ───▶ │ Proxy IP │ ──▶ Internet
└─────────┘ └───────────────┘ └──────────────────┘ └───────────┘
(users with proxy_ip_enabled=true)
  • Normal users connect straight to the panel's Reality / WS inbounds.
  • Worker users (proxy_ip_enabled = true) get a config addressed to the Worker domain with path /route/{country-code}. The Worker looks up the country → proxy IP and forwards the connection. Traffic never crosses Railway.

🚀 Deploy on Railway

  1. Push this repo to GitHub (or use the template directly).
  2. On Railway: New Project → Deploy from GitHub → select the repo.
  3. Railway auto‑detects the Python app (python main.py) and reads PORT.
  4. Add the environment variables below.
  5. Open the generated *.up.railway.app URL → sign in with the default password (admin) → change it immediately.

Environment variables

VariableDefaultPurpose
PORT8080HTTP port Railway forwards to
ADMIN_PASSWORDadminInitial dashboard password (change after first login)
SECRET_KEYspider-panel-secret-key-v2Session / hashing secret — set a strong random one
RAILWAY_PUBLIC_DOMAINAuto‑set by Railway; used as the real panel domain in configs
DATA_DIR/dataPersistence dir for spider_state.json
WORKER_SYNC_INTERVAL3600Seconds between auto proxy-source syncs (default: hourly)

RAILWAY_PUBLIC_DOMAIN is provided automatically. The WS‑TLS config generator uses it (or an optional manually set domain) for address/host/snino manual domain typing required.


⚡ Cloudflare Worker setup (optional, for multi-location proxy)

The Worker tab in the sidebar walks you through connecting the panel to a Cloudflare Worker. The deployed Worker is a VLESS WS relay (edgetunnel-style): it accepts WebSocket connections from VLESS clients, authenticates them via UUID in its KV store, and forwards traffic through a TCP proxy to the target.

Supported auth: Global API Key (cfk_... + email) or Bearer token.

  1. Open Worker in the sidebar → Setup form.
  2. Cloudflare API Token — create a Global API Key at https://dash.cloudflare.com/profile/api-tokens or a scoped token with Workers Scripts: Edit + KV Storage: Edit permissions.
  3. Email — your Cloudflare account email (required for Global API Key auth).
  4. Account ID — your Cloudflare account UUID (dashboard overview / right sidebar).
  5. Click Connect & Deploy. The panel:
    • Verifies the token/email
    • Auto-discovers your Worker subdomain from the Cloudflare API
    • Creates a KV namespace (spider-worker-kv) and binds it to the Worker
    • Deploys the VLESS WS relay script (from worker/_worker.js in this repo)
    • Pushes all active panel users (uuid + traffic limit + expiry) to the Worker's KV
  6. In the Worker tab, the Proxy IP Pool shows all available country proxies (fetched daily from the GitHub source). Use the dropdown to manage them.

How it works: When a user picks a Worker inbound, the panel syncs their config_uuidlimit_bytes + expire to the Worker's KV. The Worker authenticates by checking user:{uuid} in KV. Users whose quota is exceeded or whose expiry has passed get a 403.

Traffic flow: Client → Worker Domain (wss://) → Cloudflare Worker → target IP → Internet. Railway is only the control plane (panel / API / config generation / user management).

Worker source lives in the repo

worker/_worker.js is the deployed script. The panel reads it at deploy time and injects __PANEL_DOMAIN__ and __PANEL_TOKEN__ before uploading. You can edit the Worker logic with a normal git push — no need to touch Python code.

Daily proxy auto-sync

The panel can pull a fresh country → proxy list from a daily GitHub source and push it to the deployed Worker automatically:

  • Every hour (configurable via WORKER_SYNC_INTERVAL, default 3600), if the worker is connected and auto-sync is on, the panel fetches the source, parses it and re-deploys the worker with the updated map.
  • Source defaults to the NiREvil ProxyIP-Daily.md list (62 countries, best-risk IPs first). You can change the URL in the Worker tab.
  • The parser decodes each section's flag emoji → ISO country code, keeps the first 3 IPs per country, and the Worker round-robins across them per request.
  • Manual entries you add/edit in the panel carry a manual flag and survive source refreshes (your overrides are never wiped).
  • In the Worker tab you get: auto-update toggle, source URL, a "Update Now" button, and a country/IP preview that works even before the worker is connected.

Update flow:Worker tab → set source → Save → Update Now (or just wait for the hourly sync).


📦 Supported config types

TypeSecurityTransportNotes
VLESS Realityrealitytcp / xhttpx25519 + ML‑DSA‑65 keys from the Xray binary
VLESS WS TLStlswsauto panel domain for address/host/sni
VLESS XHTTPtlsxhttppacket‑up / stream‑up / stream‑one
VMess / Trojan / Shadowsockstlsws/grpc/tcplegacy protocols
Custom‑IP WS TLStlswsaddress = scanned IP, host/sni = panel domain

Sub page layout (per user):

[Status config] ← always first (shows days left + traffic %)
[Main config #1] ← one per selected inbound
[Main config #2]
─────────────────────
[Custom IP (Railway) + 10 configs]
[Custom #1] [Custom #2] …

🖱 IP scanner

Runs entirely from the visitor's browser using the fastest, simplest method:

conststart=performance.now();awaitfetch("https://1.2.3.4/",{mode: "no-cors",cache: "no-store"});constping=performance.now()-start;
  • Pings 16 targets at a time with Promise.all, sorts by latency, live‑saves the best 10.
  • Cloudflare / Railway tabs generate random candidate IPs from known ranges.
  • TCP tab resolves a domain to its IPs and reports connect latency.
  • Uses the user's own network & IP — no server bandwidth, works on phones and computers.
  • Clearing stops the scan, wipes the list, and the cleared state persists (stale in‑flight writes are dropped server‑side, so results never “come back”).

Saved scanned IPs are consumed when you assign Custom IP (scanner) to a user → up to 10 extra WS‑TLS configs in their sub.


🔌 API reference (main endpoints)

All /api/* endpoints (except the public sub/config ones) require the auth cookie.

Auth

MethodPathBody
POST/api/login{ password }
POST/api/logout
POST/api/change-password{ current_password, new_password }

Users & subscriptions

MethodPathNotes
GET/POST/api/userslist / create (proxy_ip_enabled, custom_ip_type, proxy_country, …)
GET/PATCH/DELETE/api/users/{id}read / update / delete
GET/api/users/{id}/configgenerated VLESS config
GET/api/users/{id}/qrQR code
GET/api/sub/{username}public sub data — configs + custom_configs (split for the sub page)
GET/sub/{identifier}user subscription page / raw link

Inbounds

MethodPathNotes
GET/POST/api/inboundslist / create (Reality keys auto‑generated via the Xray binary)
PATCH/DELETE/api/inbounds/{id}update / delete
POST/api/inbounds/{id}/generate-reality-keysfresh pbk/sid/spx
POST/api/inbounds/{id}/generate-short-idnew short id

IP scanner

MethodPathNotes
GET/api/scanner/ips/{ctype}cf or railway → saved list + seq
POST/api/scanner/savewrite list; pass current seq — stale writes rejected
GET/api/scanner/resolve?host=DNS resolve for TCP tab
POST/api/scanner/ping-batchserver‑side TCP latency probe (fallback)

Cloudflare Worker

MethodPathNotes
GET/api/workerstatus + proxy map (no token)
POST/api/worker/setupverify token, deploy worker, save connection
POST/api/worker/syncre‑deploy after proxy changes
POST/api/worker/sync-sourcefetch daily source now, update pool + deploy
POST/api/worker/settingsset source_url / auto_sync
DELETE/api/workerremove connection
POST/api/worker/proxiesadd/update a country → proxy
DELETE/api/worker/proxies/{code}remove a country
GET/api/worker/locationslocation status for the map tab

Groups / IP pool / tools

MethodPathNotes
GET/POST/api/groupsgroup management
POST/api/ips/assignassign IPs to a user
GET/api/tools/reality-settingsReality presets
POST/api/tools/config-generatorad‑hoc config builder
GET/api/server/statslive CPU/RAM/disk/net

🗂 Project layout

main.py FastAPI app — users, inbounds, config generator, scanner, worker manager, relay
pages.py public page HTML helpers
relay_vless.py VLESS/WS/XHTTP relay logic
xhttp_siz10.py XHTTP streaming helpers
fetch_proxies.py legacy proxy‑list fetcher (no longer used by the UI)
static/
index.html dashboard SPA (sidebar: Dashboard / Users / Inbounds / IP Scanner / Worker / Settings)
sub.html per‑user subscription page
login.html login page
worker/_worker.js Cloudflare Worker template (deployed by the panel, not under /static)
xray/ Xray binary + generated config (installed at runtime)
data/ spider_state.json, scanned/ (gitignored)

🔒 Security notes

  • Never share the dashboard URL with users; change the default password right away.
  • The Cloudflare API token is kept server‑side and stripped from every API response.
  • Use a strong SECRET_KEY; it protects sessions and password hashing.
  • Reality private keys are generated by the Xray binary and stored in state; keep data/ private.

🧑‍💻 Development

pip install -r requirements.txt
python main.py # http://localhost:8080 (login: admin / admin)

Set RAILWAY_PUBLIC_DOMAIN or an in‑panel domain to see real domains in WS‑TLS configs locally.


📄 License

MIT — use it, fork it, build on it. For a production deployment you are responsible for your own infrastructure, users and applicable laws.

About

A prsonal vpn panel

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages