From 863a05041397f117f62a97efc15b690388803ee8 Mon Sep 17 00:00:00 2001 From: Joel Mattison Date: Thu, 25 Jun 2026 20:32:23 -0400 Subject: [PATCH] Run XUI installer non-interactively with auto-generated license MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit XUI 1.5.13 is the post-shutdown license-free build: the installer's isValidLicense() only checks len==16 + hex, and the license servers are offline. Auto-generate a 16-hex key (openssl rand -hex 8), inject it, and answer the sysctl prompt — fully unattended by default. Adds XUI_LICENSE, XUI_SYSCTL, XUI_INTERACTIVE env vars and surfaces the panel setup URL. Co-Authored-By: Claude Opus 4.8 (1M context) --- README.md | 33 +++++++++++++++----- install_xui.sh | 82 +++++++++++++++++++++++++++++++++++++++++++++----- 2 files changed, 100 insertions(+), 15 deletions(-) diff --git a/README.md b/README.md index a49958f..270c19b 100644 --- a/README.md +++ b/README.md @@ -15,13 +15,23 @@ fallback. 3. Downloads `XUI_1.5.13.zip` (~661 MB) from the Gitea mirror (falls back to GitHub) 4. Verifies the SHA-256 checksum (on by default) 5. Extracts `install`, `database.sql`, `xui.tar.gz` -6. Runs the bundled `./install`, which prompts for your **license key** and a - sysctl overwrite (answer **Y**) -7. Panel URL + MySQL credentials are written to `/root/credentials.txt` +6. Runs the bundled `./install` **non-interactively** — auto-generates a valid + license key and answers the sysctl prompt +7. Prints the panel **setup URL**; MySQL credentials are saved to + `/credentials.txt` -> The release is **pre-patched/pre-licensed**. You still enter a license key -> when the bundled `install` runs — that behavior comes from the XUI package -> itself, not this wrapper. +### About the "license" + +XUI.ONE 1.5.13 is the **post-shutdown, license-free build**. The developer +(GTAXUI) wound down the product and took the license servers offline, then +released a clean 1.5.13 with all license verification patched out (unlocked +extensions for PHP 7.2 / 7.4). It **never phones home**. + +The bundled installer still asks for a key, but it only checks the format — +`isValidLicense()` is literally `len == 16 and all hex`. So **any valid 16-char +hex string works** (e.g. `a9f3b7e2c6d8140f`). This wrapper auto-generates a +random one with `openssl rand -hex 8`, exactly like the community auto-installers. +Set `XUI_LICENSE` to pin a specific key. ## Usage @@ -69,7 +79,16 @@ curl -X PUT \ | `XUI_URL` | Gitea mirror URL (above) | Override the primary download source | | `XUI_FALLBACK_URL` | GitHub XUIPatch release | Override the fallback source | | `XUI_SHA256` | baked-in known-good hash | Override, or set to `""` to skip checksum verify | -| `XUI_WORKDIR` | `/opt/xui_install` | Where the package is downloaded/extracted | +| `XUI_WORKDIR` | `/opt/xui_install` | Where the package is downloaded/extracted/run | +| `XUI_LICENSE` | auto-generated 16-hex | Pin a specific 16-char hex license key | +| `XUI_SYSCTL` | `Y` | Answer to the installer's sysctl-overwrite prompt | +| `XUI_INTERACTIVE` | `0` | Set to `1` to answer the installer's prompts yourself| + +Example pinning a license and running fully unattended: + +```bash +XUI_LICENSE="a9f3b7e2c6d8140f" ./install_xui.sh +``` Example pointing at a different mirror: diff --git a/install_xui.sh b/install_xui.sh index ea1b915..aa1e487 100755 --- a/install_xui.sh +++ b/install_xui.sh @@ -33,6 +33,21 @@ EXPECTED_SHA256="${XUI_SHA256-a92e5f21a338c56190d7580f449492c970b5d4219474548ca5 WORKDIR="${XUI_WORKDIR:-/opt/xui_install}" +# License key. XUI 1.5.13 is the post-shutdown, license-free build: the patched +# extensions removed all license verification and the GTAXUI license servers are +# offline. The bundled installer only checks that the key is exactly 16 hex chars +# (isValidLicense: len==16 and all hex) — it never phones home. So any valid hex +# works; we auto-generate one unless XUI_LICENSE is provided. +XUI_LICENSE="${XUI_LICENSE:-}" + +# Answer to the installer's "Overwrite sysctl configuration?" prompt (Y/N). +# Y is recommended (sets XUI's TCP tuning + open-file limits). +XUI_SYSCTL="${XUI_SYSCTL:-Y}" + +# Set XUI_INTERACTIVE=1 to answer the installer's prompts yourself instead of +# letting this wrapper drive them non-interactively. +XUI_INTERACTIVE="${XUI_INTERACTIVE:-0}" + # --------------------------------------------------------------------------- # Helpers # --------------------------------------------------------------------------- @@ -44,6 +59,22 @@ ok() { printf '%s[+]%s %s\n' "$c_green" "$c_reset" "$*"; } warn() { printf '%s[!]%s %s\n' "$c_yellow" "$c_reset" "$*"; } die() { printf '%s[x]%s %s\n' "$c_red" "$c_reset" "$*" >&2; exit 1; } +# Return a valid 16-char hex license: use XUI_LICENSE if set (validated), else +# generate a random one. +resolve_license() { + if [ -n "$XUI_LICENSE" ]; then + if printf '%s' "$XUI_LICENSE" | grep -Eq '^[0-9a-fA-F]{16}$'; then + printf '%s' "$XUI_LICENSE"; return 0 + fi + die "XUI_LICENSE must be exactly 16 hex chars (got: '$XUI_LICENSE')." + fi + if command -v openssl >/dev/null 2>&1; then + openssl rand -hex 8 + else + head -c 8 /dev/urandom | od -An -tx1 | tr -d ' \n' + fi +} + banner() { cat <<'EOF' @@ -160,20 +191,42 @@ extract_and_run() { info "Setting permissions..." chmod +x install - cat <<'EOF' + if [ "$XUI_INTERACTIVE" = "1" ]; then + cat <<'EOF' ----------------------------------------------- - Handing over to the XUI installer. + Handing over to the XUI installer (interactive). You will be prompted for: - - your license key + - your license key (any 16-char hex works) - sysctl overwrite (answer Y — recommended) - After it finishes, MySQL credentials are saved - to /root/credentials.txt ----------------------------------------------- EOF - info "Starting XUI install..." - ./install + info "Starting XUI install..." + ./install + return + fi + + LICENSE="$(resolve_license)" + local log="$WORKDIR/install.log" + cat <&1 | tee "$log" + + # Surface the panel setup URL the installer prints at the end. + SETUP_URL="$(grep -aoE 'http://[0-9.]+/[A-Za-z0-9]+' "$log" | tail -1 || true)" } # --------------------------------------------------------------------------- @@ -185,7 +238,20 @@ main() { ensure_deps fetch extract_and_run - ok "Installer finished. Check /root/credentials.txt for your panel details." + + echo + ok "XUI installation finished." + if [ "$XUI_INTERACTIVE" != "1" ]; then + printf '%s\n' "-----------------------------------------------" + [ -n "${SETUP_URL:-}" ] && printf ' Panel setup URL : %s\n' "$SETUP_URL" + printf ' License key : %s\n' "${LICENSE:-}" + printf ' MySQL creds : %s/credentials.txt\n' "$WORKDIR" + printf ' Full log : %s/install.log\n' "$WORKDIR" + printf '%s\n' "-----------------------------------------------" + warn "Save credentials.txt somewhere safe, then open the setup URL to finish." + else + info "Check ${WORKDIR}/credentials.txt and the 'Continue Setup' URL above." + fi } main "$@"