Compare commits
8 Commits
v2.5.0
...
Group_Mana
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
04c6b2722b | ||
|
|
94d651fc93 | ||
|
|
aae0cb37b7 | ||
|
|
b922d986d6 | ||
|
|
8a7cffd63f | ||
|
|
c8e8c97afc | ||
|
|
46ba4c4518 | ||
|
|
a787ab497c |
2
.github/workflows/release.yml
vendored
2
.github/workflows/release.yml
vendored
@@ -83,7 +83,7 @@ jobs:
|
||||
cd x-ui/bin
|
||||
|
||||
# Download dependencies
|
||||
Xray_URL="https://github.com/XTLS/Xray-core/releases/download/v25.1.1/"
|
||||
Xray_URL="https://github.com/XTLS/Xray-core/releases/download/v25.1.30/"
|
||||
if [ "${{ matrix.platform }}" == "amd64" ]; then
|
||||
wget -q ${Xray_URL}Xray-linux-64.zip
|
||||
unzip Xray-linux-64.zip
|
||||
|
||||
@@ -27,7 +27,7 @@ case $1 in
|
||||
esac
|
||||
mkdir -p build/bin
|
||||
cd build/bin
|
||||
wget -q "https://github.com/XTLS/Xray-core/releases/download/v25.1.1/Xray-linux-${ARCH}.zip"
|
||||
wget -q "https://github.com/XTLS/Xray-core/releases/download/v25.1.30/Xray-linux-${ARCH}.zip"
|
||||
unzip "Xray-linux-${ARCH}.zip"
|
||||
rm -f "Xray-linux-${ARCH}.zip" geoip.dat geosite.dat
|
||||
mv xray "xray-linux-${FNAME}"
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
[English](/README.md) | [中文](/README.zh_CN.md) | [Español](/README.es_ES.md) | [Русский](/README.ru_RU.md)
|
||||
[English](/README.md) | [فارسی](/README.fa_IR.md) | [中文](/README.zh_CN.md) | [Español](/README.es_ES.md) | [Русский](/README.ru_RU.md)
|
||||
|
||||
<p align="center">
|
||||
<picture>
|
||||
|
||||
527
README.fa_IR.md
Normal file
527
README.fa_IR.md
Normal file
@@ -0,0 +1,527 @@
|
||||
[English](/README.md) | [فارسی](/README.fa_IR.md) | [中文](/README.zh_CN.md) | [Español](/README.es_ES.md) | [Русский](/README.ru_RU.md)
|
||||
|
||||
<p align="center">
|
||||
<picture>
|
||||
<source media="(prefers-color-scheme: dark)" srcset="./media/3x-ui-dark.png">
|
||||
<img alt="3x-ui" src="./media/3x-ui-light.png">
|
||||
</picture>
|
||||
</p>
|
||||
|
||||
**یک پنل وب پیشرفته • ساخته شده بر پایه Xray Core**
|
||||
|
||||
[](https://github.com/MHSanaei/3x-ui/releases)
|
||||
[](#)
|
||||
[](#)
|
||||
[](#)
|
||||
[](https://www.gnu.org/licenses/gpl-3.0.en.html)
|
||||
|
||||
> **سلب مسئولیت:** این پروژه صرفاً برای اهداف آموزشی و تحقیقاتی است. استفاده از آن برای مقاصد غیرقانونی یا در محیطهای عملیاتی ممنوع است.
|
||||
|
||||
**اگر این پروژه برای شما مفید بوده، میتوانید با دادن یک**:star2: از آن حمایت کنید.
|
||||
|
||||
<p align="left">
|
||||
<a href="https://buymeacoffee.com/mhsanaei" target="_blank">
|
||||
<img src="./media/buymeacoffe.png" alt="Image">
|
||||
</a>
|
||||
</p>
|
||||
|
||||
- USDT (TRC20): `TXncxkvhkDWGts487Pjqq1qT9JmwRUz8CC`
|
||||
- MATIC (polygon): `0x41C9548675D044c6Bfb425786C765bc37427256A`
|
||||
- LTC (Litecoin): `ltc1q2ach7x6d2zq0n4l0t4zl7d7xe2s6fs7a3vspwv`
|
||||
|
||||
## نصب و ارتقا
|
||||
|
||||
```
|
||||
bash <(curl -Ls https://raw.githubusercontent.com/mhsanaei/3x-ui/master/install.sh)
|
||||
```
|
||||
|
||||
## نصب نسخههای قدیمی (توصیه نمیشود)
|
||||
|
||||
برای نصب نسخه خاصی از دستور زیر استفاده کنید. مثال برای نسخه `v1.7.9`:
|
||||
|
||||
```
|
||||
VERSION=v1.7.9 && bash <(curl -Ls "https://raw.githubusercontent.com/mhsanaei/3x-ui/$VERSION/install.sh") $VERSION
|
||||
```
|
||||
|
||||
## گواهی SSL
|
||||
|
||||
<details>
|
||||
<summary>جزئیات گواهی SSL</summary>
|
||||
|
||||
### ACME
|
||||
|
||||
برای مدیریت گواهیهای SSL با استفاده از ACME:
|
||||
|
||||
1. اطمینان حاصل کنید دامنه شما به درستی به سرور متصل است.
|
||||
2. دستور `x-ui` را در ترمینال اجرا کرده و گزینه `مدیریت گواهی SSL` را انتخاب کنید.
|
||||
3. گزینههای زیر نمایش داده میشوند:
|
||||
|
||||
- **دریافت SSL:** دریافت گواهی SSL
|
||||
- **لغو:** لغو گواهیهای موجود
|
||||
- **تمدید اجباری:** تمدید اجباری گواهیها
|
||||
- **نمایش دامنههای موجود:** نمایش تمام دامنههای دارای گواهی
|
||||
- **تنظیم مسیر گواهی برای پنل:** تنظیم مسیر گواهی برای دامنه شما
|
||||
|
||||
### Certbot
|
||||
|
||||
نصب و استفاده از Certbot:
|
||||
|
||||
```sh
|
||||
apt-get install certbot -y
|
||||
certbot certonly --standalone --agree-tos --register-unsafely-without-email -d yourdomain.com
|
||||
certbot renew --dry-run
|
||||
```
|
||||
|
||||
### Cloudflare
|
||||
|
||||
اسکریپت داخلی برای دریافت گواهی SSL از Cloudflare. نیازمند:
|
||||
|
||||
- ایمیل ثبتشده در Cloudflare
|
||||
- کلید API جهانی Cloudflare
|
||||
- دامنه باید از طریق Cloudflare به سرور متصل باشد
|
||||
|
||||
**دریافت کلید API جهانی Cloudflare:**
|
||||
|
||||
1. دستور `x-ui` را اجرا و گزینه `گواهی SSL کلادفلر` را انتخاب کنید.
|
||||
2. به لینک [Cloudflare API Tokens](https://dash.cloudflare.com/profile/api-tokens) مراجعه کنید.
|
||||
3. روی "View Global API Key" کلیک کنید:
|
||||

|
||||
4. پس از احراز هویت، کلید API نمایش داده میشود:
|
||||

|
||||
|
||||
در هنگام استفاده، نام دامنه، ایمیل و کلید API را وارد کنید:
|
||||

|
||||
|
||||
</details>
|
||||
|
||||
## نصب دستی و ارتقا
|
||||
|
||||
<details>
|
||||
<summary>جزئیات نصب دستی</summary>
|
||||
|
||||
#### استفاده
|
||||
|
||||
1. دریافت آخرین نسخه از سرور:
|
||||
|
||||
```sh
|
||||
ARCH=$(uname -m)
|
||||
case "${ARCH}" in
|
||||
x86_64 | x64 | amd64) XUI_ARCH="amd64" ;;
|
||||
i*86 | x86) XUI_ARCH="386" ;;
|
||||
armv8* | armv8 | arm64 | aarch64) XUI_ARCH="arm64" ;;
|
||||
armv7* | armv7) XUI_ARCH="armv7" ;;
|
||||
armv6* | armv6) XUI_ARCH="armv6" ;;
|
||||
armv5* | armv5) XUI_ARCH="armv5" ;;
|
||||
s390x) echo 's390x' ;;
|
||||
*) XUI_ARCH="amd64" ;;
|
||||
esac
|
||||
|
||||
wget https://github.com/MHSanaei/3x-ui/releases/latest/download/x-ui-linux-${XUI_ARCH}.tar.gz
|
||||
```
|
||||
|
||||
2. نصب یا ارتقا:
|
||||
|
||||
```sh
|
||||
ARCH=$(uname -m)
|
||||
case "${ARCH}" in
|
||||
x86_64 | x64 | amd64) XUI_ARCH="amd64" ;;
|
||||
i*86 | x86) XUI_ARCH="386" ;;
|
||||
armv8* | armv8 | arm64 | aarch64) XUI_ARCH="arm64" ;;
|
||||
armv7* | armv7) XUI_ARCH="armv7" ;;
|
||||
armv6* | armv6) XUI_ARCH="armv6" ;;
|
||||
armv5* | armv5) XUI_ARCH="armv5" ;;
|
||||
s390x) echo 's390x' ;;
|
||||
*) XUI_ARCH="amd64" ;;
|
||||
esac
|
||||
|
||||
cd /root/
|
||||
rm -rf x-ui/ /usr/local/x-ui/ /usr/bin/x-ui
|
||||
tar zxvf x-ui-linux-${XUI_ARCH}.tar.gz
|
||||
chmod +x x-ui/x-ui x-ui/bin/xray-linux-* x-ui/x-ui.sh
|
||||
cp x-ui/x-ui.sh /usr/bin/x-ui
|
||||
cp -f x-ui/x-ui.service /etc/systemd/system/
|
||||
mv x-ui/ /usr/local/
|
||||
systemctl daemon-reload
|
||||
systemctl enable x-ui
|
||||
systemctl restart x-ui
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
## نصب با Docker
|
||||
|
||||
<details>
|
||||
<summary>جزئیات Docker</summary>
|
||||
|
||||
#### استفاده
|
||||
|
||||
1. **نصب Docker:**
|
||||
|
||||
```sh
|
||||
bash <(curl -sSL https://get.docker.com)
|
||||
```
|
||||
|
||||
2. **کلون پروژه:**
|
||||
|
||||
```sh
|
||||
git clone https://github.com/MHSanaei/3x-ui.git
|
||||
cd 3x-ui
|
||||
```
|
||||
|
||||
3. **راهاندازی سرویس:**
|
||||
|
||||
```sh
|
||||
docker compose up -d
|
||||
```
|
||||
|
||||
یا
|
||||
|
||||
```sh
|
||||
docker run -itd \
|
||||
-e XRAY_VMESS_AEAD_FORCED=false \
|
||||
-v $PWD/db/:/etc/x-ui/ \
|
||||
-v $PWD/cert/:/root/cert/ \
|
||||
--network=host \
|
||||
--restart=unless-stopped \
|
||||
--name 3x-ui \
|
||||
ghcr.io/mhsanaei/3x-ui:latest
|
||||
```
|
||||
|
||||
4. **بهروزرسانی:**
|
||||
|
||||
```sh
|
||||
cd 3x-ui
|
||||
docker compose down
|
||||
docker compose pull 3x-ui
|
||||
docker compose up -d
|
||||
```
|
||||
|
||||
5. **حذف:**
|
||||
|
||||
```sh
|
||||
docker stop 3x-ui
|
||||
docker rm 3x-ui
|
||||
cd --
|
||||
rm -r 3x-ui
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
## تنظیمات Nginx
|
||||
<details>
|
||||
<summary>پیکربندی Reverse Proxy</summary>
|
||||
|
||||
#### Nginx Reverse Proxy
|
||||
```nginx
|
||||
location / {
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
proxy_set_header Host $http_host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header Range $http_range;
|
||||
proxy_set_header If-Range $http_if_range;
|
||||
proxy_redirect off;
|
||||
proxy_pass http://127.0.0.1:2053;
|
||||
}
|
||||
```
|
||||
|
||||
#### مسیر فرعی در Nginx
|
||||
- اطمینان حاصل کنید "URI Path" در تنظیمات پنل یکسان باشد.
|
||||
- `url` در تنظیمات پنل باید با `/` پایان یابد.
|
||||
|
||||
```nginx
|
||||
location /sub {
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
proxy_set_header Host $http_host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header Range $http_range;
|
||||
proxy_set_header If-Range $http_if_range;
|
||||
proxy_redirect off;
|
||||
proxy_pass http://127.0.0.1:2053;
|
||||
}
|
||||
```
|
||||
</details>
|
||||
|
||||
## سیستمعاملهای توصیه شده
|
||||
|
||||
- Ubuntu 20.04+
|
||||
- Debian 11+
|
||||
- CentOS 8+
|
||||
- OpenEuler 22.03+
|
||||
- Fedora 36+
|
||||
- Arch Linux
|
||||
- Parch Linux
|
||||
- Manjaro
|
||||
- Armbian
|
||||
- AlmaLinux 8.0+
|
||||
- Rocky Linux 8+
|
||||
- Oracle Linux 8+
|
||||
- OpenSUSE Tubleweed
|
||||
- Amazon Linux 2023
|
||||
- Windows x64
|
||||
|
||||
## معماریها و دستگاههای پشتیبانی شده
|
||||
|
||||
<details>
|
||||
<summary>جزئیات معماریها و دستگاهها</summary>
|
||||
|
||||
- **amd64**: معماری استاندارد برای کامپیوترهای شخصی و سرورها
|
||||
- **x86 / i386**: سیستمهای دسکتاپ و لپتاپ
|
||||
- **armv8 / arm64 / aarch64**: دستگاههای موبایل و embedded مانند Raspberry Pi 4
|
||||
- **armv7 / arm / arm32**: دستگاههای قدیمی مانند Orange Pi Zero
|
||||
- **armv6 / arm / arm32**: دستگاههای بسیار قدیمی مانند Raspberry Pi 1
|
||||
- **armv5 / arm / arm32**: سیستمهای embedded قدیمی
|
||||
- **s390x**: کامپیوترهای IBM mainframe
|
||||
</details>
|
||||
|
||||
## زبانهای پشتیبانی شده
|
||||
|
||||
- انگلیسی
|
||||
- فارسی
|
||||
- چینی سنتی
|
||||
- چینی سادهشده
|
||||
- ژاپنی
|
||||
- روسی
|
||||
- ویتنامی
|
||||
- اسپانیایی
|
||||
- اندونزیایی
|
||||
- اوکراینی
|
||||
- ترکی
|
||||
- پرتغالی (برزیل)
|
||||
|
||||
## ویژگیها
|
||||
|
||||
- مانیتورینگ وضعیت سیستم
|
||||
- جستجو در بین inboundها و کلاینتها
|
||||
- تم تاریک/روشن
|
||||
- پشتیبانی از چند کاربر و پروتکل
|
||||
- پروتکلهای VMESS، VLESS، Trojan، Shadowsocks، Dokodemo-door، Socks، HTTP، WireGuard
|
||||
- پشتیبانی از XTLS شامل RPRX-Direct، Vision، REALITY
|
||||
- آمار ترافیک، محدودیت ترافیک، محدودیت زمانی
|
||||
- تنظیمات سفارشی Xray
|
||||
- پشتیبانی از HTTPS برای پنل
|
||||
- دریافت خودکار گواهی SSL
|
||||
- مسیرهای API اصلاح شده
|
||||
- پشتیبانی از تغییر تنظیمات از طریق پنل
|
||||
- امکان export/import دیتابیس
|
||||
|
||||
## تنظیمات پیشفرض پنل
|
||||
|
||||
<details>
|
||||
<summary>جزئیات تنظیمات پیشفرض</summary>
|
||||
|
||||
### نام کاربری، رمز عبور، پورت و مسیر وب
|
||||
|
||||
در صورت عدم تغییر، این موارد به صورت تصادفی ایجاد میشوند (به جز Docker).
|
||||
|
||||
**تنظیمات پیشفرض Docker:**
|
||||
- **نام کاربری:** admin
|
||||
- **رمز عبور:** admin
|
||||
- **پورت:** 2053
|
||||
|
||||
### مدیریت دیتابیس:
|
||||
|
||||
امکان Backup و Restore دیتابیس از طریق پنل.
|
||||
|
||||
- **مسیر دیتابیس:**
|
||||
- `/etc/x-ui/x-ui.db`
|
||||
|
||||
### مسیر پایه وب
|
||||
|
||||
1. **بازنشانی مسیر:**
|
||||
- اجرای دستور `x-ui`
|
||||
- انتخاب گزینه `Reset Web Base Path`
|
||||
|
||||
2. **ساخت یا تنظیم مسیر:**
|
||||
- مسیر به صورت تصادفی ساخته شده یا قابل تنظیم است
|
||||
|
||||
3. **مشاهده تنظیمات فعلی:**
|
||||
- استفاده از دستور `x-ui settings` یا `View Current Settings` در `x-ui`
|
||||
|
||||
**توصیه امنیتی:**
|
||||
- استفاده از مسیرهای طولانی و تصادفی برای افزایش امنیت
|
||||
|
||||
**مثال:**
|
||||
- `http://ip:port/*webbasepath*/panel`
|
||||
- `http://domain:port/*webbasepath*/panel`
|
||||
|
||||
</details>
|
||||
|
||||
## پیکربندی WARP
|
||||
|
||||
<details>
|
||||
<summary>جزئیات WARP</summary>
|
||||
|
||||
#### استفاده
|
||||
|
||||
**برای نسخههای `v2.1.0` و جدیدتر:**
|
||||
|
||||
WARP به صورت داخلی پشتیبانی میشود. تنها نیاز به فعالسازی در پنل است.
|
||||
|
||||
</details>
|
||||
|
||||
## محدودیت IP
|
||||
|
||||
<details>
|
||||
<summary>جزئیات محدودیت IP</summary>
|
||||
|
||||
#### استفاده
|
||||
|
||||
**توجه:** محدودیت IP در صورت استفاده از IP Tunnel کار نمیکند.
|
||||
|
||||
- **تا نسخه `v1.6.1`:**
|
||||
- محدودیت IP به صورت داخلی در پنل وجود دارد
|
||||
|
||||
**برای نسخههای `v1.7.0` و جدیدتر:**
|
||||
|
||||
برای فعالسازی نیاز به نصب `fail2ban` است:
|
||||
|
||||
1. اجرای دستور `x-ui` و انتخاب `مدیریت محدودیت IP`
|
||||
2. گزینههای موجود:
|
||||
|
||||
- **تغییر مدت زمان Ban**
|
||||
- **حذف تمام Banها**
|
||||
- **مشاهده لاگها**
|
||||
- **وضعیت Fail2ban**
|
||||
- **راهاندازی مجدد Fail2ban**
|
||||
- **حذف Fail2ban**
|
||||
|
||||
3. تنظیم مسیر `Access log` در پنل به `./access.log` و ذخیره و راهاندازی مجدد Xray
|
||||
|
||||
- **قبل از نسخه `v2.1.3`:**
|
||||
- تنظیم دستی `access.log` در تنظیمات Xray:
|
||||
|
||||
```sh
|
||||
"log": {
|
||||
"access": "./access.log",
|
||||
"dnsLog": false,
|
||||
"loglevel": "warning"
|
||||
},
|
||||
```
|
||||
|
||||
- **از نسخه `v2.1.3`:**
|
||||
- امکان تنظیم `access.log` از طریق پنل
|
||||
|
||||
</details>
|
||||
|
||||
## ربات تلگرام
|
||||
|
||||
<details>
|
||||
<summary>جزئیات ربات تلگرام</summary>
|
||||
|
||||
#### استفاده
|
||||
|
||||
ربات تلگرام برای اطلاعرسانی ترافیک، ورود به پنل، Backup دیتابیس و ... استفاده میشود. نیازمند تنظیم:
|
||||
|
||||
- توکن تلگرام
|
||||
- Chat ID ادمینها
|
||||
- زمان اطلاعرسانی (Cron syntax)
|
||||
- اطلاعرسانی انقضا
|
||||
- اطلاعرسانی ترافیک
|
||||
- Backup دیتابیس
|
||||
- اطلاعرسانی مصرف CPU
|
||||
|
||||
**سینتکس نمونه:**
|
||||
|
||||
- `30 \* \* \* \* \*` - اطلاع در ثانیه 30 هر دقیقه
|
||||
- `@hourly` - هر ساعت
|
||||
- `@daily` - هر روز
|
||||
|
||||
### ویژگیهای ربات
|
||||
|
||||
- گزارش دورهای
|
||||
- اطلاع ورود به پنل
|
||||
- اطلاع مصرف CPU
|
||||
- اطلاع پیشاز موعد انقضا و ترافیک
|
||||
- گزارش ترافیک کلاینتها
|
||||
- منوی مبتنی بر دستور
|
||||
- جستجوی کلاینت بر اساس ایمیل
|
||||
- بررسی inboundها
|
||||
- بررسی وضعیت سرور
|
||||
- دریافت Backup
|
||||
- چندزبانه
|
||||
|
||||
### راهاندازی ربات
|
||||
|
||||
- شروع [Botfather](https://t.me/BotFather) در تلگرام:
|
||||

|
||||
|
||||
- ساخت ربات جدید با دستور /newbot:
|
||||

|
||||
|
||||
- شروع ربات ساخته شده:
|
||||

|
||||
|
||||
- تنظیمات پنل:
|
||||

|
||||
|
||||
وارد کردن توکن و Chat ID (دریافت از [این ربات](https://t.me/useridinfobot)):
|
||||

|
||||
|
||||
</details>
|
||||
|
||||
## مسیرهای API
|
||||
|
||||
<details>
|
||||
<summary>جزئیات API</summary>
|
||||
|
||||
#### استفاده
|
||||
|
||||
- [مستندات API](https://www.postman.com/hsanaei/3x-ui/collection/q1l5l0u/3x-ui)
|
||||
- `/login` با `POST` داده کاربر: `{username: '', password: ''}`
|
||||
|
||||
| Method | مسیر | عملکرد |
|
||||
| :----: | ---------------------------------- | ------------------------------------------- |
|
||||
| `GET` | `"/list"` | دریافت تمام inboundها |
|
||||
| `GET` | `"/get/:id"` | دریافت inbound بر اساس id |
|
||||
| `POST` | `"/add"` | افزودن inbound |
|
||||
| `POST` | `"/del/:id"` | حذف inbound |
|
||||
|
||||
- [<img src="https://run.pstmn.io/button.svg" alt="Run In Postman" style="width: 128px; height: 32px;">](https://app.getpostman.com/run-collection/5146551-dda3cab3-0e33-485f-96f9-d4262f437ac5?action=collection%2Ffork&source=rip_markdown&collection-url=entityId%3D5146551-dda3cab3-0e33-485f-96f9-d4262f437ac5%26entityType%3Dcollection%26workspaceId%3Dd64f609f-485a-4951-9b8f-876b3f917124)
|
||||
</details>
|
||||
|
||||
## متغیرهای محیطی
|
||||
|
||||
<details>
|
||||
<summary>جزئیات متغیرها</summary>
|
||||
|
||||
#### استفاده
|
||||
|
||||
| متغیر | نوع | پیشفرض |
|
||||
| ------------- | :--------------------------------------------: | :------------ |
|
||||
| XUI_LOG_LEVEL | `"debug"` \| `"info"` \| `"warn"` \| `"error"` | `"info"` |
|
||||
| XUI_DEBUG | `boolean` | `false` |
|
||||
| XUI_BIN_FOLDER| `string` | `"bin"` |
|
||||
|
||||
مثال:
|
||||
|
||||
```sh
|
||||
XUI_BIN_FOLDER="bin" XUI_DB_FOLDER="/etc/x-ui" go build main.go
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
## پیشنمایش
|
||||
|
||||
<picture>
|
||||
<source media="(prefers-color-scheme: dark)" srcset="./media/01-overview-dark.png">
|
||||
<img alt="3x-ui" src="./media/01-overview-light.png">
|
||||
</picture>
|
||||
<picture>
|
||||
<source media="(prefers-color-scheme: dark)" srcset="./media/02-inbounds-dark.png">
|
||||
<img alt="3x-ui" src="./media/02-inbounds-light.png">
|
||||
</picture>
|
||||
|
||||
## قدردانی ویژه از
|
||||
|
||||
- [alireza0](https://github.com/alireza0/)
|
||||
|
||||
## تشکر و قدردانی
|
||||
|
||||
- [Iran v2ray rules](https://github.com/chocolate4u/Iran-v2ray-rules) (مجوز: **GPL-3.0**)
|
||||
- [Russia v2ray rules](https://github.com/runetfreedom/russia-v2ray-rules-dat) (مجوز: **GPL-3.0**)
|
||||
|
||||
## Stargazers over Time
|
||||
|
||||
[](https://starchart.cc/MHSanaei/3x-ui)
|
||||
@@ -1,4 +1,4 @@
|
||||
[English](/README.md) | [中文](/README.zh_CN.md) | [Español](/README.es_ES.md) | [Русский](/README.ru_RU.md)
|
||||
[English](/README.md) | [فارسی](/README.fa_IR.md) | [中文](/README.zh_CN.md) | [Español](/README.es_ES.md) | [Русский](/README.ru_RU.md)
|
||||
|
||||
<p align="center">
|
||||
<picture>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
[English](/README.md) | [中文](/README.zh_CN.md) | [Español](/README.es_ES.md) | [Русский](/README.ru_RU.md)
|
||||
[English](/README.md) | [فارسی](/README.fa_IR.md) | [中文](/README.zh_CN.md) | [Español](/README.es_ES.md) | [Русский](/README.ru_RU.md)
|
||||
|
||||
<p align="center">
|
||||
<picture>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
[English](/README.md) | [中文](/README.zh_CN.md) | [Español](/README.es_ES.md) | [Русский](/README.ru_RU.md)
|
||||
[English](/README.md) | [فارسی](/README.fa_IR.md) | [中文](/README.zh_CN.md) | [Español](/README.es_ES.md) | [Русский](/README.ru_RU.md)
|
||||
|
||||
<p align="center">
|
||||
<picture>
|
||||
|
||||
@@ -1 +1 @@
|
||||
2.5.0
|
||||
2.5.1
|
||||
@@ -26,20 +26,35 @@ const (
|
||||
)
|
||||
|
||||
func initModels() error {
|
||||
models := []interface{}{
|
||||
// Order matters: first create tables without dependencies
|
||||
baseModels := []interface{}{
|
||||
&model.User{},
|
||||
&model.Inbound{},
|
||||
&model.OutboundTraffics{},
|
||||
&model.Setting{},
|
||||
&model.InboundClientIps{},
|
||||
&xray.ClientTraffic{},
|
||||
}
|
||||
for _, model := range models {
|
||||
|
||||
// Migrate base models
|
||||
for _, model := range baseModels {
|
||||
if err := db.AutoMigrate(model); err != nil {
|
||||
log.Printf("Error auto migrating model: %v", err)
|
||||
log.Printf("Error auto migrating base model: %v", err)
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// Then migrate models with dependencies
|
||||
dependentModels := []interface{}{
|
||||
&model.Inbound{},
|
||||
&model.OutboundTraffics{},
|
||||
&model.InboundClientIps{},
|
||||
&xray.ClientTraffic{},
|
||||
}
|
||||
|
||||
for _, model := range dependentModels {
|
||||
if err := db.AutoMigrate(model); err != nil {
|
||||
log.Printf("Error auto migrating dependent model: %v", err)
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
@@ -29,14 +29,14 @@ type User struct {
|
||||
|
||||
type Inbound struct {
|
||||
Id int `json:"id" form:"id" gorm:"primaryKey;autoIncrement"`
|
||||
UserId int `json:"-"`
|
||||
UserId int `json:"-" gorm:"index"`
|
||||
Up int64 `json:"up" form:"up"`
|
||||
Down int64 `json:"down" form:"down"`
|
||||
Total int64 `json:"total" form:"total"`
|
||||
Remark string `json:"remark" form:"remark"`
|
||||
Enable bool `json:"enable" form:"enable"`
|
||||
ExpiryTime int64 `json:"expiryTime" form:"expiryTime"`
|
||||
ClientStats []xray.ClientTraffic `gorm:"foreignKey:InboundId;references:Id" json:"clientStats" form:"clientStats"`
|
||||
ClientStats []xray.ClientTraffic `gorm:"foreignKey:InboundId;references:Id;constraint:OnDelete:CASCADE" json:"clientStats"`
|
||||
|
||||
// config part
|
||||
Listen string `json:"listen" form:"listen"`
|
||||
|
||||
16
go.mod
16
go.mod
@@ -3,18 +3,18 @@ module x-ui
|
||||
go 1.23.5
|
||||
|
||||
require (
|
||||
github.com/gin-contrib/gzip v1.2.0
|
||||
github.com/gin-contrib/gzip v1.2.2
|
||||
github.com/gin-contrib/sessions v1.0.2
|
||||
github.com/gin-gonic/gin v1.10.0
|
||||
github.com/goccy/go-json v0.10.4
|
||||
github.com/goccy/go-json v0.10.5
|
||||
github.com/mymmrac/telego v0.32.0
|
||||
github.com/nicksnyder/go-i18n/v2 v2.5.0
|
||||
github.com/nicksnyder/go-i18n/v2 v2.5.1
|
||||
github.com/op/go-logging v0.0.0-20160315200505-970db520ece7
|
||||
github.com/pelletier/go-toml/v2 v2.2.3
|
||||
github.com/robfig/cron/v3 v3.0.1
|
||||
github.com/shirou/gopsutil/v4 v4.24.12
|
||||
github.com/shirou/gopsutil/v4 v4.25.1
|
||||
github.com/valyala/fasthttp v1.58.0
|
||||
github.com/xtls/xray-core v1.8.25-0.20250126155934-7b59379d73c3
|
||||
github.com/xtls/xray-core v1.8.25-0.20250130105737-0a8470cb14eb
|
||||
go.uber.org/atomic v1.11.0
|
||||
golang.org/x/text v0.21.0
|
||||
google.golang.org/grpc v1.70.0
|
||||
@@ -39,7 +39,7 @@ require (
|
||||
github.com/go-playground/validator/v10 v10.24.0 // indirect
|
||||
github.com/go-task/slim-sprig/v3 v3.0.0 // indirect
|
||||
github.com/google/btree v1.1.3 // indirect
|
||||
github.com/google/pprof v0.0.0-20250125003558-7fdb3d7e6fa0 // indirect
|
||||
github.com/google/pprof v0.0.0-20250202011525-fc3143867406 // indirect
|
||||
github.com/gorilla/context v1.1.2 // indirect
|
||||
github.com/gorilla/securecookie v1.1.2 // indirect
|
||||
github.com/gorilla/sessions v1.4.0 // indirect
|
||||
@@ -84,7 +84,7 @@ require (
|
||||
go4.org/netipx v0.0.0-20231129151722-fdeea329fbba // indirect
|
||||
golang.org/x/arch v0.13.0 // indirect
|
||||
golang.org/x/crypto v0.32.0 // indirect
|
||||
golang.org/x/exp v0.0.0-20250106191152-7588d65b2ba8 // indirect
|
||||
golang.org/x/exp v0.0.0-20250128182459-e0ece0dbea4c // indirect
|
||||
golang.org/x/mod v0.22.0 // indirect
|
||||
golang.org/x/net v0.34.0 // indirect
|
||||
golang.org/x/sync v0.10.0 // indirect
|
||||
@@ -93,7 +93,7 @@ require (
|
||||
golang.org/x/tools v0.29.0 // indirect
|
||||
golang.zx2c4.com/wintun v0.0.0-20230126152724-0fa3db229ce2 // indirect
|
||||
golang.zx2c4.com/wireguard v0.0.0-20231211153847-12269c276173 // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250124145028-65684f501c47 // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250127172529-29210b9bc287 // indirect
|
||||
google.golang.org/protobuf v1.36.4 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
gvisor.dev/gvisor v0.0.0-20240320123526-dc6abceb7ff0 // indirect
|
||||
|
||||
36
go.sum
36
go.sum
@@ -29,8 +29,8 @@ github.com/gabriel-vasile/mimetype v1.4.8 h1:FfZ3gj38NjllZIeJAmMhr+qKL8Wu+nOoI3G
|
||||
github.com/gabriel-vasile/mimetype v1.4.8/go.mod h1:ByKUIKGjh1ODkGM1asKUbQZOLGrPjydw3hYPU2YU9t8=
|
||||
github.com/ghodss/yaml v1.0.1-0.20220118164431-d8423dcdf344 h1:Arcl6UOIS/kgO2nW3A65HN+7CMjSDP/gofXL4CZt1V4=
|
||||
github.com/ghodss/yaml v1.0.1-0.20220118164431-d8423dcdf344/go.mod h1:GIjDIg/heH5DOkXY3YJ/wNhfHsQHoXGjl8G8amsYQ1I=
|
||||
github.com/gin-contrib/gzip v1.2.0 h1:JzN6DT3/xYL5zAdviN1ORNzKeklrwafXCIDKIR+qmUA=
|
||||
github.com/gin-contrib/gzip v1.2.0/go.mod h1:C1a5cacjlDsS20cKnHlZRCPUu57D3qH6B2pV0rl+Y/s=
|
||||
github.com/gin-contrib/gzip v1.2.2 h1:iUU/EYCM8ENfkjmZaVrxbjF/ZC267Iqv5S0MMCMEliI=
|
||||
github.com/gin-contrib/gzip v1.2.2/go.mod h1:C1a5cacjlDsS20cKnHlZRCPUu57D3qH6B2pV0rl+Y/s=
|
||||
github.com/gin-contrib/sessions v1.0.2 h1:UaIjUvTH1cMeOdj3in6dl+Xb6It8RiKRF9Z1anbUyCA=
|
||||
github.com/gin-contrib/sessions v1.0.2/go.mod h1:KxKxWqWP5LJVDCInulOl4WbLzK2KSPlLesfZ66wRvMs=
|
||||
github.com/gin-contrib/sse v1.0.0 h1:y3bT1mUWUxDpW4JLQg/HnTqV4rozuW4tC9eFKTxYI9E=
|
||||
@@ -54,8 +54,8 @@ github.com/go-playground/validator/v10 v10.24.0 h1:KHQckvo8G6hlWnrPX4NJJ+aBfWNAE
|
||||
github.com/go-playground/validator/v10 v10.24.0/go.mod h1:GGzBIJMuE98Ic/kJsBXbz1x/7cByt++cQ+YOuDM5wus=
|
||||
github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI=
|
||||
github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8=
|
||||
github.com/goccy/go-json v0.10.4 h1:JSwxQzIqKfmFX1swYPpUThQZp/Ka4wzJdK0LWVytLPM=
|
||||
github.com/goccy/go-json v0.10.4/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M=
|
||||
github.com/goccy/go-json v0.10.5 h1:Fq85nIqj+gXn/S5ahsiTlK3TmC85qgirsdTP/+DeaC4=
|
||||
github.com/goccy/go-json v0.10.5/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M=
|
||||
github.com/golang/mock v1.7.0-rc.1 h1:YojYx61/OLFsiv6Rw1Z96LpldJIy31o+UHmwAUMJ6/U=
|
||||
github.com/golang/mock v1.7.0-rc.1/go.mod h1:s42URUywIqd+OcERslBJvOjepvNymP31m3q8d/GkuRs=
|
||||
github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=
|
||||
@@ -67,8 +67,8 @@ github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeN
|
||||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0=
|
||||
github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
github.com/google/pprof v0.0.0-20250125003558-7fdb3d7e6fa0 h1:my2ucqBZmv+cWHIhZNSIYKzgN8EBGyHdC7zD5sASRAg=
|
||||
github.com/google/pprof v0.0.0-20250125003558-7fdb3d7e6fa0/go.mod h1:vavhavw2zAxS5dIdcRluK6cSGGPlZynqzFM8NdvU144=
|
||||
github.com/google/pprof v0.0.0-20250202011525-fc3143867406 h1:wlQI2cYY0BsWmmPPAnxfQ8SDW0S3Jasn+4B8kXFxprg=
|
||||
github.com/google/pprof v0.0.0-20250202011525-fc3143867406/go.mod h1:vavhavw2zAxS5dIdcRluK6cSGGPlZynqzFM8NdvU144=
|
||||
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
|
||||
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/gorilla/context v1.1.2 h1:WRkNAv2uoa03QNIc1A6u4O7DAGMUVoopZhkiXWA2V1o=
|
||||
@@ -105,8 +105,8 @@ github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWE
|
||||
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
||||
github.com/mattn/go-sqlite3 v1.14.24 h1:tpSp2G2KyMnnQu99ngJ47EIkWVmliIizyZBfPrBWDRM=
|
||||
github.com/mattn/go-sqlite3 v1.14.24/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y=
|
||||
github.com/miekg/dns v1.1.62 h1:cN8OuEF1/x5Rq6Np+h1epln8OiyPWV+lROx9LxcGgIQ=
|
||||
github.com/miekg/dns v1.1.62/go.mod h1:mvDlcItzm+br7MToIKqkglaGhlFMHJ9DTNNWONWXbNQ=
|
||||
github.com/miekg/dns v1.1.63 h1:8M5aAw6OMZfFXTT7K5V0Eu5YiiL8l7nUAkyN6C9YwaY=
|
||||
github.com/miekg/dns v1.1.63/go.mod h1:6NGHfjhpmr5lt3XPLuyfDJi5AXbNIPM9PY6H6sF1Nfs=
|
||||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
@@ -114,8 +114,8 @@ github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9G
|
||||
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
|
||||
github.com/mymmrac/telego v0.32.0 h1:4X8C1l3k+opkk86r95+eQE8DxiS2LYlR61L/G7yreDY=
|
||||
github.com/mymmrac/telego v0.32.0/go.mod h1:qS6NaRhJgcuEEBEMVCV79S2xCAuHq9O+ixwfLuRW31M=
|
||||
github.com/nicksnyder/go-i18n/v2 v2.5.0 h1:3wH1gpaekcgGuwzWdSu7JwJhH9Tk87k1ezt0i1p2/Is=
|
||||
github.com/nicksnyder/go-i18n/v2 v2.5.0/go.mod h1:DrhgsSDZxoAfvVrBVLXoxZn/pN5TXqaDbq7ju94viiQ=
|
||||
github.com/nicksnyder/go-i18n/v2 v2.5.1 h1:IxtPxYsR9Gp60cGXjfuR/llTqV8aYMsC472zD0D1vHk=
|
||||
github.com/nicksnyder/go-i18n/v2 v2.5.1/go.mod h1:DrhgsSDZxoAfvVrBVLXoxZn/pN5TXqaDbq7ju94viiQ=
|
||||
github.com/onsi/ginkgo/v2 v2.22.2 h1:/3X8Panh8/WwhU/3Ssa6rCKqPLuAkVY2I0RoyDLySlU=
|
||||
github.com/onsi/ginkgo/v2 v2.22.2/go.mod h1:oeMosUL+8LtarXBHu/c0bx2D/K9zyQ6uX3cTyztHwsk=
|
||||
github.com/onsi/gomega v1.36.2 h1:koNYke6TVk6ZmnyHrCXba/T/MoLBXFjeC1PtvYgw0A8=
|
||||
@@ -152,8 +152,8 @@ github.com/savsgio/gotils v0.0.0-20240704082632-aef3928b8a38 h1:D0vL7YNisV2yqE55
|
||||
github.com/savsgio/gotils v0.0.0-20240704082632-aef3928b8a38/go.mod h1:sM7Mt7uEoCeFSCBM+qBrqvEo+/9vdmj19wzp3yzUhmg=
|
||||
github.com/seiflotfy/cuckoofilter v0.0.0-20240715131351-a2f2c23f1771 h1:emzAzMZ1L9iaKCTxdy3Em8Wv4ChIAGnfiz18Cda70g4=
|
||||
github.com/seiflotfy/cuckoofilter v0.0.0-20240715131351-a2f2c23f1771/go.mod h1:bR6DqgcAl1zTcOX8/pE2Qkj9XO00eCNqmKb7lXP8EAg=
|
||||
github.com/shirou/gopsutil/v4 v4.24.12 h1:qvePBOk20e0IKA1QXrIIU+jmk+zEiYVVx06WjBRlZo4=
|
||||
github.com/shirou/gopsutil/v4 v4.24.12/go.mod h1:DCtMPAad2XceTeIAbGyVfycbYQNBGk2P8cvDi7/VN9o=
|
||||
github.com/shirou/gopsutil/v4 v4.25.1 h1:QSWkTc+fu9LTAWfkZwZ6j8MSUk4A2LV7rbH0ZqmLjXs=
|
||||
github.com/shirou/gopsutil/v4 v4.25.1/go.mod h1:RoUCUpndaJFtT+2zsZzzmhvbfGoDCJ7nFXKJf8GqJbI=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
||||
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
|
||||
@@ -190,8 +190,8 @@ github.com/vishvananda/netns v0.0.5 h1:DfiHV+j8bA32MFM7bfEunvT8IAqQ/NzSJHtcmW5zd
|
||||
github.com/vishvananda/netns v0.0.5/go.mod h1:SpkAiCQRtJ6TvvxPnOSyH3BMl6unz3xZlaprSwhNNJM=
|
||||
github.com/xtls/reality v0.0.0-20240909153216-e26ae2305463 h1:g1Cj7d+my6k/HHxLAyxPwyX8i7FGRr6ulBDMkBzg2BM=
|
||||
github.com/xtls/reality v0.0.0-20240909153216-e26ae2305463/go.mod h1:BjIOLmkEEtAgloAiVUcYj0Mt+YU00JARZw8AEU0IwAg=
|
||||
github.com/xtls/xray-core v1.8.25-0.20250126155934-7b59379d73c3 h1:JzofxKb13MvNZeSLPS9B07Few0fu11dPEa40EQNV/hE=
|
||||
github.com/xtls/xray-core v1.8.25-0.20250126155934-7b59379d73c3/go.mod h1:KmpYBu4IFdODX7qgG7DP7v9sHJBcHpdKE+qxUZ2N304=
|
||||
github.com/xtls/xray-core v1.8.25-0.20250130105737-0a8470cb14eb h1:VBzDZ4XHT9FM0S3qvXp6KuTOk7mXQQm0pjOW0Neeog4=
|
||||
github.com/xtls/xray-core v1.8.25-0.20250130105737-0a8470cb14eb/go.mod h1:EKhNEDY/WIB+ylEbVv2pzUaP08W/lt0sYmJQ9FJruko=
|
||||
github.com/xyproto/randomstring v1.0.5 h1:YtlWPoRdgMu3NZtP45drfy1GKoojuR7hmRcnhZqKjWU=
|
||||
github.com/xyproto/randomstring v1.0.5/go.mod h1:rgmS5DeNXLivK7YprL0pY+lTuhNQW3iGxZ18UQApw/E=
|
||||
github.com/yusufpapurcu/wmi v1.2.4 h1:zFUKzehAFReQwLys1b/iSMl+JQGSCSjtVqQn9bBrPo0=
|
||||
@@ -216,8 +216,8 @@ golang.org/x/arch v0.13.0 h1:KCkqVVV1kGg0X87TFysjCJ8MxtZEIU4Ja/yXGeoECdA=
|
||||
golang.org/x/arch v0.13.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys=
|
||||
golang.org/x/crypto v0.32.0 h1:euUpcYgM8WcP71gNpTqQCn6rC2t6ULUPiOzfWaXVVfc=
|
||||
golang.org/x/crypto v0.32.0/go.mod h1:ZnnJkOaASj8g0AjIduWNlq2NRxL0PlBrbKVyZ6V/Ugc=
|
||||
golang.org/x/exp v0.0.0-20250106191152-7588d65b2ba8 h1:yqrTHse8TCMW1M1ZCP+VAR/l0kKxwaAIqN/il7x4voA=
|
||||
golang.org/x/exp v0.0.0-20250106191152-7588d65b2ba8/go.mod h1:tujkw807nyEEAamNbDrEGzRav+ilXA7PCRAd6xsmwiU=
|
||||
golang.org/x/exp v0.0.0-20250128182459-e0ece0dbea4c h1:KL/ZBHXgKGVmuZBZ01Lt57yE5ws8ZPSkkihmEyq7FXc=
|
||||
golang.org/x/exp v0.0.0-20250128182459-e0ece0dbea4c/go.mod h1:tujkw807nyEEAamNbDrEGzRav+ilXA7PCRAd6xsmwiU=
|
||||
golang.org/x/mod v0.22.0 h1:D4nJWe9zXqHOmWqj4VMOJhvzj7bEZg4wEYa759z1pH4=
|
||||
golang.org/x/mod v0.22.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY=
|
||||
golang.org/x/net v0.34.0 h1:Mb7Mrk043xzHgnRM88suvJFwzVrRfHEHJEl5/71CKw0=
|
||||
@@ -242,8 +242,8 @@ golang.zx2c4.com/wintun v0.0.0-20230126152724-0fa3db229ce2 h1:B82qJJgjvYKsXS9jeu
|
||||
golang.zx2c4.com/wintun v0.0.0-20230126152724-0fa3db229ce2/go.mod h1:deeaetjYA+DHMHg+sMSMI58GrEteJUUzzw7en6TJQcI=
|
||||
golang.zx2c4.com/wireguard v0.0.0-20231211153847-12269c276173 h1:/jFs0duh4rdb8uIfPMv78iAJGcPKDeqAFnaLBropIC4=
|
||||
golang.zx2c4.com/wireguard v0.0.0-20231211153847-12269c276173/go.mod h1:tkCQ4FQXmpAgYVh++1cq16/dH4QJtmvpRv19DWGAHSA=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250124145028-65684f501c47 h1:91mG8dNTpkC0uChJUQ9zCiRqx3GEEFOWaRZ0mI6Oj2I=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250124145028-65684f501c47/go.mod h1:+2Yz8+CLJbIfL9z73EW45avw8Lmge3xVElCP9zEKi50=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250127172529-29210b9bc287 h1:J1H9f+LEdWAfHcez/4cvaVBox7cOYT+IU6rgqj5x++8=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250127172529-29210b9bc287/go.mod h1:8BS3B93F/U1juMFq9+EDk+qOT5CO1R9IzXxG3PTqiRk=
|
||||
google.golang.org/grpc v1.70.0 h1:pWFv03aZoHzlRKHWicjsZytKAiYCtNS0dHbXnIdq7jQ=
|
||||
google.golang.org/grpc v1.70.0/go.mod h1:ofIJqVKDXx/JiXrwr2IG4/zwdH9txy3IlF40RmcJSQw=
|
||||
google.golang.org/protobuf v1.36.4 h1:6A3ZDJHn/eNqc1i+IdefRzy/9PokBTPvcqMySR7NNIM=
|
||||
|
||||
@@ -283,4 +283,4 @@ install_x-ui() {
|
||||
|
||||
echo -e "${green}Running...${plain}"
|
||||
install_base
|
||||
install_x-ui $1
|
||||
install_x-ui $1
|
||||
@@ -1195,35 +1195,48 @@
|
||||
}
|
||||
},
|
||||
getSubGroupClients(dbInbounds, currentClient) {
|
||||
const response = {
|
||||
inbounds: [],
|
||||
clients: [],
|
||||
editIds: []
|
||||
const response = {
|
||||
inbounds: [],
|
||||
clients: [],
|
||||
editIds: [],
|
||||
};
|
||||
|
||||
if (!Array.isArray(dbInbounds) || dbInbounds.length === 0) {
|
||||
return response;
|
||||
}
|
||||
if (!currentClient || !currentClient.subId) {
|
||||
return response;
|
||||
}
|
||||
|
||||
dbInbounds.forEach((dbInboundItem) => {
|
||||
try {
|
||||
const dbInbound = new DBInbound(dbInboundItem);
|
||||
if (!dbInbound) {
|
||||
return;
|
||||
}
|
||||
if (dbInbounds && dbInbounds.length > 0 && currentClient) {
|
||||
dbInbounds.forEach((dbInboundItem) => {
|
||||
const dbInbound = new DBInbound(dbInboundItem);
|
||||
if (dbInbound) {
|
||||
const inbound = dbInbound.toInbound();
|
||||
if (inbound) {
|
||||
const clients = inbound.clients;
|
||||
if (clients.length > 0) {
|
||||
clients.forEach((client) => {
|
||||
if (client['subId'] === currentClient['subId']) {
|
||||
client['inboundId'] = dbInboundItem.id
|
||||
client['clientId'] = this.getClientId(dbInbound.protocol, client)
|
||||
response.inbounds.push(dbInboundItem.id)
|
||||
response.clients.push(client)
|
||||
response.editIds.push(client['clientId'])
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
const inbound = dbInbound.toInbound();
|
||||
if (!inbound || !Array.isArray(inbound.clients)) {
|
||||
return;
|
||||
}
|
||||
return response;
|
||||
},
|
||||
|
||||
inbound.clients.forEach((client) => {
|
||||
if (client.subId === currentClient.subId) {
|
||||
client.inboundId = dbInboundItem.id;
|
||||
client.clientId = this.getClientId(dbInbound.protocol, client);
|
||||
|
||||
response.inbounds.push(dbInboundItem.id);
|
||||
response.clients.push(client);
|
||||
response.editIds.push(client.clientId);
|
||||
}
|
||||
});
|
||||
} catch (error) {
|
||||
console.error("Error processing dbInboundItem:", dbInboundItem, error);
|
||||
}
|
||||
});
|
||||
|
||||
return response;
|
||||
},
|
||||
getClientId(protocol, client) {
|
||||
switch (protocol) {
|
||||
case Protocols.TROJAN: return client.password;
|
||||
|
||||
@@ -143,6 +143,7 @@
|
||||
</a-select>
|
||||
</a-col>
|
||||
</a-row>
|
||||
<setting-list-item type="switch" title='{{ i18n "pages.xray.outboundTraffic"}}' desc='{{ i18n "pages.xray.outboundTrafficDesc"}}' v-model="outboundTraffic"></setting-list-item>
|
||||
</a-list-item>
|
||||
</a-collapse-panel>
|
||||
<a-collapse-panel header='{{ i18n "pages.xray.logConfigs" }}'>
|
||||
@@ -1823,6 +1824,18 @@
|
||||
this.templateSettings = newTemplateSettings;
|
||||
}
|
||||
},
|
||||
outboundTraffic: {
|
||||
get: function () {
|
||||
if (!this.templateSettings || !this.templateSettings.policy.system || !this.templateSettings.policy.system.statsOutboundDownlink) return false;
|
||||
return this.templateSettings.policy.system.statsOutboundDownlink;
|
||||
},
|
||||
set: function (newValue) {
|
||||
newTemplateSettings = this.templateSettings;
|
||||
newTemplateSettings.policy.system.statsOutboundDownlink = newValue;
|
||||
newTemplateSettings.policy.system.statsOutboundUplink = newValue;
|
||||
this.templateSettings = newTemplateSettings;
|
||||
}
|
||||
},
|
||||
maskAddressLog: {
|
||||
get: function () {
|
||||
if (!this.templateSettings || !this.templateSettings.log || !this.templateSettings.log.maskAddress) return "";
|
||||
|
||||
@@ -373,6 +373,8 @@
|
||||
"errorLogDesc" = "The file path for the error log. The special value 'none' disabled error logs"
|
||||
"dnsLog" = "DNS Log"
|
||||
"dnsLogDesc" = "Whether to enable DNS query logs"
|
||||
"outboundTraffic" = "Outbounds Traffic"
|
||||
"outboundTrafficDesc" = "Whether to enable outbound traffic"
|
||||
"maskAddress" = "Mask Address"
|
||||
"maskAddressDesc" = "IP address mask, when enabled, will automatically replace the IP address that appears in the log."
|
||||
|
||||
|
||||
@@ -371,6 +371,8 @@
|
||||
"errorLogDesc" = "La ruta del archivo para el registro de errores. El valor especial 'none' desactiva los registros de errores."
|
||||
"dnsLog" = "Registro DNS"
|
||||
"dnsLogDesc" = "Si habilitar los registros de consulta DNS"
|
||||
"outboundTraffic" = "Tráfico saliente"
|
||||
"outboundTrafficDesc" = "Si se debe habilitar el tráfico saliente"
|
||||
"maskAddress" = "Enmascarar Dirección"
|
||||
"maskAddressDesc" = "Máscara de dirección IP, cuando se habilita, reemplazará automáticamente la dirección IP que aparece en el registro."
|
||||
|
||||
|
||||
@@ -373,6 +373,8 @@
|
||||
"errorLogDesc" = "مسیر فایل برای ورود به سیستم خطا. مقدار ویژه «هیچ» گزارش های خطا را غیرفعال میکند"
|
||||
"dnsLog" = "گزارش DNS"
|
||||
"dnsLogDesc" = "آیا ثبتهای درخواست DNS را فعال کنید"
|
||||
"outboundTraffic" = "ترافیک خروجی"
|
||||
"outboundTrafficDesc" = "فعال کردن ترافیک خروجی"
|
||||
"maskAddress" = "پنهان کردن آدرس"
|
||||
"maskAddressDesc" = "پوشش آدرس IP، هنگامی که فعال میشود، به طور خودکار آدرس IP که در لاگ ظاهر میشود را جایگزین میکند."
|
||||
|
||||
|
||||
@@ -373,6 +373,8 @@
|
||||
"errorLogDesc" = "Jalur file untuk log kesalahan. Nilai khusus 'tidak ada' menonaktifkan log kesalahan"
|
||||
"dnsLog" = "Log DNS"
|
||||
"dnsLogDesc" = "Apakah akan mengaktifkan log kueri DNS"
|
||||
"outboundTraffic" = "Lalu Lintas Keluar"
|
||||
"outboundTrafficDesc" = "Apakah mengaktifkan lalu lintas keluar"
|
||||
"maskAddress" = "Alamat Masker"
|
||||
"maskAddressDesc" = "Masker alamat IP, ketika diaktifkan, akan secara otomatis mengganti alamat IP yang muncul di log."
|
||||
|
||||
|
||||
@@ -373,6 +373,8 @@
|
||||
"errorLogDesc" = "エラーログのファイルパス。特殊値 'none' はエラーログを無効にします"
|
||||
"dnsLog" = "DNS ログ"
|
||||
"dnsLogDesc" = "DNSクエリのログを有効にするかどうか"
|
||||
"outboundTraffic" = "アウトバウンドトラフィック"
|
||||
"outboundTrafficDesc" = "アウトバウンドトラフィックを有効にするかどうか"
|
||||
"maskAddress" = "アドレスをマスク"
|
||||
"maskAddressDesc" = "IPアドレスをマスクし、有効にするとログに表示されるIPアドレスを自動的に置き換えます"
|
||||
|
||||
|
||||
@@ -373,6 +373,8 @@
|
||||
"errorLogDesc" = "O caminho do arquivo para o log de erros. O valor especial 'none' desativa os logs de erro."
|
||||
"dnsLog" = "Log DNS"
|
||||
"dnsLogDesc" = "Se ativar logs de consulta DNS"
|
||||
"outboundTraffic" = "Tráfego de saída"
|
||||
"outboundTrafficDesc" = "Se deve habilitar o tráfego de saída"
|
||||
"maskAddress" = "Mascarar Endereço"
|
||||
"maskAddressDesc" = "Máscara de endereço IP, quando ativado, substitui automaticamente o endereço IP que aparece no log."
|
||||
|
||||
|
||||
@@ -373,6 +373,8 @@
|
||||
"errorLogDesc" = "Путь к файлу журнала ошибок. Специальное значение «none» отключает журналы ошибок."
|
||||
"dnsLog" = "DNS Журнал"
|
||||
"dnsLogDesc" = "Включить логи запросов DNS"
|
||||
"outboundTraffic" = "Исходящий трафик"
|
||||
"outboundTrafficDesc" = "Включить исходящий трафик"
|
||||
"maskAddress" = "Маскировать Адрес"
|
||||
"maskAddressDesc" = "Маска IP-адреса, при активации автоматически заменяет IP-адрес, который появляется в логе."
|
||||
|
||||
|
||||
@@ -373,6 +373,8 @@
|
||||
"errorLogDesc" = "Hata günlüğü için dosya yolu. 'none' özel değeri hata günlüklerini devre dışı bırakır"
|
||||
"dnsLog" = "DNS Günlüğü"
|
||||
"dnsLogDesc" = "DNS sorgu günlüklerini etkinleştirin"
|
||||
"outboundTraffic" = "Gidenler trafiği"
|
||||
"outboundTrafficDesc" = "Çıkış trafiğini etkinleştirip etkinleştirmeyeceğiniz"
|
||||
"maskAddress" = "Adres Maskesi"
|
||||
"maskAddressDesc" = "IP adresi maskesi, etkinleştirildiğinde, günlükte görünen IP adresini otomatik olarak değiştirecektir."
|
||||
|
||||
|
||||
@@ -373,6 +373,8 @@
|
||||
"errorLogDesc" = "Шлях до файлу журналу помилок. Спеціальне значення 'none' вимикає журнали помилок"
|
||||
"dnsLog" = "Журнал DNS"
|
||||
"dnsLogDesc" = "Чи включити журнали запитів DNS"
|
||||
"outboundTraffic" = "Вихідний трафік"
|
||||
"outboundTrafficDesc" = "Чи потрібно увімкнути вихідний трафік"
|
||||
"maskAddress" = "Маскувати Адресу"
|
||||
"maskAddressDesc" = "Маска IP-адреси, при активації автоматично замінює IP-адресу, яка з'являється у журналі."
|
||||
|
||||
|
||||
@@ -373,6 +373,8 @@
|
||||
"errorLogDesc" = "Đường dẫn tệp cho nhật ký lỗi. Nhật ký lỗi bị vô hiệu hóa có giá trị đặc biệt 'không'"
|
||||
"dnsLog" = "Nhật ký DNS"
|
||||
"dnsLogDesc" = "Có bật nhật ký truy vấn DNS không"
|
||||
"outboundTraffic" = "Lưu lượng đi ra"
|
||||
"outboundTrafficDesc" = "Có nên bật lưu lượng ra không"
|
||||
"maskAddress" = "Ẩn Địa Chỉ"
|
||||
"maskAddressDesc" = "Mặt nạ địa chỉ IP, khi được bật, sẽ tự động thay thế địa chỉ IP xuất hiện trong nhật ký."
|
||||
|
||||
|
||||
@@ -373,6 +373,8 @@
|
||||
"errorLogDesc" = "错误日志的文件路径。特殊值 'none' 禁用错误日志"
|
||||
"dnsLog" = "DNS 日志"
|
||||
"dnsLogDesc" = "是否启用 DNS 查询日志"
|
||||
"outboundTraffic" = "出站流量"
|
||||
"outboundTrafficDesc" = "是否启用出站流量"
|
||||
"maskAddress" = "隐藏地址"
|
||||
"maskAddressDesc" = "IP 地址掩码,启用时会自动替换日志中出现的 IP 地址。"
|
||||
|
||||
|
||||
@@ -373,6 +373,8 @@
|
||||
"errorLogDesc" = "錯誤日誌的檔案路徑。特殊值 'none' 禁用錯誤日誌"
|
||||
"dnsLog" = "DNS 日誌"
|
||||
"dnsLogDesc" = "是否啟用 DNS 查詢日誌"
|
||||
"outboundTraffic" = "出站流量"
|
||||
"outboundTrafficDesc" = "是否啟用出站流量"
|
||||
"maskAddress" = "隱藏地址"
|
||||
"maskAddressDesc" = "IP 地址掩碼,啟用時會自動替換日誌中出現的 IP 地址。"
|
||||
|
||||
|
||||
@@ -2,9 +2,9 @@ package xray
|
||||
|
||||
type ClientTraffic struct {
|
||||
Id int `json:"id" form:"id" gorm:"primaryKey;autoIncrement"`
|
||||
InboundId int `json:"inboundId" form:"inboundId"`
|
||||
InboundId int `json:"inboundId" form:"inboundId" gorm:"index;not null"`
|
||||
Enable bool `json:"enable" form:"enable"`
|
||||
Email string `json:"email" form:"email" gorm:"unique"`
|
||||
Email string `json:"email" form:"email" gorm:"uniqueIndex"`
|
||||
Up int64 `json:"up" form:"up"`
|
||||
Down int64 `json:"down" form:"down"`
|
||||
ExpiryTime int64 `json:"expiryTime" form:"expiryTime"`
|
||||
|
||||
Reference in New Issue
Block a user