A lightweight VLESS-over-WebSocket proxy panel built with FastAPI, deployable on Render or Railway.
- VLESS over WebSocket (TLS) tunneling
- Multi-inbound management with per-user traffic quotas
- Connection limits per inbound (max IPs)
- Expiry date support per inbound
- Subscription link (
/sub/<uid>) compatible with v2rayNG, Hiddify, etc. - Clean IP / alternative address management
- Real-time dashboard: CPU, memory, hourly traffic chart
- Bilingual UI (English / Persian)
- Dark & Light mode
- Session-based authentication with password change
- Keep-alive mechanism for free-tier hosting
.
├── main.py # FastAPI application (gateway + panel UI)
├── requirements.txt # Python dependencies
├── render.yaml # Render deployment config
└── Procfile # Process entry point
- Fork or push this repo to GitHub.
- Go to render.com → New Web Service → connect your repo.
- Render will auto-detect
render.yamland configure everything. - Set your
ADMIN_PASSWORDenvironment variable (default:admin).
💡 Tip: For better speed, set the Region to Frankfurt (EU) in Render settings.
| Field | Value |
|---|---|
| Environment | Python |
| Build Command | pip install -r requirements.txt |
| Start Command | python main.py |
This panel on Render routes through Cloudflare's clean IPs exclusively.
Render's infrastructure sits behind Cloudflare's network, so all VLESS+WS configs will automatically use Cloudflare clean IP ranges — which are generally unblocked and stable in restricted regions.
✅ Use the panel URL directly — Cloudflare CDN handles routing automatically.
If configs don't connect, try manually entering a known Cloudflare clean IP (e.g.
104.21.x.xor172.67.x.x) in your client instead of the hostname.
- Fork or push this repo to GitHub.
- Go to railway.app → New Project → Deploy from GitHub repo → select your repo.
- Wait for the deployment to finish. You'll be given a URL — that's your service domain. To access the panel, just add
/loginto the end of your domain.
Railway does NOT use Cloudflare. It uses its own dedicated IP ranges.
Railway's outbound IPs typically fall in the range
69.46.46.x, so your configs will use Railway's own IPs — not Cloudflare's. These may or may not be accessible depending on your network restrictions.If configs don't work on Railway:
- Check whether the
69.46.46.xrange is reachable from your network.- Enable Fragment Mode in your v2ray / v2rayNG client (see section below).
- Switch to Render for Cloudflare clean IP routing.
If your configurations are not connecting — especially on Railway — enable Fragment Mode in your client:
v2rayNG (Android):
- Go to Settings → Fragment
- Enable Fragment and set: Packets
tlshello, Length10-30, Interval10-20 - Reconnect
v2ray (Desktop): Add to your outbound → streamSettings:
"sockopt": {
"dialerProxy": "fragment",
"tcpKeepAliveIdle": 100
}Fragment mode splits the TLS ClientHello packet to bypass deep packet inspection (DPI) firewalls.
pip install -r requirements.txt
python main.pyPanel will be available at: http://localhost:8000/login
After deploying on Render or Railway, access your panel at:
https://yourdomain/login
| Variable | Description | Default |
|---|---|---|
ADMIN_PASSWORD |
Panel login password | admin |
SECRET_KEY |
Session & hash secret (auto-generated) | random |
PORT |
Server port | 8000 |
⚠️ ChangeADMIN_PASSWORDbefore deploying to production.
fastapi==0.104.1
uvicorn==0.24.0
websockets==12.0
httpx==0.25.1
psutil==5.9.6
| Platform | Static IP? | Notes |
|---|---|---|
| Render (Free) | ❌ No | Shared Cloudflare IPs; clean and stable |
| Render (Paid) | ✅ Yes | Available on Starter plan and above |
| Railway | ✅ Optional | Enable via Settings → Networking → Static IP (paid feature) |
| Method | Path | Description |
|---|---|---|
POST |
/api/login |
Login with password |
POST |
/api/logout |
Logout |
GET |
/api/me |
Check session status |
POST |
/api/change-password |
Change admin password |
| Method | Path | Description |
|---|---|---|
GET |
/api/links |
List all inbounds |
POST |
/api/links |
Create new inbound |
PATCH |
/api/links/{uid} |
Edit inbound |
DELETE |
/api/links/{uid} |
Delete inbound |
GET |
/api/links/{uid}/sub |
Get subscription info |
| Method | Path | Description |
|---|---|---|
GET |
/sub/{uid} |
Base64 subscription (v2ray/Hiddify compatible) |
| Method | Path | Description |
|---|---|---|
GET |
/api/addresses |
List alternative addresses |
POST |
/api/addresses |
Add address |
DELETE |
/api/addresses/{index} |
Remove address |
| Method | Path | Description |
|---|---|---|
GET |
/stats |
Server stats (auth required) |
GET |
/health |
Health check |
vless://<uuid>@<domain>:443?encryption=none&security=tls&type=ws&host=<domain>&path=/ws/<uuid>&sni=<domain>&fp=chrome&alpn=http/1.1#Luffy-<name>
| Page | Description |
|---|---|
| Dashboard | Traffic, uptime, CPU/memory, hourly chart |
| Inbounds | Create/edit/delete users, copy config, QR code |
| Traffic | Total stats |
| Clean IP | Manage alternative subscription addresses |
| Security | Change password |
- Open the panel and go to Inbounds.
- Click Sub to copy the subscription URL.
- In your client app, add a new subscription with that URL.
- Update subscription — configs will appear automatically.
- All data is stored in-memory. Restarting the service resets all inbounds and traffic stats.
- For persistent storage, a database backend (e.g. SQLite) would need to be added.
- The keep-alive task pings
/healthevery 10 minutes to prevent Render free-tier spin-down.
- Fork the repository
- Create a new branch:
git checkout -b feature/amazing-feature - Commit your changes:
git commit -m 'Add amazing feature' - Push to your branch:
git push origin feature/amazing-feature - Open a Pull Request
MIT — use freely, modify as needed.
یک پنل پراکسی سبک VLESS-over-WebSocket ساختهشده با FastAPI، قابل استقرار روی Render یا Railway.
- تانلینگ VLESS روی WebSocket (TLS)
- مدیریت چند اینباند با محدودیت ترافیک برای هر کاربر
- محدودیت تعداد اتصال (IP) برای هر اینباند
- پشتیبانی از تاریخ انقضا برای هر اینباند
- لینک اشتراک (
/sub/<uid>) سازگار با v2rayNG، Hiddify و غیره - مدیریت آیپی تمیز / آدرسهای جایگزین
- داشبورد لحظهای: CPU، حافظه، نمودار ترافیک ساعتی
- رابط کاربری دو زبانه (فارسی / انگلیسی)
- حالت تاریک و روشن
- احراز هویت مبتنی بر session با امکان تغییر رمز
- مکانیزم keep-alive برای هاستینگ رایگان
.
├── main.py # اپلیکیشن FastAPI (گیتوی + رابط پنل)
├── requirements.txt # وابستگیهای پایتون
├── render.yaml # تنظیمات استقرار Render
└── Procfile # نقطه ورود پروسه
- ریپو را fork کنید یا روی GitHub آپلود کنید.
- به render.com بروید ← New Web Service ← ریپو را متصل کنید.
- Render بهصورت خودکار
render.yamlرا شناسایی و همه چیز را تنظیم میکند. - متغیر
ADMIN_PASSWORDرا تنظیم کنید (پیشفرض:admin).
💡 نکته: برای سرعت بهتر، Region را روی Frankfurt (EU) تنظیم کنید.
| فیلد | مقدار |
|---|---|
| محیط | Python |
| دستور Build | pip install -r requirements.txt |
| دستور Start | python main.py |
⭐ این پنل روی Render فقط از آیپیهای تمیز Cloudflare استفاده میکند.
زیرساخت Render پشت شبکه Cloudflare قرار دارد، بنابراین تمام کانفیگهای VLESS+WS بهصورت خودکار از آیپیهای تمیز Cloudflare عبور میکنند — که معمولاً آنبلاک و پایدار هستند.
✅ URL پنل را مستقیم استفاده کنید — Cloudflare CDN مسیریابی را خودکار انجام میدهد.
اگر کانفیگها وصل نشدند، یک آیپی تمیز شناختهشده Cloudflare (مثل
104.21.x.xیا172.67.x.x) را در کلاینت خود به جای hostname وارد کنید.
- ریپو را fork کنید یا روی GitHub آپلود کنید.
- به railway.app بروید ← New Project ← Deploy from GitHub repo ← ریپو را انتخاب کنید. 3.صبر کنید تا deploy شود بعد از deploy یک url به شما داده میشود که ان دامنه سرویس شماست برای ورود به پنل کافیست به اخر دامنه تان /login اضافه کنید.
⭐ Railway از Cloudflare استفاده نمیکند و از آیپیهای اختصاصی خودش استفاده میکند.
آیپیهای خروجی Railway معمولاً در رنج
69.46.46.xهستند، بنابراین کانفیگهای شما از آیپیهای خود Railway عبور میکنند — نه از Cloudflare. این آیپیها ممکن است بسته به محدودیتهای شبکه شما در دسترس باشند یا نباشند.اگر کانفیگها روی Railway کار نکرد:
- بررسی کنید که رنج
69.46.46.xاز شبکه شما در دسترس است.- حالت Fragment را در کلاینت v2ray / v2rayNG فعال کنید (بخش زیر را ببینید).
- برای استفاده از آیپیهای تمیز Cloudflare، به Render بروید.
اگر کانفیگها وصل نمیشوند — بهخصوص روی Railway — حالت Fragment را فعال کنید:
v2rayNG (اندروید):
- به Settings → Fragment بروید
- Fragment را فعال کنید و تنظیم کنید: Packets روی
tlshello، Length روی10-30، Interval روی10-20 - مجدداً وصل شوید
v2ray (دسکتاپ): به outbound → streamSettings اضافه کنید:
"sockopt": {
"dialerProxy": "fragment",
"tcpKeepAliveIdle": 100
}حالت Fragment بسته TLS ClientHello را تقسیم میکند تا از فایروالهای DPI عبور کند.
pip install -r requirements.txt
python main.pyپنل در این آدرس در دسترس است: http://localhost:8000/login
بعد از استقرار روی Render،Railway از این آدرس وارد پنل شوید:
https://yourdomain/login
| متغیر | توضیح | پیشفرض |
|---|---|---|
ADMIN_PASSWORD |
رمز ورود به پنل | admin |
SECRET_KEY |
مخفی session و هش (خودکار تولید میشود) | تصادفی |
PORT |
پورت سرور | 8000 |
⚠️ بعد از استقرار در محیط عمومی،ADMIN_PASSWORDرا تغییر دهید.
fastapi==0.104.1
uvicorn==0.24.0
websockets==12.0
httpx==0.25.1
psutil==5.9.6
| پلتفرم | آیپی استاتیک؟ | توضیحات |
|---|---|---|
| Render (رایگان) | ❌ خیر | آیپیهای مشترک Cloudflare؛ تمیز و پایدار |
| Render (پولی) | ✅ بله | از پلان Starter به بالا در دسترس |
| Railway | ✅ اختیاری | از طریق Settings → Networking → Static IP فعال شود (ویژگی پولی) |
| متد | مسیر | توضیح |
|---|---|---|
POST |
/api/login |
ورود با رمز |
POST |
/api/logout |
خروج |
GET |
/api/me |
بررسی وضعیت session |
POST |
/api/change-password |
تغییر رمز ادمین |
| متد | مسیر | توضیح |
|---|---|---|
GET |
/api/links |
لیست همه اینباندها |
POST |
/api/links |
ایجاد اینباند جدید |
PATCH |
/api/links/{uid} |
ویرایش اینباند |
DELETE |
/api/links/{uid} |
حذف اینباند |
GET |
/api/links/{uid}/sub |
دریافت اطلاعات اشتراک |
| متد | مسیر | توضیح |
|---|---|---|
GET |
/sub/{uid} |
اشتراک Base64 (سازگار با v2ray/Hiddify) |
| متد | مسیر | توضیح |
|---|---|---|
GET |
/api/addresses |
لیست آدرسهای جایگزین |
POST |
/api/addresses |
افزودن آدرس |
DELETE |
/api/addresses/{index} |
حذف آدرس |
| متد | مسیر | توضیح |
|---|---|---|
GET |
/stats |
آمار سرور (نیاز به احراز هویت) |
GET |
/health |
بررسی سلامت سرور |
vless://<uuid>@<domain>:443?encryption=none&security=tls&type=ws&host=<domain>&path=/ws/<uuid>&sni=<domain>&fp=chrome&alpn=http/1.1#Luffy-<name>
| صفحه | توضیح |
|---|---|
| داشبورد | ترافیک، آپتایم، CPU/حافظه، نمودار ساعتی |
| اینباندها | ایجاد/ویرایش/حذف کاربر، کپی کانفیگ، کد QR |
| ترافیک | آمار کلی |
| آیپی تمیز | مدیریت آدرسهای جایگزین اشتراک |
| امنیت | تغییر رمز |
- پنل را باز کنید و به اینباندها بروید.
- روی Sub کلیک کنید تا لینک اشتراک کپی شود.
- در اپ کلاینت، یک اشتراک جدید با آن لینک اضافه کنید.
- اشتراک را آپدیت کنید — کانفیگها بهصورت خودکار نمایش داده میشوند.
- تمام دادهها در حافظه ذخیره میشوند. با ریستارت سرویس، همه اینباندها و آمار ترافیک پاک میشوند.
- برای ذخیرهسازی دائمی، نیاز به اضافه کردن دیتابیس (مثلاً SQLite) وجود دارد.
- تسک keep-alive هر ۱۰ دقیقه به
/healthپینگ میزند تا از خواب رفتن سرویس رایگان Render جلوگیری کند.
MIT — آزادانه استفاده و ویرایش کنید.