mirror of
https://github.com/alireza0/x-ui.git
synced 2026-03-21 16:25:49 +00:00
Compare commits
8 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9d93468332 | ||
|
|
5e28644ec7 | ||
|
|
9b08f181a6 | ||
|
|
1a0c39693e | ||
|
|
18662b9c71 | ||
|
|
c39ad9cac1 | ||
|
|
b8f2195a3a | ||
|
|
57d437dff8 |
4
.github/workflows/release.yml
vendored
4
.github/workflows/release.yml
vendored
@@ -86,7 +86,7 @@ jobs:
|
|||||||
cd x-ui/bin
|
cd x-ui/bin
|
||||||
|
|
||||||
# Download dependencies
|
# Download dependencies
|
||||||
Xray_URL="https://github.com/XTLS/Xray-core/releases/download/v26.1.31/"
|
Xray_URL="https://github.com/XTLS/Xray-core/releases/download/v26.2.6/"
|
||||||
if [ "${{ matrix.platform }}" == "amd64" ]; then
|
if [ "${{ matrix.platform }}" == "amd64" ]; then
|
||||||
wget -q ${Xray_URL}Xray-linux-64.zip
|
wget -q ${Xray_URL}Xray-linux-64.zip
|
||||||
unzip Xray-linux-64.zip
|
unzip Xray-linux-64.zip
|
||||||
@@ -182,7 +182,7 @@ jobs:
|
|||||||
cd x-ui\bin
|
cd x-ui\bin
|
||||||
|
|
||||||
# Download Xray for Windows
|
# Download Xray for Windows
|
||||||
$Xray_URL = "https://github.com/XTLS/Xray-core/releases/download/v26.1.31/"
|
$Xray_URL = "https://github.com/XTLS/Xray-core/releases/download/v26.2.6/"
|
||||||
Invoke-WebRequest -Uri "${Xray_URL}Xray-windows-64.zip" -OutFile "Xray-windows-64.zip"
|
Invoke-WebRequest -Uri "${Xray_URL}Xray-windows-64.zip" -OutFile "Xray-windows-64.zip"
|
||||||
Expand-Archive -Path "Xray-windows-64.zip" -DestinationPath .
|
Expand-Archive -Path "Xray-windows-64.zip" -DestinationPath .
|
||||||
Remove-Item "Xray-windows-64.zip"
|
Remove-Item "Xray-windows-64.zip"
|
||||||
|
|||||||
1
.gitignore
vendored
1
.gitignore
vendored
@@ -15,3 +15,4 @@ release/
|
|||||||
/release.sh
|
/release.sh
|
||||||
/x-ui
|
/x-ui
|
||||||
.DS_Store
|
.DS_Store
|
||||||
|
/dev/
|
||||||
|
|||||||
94
CONTRIBUTING.md
Normal file
94
CONTRIBUTING.md
Normal file
@@ -0,0 +1,94 @@
|
|||||||
|
# Contribution guide
|
||||||
|
|
||||||
|
This document describes **development-only** setup options for contributing to the x-ui project.
|
||||||
|
Production deployments are **out of scope** for this guide.
|
||||||
|
|
||||||
|
For safety, Docker-based development is **strongly recommended**.
|
||||||
|
Local installation should be performed **only inside a VM or disposable environment**.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Recommended: Docker development setup
|
||||||
|
|
||||||
|
### Prerequisites
|
||||||
|
|
||||||
|
- Docker
|
||||||
|
- Docker Compose (v2+)
|
||||||
|
- Git
|
||||||
|
|
||||||
|
### Steps
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git clone https://github.com/alireza0/x-ui.git
|
||||||
|
# or:
|
||||||
|
# git clone https://github.com/<your_fork_name>/x-ui.git
|
||||||
|
|
||||||
|
docker compose -f docker-compose.yml -f docker-compose.dev.yml up --build
|
||||||
|
```
|
||||||
|
|
||||||
|
### Explore panel
|
||||||
|
|
||||||
|
- Panel should be available at localhost:54321 like: [http://127.0.0.1:54321](http://127.0.0.1:54321) for example
|
||||||
|
- Default credentials: `admin` / `admin`
|
||||||
|
|
||||||
|
To stop and remove containers or `ctrl` + `C`:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker compose down
|
||||||
|
```
|
||||||
|
|
||||||
|
### Environment
|
||||||
|
|
||||||
|
When using the Docker development setup, the [docker-compose.dev.yml](/docker-compose.dev.yml) file mounts the local database directory into the container:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
volumes:
|
||||||
|
- ./dev/db:/etc/x-ui
|
||||||
|
```
|
||||||
|
|
||||||
|
This means:
|
||||||
|
|
||||||
|
- [./dev/db](/dev/db/) on the host is used to persist panel state during development
|
||||||
|
- `/etc/x-ui` inside the container is the active database/config directory
|
||||||
|
- Data will survive container restarts but is isolated from the host system
|
||||||
|
- You can safely delete `./dev/db` to reset the development database
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Local development setup (unsafe on host OS)
|
||||||
|
|
||||||
|
This method runs scripts with root privileges and alters the host system.
|
||||||
|
Use **only inside a VM, container, or disposable test environment**.
|
||||||
|
|
||||||
|
### Prerequisites
|
||||||
|
|
||||||
|
- Ubuntu/Debian or Fedora (actually anything with systemd, just use proper package manager)
|
||||||
|
|
||||||
|
### Install dependencies
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Ubuntu / Debian
|
||||||
|
sudo apt update
|
||||||
|
sudo apt upgrade -y
|
||||||
|
sudo apt install -y golang unzip git wget
|
||||||
|
|
||||||
|
# Fedora
|
||||||
|
sudo dnf update -y
|
||||||
|
sudo dnf install -y golang unzip git wget
|
||||||
|
```
|
||||||
|
|
||||||
|
### Setup panel
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git clone https://github.com/alireza0/x-ui.git
|
||||||
|
# or:
|
||||||
|
# git clone https://github.com/<your_fork_name>/x-ui.git
|
||||||
|
|
||||||
|
cd x-ui/
|
||||||
|
sudo bash x-ui.sh # Select -> 10. Start
|
||||||
|
```
|
||||||
|
|
||||||
|
### Explore panel
|
||||||
|
|
||||||
|
- Panel should be available at localhost:54321 like: [http://127.0.0.1:54321](http://127.0.0.1:54321) for example
|
||||||
|
- Default credentials: `admin` / `admin`
|
||||||
@@ -23,7 +23,7 @@ case $1 in
|
|||||||
esac
|
esac
|
||||||
mkdir -p build/bin
|
mkdir -p build/bin
|
||||||
cd build/bin
|
cd build/bin
|
||||||
wget -q "https://github.com/XTLS/Xray-core/releases/download/v26.1.31/Xray-linux-${ARCH}.zip"
|
wget -q "https://github.com/XTLS/Xray-core/releases/download/v26.2.6/Xray-linux-${ARCH}.zip"
|
||||||
unzip "Xray-linux-${ARCH}.zip"
|
unzip "Xray-linux-${ARCH}.zip"
|
||||||
rm -f "Xray-linux-${ARCH}.zip" geoip.dat geosite.dat LICENSE README.md
|
rm -f "Xray-linux-${ARCH}.zip" geoip.dat geosite.dat LICENSE README.md
|
||||||
mv xray "xray-linux-${FNAME}"
|
mv xray "xray-linux-${FNAME}"
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
1.10.0
|
1.10.1
|
||||||
15
docker-compose.dev.yml
Normal file
15
docker-compose.dev.yml
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
services:
|
||||||
|
xui:
|
||||||
|
build:
|
||||||
|
context: .
|
||||||
|
target: builder
|
||||||
|
working_dir: /app
|
||||||
|
volumes:
|
||||||
|
- .:/app
|
||||||
|
- ./dev/db:/etc/x-ui
|
||||||
|
environment:
|
||||||
|
XUI_BIN_FOLDER: /app/dev/bin
|
||||||
|
XUI_DB_FOLDER: /etc/x-ui
|
||||||
|
XUI_LOG_LEVEL: debug
|
||||||
|
XUI_DEBUG: "true"
|
||||||
|
command: ["go","run","./main.go"]
|
||||||
10
go.mod
10
go.mod
@@ -12,13 +12,13 @@ require (
|
|||||||
github.com/op/go-logging v0.0.0-20160315200505-970db520ece7
|
github.com/op/go-logging v0.0.0-20160315200505-970db520ece7
|
||||||
github.com/pelletier/go-toml/v2 v2.2.4
|
github.com/pelletier/go-toml/v2 v2.2.4
|
||||||
github.com/robfig/cron/v3 v3.0.1
|
github.com/robfig/cron/v3 v3.0.1
|
||||||
github.com/shirou/gopsutil/v4 v4.25.12
|
github.com/shirou/gopsutil/v4 v4.26.1
|
||||||
github.com/xtls/xray-core v1.260131.0
|
github.com/xtls/xray-core v1.260202.0
|
||||||
go.uber.org/atomic v1.11.0
|
go.uber.org/atomic v1.11.0
|
||||||
golang.org/x/text v0.33.0
|
golang.org/x/text v0.33.0
|
||||||
google.golang.org/grpc v1.78.0
|
google.golang.org/grpc v1.78.0
|
||||||
gorm.io/driver/sqlite v1.6.0
|
gorm.io/driver/sqlite v1.6.0
|
||||||
gorm.io/gorm v1.31.0
|
gorm.io/gorm v1.31.1
|
||||||
)
|
)
|
||||||
|
|
||||||
require (
|
require (
|
||||||
@@ -30,13 +30,13 @@ require (
|
|||||||
github.com/cloudflare/circl v1.6.3 // indirect
|
github.com/cloudflare/circl v1.6.3 // indirect
|
||||||
github.com/cloudwego/base64x v0.1.6 // indirect
|
github.com/cloudwego/base64x v0.1.6 // indirect
|
||||||
github.com/ebitengine/purego v0.9.1 // indirect
|
github.com/ebitengine/purego v0.9.1 // indirect
|
||||||
github.com/gabriel-vasile/mimetype v1.4.12 // indirect
|
github.com/gabriel-vasile/mimetype v1.4.13 // indirect
|
||||||
github.com/gin-contrib/sse v1.1.0 // indirect
|
github.com/gin-contrib/sse v1.1.0 // indirect
|
||||||
github.com/go-ole/go-ole v1.3.0 // indirect
|
github.com/go-ole/go-ole v1.3.0 // indirect
|
||||||
github.com/go-playground/locales v0.14.1 // indirect
|
github.com/go-playground/locales v0.14.1 // indirect
|
||||||
github.com/go-playground/universal-translator v0.18.1 // indirect
|
github.com/go-playground/universal-translator v0.18.1 // indirect
|
||||||
github.com/go-playground/validator/v10 v10.30.1 // indirect
|
github.com/go-playground/validator/v10 v10.30.1 // indirect
|
||||||
github.com/goccy/go-yaml v1.18.0 // indirect
|
github.com/goccy/go-yaml v1.19.2 // indirect
|
||||||
github.com/google/btree v1.1.3 // indirect
|
github.com/google/btree v1.1.3 // indirect
|
||||||
github.com/gorilla/context v1.1.2 // indirect
|
github.com/gorilla/context v1.1.2 // indirect
|
||||||
github.com/gorilla/securecookie v1.1.2 // indirect
|
github.com/gorilla/securecookie v1.1.2 // indirect
|
||||||
|
|||||||
10
go.sum
10
go.sum
@@ -21,6 +21,8 @@ github.com/ebitengine/purego v0.9.1 h1:a/k2f2HQU3Pi399RPW1MOaZyhKJL9w/xFpKAg4q1s
|
|||||||
github.com/ebitengine/purego v0.9.1/go.mod h1:iIjxzd6CiRiOG0UyXP+V1+jWqUXVjPKLAI0mRfJZTmQ=
|
github.com/ebitengine/purego v0.9.1/go.mod h1:iIjxzd6CiRiOG0UyXP+V1+jWqUXVjPKLAI0mRfJZTmQ=
|
||||||
github.com/gabriel-vasile/mimetype v1.4.12 h1:e9hWvmLYvtp846tLHam2o++qitpguFiYCKbn0w9jyqw=
|
github.com/gabriel-vasile/mimetype v1.4.12 h1:e9hWvmLYvtp846tLHam2o++qitpguFiYCKbn0w9jyqw=
|
||||||
github.com/gabriel-vasile/mimetype v1.4.12/go.mod h1:d+9Oxyo1wTzWdyVUPMmXFvp4F9tea18J8ufA774AB3s=
|
github.com/gabriel-vasile/mimetype v1.4.12/go.mod h1:d+9Oxyo1wTzWdyVUPMmXFvp4F9tea18J8ufA774AB3s=
|
||||||
|
github.com/gabriel-vasile/mimetype v1.4.13 h1:46nXokslUBsAJE/wMsp5gtO500a4F3Nkz9Ufpk2AcUM=
|
||||||
|
github.com/gabriel-vasile/mimetype v1.4.13/go.mod h1:d+9Oxyo1wTzWdyVUPMmXFvp4F9tea18J8ufA774AB3s=
|
||||||
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 h1:Arcl6UOIS/kgO2nW3A65HN+7CMjSDP/gofXL4CZt1V4=
|
||||||
github.com/ghodss/yaml v1.0.1-0.20220118164431-d8423dcdf344/go.mod h1:GIjDIg/heH5DOkXY3YJ/wNhfHsQHoXGjl8G8amsYQ1I=
|
github.com/ghodss/yaml v1.0.1-0.20220118164431-d8423dcdf344/go.mod h1:GIjDIg/heH5DOkXY3YJ/wNhfHsQHoXGjl8G8amsYQ1I=
|
||||||
github.com/gin-contrib/gzip v1.2.5 h1:fIZs0S+l17pIu1P5XRJOo/YNqfIuPCrZZ3TWB7pjckI=
|
github.com/gin-contrib/gzip v1.2.5 h1:fIZs0S+l17pIu1P5XRJOo/YNqfIuPCrZZ3TWB7pjckI=
|
||||||
@@ -52,6 +54,8 @@ 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/goccy/go-json v0.10.5/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M=
|
||||||
github.com/goccy/go-yaml v1.18.0 h1:8W7wMFS12Pcas7KU+VVkaiCng+kG8QiFeFwzFb+rwuw=
|
github.com/goccy/go-yaml v1.18.0 h1:8W7wMFS12Pcas7KU+VVkaiCng+kG8QiFeFwzFb+rwuw=
|
||||||
github.com/goccy/go-yaml v1.18.0/go.mod h1:XBurs7gK8ATbW4ZPGKgcbrY1Br56PdM69F7LkFRi1kA=
|
github.com/goccy/go-yaml v1.18.0/go.mod h1:XBurs7gK8ATbW4ZPGKgcbrY1Br56PdM69F7LkFRi1kA=
|
||||||
|
github.com/goccy/go-yaml v1.19.2 h1:PmFC1S6h8ljIz6gMRBopkjP1TVT7xuwrButHID66PoM=
|
||||||
|
github.com/goccy/go-yaml v1.19.2/go.mod h1:XBurs7gK8ATbW4ZPGKgcbrY1Br56PdM69F7LkFRi1kA=
|
||||||
github.com/golang/mock v1.7.0-rc.1 h1:YojYx61/OLFsiv6Rw1Z96LpldJIy31o+UHmwAUMJ6/U=
|
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/mock v1.7.0-rc.1/go.mod h1:s42URUywIqd+OcERslBJvOjepvNymP31m3q8d/GkuRs=
|
||||||
github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=
|
github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=
|
||||||
@@ -134,6 +138,8 @@ github.com/sagernet/sing-shadowsocks v0.2.9 h1:Paep5zCszRKsEn8587O0MnhFWKJwDW1Y4
|
|||||||
github.com/sagernet/sing-shadowsocks v0.2.9/go.mod h1:TE/Z6401Pi8tgr0nBZcM/xawAI6u3F6TTbz4nH/qw+8=
|
github.com/sagernet/sing-shadowsocks v0.2.9/go.mod h1:TE/Z6401Pi8tgr0nBZcM/xawAI6u3F6TTbz4nH/qw+8=
|
||||||
github.com/shirou/gopsutil/v4 v4.25.12 h1:e7PvW/0RmJ8p8vPGJH4jvNkOyLmbkXgXW4m6ZPic6CY=
|
github.com/shirou/gopsutil/v4 v4.25.12 h1:e7PvW/0RmJ8p8vPGJH4jvNkOyLmbkXgXW4m6ZPic6CY=
|
||||||
github.com/shirou/gopsutil/v4 v4.25.12/go.mod h1:EivAfP5x2EhLp2ovdpKSozecVXn1TmuG7SMzs/Wh4PU=
|
github.com/shirou/gopsutil/v4 v4.25.12/go.mod h1:EivAfP5x2EhLp2ovdpKSozecVXn1TmuG7SMzs/Wh4PU=
|
||||||
|
github.com/shirou/gopsutil/v4 v4.26.1 h1:TOkEyriIXk2HX9d4isZJtbjXbEjf5qyKPAzbzY0JWSo=
|
||||||
|
github.com/shirou/gopsutil/v4 v4.26.1/go.mod h1:medLI9/UNAb0dOI9Q3/7yWSqKkj00u+1tgY8nvv41pc=
|
||||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
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.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
||||||
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
|
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
|
||||||
@@ -161,6 +167,8 @@ github.com/xtls/reality v0.0.0-20251116175510-cd53f7d50237 h1:UXjrmniKlY+ZbIqpN9
|
|||||||
github.com/xtls/reality v0.0.0-20251116175510-cd53f7d50237/go.mod h1:vbHCV/3VWUvy1oKvTxxWJRPEWSeR1sYgQHIh6u/JiZQ=
|
github.com/xtls/reality v0.0.0-20251116175510-cd53f7d50237/go.mod h1:vbHCV/3VWUvy1oKvTxxWJRPEWSeR1sYgQHIh6u/JiZQ=
|
||||||
github.com/xtls/xray-core v1.260131.0 h1:gPBykLhUvRZ8sfubNerkwWqV3c15UtmSYQG2cgKqrV4=
|
github.com/xtls/xray-core v1.260131.0 h1:gPBykLhUvRZ8sfubNerkwWqV3c15UtmSYQG2cgKqrV4=
|
||||||
github.com/xtls/xray-core v1.260131.0/go.mod h1:cxzYFZrxu1B1NtPjHsqv4UzgDvRA71mV4rXYH4KtO7Q=
|
github.com/xtls/xray-core v1.260131.0/go.mod h1:cxzYFZrxu1B1NtPjHsqv4UzgDvRA71mV4rXYH4KtO7Q=
|
||||||
|
github.com/xtls/xray-core v1.260202.0 h1:dYduYxGlkn/krSQJbmksbTtCdRe8OFb3YwpuXXEJG5c=
|
||||||
|
github.com/xtls/xray-core v1.260202.0/go.mod h1:cxzYFZrxu1B1NtPjHsqv4UzgDvRA71mV4rXYH4KtO7Q=
|
||||||
github.com/xyproto/randomstring v1.0.5 h1:YtlWPoRdgMu3NZtP45drfy1GKoojuR7hmRcnhZqKjWU=
|
github.com/xyproto/randomstring v1.0.5 h1:YtlWPoRdgMu3NZtP45drfy1GKoojuR7hmRcnhZqKjWU=
|
||||||
github.com/xyproto/randomstring v1.0.5/go.mod h1:rgmS5DeNXLivK7YprL0pY+lTuhNQW3iGxZ18UQApw/E=
|
github.com/xyproto/randomstring v1.0.5/go.mod h1:rgmS5DeNXLivK7YprL0pY+lTuhNQW3iGxZ18UQApw/E=
|
||||||
github.com/yusufpapurcu/wmi v1.2.4 h1:zFUKzehAFReQwLys1b/iSMl+JQGSCSjtVqQn9bBrPo0=
|
github.com/yusufpapurcu/wmi v1.2.4 h1:zFUKzehAFReQwLys1b/iSMl+JQGSCSjtVqQn9bBrPo0=
|
||||||
@@ -235,6 +243,8 @@ gorm.io/driver/sqlite v1.6.0 h1:WHRRrIiulaPiPFmDcod6prc4l2VGVWHz80KspNsxSfQ=
|
|||||||
gorm.io/driver/sqlite v1.6.0/go.mod h1:AO9V1qIQddBESngQUKWL9yoH93HIeA1X6V633rBwyT8=
|
gorm.io/driver/sqlite v1.6.0/go.mod h1:AO9V1qIQddBESngQUKWL9yoH93HIeA1X6V633rBwyT8=
|
||||||
gorm.io/gorm v1.31.0 h1:0VlycGreVhK7RF/Bwt51Fk8v0xLiiiFdbGDPIZQ7mJY=
|
gorm.io/gorm v1.31.0 h1:0VlycGreVhK7RF/Bwt51Fk8v0xLiiiFdbGDPIZQ7mJY=
|
||||||
gorm.io/gorm v1.31.0/go.mod h1:XyQVbO2k6YkOis7C2437jSit3SsDK72s7n7rsSHd+Gs=
|
gorm.io/gorm v1.31.0/go.mod h1:XyQVbO2k6YkOis7C2437jSit3SsDK72s7n7rsSHd+Gs=
|
||||||
|
gorm.io/gorm v1.31.1 h1:7CA8FTFz/gRfgqgpeKIBcervUn3xSyPUmr6B2WXJ7kg=
|
||||||
|
gorm.io/gorm v1.31.1/go.mod h1:XyQVbO2k6YkOis7C2437jSit3SsDK72s7n7rsSHd+Gs=
|
||||||
gvisor.dev/gvisor v0.0.0-20260122175437-89a5d21be8f0 h1:Lk6hARj5UPY47dBep70OD/TIMwikJ5fGUGX0Rm3Xigk=
|
gvisor.dev/gvisor v0.0.0-20260122175437-89a5d21be8f0 h1:Lk6hARj5UPY47dBep70OD/TIMwikJ5fGUGX0Rm3Xigk=
|
||||||
gvisor.dev/gvisor v0.0.0-20260122175437-89a5d21be8f0/go.mod h1:QkHjoMIBaYtpVufgwv3keYAbln78mBoCuShZrPrer1Q=
|
gvisor.dev/gvisor v0.0.0-20260122175437-89a5d21be8f0/go.mod h1:QkHjoMIBaYtpVufgwv3keYAbln78mBoCuShZrPrer1Q=
|
||||||
lukechampine.com/blake3 v1.4.1 h1:I3Smz7gso8w4/TunLKec6K2fn+kyKtDxr/xcQEN84Wg=
|
lukechampine.com/blake3 v1.4.1 h1:I3Smz7gso8w4/TunLKec6K2fn+kyKtDxr/xcQEN84Wg=
|
||||||
|
|||||||
@@ -596,7 +596,6 @@ class TlsStreamSettings extends XrayCommonClass {
|
|||||||
maxVersion = TLS_VERSION_OPTION.TLS13,
|
maxVersion = TLS_VERSION_OPTION.TLS13,
|
||||||
cipherSuites = '',
|
cipherSuites = '',
|
||||||
rejectUnknownSni = false,
|
rejectUnknownSni = false,
|
||||||
pinnedPeerCertSha256 = [],
|
|
||||||
disableSystemRoot = false,
|
disableSystemRoot = false,
|
||||||
enableSessionResumption = false,
|
enableSessionResumption = false,
|
||||||
certificates = [new TlsStreamSettings.Cert()],
|
certificates = [new TlsStreamSettings.Cert()],
|
||||||
@@ -611,7 +610,6 @@ class TlsStreamSettings extends XrayCommonClass {
|
|||||||
this.maxVersion = maxVersion;
|
this.maxVersion = maxVersion;
|
||||||
this.cipherSuites = cipherSuites;
|
this.cipherSuites = cipherSuites;
|
||||||
this.rejectUnknownSni = rejectUnknownSni;
|
this.rejectUnknownSni = rejectUnknownSni;
|
||||||
this.pinnedPeerCertSha256 = pinnedPeerCertSha256;
|
|
||||||
this.disableSystemRoot = disableSystemRoot;
|
this.disableSystemRoot = disableSystemRoot;
|
||||||
this.enableSessionResumption = enableSessionResumption;
|
this.enableSessionResumption = enableSessionResumption;
|
||||||
this.certs = certificates;
|
this.certs = certificates;
|
||||||
@@ -645,7 +643,6 @@ class TlsStreamSettings extends XrayCommonClass {
|
|||||||
json.maxVersion,
|
json.maxVersion,
|
||||||
json.cipherSuites,
|
json.cipherSuites,
|
||||||
json.rejectUnknownSni,
|
json.rejectUnknownSni,
|
||||||
json.pinnedPeerCertSha256 || [],
|
|
||||||
json.disableSystemRoot,
|
json.disableSystemRoot,
|
||||||
json.enableSessionResumption,
|
json.enableSessionResumption,
|
||||||
certs,
|
certs,
|
||||||
@@ -663,7 +660,6 @@ class TlsStreamSettings extends XrayCommonClass {
|
|||||||
maxVersion: this.maxVersion,
|
maxVersion: this.maxVersion,
|
||||||
cipherSuites: this.cipherSuites,
|
cipherSuites: this.cipherSuites,
|
||||||
rejectUnknownSni: this.rejectUnknownSni,
|
rejectUnknownSni: this.rejectUnknownSni,
|
||||||
pinnedPeerCertSha256: this.pinnedPeerCertSha256.length > 0 ? this.pinnedPeerCertSha256 : undefined,
|
|
||||||
disableSystemRoot: this.disableSystemRoot,
|
disableSystemRoot: this.disableSystemRoot,
|
||||||
enableSessionResumption: this.enableSessionResumption,
|
enableSessionResumption: this.enableSessionResumption,
|
||||||
certificates: TlsStreamSettings.toJsonArray(this.certs),
|
certificates: TlsStreamSettings.toJsonArray(this.certs),
|
||||||
@@ -984,6 +980,8 @@ class UdpMask extends XrayCommonClass {
|
|||||||
case 'header-dns':
|
case 'header-dns':
|
||||||
case 'xdns':
|
case 'xdns':
|
||||||
return { domain: settings.domain || '' };
|
return { domain: settings.domain || '' };
|
||||||
|
case 'xicmp':
|
||||||
|
return { ip: settings.ip || '', id: settings.id ?? 0 };
|
||||||
case 'mkcp-original':
|
case 'mkcp-original':
|
||||||
case 'header-dtls':
|
case 'header-dtls':
|
||||||
case 'header-srtp':
|
case 'header-srtp':
|
||||||
@@ -1309,14 +1307,6 @@ class Inbound extends XrayCommonClass {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
get kcpType() {
|
|
||||||
return this.stream.kcp.type;
|
|
||||||
}
|
|
||||||
|
|
||||||
get kcpSeed() {
|
|
||||||
return this.stream.kcp.seed;
|
|
||||||
}
|
|
||||||
|
|
||||||
get serviceName() {
|
get serviceName() {
|
||||||
return this.stream.grpc.serviceName;
|
return this.stream.grpc.serviceName;
|
||||||
}
|
}
|
||||||
@@ -1392,8 +1382,6 @@ class Inbound extends XrayCommonClass {
|
|||||||
}
|
}
|
||||||
} else if (network === 'kcp') {
|
} else if (network === 'kcp') {
|
||||||
const kcp = this.stream.kcp;
|
const kcp = this.stream.kcp;
|
||||||
obj.type = kcp.type;
|
|
||||||
obj.path = kcp.seed;
|
|
||||||
} else if (network === 'ws') {
|
} else if (network === 'ws') {
|
||||||
const ws = this.stream.ws;
|
const ws = this.stream.ws;
|
||||||
obj.path = ws.path;
|
obj.path = ws.path;
|
||||||
@@ -1456,8 +1444,6 @@ class Inbound extends XrayCommonClass {
|
|||||||
break;
|
break;
|
||||||
case "kcp":
|
case "kcp":
|
||||||
const kcp = this.stream.kcp;
|
const kcp = this.stream.kcp;
|
||||||
params.set("headerType", kcp.type);
|
|
||||||
params.set("seed", kcp.seed);
|
|
||||||
break;
|
break;
|
||||||
case "ws":
|
case "ws":
|
||||||
const ws = this.stream.ws;
|
const ws = this.stream.ws;
|
||||||
@@ -1561,8 +1547,6 @@ class Inbound extends XrayCommonClass {
|
|||||||
break;
|
break;
|
||||||
case "kcp":
|
case "kcp":
|
||||||
const kcp = this.stream.kcp;
|
const kcp = this.stream.kcp;
|
||||||
params.set("headerType", kcp.type);
|
|
||||||
params.set("seed", kcp.seed);
|
|
||||||
break;
|
break;
|
||||||
case "ws":
|
case "ws":
|
||||||
const ws = this.stream.ws;
|
const ws = this.stream.ws;
|
||||||
@@ -1642,8 +1626,6 @@ class Inbound extends XrayCommonClass {
|
|||||||
break;
|
break;
|
||||||
case "kcp":
|
case "kcp":
|
||||||
const kcp = this.stream.kcp;
|
const kcp = this.stream.kcp;
|
||||||
params.set("headerType", kcp.type);
|
|
||||||
params.set("seed", kcp.seed);
|
|
||||||
break;
|
break;
|
||||||
case "ws":
|
case "ws":
|
||||||
const ws = this.stream.ws;
|
const ws = this.stream.ws;
|
||||||
|
|||||||
@@ -345,7 +345,8 @@ class TlsStreamSettings extends CommonClass {
|
|||||||
fingerprint = '',
|
fingerprint = '',
|
||||||
allowInsecure = false,
|
allowInsecure = false,
|
||||||
echConfigList = '',
|
echConfigList = '',
|
||||||
verifyPeerCertByName = []
|
verifyPeerCertByName = 'cloudflare-dns.com',
|
||||||
|
pinnedPeerCertSha256 = '',
|
||||||
) {
|
) {
|
||||||
super();
|
super();
|
||||||
this.serverName = serverName;
|
this.serverName = serverName;
|
||||||
@@ -353,7 +354,8 @@ class TlsStreamSettings extends CommonClass {
|
|||||||
this.fingerprint = fingerprint;
|
this.fingerprint = fingerprint;
|
||||||
this.allowInsecure = allowInsecure;
|
this.allowInsecure = allowInsecure;
|
||||||
this.echConfigList = echConfigList;
|
this.echConfigList = echConfigList;
|
||||||
this.verifyPeerCertByName = Array.isArray(verifyPeerCertByName) ? verifyPeerCertByName.join(",") : verifyPeerCertByName;
|
this.verifyPeerCertByName = verifyPeerCertByName;
|
||||||
|
this.pinnedPeerCertSha256 = pinnedPeerCertSha256;
|
||||||
}
|
}
|
||||||
|
|
||||||
static fromJson(json = {}) {
|
static fromJson(json = {}) {
|
||||||
@@ -363,7 +365,8 @@ class TlsStreamSettings extends CommonClass {
|
|||||||
json.fingerprint,
|
json.fingerprint,
|
||||||
json.allowInsecure,
|
json.allowInsecure,
|
||||||
json.echConfigList,
|
json.echConfigList,
|
||||||
json.verifyPeerCertByName
|
json.verifyPeerCertByName,
|
||||||
|
json.pinnedPeerCertSha256,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -374,7 +377,8 @@ class TlsStreamSettings extends CommonClass {
|
|||||||
fingerprint: this.fingerprint,
|
fingerprint: this.fingerprint,
|
||||||
allowInsecure: this.allowInsecure,
|
allowInsecure: this.allowInsecure,
|
||||||
echConfigList: this.echConfigList,
|
echConfigList: this.echConfigList,
|
||||||
verifyPeerCertByName: this.verifyPeerCertByName.length > 0 ? this.verifyPeerCertByName.split(",") : undefined,
|
verifyPeerCertByName: this.verifyPeerCertByName,
|
||||||
|
pinnedPeerCertSha256: this.pinnedPeerCertSha256
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -577,6 +581,8 @@ class UdpMask extends CommonClass {
|
|||||||
case 'header-dns':
|
case 'header-dns':
|
||||||
case 'xdns':
|
case 'xdns':
|
||||||
return { domain: settings.domain || '' };
|
return { domain: settings.domain || '' };
|
||||||
|
case 'xicmp':
|
||||||
|
return { ip: settings.ip || '', id: settings.id ?? 0 };
|
||||||
case 'mkcp-original':
|
case 'mkcp-original':
|
||||||
case 'header-dtls':
|
case 'header-dtls':
|
||||||
case 'header-srtp':
|
case 'header-srtp':
|
||||||
|
|||||||
@@ -586,8 +586,13 @@
|
|||||||
<a-form-item label="Allow Insecure">
|
<a-form-item label="Allow Insecure">
|
||||||
<a-switch v-model="outbound.stream.tls.allowInsecure"></a-switch>
|
<a-switch v-model="outbound.stream.tls.allowInsecure"></a-switch>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
<a-form-item label="VerifyPeerCertByNames">
|
<a-form-item label="Verify Peer Cert By Name">
|
||||||
<a-input v-model.trim="outbound.stream.tls.verifyPeerCertByNames"></a-input>
|
<a-input v-model.trim="outbound.stream.tls.verifyPeerCertByName"></a-input>
|
||||||
|
</a-form-item>
|
||||||
|
<a-form-item label="Pinned Peer Cert">
|
||||||
|
<a-input v-model.trim="outbound.stream.tls.pinnedPeerCertSha256"
|
||||||
|
placeholder="Enter SHA256 fingerprints (base64)">
|
||||||
|
</a-input>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|||||||
@@ -48,6 +48,9 @@
|
|||||||
v-if="['tcp', 'ws', 'httpupgrade', 'xhttp'].includes(inbound.stream.network)"
|
v-if="['tcp', 'ws', 'httpupgrade', 'xhttp'].includes(inbound.stream.network)"
|
||||||
value="xdns">
|
value="xdns">
|
||||||
xDNS (Experimental)</a-select-option>
|
xDNS (Experimental)</a-select-option>
|
||||||
|
<a-select-option v-if="inbound.stream.network === 'kcp'"
|
||||||
|
value="xicmp">
|
||||||
|
xICMP (Experimental)</a-select-option>
|
||||||
</a-select>
|
</a-select>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
<a-form-item label='Password'
|
<a-form-item label='Password'
|
||||||
|
|||||||
@@ -58,12 +58,6 @@
|
|||||||
<a-form-item label="Session Resumption">
|
<a-form-item label="Session Resumption">
|
||||||
<a-switch v-model="inbound.stream.tls.enableSessionResumption"></a-switch>
|
<a-switch v-model="inbound.stream.tls.enableSessionResumption"></a-switch>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
<a-form-item label="Pinned Peer Cert">
|
|
||||||
<a-select mode="tags" v-model="inbound.stream.tls.pinnedPeerCertSha256"
|
|
||||||
:dropdown-class-name="themeSwitcher.currentTheme"
|
|
||||||
placeholder="Enter SHA256 fingerprints (base64)">
|
|
||||||
</a-select>
|
|
||||||
</a-form-item>
|
|
||||||
<a-divider :style="{ margin: '0' }"></a-divider>
|
<a-divider :style="{ margin: '0' }"></a-divider>
|
||||||
<template v-for="cert,index in inbound.stream.tls.certs">
|
<template v-for="cert,index in inbound.stream.tls.certs">
|
||||||
<a-form-item label='{{ i18n "certificate" }}'>
|
<a-form-item label='{{ i18n "certificate" }}'>
|
||||||
|
|||||||
@@ -52,11 +52,6 @@
|
|||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</template>
|
</template>
|
||||||
<template v-if="inbound.isKcp">
|
|
||||||
<tr><td>kcp {{ i18n "encryption" }}</td><td><a-tag>[[ inbound.kcpType ]]</a-tag></td></tr>
|
|
||||||
<tr><td>kcp {{ i18n "password" }}</td><td><a-tag>[[ inbound.kcpSeed ]]</a-tag></td></tr>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<template v-if="inbound.isGrpc">
|
<template v-if="inbound.isGrpc">
|
||||||
<tr><td>grpc serviceName</td><td>
|
<tr><td>grpc serviceName</td><td>
|
||||||
<a-tooltip :title="[[ inbound.serviceName ]]">
|
<a-tooltip :title="[[ inbound.serviceName ]]">
|
||||||
|
|||||||
@@ -220,13 +220,13 @@
|
|||||||
newRule = {};
|
newRule = {};
|
||||||
rule.type = "field";
|
rule.type = "field";
|
||||||
rule.domainMatcher = value.domainMatcher;
|
rule.domainMatcher = value.domainMatcher;
|
||||||
rule.domain = value.domain.length>0 ? value.domain.split(',') : [];
|
rule.domain = value.domain.length>0 ? value.domain.split(',').map(s => s.trim()) : [];
|
||||||
rule.ip = value.ip.length>0 ? value.ip.split(',') : [];
|
rule.ip = value.ip.length>0 ? value.ip.split(',').map(s => s.trim()) : [];
|
||||||
rule.port = value.port;
|
rule.port = value.port;
|
||||||
rule.sourcePort = value.sourcePort;
|
rule.sourcePort = value.sourcePort;
|
||||||
rule.network = value.network;
|
rule.network = value.network;
|
||||||
rule.source = value.source.length>0 ? value.source.split(',') : [];
|
rule.source = value.source.length>0 ? value.source.split(',').map(s => s.trim()) : [];
|
||||||
rule.user = value.user.length>0 ? value.user.split(',') : [];
|
rule.user = value.user.length>0 ? value.user.split(',').map(s => s.trim()) : [];
|
||||||
rule.inboundTag = value.inboundTag;
|
rule.inboundTag = value.inboundTag;
|
||||||
rule.protocol = value.protocol;
|
rule.protocol = value.protocol;
|
||||||
rule.attrs = Object.fromEntries(value.attrs);
|
rule.attrs = Object.fromEntries(value.attrs);
|
||||||
|
|||||||
@@ -48,10 +48,10 @@ func InitLocalizer(i18nFS embed.FS, settingService SettingService) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func createTemplateData(params []string, seperator ...string) map[string]interface{} {
|
func createTemplateData(params []string, separator ...string) map[string]interface{} {
|
||||||
var sep string = "=="
|
var sep string = "=="
|
||||||
if len(seperator) > 0 {
|
if len(separator) > 0 {
|
||||||
sep = seperator[0]
|
sep = separator[0]
|
||||||
}
|
}
|
||||||
|
|
||||||
templateData := make(map[string]interface{})
|
templateData := make(map[string]interface{})
|
||||||
|
|||||||
@@ -359,7 +359,12 @@ func (s *SettingService) GetTimeLocation() (*time.Location, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
defaultLocation := defaultValueMap["timeLocation"]
|
defaultLocation := defaultValueMap["timeLocation"]
|
||||||
logger.Errorf("location <%v> not exist, using default location: %v", l, defaultLocation)
|
logger.Errorf("location <%v> not exist, using default location: %v", l, defaultLocation)
|
||||||
return time.LoadLocation(defaultLocation)
|
location, err = time.LoadLocation(defaultLocation)
|
||||||
|
if err != nil {
|
||||||
|
logger.Errorf("failed to load default location, using UTC: %v", err)
|
||||||
|
return time.UTC, nil
|
||||||
|
}
|
||||||
|
return location, nil
|
||||||
}
|
}
|
||||||
return location, nil
|
return location, nil
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user