diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index ce3a94f0..0e460d24 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -10,7 +10,7 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 with: submodules: true diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 358e9029..96ef2d7b 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -7,8 +7,9 @@ on: push: branches: - main + tags: + - "v*.*.*" paths: - - '.github/workflows/release.yml' - '**.js' - '**.css' - '**.html' @@ -35,10 +36,10 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout repository - uses: actions/checkout@v4 + uses: actions/checkout@v5 - name: Setup Go - uses: actions/setup-go@v5 + uses: actions/setup-go@v6 with: go-version-file: go.mod check-latest: true @@ -84,7 +85,7 @@ jobs: cd x-ui/bin # Download dependencies - Xray_URL="https://github.com/XTLS/Xray-core/releases/download/v25.8.3/" + Xray_URL="https://github.com/XTLS/Xray-core/releases/download/v25.9.5/" if [ "${{ matrix.platform }}" == "amd64" ]; then wget -q ${Xray_URL}Xray-linux-64.zip unzip Xray-linux-64.zip @@ -135,10 +136,13 @@ jobs: - name: Upload files to GH release uses: svenstaro/upload-release-action@v2 - if: github.event_name == 'release' && github.event.action == 'published' + if: | + (github.event_name == 'release' && github.event.action == 'published') || + (github.event_name == 'push' && startsWith(github.ref, 'refs/tags/')) with: repo_token: ${{ secrets.GITHUB_TOKEN }} tag: ${{ github.ref }} file: x-ui-linux-${{ matrix.platform }}.tar.gz asset_name: x-ui-linux-${{ matrix.platform }}.tar.gz + overwrite: true prerelease: true diff --git a/DockerInit.sh b/DockerInit.sh index c457a33b..d08eaf61 100755 --- a/DockerInit.sh +++ b/DockerInit.sh @@ -27,7 +27,7 @@ case $1 in esac mkdir -p build/bin cd build/bin -wget -q "https://github.com/XTLS/Xray-core/releases/download/v25.8.3/Xray-linux-${ARCH}.zip" +wget -q "https://github.com/XTLS/Xray-core/releases/download/v25.9.5/Xray-linux-${ARCH}.zip" unzip "Xray-linux-${ARCH}.zip" rm -f "Xray-linux-${ARCH}.zip" geoip.dat geosite.dat mv xray "xray-linux-${FNAME}" diff --git a/Dockerfile b/Dockerfile index 4a15f98d..b818a7cd 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,7 +1,7 @@ # ======================================================== # Stage: Builder # ======================================================== -FROM golang:1.24-alpine AS builder +FROM golang:1.25-alpine AS builder WORKDIR /app ARG TARGETARCH diff --git a/config/version b/config/version index 952f449f..4484c2b2 100644 --- a/config/version +++ b/config/version @@ -1 +1 @@ -2.6.6 \ No newline at end of file +2.6.8 \ No newline at end of file diff --git a/database/model/model.go b/database/model/model.go index 68d56593..8157c510 100644 --- a/database/model/model.go +++ b/database/model/model.go @@ -32,6 +32,7 @@ type Inbound struct { Up int64 `json:"up" form:"up"` Down int64 `json:"down" form:"down"` Total int64 `json:"total" form:"total"` + AllTime int64 `json:"allTime" form:"allTime" gorm:"default:0"` Remark string `json:"remark" form:"remark"` Enable bool `json:"enable" form:"enable"` ExpiryTime int64 `json:"expiryTime" form:"expiryTime"` @@ -45,7 +46,6 @@ type Inbound struct { StreamSettings string `json:"streamSettings" form:"streamSettings"` Tag string `json:"tag" form:"tag" gorm:"unique"` Sniffing string `json:"sniffing" form:"sniffing"` - Allocate string `json:"allocate" form:"allocate"` } type OutboundTraffics struct { @@ -80,7 +80,6 @@ func (i *Inbound) GenXrayInboundConfig() *xray.InboundConfig { StreamSettings: json_util.RawMessage(i.StreamSettings), Tag: i.Tag, Sniffing: json_util.RawMessage(i.Sniffing), - Allocate: json_util.RawMessage(i.Allocate), } } @@ -104,6 +103,15 @@ type Client struct { SubID string `json:"subId" form:"subId"` Comment string `json:"comment" form:"comment"` Reset int `json:"reset" form:"reset"` + CreatedAt int64 `json:"created_at,omitempty"` + UpdatedAt int64 `json:"updated_at,omitempty"` +} + +type VLESSSettings struct { + Clients []Client `json:"clients"` + Decryption string `json:"decryption"` + Encryption string `json:"encryption"` + Fallbacks []any `json:"fallbacks"` } type Server struct { diff --git a/go.mod b/go.mod index 4d18f4b8..1438e29b 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module x-ui -go 1.24.5 +go 1.25.0 require ( github.com/gin-contrib/gzip v1.2.3 @@ -9,32 +9,33 @@ require ( github.com/goccy/go-json v0.10.5 github.com/google/uuid v1.6.0 github.com/joho/godotenv v1.5.1 - github.com/mymmrac/telego v1.2.0 + github.com/mymmrac/telego v1.3.0 github.com/nicksnyder/go-i18n/v2 v2.6.0 github.com/op/go-logging v0.0.0-20160315200505-970db520ece7 github.com/pelletier/go-toml/v2 v2.2.4 github.com/robfig/cron/v3 v3.0.1 - github.com/shirou/gopsutil/v4 v4.25.7 - github.com/valyala/fasthttp v1.64.0 + github.com/shirou/gopsutil/v4 v4.25.8 + github.com/valyala/fasthttp v1.65.0 github.com/xlzd/gotp v0.1.0 - github.com/xtls/xray-core v1.250803.0 + github.com/xtls/xray-core v1.250905.0 go.uber.org/atomic v1.11.0 golang.org/x/crypto v0.41.0 golang.org/x/text v0.28.0 - google.golang.org/grpc v1.74.2 + google.golang.org/grpc v1.75.0 gorm.io/driver/sqlite v1.6.0 - gorm.io/gorm v1.30.1 + gorm.io/gorm v1.30.2 ) require ( github.com/andybalholm/brotli v1.2.0 // indirect - github.com/bytedance/sonic v1.14.0 // indirect + github.com/bytedance/gopkg v0.1.3 // indirect + github.com/bytedance/sonic v1.14.1 // indirect github.com/bytedance/sonic/loader v0.3.0 // indirect github.com/cloudflare/circl v1.6.1 // indirect github.com/cloudwego/base64x v0.1.6 // indirect github.com/dgryski/go-metro v0.0.0-20250106013310-edb8663e5e33 // indirect github.com/ebitengine/purego v0.8.4 // indirect - github.com/gabriel-vasile/mimetype v1.4.9 // indirect + github.com/gabriel-vasile/mimetype v1.4.10 // indirect github.com/gin-contrib/sse v1.1.0 // indirect github.com/go-ole/go-ole v1.3.0 // indirect github.com/go-playground/locales v0.14.1 // indirect @@ -54,9 +55,9 @@ require ( github.com/klauspost/cpuid/v2 v2.3.0 // indirect github.com/kr/text v0.2.0 // indirect github.com/leodido/go-urn v1.4.0 // indirect - github.com/lufia/plan9stats v0.0.0-20250317134145-8bc96cf8fc35 // indirect + github.com/lufia/plan9stats v0.0.0-20250827001030-24949be3fa54 // indirect github.com/mattn/go-isatty v0.0.20 // indirect - github.com/mattn/go-sqlite3 v1.14.30 // indirect + github.com/mattn/go-sqlite3 v1.14.32 // indirect github.com/miekg/dns v1.1.68 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect @@ -68,8 +69,8 @@ require ( github.com/refraction-networking/utls v1.8.0 // indirect github.com/riobard/go-bloom v0.0.0-20200614022211-cdc8013cb5b3 // indirect github.com/rogpeppe/go-internal v1.14.1 // indirect - github.com/sagernet/sing v0.7.5 // indirect - github.com/sagernet/sing-shadowsocks v0.2.8 // indirect + github.com/sagernet/sing v0.7.7 // indirect + github.com/sagernet/sing-shadowsocks v0.2.9 // indirect github.com/seiflotfy/cuckoofilter v0.0.0-20240715131351-a2f2c23f1771 // indirect github.com/tklauser/go-sysconf v0.3.15 // indirect github.com/tklauser/numcpus v0.10.0 // indirect @@ -80,21 +81,21 @@ require ( github.com/valyala/fastjson v1.6.4 // indirect github.com/vishvananda/netlink v1.3.1 // indirect github.com/vishvananda/netns v0.0.5 // indirect - github.com/xtls/reality v0.0.0-20250727231020-de3bb4d08f5a // indirect + github.com/xtls/reality v0.0.0-20250904214705-431b6ff8c67c // indirect github.com/yusufpapurcu/wmi v1.2.4 // indirect - go.uber.org/mock v0.5.2 // indirect + go.uber.org/mock v0.6.0 // indirect go4.org/netipx v0.0.0-20231129151722-fdeea329fbba // indirect - golang.org/x/arch v0.20.0 // indirect + golang.org/x/arch v0.21.0 // indirect golang.org/x/mod v0.27.0 // indirect golang.org/x/net v0.43.0 // indirect - golang.org/x/sync v0.16.0 // indirect - golang.org/x/sys v0.35.0 // indirect - golang.org/x/time v0.12.0 // indirect + golang.org/x/sync v0.17.0 // indirect + golang.org/x/sys v0.36.0 // indirect + golang.org/x/time v0.13.0 // indirect golang.org/x/tools v0.36.0 // indirect golang.zx2c4.com/wintun v0.0.0-20230126152724-0fa3db229ce2 // indirect golang.zx2c4.com/wireguard v0.0.0-20250521234502-f333402bd9cb // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20250804133106-a7a43d27e69b // indirect - google.golang.org/protobuf v1.36.7 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20250826171959-ef028d996bc1 // indirect + google.golang.org/protobuf v1.36.8 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect gvisor.dev/gvisor v0.0.0-20250503011706-39ed1f5ac29c // indirect lukechampine.com/blake3 v1.4.1 // indirect diff --git a/go.sum b/go.sum index f11a3071..d5ece387 100644 --- a/go.sum +++ b/go.sum @@ -2,8 +2,10 @@ github.com/BurntSushi/toml v1.5.0 h1:W5quZX/G/csjUnuI8SUYlsHs9M38FC7znL0lIO+DvMg github.com/BurntSushi/toml v1.5.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho= github.com/andybalholm/brotli v1.2.0 h1:ukwgCxwYrmACq68yiUqwIWnGY0cTPox/M94sVwToPjQ= github.com/andybalholm/brotli v1.2.0/go.mod h1:rzTDkvFWvIrjDXZHkuS16NPggd91W3kUSvPlQ1pLaKY= -github.com/bytedance/sonic v1.14.0 h1:/OfKt8HFw0kh2rj8N0F6C/qPGRESq0BbaNZgcNXXzQQ= -github.com/bytedance/sonic v1.14.0/go.mod h1:WoEbx8WTcFJfzCe0hbmyTGrfjt8PzNEBdxlNUO24NhA= +github.com/bytedance/gopkg v0.1.3 h1:TPBSwH8RsouGCBcMBktLt1AymVo2TVsBVCY4b6TnZ/M= +github.com/bytedance/gopkg v0.1.3/go.mod h1:576VvJ+eJgyCzdjS+c4+77QF3p7ubbtiKARP3TxducM= +github.com/bytedance/sonic v1.14.1 h1:FBMC0zVz5XUmE4z9wF4Jey0An5FueFvOsTKKKtwIl7w= +github.com/bytedance/sonic v1.14.1/go.mod h1:gi6uhQLMbTdeP0muCnrjHLeCUPyb70ujhnNlhOylAFc= github.com/bytedance/sonic/loader v0.3.0 h1:dskwH8edlzNMctoruo8FPTJDF3vLtDT0sXZwvZJyqeA= github.com/bytedance/sonic/loader v0.3.0/go.mod h1:N8A3vUdtUebEY2/VQC0MyhYeKUFosQU6FxH2JmUe6VI= github.com/cloudflare/circl v1.6.1 h1:zqIqSPIndyBh1bjLVVDHMPpVKqp8Su/V+6MeDzzQBQ0= @@ -19,8 +21,8 @@ github.com/dgryski/go-metro v0.0.0-20250106013310-edb8663e5e33 h1:ucRHb6/lvW/+mT github.com/dgryski/go-metro v0.0.0-20250106013310-edb8663e5e33/go.mod h1:c9O8+fpSOX1DM8cPNSkX/qsBWdkD4yd2dpciOWQjpBw= github.com/ebitengine/purego v0.8.4 h1:CF7LEKg5FFOsASUj0+QwaXf8Ht6TlFxg09+S9wz0omw= github.com/ebitengine/purego v0.8.4/go.mod h1:iIjxzd6CiRiOG0UyXP+V1+jWqUXVjPKLAI0mRfJZTmQ= -github.com/gabriel-vasile/mimetype v1.4.9 h1:5k+WDwEsD9eTLL8Tz3L0VnmVh9QxGjRmjBvAG7U/oYY= -github.com/gabriel-vasile/mimetype v1.4.9/go.mod h1:WnSQhFKJuBlRyLiKohA/2DtIlPFAbguNaG7QCHcyGok= +github.com/gabriel-vasile/mimetype v1.4.10 h1:zyueNbySn/z8mJZHLt6IPw0KoZsiQNszIpU+bX4+ZK0= +github.com/gabriel-vasile/mimetype v1.4.10/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/go.mod h1:GIjDIg/heH5DOkXY3YJ/wNhfHsQHoXGjl8G8amsYQ1I= github.com/gin-contrib/gzip v1.2.3 h1:dAhT722RuEG330ce2agAs75z7yB+NKvX/ZM1r8w0u2U= @@ -91,12 +93,12 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ= github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI= -github.com/lufia/plan9stats v0.0.0-20250317134145-8bc96cf8fc35 h1:PpXWgLPs+Fqr325bN2FD2ISlRRztXibcX6e8f5FR5Dc= -github.com/lufia/plan9stats v0.0.0-20250317134145-8bc96cf8fc35/go.mod h1:autxFIvghDt3jPTLoqZ9OZ7s9qTGNAWmYCjVFWPX/zg= +github.com/lufia/plan9stats v0.0.0-20250827001030-24949be3fa54 h1:mFWunSatvkQQDhpdyuFAYwyAan3hzCuma+Pz8sqvOfg= +github.com/lufia/plan9stats v0.0.0-20250827001030-24949be3fa54/go.mod h1:autxFIvghDt3jPTLoqZ9OZ7s9qTGNAWmYCjVFWPX/zg= github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= -github.com/mattn/go-sqlite3 v1.14.30 h1:bVreufq3EAIG1Quvws73du3/QgdeZ3myglJlrzSYYCY= -github.com/mattn/go-sqlite3 v1.14.30/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y= +github.com/mattn/go-sqlite3 v1.14.32 h1:JD12Ag3oLy1zQA+BNn74xRgaBbdhbNIDYvQUEuuErjs= +github.com/mattn/go-sqlite3 v1.14.32/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y= github.com/miekg/dns v1.1.68 h1:jsSRkNozw7G/mnmXULynzMNIsgY2dHC8LO6U6Ij2JEA= github.com/miekg/dns v1.1.68/go.mod h1:fujopn7TB3Pu3JM69XaawiU0wqjpL9/8xGop5UrTPps= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= @@ -104,8 +106,8 @@ github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= -github.com/mymmrac/telego v1.2.0 h1:CHmR9eiugpTiF/ttppmK89E6mcu9d4DmNQS0tMpUs6M= -github.com/mymmrac/telego v1.2.0/go.mod h1:OiCm4QjqB/ZY2E4VAmkVH8EeLLhM4QuFuO1KOCuvGoM= +github.com/mymmrac/telego v1.3.0 h1:y2bDDCioLgkcs+5luUaPgTNHKel1Qh30iUxFcMUrowg= +github.com/mymmrac/telego v1.3.0/go.mod h1:0D2l/IA/gUFn4oqsi1O4/tSnlezw5jNV/ReFRDUEKk8= github.com/nicksnyder/go-i18n/v2 v2.6.0 h1:C/m2NNWNiTB6SK4Ao8df5EWm3JETSTIGNXBpMJTxzxQ= github.com/nicksnyder/go-i18n/v2 v2.6.0/go.mod h1:88sRqr0C6OPyJn0/KRNaEz1uWorjxIKP7rUUcvycecE= github.com/op/go-logging v0.0.0-20160315200505-970db520ece7 h1:lDH9UUVJtmYCjyT0CI4q8xvlXPxeZ0gYCVvWbmPlp88= @@ -132,14 +134,14 @@ github.com/robfig/cron/v3 v3.0.1 h1:WdRxkvbJztn8LMz/QEvLN5sBU+xKpSqwwUO1Pjr4qDs= github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro= github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ= github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc= -github.com/sagernet/sing v0.7.5 h1:gNMwZCLPqR+4e0g6dwi0sSsrvOmoMjpZgqxKsuJZatc= -github.com/sagernet/sing v0.7.5/go.mod h1:ARkL0gM13/Iv5VCZmci/NuoOlePoIsW0m7BWfln/Hak= -github.com/sagernet/sing-shadowsocks v0.2.8 h1:PURj5PRoAkqeHh2ZW205RWzN9E9RtKCVCzByXruQWfE= -github.com/sagernet/sing-shadowsocks v0.2.8/go.mod h1:lo7TWEMDcN5/h5B8S0ew+r78ZODn6SwVaFhvB6H+PTI= +github.com/sagernet/sing v0.7.7 h1:o46FzVZS+wKbBMEkMEdEHoVZxyM9jvfRpKXc7pEgS/c= +github.com/sagernet/sing v0.7.7/go.mod h1:ARkL0gM13/Iv5VCZmci/NuoOlePoIsW0m7BWfln/Hak= +github.com/sagernet/sing-shadowsocks v0.2.9 h1:Paep5zCszRKsEn8587O0MnhFWKJwDW1Y4zOYYlIxMkM= +github.com/sagernet/sing-shadowsocks v0.2.9/go.mod h1:TE/Z6401Pi8tgr0nBZcM/xawAI6u3F6TTbz4nH/qw+8= github.com/seiflotfy/cuckoofilter v0.0.0-20240715131351-a2f2c23f1771 h1:emzAzMZ1L9iaKCTxdy3Em8Wv4ChIAGnfiz18Cda70g4= github.com/seiflotfy/cuckoofilter v0.0.0-20240715131351-a2f2c23f1771/go.mod h1:bR6DqgcAl1zTcOX8/pE2Qkj9XO00eCNqmKb7lXP8EAg= -github.com/shirou/gopsutil/v4 v4.25.7 h1:bNb2JuqKuAu3tRlPv5piSmBZyMfecwQ+t/ILq+1JqVM= -github.com/shirou/gopsutil/v4 v4.25.7/go.mod h1:XV/egmwJtd3ZQjBpJVY5kndsiOO4IRqy9TQnmm6VP7U= +github.com/shirou/gopsutil/v4 v4.25.8 h1:NnAsw9lN7587WHxjJA9ryDnqhJpFH6A+wagYWTOH970= +github.com/shirou/gopsutil/v4 v4.25.8/go.mod h1:q9QdMmfAOVIw7a+eF86P7ISEU6ka+NLgkUxlopV4RwI= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= @@ -148,8 +150,8 @@ github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= -github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= -github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= +github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= github.com/tklauser/go-sysconf v0.3.15 h1:VE89k0criAymJ/Os65CSn1IXaol+1wrsFHEB8Ol49K4= github.com/tklauser/go-sysconf v0.3.15/go.mod h1:Dmjwr6tYFIseJw7a3dRLJfsHAMXZ3nEnL/aZY+0IuI4= github.com/tklauser/numcpus v0.10.0 h1:18njr6LDBk1zuna922MgdjQuJFjrdppsZG60sHGfjso= @@ -162,8 +164,8 @@ github.com/v2fly/ss-bloomring v0.0.0-20210312155135-28617310f63e h1:5QefA066A1tF github.com/v2fly/ss-bloomring v0.0.0-20210312155135-28617310f63e/go.mod h1:5t19P9LBIrNamL6AcMQOncg/r10y3Pc01AbHeMhwlpU= github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= -github.com/valyala/fasthttp v1.64.0 h1:QBygLLQmiAyiXuRhthf0tuRkqAFcrC42dckN2S+N3og= -github.com/valyala/fasthttp v1.64.0/go.mod h1:dGmFxwkWXSK0NbOSJuF7AMVzU+lkHz0wQVvVITv2UQA= +github.com/valyala/fasthttp v1.65.0 h1:j/u3uzFEGFfRxw79iYzJN+TteTJwbYkru9uDp3d0Yf8= +github.com/valyala/fasthttp v1.65.0/go.mod h1:P/93/YkKPMsKSnATEeELUCkG8a7Y+k99uxNHVbKINr4= github.com/valyala/fastjson v1.6.4 h1:uAUNq9Z6ymTgGhcm0UynUAB6tlbakBrz6CQFax3BXVQ= github.com/valyala/fastjson v1.6.4/go.mod h1:CLCAqky6SMuOcxStkYQvblddUtoRxhYMGLrsQns1aXY= github.com/vishvananda/netlink v1.3.1 h1:3AEMt62VKqz90r0tmNhog0r/PpWKmrEShJU0wJW6bV0= @@ -172,66 +174,68 @@ github.com/vishvananda/netns v0.0.5 h1:DfiHV+j8bA32MFM7bfEunvT8IAqQ/NzSJHtcmW5zd github.com/vishvananda/netns v0.0.5/go.mod h1:SpkAiCQRtJ6TvvxPnOSyH3BMl6unz3xZlaprSwhNNJM= github.com/xlzd/gotp v0.1.0 h1:37blvlKCh38s+fkem+fFh7sMnceltoIEBYTVXyoa5Po= github.com/xlzd/gotp v0.1.0/go.mod h1:ndLJ3JKzi3xLmUProq4LLxCuECL93dG9WASNLpHz8qg= -github.com/xtls/reality v0.0.0-20250727231020-de3bb4d08f5a h1:Fs8Pc0JAc/LDOf9Q4DzKrk+Ujf4ILlyvfvDVZcmOZ2o= -github.com/xtls/reality v0.0.0-20250727231020-de3bb4d08f5a/go.mod h1:XxvnCCgBee4WWE0bc4E+a7wbk8gkJ/rS0vNVNtC5qp0= -github.com/xtls/xray-core v1.250803.0 h1:sYdRC243UsujnePINH4IfM4MfHE4lj2p4wZFAfeE2GI= -github.com/xtls/xray-core v1.250803.0/go.mod h1:z2vn2o30flYEgpSz1iEhdZP1I46UZ3+gXINZyohH3yE= +github.com/xtls/reality v0.0.0-20250904214705-431b6ff8c67c h1:LHLhQY3mKXSpTcQAkjFR4/6ar3rXjQryNeM7khK3AHU= +github.com/xtls/reality v0.0.0-20250904214705-431b6ff8c67c/go.mod h1:XxvnCCgBee4WWE0bc4E+a7wbk8gkJ/rS0vNVNtC5qp0= +github.com/xtls/xray-core v1.250905.0 h1:VNL3l/6fcwyeYXJTRbf+TYqPfJYkk0Wmmz7qoQNkxY8= +github.com/xtls/xray-core v1.250905.0/go.mod h1:WB/73DmN9Vs7lxtx4Xc/D0Ub1VUu06hAh1mMh8JN2uM= github.com/xyproto/randomstring v1.0.5 h1:YtlWPoRdgMu3NZtP45drfy1GKoojuR7hmRcnhZqKjWU= github.com/xyproto/randomstring v1.0.5/go.mod h1:rgmS5DeNXLivK7YprL0pY+lTuhNQW3iGxZ18UQApw/E= github.com/yusufpapurcu/wmi v1.2.4 h1:zFUKzehAFReQwLys1b/iSMl+JQGSCSjtVqQn9bBrPo0= github.com/yusufpapurcu/wmi v1.2.4/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA= go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A= -go.opentelemetry.io/otel v1.36.0 h1:UumtzIklRBY6cI/lllNZlALOF5nNIzJVb16APdvgTXg= -go.opentelemetry.io/otel v1.36.0/go.mod h1:/TcFMXYjyRNh8khOAO9ybYkqaDBb/70aVwkNML4pP8E= -go.opentelemetry.io/otel/metric v1.36.0 h1:MoWPKVhQvJ+eeXWHFBOPoBOi20jh6Iq2CcCREuTYufE= -go.opentelemetry.io/otel/metric v1.36.0/go.mod h1:zC7Ks+yeyJt4xig9DEw9kuUFe5C3zLbVjV2PzT6qzbs= -go.opentelemetry.io/otel/sdk v1.36.0 h1:b6SYIuLRs88ztox4EyrvRti80uXIFy+Sqzoh9kFULbs= -go.opentelemetry.io/otel/sdk v1.36.0/go.mod h1:+lC+mTgD+MUWfjJubi2vvXWcVxyr9rmlshZni72pXeY= -go.opentelemetry.io/otel/sdk/metric v1.36.0 h1:r0ntwwGosWGaa0CrSt8cuNuTcccMXERFwHX4dThiPis= -go.opentelemetry.io/otel/sdk/metric v1.36.0/go.mod h1:qTNOhFDfKRwX0yXOqJYegL5WRaW376QbB7P4Pb0qva4= -go.opentelemetry.io/otel/trace v1.36.0 h1:ahxWNuqZjpdiFAyrIoQ4GIiAIhxAunQR6MUoKrsNd4w= -go.opentelemetry.io/otel/trace v1.36.0/go.mod h1:gQ+OnDZzrybY4k4seLzPAWNwVBBVlF2szhehOBB/tGA= +go.opentelemetry.io/otel v1.37.0 h1:9zhNfelUvx0KBfu/gb+ZgeAfAgtWrfHJZcAqFC228wQ= +go.opentelemetry.io/otel v1.37.0/go.mod h1:ehE/umFRLnuLa/vSccNq9oS1ErUlkkK71gMcN34UG8I= +go.opentelemetry.io/otel/metric v1.37.0 h1:mvwbQS5m0tbmqML4NqK+e3aDiO02vsf/WgbsdpcPoZE= +go.opentelemetry.io/otel/metric v1.37.0/go.mod h1:04wGrZurHYKOc+RKeye86GwKiTb9FKm1WHtO+4EVr2E= +go.opentelemetry.io/otel/sdk v1.37.0 h1:ItB0QUqnjesGRvNcmAcU0LyvkVyGJ2xftD29bWdDvKI= +go.opentelemetry.io/otel/sdk v1.37.0/go.mod h1:VredYzxUvuo2q3WRcDnKDjbdvmO0sCzOvVAiY+yUkAg= +go.opentelemetry.io/otel/sdk/metric v1.37.0 h1:90lI228XrB9jCMuSdA0673aubgRobVZFhbjxHHspCPc= +go.opentelemetry.io/otel/sdk/metric v1.37.0/go.mod h1:cNen4ZWfiD37l5NhS+Keb5RXVWZWpRE+9WyVCpbo5ps= +go.opentelemetry.io/otel/trace v1.37.0 h1:HLdcFNbRQBE2imdSEgm/kwqmQj1Or1l/7bW6mxVK7z4= +go.opentelemetry.io/otel/trace v1.37.0/go.mod h1:TlgrlQ+PtQO5XFerSPUYG0JSgGyryXewPGyayAWSBS0= go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE= go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= -go.uber.org/mock v0.5.2 h1:LbtPTcP8A5k9WPXj54PPPbjcI4Y6lhyOZXn+VS7wNko= -go.uber.org/mock v0.5.2/go.mod h1:wLlUxC2vVTPTaE3UD51E0BGOAElKrILxhVSDYQLld5o= +go.uber.org/mock v0.6.0 h1:hyF9dfmbgIX5EfOdasqLsWD6xqpNZlXblLB/Dbnwv3Y= +go.uber.org/mock v0.6.0/go.mod h1:KiVJ4BqZJaMj4svdfmHM0AUx4NJYO8ZNpPnZn1Z+BBU= go4.org/netipx v0.0.0-20231129151722-fdeea329fbba h1:0b9z3AuHCjxk0x/opv64kcgZLBseWJUpBw5I82+2U4M= go4.org/netipx v0.0.0-20231129151722-fdeea329fbba/go.mod h1:PLyyIXexvUFg3Owu6p/WfdlivPbZJsZdgWZlrGope/Y= -golang.org/x/arch v0.20.0 h1:dx1zTU0MAE98U+TQ8BLl7XsJbgze2WnNKF/8tGp/Q6c= -golang.org/x/arch v0.20.0/go.mod h1:bdwinDaKcfZUGpH09BB7ZmOfhalA8lQdzl62l8gGWsk= +golang.org/x/arch v0.21.0 h1:iTC9o7+wP6cPWpDWkivCvQFGAHDQ59SrSxsLPcnkArw= +golang.org/x/arch v0.21.0/go.mod h1:dNHoOeKiyja7GTvF9NJS1l3Z2yntpQNzgrjh1cU103A= golang.org/x/crypto v0.41.0 h1:WKYxWedPGCTVVl5+WHSSrOBT0O8lx32+zxmHxijgXp4= golang.org/x/crypto v0.41.0/go.mod h1:pO5AFd7FA68rFak7rOAGVuygIISepHftHnr8dr6+sUc= golang.org/x/mod v0.27.0 h1:kb+q2PyFnEADO2IEF935ehFUXlWiNjJWtRNgBLSfbxQ= golang.org/x/mod v0.27.0/go.mod h1:rWI627Fq0DEoudcK+MBkNkCe0EetEaDSwJJkCcjpazc= golang.org/x/net v0.43.0 h1:lat02VYK2j4aLzMzecihNvTlJNQUq316m2Mr9rnM6YE= golang.org/x/net v0.43.0/go.mod h1:vhO1fvI4dGsIjh73sWfUVjj3N7CA9WkKJNQm2svM6Jg= -golang.org/x/sync v0.16.0 h1:ycBJEhp9p4vXvUZNszeOq0kGTPghopOL8q0fq3vstxw= -golang.org/x/sync v0.16.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= +golang.org/x/sync v0.17.0 h1:l60nONMj9l5drqw6jlhIELNv9I0A4OFgRsG9k2oT9Ug= +golang.org/x/sync v0.17.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201204225414-ed752295db88/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.35.0 h1:vz1N37gP5bs89s7He8XuIYXpyY0+QlsKmzipCbUtyxI= -golang.org/x/sys v0.35.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= +golang.org/x/sys v0.36.0 h1:KVRy2GtZBrk1cBYA7MKu5bEZFxQk4NIDV6RLVcC8o0k= +golang.org/x/sys v0.36.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= golang.org/x/text v0.28.0 h1:rhazDwis8INMIwQ4tpjLDzUhx6RlXqZNPEM0huQojng= golang.org/x/text v0.28.0/go.mod h1:U8nCwOR8jO/marOQ0QbDiOngZVEBB7MAiitBuMjXiNU= -golang.org/x/time v0.12.0 h1:ScB/8o8olJvc+CQPWrK3fPZNfh7qgwCrY0zJmoEQLSE= -golang.org/x/time v0.12.0/go.mod h1:CDIdPxbZBQxdj6cxyCIdrNogrJKMJ7pr37NYpMcMDSg= +golang.org/x/time v0.13.0 h1:eUlYslOIt32DgYD6utsuUeHs4d7AsEYLuIAdg7FlYgI= +golang.org/x/time v0.13.0/go.mod h1:eL/Oa2bBBK0TkX57Fyni+NgnyQQN4LitPmob2Hjnqw4= golang.org/x/tools v0.36.0 h1:kWS0uv/zsvHEle1LbV5LE8QujrxB3wfQyxHfhOk0Qkg= golang.org/x/tools v0.36.0/go.mod h1:WBDiHKJK8YgLHlcQPYQzNCkUxUypCaa5ZegCVutKm+s= golang.zx2c4.com/wintun v0.0.0-20230126152724-0fa3db229ce2 h1:B82qJJgjvYKsXS9jeunTOisW56dUokqW/FOteYJJ/yg= golang.zx2c4.com/wintun v0.0.0-20230126152724-0fa3db229ce2/go.mod h1:deeaetjYA+DHMHg+sMSMI58GrEteJUUzzw7en6TJQcI= golang.zx2c4.com/wireguard v0.0.0-20250521234502-f333402bd9cb h1:whnFRlWMcXI9d+ZbWg+4sHnLp52d5yiIPUxMBSt4X9A= golang.zx2c4.com/wireguard v0.0.0-20250521234502-f333402bd9cb/go.mod h1:rpwXGsirqLqN2L0JDJQlwOboGHmptD5ZD6T2VmcqhTw= -google.golang.org/genproto/googleapis/rpc v0.0.0-20250804133106-a7a43d27e69b h1:zPKJod4w6F1+nRGDI9ubnXYhU9NSWoFAijkHkUXeTK8= -google.golang.org/genproto/googleapis/rpc v0.0.0-20250804133106-a7a43d27e69b/go.mod h1:qQ0YXyHHx3XkvlzUtpXDkS29lDSafHMZBAZDc03LQ3A= -google.golang.org/grpc v1.74.2 h1:WoosgB65DlWVC9FqI82dGsZhWFNBSLjQ84bjROOpMu4= -google.golang.org/grpc v1.74.2/go.mod h1:CtQ+BGjaAIXHs/5YS3i473GqwBBa1zGQNevxdeBEXrM= -google.golang.org/protobuf v1.36.7 h1:IgrO7UwFQGJdRNXH/sQux4R1Dj1WAKcLElzeeRaXV2A= -google.golang.org/protobuf v1.36.7/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY= +gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk= +gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E= +google.golang.org/genproto/googleapis/rpc v0.0.0-20250826171959-ef028d996bc1 h1:pmJpJEvT846VzausCQ5d7KreSROcDqmO388w5YbnltA= +google.golang.org/genproto/googleapis/rpc v0.0.0-20250826171959-ef028d996bc1/go.mod h1:GmFNa4BdJZ2a8G+wCe9Bg3wwThLrJun751XstdJt5Og= +google.golang.org/grpc v1.75.0 h1:+TW+dqTd2Biwe6KKfhE5JpiYIBWq865PhKGSXiivqt4= +google.golang.org/grpc v1.75.0/go.mod h1:JtPAzKiq4v1xcAB2hydNlWI2RnF85XXcV0mhKXr2ecQ= +google.golang.org/protobuf v1.36.8 h1:xHScyCOEuuwZEc6UtSOvPbAT4zRh0xcNRYekJwfqyMc= +google.golang.org/protobuf v1.36.8/go.mod h1:fuxRtAxBytpl4zzqUh6/eyUujkJdNiuEkXntxiD/uRU= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= @@ -243,8 +247,8 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gorm.io/driver/sqlite v1.6.0 h1:WHRRrIiulaPiPFmDcod6prc4l2VGVWHz80KspNsxSfQ= gorm.io/driver/sqlite v1.6.0/go.mod h1:AO9V1qIQddBESngQUKWL9yoH93HIeA1X6V633rBwyT8= -gorm.io/gorm v1.30.1 h1:lSHg33jJTBxs2mgJRfRZeLDG+WZaHYCk3Wtfl6Ngzo4= -gorm.io/gorm v1.30.1/go.mod h1:8Z33v652h4//uMA76KjeDH8mJXPm1QNCYrMeatR0DOE= +gorm.io/gorm v1.30.2 h1:f7bevlVoVe4Byu3pmbWPVHnPsLoWaMjEb7/clyr9Ivs= +gorm.io/gorm v1.30.2/go.mod h1:8Z33v652h4//uMA76KjeDH8mJXPm1QNCYrMeatR0DOE= gvisor.dev/gvisor v0.0.0-20250503011706-39ed1f5ac29c h1:m/r7OM+Y2Ty1sgBQ7Qb27VgIMBW8ZZhT4gLnUyDIhzI= gvisor.dev/gvisor v0.0.0-20250503011706-39ed1f5ac29c/go.mod h1:3r5CMtNQMKIvBlrmM9xWUNamjKBYPOWyXOjmg5Kts3g= lukechampine.com/blake3 v1.4.1 h1:I3Smz7gso8w4/TunLKec6K2fn+kyKtDxr/xcQEN84Wg= diff --git a/install.sh b/install.sh index 5b47fd55..32657189 100644 --- a/install.sh +++ b/install.sh @@ -7,7 +7,6 @@ yellow='\033[0;33m' plain='\033[0m' cur_dir=$(pwd) -show_ip_service_lists=("https://api.ipify.org" "https://4.ident.me") # check root [[ $EUID -ne 0 ]] && echo -e "${red}Fatal error: ${plain} Please run this script with root privilege \n " && exit 1 @@ -58,7 +57,7 @@ install_base() { zypper refresh && zypper -q install -y wget curl tar timezone ;; *) - apt-get update && apt install -y -q wget curl tar tzdata + apt-get update && apt-get install -y -q wget curl tar tzdata ;; esac } @@ -73,10 +72,18 @@ config_after_install() { local existing_hasDefaultCredential=$(/usr/local/x-ui/x-ui setting -show true | grep -Eo 'hasDefaultCredential: .+' | awk '{print $2}') local existing_webBasePath=$(/usr/local/x-ui/x-ui setting -show true | grep -Eo 'webBasePath: .+' | awk '{print $2}') local existing_port=$(/usr/local/x-ui/x-ui setting -show true | grep -Eo 'port: .+' | awk '{print $2}') - - for ip_service_addr in "${show_ip_service_lists[@]}"; do - local server_ip=$(curl -s --max-time 3 ${ip_service_addr} 2>/dev/null) - if [ -n "${server_ip}" ]; then + local URL_lists=( + "https://api4.ipify.org" + "https://ipv4.icanhazip.com" + "https://v4.api.ipinfo.io/ip" + "https://ipv4.myexternalip.com/raw" + "https://4.ident.me" + "https://check-host.net/ip" + ) + local server_ip="" + for ip_address in "${URL_lists[@]}"; do + server_ip=$(curl -s --max-time 3 "${ip_address}" 2>/dev/null | tr -d '[:space:]') + if [[ -n "${server_ip}" ]]; then break fi done diff --git a/sub/subController.go b/sub/subController.go index 2f22ecab..3f053740 100644 --- a/sub/subController.go +++ b/sub/subController.go @@ -53,7 +53,6 @@ func (a *SUBController) initRouter(g *gin.RouterGroup) { gJson := g.Group(a.subJsonPath) gLink.GET(":subid", a.subs) - gJson.GET(":subid", a.subJsons) } @@ -85,7 +84,7 @@ func (a *SUBController) subs(c *gin.Context) { // Add headers c.Writer.Header().Set("Subscription-Userinfo", header) c.Writer.Header().Set("Profile-Update-Interval", a.updateInterval) - c.Writer.Header().Set("Profile-Title", "base64:" + base64.StdEncoding.EncodeToString([]byte(a.subTitle))) + c.Writer.Header().Set("Profile-Title", "base64:"+base64.StdEncoding.EncodeToString([]byte(a.subTitle))) if a.subEncrypt { c.String(200, base64.StdEncoding.EncodeToString([]byte(result))) @@ -119,7 +118,7 @@ func (a *SUBController) subJsons(c *gin.Context) { // Add headers c.Writer.Header().Set("Subscription-Userinfo", header) c.Writer.Header().Set("Profile-Update-Interval", a.updateInterval) - c.Writer.Header().Set("Profile-Title", "base64:" + base64.StdEncoding.EncodeToString([]byte(a.subTitle))) + c.Writer.Header().Set("Profile-Title", "base64:"+base64.StdEncoding.EncodeToString([]byte(a.subTitle))) c.String(200, jsonSub) } diff --git a/sub/subJsonService.go b/sub/subJsonService.go index 7bc4d1db..def8b855 100644 --- a/sub/subJsonService.go +++ b/sub/subJsonService.go @@ -184,8 +184,14 @@ func (s *SubJsonService) getConfig(inbound *model.Inbound, client model.Client, var newOutbounds []json_util.RawMessage switch inbound.Protocol { - case "vmess", "vless": - newOutbounds = append(newOutbounds, s.genVnext(inbound, streamSettings, client)) + case "vmess": + newOutbounds = append(newOutbounds, s.genVnext(inbound, streamSettings, client, "")) + case "vless": + var vlessSettings model.VLESSSettings + _ = json.Unmarshal([]byte(inbound.Settings), &vlessSettings) + + newOutbounds = append(newOutbounds, + s.genVnext(inbound, streamSettings, client, vlessSettings.Encryption)) case "trojan", "shadowsocks": newOutbounds = append(newOutbounds, s.genServer(inbound, streamSettings, client)) } @@ -209,9 +215,10 @@ func (s *SubJsonService) streamData(stream string) map[string]any { var streamSettings map[string]any json.Unmarshal([]byte(stream), &streamSettings) security, _ := streamSettings["security"].(string) - if security == "tls" { + switch security { + case "tls": streamSettings["tlsSettings"] = s.tlsData(streamSettings["tlsSettings"].(map[string]any)) - } else if security == "reality" { + case "reality": streamSettings["realitySettings"] = s.realityData(streamSettings["realitySettings"].(map[string]any)) } delete(streamSettings, "sockopt") @@ -283,7 +290,7 @@ func (s *SubJsonService) realityData(rData map[string]any) map[string]any { return rltyData } -func (s *SubJsonService) genVnext(inbound *model.Inbound, streamSettings json_util.RawMessage, client model.Client) json_util.RawMessage { +func (s *SubJsonService) genVnext(inbound *model.Inbound, streamSettings json_util.RawMessage, client model.Client, encryption string) json_util.RawMessage { outbound := Outbound{} usersData := make([]UserVnext, 1) @@ -294,7 +301,7 @@ func (s *SubJsonService) genVnext(inbound *model.Inbound, streamSettings json_ut } if inbound.Protocol == model.VLESS { usersData[0].Flow = client.Flow - usersData[0].Encryption = "none" + usersData[0].Encryption = encryption } vnextData := make([]VnextSetting, 1) diff --git a/sub/subService.go b/sub/subService.go index 81d0f9fb..b1d6d328 100644 --- a/sub/subService.go +++ b/sub/subService.go @@ -330,6 +330,9 @@ func (s *SubService) genVlessLink(inbound *model.Inbound, email string, server * if inbound.Protocol != model.VLESS { return "" } + var vlessSettings model.VLESSSettings + _ = json.Unmarshal([]byte(inbound.Settings), &vlessSettings) + var stream map[string]any json.Unmarshal([]byte(inbound.StreamSettings), &stream) clients, _ := s.inboundService.GetClients(inbound) @@ -344,6 +347,9 @@ func (s *SubService) genVlessLink(inbound *model.Inbound, email string, server * port := inbound.Port streamNetwork := stream["network"].(string) params := make(map[string]string) + if vlessSettings.Encryption != "" { + params["encryption"] = vlessSettings.Encryption + } params["type"] = streamNetwork switch streamNetwork { diff --git a/web/assets/js/model/dbinbound.js b/web/assets/js/model/dbinbound.js index 45301ddd..acb62ce4 100644 --- a/web/assets/js/model/dbinbound.js +++ b/web/assets/js/model/dbinbound.js @@ -6,6 +6,7 @@ class DBInbound { this.up = 0; this.down = 0; this.total = 0; + this.allTime = 0; this.remark = ""; this.enable = true; this.expiryTime = 0; diff --git a/web/assets/js/model/inbound.js b/web/assets/js/model/inbound.js index 803b5d94..c2467c36 100644 --- a/web/assets/js/model/inbound.js +++ b/web/assets/js/model/inbound.js @@ -11,10 +11,8 @@ const Protocols = { const SSMethods = { AES_256_GCM: 'aes-256-gcm', - AES_128_GCM: 'aes-128-gcm', CHACHA20_POLY1305: 'chacha20-poly1305', CHACHA20_IETF_POLY1305: 'chacha20-ietf-poly1305', - XCHACHA20_POLY1305: 'xchacha20-poly1305', XCHACHA20_IETF_POLY1305: 'xchacha20-ietf-poly1305', BLAKE3_AES_128_GCM: '2022-blake3-aes-128-gcm', BLAKE3_AES_256_GCM: '2022-blake3-aes-256-gcm', @@ -1042,27 +1040,6 @@ class Sniffing extends XrayCommonClass { } } -class Allocate extends XrayCommonClass { - constructor( - strategy = "always", - refresh = 5, - concurrency = 3, - ) { - super(); - this.strategy = strategy; - this.refresh = refresh; - this.concurrency = concurrency; - } - - static fromJson(json = {}) { - return new Allocate( - json.strategy, - json.refresh, - json.concurrency, - ); - } -} - class Inbound extends XrayCommonClass { constructor( port = RandomUtil.randomInteger(10000, 60000), @@ -1072,7 +1049,6 @@ class Inbound extends XrayCommonClass { streamSettings = new StreamSettings(), tag = '', sniffing = new Sniffing(), - allocate = new Allocate(), clientStats = '', ) { super(); @@ -1083,7 +1059,6 @@ class Inbound extends XrayCommonClass { this.stream = streamSettings; this.tag = tag; this.sniffing = sniffing; - this.allocate = allocate; this.clientStats = clientStats; } getClientStats() { @@ -1248,7 +1223,6 @@ class Inbound extends XrayCommonClass { this.stream = new StreamSettings(); this.tag = ''; this.sniffing = new Sniffing(); - this.allocate = new Allocate(); } genVmessLink(address = '', port = this.port, forceTls, remark = '', clientId, security) { @@ -1325,6 +1299,7 @@ class Inbound extends XrayCommonClass { const security = forceTls == 'same' ? this.stream.security : forceTls; const params = new Map(); params.set("type", this.stream.network); + params.set("encryption", this.settings.encryption); switch (type) { case "tcp": const tcp = this.stream.tcp; @@ -1703,7 +1678,6 @@ class Inbound extends XrayCommonClass { StreamSettings.fromJson(json.streamSettings), json.tag, Sniffing.fromJson(json.sniffing), - Allocate.fromJson(json.allocate), json.clientStats ) } @@ -1721,7 +1695,6 @@ class Inbound extends XrayCommonClass { streamSettings: streamSettings, tag: this.tag, sniffing: this.sniffing.toJson(), - allocate: this.allocate.toJson(), clientStats: this.clientStats }; } @@ -1817,7 +1790,9 @@ Inbound.VmessSettings.VMESS = class extends XrayCommonClass { tgId = '', subId = RandomUtil.randomLowerAndNum(16), comment = '', - reset = 0 + reset = 0, + created_at = undefined, + updated_at = undefined ) { super(); this.id = id; @@ -1831,6 +1806,8 @@ Inbound.VmessSettings.VMESS = class extends XrayCommonClass { this.subId = subId; this.comment = comment; this.reset = reset; + this.created_at = created_at; + this.updated_at = updated_at; } static fromJson(json = {}) { @@ -1846,6 +1823,8 @@ Inbound.VmessSettings.VMESS = class extends XrayCommonClass { json.subId, json.comment, json.reset, + json.created_at, + json.updated_at, ); } get _expiryTime() { @@ -1879,13 +1858,17 @@ Inbound.VLESSSettings = class extends Inbound.Settings { constructor( protocol, vlesses = [new Inbound.VLESSSettings.VLESS()], - decryption = 'none', - fallbacks = [] + decryption = "none", + encryption = "none", + fallbacks = [], + selectedAuth = undefined, ) { super(protocol); this.vlesses = vlesses; this.decryption = decryption; + this.encryption = encryption; this.fallbacks = fallbacks; + this.selectedAuth = selectedAuth; } addFallback() { @@ -1896,22 +1879,43 @@ Inbound.VLESSSettings = class extends Inbound.Settings { this.fallbacks.splice(index, 1); } - // decryption should be set to static value static fromJson(json = {}) { - return new Inbound.VLESSSettings( + const obj = new Inbound.VLESSSettings( Protocols.VLESS, - json.clients.map(client => Inbound.VLESSSettings.VLESS.fromJson(client)), - json.decryption || 'none', - Inbound.VLESSSettings.Fallback.fromJson(json.fallbacks),); + (json.clients || []).map(client => Inbound.VLESSSettings.VLESS.fromJson(client)), + json.decryption, + json.encryption, + Inbound.VLESSSettings.Fallback.fromJson(json.fallbacks || []), + json.selectedAuth + ); + return obj; } + toJson() { - return { + const json = { clients: Inbound.VLESSSettings.toJsonArray(this.vlesses), - decryption: this.decryption, - fallbacks: Inbound.VLESSSettings.toJsonArray(this.fallbacks), }; + + if (this.decryption) { + json.decryption = this.decryption; + } + + if (this.encryption) { + json.encryption = this.encryption; + } + + if (this.fallbacks && this.fallbacks.length > 0) { + json.fallbacks = Inbound.VLESSSettings.toJsonArray(this.fallbacks); + } + if (this.selectedAuth) { + json.selectedAuth = this.selectedAuth; + } + + return json; } + + }; Inbound.VLESSSettings.VLESS = class extends XrayCommonClass { @@ -1926,7 +1930,9 @@ Inbound.VLESSSettings.VLESS = class extends XrayCommonClass { tgId = '', subId = RandomUtil.randomLowerAndNum(16), comment = '', - reset = 0 + reset = 0, + created_at = undefined, + updated_at = undefined ) { super(); this.id = id; @@ -1940,6 +1946,8 @@ Inbound.VLESSSettings.VLESS = class extends XrayCommonClass { this.subId = subId; this.comment = comment; this.reset = reset; + this.created_at = created_at; + this.updated_at = updated_at; } static fromJson(json = {}) { @@ -1955,6 +1963,8 @@ Inbound.VLESSSettings.VLESS = class extends XrayCommonClass { json.subId, json.comment, json.reset, + json.created_at, + json.updated_at, ); } @@ -2065,7 +2075,9 @@ Inbound.TrojanSettings.Trojan = class extends XrayCommonClass { tgId = '', subId = RandomUtil.randomLowerAndNum(16), comment = '', - reset = 0 + reset = 0, + created_at = undefined, + updated_at = undefined ) { super(); this.password = password; @@ -2078,6 +2090,8 @@ Inbound.TrojanSettings.Trojan = class extends XrayCommonClass { this.subId = subId; this.comment = comment; this.reset = reset; + this.created_at = created_at; + this.updated_at = updated_at; } toJson() { @@ -2092,6 +2106,8 @@ Inbound.TrojanSettings.Trojan = class extends XrayCommonClass { subId: this.subId, comment: this.comment, reset: this.reset, + created_at: this.created_at, + updated_at: this.updated_at, }; } @@ -2107,6 +2123,8 @@ Inbound.TrojanSettings.Trojan = class extends XrayCommonClass { json.subId, json.comment, json.reset, + json.created_at, + json.updated_at, ); } @@ -2226,7 +2244,9 @@ Inbound.ShadowsocksSettings.Shadowsocks = class extends XrayCommonClass { tgId = '', subId = RandomUtil.randomLowerAndNum(16), comment = '', - reset = 0 + reset = 0, + created_at = undefined, + updated_at = undefined ) { super(); this.method = method; @@ -2240,6 +2260,8 @@ Inbound.ShadowsocksSettings.Shadowsocks = class extends XrayCommonClass { this.subId = subId; this.comment = comment; this.reset = reset; + this.created_at = created_at; + this.updated_at = updated_at; } toJson() { @@ -2255,6 +2277,8 @@ Inbound.ShadowsocksSettings.Shadowsocks = class extends XrayCommonClass { subId: this.subId, comment: this.comment, reset: this.reset, + created_at: this.created_at, + updated_at: this.updated_at, }; } @@ -2271,6 +2295,8 @@ Inbound.ShadowsocksSettings.Shadowsocks = class extends XrayCommonClass { json.subId, json.comment, json.reset, + json.created_at, + json.updated_at, ); } diff --git a/web/assets/js/model/outbound.js b/web/assets/js/model/outbound.js index a42c400d..2d5660fb 100644 --- a/web/assets/js/model/outbound.js +++ b/web/assets/js/model/outbound.js @@ -813,7 +813,7 @@ class Outbound extends CommonClass { var settings; switch (protocol) { case Protocols.VLESS: - settings = new Outbound.VLESSSettings(address, port, userData, url.searchParams.get('flow') ?? ''); + settings = new Outbound.VLESSSettings(address, port, userData, url.searchParams.get('flow') ?? '', url.searchParams.get('encryption') ?? 'none'); break; case Protocols.Trojan: settings = new Outbound.TrojanSettings(address, port, userData); @@ -919,12 +919,14 @@ Outbound.FreedomSettings.Fragment = class extends CommonClass { constructor( packets = '1-3', length = '', - interval = '' + interval = '', + maxSplit = '' ) { super(); this.packets = packets; this.length = length; this.interval = interval; + this.maxSplit = maxSplit; } static fromJson(json = {}) { @@ -932,6 +934,7 @@ Outbound.FreedomSettings.Fragment = class extends CommonClass { json.packets, json.length, json.interval, + json.maxSplit ); } }; @@ -940,12 +943,14 @@ Outbound.FreedomSettings.Noise = class extends CommonClass { constructor( type = 'rand', packet = '10-20', - delay = '10-16' + delay = '10-16', + applyTo = 'ip' ) { super(); this.type = type; this.packet = packet; this.delay = delay; + this.applyTo = applyTo; } static fromJson(json = {}) { @@ -953,6 +958,7 @@ Outbound.FreedomSettings.Noise = class extends CommonClass { json.type, json.packet, json.delay, + json.applyTo ); } @@ -961,6 +967,7 @@ Outbound.FreedomSettings.Noise = class extends CommonClass { type: this.type, packet: this.packet, delay: this.delay, + applyTo: this.applyTo }; } }; @@ -988,7 +995,7 @@ Outbound.DNSSettings = class extends CommonClass { network = 'udp', address = '', port = 53, - nonIPQuery = 'drop', + nonIPQuery = 'reject', blockTypes = [] ) { super(); @@ -1039,13 +1046,13 @@ Outbound.VmessSettings = class extends CommonClass { } }; Outbound.VLESSSettings = class extends CommonClass { - constructor(address, port, id, flow, encryption = 'none') { + constructor(address, port, id, flow, encryption) { super(); this.address = address; this.port = port; this.id = id; this.flow = flow; - this.encryption = encryption + this.encryption = encryption; } static fromJson(json = {}) { @@ -1064,7 +1071,7 @@ Outbound.VLESSSettings = class extends CommonClass { vnext: [{ address: this.address, port: this.port, - users: [{ id: this.id, flow: this.flow, encryption: 'none', }], + users: [{ id: this.id, flow: this.flow, encryption: this.encryption }], }], }; } diff --git a/web/assets/js/util/date-util.js b/web/assets/js/util/date-util.js index 9b4b0f81..bbca1272 100644 --- a/web/assets/js/util/date-util.js +++ b/web/assets/js/util/date-util.js @@ -134,7 +134,7 @@ class DateUtil { } static formatMillis(millis) { - return moment(millis).format('YYYY-M-D H:m:s'); + return moment(millis).format('YYYY-M-D HH:mm:ss'); } static firstDayOfMonth() { diff --git a/web/controller/api.go b/web/controller/api.go index 636035ba..32af934e 100644 --- a/web/controller/api.go +++ b/web/controller/api.go @@ -47,6 +47,7 @@ func (a *APIController) initRouter(g *gin.RouterGroup) { {"POST", "/resetAllClientTraffics/:id", a.inboundController.resetAllClientTraffics}, {"POST", "/delDepletedClients/:id", a.inboundController.delDepletedClients}, {"POST", "/onlines", a.inboundController.onlines}, + {"POST", "/lastOnline", a.inboundController.lastOnline}, {"POST", "/updateClientTraffic/:email", a.inboundController.updateClientTraffic}, } diff --git a/web/controller/inbound.go b/web/controller/inbound.go index 2566edab..bcf4215b 100644 --- a/web/controller/inbound.go +++ b/web/controller/inbound.go @@ -352,6 +352,11 @@ func (a *InboundController) onlines(c *gin.Context) { jsonObj(c, a.inboundService.GetOnlineClients(), nil) } +func (a *InboundController) lastOnline(c *gin.Context) { + data, err := a.inboundService.GetClientsLastOnline() + jsonObj(c, data, err) +} + func (a *InboundController) updateClientTraffic(c *gin.Context) { email := c.Param("email") diff --git a/web/controller/server.go b/web/controller/server.go index 2d2f741e..b1174b8f 100644 --- a/web/controller/server.go +++ b/web/controller/server.go @@ -55,6 +55,7 @@ func (a *ServerController) initRouter(g *gin.RouterGroup) { g.POST("/getNewX25519Cert", a.getNewX25519Cert) g.POST("/getNewmldsa65", a.getNewmldsa65) g.POST("/getNewEchCert", a.getNewEchCert) + g.POST("/getNewVlessEnc", a.getNewVlessEnc) } func (a *ServerController) refreshStatus() { @@ -266,3 +267,12 @@ func (a *ServerController) getNewEchCert(c *gin.Context) { } jsonObj(c, cert, nil) } + +func (a *ServerController) getNewVlessEnc(c *gin.Context) { + out, err := a.serverService.GetNewVlessEnc() + if err != nil { + jsonMsg(c, I18nWeb(c, "pages.inbounds.toasts.getNewVlessEncError"), err) + return + } + jsonObj(c, out, nil) +} diff --git a/web/entity/entity.go b/web/entity/entity.go index 889c9024..844a7ce0 100644 --- a/web/entity/entity.go +++ b/web/entity/entity.go @@ -2,10 +2,10 @@ package entity import ( "crypto/tls" + "math" "net" "strings" "time" - "math" "x-ui/util/common" ) @@ -39,8 +39,8 @@ type AllSetting struct { TgCpu int `json:"tgCpu" form:"tgCpu"` TgLang string `json:"tgLang" form:"tgLang"` TimeLocation string `json:"timeLocation" form:"timeLocation"` - TwoFactorEnable bool `json:"twoFactorEnable" form:"twoFactorEnable"` - TwoFactorToken string `json:"twoFactorToken" form:"twoFactorToken"` + TwoFactorEnable bool `json:"twoFactorEnable" form:"twoFactorEnable"` + TwoFactorToken string `json:"twoFactorToken" form:"twoFactorToken"` SubEnable bool `json:"subEnable" form:"subEnable"` SubTitle string `json:"subTitle" form:"subTitle"` SubListen string `json:"subListen" form:"subListen"` diff --git a/web/html/component/aClientTable.html b/web/html/component/aClientTable.html index 96bd502f..a7279e50 100644 --- a/web/html/component/aClientTable.html +++ b/web/html/component/aClientTable.html @@ -33,12 +33,17 @@ + + @@ -75,6 +78,11 @@ + + + [[ s ]] + + @@ -97,7 +105,7 @@ - [[ s ]] + [[ s ]] @@ -218,6 +226,11 @@ +