mirror of
https://github.com/MHSanaei/3x-ui.git
synced 2025-04-20 05:52:24 +00:00
Merge pull request #266 from hamid-gh98/main
[Support] change settings by different items in panel
This commit is contained in:
commit
dc7dbae14a
16 changed files with 1251 additions and 609 deletions
8
.github/workflows/release.yml
vendored
8
.github/workflows/release.yml
vendored
|
@ -14,7 +14,7 @@ jobs:
|
|||
- name: Set up Go
|
||||
uses: actions/setup-go@v4.0.0
|
||||
with:
|
||||
go-version: 'stable'
|
||||
go-version: "stable"
|
||||
- name: build linux amd64 version
|
||||
run: |
|
||||
CGO_ENABLED=1 GOOS=linux GOARCH=amd64 go build -o xui-release -v main.go
|
||||
|
@ -28,7 +28,7 @@ jobs:
|
|||
cd bin
|
||||
wget https://github.com/mhsanaei/Xray-core/releases/latest/download/Xray-linux-64.zip
|
||||
unzip Xray-linux-64.zip
|
||||
rm -f Xray-linux-64.zip geoip.dat geosite.dat
|
||||
rm -f Xray-linux-64.zip geoip.dat geosite.dat iran.dat
|
||||
wget https://github.com/Loyalsoldier/v2ray-rules-dat/releases/latest/download/geoip.dat
|
||||
wget https://github.com/Loyalsoldier/v2ray-rules-dat/releases/latest/download/geosite.dat
|
||||
wget https://github.com/bootmortis/iran-hosted-domains/releases/latest/download/iran.dat
|
||||
|
@ -54,7 +54,7 @@ jobs:
|
|||
- name: Set up Go
|
||||
uses: actions/setup-go@v4.0.0
|
||||
with:
|
||||
go-version: 'stable'
|
||||
go-version: "stable"
|
||||
- name: build linux arm64 version
|
||||
run: |
|
||||
sudo apt-get update
|
||||
|
@ -70,7 +70,7 @@ jobs:
|
|||
cd bin
|
||||
wget https://github.com/mhsanaei/xray-core/releases/latest/download/Xray-linux-arm64-v8a.zip
|
||||
unzip Xray-linux-arm64-v8a.zip
|
||||
rm -f Xray-linux-arm64-v8a.zip geoip.dat geosite.dat
|
||||
rm -f Xray-linux-arm64-v8a.zip geoip.dat geosite.dat iran.dat
|
||||
wget https://github.com/Loyalsoldier/v2ray-rules-dat/releases/latest/download/geoip.dat
|
||||
wget https://github.com/Loyalsoldier/v2ray-rules-dat/releases/latest/download/geosite.dat
|
||||
wget https://github.com/bootmortis/iran-hosted-domains/releases/latest/download/iran.dat
|
||||
|
|
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -1,5 +1,6 @@
|
|||
.idea
|
||||
tmp
|
||||
backup/
|
||||
bin/
|
||||
dist/
|
||||
x-ui-*.tar.gz
|
||||
|
@ -9,4 +10,5 @@ x-ui-*.tar.gz
|
|||
main
|
||||
release/
|
||||
access.log
|
||||
error.log
|
||||
.cache
|
||||
|
|
99
README.md
99
README.md
|
@ -1,11 +1,11 @@
|
|||
# 3x-ui
|
||||
|
||||
[](https://github.com/MHSanaei/3x-ui/releases)
|
||||
[](#)
|
||||
[](#)
|
||||
[](#)
|
||||
[](https://www.gnu.org/licenses/gpl-3.0.en.html)
|
||||
|
||||
|
||||
> **Disclaimer: This project is only for personal learning and communication, please do not use it for illegal purposes, please do not use it in a production environment**
|
||||
|
||||
**If you think this project is helpful to you, you may wish to give a** :star2:
|
||||
|
@ -17,20 +17,23 @@ xray panel supporting multi-protocol, **Multi-lang (English,Farsi,Chinese)**
|
|||
```
|
||||
bash <(curl -Ls https://raw.githubusercontent.com/mhsanaei/3x-ui/master/install.sh)
|
||||
```
|
||||
|
||||
## Install custom version
|
||||
|
||||
To install your desired version you can add the version to the end of install command. Example for ver `v1.0.9`:
|
||||
|
||||
```
|
||||
bash <(curl -Ls https://raw.githubusercontent.com/mhsanaei/3x-ui/master/install.sh) v1.0.9
|
||||
```
|
||||
|
||||
# SSL
|
||||
|
||||
```
|
||||
apt-get install certbot -y
|
||||
certbot certonly --standalone --agree-tos --register-unsafely-without-email -d yourdomain.com
|
||||
certbot renew --dry-run
|
||||
```
|
||||
|
||||
|
||||
|
||||
# Default settings
|
||||
|
||||
- Port: 2053
|
||||
|
@ -38,18 +41,57 @@ certbot renew --dry-run
|
|||
- database path: /etc/x-ui/x-ui.db
|
||||
- xray config path: /usr/local/x-ui/bin/config.json
|
||||
|
||||
before you set ssl on settings
|
||||
- http:// ip or domain:2053/xui
|
||||
Before you set ssl on settings
|
||||
|
||||
- http://ip:2053/xui
|
||||
- http://domain:2053/xui
|
||||
|
||||
After you set ssl on settings
|
||||
|
||||
- https://yourdomain:2053/xui
|
||||
|
||||
# Enable Traffic For Users:
|
||||
# Environment Variables
|
||||
|
||||
| Variable | Type | Default |
|
||||
| -------------- | :--------------------------------------------: | :------------ |
|
||||
| XUI_LOG_LEVEL | `"debug"` \| `"info"` \| `"warn"` \| `"error"` | `"info"` |
|
||||
| XUI_DEBUG | `boolean` | `false` |
|
||||
| XUI_BIN_FOLDER | `string` | `"bin"` |
|
||||
| XUI_DB_FOLDER | `string` | `"/etc/x-ui"` |
|
||||
|
||||
Example:
|
||||
|
||||
```sh
|
||||
XUI_BIN_FOLDER="bin" XUI_DB_FOLDER="/etc/x-ui" go build main.go
|
||||
```
|
||||
|
||||
# Xray Configurations:
|
||||
|
||||
**copy and paste to xray Configuration :** (you don't need to do this if you have a fresh install)
|
||||
- [enable traffic](./media/enable-traffic.txt)
|
||||
- [enable traffic+block all IR IP address](./media/enable-traffic+block-IR-IP.txt)
|
||||
- [enable traffic+block all IR domain](./media/enable-traffic+block-IR-domain.txt)
|
||||
|
||||
- [traffic](./media/configs/traffic.json)
|
||||
- [traffic + Block all Iran IP address](./media/configs/traffic+block-iran-ip.json)
|
||||
- [traffic + Block all Iran Domains](./media/configs/traffic+block-iran-domains.json)
|
||||
- [traffic + Block Ads + Use IPv4 for Google](./media/configs/traffic+block-ads+ipv4-google.json)
|
||||
- [traffic + Block Ads + Route Google + Netflix + Spotify + OpenAI (ChatGPT) to WARP](./media/configs/traffic+block-ads+warp.json)
|
||||
|
||||
# [WARP Configuration](https://github.com/fscarmen/warp) (Optional)
|
||||
|
||||
If you want to use routing to WARP follow steps as below:
|
||||
|
||||
1. Install WARP on **socks proxy mode**:
|
||||
|
||||
```sh
|
||||
curl -fsSL https://gist.githubusercontent.com/hamid-gh98/dc5dd9b0cc5b0412af927b1ccdb294c7/raw/install_warp_proxy.sh | bash
|
||||
```
|
||||
|
||||
2. Turn on the config you need in panel or [Copy and paste this file to Xray Configuration](./media/configs/traffic+block-ads+warp.json)
|
||||
|
||||
Config Features:
|
||||
|
||||
- Block Ads
|
||||
- Route Google + Netflix + Spotify + OpenAI (ChatGPT) to WARP
|
||||
- Fix Google 403 error
|
||||
|
||||
# Features
|
||||
|
||||
|
@ -64,7 +106,8 @@ After you set ssl on settings
|
|||
- Support https access panel (self-provided domain name + ssl certificate)
|
||||
- Support one-click SSL certificate application and automatic renewal
|
||||
- For more advanced configuration items, please refer to the panel
|
||||
- fix api routes (user setting will create with api)
|
||||
- Fix api routes (user setting will create with api)
|
||||
- Support to change configs by different items provided in panel
|
||||
|
||||
# Tg robot use
|
||||
|
||||
|
@ -81,8 +124,8 @@ Set the robot-related parameters in the panel background, including:
|
|||
|
||||
Reference syntax:
|
||||
|
||||
- 30 * * * * * //Notify at the 30s of each point
|
||||
- 0 */10 * * * * //Notify at the first second of each 10 minutes
|
||||
- 30 \* \* \* \* \* //Notify at the 30s of each point
|
||||
- 0 \*/10 \* \* \* \* //Notify at the first second of each 10 minutes
|
||||
- @hourly // hourly notification
|
||||
- @daily // Daily notification (00:00 in the morning)
|
||||
- @every 8h // notify every 8 hours
|
||||
|
@ -102,33 +145,34 @@ Reference syntax:
|
|||
- Check depleted users
|
||||
- Receive backup by request and in periodic reports
|
||||
|
||||
|
||||
## API routes
|
||||
|
||||
- `/login` with `PUSH` user data: `{username: '', password: ''}` for login
|
||||
- `/xui/API/inbounds` base for following actions:
|
||||
|
||||
| Method | Path | Action |
|
||||
| ------------- | ------------- | ------------- |
|
||||
| GET | "/list" | Get all inbounds |
|
||||
| GET | "/get/:id" | Get inbound with inbound.id |
|
||||
| POST | "/add" | Add inbound |
|
||||
| POST | "/del/:id" | Delete Inbound |
|
||||
| POST | "/update/:id" | Update Inbound |
|
||||
| POST | "/clientIps/:email" | Client Ip address |
|
||||
| POST | "/clearClientIps/:email" | Clear Client Ip address |
|
||||
| POST | "/addClient/" | Add Client to inbound |
|
||||
| POST | "/delClient/:email" | Delete Client |
|
||||
| POST | "/updateClient/:index" | Update Client |
|
||||
| POST | "/:id/resetClientTraffic/:email" | Reset Client's Traffic |
|
||||
| POST | "/resetAllTraffics" | Reset traffics of all inbounds |
|
||||
| POST | "/resetAllClientTraffics/:id" | Reset traffics of all clients in an inbound |
|
||||
| :----: | ---------------------------------- | ------------------------------------------- |
|
||||
| `GET` | `"/list"` | Get all inbounds |
|
||||
| `GET` | `"/get/:id"` | Get inbound with inbound.id |
|
||||
| `POST` | `"/add"` | Add inbound |
|
||||
| `POST` | `"/del/:id"` | Delete Inbound |
|
||||
| `POST` | `"/update/:id"` | Update Inbound |
|
||||
| `POST` | `"/clientIps/:email"` | Client Ip address |
|
||||
| `POST` | `"/clearClientIps/:email"` | Clear Client Ip address |
|
||||
| `POST` | `"/addClient/"` | Add Client to inbound |
|
||||
| `POST` | `"/delClient/:email"` | Delete Client |
|
||||
| `POST` | `"/updateClient/:index"` | Update Client |
|
||||
| `POST` | `"/:id/resetClientTraffic/:email"` | Reset Client's Traffic |
|
||||
| `POST` | `"/resetAllTraffics"` | Reset traffics of all inbounds |
|
||||
| `POST` | `"/resetAllClientTraffics/:id"` | Reset traffics of all clients in an inbound |
|
||||
|
||||
# A Special Thanks To
|
||||
|
||||
- [alireza0](https://github.com/alireza0/)
|
||||
- [FranzKafkaYu](https://github.com/FranzKafkaYu)
|
||||
|
||||
# Suggestion System
|
||||
|
||||
- Ubuntu 20.04+
|
||||
- Debian 10+
|
||||
- CentOS 8+
|
||||
|
@ -137,6 +181,7 @@ Reference syntax:
|
|||
# Buy Me a Coffee
|
||||
|
||||
[](#)
|
||||
|
||||
```
|
||||
TXncxkvhkDWGts487Pjqq1qT9JmwRUz8CC
|
||||
```
|
||||
|
|
88
media/configs/traffic+block-ads+ipv4-google.json
Normal file
88
media/configs/traffic+block-ads+ipv4-google.json
Normal file
|
@ -0,0 +1,88 @@
|
|||
{
|
||||
"log": {
|
||||
"loglevel": "warning",
|
||||
"access": "./access.log",
|
||||
"error": "./error.log"
|
||||
},
|
||||
"api": {
|
||||
"tag": "api",
|
||||
"services": ["HandlerService", "LoggerService", "StatsService"]
|
||||
},
|
||||
"inbounds": [
|
||||
{
|
||||
"tag": "api",
|
||||
"listen": "127.0.0.1",
|
||||
"port": 62789,
|
||||
"protocol": "dokodemo-door",
|
||||
"settings": {
|
||||
"address": "127.0.0.1"
|
||||
}
|
||||
}
|
||||
],
|
||||
"outbounds": [
|
||||
{
|
||||
"protocol": "freedom",
|
||||
"settings": {}
|
||||
},
|
||||
{
|
||||
"tag": "blocked",
|
||||
"protocol": "blackhole",
|
||||
"settings": {}
|
||||
},
|
||||
{
|
||||
"tag": "IPv4",
|
||||
"protocol": "freedom",
|
||||
"settings": {
|
||||
"domainStrategy": "UseIPv4"
|
||||
}
|
||||
}
|
||||
],
|
||||
"policy": {
|
||||
"levels": {
|
||||
"0": {
|
||||
"statsUserDownlink": true,
|
||||
"statsUserUplink": true
|
||||
}
|
||||
},
|
||||
"system": {
|
||||
"statsInboundDownlink": true,
|
||||
"statsInboundUplink": true
|
||||
}
|
||||
},
|
||||
"routing": {
|
||||
"domainStrategy": "IPIfNonMatch",
|
||||
"rules": [
|
||||
{
|
||||
"type": "field",
|
||||
"inboundTag": ["api"],
|
||||
"outboundTag": "api"
|
||||
},
|
||||
{
|
||||
"type": "field",
|
||||
"outboundTag": "blocked",
|
||||
"ip": ["geoip:private"]
|
||||
},
|
||||
{
|
||||
"type": "field",
|
||||
"outboundTag": "blocked",
|
||||
"protocol": ["bittorrent"]
|
||||
},
|
||||
{
|
||||
"type": "field",
|
||||
"outboundTag": "blocked",
|
||||
"domain": [
|
||||
"geosite:category-ads-all",
|
||||
"geosite:category-ads",
|
||||
"geosite:google-ads",
|
||||
"geosite:spotify-ads"
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "field",
|
||||
"outboundTag": "IPv4",
|
||||
"domain": ["geosite:google"]
|
||||
}
|
||||
]
|
||||
},
|
||||
"stats": {}
|
||||
}
|
98
media/configs/traffic+block-ads+warp.json
Normal file
98
media/configs/traffic+block-ads+warp.json
Normal file
|
@ -0,0 +1,98 @@
|
|||
{
|
||||
"log": {
|
||||
"loglevel": "warning",
|
||||
"access": "./access.log",
|
||||
"error": "./error.log"
|
||||
},
|
||||
"api": {
|
||||
"tag": "api",
|
||||
"services": ["HandlerService", "LoggerService", "StatsService"]
|
||||
},
|
||||
"inbounds": [
|
||||
{
|
||||
"tag": "api",
|
||||
"listen": "127.0.0.1",
|
||||
"port": 62789,
|
||||
"protocol": "dokodemo-door",
|
||||
"settings": {
|
||||
"address": "127.0.0.1"
|
||||
}
|
||||
}
|
||||
],
|
||||
"outbounds": [
|
||||
{
|
||||
"protocol": "freedom",
|
||||
"settings": {}
|
||||
},
|
||||
{
|
||||
"tag": "blocked",
|
||||
"protocol": "blackhole",
|
||||
"settings": {}
|
||||
},
|
||||
{
|
||||
"tag": "WARP",
|
||||
"protocol": "socks",
|
||||
"settings": {
|
||||
"servers": [
|
||||
{
|
||||
"address": "127.0.0.1",
|
||||
"port": 40000
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
],
|
||||
"policy": {
|
||||
"levels": {
|
||||
"0": {
|
||||
"statsUserDownlink": true,
|
||||
"statsUserUplink": true
|
||||
}
|
||||
},
|
||||
"system": {
|
||||
"statsInboundDownlink": true,
|
||||
"statsInboundUplink": true
|
||||
}
|
||||
},
|
||||
"routing": {
|
||||
"domainStrategy": "IPIfNonMatch",
|
||||
"rules": [
|
||||
{
|
||||
"type": "field",
|
||||
"inboundTag": ["api"],
|
||||
"outboundTag": "api"
|
||||
},
|
||||
{
|
||||
"type": "field",
|
||||
"outboundTag": "blocked",
|
||||
"ip": ["geoip:private"]
|
||||
},
|
||||
{
|
||||
"type": "field",
|
||||
"outboundTag": "blocked",
|
||||
"protocol": ["bittorrent"]
|
||||
},
|
||||
{
|
||||
"type": "field",
|
||||
"outboundTag": "blocked",
|
||||
"domain": [
|
||||
"geosite:category-ads-all",
|
||||
"geosite:category-ads",
|
||||
"geosite:google-ads",
|
||||
"geosite:spotify-ads"
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "field",
|
||||
"outboundTag": "WARP",
|
||||
"domain": [
|
||||
"geosite:google",
|
||||
"geosite:netflix",
|
||||
"geosite:spotify",
|
||||
"geosite:openai"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"stats": {}
|
||||
}
|
|
@ -1,25 +1,22 @@
|
|||
{
|
||||
"log": {
|
||||
"loglevel": "warning",
|
||||
"access": "./access.log"
|
||||
"access": "./access.log",
|
||||
"error": "./error.log"
|
||||
},
|
||||
"api": {
|
||||
"services": [
|
||||
"HandlerService",
|
||||
"LoggerService",
|
||||
"StatsService"
|
||||
],
|
||||
"tag": "api"
|
||||
"tag": "api",
|
||||
"services": ["HandlerService", "LoggerService", "StatsService"]
|
||||
},
|
||||
"inbounds": [
|
||||
{
|
||||
"tag": "api",
|
||||
"listen": "127.0.0.1",
|
||||
"port": 62789,
|
||||
"protocol": "dokodemo-door",
|
||||
"settings": {
|
||||
"address": "127.0.0.1"
|
||||
},
|
||||
"tag": "api"
|
||||
}
|
||||
}
|
||||
],
|
||||
"outbounds": [
|
||||
|
@ -28,16 +25,16 @@
|
|||
"settings": {}
|
||||
},
|
||||
{
|
||||
"tag": "blocked",
|
||||
"protocol": "blackhole",
|
||||
"settings": {},
|
||||
"tag": "blocked"
|
||||
"settings": {}
|
||||
}
|
||||
],
|
||||
"policy": {
|
||||
"levels": {
|
||||
"0": {
|
||||
"statsUserUplink": true,
|
||||
"statsUserDownlink": true
|
||||
"statsUserDownlink": true,
|
||||
"statsUserUplink": true
|
||||
}
|
||||
},
|
||||
"system": {
|
||||
|
@ -49,34 +46,29 @@
|
|||
"domainStrategy": "IPIfNonMatch",
|
||||
"rules": [
|
||||
{
|
||||
"inboundTag": [
|
||||
"api"
|
||||
],
|
||||
"outboundTag": "api",
|
||||
"type": "field"
|
||||
"type": "field",
|
||||
"inboundTag": ["api"],
|
||||
"outboundTag": "api"
|
||||
},
|
||||
{
|
||||
"ip": [
|
||||
"geoip:private"
|
||||
],
|
||||
"type": "field",
|
||||
"outboundTag": "blocked",
|
||||
"type": "field"
|
||||
"ip": ["geoip:private"]
|
||||
},
|
||||
{
|
||||
"type": "field",
|
||||
"outboundTag": "blocked",
|
||||
"protocol": [
|
||||
"bittorrent"
|
||||
],
|
||||
"type": "field"
|
||||
"protocol": ["bittorrent"]
|
||||
},
|
||||
{
|
||||
"type": "field",
|
||||
"outboundTag": "blocked",
|
||||
"domain": [
|
||||
"regexp:.+.ir$",
|
||||
"regexp:.*\\.ir$",
|
||||
"ext:iran.dat:ir",
|
||||
"ext:iran.dat:other"
|
||||
],
|
||||
"type": "field"
|
||||
"ext:iran.dat:other",
|
||||
"geosite:category-ir"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
|
@ -1,25 +1,22 @@
|
|||
{
|
||||
"log": {
|
||||
"loglevel": "warning",
|
||||
"access": "./access.log"
|
||||
"access": "./access.log",
|
||||
"error": "./error.log"
|
||||
},
|
||||
"api": {
|
||||
"services": [
|
||||
"HandlerService",
|
||||
"LoggerService",
|
||||
"StatsService"
|
||||
],
|
||||
"tag": "api"
|
||||
"tag": "api",
|
||||
"services": ["HandlerService", "LoggerService", "StatsService"]
|
||||
},
|
||||
"inbounds": [
|
||||
{
|
||||
"tag": "api",
|
||||
"listen": "127.0.0.1",
|
||||
"port": 62789,
|
||||
"protocol": "dokodemo-door",
|
||||
"settings": {
|
||||
"address": "127.0.0.1"
|
||||
},
|
||||
"tag": "api"
|
||||
}
|
||||
}
|
||||
],
|
||||
"outbounds": [
|
||||
|
@ -28,16 +25,16 @@
|
|||
"settings": {}
|
||||
},
|
||||
{
|
||||
"tag": "blocked",
|
||||
"protocol": "blackhole",
|
||||
"settings": {},
|
||||
"tag": "blocked"
|
||||
"settings": {}
|
||||
}
|
||||
],
|
||||
"policy": {
|
||||
"levels": {
|
||||
"0": {
|
||||
"statsUserUplink": true,
|
||||
"statsUserDownlink": true
|
||||
"statsUserDownlink": true,
|
||||
"statsUserUplink": true
|
||||
}
|
||||
},
|
||||
"system": {
|
||||
|
@ -49,32 +46,29 @@
|
|||
"domainStrategy": "IPIfNonMatch",
|
||||
"rules": [
|
||||
{
|
||||
"inboundTag": [
|
||||
"api"
|
||||
],
|
||||
"outboundTag": "api",
|
||||
"type": "field"
|
||||
"type": "field",
|
||||
"inboundTag": ["api"],
|
||||
"outboundTag": "api"
|
||||
},
|
||||
{
|
||||
"type": "field",
|
||||
"outboundTag": "blocked",
|
||||
"protocol": [
|
||||
"bittorrent"
|
||||
],
|
||||
"type": "field"
|
||||
"ip": ["geoip:private"]
|
||||
},
|
||||
{
|
||||
"type": "field",
|
||||
"outboundTag": "blocked",
|
||||
"ip": [
|
||||
"geoip:private"
|
||||
],
|
||||
"type": "field"
|
||||
"protocol": ["bittorrent"]
|
||||
},
|
||||
{
|
||||
"type": "field",
|
||||
"outboundTag": "blocked",
|
||||
"ip": [
|
||||
"geoip:ir"
|
||||
],
|
||||
"type": "field"
|
||||
"ip": ["geoip:private"]
|
||||
},
|
||||
{
|
||||
"type": "field",
|
||||
"outboundTag": "blocked",
|
||||
"ip": ["geoip:ir"]
|
||||
}
|
||||
]
|
||||
},
|
|
@ -1,25 +1,22 @@
|
|||
{
|
||||
"log": {
|
||||
"loglevel": "warning",
|
||||
"access": "./access.log"
|
||||
"access": "./access.log",
|
||||
"error": "./error.log"
|
||||
},
|
||||
"api": {
|
||||
"services": [
|
||||
"HandlerService",
|
||||
"LoggerService",
|
||||
"StatsService"
|
||||
],
|
||||
"tag": "api"
|
||||
"tag": "api",
|
||||
"services": ["HandlerService", "LoggerService", "StatsService"]
|
||||
},
|
||||
"inbounds": [
|
||||
{
|
||||
"tag": "api",
|
||||
"listen": "127.0.0.1",
|
||||
"port": 62789,
|
||||
"protocol": "dokodemo-door",
|
||||
"settings": {
|
||||
"address": "127.0.0.1"
|
||||
},
|
||||
"tag": "api"
|
||||
}
|
||||
}
|
||||
],
|
||||
"outbounds": [
|
||||
|
@ -28,16 +25,16 @@
|
|||
"settings": {}
|
||||
},
|
||||
{
|
||||
"tag": "blocked",
|
||||
"protocol": "blackhole",
|
||||
"settings": {},
|
||||
"tag": "blocked"
|
||||
"settings": {}
|
||||
}
|
||||
],
|
||||
"policy": {
|
||||
"levels": {
|
||||
"0": {
|
||||
"statsUserUplink": true,
|
||||
"statsUserDownlink": true
|
||||
"statsUserDownlink": true,
|
||||
"statsUserUplink": true
|
||||
}
|
||||
},
|
||||
"system": {
|
||||
|
@ -49,25 +46,19 @@
|
|||
"domainStrategy": "IPIfNonMatch",
|
||||
"rules": [
|
||||
{
|
||||
"inboundTag": [
|
||||
"api"
|
||||
],
|
||||
"outboundTag": "api",
|
||||
"type": "field"
|
||||
"type": "field",
|
||||
"inboundTag": ["api"],
|
||||
"outboundTag": "api"
|
||||
},
|
||||
{
|
||||
"type": "field",
|
||||
"outboundTag": "blocked",
|
||||
"ip": [
|
||||
"geoip:private"
|
||||
],
|
||||
"type": "field"
|
||||
"ip": ["geoip:private"]
|
||||
},
|
||||
{
|
||||
"type": "field",
|
||||
"outboundTag": "blocked",
|
||||
"protocol": [
|
||||
"bittorrent"
|
||||
],
|
||||
"type": "field"
|
||||
"protocol": ["bittorrent"]
|
||||
}
|
||||
]
|
||||
},
|
|
@ -37,6 +37,7 @@ func (a *SettingController) initRouter(g *gin.RouterGroup) {
|
|||
g.POST("/update", a.updateSetting)
|
||||
g.POST("/updateUser", a.updateUser)
|
||||
g.POST("/restartPanel", a.restartPanel)
|
||||
g.GET("/getDefaultJsonConfig", a.getDefaultJsonConfig)
|
||||
}
|
||||
|
||||
func (a *SettingController) getAllSetting(c *gin.Context) {
|
||||
|
@ -48,6 +49,15 @@ func (a *SettingController) getAllSetting(c *gin.Context) {
|
|||
jsonObj(c, allSetting, nil)
|
||||
}
|
||||
|
||||
func (a *SettingController) getDefaultJsonConfig(c *gin.Context) {
|
||||
defaultJsonConfig, err := a.settingService.GetDefaultJsonConfig()
|
||||
if err != nil {
|
||||
jsonMsg(c, I18n(c, "pages.setting.toasts.getSetting"), err)
|
||||
return
|
||||
}
|
||||
jsonObj(c, defaultJsonConfig, nil)
|
||||
}
|
||||
|
||||
func (a *SettingController) getDefaultSettings(c *gin.Context) {
|
||||
expireDiff, err := a.settingService.GetExpireDiff()
|
||||
if err != nil {
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
background: white;
|
||||
}
|
||||
</style>
|
||||
|
||||
<body>
|
||||
<a-layout id="app" v-cloak>
|
||||
{{ template "commonSider" . }}
|
||||
|
@ -35,9 +36,9 @@
|
|||
<a-button type="primary" :disabled="saveBtnDisable" @click="updateAllSetting">{{ i18n "pages.setting.save" }}</a-button>
|
||||
<a-button type="danger" :disabled="!saveBtnDisable" @click="restartPanel">{{ i18n "pages.setting.restartPanel" }}</a-button>
|
||||
</a-space>
|
||||
|
||||
<a-tabs default-active-key="1" :class="siderDrawer.isDarkTheme ? darkClass : ''">
|
||||
<a-tab-pane key="1" tab='{{ i18n "pages.setting.panelConfig"}}'>
|
||||
|
||||
<a-list item-layout="horizontal" :style="siderDrawer.isDarkTheme ? 'color: hsla(0,0%,100%,.65);': 'background: white;'">
|
||||
<setting-list-item type="text" title='{{ i18n "pages.setting.panelListeningIP"}}' desc='{{ i18n "pages.setting.panelListeningIPDesc"}}' v-model="allSetting.webListen"></setting-list-item>
|
||||
<setting-list-item type="number" title='{{ i18n "pages.setting.panelPort"}}' desc='{{ i18n "pages.setting.panelPortDesc"}}' v-model.number="allSetting.webPort"></setting-list-item>
|
||||
|
@ -51,6 +52,7 @@
|
|||
<a-col :lg="24" :xl="12">
|
||||
<a-list-item-meta title="Language" />
|
||||
</a-col>
|
||||
|
||||
<a-col :lg="24" :xl="12">
|
||||
<template>
|
||||
<a-select
|
||||
|
@ -61,8 +63,7 @@
|
|||
style="width: 100%"
|
||||
>
|
||||
<a-select-option :value="l.value" :label="l.value" v-for="l in supportLangs">
|
||||
<span role="img" aria-label="l.name" v-text="l.icon"></span>
|
||||
<span v-text="l.name"></span>
|
||||
<span role="img" aria-label="l.name" v-text="l.icon"></span> <span v-text="l.name"></span>
|
||||
</a-select-option>
|
||||
</a-select>
|
||||
</template>
|
||||
|
@ -71,50 +72,81 @@
|
|||
</a-list-item>
|
||||
</a-list>
|
||||
</a-tab-pane>
|
||||
|
||||
<a-tab-pane key="2" tab='{{ i18n "pages.setting.userSetting"}}'>
|
||||
<a-form :style="siderDrawer.isDarkTheme ? 'color: hsla(0,0%,100%,.65); padding: 20px;': 'background: white; padding: 20px;'">
|
||||
<a-form-item label='{{ i18n "pages.setting.oldUsername"}}'>
|
||||
<a-input v-model="user.oldUsername" style="max-width: 300px"></a-input>
|
||||
</a-form-item>
|
||||
<a-form-item label='{{ i18n "pages.setting.currentPassword"}}'>
|
||||
<a-input type="password" v-model="user.oldPassword"
|
||||
style="max-width: 300px"></a-input>
|
||||
<a-input type="password" v-model="user.oldPassword" style="max-width: 300px"></a-input>
|
||||
</a-form-item>
|
||||
<a-form-item label='{{ i18n "pages.setting.newUsername"}}'>
|
||||
<a-input v-model="user.newUsername" style="max-width: 300px"></a-input>
|
||||
</a-form-item>
|
||||
<a-form-item label='{{ i18n "pages.setting.newPassword"}}'>
|
||||
<a-input type="password" v-model="user.newPassword"
|
||||
style="max-width: 300px"></a-input>
|
||||
<a-input type="password" v-model="user.newPassword" style="max-width: 300px"></a-input>
|
||||
</a-form-item>
|
||||
<a-form-item>
|
||||
<!-- <a-button type="primary" @click="updateUser">Revise</a-button>-->
|
||||
<a-button type="primary" @click="updateUser">{{ i18n "confirm" }}</a-button>
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
</a-tab-pane>
|
||||
|
||||
<a-tab-pane key="3" tab='{{ i18n "pages.setting.xrayConfiguration"}}'>
|
||||
<a-list item-layout="horizontal" :style="siderDrawer.isDarkTheme ? 'color: hsla(0,0%,100%,.65);': 'background: white;'">
|
||||
<a-divider>{{ i18n "pages.setting.actions"}}</a-divider>
|
||||
<a-space direction="horizontal" style="padding: 0 20px">
|
||||
<a-button type="primary" @click="resetXrayConfigToDefault">{{ i18n "pages.setting.resetDefaultConfig" }}</a-button>
|
||||
</a-space>
|
||||
|
||||
<a-divider>{{ i18n "pages.setting.basicTemplate"}}</a-divider>
|
||||
<a-collapse>
|
||||
<a-collapse-panel header='{{ i18n "pages.setting.generalConfigs"}}'>
|
||||
<setting-list-item type="switch" title='{{ i18n "pages.setting.xrayConfigTorrent"}}' desc='{{ i18n "pages.setting.xrayConfigTorrentDesc"}}' v-model="torrentSettings"></setting-list-item>
|
||||
<setting-list-item type="switch" title='{{ i18n "pages.setting.xrayConfigPrivateIp"}}' desc='{{ i18n "pages.setting.xrayConfigPrivateIpDesc"}}' v-model="privateIpSettings"></setting-list-item>
|
||||
<setting-list-item type="switch" title='{{ i18n "pages.setting.xrayConfigAds"}}' desc='{{ i18n "pages.setting.xrayConfigAdsDesc"}}' v-model="AdsSettings"></setting-list-item>
|
||||
<setting-list-item type="switch" title='{{ i18n "pages.setting.xrayConfigPorn"}}' desc='{{ i18n "pages.setting.xrayConfigPornDesc"}}' v-model="PornSettings"></setting-list-item>
|
||||
</a-collapse-panel>
|
||||
<a-collapse-panel header='{{ i18n "pages.setting.countryConfigs"}}'>
|
||||
<setting-list-item type="switch" title='{{ i18n "pages.setting.xrayConfigIRIp"}}' desc='{{ i18n "pages.setting.xrayConfigIRIpDesc"}}' v-model="IRIpSettings"></setting-list-item>
|
||||
<setting-list-item type="switch" title='{{ i18n "pages.setting.xrayConfigIRdomain"}}' desc='{{ i18n "pages.setting.xrayConfigIRdomainDesc"}}' v-model="IRdomainSettings"></setting-list-item>
|
||||
<setting-list-item type="switch" title='{{ i18n "pages.setting.xrayConfigIRDomain"}}' desc='{{ i18n "pages.setting.xrayConfigIRDomainDesc"}}' v-model="IRDomainSettings"></setting-list-item>
|
||||
<setting-list-item type="switch" title='{{ i18n "pages.setting.xrayConfigChinaIp"}}' desc='{{ i18n "pages.setting.xrayConfigChinaIpDesc"}}' v-model="ChinaIpSettings"></setting-list-item>
|
||||
<setting-list-item type="switch" title='{{ i18n "pages.setting.xrayConfigChinaDomain"}}' desc='{{ i18n "pages.setting.xrayConfigChinaDomainDesc"}}' v-model="ChinaDomainSettings"></setting-list-item>
|
||||
<setting-list-item type="switch" title='{{ i18n "pages.setting.xrayConfigRussiaIp"}}' desc='{{ i18n "pages.setting.xrayConfigRussiaIpDesc"}}' v-model="RussiaIpSettings"></setting-list-item>
|
||||
<setting-list-item type="switch" title='{{ i18n "pages.setting.xrayConfigRussiaDomain"}}' desc='{{ i18n "pages.setting.xrayConfigRussiaDomainDesc"}}' v-model="RussiaDomainSettings"></setting-list-item>
|
||||
</a-collapse-panel>
|
||||
<a-collapse-panel header='{{ i18n "pages.setting.ipv4Configs"}}'>
|
||||
<setting-list-item type="switch" title='{{ i18n "pages.setting.xrayConfigGoogleIPv4"}}' desc='{{ i18n "pages.setting.xrayConfigGoogleIPv4Desc"}}' v-model="GoogleIPv4Settings"></setting-list-item>
|
||||
<setting-list-item type="switch" title='{{ i18n "pages.setting.xrayConfigNetflixIPv4"}}' desc='{{ i18n "pages.setting.xrayConfigNetflixIPv4Desc"}}' v-model="NetflixIPv4Settings"></setting-list-item>
|
||||
</a-collapse-panel>
|
||||
<a-collapse-panel header='{{ i18n "pages.setting.warpConfigs"}}'>
|
||||
<setting-list-item type="switch" title='{{ i18n "pages.setting.xrayConfigGoogleWARP"}}' desc='{{ i18n "pages.setting.xrayConfigGoogleWARPDesc"}}' v-model="GoogleWARPSettings"></setting-list-item>
|
||||
<setting-list-item type="switch" title='{{ i18n "pages.setting.xrayConfigOpenAIWARP"}}' desc='{{ i18n "pages.setting.xrayConfigOpenAIWARPDesc"}}' v-model="OpenAIWARPSettings"></setting-list-item>
|
||||
<setting-list-item type="switch" title='{{ i18n "pages.setting.xrayConfigNetflixWARP"}}' desc='{{ i18n "pages.setting.xrayConfigNetflixWARPDesc"}}' v-model="NetflixWARPSettings"></setting-list-item>
|
||||
<setting-list-item type="switch" title='{{ i18n "pages.setting.xrayConfigSpotifyWARP"}}' desc='{{ i18n "pages.setting.xrayConfigSpotifyWARPDesc"}}' v-model="SpotifyWARPSettings"></setting-list-item>
|
||||
<setting-list-item type="switch" title='{{ i18n "pages.setting.xrayConfigIRWARP"}}' desc='{{ i18n "pages.setting.xrayConfigIRWARPDesc"}}' v-model="IRWARPSettings"></setting-list-item>
|
||||
</a-collapse-panel>
|
||||
</a-collapse>
|
||||
|
||||
<a-divider>{{ i18n "pages.setting.advancedTemplate"}}</a-divider>
|
||||
<a-collapse>
|
||||
<a-collapse-panel header="{{ i18n "pages.setting.xrayConfigInbounds"}}">
|
||||
<a-collapse-panel header='{{ i18n "pages.setting.xrayConfigInbounds"}}'>
|
||||
<setting-list-item type="textarea" title='{{ i18n "pages.setting.xrayConfigInbounds"}}' desc='{{ i18n "pages.setting.xrayConfigInboundsDesc"}}' v-model="inboundSettings"></setting-list-item>
|
||||
</a-collapse-panel>
|
||||
<a-collapse-panel header="{{ i18n "pages.setting.xrayConfigOutbounds"}}">
|
||||
<a-collapse-panel header='{{ i18n "pages.setting.xrayConfigOutbounds"}}'>
|
||||
<setting-list-item type="textarea" title='{{ i18n "pages.setting.xrayConfigOutbounds"}}' desc='{{ i18n "pages.setting.xrayConfigOutboundsDesc"}}' v-model="outboundSettings"></setting-list-item>
|
||||
</a-collapse-panel>
|
||||
<a-collapse-panel header="{{ i18n "pages.setting.xrayConfigRoutings"}}">
|
||||
<a-collapse-panel header='{{ i18n "pages.setting.xrayConfigRoutings"}}'>
|
||||
<setting-list-item type="textarea" title='{{ i18n "pages.setting.xrayConfigRoutings"}}' desc='{{ i18n "pages.setting.xrayConfigRoutingsDesc"}}' v-model="routingRuleSettings"></setting-list-item>
|
||||
</a-collapse-panel>
|
||||
</a-collapse>
|
||||
|
||||
<a-divider>{{ i18n "pages.setting.completeTemplate"}}</a-divider>
|
||||
<setting-list-item type="textarea" title='{{ i18n "pages.setting.xrayConfigTemplate"}}' desc='{{ i18n "pages.setting.xrayConfigTemplateDesc"}}' v-model="allSetting.xrayTemplateConfig"></setting-list-item>
|
||||
</a-list>
|
||||
</a-tab-pane>
|
||||
|
||||
<a-tab-pane key="4" tab='{{ i18n "pages.setting.TGReminder"}}'>
|
||||
<a-list item-layout="horizontal" :style="siderDrawer.isDarkTheme ? 'color: hsla(0,0%,100%,.65);': 'background: white;'">
|
||||
<setting-list-item type="switch" title='{{ i18n "pages.setting.telegramBotEnable" }}' desc='{{ i18n "pages.setting.telegramBotEnableDesc" }}' v-model="allSetting.tgBotEnable"></setting-list-item>
|
||||
|
@ -125,6 +157,7 @@
|
|||
<setting-list-item type="number" title='{{ i18n "pages.setting.tgNotifyCpu" }}' desc='{{ i18n "pages.setting.tgNotifyCpuDesc" }}' v-model="allSetting.tgCpu" :min="0" :max="100"></setting-list-item>
|
||||
</a-list>
|
||||
</a-tab-pane>
|
||||
|
||||
<a-tab-pane key="5" tab='{{ i18n "pages.setting.otherSetting"}}'>
|
||||
<a-list item-layout="horizontal" :style="siderDrawer.isDarkTheme ? 'color: hsla(0,0%,100%,.65);': 'background: white;'">
|
||||
<setting-list-item type="text" title='{{ i18n "pages.setting.timeZonee"}}' desc='{{ i18n "pages.setting.timeZoneDesc"}}' v-model="allSetting.timeLocation"></setting-list-item>
|
||||
|
@ -150,7 +183,60 @@
|
|||
allSetting: new AllSetting(),
|
||||
saveBtnDisable: true,
|
||||
user: {},
|
||||
lang : getLang()
|
||||
lang: getLang(),
|
||||
ipv4Settings: {
|
||||
tag: "IPv4",
|
||||
protocol: "freedom",
|
||||
settings: {
|
||||
domainStrategy: "UseIPv4"
|
||||
}
|
||||
},
|
||||
warpSettings: {
|
||||
tag: "WARP",
|
||||
protocol: "socks",
|
||||
settings: {
|
||||
servers: [
|
||||
{
|
||||
address: "127.0.0.1",
|
||||
port: 40000
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
settingsData: {
|
||||
protocols: {
|
||||
bittorrent: ["bittorrent"],
|
||||
},
|
||||
ips: {
|
||||
local: ["geoip:private"],
|
||||
google: ["geoip:google"],
|
||||
cn: ["geoip:cn"],
|
||||
ir: ["geoip:ir"],
|
||||
ru: ["geoip:ru"],
|
||||
},
|
||||
domains: {
|
||||
ads: [
|
||||
"geosite:category-ads-all",
|
||||
"geosite:category-ads",
|
||||
"geosite:google-ads",
|
||||
"geosite:spotify-ads"
|
||||
],
|
||||
porn: ["geosite:category-porn"],
|
||||
openai: ["geosite:openai"],
|
||||
google: ["geosite:google"],
|
||||
spotify: ["geosite:spotify"],
|
||||
netflix: ["geosite:netflix"],
|
||||
cn: ["geosite:cn"],
|
||||
ru: ["geosite:category-ru-gov"],
|
||||
ir: [
|
||||
"regexp:.*\\.ir$",
|
||||
"ext:iran.dat:ir",
|
||||
"ext:iran.dat:other",
|
||||
"ext:iran.dat:ads",
|
||||
"geosite:category-ir"
|
||||
]
|
||||
},
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
loading(spinning = true) {
|
||||
|
@ -200,6 +286,82 @@
|
|||
await PromiseUtil.sleep(5000);
|
||||
location.reload();
|
||||
}
|
||||
},
|
||||
async resetXrayConfigToDefault() {
|
||||
this.loading(true);
|
||||
const msg = await HttpUtil.get("/xui/setting/getDefaultJsonConfig");
|
||||
this.loading(false);
|
||||
if (msg.success) {
|
||||
this.templateSettings = JSON.parse(JSON.stringify(msg.obj, null, 2));
|
||||
this.saveBtnDisable = true;
|
||||
}
|
||||
},
|
||||
checkRequiredOutbounds() {
|
||||
const newTemplateSettings = this.templateSettings;
|
||||
const haveIPv4Outbounds = newTemplateSettings.outbounds.some((o) => o?.tag === "IPv4");
|
||||
const haveIPv4Rules = newTemplateSettings.routing.rules.some((r) => r?.outboundTag === "IPv4");
|
||||
const haveWARPOutbounds = newTemplateSettings.outbounds.some((o) => o?.tag === "WARP");
|
||||
const haveWARPRules = newTemplateSettings.routing.rules.some((r) => r?.outboundTag === "WARP");
|
||||
if (haveWARPRules && !haveWARPOutbounds) {
|
||||
newTemplateSettings.outbounds.push(this.warpSettings);
|
||||
}
|
||||
if (haveIPv4Rules && !haveIPv4Outbounds) {
|
||||
newTemplateSettings.outbounds.push(this.ipv4Settings);
|
||||
}
|
||||
this.templateSettings = newTemplateSettings;
|
||||
},
|
||||
templateRuleGetter(routeSettings) {
|
||||
const { data, property, outboundTag } = routeSettings;
|
||||
let result = false;
|
||||
if (this.templateSettings != null) {
|
||||
this.templateSettings.routing.rules.forEach(
|
||||
(routingRule) => {
|
||||
if (
|
||||
routingRule.hasOwnProperty(property) &&
|
||||
routingRule.hasOwnProperty("outboundTag") &&
|
||||
routingRule.outboundTag === outboundTag
|
||||
) {
|
||||
if (data.includes(routingRule[property][0])) {
|
||||
result = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
return result;
|
||||
},
|
||||
templateRuleSetter(routeSettings) {
|
||||
const { newValue, data, property, outboundTag } = routeSettings;
|
||||
const oldTemplateSettings = this.templateSettings;
|
||||
const newTemplateSettings = oldTemplateSettings;
|
||||
if (newValue) {
|
||||
const propertyRule = {
|
||||
type: "field",
|
||||
outboundTag,
|
||||
[property]: data
|
||||
};
|
||||
newTemplateSettings.routing.rules.push(propertyRule);
|
||||
}
|
||||
else {
|
||||
const newRules = [];
|
||||
newTemplateSettings.routing.rules.forEach(
|
||||
(routingRule) => {
|
||||
if (
|
||||
routingRule.hasOwnProperty(property) &&
|
||||
routingRule.hasOwnProperty("outboundTag") &&
|
||||
routingRule.outboundTag === outboundTag
|
||||
) {
|
||||
if (data.includes(routingRule[property][0])) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
newRules.push(routingRule);
|
||||
}
|
||||
);
|
||||
newTemplateSettings.routing.rules = newRules;
|
||||
}
|
||||
this.templateSettings = newTemplateSettings;
|
||||
this.checkRequiredOutbounds();
|
||||
}
|
||||
},
|
||||
async mounted() {
|
||||
|
@ -240,140 +402,297 @@
|
|||
},
|
||||
torrentSettings: {
|
||||
get: function () {
|
||||
torrentFilter = false
|
||||
if(this.templateSettings != null){
|
||||
this.templateSettings.routing.rules.forEach(routingRule => {
|
||||
if(routingRule.hasOwnProperty("protocol")){
|
||||
if (routingRule.protocol[0] === "bittorrent" && routingRule.outboundTag == "blocked"){
|
||||
torrentFilter = true
|
||||
}
|
||||
}
|
||||
return this.templateRuleGetter({
|
||||
outboundTag: "blocked",
|
||||
property: "protocol",
|
||||
data: this.settingsData.protocols.bittorrent
|
||||
});
|
||||
}
|
||||
return torrentFilter
|
||||
},
|
||||
set: function (newValue) {
|
||||
newTemplateSettings = JSON.parse(this.allSetting.xrayTemplateConfig);
|
||||
if (newValue){
|
||||
newTemplateSettings.routing.rules.push(JSON.parse("{\"outboundTag\": \"blocked\",\"protocol\": [\"bittorrent\"],\"type\": \"field\"}"))
|
||||
}
|
||||
else {
|
||||
newTemplateSettings.routing.rules = [];
|
||||
this.templateSettings.routing.rules.forEach(routingRule => {
|
||||
if (routingRule.hasOwnProperty('protocol')){
|
||||
if (routingRule.protocol[0] === "bittorrent" && routingRule.outboundTag == "blocked"){
|
||||
return;
|
||||
}
|
||||
}
|
||||
newTemplateSettings.routing.rules.push(routingRule);
|
||||
this.templateRuleSetter({
|
||||
newValue,
|
||||
outboundTag: "blocked",
|
||||
property: "protocol",
|
||||
data: this.settingsData.protocols.bittorrent
|
||||
});
|
||||
}
|
||||
this.templateSettings = newTemplateSettings
|
||||
},
|
||||
},
|
||||
privateIpSettings: {
|
||||
get: function () {
|
||||
localIpFilter = false
|
||||
if(this.templateSettings != null){
|
||||
this.templateSettings.routing.rules.forEach(routingRule => {
|
||||
if(routingRule.hasOwnProperty("ip")){
|
||||
if (routingRule.ip[0] === "geoip:private" && routingRule.outboundTag == "blocked"){
|
||||
localIpFilter = true
|
||||
}
|
||||
}
|
||||
return this.templateRuleGetter({
|
||||
outboundTag: "blocked",
|
||||
property: "ip",
|
||||
data: this.settingsData.ips.local
|
||||
});
|
||||
}
|
||||
return localIpFilter
|
||||
},
|
||||
set: function (newValue) {
|
||||
newTemplateSettings = JSON.parse(this.allSetting.xrayTemplateConfig);
|
||||
if (newValue){
|
||||
newTemplateSettings.routing.rules.push(JSON.parse("{\"outboundTag\": \"blocked\",\"ip\": [\"geoip:private\"],\"type\": \"field\"}"))
|
||||
}
|
||||
else {
|
||||
newTemplateSettings.routing.rules = [];
|
||||
this.templateSettings.routing.rules.forEach(routingRule => {
|
||||
if (routingRule.hasOwnProperty('ip')){
|
||||
if (routingRule.ip[0] === "geoip:private" && routingRule.outboundTag == "blocked"){
|
||||
return;
|
||||
}
|
||||
}
|
||||
newTemplateSettings.routing.rules.push(routingRule);
|
||||
this.templateRuleSetter({
|
||||
newValue,
|
||||
outboundTag: "blocked",
|
||||
property: "ip",
|
||||
data: this.settingsData.ips.local
|
||||
});
|
||||
},
|
||||
},
|
||||
AdsSettings: {
|
||||
get: function () {
|
||||
return this.templateRuleGetter({
|
||||
outboundTag: "blocked",
|
||||
property: "domain",
|
||||
data: this.settingsData.domains.ads
|
||||
});
|
||||
},
|
||||
set: function (newValue) {
|
||||
this.templateRuleSetter({
|
||||
newValue,
|
||||
outboundTag: "blocked",
|
||||
property: "domain",
|
||||
data: this.settingsData.domains.ads
|
||||
});
|
||||
},
|
||||
},
|
||||
PornSettings: {
|
||||
get: function () {
|
||||
return this.templateRuleGetter({
|
||||
outboundTag: "blocked",
|
||||
property: "domain",
|
||||
data: this.settingsData.domains.porn
|
||||
});
|
||||
},
|
||||
set: function (newValue) {
|
||||
this.templateRuleSetter({
|
||||
newValue,
|
||||
outboundTag: "blocked",
|
||||
property: "domain",
|
||||
data: this.settingsData.domains.porn
|
||||
});
|
||||
},
|
||||
},
|
||||
GoogleIPv4Settings: {
|
||||
get: function () {
|
||||
return this.templateRuleGetter({
|
||||
outboundTag: "IPv4",
|
||||
property: "domain",
|
||||
data: this.settingsData.domains.google
|
||||
});
|
||||
},
|
||||
set: function (newValue) {
|
||||
this.templateRuleSetter({
|
||||
newValue,
|
||||
outboundTag: "IPv4",
|
||||
property: "domain",
|
||||
data: this.settingsData.domains.google
|
||||
});
|
||||
},
|
||||
},
|
||||
NetflixIPv4Settings: {
|
||||
get: function () {
|
||||
return this.templateRuleGetter({
|
||||
outboundTag: "IPv4",
|
||||
property: "domain",
|
||||
data: this.settingsData.domains.netflix
|
||||
});
|
||||
},
|
||||
set: function (newValue) {
|
||||
this.templateRuleSetter({
|
||||
newValue,
|
||||
outboundTag: "IPv4",
|
||||
property: "domain",
|
||||
data: this.settingsData.domains.netflix
|
||||
});
|
||||
}
|
||||
this.templateSettings = newTemplateSettings
|
||||
},
|
||||
},
|
||||
IRIpSettings: {
|
||||
get: function () {
|
||||
localIpFilter = false
|
||||
if(this.templateSettings != null){
|
||||
this.templateSettings.routing.rules.forEach(routingRule => {
|
||||
if(routingRule.hasOwnProperty("ip")){
|
||||
if (routingRule.ip[0] === "geoip:ir" && routingRule.outboundTag == "blocked"){
|
||||
localIpFilter = true
|
||||
}
|
||||
}
|
||||
return this.templateRuleGetter({
|
||||
outboundTag: "blocked",
|
||||
property: "ip",
|
||||
data: this.settingsData.ips.ir
|
||||
});
|
||||
}
|
||||
return localIpFilter
|
||||
},
|
||||
set: function (newValue) {
|
||||
newTemplateSettings = JSON.parse(this.allSetting.xrayTemplateConfig);
|
||||
if (newValue){
|
||||
newTemplateSettings.routing.rules.push(JSON.parse("{\"outboundTag\": \"blocked\",\"ip\": [\"geoip:ir\"],\"type\": \"field\"}"))
|
||||
}
|
||||
else {
|
||||
newTemplateSettings.routing.rules = [];
|
||||
this.templateSettings.routing.rules.forEach(routingRule => {
|
||||
if (routingRule.hasOwnProperty('ip')){
|
||||
if (routingRule.ip[0] === "geoip:ir" && routingRule.outboundTag == "blocked"){
|
||||
return;
|
||||
}
|
||||
}
|
||||
newTemplateSettings.routing.rules.push(routingRule);
|
||||
this.templateRuleSetter({
|
||||
newValue,
|
||||
outboundTag: "blocked",
|
||||
property: "ip",
|
||||
data: this.settingsData.ips.ir
|
||||
});
|
||||
}
|
||||
this.templateSettings = newTemplateSettings
|
||||
},
|
||||
},
|
||||
IRdomainSettings: {
|
||||
IRDomainSettings: {
|
||||
get: function () {
|
||||
localdomainFilter = false
|
||||
if(this.templateSettings != null){
|
||||
this.templateSettings.routing.rules.forEach(routingRule => {
|
||||
if(routingRule.hasOwnProperty("domain")){
|
||||
if ((routingRule.domain[0] === "regexp:.+.ir$" || routingRule.domain[0] === "ext:iran.dat:ir" || routingRule.domain[0] === "ext:iran.dat:other") && routingRule.outboundTag == "blocked") {
|
||||
localdomainFilter = true
|
||||
}
|
||||
}
|
||||
return this.templateRuleGetter({
|
||||
outboundTag: "blocked",
|
||||
property: "domain",
|
||||
data: this.settingsData.domains.ir
|
||||
});
|
||||
}
|
||||
return localdomainFilter
|
||||
},
|
||||
set: function (newValue) {
|
||||
newTemplateSettings = JSON.parse(this.allSetting.xrayTemplateConfig);
|
||||
if (newValue){
|
||||
newTemplateSettings.routing.rules.push(JSON.parse("{\"outboundTag\": \"blocked\",\"domain\": [\"regexp:.+.ir$\", \"ext:iran.dat:ir\", \"ext:iran.dat:other\"],\"type\": \"field\"}"))
|
||||
}
|
||||
else {
|
||||
newTemplateSettings.routing.rules = [];
|
||||
this.templateSettings.routing.rules.forEach(routingRule => {
|
||||
if (routingRule.hasOwnProperty('domain')){
|
||||
if ((routingRule.domain[0] === "regexp:.+.ir$" || routingRule.domain[0] === "ext:iran.dat:ir" || routingRule.domain[0] === "ext:iran.dat:other") && routingRule.outboundTag == "blocked"){
|
||||
return;
|
||||
}
|
||||
}
|
||||
newTemplateSettings.routing.rules.push(routingRule);
|
||||
this.templateRuleSetter({
|
||||
newValue,
|
||||
outboundTag: "blocked",
|
||||
property: "domain",
|
||||
data: this.settingsData.domains.ir
|
||||
});
|
||||
},
|
||||
},
|
||||
ChinaIpSettings: {
|
||||
get: function () {
|
||||
return this.templateRuleGetter({
|
||||
outboundTag: "blocked",
|
||||
property: "ip",
|
||||
data: this.settingsData.ips.cn
|
||||
});
|
||||
},
|
||||
set: function (newValue) {
|
||||
this.templateRuleSetter({
|
||||
newValue,
|
||||
outboundTag: "blocked",
|
||||
property: "ip",
|
||||
data: this.settingsData.ips.cn
|
||||
});
|
||||
},
|
||||
},
|
||||
ChinaDomainSettings: {
|
||||
get: function () {
|
||||
return this.templateRuleGetter({
|
||||
outboundTag: "blocked",
|
||||
property: "domain",
|
||||
data: this.settingsData.domains.cn
|
||||
});
|
||||
},
|
||||
set: function (newValue) {
|
||||
this.templateRuleSetter({
|
||||
newValue,
|
||||
outboundTag: "blocked",
|
||||
property: "domain",
|
||||
data: this.settingsData.domains.cn
|
||||
});
|
||||
},
|
||||
},
|
||||
RussiaIpSettings: {
|
||||
get: function () {
|
||||
return this.templateRuleGetter({
|
||||
outboundTag: "blocked",
|
||||
property: "ip",
|
||||
data: this.settingsData.ips.ru
|
||||
});
|
||||
},
|
||||
set: function (newValue) {
|
||||
this.templateRuleSetter({
|
||||
newValue,
|
||||
outboundTag: "blocked",
|
||||
property: "ip",
|
||||
data: this.settingsData.ips.ru
|
||||
});
|
||||
},
|
||||
},
|
||||
RussiaDomainSettings: {
|
||||
get: function () {
|
||||
return this.templateRuleGetter({
|
||||
outboundTag: "blocked",
|
||||
property: "domain",
|
||||
data: this.settingsData.domains.ru
|
||||
});
|
||||
},
|
||||
set: function (newValue) {
|
||||
this.templateRuleSetter({
|
||||
newValue,
|
||||
outboundTag: "blocked",
|
||||
property: "domain",
|
||||
data: this.settingsData.domains.ru
|
||||
});
|
||||
},
|
||||
},
|
||||
GoogleWARPSettings: {
|
||||
get: function () {
|
||||
return this.templateRuleGetter({
|
||||
outboundTag: "WARP",
|
||||
property: "domain",
|
||||
data: this.settingsData.domains.google
|
||||
});
|
||||
},
|
||||
set: function (newValue) {
|
||||
this.templateRuleSetter({
|
||||
newValue,
|
||||
outboundTag: "WARP",
|
||||
property: "domain",
|
||||
data: this.settingsData.domains.google
|
||||
});
|
||||
},
|
||||
},
|
||||
OpenAIWARPSettings: {
|
||||
get: function () {
|
||||
return this.templateRuleGetter({
|
||||
outboundTag: "WARP",
|
||||
property: "domain",
|
||||
data: this.settingsData.domains.openai
|
||||
});
|
||||
},
|
||||
set: function (newValue) {
|
||||
this.templateRuleSetter({
|
||||
newValue,
|
||||
outboundTag: "WARP",
|
||||
property: "domain",
|
||||
data: this.settingsData.domains.openai
|
||||
});
|
||||
},
|
||||
},
|
||||
NetflixWARPSettings: {
|
||||
get: function () {
|
||||
return this.templateRuleGetter({
|
||||
outboundTag: "WARP",
|
||||
property: "domain",
|
||||
data: this.settingsData.domains.netflix
|
||||
});
|
||||
},
|
||||
set: function (newValue) {
|
||||
this.templateRuleSetter({
|
||||
newValue,
|
||||
outboundTag: "WARP",
|
||||
property: "domain",
|
||||
data: this.settingsData.domains.netflix
|
||||
});
|
||||
},
|
||||
},
|
||||
SpotifyWARPSettings: {
|
||||
get: function () {
|
||||
return this.templateRuleGetter({
|
||||
outboundTag: "WARP",
|
||||
property: "domain",
|
||||
data: this.settingsData.domains.spotify
|
||||
});
|
||||
},
|
||||
set: function (newValue) {
|
||||
this.templateRuleSetter({
|
||||
newValue,
|
||||
outboundTag: "WARP",
|
||||
property: "domain",
|
||||
data: this.settingsData.domains.spotify
|
||||
});
|
||||
},
|
||||
},
|
||||
IRWARPSettings: {
|
||||
get: function () {
|
||||
return this.templateRuleGetter({
|
||||
outboundTag: "WARP",
|
||||
property: "domain",
|
||||
data: this.settingsData.domains.ir
|
||||
});
|
||||
},
|
||||
set: function (newValue) {
|
||||
this.templateRuleSetter({
|
||||
newValue,
|
||||
outboundTag: "WARP",
|
||||
property: "domain",
|
||||
data: this.settingsData.domains.ir
|
||||
});
|
||||
}
|
||||
this.templateSettings = newTemplateSettings
|
||||
},
|
||||
},
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
</script>
|
||||
</body>
|
||||
|
||||
</html>
|
|
@ -1,25 +1,22 @@
|
|||
{
|
||||
"log": {
|
||||
"loglevel": "warning",
|
||||
"access": "./access.log"
|
||||
"access": "./access.log",
|
||||
"error": "./error.log"
|
||||
},
|
||||
"api": {
|
||||
"services": [
|
||||
"HandlerService",
|
||||
"LoggerService",
|
||||
"StatsService"
|
||||
],
|
||||
"tag": "api"
|
||||
"tag": "api",
|
||||
"services": ["HandlerService", "LoggerService", "StatsService"]
|
||||
},
|
||||
"inbounds": [
|
||||
{
|
||||
"tag": "api",
|
||||
"listen": "127.0.0.1",
|
||||
"port": 62789,
|
||||
"protocol": "dokodemo-door",
|
||||
"settings": {
|
||||
"address": "127.0.0.1"
|
||||
},
|
||||
"tag": "api"
|
||||
}
|
||||
}
|
||||
],
|
||||
"outbounds": [
|
||||
|
@ -28,16 +25,16 @@
|
|||
"settings": {}
|
||||
},
|
||||
{
|
||||
"tag": "blocked",
|
||||
"protocol": "blackhole",
|
||||
"settings": {},
|
||||
"tag": "blocked"
|
||||
"settings": {}
|
||||
}
|
||||
],
|
||||
"policy": {
|
||||
"levels": {
|
||||
"0": {
|
||||
"statsUserUplink": true,
|
||||
"statsUserDownlink": true
|
||||
"statsUserDownlink": true,
|
||||
"statsUserUplink": true
|
||||
}
|
||||
},
|
||||
"system": {
|
||||
|
@ -49,25 +46,19 @@
|
|||
"domainStrategy": "IPIfNonMatch",
|
||||
"rules": [
|
||||
{
|
||||
"inboundTag": [
|
||||
"api"
|
||||
],
|
||||
"outboundTag": "api",
|
||||
"type": "field"
|
||||
"type": "field",
|
||||
"inboundTag": ["api"],
|
||||
"outboundTag": "api"
|
||||
},
|
||||
{
|
||||
"type": "field",
|
||||
"outboundTag": "blocked",
|
||||
"ip": [
|
||||
"geoip:private"
|
||||
],
|
||||
"type": "field"
|
||||
"ip": ["geoip:private"]
|
||||
},
|
||||
{
|
||||
"type": "field",
|
||||
"outboundTag": "blocked",
|
||||
"protocol": [
|
||||
"bittorrent"
|
||||
],
|
||||
"type": "field"
|
||||
"protocol": ["bittorrent"]
|
||||
}
|
||||
]
|
||||
},
|
||||
|
|
|
@ -2,6 +2,7 @@ package service
|
|||
|
||||
import (
|
||||
_ "embed"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"reflect"
|
||||
|
@ -42,6 +43,15 @@ var defaultValueMap = map[string]string{
|
|||
type SettingService struct {
|
||||
}
|
||||
|
||||
func (s *SettingService) GetDefaultJsonConfig() (interface{}, error) {
|
||||
var jsonData interface{}
|
||||
err := json.Unmarshal([]byte(xrayTemplateConfig), &jsonData)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return jsonData, nil
|
||||
}
|
||||
|
||||
func (s *SettingService) GetAllSetting() (*entity.AllSetting, error) {
|
||||
db := database.GetDB()
|
||||
settings := make([]*model.Setting, 0)
|
||||
|
|
|
@ -196,6 +196,8 @@
|
|||
"save" = "Save"
|
||||
"restartPanel" = "Restart Panel"
|
||||
"restartPanelDesc" = "Are you sure you want to restart the panel? Click OK to restart after 3 seconds. If you cannot access the panel after restarting, please go to the server to view the panel log information"
|
||||
"actions" = "Actions"
|
||||
"resetDefaultConfig" = "Reset to default config"
|
||||
"panelConfig" = "Panel Configuration"
|
||||
"userSetting" = "User Setting"
|
||||
"xrayConfiguration" = "Xray Configuration"
|
||||
|
@ -215,18 +217,49 @@
|
|||
"currentPassword" = "Current Password"
|
||||
"newUsername" = "New Username"
|
||||
"newPassword" = "New Password"
|
||||
"advancedTemplate" = "Advanced template parts"
|
||||
"completeTemplate" = "Complete template of Xray configuration"
|
||||
"basicTemplate" = "Basic Template"
|
||||
"advancedTemplate" = "Advanced Template parts"
|
||||
"completeTemplate" = "Complete Template of Xray configuration"
|
||||
"generalConfigs" = "General Configs"
|
||||
"countryConfigs" = "Country Configs"
|
||||
"ipv4Configs" = "IPv4 Configs"
|
||||
"warpConfigs" = "WARP Configs"
|
||||
"xrayConfigTemplate" = "Xray Configuration Template"
|
||||
"xrayConfigTemplateDesc" = "Generate the final xray configuration file based on this template, restart the panel to take effect."
|
||||
"xrayConfigTorrent" = "Ban bittorrent usage"
|
||||
"xrayConfigTorrentDesc" = "Change the configuration template to avoid using bittorrent by users, restart the panel to take effect"
|
||||
"xrayConfigPrivateIp" = "Ban private IP ranges to connect"
|
||||
"xrayConfigPrivateIpDesc" = "Change the configuration template to avoid connecting with private IP ranges, restart the panel to take effect"
|
||||
"xrayConfigAds" = "Block Ads"
|
||||
"xrayConfigAdsDesc" = "Change the configuration template to block Ads, restart the panel to take effect"
|
||||
"xrayConfigPorn" = "Ban Porn websites to connect"
|
||||
"xrayConfigPornDesc" = "Change the configuration template to avoid connecting to Porn websites, restart the panel to take effect"
|
||||
"xrayConfigIRIp" = "Ban Iran IP ranges to connect"
|
||||
"xrayConfigIRIpDesc" = "Change the configuration template to avoid connecting with Iran IP ranges, restart the panel to take effect"
|
||||
"xrayConfigIRdomain" = "Ban IR domains to connect"
|
||||
"xrayConfigIRdomainDesc" = "Change the configuration template to avoid connecting with IR domains, restart the panel to take effect"
|
||||
"xrayConfigIRDomain" = "Ban Iran Domains to connect"
|
||||
"xrayConfigIRDomainDesc" = "Change the configuration template to avoid connecting with Iran domains, restart the panel to take effect"
|
||||
"xrayConfigChinaIp" = "Ban China IP ranges to connect"
|
||||
"xrayConfigChinaIpDesc" = "Change the configuration template to avoid connecting with China IP ranges, restart the panel to take effect"
|
||||
"xrayConfigChinaDomain" = "Ban China Domains to connect"
|
||||
"xrayConfigChinaDomainDesc" = "Change the configuration template to avoid connecting with China domains, restart the panel to take effect"
|
||||
"xrayConfigRussiaIp" = "Ban Russia IP ranges to connect"
|
||||
"xrayConfigRussiaIpDesc" = "Change the configuration template to avoid connecting with Russia IP ranges, restart the panel to take effect"
|
||||
"xrayConfigRussiaDomain" = "Ban Russia Domains to connect"
|
||||
"xrayConfigRussiaDomainDesc" = "Change the configuration template to avoid connecting with Russia domains, restart the panel to take effect"
|
||||
"xrayConfigGoogleIPv4" = "Use IPv4 for Google"
|
||||
"xrayConfigGoogleIPv4Desc" = "Add routing for google to connect with IPv4, restart the panel to take effect"
|
||||
"xrayConfigNetflixIPv4" = "Use IPv4 for Netflix"
|
||||
"xrayConfigNetflixIPv4Desc" = "Add routing for Netflix to connect with IPv4, restart the panel to take effect"
|
||||
"xrayConfigGoogleWARP" = "Route Google to WARP"
|
||||
"xrayConfigGoogleWARPDesc" = "Add routing for Google to WARP, restart the panel to take effect"
|
||||
"xrayConfigOpenAIWARP" = "Route OpenAI (ChatGPT) to WARP"
|
||||
"xrayConfigOpenAIWARPDesc" = "Add routing for OpenAI (ChatGPT) to WARP, restart the panel to take effect"
|
||||
"xrayConfigNetflixWARP" = "Route Netflix to WARP"
|
||||
"xrayConfigNetflixWARPDesc" = "Add routing for Netflix to WARP, restart the panel to take effect"
|
||||
"xrayConfigSpotifyWARP" = "Route Spotify to WARP"
|
||||
"xrayConfigSpotifyWARPDesc" = "Add routing for Spotify to WARP, restart the panel to take effect"
|
||||
"xrayConfigIRWARP" = "Route Iran Domains to WARP"
|
||||
"xrayConfigIRWARPDesc" = "Add routing for Iran Domains to WARP. restart the panel to take effect"
|
||||
"xrayConfigInbounds" = "Configuration of Inbounds"
|
||||
"xrayConfigInboundsDesc" = "Change the configuration template to accept special clients, restart the panel to take effect"
|
||||
"xrayConfigOutbounds" = "Configuration of Outbounds"
|
||||
|
|
|
@ -194,6 +194,8 @@
|
|||
"save" = "ذخیره"
|
||||
"restartPanel" = "ریستارت پنل"
|
||||
"restartPanelDesc" = "آیا مطمئن هستید که می خواهید پنل را دوباره راه اندازی کنید؟ برای راه اندازی مجدد روی OK کلیک کنید. اگر بعد از 3 ثانیه نمی توانید به پنل دسترسی پیدا کنید، لطفاً برای مشاهده اطلاعات گزارش پانل به سرور برگردید"
|
||||
"actions" = "عملیات ها"
|
||||
"resetDefaultConfig" = "برگشت به تنظیمات پیشفرض"
|
||||
"panelConfig" = "تنظیمات پنل"
|
||||
"userSetting" = "تنظیمات مدیر"
|
||||
"xrayConfiguration" = "تنظیمات Xray"
|
||||
|
@ -213,18 +215,49 @@
|
|||
"currentPassword" = "رمز عبور فعلی"
|
||||
"newUsername" = "نام کاربری جدید"
|
||||
"newPassword" = "رمز عبور جدید"
|
||||
"basicTemplate" = "بخش پایه"
|
||||
"advancedTemplate" = "بخش های پیشرفته الگو"
|
||||
"completeTemplate" = "الگوی کامل تنظیمات ایکس ری"
|
||||
"generalConfigs" = "تنظیمات عمومی"
|
||||
"countryConfigs" = "تنظیمات برای کشورها"
|
||||
"ipv4Configs" = "تنظیمات برای IPv4"
|
||||
"warpConfigs" = "تنظیمات برای WARP"
|
||||
"xrayConfigTemplate" = "تنظیمات الگو ایکس ری"
|
||||
"xrayConfigTemplateDesc" = "فایل پیکربندی ایکس ری نهایی بر اساس این الگو ایجاد میشود. لطفاً این را تغییر ندهید مگر اینکه دقیقاً بدانید که چه کاری انجام می دهید! پنل را مجدداً راه اندازی کنید تا اعمال شود"
|
||||
"xrayConfigTorrent" = "فیلتر کردن بیت تورنت"
|
||||
"xrayConfigTorrentDesc" = "الگوی تنظیمات را برای فیلتر کردن پروتکل بیت تورنت برای کاربران تغییر میدهد. پنل را مجدداً راه اندازی کنید تا اعمال شود"
|
||||
"xrayConfigPrivateIp" = "جلوگیری از اتصال آی پی های نامعتبر"
|
||||
"xrayConfigPrivateIpDesc" = "الگوی تنظیمات را برای فیلتر کردن اتصال آی پی های نامعتبر و بسته های سرگردان تغییر میدهد. پنل را مجدداً راه اندازی کنید تا اعمال شود"
|
||||
"xrayConfigPrivateIp" = "جلوگیری از اتصال آیپی های خصوصی یا محلی"
|
||||
"xrayConfigPrivateIpDesc" = "الگوی تنظیمات را برای فیلتر کردن اتصال آیپی های خصوصی یا محلی و بسته های سرگردان تغییر میدهد. پنل را مجدداً راه اندازی کنید تا اعمال شود"
|
||||
"xrayConfigAds" = "مسدود کردن تبلیغات"
|
||||
"xrayConfigAdsDesc" = "الگوی تنظیمات را برای مسدود کردن تبلیغات تغییر میدهد. پنل را مجدداً راه اندازی کنید تا اعمال شود"
|
||||
"xrayConfigPorn" = "جلوگیری از اتصال به سایت های پورن"
|
||||
"xrayConfigPornDesc" = "الگوی تنظیمات را برای فیلتر کردن اتصال به سایت های پورن تغییر میدهد. پنل را مجدداً راه اندازی کنید تا اعمال شود"
|
||||
"xrayConfigIRIp" = "جلوگیری از اتصال آیپی های ایران"
|
||||
"xrayConfigIRIpDesc" = "الگوی تنظیمات را برای فیلتر کردن اتصال آیپی های ایران تغییر میدهد. پنل را مجدداً راه اندازی کنید تا اعمال شود"
|
||||
"xrayConfigIRdomain" = "جلوگیری از اتصال دامنه های ایران"
|
||||
"xrayConfigIRdomainDesc" = "الگوی تنظیمات را برای فیلتر کردن اتصال دامنه های ایران تغییر میدهد. پنل را مجدداً راه اندازی کنید تا اعمال شود"
|
||||
"xrayConfigIRDomain" = "جلوگیری از اتصال دامنه های ایران"
|
||||
"xrayConfigIRDomainDesc" = "الگوی تنظیمات را برای فیلتر کردن اتصال دامنه های ایران تغییر میدهد. پنل را مجدداً راه اندازی کنید تا اعمال شود"
|
||||
"xrayConfigChinaIp" = "جلوگیری از اتصال آیپی های چین"
|
||||
"xrayConfigChinaIpDesc" = "الگوی تنظیمات را برای فیلتر کردن اتصال آیپی های چین تغییر میدهد. پنل را مجدداً راه اندازی کنید تا اعمال شود"
|
||||
"xrayConfigChinaDomain" = "جلوگیری از اتصال دامنه های چین"
|
||||
"xrayConfigChinaDomainDesc" = "الگوی تنظیمات را برای فیلتر کردن اتصال دامنه های چین تغییر میدهد. پنل را مجدداً راه اندازی کنید تا اعمال شود"
|
||||
"xrayConfigRussiaIp" = "جلوگیری از اتصال آیپی های روسیه"
|
||||
"xrayConfigRussiaIpDesc" = "الگوی تنظیمات را برای فیلتر کردن اتصال آیپی های روسیه تغییر میدهد. پنل را مجدداً راه اندازی کنید تا اعمال شود"
|
||||
"xrayConfigRussiaDomain" = "جلوگیری از اتصال دامنه های روسیه"
|
||||
"xrayConfigRussiaDomainDesc" = "الگوی تنظیمات را برای فیلتر کردن اتصال دامنه های روسیه تغییر میدهد. پنل را مجدداً راه اندازی کنید تا اعمال شود"
|
||||
"xrayConfigGoogleIPv4" = "استفاده از آیپی ورژن 4 برای اتصال به گوگل"
|
||||
"xrayConfigGoogleIPv4Desc" = "مسیردهی جدید برای اتصال به گوگل با آیپی ورژن 4 اضافه میکند. پنل را مجدداً راه اندازی کنید تا اعمال شود"
|
||||
"xrayConfigNetflixIPv4" = "استفاده از آیپی ورژن 4 برای اتصال به نتفلیکس"
|
||||
"xrayConfigNetflixIPv4Desc" = "مسیردهی جدید برای اتصال به نتفلیکس با آیپی ورژن 4 اضافه میکند. پنل را مجدداً راه اندازی کنید تا اعمال شود"
|
||||
"xrayConfigGoogleWARP" = "مسیردهی گوگل به WARP"
|
||||
"xrayConfigGoogleWARPDesc" = "مسیردهی جدید برای اتصال به گوگل به WARP اضافه میکند. پنل را مجدداً راه اندازی کنید تا اعمال شود"
|
||||
"xrayConfigOpenAIWARP" = "مسیردهی OpenAI (ChatGPT) به WARP"
|
||||
"xrayConfigOpenAIWARPDesc" = "مسیردهی جدید برای اتصال به OpenAI (ChatGPT) به WARP اضافه میکند. پنل را مجدداً راه اندازی کنید تا اعمال شود"
|
||||
"xrayConfigNetflixWARP" = "مسیردهی نتفلیکس به WARP"
|
||||
"xrayConfigNetflixWARPDesc" = "مسیردهی جدید برای اتصال به نتفلیکس به WARP اضافه میکند. پنل را مجدداً راه اندازی کنید تا اعمال شود"
|
||||
"xrayConfigSpotifyWARP" = "مسیردهی اسپاتیفای به WARP"
|
||||
"xrayConfigSpotifyWARPDesc" = "مسیردهی جدید برای اتصال به اسپاتیفای به WARP اضافه میکند. پنل را مجدداً راه اندازی کنید تا اعمال شود"
|
||||
"xrayConfigIRWARP" = "مسیردهی دامنه های ایران به WARP"
|
||||
"xrayConfigIRWARPDesc" = "مسیردهی جدید برای اتصال به دامنه های ایران به WARP اضافه میکند. پنل را مجدداً راه اندازی کنید تا اعمال شود"
|
||||
"xrayConfigInbounds" = "تنظیمات ورودی"
|
||||
"xrayConfigInboundsDesc" = "میتوانید الگوی تنظیمات را برای ورودی های خاص تنظیم نمایید. پنل را مجدداً راه اندازی کنید تا اعمال شود"
|
||||
"xrayConfigOutbounds" = "تنظیمات خروجی"
|
||||
|
|
|
@ -194,6 +194,8 @@
|
|||
"save" = "保存配置"
|
||||
"restartPanel" = "重启面板"
|
||||
"restartPanelDesc" = "确定要重启面板吗?点击确定将于 3 秒后重启,若重启后无法访问面板,请前往服务器查看面板日志信息"
|
||||
"actions" = "动作"
|
||||
"resetDefaultConfig" = "重置为默认配置"
|
||||
"panelConfig" = "面板配置"
|
||||
"userSetting" = "用户设置"
|
||||
"xrayConfiguration" = "xray 相关设置"
|
||||
|
@ -213,18 +215,49 @@
|
|||
"currentPassword" = "原密码"
|
||||
"newUsername" = "新用户名"
|
||||
"newPassword" = "新密码"
|
||||
"basicTemplate" = "基本模板"
|
||||
"advancedTemplate" = "高级模板部件"
|
||||
"completeTemplate" = "Xray 配置的完整模板"
|
||||
"generalConfigs" = "一般配置"
|
||||
"countryConfigs" = "国家配置"
|
||||
"ipv4Configs" = "IPv4 配置"
|
||||
"warpConfigs" = "WARP 配置"
|
||||
"xrayConfigTemplate" = "xray 配置模板"
|
||||
"xrayConfigTemplateDesc" = "以该模型为基础生成最终的xray配置文件,重新启动面板生成效率"
|
||||
"xrayConfigTorrent" = "禁止使用 bittorrent"
|
||||
"xrayConfigTorrentDesc" = "更改配置模板避免用户使用bittorrent,重启面板生效"
|
||||
"xrayConfigPrivateIp" = "禁止私人 ip 范围连接"
|
||||
"xrayConfigPrivateIp" = "禁止私人 IP 范围连接"
|
||||
"xrayConfigPrivateIpDesc" = "更改配置模板以避免连接私有 IP 范围,重启面板生效"
|
||||
"xrayConfigAds" = "屏蔽广告"
|
||||
"xrayConfigAdsDesc" = "修改配置模板屏蔽广告,重启面板生效"
|
||||
"xrayConfigPorn" = "禁止色情网站连接"
|
||||
"xrayConfigPornDesc" = "更改配置模板避免连接色情网站,重启面板生效"
|
||||
"xrayConfigIRIp" = "禁止伊朗 IP 范围连接"
|
||||
"xrayConfigIRIpDesc" = "修改配置模板避免连接伊朗IP范围,重启面板生效"
|
||||
"xrayConfigIRdomain" = "禁止伊朗域连接"
|
||||
"xrayConfigIRdomainDesc" = "修改配置模板避免连接伊朗域名,重启面板生效"
|
||||
"xrayConfigIRIpDesc" = "修改配置模板避免连接伊朗IP段,重启面板生效"
|
||||
"xrayConfigIRDomain" = "禁止伊朗域连接"
|
||||
"xrayConfigIRDomainDesc" = "更改配置模板避免连接伊朗域名,重启面板生效"
|
||||
"xrayConfigChinaIp" = "禁止中国 IP 范围连接"
|
||||
"xrayConfigChinaIpDesc" = "修改配置模板避免连接中国IP段,重启面板生效"
|
||||
"xrayConfigChinaDomain" = "禁止中国域名连接"
|
||||
"xrayConfigChinaDomainDesc" = "更改配置模板避免连接中国域,重启面板生效"
|
||||
"xrayConfigRussiaIp" = "禁止俄罗斯 IP 范围连接"
|
||||
"xrayConfigRussiaIpDesc" = "修改配置模板避免连接俄罗斯IP范围,重启面板生效"
|
||||
"xrayConfigRussiaDomain" = "禁止俄罗斯域连接"
|
||||
"xrayConfigRussiaDomainDesc" = "更改配置模板避免连接俄罗斯域,重启面板生效"
|
||||
"xrayConfigGoogleIPv4" = "为谷歌使用 IPv4"
|
||||
"xrayConfigGoogleIPv4Desc" = "添加谷歌连接IPv4的路由,重启面板生效"
|
||||
"xrayConfigNetflixIPv4" = "为 Netflix 使用 IPv4"
|
||||
"xrayConfigNetflixIPv4Desc" = "添加Netflix连接IPv4的路由,重启面板生效"
|
||||
"xrayConfigGoogleWARP" = "将谷歌路由到 WARP"
|
||||
"xrayConfigGoogleWARPDesc" = "为谷歌添加路由到WARP,重启面板生效"
|
||||
"xrayConfigOpenAIWARP" = "将 OpenAI (ChatGPT) 路由到 WARP"
|
||||
"xrayConfigOpenAIWARPDesc" = "将OpenAI(ChatGPT)路由添加到WARP,重启面板生效"
|
||||
"xrayConfigNetflixWARP" = "将 Netflix 路由到 WARP"
|
||||
"xrayConfigNetflixWARPDesc" = "为Netflix添加路由到WARP,重启面板生效"
|
||||
"xrayConfigSpotifyWARP" = "将 Spotify 路由到 WARP"
|
||||
"xrayConfigSpotifyWARPDesc" = "为Spotify添加路由到WARP,重启面板生效"
|
||||
"xrayConfigIRWARP" = "将伊朗域名路由到 WARP"
|
||||
"xrayConfigIRWARPDesc" = "将伊朗域的路由添加到 WARP。 重启面板生效"
|
||||
"xrayConfigInbounds" = "入站配置"
|
||||
"xrayConfigInboundsDesc" = "更改配置模板接受特殊客户端,重启面板生效"
|
||||
"xrayConfigOutbounds" = "出站配置"
|
||||
|
|
53
x-ui.sh
53
x-ui.sh
|
@ -17,6 +17,7 @@ function LOGE() {
|
|||
function LOGI() {
|
||||
echo -e "${green}[INF] $* ${plain}"
|
||||
}
|
||||
|
||||
# check root
|
||||
[[ $EUID -ne 0 ]] && LOGE "ERROR: You must be root to run this script! \n" && exit 1
|
||||
|
||||
|
@ -34,7 +35,6 @@ fi
|
|||
|
||||
echo "The OS release is: $release"
|
||||
|
||||
|
||||
os_version=""
|
||||
os_version=$(grep -i version_id /etc/os-release | cut -d \" -f2 | cut -d . -f1)
|
||||
|
||||
|
@ -44,21 +44,18 @@ if [[ "${release}" == "centos" ]]; then
|
|||
fi
|
||||
elif [[ "${release}" == "ubuntu" ]]; then
|
||||
if [[ ${os_version} -lt 20 ]]; then
|
||||
echo -e "${red}please use Ubuntu 20 or higher version!${plain}\n" && exit 1
|
||||
echo -e "${red}please use Ubuntu 20 or higher version! ${plain}\n" && exit 1
|
||||
fi
|
||||
|
||||
elif [[ "${release}" == "fedora" ]]; then
|
||||
if [[ ${os_version} -lt 36 ]]; then
|
||||
echo -e "${red}please use Fedora 36 or higher version!${plain}\n" && exit 1
|
||||
echo -e "${red}please use Fedora 36 or higher version! ${plain}\n" && exit 1
|
||||
fi
|
||||
|
||||
elif [[ "${release}" == "debian" ]]; then
|
||||
if [[ ${os_version} -lt 10 ]]; then
|
||||
echo -e "${red} Please use Debian 10 or higher ${plain}\n" && exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
|
||||
confirm() {
|
||||
if [[ $# > 1 ]]; then
|
||||
echo && read -p "$1 [Default$2]: " temp
|
||||
|
@ -133,7 +130,7 @@ uninstall() {
|
|||
rm /usr/local/x-ui/ -rf
|
||||
|
||||
echo ""
|
||||
echo -e "Uninstalled Successfully,If you want to remove this script,then after exiting the script run ${green}rm /usr/bin/x-ui -f${plain} to delete it."
|
||||
echo -e "Uninstalled Successfully, If you want to remove this script, then after exiting the script run ${green}rm /usr/bin/x-ui -f${plain} to delete it."
|
||||
echo ""
|
||||
|
||||
if [[ $# == 0 ]]; then
|
||||
|
@ -150,12 +147,12 @@ reset_user() {
|
|||
return 0
|
||||
fi
|
||||
/usr/local/x-ui/x-ui setting -username admin -password admin
|
||||
echo -e "Username and password have been reset to ${green}admin${plain},Please restart the panel now."
|
||||
echo -e "Username and password have been reset to ${green}admin${plain}, Please restart the panel now."
|
||||
confirm_restart
|
||||
}
|
||||
|
||||
reset_config() {
|
||||
confirm "Are you sure you want to reset all panel settings,Account data will not be lost,Username and password will not change" "n"
|
||||
confirm "Are you sure you want to reset all panel settings, Account data will not be lost, Username and password will not change" "n"
|
||||
if [[ $? != 0 ]]; then
|
||||
if [[ $# == 0 ]]; then
|
||||
show_menu
|
||||
|
@ -163,7 +160,7 @@ reset_config() {
|
|||
return 0
|
||||
fi
|
||||
/usr/local/x-ui/x-ui setting -reset
|
||||
echo -e "All panel settings have been reset to default,Please restart the panel now,and use the default ${green}2053${plain} Port to Access the web Panel"
|
||||
echo -e "All panel settings have been reset to default, Please restart the panel now, and use the default ${green}2053${plain} Port to Access the web Panel"
|
||||
confirm_restart
|
||||
}
|
||||
|
||||
|
@ -183,7 +180,7 @@ set_port() {
|
|||
before_show_menu
|
||||
else
|
||||
/usr/local/x-ui/x-ui setting -port ${port}
|
||||
echo -e "The port is set,Please restart the panel now,and use the new port ${green}${port}${plain} to access web panel"
|
||||
echo -e "The port is set, Please restart the panel now, and use the new port ${green}${port}${plain} to access web panel"
|
||||
confirm_restart
|
||||
fi
|
||||
}
|
||||
|
@ -192,7 +189,7 @@ start() {
|
|||
check_status
|
||||
if [[ $? == 0 ]]; then
|
||||
echo ""
|
||||
LOGI "Panel is running,No need to start again,If you need to restart, please select restart"
|
||||
LOGI "Panel is running, No need to start again, If you need to restart, please select restart"
|
||||
else
|
||||
systemctl start x-ui
|
||||
sleep 2
|
||||
|
@ -200,7 +197,7 @@ start() {
|
|||
if [[ $? == 0 ]]; then
|
||||
LOGI "x-ui Started Successfully"
|
||||
else
|
||||
LOGE "panel Failed to start,Probably because it takes longer than two seconds to start,Please check the log information later"
|
||||
LOGE "panel Failed to start, Probably because it takes longer than two seconds to start, Please check the log information later"
|
||||
fi
|
||||
fi
|
||||
|
||||
|
@ -213,7 +210,7 @@ stop() {
|
|||
check_status
|
||||
if [[ $? == 1 ]]; then
|
||||
echo ""
|
||||
LOGI "Panel stopped,No need to stop again!"
|
||||
LOGI "Panel stopped, No need to stop again!"
|
||||
else
|
||||
systemctl stop x-ui
|
||||
sleep 2
|
||||
|
@ -221,7 +218,7 @@ stop() {
|
|||
if [[ $? == 1 ]]; then
|
||||
LOGI "x-ui and xray stopped successfully"
|
||||
else
|
||||
LOGE "Panel stop failed,Probably because the stop time exceeds two seconds,Please check the log information later"
|
||||
LOGE "Panel stop failed, Probably because the stop time exceeds two seconds, Please check the log information later"
|
||||
fi
|
||||
fi
|
||||
|
||||
|
@ -237,7 +234,7 @@ restart() {
|
|||
if [[ $? == 0 ]]; then
|
||||
LOGI "x-ui and xray Restarted successfully"
|
||||
else
|
||||
LOGE "Panel restart failed,Probably because it takes longer than two seconds to start,Please check the log information later"
|
||||
LOGE "Panel restart failed, Probably because it takes longer than two seconds to start, Please check the log information later"
|
||||
fi
|
||||
if [[ $# == 0 ]]; then
|
||||
before_show_menu
|
||||
|
@ -285,7 +282,6 @@ show_log() {
|
|||
}
|
||||
|
||||
enable_bbr() {
|
||||
|
||||
if grep -q "net.core.default_qdisc=fq" /etc/sysctl.conf && grep -q "net.ipv4.tcp_congestion_control=bbr" /etc/sysctl.conf; then
|
||||
echo -e "${green}BBR is already enabled!${plain}"
|
||||
exit 0
|
||||
|
@ -318,18 +314,17 @@ if [[ $(sysctl net.ipv4.tcp_congestion_control | awk '{print $3}') == "bbr" ]];
|
|||
else
|
||||
echo -e "${red}Failed to enable BBR. Please check your system configuration.${plain}"
|
||||
fi
|
||||
|
||||
}
|
||||
|
||||
update_shell() {
|
||||
wget -O /usr/bin/x-ui -N --no-check-certificate https://github.com/MHSanaei/3x-ui/raw/main/x-ui.sh
|
||||
if [[ $? != 0 ]]; then
|
||||
echo ""
|
||||
LOGE "Failed to download script,Please check whether the machine can connect Github"
|
||||
LOGE "Failed to download script, Please check whether the machine can connect Github"
|
||||
before_show_menu
|
||||
else
|
||||
chmod +x /usr/bin/x-ui
|
||||
LOGI "Upgrade script succeeded,Please rerun the script" && exit 0
|
||||
LOGI "Upgrade script succeeded, Please rerun the script" && exit 0
|
||||
fi
|
||||
}
|
||||
|
||||
|
@ -359,7 +354,7 @@ check_uninstall() {
|
|||
check_status
|
||||
if [[ $? != 2 ]]; then
|
||||
echo ""
|
||||
LOGE "Panel installed,Please do not reinstall"
|
||||
LOGE "Panel installed, Please do not reinstall"
|
||||
if [[ $# == 0 ]]; then
|
||||
before_show_menu
|
||||
fi
|
||||
|
@ -506,17 +501,24 @@ fi
|
|||
sudo ufw status | grep $ports
|
||||
}
|
||||
|
||||
|
||||
|
||||
update_geo() {
|
||||
local defaultBinFolder="/usr/local/x-ui/bin"
|
||||
read -p "Please enter x-ui bin folder path. Leave blank for default. (Default: '${defaultBinFolder}')" binFolder
|
||||
binFolder=${binFolder:-${defaultBinFolder}}
|
||||
if [[ ! -d ${binFolder} ]]; then
|
||||
LOGE "Folder ${binFolder} not exists!"
|
||||
LOGI "making bin folder: ${binFolder}..."
|
||||
mkdir -p ${binFolder}
|
||||
fi
|
||||
|
||||
systemctl stop x-ui
|
||||
cd /usr/local/x-ui/bin
|
||||
cd ${binFolder}
|
||||
rm -f geoip.dat geosite.dat iran.dat
|
||||
wget -N https://github.com/Loyalsoldier/v2ray-rules-dat/releases/latest/download/geoip.dat
|
||||
wget -N https://github.com/Loyalsoldier/v2ray-rules-dat/releases/latest/download/geosite.dat
|
||||
wget -N https://github.com/bootmortis/iran-hosted-domains/releases/latest/download/iran.dat
|
||||
systemctl start x-ui
|
||||
echo -e "${green}Geosite and Geoip have been updated successfully!${plain}"
|
||||
echo -e "${green}Geosite.dat + Geoip.dat + Iran.dat have been updated successfully in bin folder '${binfolder}'!${plain}"
|
||||
before_show_menu
|
||||
}
|
||||
|
||||
|
@ -714,6 +716,7 @@ ssl_cert_issue_by_cloudflare() {
|
|||
show_menu
|
||||
fi
|
||||
}
|
||||
|
||||
google_recaptcha() {
|
||||
curl -O https://raw.githubusercontent.com/jinwyp/one_click_script/master/install_kernel.sh && chmod +x ./install_kernel.sh && ./install_kernel.sh
|
||||
echo ""
|
||||
|
|
Loading…
Reference in a new issue