diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 1f019498..b249622d 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -97,7 +97,7 @@ jobs: cd x-ui/bin # Download dependencies - Xray_URL="https://github.com/XTLS/Xray-core/releases/download/v25.5.16/" + Xray_URL="https://github.com/XTLS/Xray-core/releases/download/v25.6.8/" if [ "${{ matrix.platform }}" == "amd64" ]; then wget -q ${Xray_URL}Xray-linux-64.zip unzip Xray-linux-64.zip diff --git a/DockerInit.sh b/DockerInit.sh index b22c6059..ca1b4b3f 100755 --- a/DockerInit.sh +++ b/DockerInit.sh @@ -1,12 +1,21 @@ #!/bin/sh # POSIX-compatible script to download Xray binary and GeoIP/GeoSite databases +<<<<<<< HEAD set -eu XRAY_VERSION="v25.6.8" BASE_URL="https://github.com/XTLS/Xray-core/releases/download/${XRAY_VERSION}" DAT_DIR="build/bin" ARCH="${1:-amd64}" # Default to amd64 if not provided +======= +# ------------------------------------------------------------------------------ +# DockerInit.sh � download and prepare Xray binaries and geolocation databases +# ------------------------------------------------------------------------------ + +# Xray version +readonly XRAY_VERSION="v25.6.8" +>>>>>>> f7a3ebf2f3c28d40c1ae126f73ac6a8c9e22c2c6 # Map architecture case "$ARCH" in @@ -51,5 +60,129 @@ download_variant() { download_variant "IR" "https://github.com/chocolate4u/Iran-v2ray-rules/releases/latest/download" download_variant "RU" "https://github.com/runetfreedom/russia-v2ray-rules-dat/releases/latest/download" +<<<<<<< HEAD echo "All files downloaded successfully." cd ../../ +======= +Supported architectures: + amd64 ? 64-bit x86 + i386 ? 32-bit x86 + armv8 ? ARM64-v8a (also accepts arm64, aarch64) + armv7 ? ARM32-v7a (also accepts arm, arm32) + armv6 ? ARM32-v6 + +If no argument is provided or the argument is not recognized, 'amd64' will be used by default. + +Example: + $0 armv7 +EOF + exit 1 +} + +# Determine ARCH and FNAME based on input argument +detect_arch() { + local input="$1" + + case "$input" in + amd64) + ARCH="64" + FNAME="amd64" + ;; + i386) + ARCH="32" + FNAME="i386" + ;; + armv8 | arm64 | aarch64) + ARCH="arm64-v8a" + FNAME="arm64" + ;; + armv7 | arm | arm32) + ARCH="arm32-v7a" + FNAME="arm32" + ;; + armv6) + ARCH="arm32-v6" + FNAME="armv6" + ;; + "") + # If argument is empty, default to amd64 + ARCH="64" + FNAME="amd64" + ;; + *) + echo "Warning: Architecture '$input' not recognized. Defaulting to 'amd64'." >&2 + ARCH="64" + FNAME="amd64" + ;; + esac +} + +# Generic function to download a file by URL (with error handling) +download_file() { + local url="$1" + local output="$2" + + echo "Downloading: $url" + if ! wget -q -O "$output" "$url"; then + echo "Error: Failed to download '$url'" >&2 + exit 1 + fi +} + +# Main function: create directory, download and unpack Xray, then geolocation databases +main() { + # Check dependencies + check_dependencies + + # Get architecture from argument + local ARCH_ARG="${1-}" + detect_arch "$ARCH_ARG" + + # Construct URL for Xray download + local xray_url + printf -v xray_url "$XRAY_URL_TEMPLATE" "$ARCH" + + # Create build directory + echo "Creating directory: $BUILD_DIR" + mkdir -p "$BUILD_DIR" + cd "$BUILD_DIR" || exit 1 + + # Download and unpack Xray + local xray_zip="Xray-linux-${ARCH}.zip" + download_file "$xray_url" "$xray_zip" + echo "Unpacking $xray_zip" + unzip -q "$xray_zip" + rm -f "$xray_zip" geoip.dat geosite.dat + + # Rename binary according to target architecture + mv xray "xray-linux-${FNAME}" + chmod +x "xray-linux-${FNAME}" + + # Return to project root + cd "$ROOT_DIR" || exit 1 + + # Download standard GeoIP and GeoSite databases + echo "Downloading default GeoIP and GeoSite databases" + download_file "https://github.com/Loyalsoldier/v2ray-rules-dat/releases/latest/download/geoip.dat" "geoip.dat" + download_file "https://github.com/Loyalsoldier/v2ray-rules-dat/releases/latest/download/geosite.dat" "geosite.dat" + + # Download alternative GeoIP/GeoSite for Iran (IR) and Russia (RU) + echo "Downloading alternative GeoIP/GeoSite for Iran" + download_file "https://github.com/chocolate4u/Iran-v2ray-rules/releases/latest/download/geoip.dat" "geoip_IR.dat" + download_file "https://github.com/chocolate4u/Iran-v2ray-rules/releases/latest/download/geosite.dat" "geosite_IR.dat" + + echo "Downloading alternative GeoIP/GeoSite for Russia" + download_file "https://github.com/runetfreedom/russia-v2ray-rules-dat/releases/latest/download/geoip.dat" "geoip_RU.dat" + download_file "https://github.com/runetfreedom/russia-v2ray-rules-dat/releases/latest/download/geosite.dat" "geosite_RU.dat" + + echo "Done." +} + +# If -h or --help is passed, show usage +if [[ "${1-}" == "-h" || "${1-}" == "--help" ]]; then + usage +fi + +# Run main with the provided argument (if any) +main "${1-}" +>>>>>>> f7a3ebf2f3c28d40c1ae126f73ac6a8c9e22c2c6 diff --git a/README.ar_EG.md b/README.ar_EG.md index 99354e55..d2f6dcc3 100644 --- a/README.ar_EG.md +++ b/README.ar_EG.md @@ -23,7 +23,7 @@ ## البدء السريع ``` -$ bash <(curl -Ls https://raw.githubusercontent.com/mhsanaei/3x-ui/master/install.sh) +bash <(curl -Ls https://raw.githubusercontent.com/mhsanaei/3x-ui/master/install.sh) ``` للحصول على الوثائق الكاملة، يرجى زيارة [ويكي المشروع](https://github.com/MHSanaei/3x-ui/wiki). @@ -53,4 +53,4 @@ $ bash <(curl -Ls https://raw.githubusercontent.com/mhsanaei/3x-ui/master/instal ## النجوم عبر الزمن -[![Stargazers over time](https://starchart.cc/MHSanaei/3x-ui.svg?variant=adaptive)](https://starchart.cc/MHSanaei/3x-ui) \ No newline at end of file +[![Stargazers over time](https://starchart.cc/MHSanaei/3x-ui.svg?variant=adaptive)](https://starchart.cc/MHSanaei/3x-ui) diff --git a/README.es_ES.md b/README.es_ES.md index 915cc4c4..52625664 100644 --- a/README.es_ES.md +++ b/README.es_ES.md @@ -23,7 +23,7 @@ Como una versión mejorada del proyecto X-UI original, 3X-UI proporciona mayor e ## Inicio Rápido ``` -$ bash <(curl -Ls https://raw.githubusercontent.com/mhsanaei/3x-ui/master/install.sh) +bash <(curl -Ls https://raw.githubusercontent.com/mhsanaei/3x-ui/master/install.sh) ``` Para documentación completa, visita la [Wiki del proyecto](https://github.com/MHSanaei/3x-ui/wiki). @@ -53,4 +53,4 @@ Para documentación completa, visita la [Wiki del proyecto](https://github.com/M ## Estrellas a lo Largo del Tiempo -[![Stargazers over time](https://starchart.cc/MHSanaei/3x-ui.svg?variant=adaptive)](https://starchart.cc/MHSanaei/3x-ui) \ No newline at end of file +[![Stargazers over time](https://starchart.cc/MHSanaei/3x-ui.svg?variant=adaptive)](https://starchart.cc/MHSanaei/3x-ui) diff --git a/README.fa_IR.md b/README.fa_IR.md index e194b663..2b2dc5ec 100644 --- a/README.fa_IR.md +++ b/README.fa_IR.md @@ -23,7 +23,7 @@ ## شروع سریع ``` -$ bash <(curl -Ls https://raw.githubusercontent.com/mhsanaei/3x-ui/master/install.sh) +bash <(curl -Ls https://raw.githubusercontent.com/mhsanaei/3x-ui/master/install.sh) ``` برای مستندات کامل، لطفاً به [ویکی پروژه](https://github.com/MHSanaei/3x-ui/wiki) مراجعه کنید. @@ -53,4 +53,4 @@ $ bash <(curl -Ls https://raw.githubusercontent.com/mhsanaei/3x-ui/master/instal ## ستاره‌ها در طول زمان -[![Stargazers over time](https://starchart.cc/MHSanaei/3x-ui.svg?variant=adaptive)](https://starchart.cc/MHSanaei/3x-ui) \ No newline at end of file +[![Stargazers over time](https://starchart.cc/MHSanaei/3x-ui.svg?variant=adaptive)](https://starchart.cc/MHSanaei/3x-ui) diff --git a/README.md b/README.md index a63a0fb3..7cda8370 100644 --- a/README.md +++ b/README.md @@ -23,7 +23,7 @@ As an enhanced fork of the original X-UI project, 3X-UI provides improved stabil ## Quick Start ```bash -$ bash <(curl -Ls https://raw.githubusercontent.com/mhsanaei/3x-ui/master/install.sh) +bash <(curl -Ls https://raw.githubusercontent.com/mhsanaei/3x-ui/master/install.sh) ``` For full documentation, please visit the [project Wiki](https://github.com/MHSanaei/3x-ui/wiki). @@ -53,4 +53,4 @@ For full documentation, please visit the [project Wiki](https://github.com/MHSan ## Stargazers over Time -[![Stargazers over time](https://starchart.cc/MHSanaei/3x-ui.svg?variant=adaptive)](https://starchart.cc/MHSanaei/3x-ui) \ No newline at end of file +[![Stargazers over time](https://starchart.cc/MHSanaei/3x-ui.svg?variant=adaptive)](https://starchart.cc/MHSanaei/3x-ui) diff --git a/README.ru_RU.md b/README.ru_RU.md index 1bb8d611..d971f403 100644 --- a/README.ru_RU.md +++ b/README.ru_RU.md @@ -23,7 +23,7 @@ ## Быстрый старт ``` -$ bash <(curl -Ls https://raw.githubusercontent.com/mhsanaei/3x-ui/master/install.sh) +bash <(curl -Ls https://raw.githubusercontent.com/mhsanaei/3x-ui/master/install.sh) ``` Полную документацию смотрите в [вики проекта](https://github.com/MHSanaei/3x-ui/wiki). @@ -53,4 +53,4 @@ $ bash <(curl -Ls https://raw.githubusercontent.com/mhsanaei/3x-ui/master/instal ## Звезды с течением времени -[![Stargazers over time](https://starchart.cc/MHSanaei/3x-ui.svg?variant=adaptive)](https://starchart.cc/MHSanaei/3x-ui) \ No newline at end of file +[![Stargazers over time](https://starchart.cc/MHSanaei/3x-ui.svg?variant=adaptive)](https://starchart.cc/MHSanaei/3x-ui) diff --git a/README.zh_CN.md b/README.zh_CN.md index 133ffe0c..75e75603 100644 --- a/README.zh_CN.md +++ b/README.zh_CN.md @@ -23,7 +23,7 @@ ## 快速开始 ``` -$ bash <(curl -Ls https://raw.githubusercontent.com/mhsanaei/3x-ui/master/install.sh) +bash <(curl -Ls https://raw.githubusercontent.com/mhsanaei/3x-ui/master/install.sh) ``` 完整文档请参阅 [项目Wiki](https://github.com/MHSanaei/3x-ui/wiki)。 @@ -53,4 +53,4 @@ $ bash <(curl -Ls https://raw.githubusercontent.com/mhsanaei/3x-ui/master/instal ## 随时间变化的星标数 -[![Stargazers over time](https://starchart.cc/MHSanaei/3x-ui.svg?variant=adaptive)](https://starchart.cc/MHSanaei/3x-ui) \ No newline at end of file +[![Stargazers over time](https://starchart.cc/MHSanaei/3x-ui.svg?variant=adaptive)](https://starchart.cc/MHSanaei/3x-ui) diff --git a/docker-compose.yml b/docker-compose.yml index e27a735e..198df198 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,8 +1,10 @@ services: - 3x-ui: - image: ghcr.io/mhsanaei/3x-ui:latest - container_name: 3x-ui - hostname: yourhostname + 3xui: + build: + context: . + dockerfile: ./Dockerfile + container_name: 3xui_app + # hostname: yourhostname <- optional volumes: - $PWD/db/:/etc/x-ui/ - $PWD/cert/:/root/cert/ diff --git a/install.sh b/install.sh index 0398285d..8fb23f3b 100644 --- a/install.sh +++ b/install.sh @@ -57,7 +57,7 @@ install_base() { ubuntu | debian | armbian) apt-get update && apt-get install -y -q wget curl tar tzdata ;; - centos | almalinux | rocky | ol) + centos | rhel | almalinux | rocky | ol) yum -y update && yum install -y -q wget curl tar tzdata ;; fedora | amzn | virtuozzo) diff --git a/web/assets/js/model/inbound.js b/web/assets/js/model/inbound.js index 2a5fb6d6..5228001c 100644 --- a/web/assets/js/model/inbound.js +++ b/web/assets/js/model/inbound.js @@ -2150,7 +2150,7 @@ Inbound.TrojanSettings.Fallback = class extends XrayCommonClass { Inbound.ShadowsocksSettings = class extends Inbound.Settings { constructor(protocol, method = SSMethods.BLAKE3_AES_256_GCM, - password = RandomUtil.randomShadowsocksPassword(), + password = '', network = 'tcp,udp', shadowsockses = [new Inbound.ShadowsocksSettings.Shadowsocks()], ivCheck = false, @@ -2188,7 +2188,7 @@ Inbound.ShadowsocksSettings = class extends Inbound.Settings { Inbound.ShadowsocksSettings.Shadowsocks = class extends XrayCommonClass { constructor( method = '', - password = RandomUtil.randomShadowsocksPassword(), + password = '', email = RandomUtil.randomLowerAndNum(8), limitIp = 0, totalGB = 0, diff --git a/web/assets/js/util/index.js b/web/assets/js/util/index.js index 0d869af6..4bf760d7 100644 --- a/web/assets/js/util/index.js +++ b/web/assets/js/util/index.js @@ -138,8 +138,14 @@ class RandomUtil { } } - static randomShadowsocksPassword() { - const array = new Uint8Array(32); + static randomShadowsocksPassword(method = SSMethods.BLAKE3_AES_256_GCM) { + let length = 32; + + if ([SSMethods.BLAKE3_AES_128_GCM].includes(method)) { + length = 16; + } + + const array = new Uint8Array(length); window.crypto.getRandomValues(array); @@ -789,6 +795,25 @@ class LanguageManager { if (window.navigator) { lang = window.navigator.language || window.navigator.userLanguage; + const simularLangs = [ + ["ar", this.supportedLanguages[0].value], + ["fa", this.supportedLanguages[2].value], + ["ja", this.supportedLanguages[5].value], + ["ru", this.supportedLanguages[6].value], + ["vi", this.supportedLanguages[7].value], + ["es", this.supportedLanguages[8].value], + ["id", this.supportedLanguages[9].value], + ["uk", this.supportedLanguages[10].value], + ["tr", this.supportedLanguages[11].value], + ["pt", this.supportedLanguages[12].value], + ] + + simularLangs.forEach((pair) => { + if (lang === pair[0]) { + lang = pair[1]; + } + }); + if (LanguageManager.isSupportLanguage(lang)) { CookieManager.setCookie("lang", lang, 150); } else { diff --git a/web/entity/entity.go b/web/entity/entity.go index 543b80e0..889c9024 100644 --- a/web/entity/entity.go +++ b/web/entity/entity.go @@ -5,6 +5,7 @@ import ( "net" "strings" "time" + "math" "x-ui/util/common" ) @@ -78,11 +79,11 @@ func (s *AllSetting) CheckValid() error { } } - if s.WebPort <= 0 || s.WebPort > 65535 { + if s.WebPort <= 0 || s.WebPort > math.MaxUint16 { return common.NewError("web port is not a valid port:", s.WebPort) } - if s.SubPort <= 0 || s.SubPort > 65535 { + if s.SubPort <= 0 || s.SubPort > math.MaxUint16 { return common.NewError("Sub port is not a valid port:", s.SubPort) } diff --git a/web/html/common/head.html b/web/html/common/head.html deleted file mode 100644 index 35901769..00000000 --- a/web/html/common/head.html +++ /dev/null @@ -1,31 +0,0 @@ -{{define "head"}} - - - - - - - - - {{ .host }} – {{ i18n .title}} - -
-{{end}} \ No newline at end of file diff --git a/web/html/common/js.html b/web/html/common/js.html deleted file mode 100644 index 1c2d64b3..00000000 --- a/web/html/common/js.html +++ /dev/null @@ -1,14 +0,0 @@ -{{define "js"}} - - - - - - - - - -{{end}} \ No newline at end of file diff --git a/web/html/common/page.html b/web/html/common/page.html new file mode 100644 index 00000000..f1c58fe1 --- /dev/null +++ b/web/html/common/page.html @@ -0,0 +1,58 @@ +{{ define "page/head_start" }} + + + + + + + + + + + {{ .host }} – {{ i18n .title}} +{{ end }} + +{{ define "page/head_end" }} + +{{ end }} + +{{ define "page/body_start" }} + +
+{{ end }} + +{{ define "page/body_scripts" }} + + + + + + + + + +{{ end }} + +{{ define "page/body_end" }} + + +{{ end }} \ No newline at end of file diff --git a/web/html/component/aClientTable.html b/web/html/component/aClientTable.html index 868112d9..96bd502f 100644 --- a/web/html/component/aClientTable.html +++ b/web/html/component/aClientTable.html @@ -41,14 +41,28 @@ {{ i18n "password" }} - + diff --git a/web/html/form/protocol/shadowsocks.html b/web/html/form/protocol/shadowsocks.html index b9813afb..06e12075 100644 --- a/web/html/form/protocol/shadowsocks.html +++ b/web/html/form/protocol/shadowsocks.html @@ -31,7 +31,7 @@ Password + Password diff --git a/web/html/inbounds.html b/web/html/inbounds.html index 29e6b00f..e1267190 100644 --- a/web/html/inbounds.html +++ b/web/html/inbounds.html @@ -1,6 +1,4 @@ - - -{{template "head" .}} +{{ template "page/head_start" .}} +{{ template "page/head_end" .}} - +{{ template "page/body_start" .}} - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - {{ i18n "none" }} - {{ i18n "disabled" }} - {{ i18n "depleted" }} - {{ i18n "depletingSoon" }} - {{ i18n "online" }} - -
- -