Compare commits
204
Commits
static-v3.7.0
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f51e70cb17 | ||
|
|
419999dbf6 | ||
|
|
e8e154773f | ||
|
|
eea1e17c35 | ||
|
|
fbb296ca3d | ||
|
|
9253c0016d | ||
|
|
c29206aba2 | ||
|
|
09855c7b23 | ||
|
|
9e0926be96 | ||
|
|
0d0a4b32ae | ||
|
|
c662fdc8b9 | ||
|
|
84b91c4349 | ||
|
|
9c6b594328 | ||
|
|
4000be75e0 | ||
|
|
ad3e70d59b | ||
|
|
f45a6f626f | ||
|
|
d65f86ae8e | ||
|
|
9cb985640a | ||
|
|
2ae3f7aa15 | ||
|
|
5f76f9b58e | ||
|
|
51bb2a7e5b | ||
|
|
1dc1924664 | ||
|
|
908eda5844 | ||
|
|
abc232ae11 | ||
|
|
19755418cf | ||
|
|
607c37044e | ||
|
|
4606708a56 | ||
|
|
d8227ca06f | ||
|
|
72bdce8743 | ||
|
|
a27e98ed24 | ||
|
|
346001567c | ||
|
|
cf2e543eb6 | ||
|
|
739f35f804 | ||
|
|
d19d7f39f3 | ||
|
|
f6f93cf973 | ||
|
|
1d340b5abd | ||
|
|
495115f869 | ||
|
|
2212604636 | ||
|
|
71e9ee1767 | ||
|
|
20db43210e | ||
|
|
1acf4643b6 | ||
|
|
54dc346697 | ||
|
|
5a9c9837e1 | ||
|
|
739c18ce48 | ||
|
|
f2695ddb22 | ||
|
|
e0ed2b0352 | ||
|
|
2b914d374f | ||
|
|
269c37653c | ||
|
|
6a5ee8f77b | ||
|
|
8158cedfc1 | ||
|
|
1b255eb414 | ||
|
|
f1132461db | ||
|
|
9ceca7d58f | ||
|
|
e7676f8635 | ||
|
|
b6e8fc558d | ||
|
|
460b02cec6 | ||
|
|
9681dc6f4a | ||
|
|
12aff835ed | ||
|
|
66bf6a88eb | ||
|
|
6842da3c7e | ||
|
|
6f4a4379d9 | ||
|
|
11afed3bac | ||
|
|
1ee07ba73d | ||
|
|
d70fd38978 | ||
|
|
5a7f89ee21 | ||
|
|
6dd31b3619 | ||
|
|
c59882b846 | ||
|
|
e5d42224aa | ||
|
|
7244f3c9da | ||
|
|
f9183e9dbb | ||
|
|
f99c43dd2a | ||
|
|
ef89259a49 | ||
|
|
4c04cdb1bc | ||
|
|
bdfcce0e11 | ||
|
|
7ba1841df2 | ||
|
|
3a3c7c0dc9 | ||
|
|
388e26c292 | ||
|
|
1d1258a10d | ||
|
|
81299db6ff | ||
|
|
89b65f1606 | ||
|
|
d16b888146 | ||
|
|
c94136c8a1 | ||
|
|
e7f4bfed24 | ||
|
|
6b9832cdcc | ||
|
|
e78cb8ccc5 | ||
|
|
ef662c9fdb | ||
|
|
a81eff8c0d | ||
|
|
1d7eb16784 | ||
|
|
a13179ed9b | ||
|
|
93c1620c15 | ||
|
|
ba57fb3c00 | ||
|
|
151b07b73f | ||
|
|
cec5905483 | ||
|
|
1df78dd874 | ||
|
|
92dfdc542c | ||
|
|
a25c51003e | ||
|
|
b27bcfcb5b | ||
|
|
75f10b27fa | ||
|
|
7df3a338ef | ||
|
|
5ca22ec340 | ||
|
|
2d37a6de18 | ||
|
|
db6f666ff7 | ||
|
|
d4d259fa58 | ||
|
|
9caa4e0cf9 | ||
|
|
29de9761c8 | ||
|
|
c2f1840535 | ||
|
|
06de0e8384 | ||
|
|
0a6e9b7a7d | ||
|
|
7e15bfbf8e | ||
|
|
6de22ae2e3 | ||
|
|
05c164dc8f | ||
|
|
c610ab88ea | ||
|
|
4a532e8c5a | ||
|
|
3e2829e49d | ||
|
|
19bf6fbc22 | ||
|
|
460b314786 | ||
|
|
3a02211555 | ||
|
|
268e6596bc | ||
|
|
7df7b530d3 | ||
|
|
9e2807d3ec | ||
|
|
e43bd68986 | ||
|
|
b889526b0d | ||
|
|
031b422365 | ||
|
|
277838d7ca | ||
|
|
f646212df2 | ||
|
|
2ee20b9691 | ||
|
|
000731c4e0 | ||
|
|
2558efd9fb | ||
|
|
7ad65652ec | ||
|
|
1762e54d5f | ||
|
|
1763f94a5f | ||
|
|
0d1607c358 | ||
|
|
e03ceaa41f | ||
|
|
741cd905ff | ||
|
|
540c05b0a5 | ||
|
|
d5dab0229c | ||
|
|
0e9c2031fb | ||
|
|
3e052c42b8 | ||
|
|
39ad8b8a2e | ||
|
|
1bd63e6625 | ||
|
|
a47e64f70a | ||
|
|
0a973bc95c | ||
|
|
9843a7ce4e | ||
|
|
750a270955 | ||
|
|
3413ccca9f | ||
|
|
8e89960474 | ||
|
|
afb5456b8f | ||
|
|
36acc4c2b1 | ||
|
|
7f098c6c4e | ||
|
|
942b220f80 | ||
|
|
7d9a38490d | ||
|
|
3df652a67d | ||
|
|
c91fb454a8 | ||
|
|
c490bdcd76 | ||
|
|
5c432205ad | ||
|
|
8901267867 | ||
|
|
e310abcba0 | ||
|
|
ced5e69de0 | ||
|
|
a82d1e56fa | ||
|
|
7e7ab2ecbd | ||
|
|
d46035708e | ||
|
|
2596880327 | ||
|
|
2365eb138b | ||
|
|
27a5097756 | ||
|
|
f18aca9410 | ||
|
|
29b724dae1 | ||
|
|
1edb8f71da | ||
|
|
8900ef68fc | ||
|
|
e5f39ed20b | ||
|
|
487b074801 | ||
|
|
3536d4174e | ||
|
|
84d7b85be7 | ||
|
|
81d89840e4 | ||
|
|
ff1204ce2d | ||
|
|
58cdfe73b0 | ||
|
|
ac39370879 | ||
|
|
f569680182 | ||
|
|
9adffd049c | ||
|
|
8ca1a4647a | ||
|
|
0ed6d8a1cf | ||
|
|
dcfaf6ace6 | ||
|
|
7d03749246 | ||
|
|
5efaaef2c2 | ||
|
|
bea7f4b2b6 | ||
|
|
051a74be80 | ||
|
|
d867b15f4a | ||
|
|
4da8d58307 | ||
|
|
6a880aed09 | ||
|
|
1035d00fe4 | ||
|
|
f6d652019d | ||
|
|
ceca96571d | ||
|
|
5031a70ccb | ||
|
|
6772c97f8e | ||
|
|
7284fa6cf0 | ||
|
|
261a1f6787 | ||
|
|
60ce5eab98 | ||
|
|
f887f47bb9 | ||
|
|
2c85f85549 | ||
|
|
0f0335e943 | ||
|
|
4828f946b1 | ||
|
|
945b3a56a2 | ||
|
|
b8e132fc0b | ||
|
|
c67f0cb0cf | ||
|
|
8da3cde494 |
+1
-1
@@ -5,6 +5,6 @@ build
|
|||||||
db
|
db
|
||||||
cert
|
cert
|
||||||
pgdata
|
pgdata
|
||||||
x-ui/
|
l-ui/
|
||||||
*.db
|
*.db
|
||||||
*.dump
|
*.dump
|
||||||
|
|||||||
+46
-46
@@ -2,25 +2,25 @@
|
|||||||
# 1. Developer Bootstrap: The active (uncommented) variables directly below
|
# 1. Developer Bootstrap: The active (uncommented) variables directly below
|
||||||
# configure a safe, unprivileged local environment for 'go run .'.
|
# configure a safe, unprivileged local environment for 'go run .'.
|
||||||
# This allows 'cp .env.example .env' to work out-of-the-box without root.
|
# This allows 'cp .env.example .env' to work out-of-the-box without root.
|
||||||
# 2. Production Reference: All available XUI_* configuration options are
|
# 2. Production Reference: All available LUI_* configuration options are
|
||||||
# documented and commented out in the reference section further below.
|
# documented and commented out in the reference section further below.
|
||||||
#
|
#
|
||||||
# 3x-ui reads its runtime configuration from XUI_* environment variables.
|
# L-UI reads its runtime configuration from LUI_* environment variables.
|
||||||
# On a script install, the installer writes them to the service environment file
|
# On a script install, the installer writes them to the service environment file
|
||||||
# (/etc/default/x-ui, /etc/conf.d/x-ui, or /etc/sysconfig/x-ui depending on the distro).
|
# (/etc/default/l-ui, /etc/conf.d/l-ui, or /etc/sysconfig/l-ui depending on the distro).
|
||||||
# For Docker, you set them in docker-compose.yml or via 'docker run -e'.
|
# For Docker, you set them in docker-compose.yml or via 'docker run -e'.
|
||||||
#
|
#
|
||||||
# Defaults are sensible — set only what you need to change, then restart:
|
# Defaults are sensible — set only what you need to change, then restart:
|
||||||
# systemctl restart x-ui
|
# systemctl restart l-ui
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
# LOCAL DEVELOPMENT OVERRIDES (ACTIVE BY DEFAULT)
|
# LOCAL DEVELOPMENT OVERRIDES (ACTIVE BY DEFAULT)
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
XUI_DEBUG=true
|
LUI_DEBUG=true
|
||||||
XUI_DB_FOLDER=x-ui
|
LUI_DB_FOLDER=l-ui
|
||||||
XUI_LOG_FOLDER=x-ui
|
LUI_LOG_FOLDER=l-ui
|
||||||
XUI_BIN_FOLDER=x-ui
|
LUI_BIN_FOLDER=l-ui
|
||||||
XUI_INIT_WEB_BASE_PATH=/
|
LUI_INIT_WEB_BASE_PATH=/
|
||||||
|
|
||||||
# ==============================================================================
|
# ==============================================================================
|
||||||
# REFERENCE CONFIGURATION (ALL OPTIONS)
|
# REFERENCE CONFIGURATION (ALL OPTIONS)
|
||||||
@@ -31,21 +31,21 @@ XUI_INIT_WEB_BASE_PATH=/
|
|||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
# Backend database type: sqlite, or postgres (also accepts postgresql / pg)
|
# Backend database type: sqlite, or postgres (also accepts postgresql / pg)
|
||||||
# Default: sqlite
|
# Default: sqlite
|
||||||
#XUI_DB_TYPE=sqlite
|
#LUI_DB_TYPE=sqlite
|
||||||
|
|
||||||
# Folder for the SQLite database file (x-ui.db)
|
# Folder for the SQLite database file (l-ui.db)
|
||||||
# Default: /etc/x-ui (Overridden to 'x-ui' in the development block above)
|
# Default: /etc/l-ui (Overridden to 'l-ui' in the development block above)
|
||||||
#XUI_DB_FOLDER=/etc/x-ui
|
#LUI_DB_FOLDER=/etc/l-ui
|
||||||
|
|
||||||
# PostgreSQL connection string (used when XUI_DB_TYPE=postgres)
|
# PostgreSQL connection string (used when LUI_DB_TYPE=postgres)
|
||||||
# Example: postgres://user:password@localhost:5432/dbname?sslmode=disable
|
# Example: postgres://user:password@localhost:5432/dbname?sslmode=disable
|
||||||
#XUI_DB_DSN=
|
#LUI_DB_DSN=
|
||||||
|
|
||||||
# Max open connections in the PostgreSQL pool
|
# Max open connections in the PostgreSQL pool
|
||||||
#XUI_DB_MAX_OPEN_CONNS=
|
#LUI_DB_MAX_OPEN_CONNS=
|
||||||
|
|
||||||
# Max idle connections in the PostgreSQL pool
|
# Max idle connections in the PostgreSQL pool
|
||||||
#XUI_DB_MAX_IDLE_CONNS=
|
#LUI_DB_MAX_IDLE_CONNS=
|
||||||
|
|
||||||
# PostgreSQL Docker Container Settings
|
# PostgreSQL Docker Container Settings
|
||||||
# Default credentials used if you are running PostgreSQL via docker-compose
|
# Default credentials used if you are running PostgreSQL via docker-compose
|
||||||
@@ -58,19 +58,19 @@ XUI_INIT_WEB_BASE_PATH=/
|
|||||||
# Panel
|
# Panel
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
# Override the panel port (1–65535). Takes precedence over the stored setting.
|
# Override the panel port (1–65535). Takes precedence over the stored setting.
|
||||||
#XUI_PORT=
|
#LUI_PORT=
|
||||||
|
|
||||||
# Initial web base path on FIRST launch (e.g., /panel)
|
# Initial web base path on FIRST launch (e.g., /panel)
|
||||||
# Default: /
|
# Default: /
|
||||||
#XUI_INIT_WEB_BASE_PATH=/
|
#LUI_INIT_WEB_BASE_PATH=/
|
||||||
|
|
||||||
# Enable Fail2ban-based IP-limit enforcement
|
# Enable Fail2ban-based IP-limit enforcement
|
||||||
# Default: true
|
# Default: true
|
||||||
#XUI_ENABLE_FAIL2BAN=true
|
#LUI_ENABLE_FAIL2BAN=true
|
||||||
|
|
||||||
# Skip the HSTS header — set true when TLS is terminated by a reverse proxy
|
# Skip the HSTS header — set true when TLS is terminated by a reverse proxy
|
||||||
# Default: false
|
# Default: false
|
||||||
#XUI_SKIP_HSTS=false
|
#LUI_SKIP_HSTS=false
|
||||||
|
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
@@ -78,26 +78,26 @@ XUI_INIT_WEB_BASE_PATH=/
|
|||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
# Logging level: debug, info, notice, warning, or error
|
# Logging level: debug, info, notice, warning, or error
|
||||||
# Default: info
|
# Default: info
|
||||||
#XUI_LOG_LEVEL=info
|
#LUI_LOG_LEVEL=info
|
||||||
|
|
||||||
# Debug mode. Forces log level to debug, enables Gin debug mode,
|
# Debug mode. Forces log level to debug, enables Gin debug mode,
|
||||||
# and ensures frontend assets are served directly from disk (see CLAUDE.md).
|
# and ensures frontend assets are served directly from disk (see CLAUDE.md).
|
||||||
# Default: false (Overridden to 'true' in the development block at the top)
|
# Default: false (Overridden to 'true' in the development block at the top)
|
||||||
#XUI_DEBUG=false
|
#LUI_DEBUG=false
|
||||||
|
|
||||||
# Log output directory
|
# Log output directory
|
||||||
# Default: /var/log/x-ui (Overridden to 'x-ui' in the development block above)
|
# Default: /var/log/l-ui (Overridden to 'l-ui' in the development block above)
|
||||||
#XUI_LOG_FOLDER=/var/log/x-ui
|
#LUI_LOG_FOLDER=/var/log/l-ui
|
||||||
|
|
||||||
# Folder for the Xray-core binary and geosite/geoip files
|
# Folder for the Xray-core binary and geosite/geoip files
|
||||||
# Default: bin (Overridden to 'x-ui' in the development block above)
|
# Default: bin (Overridden to 'l-ui' in the development block above)
|
||||||
#XUI_BIN_FOLDER=bin
|
#LUI_BIN_FOLDER=bin
|
||||||
|
|
||||||
# Legacy Path Settings
|
# Legacy Path Settings
|
||||||
# Main installation folder (Default: /usr/local/x-ui for Linux, /app for Docker)
|
# Main installation folder (Default: /usr/local/l-ui for Linux, /app for Docker)
|
||||||
#XUI_MAIN_FOLDER=/usr/local/x-ui
|
#LUI_MAIN_FOLDER=/usr/local/l-ui
|
||||||
# Path to the systemd service file (Default: /etc/systemd/system)
|
# Path to the systemd service file (Default: /etc/systemd/system)
|
||||||
#XUI_SERVICE=/etc/systemd/system
|
#LUI_SERVICE=/etc/systemd/system
|
||||||
|
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
@@ -105,27 +105,27 @@ XUI_INIT_WEB_BASE_PATH=/
|
|||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
# Go GC target percentage; lower = less RAM, slightly more CPU.
|
# Go GC target percentage; lower = less RAM, slightly more CPU.
|
||||||
# Default: 75
|
# Default: 75
|
||||||
#XUI_GOGC=
|
#LUI_GOGC=
|
||||||
|
|
||||||
# Minutes between FreeOSMemory calls; 0 disables.
|
# Minutes between FreeOSMemory calls; 0 disables.
|
||||||
# Default: 10
|
# Default: 10
|
||||||
#XUI_MEMORY_RELEASE_INTERVAL=
|
#LUI_MEMORY_RELEASE_INTERVAL=
|
||||||
|
|
||||||
# Go soft memory limit in MiB
|
# Go soft memory limit in MiB
|
||||||
#XUI_MEMORY_LIMIT=
|
#LUI_MEMORY_LIMIT=
|
||||||
|
|
||||||
# Go-syntax soft limit (e.g., 400MiB); takes precedence over XUI_MEMORY_LIMIT
|
# Go-syntax soft limit (e.g., 400MiB); takes precedence over LUI_MEMORY_LIMIT
|
||||||
#GOMEMLIMIT=
|
#GOMEMLIMIT=
|
||||||
|
|
||||||
# Expose pprof profiling on 127.0.0.1:6060
|
# Expose pprof profiling on 127.0.0.1:6060
|
||||||
# Default: false
|
# Default: false
|
||||||
#XUI_PPROF=false
|
#LUI_PPROF=false
|
||||||
|
|
||||||
# Automatically set to 'true' inside the official Docker image.
|
# Automatically set to 'true' inside the official Docker image.
|
||||||
# Consumed by internal scripts (x-ui.sh) to detect the environment.
|
# Consumed by internal scripts (l-ui.sh) to detect the environment.
|
||||||
# There is normally no need to set or toggle this variable manually.
|
# There is normally no need to set or toggle this variable manually.
|
||||||
# Default: false (automatically 'true' in Docker environments)
|
# Default: false (automatically 'true' in Docker environments)
|
||||||
#XUI_IN_DOCKER=false
|
#LUI_IN_DOCKER=false
|
||||||
|
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
@@ -142,36 +142,36 @@ XUI_INIT_WEB_BASE_PATH=/
|
|||||||
# Optional watchdog: probes a URL (optionally through a local Xray inbound)
|
# Optional watchdog: probes a URL (optionally through a local Xray inbound)
|
||||||
# and restarts Xray after repeated failures. A restart drops all connected clients.
|
# and restarts Xray after repeated failures. A restart drops all connected clients.
|
||||||
# Default: false
|
# Default: false
|
||||||
#XUI_TUNNEL_HEALTH_MONITOR=false
|
#LUI_TUNNEL_HEALTH_MONITOR=false
|
||||||
|
|
||||||
# Proxy to send the probe through, e.g., socks5://127.0.0.1:1080
|
# Proxy to send the probe through, e.g., socks5://127.0.0.1:1080
|
||||||
# Empty = only checks host connectivity
|
# Empty = only checks host connectivity
|
||||||
#XUI_TUNNEL_HEALTH_PROXY=
|
#LUI_TUNNEL_HEALTH_PROXY=
|
||||||
|
|
||||||
# URL to probe
|
# URL to probe
|
||||||
# Default: https://www.cloudflare.com/cdn-cgi/trace
|
# Default: https://www.cloudflare.com/cdn-cgi/trace
|
||||||
#XUI_TUNNEL_HEALTH_URL=https://www.cloudflare.com/cdn-cgi/trace
|
#LUI_TUNNEL_HEALTH_URL=https://www.cloudflare.com/cdn-cgi/trace
|
||||||
|
|
||||||
# Interval between probes
|
# Interval between probes
|
||||||
# Default: 30s
|
# Default: 30s
|
||||||
#XUI_TUNNEL_HEALTH_INTERVAL=30s
|
#LUI_TUNNEL_HEALTH_INTERVAL=30s
|
||||||
|
|
||||||
# Per-probe timeout
|
# Per-probe timeout
|
||||||
# Default: 10s
|
# Default: 10s
|
||||||
#XUI_TUNNEL_HEALTH_TIMEOUT=10s
|
#LUI_TUNNEL_HEALTH_TIMEOUT=10s
|
||||||
|
|
||||||
# Consecutive failures before a restart
|
# Consecutive failures before a restart
|
||||||
# Default: 3
|
# Default: 3
|
||||||
#XUI_TUNNEL_HEALTH_FAILURES=3
|
#LUI_TUNNEL_HEALTH_FAILURES=3
|
||||||
|
|
||||||
# Minimum delay between restarts
|
# Minimum delay between restarts
|
||||||
# Default: 5m
|
# Default: 5m
|
||||||
#XUI_TUNNEL_HEALTH_COOLDOWN=5m
|
#LUI_TUNNEL_HEALTH_COOLDOWN=5m
|
||||||
|
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
# Unattended install
|
# Unattended install
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
# Set to 1 (or run with no TTY) to install with zero prompts.
|
# Set to 1 (or run with no TTY) to install with zero prompts.
|
||||||
# Generated credentials will be written to /etc/x-ui/install-result.env
|
# Generated credentials will be written to /etc/l-ui/install-result.env
|
||||||
#XUI_NONINTERACTIVE=1
|
#LUI_NONINTERACTIVE=1
|
||||||
|
|||||||
+5
-3
@@ -1,6 +1,8 @@
|
|||||||
# These are supported funding model platforms
|
# These are supported funding model platforms
|
||||||
|
# Fork note: the upstream author's funding handles (github / buy_me_a_coffee /
|
||||||
|
# custom donate page) were removed — they do not belong to this fork.
|
||||||
|
|
||||||
github: MHSanaei
|
github: # upstream author's handle removed in this fork
|
||||||
patreon: # Replace with a single Patreon username
|
patreon: # Replace with a single Patreon username
|
||||||
open_collective: # Replace with a single Open Collective username
|
open_collective: # Replace with a single Open Collective username
|
||||||
ko_fi: # Replace with a single Ko-fi username
|
ko_fi: # Replace with a single Ko-fi username
|
||||||
@@ -10,5 +12,5 @@ liberapay: # Replace with a single Liberapay username
|
|||||||
issuehunt: # Replace with a single IssueHunt username
|
issuehunt: # Replace with a single IssueHunt username
|
||||||
lfx_crowdfunding: # Replace with a single LFX Crowdfunding project-name e.g., cloud-foundry
|
lfx_crowdfunding: # Replace with a single LFX Crowdfunding project-name e.g., cloud-foundry
|
||||||
polar: # Replace with a single Polar username
|
polar: # Replace with a single Polar username
|
||||||
buy_me_a_coffee: mhsanaei
|
buy_me_a_coffee: # upstream author's handle removed in this fork
|
||||||
custom: https://donate.sanaei.dev/
|
custom: # upstream author's donation page removed in this fork
|
||||||
|
|||||||
@@ -54,7 +54,7 @@ body:
|
|||||||
attributes:
|
attributes:
|
||||||
label: Relevant logs
|
label: Relevant logs
|
||||||
description: |
|
description: |
|
||||||
Panel logs (`journalctl -u x-ui -n 200`) and/or the browser DevTools
|
Panel logs (`journalctl -u l-ui -n 200`) and/or the browser DevTools
|
||||||
console output. **Redact** tokens, real domains, IPs, and client UUIDs.
|
console output. **Redact** tokens, real domains, IPs, and client UUIDs.
|
||||||
render: shell
|
render: shell
|
||||||
validations:
|
validations:
|
||||||
@@ -74,7 +74,7 @@ body:
|
|||||||
- type: input
|
- type: input
|
||||||
id: xui-version
|
id: xui-version
|
||||||
attributes:
|
attributes:
|
||||||
label: 3x-ui version
|
label: L-UI version
|
||||||
description: Shown at the top of the panel sidebar.
|
description: Shown at the top of the panel sidebar.
|
||||||
placeholder: 3.1.0
|
placeholder: 3.1.0
|
||||||
validations:
|
validations:
|
||||||
@@ -92,7 +92,7 @@ body:
|
|||||||
- type: dropdown
|
- type: dropdown
|
||||||
id: install-method
|
id: install-method
|
||||||
attributes:
|
attributes:
|
||||||
label: How did you install 3x-ui?
|
label: How did you install L-UI?
|
||||||
options:
|
options:
|
||||||
- install.sh script
|
- install.sh script
|
||||||
- Docker / Docker Compose
|
- Docker / Docker Compose
|
||||||
@@ -159,7 +159,7 @@ body:
|
|||||||
options:
|
options:
|
||||||
- label: I searched [existing issues](../issues?q=is%3Aissue) and this bug has not been reported.
|
- label: I searched [existing issues](../issues?q=is%3Aissue) and this bug has not been reported.
|
||||||
required: true
|
required: true
|
||||||
- label: I am running the latest released version of 3x-ui (or have verified the bug still exists on it).
|
- label: I am running the latest released version of L-UI (or have verified the bug still exists on it).
|
||||||
required: true
|
required: true
|
||||||
- label: This bug report is written in English.
|
- label: This bug report is written in English.
|
||||||
required: true
|
required: true
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
blank_issues_enabled: false
|
blank_issues_enabled: false
|
||||||
contact_links:
|
contact_links:
|
||||||
- name: 📖 Project Wiki
|
- name: 📖 Project home (Gitea)
|
||||||
url: https://github.com/MHSanaei/3x-ui/wiki
|
url: https://git.881218.xyz/rogue/l-ui
|
||||||
about: Setup, install, configuration, and "how do I…" guides live here. Please check before opening a question.
|
about: Setup, install, configuration, and "how do I…" guides live here. Please check before opening a question.
|
||||||
- name: 🔍 Search existing issues
|
- name: 🔍 Search existing issues
|
||||||
url: https://github.com/MHSanaei/3x-ui/issues?q=is%3Aissue
|
url: https://git.881218.xyz/rogue/l-ui/issues
|
||||||
about: Your bug, feature, or question may already be tracked. Comment on the existing one rather than opening a duplicate.
|
about: Your bug, feature, or question may already be tracked. Comment on the existing one rather than opening a duplicate.
|
||||||
- name: 🚀 Latest release
|
- name: 🚀 Latest release
|
||||||
url: https://github.com/MHSanaei/3x-ui/releases/latest
|
url: https://git.881218.xyz/rogue/l-ui/releases
|
||||||
about: Reproduce on the latest version before reporting — many bugs are already fixed in the most recent release.
|
about: Reproduce on the latest version before reporting — many bugs are already fixed in the most recent release.
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
name: Feature request
|
name: Feature request
|
||||||
description: Suggest an idea or improvement for 3x-ui
|
description: Suggest an idea or improvement for L-UI
|
||||||
title: "[Feature]: "
|
title: "[Feature]: "
|
||||||
labels: ["enhancement"]
|
labels: ["enhancement"]
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
name: Question
|
name: Question
|
||||||
description: Ask how to do something with 3x-ui
|
description: Ask how to do something with L-UI
|
||||||
title: "[Question]: "
|
title: "[Question]: "
|
||||||
labels: ["question"]
|
labels: ["question"]
|
||||||
|
|
||||||
@@ -9,7 +9,7 @@ body:
|
|||||||
value: |
|
value: |
|
||||||
Before opening a question, please:
|
Before opening a question, please:
|
||||||
|
|
||||||
- Read the [project Wiki](https://github.com/MHSanaei/3x-ui/wiki) —
|
- Read the [project home](https://git.881218.xyz/rogue/l-ui) —
|
||||||
most setup, install, and "how do I …" answers live there.
|
most setup, install, and "how do I …" answers live there.
|
||||||
- Search [existing issues](../issues?q=is%3Aissue) — the question
|
- Search [existing issues](../issues?q=is%3Aissue) — the question
|
||||||
may already have been asked.
|
may already have been asked.
|
||||||
@@ -43,7 +43,7 @@ body:
|
|||||||
- type: input
|
- type: input
|
||||||
id: xui-version
|
id: xui-version
|
||||||
attributes:
|
attributes:
|
||||||
label: 3x-ui version
|
label: L-UI version
|
||||||
description: Shown at the top of the panel sidebar.
|
description: Shown at the top of the panel sidebar.
|
||||||
placeholder: 3.1.0
|
placeholder: 3.1.0
|
||||||
validations:
|
validations:
|
||||||
@@ -52,7 +52,7 @@ body:
|
|||||||
- type: dropdown
|
- type: dropdown
|
||||||
id: install-method
|
id: install-method
|
||||||
attributes:
|
attributes:
|
||||||
label: How did you install 3x-ui?
|
label: How did you install L-UI?
|
||||||
options:
|
options:
|
||||||
- install.sh script
|
- install.sh script
|
||||||
- Docker / Docker Compose
|
- Docker / Docker Compose
|
||||||
@@ -85,7 +85,7 @@ body:
|
|||||||
attributes:
|
attributes:
|
||||||
label: Before submitting
|
label: Before submitting
|
||||||
options:
|
options:
|
||||||
- label: I read the [Wiki](https://github.com/MHSanaei/3x-ui/wiki) and searched [existing issues](../issues?q=is%3Aissue).
|
- label: I read the [project home](https://git.881218.xyz/rogue/l-ui) and searched [existing issues](../issues?q=is%3Aissue).
|
||||||
required: true
|
required: true
|
||||||
- label: This is a usage question, not a bug report.
|
- label: This is a usage question, not a bug report.
|
||||||
required: true
|
required: true
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ question it already answers.
|
|||||||
|
|
||||||
## Stack
|
## Stack
|
||||||
|
|
||||||
3x-ui is an open-source web control panel for managing Xray-core servers.
|
L-UI is an open-source web control panel for managing Xray-core servers.
|
||||||
|
|
||||||
- Backend: Go 1.27, module `github.com/mhsanaei/3x-ui/v3`, Gin and GORM.
|
- Backend: Go 1.27, module `github.com/mhsanaei/3x-ui/v3`, Gin and GORM.
|
||||||
- It runs Xray-core as a managed child process (`internal/xray/process.go`) and
|
- It runs Xray-core as a managed child process (`internal/xray/process.go`) and
|
||||||
@@ -26,8 +26,8 @@ question it already answers.
|
|||||||
per inbound. Client, ad-tag and quota/expiry edits are hot-applied through the
|
per inbound. Client, ad-tag and quota/expiry edits are hot-applied through the
|
||||||
fork's management API (`PUT /secrets`) so connections survive, with a process
|
fork's management API (`PUT /secrets`) so connections survive, with a process
|
||||||
restart as the fallback on older binaries.
|
restart as the fallback on older binaries.
|
||||||
- Storage: SQLite by default (`/etc/x-ui/x-ui.db` on Linux, the executable
|
- Storage: SQLite by default (`/etc/l-ui/l-ui.db` on Linux, the executable
|
||||||
directory on Windows) or PostgreSQL (`XUI_DB_TYPE` / `XUI_DB_DSN`). The SQLite
|
directory on Windows) or PostgreSQL (`LUI_DB_TYPE` / `LUI_DB_DSN`). The SQLite
|
||||||
driver is CGo, so `CGO_ENABLED=0` builds fail.
|
driver is CGo, so `CGO_ENABLED=0` builds fail.
|
||||||
- Frontend: React 19 + Ant Design 6 + Vite 8 + TypeScript in `frontend/`, built
|
- Frontend: React 19 + Ant Design 6 + Vite 8 + TypeScript in `frontend/`, built
|
||||||
into `internal/web/dist/` (gitignored) and embedded with `embed.FS`.
|
into `internal/web/dist/` (gitignored) and embedded with `embed.FS`.
|
||||||
@@ -36,7 +36,7 @@ question it already answers.
|
|||||||
|
|
||||||
| area | path |
|
| area | path |
|
||||||
| --- | --- |
|
| --- | --- |
|
||||||
| entry point + `x-ui` CLI | `main.go` |
|
| entry point + `l-ui` CLI | `main.go` |
|
||||||
| env parsing | `internal/config/` |
|
| env parsing | `internal/config/` |
|
||||||
| schema, migrations | `internal/database/`, `internal/database/model/` |
|
| schema, migrations | `internal/database/`, `internal/database/model/` |
|
||||||
| Xray child process + config | `internal/xray/` |
|
| Xray child process + config | `internal/xray/` |
|
||||||
@@ -48,7 +48,7 @@ question it already answers.
|
|||||||
| master/sub-node over mTLS | `internal/web/runtime/` |
|
| master/sub-node over mTLS | `internal/web/runtime/` |
|
||||||
| i18n | `internal/web/locale/`, `internal/web/translation/` |
|
| i18n | `internal/web/locale/`, `internal/web/translation/` |
|
||||||
| UI source | `frontend/src/` |
|
| UI source | `frontend/src/` |
|
||||||
| install / upgrade | `install.sh`, `x-ui.sh`, `DockerInit.sh` |
|
| install / upgrade | `install.sh`, `l-ui.sh`, `DockerInit.sh` |
|
||||||
|
|
||||||
## Hard rules a change must respect
|
## Hard rules a change must respect
|
||||||
|
|
||||||
@@ -93,7 +93,7 @@ question it already answers.
|
|||||||
subtests and `t.Helper()` on helpers. An assertion must pin the exact value,
|
subtests and `t.Helper()` on helpers. An assertion must pin the exact value,
|
||||||
typed error or emitted string — `err != nil` and `len(x) > 0` are findings,
|
typed error or emitted string — `err != nil` and `len(x) > 0` are findings,
|
||||||
not nits. Prefer real dependencies: a throwaway DB via
|
not nits. Prefer real dependencies: a throwaway DB via
|
||||||
`database.InitDB(filepath.Join(t.TempDir(), "x-ui.db"))` with `t.Cleanup`, and
|
`database.InitDB(filepath.Join(t.TempDir(), "l-ui.db"))` with `t.Cleanup`, and
|
||||||
`httptest` for HTTP. `internal/sub`'s `initSubDB(t)` is the template.
|
`httptest` for HTTP. `internal/sub`'s `initSubDB(t)` is the template.
|
||||||
A test must FAIL without its fix; one that passes either way certifies
|
A test must FAIL without its fix; one that passes either way certifies
|
||||||
nothing and then gets cited as proof the fix works.
|
nothing and then gets cited as proof the fix works.
|
||||||
@@ -143,36 +143,36 @@ variable is set, and CI sets only the PostgreSQL ones above:
|
|||||||
|
|
||||||
| gate | covers |
|
| gate | covers |
|
||||||
| --- | --- |
|
| --- | --- |
|
||||||
| `XUI_TEST_PG_DSN` | PostgreSQL-specific paths |
|
| `LUI_TEST_PG_DSN` | PostgreSQL-specific paths |
|
||||||
| `XUI_DB_TYPE` + `XUI_DB_DSN` | dialect-dependent behaviour |
|
| `LUI_DB_TYPE` + `LUI_DB_DSN` | dialect-dependent behaviour |
|
||||||
| `XRAY_E2E_BINARY` | the Xray gRPC end-to-end tests in `internal/xray/` |
|
| `XRAY_E2E_BINARY` | the Xray gRPC end-to-end tests in `internal/xray/` |
|
||||||
| `XUI_SCALE_TEST` | scale tests in `internal/sub/`, `internal/web/job/`, `internal/web/service/` |
|
| `LUI_SCALE_TEST` | scale tests in `internal/sub/`, `internal/web/job/`, `internal/web/service/` |
|
||||||
|
|
||||||
Mutation testing (`mutation.yml`) runs nightly and never on a pull request, so a
|
Mutation testing (`mutation.yml`) runs nightly and never on a pull request, so a
|
||||||
test that cannot fail is invisible to CI. `make verify` is the local gate.
|
test that cannot fail is invisible to CI. `make verify` is the local gate.
|
||||||
|
|
||||||
## Support facts reporters get wrong
|
## Support facts reporters get wrong
|
||||||
|
|
||||||
- Linux install: `bash <(curl -Ls https://raw.githubusercontent.com/mhsanaei/3x-ui/master/install.sh)`
|
- Linux install: `bash <(curl -Ls https://git.881218.xyz/rogue/l-ui/raw/branch/main/install-master.sh)`
|
||||||
- Install generates a RANDOM username, password and web base path — never
|
- Install generates a RANDOM username, password and web base path — never
|
||||||
admin/admin. The `x-ui` menu on the server shows or resets them.
|
admin/admin. The `l-ui` menu on the server shows or resets them.
|
||||||
- The installer service environment file is DISTRO-DEPENDENT:
|
- The installer service environment file is DISTRO-DEPENDENT:
|
||||||
`/etc/default/x-ui` (Debian/Ubuntu), `/etc/conf.d/x-ui` (Arch),
|
`/etc/default/l-ui` (Debian/Ubuntu), `/etc/conf.d/l-ui` (Arch),
|
||||||
`/etc/sysconfig/x-ui` (RHEL/Fedora). Naming the wrong one means the reporter's
|
`/etc/sysconfig/l-ui` (RHEL/Fedora). Naming the wrong one means the reporter's
|
||||||
edit is silently never read by systemd — a common cause of "I set the variable
|
edit is silently never read by systemd — a common cause of "I set the variable
|
||||||
and nothing happened".
|
and nothing happened".
|
||||||
- Windows is supported. There the database sits next to the executable, not in
|
- Windows is supported. There the database sits next to the executable, not in
|
||||||
`/etc` — never quote the Linux path to a Windows user.
|
`/etc` — never quote the Linux path to a Windows user.
|
||||||
- SQLite to PostgreSQL: `x-ui migrate-db --dsn "postgres://..."`, then set
|
- SQLite to PostgreSQL: `l-ui migrate-db --dsn "postgres://..."`, then set
|
||||||
`XUI_DB_TYPE`/`XUI_DB_DSN` in that file and `systemctl restart x-ui`. The
|
`LUI_DB_TYPE`/`LUI_DB_DSN` in that file and `systemctl restart l-ui`. The
|
||||||
source SQLite file is left in place.
|
source SQLite file is left in place.
|
||||||
- Docker image `ghcr.io/mhsanaei/3x-ui`; PostgreSQL profile
|
- Docker image `ghcr.io/mhsanaei/3x-ui`; PostgreSQL profile
|
||||||
`docker compose --profile postgres up -d`. Fail2ban IP-limit enforcement needs
|
`docker compose --profile postgres up -d`. Fail2ban IP-limit enforcement needs
|
||||||
`NET_ADMIN` + `NET_RAW` (compose grants them; a bare `docker run` must add
|
`NET_ADMIN` + `NET_RAW` (compose grants them; a bare `docker run` must add
|
||||||
`--cap-add=NET_ADMIN --cap-add=NET_RAW`).
|
`--cap-add=NET_ADMIN --cap-add=NET_RAW`).
|
||||||
- Never state that a `XUI_*` variable does not exist without grepping
|
- Never state that a `LUI_*` variable does not exist without grepping
|
||||||
`internal/config/` and `internal/tunnelmonitor/` first. The
|
`internal/config/` and `internal/tunnelmonitor/` first. The
|
||||||
`XUI_TUNNEL_HEALTH_*` family is the usual answer to "the panel restarts Xray
|
`LUI_TUNNEL_HEALTH_*` family is the usual answer to "the panel restarts Xray
|
||||||
every few minutes".
|
every few minutes".
|
||||||
- Security per inbound is none / tls / reality. XTLS is a VLESS *flow*
|
- Security per inbound is none / tls / reality. XTLS is a VLESS *flow*
|
||||||
(`xtls-rprx-vision`), not a security setting — never tell anyone to pick XTLS
|
(`xtls-rprx-vision`), not a security setting — never tell anyone to pick XTLS
|
||||||
|
|||||||
@@ -58,8 +58,8 @@ jobs:
|
|||||||
--health-timeout 5s
|
--health-timeout 5s
|
||||||
--health-retries 5
|
--health-retries 5
|
||||||
env:
|
env:
|
||||||
XUI_DB_TYPE: postgres
|
LUI_DB_TYPE: postgres
|
||||||
XUI_DB_DSN: "host=127.0.0.1 port=5432 user=postgres password=postgres dbname=xui_durable sslmode=disable"
|
LUI_DB_DSN: "host=127.0.0.1 port=5432 user=postgres password=postgres dbname=xui_durable sslmode=disable"
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v7
|
- uses: actions/checkout@v7
|
||||||
- uses: actions/setup-go@v7
|
- uses: actions/setup-go@v7
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ jobs:
|
|||||||
--allowedTools "Bash(gh label list:*),Bash(gh issue view:*),Bash(gh issue list:*),Bash(gh issue comment ${{ github.event.issue.number }}:*),Bash(gh issue edit ${{ github.event.issue.number }} --add-label:*),Bash(gh issue edit ${{ github.event.issue.number }} --remove-label:*),Bash(gh issue edit ${{ github.event.issue.number }} --title:*),Bash(gh issue close ${{ github.event.issue.number }}:*),Bash(gh search issues:*),Bash(gh search commits:*),Bash(gh search prs:*),Bash(gh pr view:*),Bash(gh pr diff:*),Bash(gh pr list:*),Bash(gh release list:*),Bash(gh release view:*),Bash(git log:*),Bash(git show:*),Bash(git blame:*),Bash(git ls-tree:*),Bash(git tag:*),Read,Glob,Grep,Write(//tmp/**),Edit(//tmp/**)"
|
--allowedTools "Bash(gh label list:*),Bash(gh issue view:*),Bash(gh issue list:*),Bash(gh issue comment ${{ github.event.issue.number }}:*),Bash(gh issue edit ${{ github.event.issue.number }} --add-label:*),Bash(gh issue edit ${{ github.event.issue.number }} --remove-label:*),Bash(gh issue edit ${{ github.event.issue.number }} --title:*),Bash(gh issue close ${{ github.event.issue.number }}:*),Bash(gh search issues:*),Bash(gh search commits:*),Bash(gh search prs:*),Bash(gh pr view:*),Bash(gh pr diff:*),Bash(gh pr list:*),Bash(gh release list:*),Bash(gh release view:*),Bash(git log:*),Bash(git show:*),Bash(git blame:*),Bash(git ls-tree:*),Bash(git tag:*),Read,Glob,Grep,Write(//tmp/**),Edit(//tmp/**)"
|
||||||
--disallowedTools "Read(//**/.git/**),Edit(//**/.git/**)"
|
--disallowedTools "Read(//**/.git/**),Edit(//**/.git/**)"
|
||||||
prompt: |
|
prompt: |
|
||||||
You are the SENIOR GITHUB ISSUE ANALYST for the MHSanaei/3x-ui
|
You are the SENIOR GITHUB ISSUE ANALYST for the MHSanaei/L-UI
|
||||||
repository, an open-source web control panel for managing Xray-core
|
repository, an open-source web control panel for managing Xray-core
|
||||||
servers. You are the only automated reply an issue ever gets. Your
|
servers. You are the only automated reply an issue ever gets. Your
|
||||||
question is: IS THE REPORTED PROBLEM REAL, AND IF SO, WHY?
|
question is: IS THE REPORTED PROBLEM REAL, AND IF SO, WHY?
|
||||||
@@ -106,7 +106,7 @@ jobs:
|
|||||||
reports, "enhancement" for feature requests, "question" for
|
reports, "enhancement" for feature requests, "question" for
|
||||||
questions - so a pre-applied type label is a template default to
|
questions - so a pre-applied type label is a template default to
|
||||||
verify, not the reporter's considered classification. The bug form
|
verify, not the reporter's considered classification. The bug form
|
||||||
already REQUIRES the 3x-ui version, install method and OS, and also
|
already REQUIRES the L-UI version, install method and OS, and also
|
||||||
collects logs, the Xray version, affected areas and reverse-proxy
|
collects logs, the Xray version, affected areas and reverse-proxy
|
||||||
setup; the question form requires the version and install method. It
|
setup; the question form requires the version and install method. It
|
||||||
all arrives under "### <heading>" sections of the body. Read those
|
all arrives under "### <heading>" sections of the body. Read those
|
||||||
@@ -251,7 +251,7 @@ jobs:
|
|||||||
question you could have answered by reading more code.
|
question you could have answered by reading more code.
|
||||||
|
|
||||||
SECURITY EXCEPTION, which overrides everything else: if the report
|
SECURITY EXCEPTION, which overrides everything else: if the report
|
||||||
describes what looks like an exploitable vulnerability in 3x-ui - an
|
describes what looks like an exploitable vulnerability in L-UI - an
|
||||||
authentication bypass, remote code execution, injection, secret or
|
authentication bypass, remote code execution, injection, secret or
|
||||||
credential exposure, privilege escalation - do NOT investigate or
|
credential exposure, privilege escalation - do NOT investigate or
|
||||||
analyse it publicly. Post one short comment asking the reporter to
|
analyse it publicly. Post one short comment asking the reporter to
|
||||||
@@ -285,7 +285,7 @@ jobs:
|
|||||||
- CLOSE AS INVALID when the body, judged exactly as written, is
|
- CLOSE AS INVALID when the body, judged exactly as written, is
|
||||||
empty or only whitespace, punctuation or emoji; pure gibberish;
|
empty or only whitespace, punctuation or emoji; pure gibberish;
|
||||||
advertising or unrelated links; a throwaway test ("test", "asdf");
|
advertising or unrelated links; a throwaway test ("test", "asdf");
|
||||||
or unrelated to 3x-ui and Xray. Then: post the comment, add the
|
or unrelated to L-UI and Xray. Then: post the comment, add the
|
||||||
`invalid` label, and
|
`invalid` label, and
|
||||||
`gh issue close ${{ github.event.issue.number }} --reason "not planned"`.
|
`gh issue close ${{ github.event.issue.number }} --reason "not planned"`.
|
||||||
A short, vague, badly formatted, machine-translated or low-quality
|
A short, vague, badly formatted, machine-translated or low-quality
|
||||||
@@ -628,11 +628,11 @@ jobs:
|
|||||||
--allowedTools "Bash(gh issue view:*),Bash(gh issue list:*),Bash(gh issue comment ${{ github.event.issue.number }}:*),Bash(gh pr view:*),Bash(gh pr diff:*),Bash(gh pr list:*),Bash(gh pr comment ${{ github.event.issue.number }}:*),Bash(gh search issues:*),Bash(gh search commits:*),Bash(gh release list:*),Bash(gh label list:*),Read,Glob,Grep,Write(//tmp/**),Edit(//tmp/**)"
|
--allowedTools "Bash(gh issue view:*),Bash(gh issue list:*),Bash(gh issue comment ${{ github.event.issue.number }}:*),Bash(gh pr view:*),Bash(gh pr diff:*),Bash(gh pr list:*),Bash(gh pr comment ${{ github.event.issue.number }}:*),Bash(gh search issues:*),Bash(gh search commits:*),Bash(gh release list:*),Bash(gh label list:*),Read,Glob,Grep,Write(//tmp/**),Edit(//tmp/**)"
|
||||||
--disallowedTools "Read(//**/.git/**),Edit(//**/.git/**)"
|
--disallowedTools "Read(//**/.git/**),Edit(//**/.git/**)"
|
||||||
prompt: |
|
prompt: |
|
||||||
You are replying to an @claude mention from a maintainer of the MHSanaei/3x-ui repository - its owner, or somebody invited to it with write access, an open-source web panel for managing Xray-core servers. This run investigates and explains; it never changes anything. You have no tool that can edit a file in the checkout, no git command that can write, and a token that cannot push, so no file is edited, no branch is created, no commit is made and no pull request is opened or merged - on an issue and on a pull request alike. The one exception in this repository lives in a separate workflow job that only the repository owner can start, so do not mention it or offer it. The full repo source is checked out in the working directory; use Read, Glob and Grep to open and verify the relevant files before stating any default, path, flag, option name, or behavior. Your file-writing tool is limited to /tmp: a long reply goes to /tmp/comment.md and is posted with gh issue comment <number> --body-file /tmp/comment.md (or gh pr comment for a pull request). If that write is refused for any reason, pass the body inline with --body instead - never leave the thread unanswered.
|
You are replying to an @claude mention from a maintainer of the MHSanaei/L-UI repository - its owner, or somebody invited to it with write access, an open-source web panel for managing Xray-core servers. This run investigates and explains; it never changes anything. You have no tool that can edit a file in the checkout, no git command that can write, and a token that cannot push, so no file is edited, no branch is created, no commit is made and no pull request is opened or merged - on an issue and on a pull request alike. The one exception in this repository lives in a separate workflow job that only the repository owner can start, so do not mention it or offer it. The full repo source is checked out in the working directory; use Read, Glob and Grep to open and verify the relevant files before stating any default, path, flag, option name, or behavior. Your file-writing tool is limited to /tmp: a long reply goes to /tmp/comment.md and is posted with gh issue comment <number> --body-file /tmp/comment.md (or gh pr comment for a pull request). If that write is refused for any reason, pass the body inline with --body instead - never leave the thread unanswered.
|
||||||
|
|
||||||
Key layout:
|
Key layout:
|
||||||
- main.go holds the entry point and the x-ui management CLI (run, migrate, migrate-db, encrypt-tokens, setting, cert).
|
- main.go holds the entry point and the l-ui management CLI (run, migrate, migrate-db, encrypt-tokens, setting, cert).
|
||||||
- internal/config/ parses env vars (XUI_DEBUG, XUI_LOG_LEVEL, XUI_LOG_FOLDER, XUI_BIN_FOLDER, XUI_SKIP_HSTS, XUI_PORT, XUI_DB_FOLDER, XUI_DB_TYPE, XUI_DB_DSN).
|
- internal/config/ parses env vars (LUI_DEBUG, LUI_LOG_LEVEL, LUI_LOG_FOLDER, LUI_BIN_FOLDER, LUI_SKIP_HSTS, LUI_PORT, LUI_DB_FOLDER, LUI_DB_TYPE, LUI_DB_DSN).
|
||||||
- internal/database/ and internal/database/model/ hold the GORM schema (Inbound, Client, Setting, User) and the inbound protocol enum (vmess, vless, tunnel, http, trojan, shadowsocks, mixed, wireguard, hysteria, mtproto).
|
- internal/database/ and internal/database/model/ hold the GORM schema (Inbound, Client, Setting, User) and the inbound protocol enum (vmess, vless, tunnel, http, trojan, shadowsocks, mixed, wireguard, hysteria, mtproto).
|
||||||
- internal/mtproto/ runs MTProto (Telegram) proxy inbounds via the bundled mtg binary.
|
- internal/mtproto/ runs MTProto (Telegram) proxy inbounds via the bundled mtg binary.
|
||||||
- internal/web/controller/ has panel and REST API handlers with the OpenAPI spec served at /panel/api/openapi.json.
|
- internal/web/controller/ has panel and REST API handlers with the OpenAPI spec served at /panel/api/openapi.json.
|
||||||
@@ -643,13 +643,13 @@ jobs:
|
|||||||
- internal/sub/ is the subscription server.
|
- internal/sub/ is the subscription server.
|
||||||
- internal/eventbus/ is an in-process pub/sub event bus (outbound and node health, xray.crash, cpu.high, memory.high, login.attempt).
|
- internal/eventbus/ is an in-process pub/sub event bus (outbound and node health, xray.crash, cpu.high, memory.high, login.attempt).
|
||||||
- internal/xray/ runs Xray-core as a managed child process and generates its config; internal/xray/geodata/ streams the geosite/geoip .dat files.
|
- internal/xray/ runs Xray-core as a managed child process and generates its config; internal/xray/geodata/ streams the geosite/geoip .dat files.
|
||||||
- internal/crypto/ (node-token encryption), internal/logger/, internal/util/ (link, ldap, sys, wireguard - leaf-only helpers) and internal/tunnelmonitor/ (the XUI_TUNNEL_HEALTH_* tunnel watchdog) are shared infrastructure.
|
- internal/crypto/ (node-token encryption), internal/logger/, internal/util/ (link, ldap, sys, wireguard - leaf-only helpers) and internal/tunnelmonitor/ (the LUI_TUNNEL_HEALTH_* tunnel watchdog) are shared infrastructure.
|
||||||
- frontend/ is the React 19 plus Ant Design 6 plus Vite 8 plus TypeScript source built into the embedded internal/web/dist/.
|
- frontend/ is the React 19 plus Ant Design 6 plus Vite 8 plus TypeScript source built into the embedded internal/web/dist/.
|
||||||
- tools/openapigen emits the frontend API types and Zod/JSON schemas; the OpenAPI document itself is assembled by frontend/scripts/build-openapi.mjs.
|
- tools/openapigen emits the frontend API types and Zod/JSON schemas; the OpenAPI document itself is assembled by frontend/scripts/build-openapi.mjs.
|
||||||
- docs/ is a separate Next.js docs site; docs/lib/xray/ holds a third independent implementation of link/subscription generation.
|
- docs/ is a separate Next.js docs site; docs/lib/xray/ holds a third independent implementation of link/subscription generation.
|
||||||
CLAUDE.md and docs/architecture.md in the checkout are the maintained maps; when they and this layout disagree, they win.
|
CLAUDE.md and docs/architecture.md in the checkout are the maintained maps; when they and this layout disagree, they win.
|
||||||
|
|
||||||
Stack and runtime facts: Backend is Go (module github.com/mhsanaei/3x-ui/v3) with Gin and GORM; storage is SQLite by default at /etc/x-ui/x-ui.db or PostgreSQL via XUI_DB_TYPE and XUI_DB_DSN; further env vars include XUI_DB_MAX_OPEN_CONNS, XUI_DB_MAX_IDLE_CONNS, XUI_INIT_WEB_BASE_PATH, XUI_ENABLE_FAIL2BAN, and the XUI_TUNNEL_HEALTH_* family in internal/tunnelmonitor/ - never say a XUI_* variable does not exist without grepping internal/config/ and internal/tunnelmonitor/ first; the installer's service env file is distro-dependent - /etc/default/x-ui (Debian/Ubuntu/Armbian), /etc/conf.d/x-ui (Arch/Alpine), /etc/sysconfig/x-ui (RHEL/Fedora and others); SQLite to PostgreSQL migration is x-ui migrate-db --dsn followed by a service restart; install uses install.sh and the x-ui menu, generating random initial credentials; Docker image is ghcr.io/mhsanaei/3x-ui and Fail2ban IP-limit enforcement needs NET_ADMIN and NET_RAW; Windows is a supported platform (the DB sits next to the executable there, not in /etc). Do not hardcode a version: for version or is-this-fixed questions, check the latest release and recent commits or closed PRs with gh. The same discipline applies to every fact in this prompt - the repo moves, so re-verify names, paths, flags, and enum values in the source before quoting them.
|
Stack and runtime facts: Backend is Go (module github.com/mhsanaei/3x-ui/v3) with Gin and GORM; storage is SQLite by default at /etc/l-ui/l-ui.db or PostgreSQL via LUI_DB_TYPE and LUI_DB_DSN; further env vars include LUI_DB_MAX_OPEN_CONNS, LUI_DB_MAX_IDLE_CONNS, LUI_INIT_WEB_BASE_PATH, LUI_ENABLE_FAIL2BAN, and the LUI_TUNNEL_HEALTH_* family in internal/tunnelmonitor/ - never say a LUI_* variable does not exist without grepping internal/config/ and internal/tunnelmonitor/ first; the installer's service env file is distro-dependent - /etc/default/l-ui (Debian/Ubuntu/Armbian), /etc/conf.d/l-ui (Arch/Alpine), /etc/sysconfig/l-ui (RHEL/Fedora and others); SQLite to PostgreSQL migration is l-ui migrate-db --dsn followed by a service restart; install uses install.sh and the l-ui menu, generating random initial credentials; Docker image is ghcr.io/mhsanaei/3x-ui and Fail2ban IP-limit enforcement needs NET_ADMIN and NET_RAW; Windows is a supported platform (the DB sits next to the executable there, not in /etc). Do not hardcode a version: for version or is-this-fixed questions, check the latest release and recent commits or closed PRs with gh. The same discipline applies to every fact in this prompt - the repo moves, so re-verify names, paths, flags, and enum values in the source before quoting them.
|
||||||
|
|
||||||
Style: lead with the answer in the first sentence; use fenced code blocks for commands and backtick formatting for paths and setting names; distinguish what you confirmed in the source (name the file) from what you infer; never promise fixes, timelines, or releases. Ground every claim in the code or the README and wiki; do not invent features, paths, flags, or commands, and do not stop at the first plausible match. Token cost is not a concern, so investigate as deeply as the question needs.
|
Style: lead with the answer in the first sentence; use fenced code blocks for commands and backtick formatting for paths and setting names; distinguish what you confirmed in the source (name the file) from what you infer; never promise fixes, timelines, or releases. Ground every claim in the code or the README and wiki; do not invent features, paths, flags, or commands, and do not stop at the first plausible match. Token cost is not a concern, so investigate as deeply as the question needs.
|
||||||
|
|
||||||
@@ -836,7 +836,7 @@ jobs:
|
|||||||
--disallowedTools "Bash,WebFetch,WebSearch,Task,Edit(//**/.git/**),Read(//**/.git/**)"
|
--disallowedTools "Bash,WebFetch,WebSearch,Task,Edit(//**/.git/**),Read(//**/.git/**)"
|
||||||
prompt: |
|
prompt: |
|
||||||
The repository owner asked for the merge conflicts on pull request
|
The repository owner asked for the merge conflicts on pull request
|
||||||
#${{ github.event.issue.number }} of MHSanaei/3x-ui, an open-source
|
#${{ github.event.issue.number }} of MHSanaei/L-UI, an open-source
|
||||||
web panel for managing Xray-core servers, to be resolved. The merge
|
web panel for managing Xray-core servers, to be resolved. The merge
|
||||||
of `${{ steps.merge.outputs.base }}` into the pull request's branch
|
of `${{ steps.merge.outputs.base }}` into the pull request's branch
|
||||||
`${{ steps.merge.outputs.head }}` is already in progress in the
|
`${{ steps.merge.outputs.head }}` is already in progress in the
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ jobs:
|
|||||||
uses: docker/metadata-action@v6
|
uses: docker/metadata-action@v6
|
||||||
with:
|
with:
|
||||||
images: |
|
images: |
|
||||||
hsanaeii/3x-ui
|
hsanaeii/L-UI
|
||||||
ghcr.io/mhsanaei/3x-ui
|
ghcr.io/mhsanaei/3x-ui
|
||||||
tags: |
|
tags: |
|
||||||
type=ref,event=branch
|
type=ref,event=branch
|
||||||
|
|||||||
@@ -13,9 +13,9 @@ on:
|
|||||||
- "go.sum"
|
- "go.sum"
|
||||||
- "**.sh"
|
- "**.sh"
|
||||||
- "frontend/**"
|
- "frontend/**"
|
||||||
- "x-ui.service.debian"
|
- "l-ui.service.debian"
|
||||||
- "x-ui.service.arch"
|
- "l-ui.service.arch"
|
||||||
- "x-ui.service.rhel"
|
- "l-ui.service.rhel"
|
||||||
- ".github/workflows/release.yml"
|
- ".github/workflows/release.yml"
|
||||||
pull_request:
|
pull_request:
|
||||||
paths:
|
paths:
|
||||||
@@ -24,9 +24,9 @@ on:
|
|||||||
- "go.sum"
|
- "go.sum"
|
||||||
- "**.sh"
|
- "**.sh"
|
||||||
- "frontend/**"
|
- "frontend/**"
|
||||||
- "x-ui.service.debian"
|
- "l-ui.service.debian"
|
||||||
- "x-ui.service.arch"
|
- "l-ui.service.arch"
|
||||||
- "x-ui.service.rhel"
|
- "l-ui.service.rhel"
|
||||||
- ".github/workflows/release.yml"
|
- ".github/workflows/release.yml"
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
@@ -113,15 +113,15 @@ jobs:
|
|||||||
file xui-release
|
file xui-release
|
||||||
ldd xui-release || echo "Static binary confirmed"
|
ldd xui-release || echo "Static binary confirmed"
|
||||||
|
|
||||||
mkdir x-ui
|
mkdir l-ui
|
||||||
cp xui-release x-ui/
|
cp xui-release l-ui/
|
||||||
cp x-ui.service.debian x-ui/
|
cp l-ui.service.debian l-ui/
|
||||||
cp x-ui.service.arch x-ui/
|
cp l-ui.service.arch l-ui/
|
||||||
cp x-ui.service.rhel x-ui/
|
cp l-ui.service.rhel l-ui/
|
||||||
cp x-ui.sh x-ui/
|
cp l-ui.sh l-ui/
|
||||||
mv x-ui/xui-release x-ui/x-ui
|
mv l-ui/xui-release l-ui/l-ui
|
||||||
mkdir x-ui/bin
|
mkdir l-ui/bin
|
||||||
cd x-ui/bin
|
cd l-ui/bin
|
||||||
|
|
||||||
# Download dependencies
|
# Download dependencies
|
||||||
Xray_URL="https://github.com/XTLS/Xray-core/releases/download/v26.7.28/"
|
Xray_URL="https://github.com/XTLS/Xray-core/releases/download/v26.7.28/"
|
||||||
@@ -183,13 +183,13 @@ jobs:
|
|||||||
cd ../..
|
cd ../..
|
||||||
|
|
||||||
- name: Package
|
- name: Package
|
||||||
run: tar -zcvf x-ui-linux-${{ matrix.platform }}.tar.gz x-ui
|
run: tar -zcvf l-ui-linux-${{ matrix.platform }}.tar.gz l-ui
|
||||||
|
|
||||||
- name: Upload files to Artifacts
|
- name: Upload files to Artifacts
|
||||||
uses: actions/upload-artifact@v7
|
uses: actions/upload-artifact@v7
|
||||||
with:
|
with:
|
||||||
name: x-ui-linux-${{ matrix.platform }}
|
name: l-ui-linux-${{ matrix.platform }}
|
||||||
path: ./x-ui-linux-${{ matrix.platform }}.tar.gz
|
path: ./l-ui-linux-${{ matrix.platform }}.tar.gz
|
||||||
|
|
||||||
- name: Upload files to GH release
|
- name: Upload files to GH release
|
||||||
uses: svenstaro/upload-release-action@v2
|
uses: svenstaro/upload-release-action@v2
|
||||||
@@ -197,8 +197,8 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
repo_token: ${{ secrets.GITHUB_TOKEN }}
|
repo_token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
tag: ${{ github.ref_name }}
|
tag: ${{ github.ref_name }}
|
||||||
file: x-ui-linux-${{ matrix.platform }}.tar.gz
|
file: l-ui-linux-${{ matrix.platform }}.tar.gz
|
||||||
asset_name: x-ui-linux-${{ matrix.platform }}.tar.gz
|
asset_name: l-ui-linux-${{ matrix.platform }}.tar.gz
|
||||||
overwrite: true
|
overwrite: true
|
||||||
prerelease: true
|
prerelease: true
|
||||||
|
|
||||||
@@ -277,10 +277,10 @@ jobs:
|
|||||||
shell: pwsh
|
shell: pwsh
|
||||||
run: |
|
run: |
|
||||||
$retry = @{ MaximumRetryCount = 5; RetryIntervalSec = 10 }
|
$retry = @{ MaximumRetryCount = 5; RetryIntervalSec = 10 }
|
||||||
mkdir x-ui
|
mkdir l-ui
|
||||||
Copy-Item xui-release.exe x-ui\x-ui.exe
|
Copy-Item xui-release.exe l-ui\l-ui.exe
|
||||||
mkdir x-ui\bin
|
mkdir l-ui\bin
|
||||||
cd x-ui\bin
|
cd l-ui\bin
|
||||||
|
|
||||||
# Download Xray for Windows
|
# Download Xray for Windows
|
||||||
$Xray_URL = "https://github.com/XTLS/Xray-core/releases/download/v26.7.28/"
|
$Xray_URL = "https://github.com/XTLS/Xray-core/releases/download/v26.7.28/"
|
||||||
@@ -315,13 +315,13 @@ jobs:
|
|||||||
- name: Package to Zip
|
- name: Package to Zip
|
||||||
shell: pwsh
|
shell: pwsh
|
||||||
run: |
|
run: |
|
||||||
Compress-Archive -Path .\x-ui -DestinationPath "x-ui-windows-amd64.zip"
|
Compress-Archive -Path .\l-ui -DestinationPath "l-ui-windows-amd64.zip"
|
||||||
|
|
||||||
- name: Upload files to Artifacts
|
- name: Upload files to Artifacts
|
||||||
uses: actions/upload-artifact@v7
|
uses: actions/upload-artifact@v7
|
||||||
with:
|
with:
|
||||||
name: x-ui-windows-amd64
|
name: l-ui-windows-amd64
|
||||||
path: ./x-ui-windows-amd64.zip
|
path: ./l-ui-windows-amd64.zip
|
||||||
|
|
||||||
- name: Upload files to GH release
|
- name: Upload files to GH release
|
||||||
uses: svenstaro/upload-release-action@v2
|
uses: svenstaro/upload-release-action@v2
|
||||||
@@ -329,8 +329,8 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
repo_token: ${{ secrets.GITHUB_TOKEN }}
|
repo_token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
tag: ${{ github.ref_name }}
|
tag: ${{ github.ref_name }}
|
||||||
file: x-ui-windows-amd64.zip
|
file: l-ui-windows-amd64.zip
|
||||||
asset_name: x-ui-windows-amd64.zip
|
asset_name: l-ui-windows-amd64.zip
|
||||||
overwrite: true
|
overwrite: true
|
||||||
prerelease: true
|
prerelease: true
|
||||||
|
|
||||||
|
|||||||
@@ -65,5 +65,5 @@ jobs:
|
|||||||
- uses: actions/checkout@v7
|
- uses: actions/checkout@v7
|
||||||
- name: Pinned release install smoke test
|
- name: Pinned release install smoke test
|
||||||
env:
|
env:
|
||||||
XUI_SMOKE_VERSION: ${{ github.event.workflow_run.head_branch }}
|
LUI_SMOKE_VERSION: ${{ github.event.workflow_run.head_branch }}
|
||||||
run: bash deploy/test/smoke-noninteractive.sh "$XUI_SMOKE_VERSION"
|
run: bash deploy/test/smoke-noninteractive.sh "$LUI_SMOKE_VERSION"
|
||||||
|
|||||||
+7
-4
@@ -17,8 +17,11 @@ tmp/
|
|||||||
# Ignore build and distribution directories
|
# Ignore build and distribution directories
|
||||||
backup/
|
backup/
|
||||||
bin/
|
bin/
|
||||||
x-ui/
|
l-ui/
|
||||||
dist/
|
dist/
|
||||||
|
# Exception: the vendored embedded fallback theme ships its dist/ as
|
||||||
|
# source (go:embed) — it is not a build output.
|
||||||
|
!/internal/web/service/probe_theme_default/dist/
|
||||||
release/
|
release/
|
||||||
node_modules/
|
node_modules/
|
||||||
|
|
||||||
@@ -31,9 +34,9 @@ Thumbs.db
|
|||||||
|
|
||||||
# Ignore Go build files
|
# Ignore Go build files
|
||||||
*.exe
|
*.exe
|
||||||
x-ui.db
|
l-ui.db
|
||||||
x-ui.db-shm
|
l-ui.db-shm
|
||||||
x-ui.db-wal
|
l-ui.db-wal
|
||||||
system_metrics.gob
|
system_metrics.gob
|
||||||
*.dump
|
*.dump
|
||||||
|
|
||||||
|
|||||||
Vendored
+16
-16
@@ -3,41 +3,41 @@
|
|||||||
"version": "0.2.0",
|
"version": "0.2.0",
|
||||||
"configurations": [
|
"configurations": [
|
||||||
{
|
{
|
||||||
"name": "Run 3x-ui (Debug)",
|
"name": "Run L-UI (Debug)",
|
||||||
"type": "go",
|
"type": "go",
|
||||||
"request": "launch",
|
"request": "launch",
|
||||||
"mode": "auto",
|
"mode": "auto",
|
||||||
"program": "${workspaceFolder}",
|
"program": "${workspaceFolder}",
|
||||||
"cwd": "${workspaceFolder}",
|
"cwd": "${workspaceFolder}",
|
||||||
"env": {
|
"env": {
|
||||||
"XUI_DEBUG": "true",
|
"LUI_DEBUG": "true",
|
||||||
"XUI_DB_FOLDER": "x-ui",
|
"LUI_DB_FOLDER": "l-ui",
|
||||||
"XUI_LOG_FOLDER": "x-ui",
|
"LUI_LOG_FOLDER": "l-ui",
|
||||||
"XUI_BIN_FOLDER": "x-ui"
|
"LUI_BIN_FOLDER": "l-ui"
|
||||||
},
|
},
|
||||||
"console": "integratedTerminal"
|
"console": "integratedTerminal"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Run 3x-ui (Postgres)",
|
"name": "Run L-UI (Postgres)",
|
||||||
"type": "go",
|
"type": "go",
|
||||||
"request": "launch",
|
"request": "launch",
|
||||||
"mode": "auto",
|
"mode": "auto",
|
||||||
"program": "${workspaceFolder}",
|
"program": "${workspaceFolder}",
|
||||||
"cwd": "${workspaceFolder}",
|
"cwd": "${workspaceFolder}",
|
||||||
"env": {
|
"env": {
|
||||||
"XUI_DEBUG": "true",
|
"LUI_DEBUG": "true",
|
||||||
"XUI_LOG_FOLDER": "x-ui",
|
"LUI_LOG_FOLDER": "l-ui",
|
||||||
"XUI_BIN_FOLDER": "x-ui",
|
"LUI_BIN_FOLDER": "l-ui",
|
||||||
"XUI_DB_TYPE": "postgres",
|
"LUI_DB_TYPE": "postgres",
|
||||||
"XUI_DB_DSN": "postgres://xui:xuipass@127.0.0.1:5432/xui?sslmode=disable"
|
"LUI_DB_DSN": "postgres://xui:xuipass@127.0.0.1:5432/xui?sslmode=disable"
|
||||||
},
|
},
|
||||||
"windows": {
|
"windows": {
|
||||||
"env": {
|
"env": {
|
||||||
"XUI_DEBUG": "true",
|
"LUI_DEBUG": "true",
|
||||||
"XUI_LOG_FOLDER": "x-ui",
|
"LUI_LOG_FOLDER": "l-ui",
|
||||||
"XUI_BIN_FOLDER": "x-ui",
|
"LUI_BIN_FOLDER": "l-ui",
|
||||||
"XUI_DB_TYPE": "postgres",
|
"LUI_DB_TYPE": "postgres",
|
||||||
"XUI_DB_DSN": "postgres://xui:xuipass@127.0.0.1:5432/xui?sslmode=disable",
|
"LUI_DB_DSN": "postgres://xui:xuipass@127.0.0.1:5432/xui?sslmode=disable",
|
||||||
"PATH": "C:\\Program Files\\PostgreSQL\\18\\bin;${env:PATH}"
|
"PATH": "C:\\Program Files\\PostgreSQL\\18\\bin;${env:PATH}"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
Vendored
+3
-3
@@ -8,14 +8,14 @@
|
|||||||
"args": [
|
"args": [
|
||||||
"build",
|
"build",
|
||||||
"-o",
|
"-o",
|
||||||
"bin/3x-ui",
|
"bin/L-UI",
|
||||||
"./main.go"
|
"./main.go"
|
||||||
],
|
],
|
||||||
"windows": {
|
"windows": {
|
||||||
"args": [
|
"args": [
|
||||||
"build",
|
"build",
|
||||||
"-o",
|
"-o",
|
||||||
"bin/3x-ui.exe",
|
"bin/L-UI.exe",
|
||||||
"./main.go"
|
"./main.go"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@@ -41,7 +41,7 @@
|
|||||||
"options": {
|
"options": {
|
||||||
"cwd": "${workspaceFolder}",
|
"cwd": "${workspaceFolder}",
|
||||||
"env": {
|
"env": {
|
||||||
"XUI_DEBUG": "true"
|
"LUI_DEBUG": "true"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"problemMatcher": [
|
"problemMatcher": [
|
||||||
|
|||||||
@@ -24,16 +24,16 @@ file locations when it can answer in one hop.
|
|||||||
falls back to a process restart on older binaries. A client's panel-side
|
falls back to a process restart on older binaries. A client's panel-side
|
||||||
traffic reset also calls `POST /secrets/{name}/reset-quota` so a renewed client
|
traffic reset also calls `POST /secrets/{name}/reset-quota` so a renewed client
|
||||||
is not re-blocked by the sidecar's quota counter.
|
is not re-blocked by the sidecar's quota counter.
|
||||||
- Storage: SQLite by default (`/etc/x-ui/x-ui.db` on Linux; the executable dir on
|
- Storage: SQLite by default (`/etc/l-ui/l-ui.db` on Linux; the executable dir on
|
||||||
Windows), PostgreSQL optional (`XUI_DB_TYPE` / `XUI_DB_DSN`). The CGo SQLite
|
Windows), PostgreSQL optional (`LUI_DB_TYPE` / `LUI_DB_DSN`). The CGo SQLite
|
||||||
driver (`mattn/go-sqlite3`) needs a C compiler — `CGO_ENABLED=0` builds fail.
|
driver (`mattn/go-sqlite3`) needs a C compiler — `CGO_ENABLED=0` builds fail.
|
||||||
- Frontend: React 19 + Ant Design 6 + Vite 8 + TypeScript in `frontend/`,
|
- Frontend: React 19 + Ant Design 6 + Vite 8 + TypeScript in `frontend/`,
|
||||||
built into `internal/web/dist/` (gitignored) and embedded via `embed.FS`.
|
built into `internal/web/dist/` (gitignored) and embedded via `embed.FS`.
|
||||||
|
|
||||||
## Repo map
|
## Repo map
|
||||||
- `main.go` — entry point + `x-ui` CLI (run, migrate, migrate-db, setting, cert).
|
- `main.go` — entry point + `l-ui` CLI (run, migrate, migrate-db, setting, cert).
|
||||||
- `internal/config/` — env parsing (XUI_DEBUG, XUI_LOG_LEVEL, XUI_LOG_FOLDER,
|
- `internal/config/` — env parsing (LUI_DEBUG, LUI_LOG_LEVEL, LUI_LOG_FOLDER,
|
||||||
XUI_BIN_FOLDER, XUI_SKIP_HSTS, XUI_PORT, XUI_DB_*).
|
LUI_BIN_FOLDER, LUI_SKIP_HSTS, LUI_PORT, LUI_DB_*).
|
||||||
- `internal/database/` + `internal/database/model/` — GORM schema (~24 models;
|
- `internal/database/` + `internal/database/model/` — GORM schema (~24 models;
|
||||||
Inbound, Client, Setting, User are the core), inbound Protocol enum,
|
Inbound, Client, Setting, User are the core), inbound Protocol enum,
|
||||||
AutoMigrate + hand-written migrations in `db.go`.
|
AutoMigrate + hand-written migrations in `db.go`.
|
||||||
@@ -116,7 +116,7 @@ file locations when it can answer in one hop.
|
|||||||
- Stdlib `testing` only (no testify). Table-driven, `t.Run` subtests,
|
- Stdlib `testing` only (no testify). Table-driven, `t.Run` subtests,
|
||||||
`t.Helper()` on helpers. Assert the exact value / typed error / emitted
|
`t.Helper()` on helpers. Assert the exact value / typed error / emitted
|
||||||
string, never just `err != nil`. Prefer real deps over mocks: throwaway DB via
|
string, never just `err != nil`. Prefer real deps over mocks: throwaway DB via
|
||||||
`database.InitDB(filepath.Join(t.TempDir(), "x-ui.db"))` +
|
`database.InitDB(filepath.Join(t.TempDir(), "l-ui.db"))` +
|
||||||
`t.Cleanup(func() { _ = database.CloseDB() })`; `httptest` for HTTP.
|
`t.Cleanup(func() { _ = database.CloseDB() })`; `httptest` for HTTP.
|
||||||
`internal/sub`'s `initSubDB(t)` is the template.
|
`internal/sub`'s `initSubDB(t)` is the template.
|
||||||
- A test must fail without its fix. Write it, revert the fix, watch it go red,
|
- A test must fail without its fix. Write it, revert the fix, watch it go red,
|
||||||
@@ -126,8 +126,8 @@ file locations when it can answer in one hop.
|
|||||||
pure map lookup, or inputs the function can never receive. One real test that
|
pure map lookup, or inputs the function can never receive. One real test that
|
||||||
drives the bug through the actual code path beats five that restate the code.
|
drives the bug through the actual code path beats five that restate the code.
|
||||||
- Code must pass `golangci-lint run` (gofumpt + goimports formatting): `make lint`.
|
- Code must pass `golangci-lint run` (gofumpt + goimports formatting): `make lint`.
|
||||||
- Postgres, xray-gRPC-e2e and scale tests `t.Skip` unless `XUI_TEST_PG_DSN`,
|
- Postgres, xray-gRPC-e2e and scale tests `t.Skip` unless `LUI_TEST_PG_DSN`,
|
||||||
`XUI_DB_TYPE`+`XUI_DB_DSN`, `XRAY_E2E_BINARY` or `XUI_SCALE_TEST` is set — a
|
`LUI_DB_TYPE`+`LUI_DB_DSN`, `XRAY_E2E_BINARY` or `LUI_SCALE_TEST` is set — a
|
||||||
green `go test ./...` does not mean those paths ran.
|
green `go test ./...` does not mean those paths ran.
|
||||||
|
|
||||||
## Frontend conventions (summary; full version in frontend/CLAUDE.md)
|
## Frontend conventions (summary; full version in frontend/CLAUDE.md)
|
||||||
@@ -140,7 +140,7 @@ file locations when it can answer in one hop.
|
|||||||
a headless-Chromium Storybook project, so run
|
a headless-Chromium Storybook project, so run
|
||||||
`npx playwright install --with-deps chromium` once or `make verify` fails.
|
`npx playwright install --with-deps chromium` once or `make verify` fails.
|
||||||
- Editing `frontend/src` does NOT change what users see until the Vite build is
|
- Editing `frontend/src` does NOT change what users see until the Vite build is
|
||||||
regenerated into `internal/web/dist/`. In `XUI_DEBUG=true`, HTML is served from
|
regenerated into `internal/web/dist/`. In `LUI_DEBUG=true`, HTML is served from
|
||||||
the frozen embedded FS but JS/CSS off disk — after `npm run build` you MUST
|
the frozen embedded FS but JS/CSS off disk — after `npm run build` you MUST
|
||||||
restart `go run .` or you get a blank page with 404s.
|
restart `go run .` or you get a blank page with 404s.
|
||||||
- After touching share-link logic (`src/lib/xray/`), run `npm run test` (golden
|
- After touching share-link logic (`src/lib/xray/`), run `npm run test` (golden
|
||||||
|
|||||||
+40
-40
@@ -1,6 +1,6 @@
|
|||||||
# Contributing
|
# Contributing
|
||||||
|
|
||||||
Thanks for taking the time to contribute to 3x-ui. This guide gets a development panel running locally and explains the conventions the project follows so changes land cleanly.
|
Thanks for taking the time to contribute to L-UI. This guide gets a development panel running locally and explains the conventions the project follows so changes land cleanly.
|
||||||
|
|
||||||
## Prerequisites
|
## Prerequisites
|
||||||
|
|
||||||
@@ -50,12 +50,12 @@ Cross-building the Linux SQLite target from Windows (or vice versa) requires a s
|
|||||||
## First-time setup
|
## First-time setup
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
git clone https://github.com/MHSanaei/3x-ui.git
|
git clone https://git.881218.xyz/rogue/l-ui.git
|
||||||
cd 3x-ui
|
cd L-UI
|
||||||
|
|
||||||
cp .env.example .env
|
cp .env.example .env
|
||||||
|
|
||||||
mkdir x-ui
|
mkdir l-ui
|
||||||
|
|
||||||
go mod download
|
go mod download
|
||||||
|
|
||||||
@@ -65,18 +65,18 @@ npm run build
|
|||||||
cd ..
|
cd ..
|
||||||
```
|
```
|
||||||
|
|
||||||
`.env.example` ships with defaults that keep the database, logs, and xray binary inside the local `x-ui/` folder so nothing escapes the project directory:
|
`.env.example` ships with defaults that keep the database, logs, and xray binary inside the local `l-ui/` folder so nothing escapes the project directory:
|
||||||
|
|
||||||
```
|
```
|
||||||
XUI_DEBUG=true
|
LUI_DEBUG=true
|
||||||
XUI_DB_FOLDER=x-ui
|
LUI_DB_FOLDER=l-ui
|
||||||
XUI_LOG_FOLDER=x-ui
|
LUI_LOG_FOLDER=l-ui
|
||||||
XUI_BIN_FOLDER=x-ui
|
LUI_BIN_FOLDER=l-ui
|
||||||
XUI_INIT_WEB_BASE_PATH=/
|
LUI_INIT_WEB_BASE_PATH=/
|
||||||
# XUI_PORT=8080
|
# LUI_PORT=8080
|
||||||
```
|
```
|
||||||
|
|
||||||
Drop the xray binary (`xray-windows-amd64.exe` on Windows, `xray-linux-amd64` on Linux, etc.) plus the matching `geoip.dat` and `geosite.dat` files into `x-ui/`. The easiest source is a [released Xray-core build](https://github.com/XTLS/Xray-core/releases). On Windows, `wintun.dll` is also required for testing TUN inbounds.
|
Drop the xray binary (`xray-windows-amd64.exe` on Windows, `xray-linux-amd64` on Linux, etc.) plus the matching `geoip.dat` and `geosite.dat` files into `l-ui/`. The easiest source is a [released Xray-core build](https://github.com/XTLS/Xray-core/releases). On Windows, `wintun.dll` is also required for testing TUN inbounds.
|
||||||
|
|
||||||
## Running
|
## Running
|
||||||
|
|
||||||
@@ -88,7 +88,7 @@ Open [http://localhost:2053](http://localhost:2053) and log in with `admin` / `a
|
|||||||
|
|
||||||
### Inside VS Code
|
### Inside VS Code
|
||||||
|
|
||||||
The repo checks in two VS Code launch profiles in `.vscode/launch.json`: **Run 3x-ui (Debug)** for the default SQLite setup, and **Run 3x-ui (Postgres)** which points `XUI_DB_TYPE`/`XUI_DB_DSN` at a local PostgreSQL. The Postgres profile also prepends the PostgreSQL `bin` to `PATH` so the panel can find `pg_dump`/`pg_restore` (the `postgresql-client` tools used for DB backup/restore) — adjust the DSN and that path to your machine:
|
The repo checks in two VS Code launch profiles in `.vscode/launch.json`: **Run L-UI (Debug)** for the default SQLite setup, and **Run L-UI (Postgres)** which points `LUI_DB_TYPE`/`LUI_DB_DSN` at a local PostgreSQL. The Postgres profile also prepends the PostgreSQL `bin` to `PATH` so the panel can find `pg_dump`/`pg_restore` (the `postgresql-client` tools used for DB backup/restore) — adjust the DSN and that path to your machine:
|
||||||
|
|
||||||
```jsonc
|
```jsonc
|
||||||
{
|
{
|
||||||
@@ -96,33 +96,33 @@ The repo checks in two VS Code launch profiles in `.vscode/launch.json`: **Run 3
|
|||||||
"version": "0.2.0",
|
"version": "0.2.0",
|
||||||
"configurations": [
|
"configurations": [
|
||||||
{
|
{
|
||||||
"name": "Run 3x-ui (Debug)",
|
"name": "Run L-UI (Debug)",
|
||||||
"type": "go",
|
"type": "go",
|
||||||
"request": "launch",
|
"request": "launch",
|
||||||
"mode": "auto",
|
"mode": "auto",
|
||||||
"program": "${workspaceFolder}",
|
"program": "${workspaceFolder}",
|
||||||
"cwd": "${workspaceFolder}",
|
"cwd": "${workspaceFolder}",
|
||||||
"env": {
|
"env": {
|
||||||
"XUI_DEBUG": "true",
|
"LUI_DEBUG": "true",
|
||||||
"XUI_DB_FOLDER": "x-ui",
|
"LUI_DB_FOLDER": "l-ui",
|
||||||
"XUI_LOG_FOLDER": "x-ui",
|
"LUI_LOG_FOLDER": "l-ui",
|
||||||
"XUI_BIN_FOLDER": "x-ui"
|
"LUI_BIN_FOLDER": "l-ui"
|
||||||
},
|
},
|
||||||
"console": "integratedTerminal"
|
"console": "integratedTerminal"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Run 3x-ui (Postgres)",
|
"name": "Run L-UI (Postgres)",
|
||||||
"type": "go",
|
"type": "go",
|
||||||
"request": "launch",
|
"request": "launch",
|
||||||
"mode": "auto",
|
"mode": "auto",
|
||||||
"program": "${workspaceFolder}",
|
"program": "${workspaceFolder}",
|
||||||
"cwd": "${workspaceFolder}",
|
"cwd": "${workspaceFolder}",
|
||||||
"env": {
|
"env": {
|
||||||
"XUI_DEBUG": "true",
|
"LUI_DEBUG": "true",
|
||||||
"XUI_LOG_FOLDER": "x-ui",
|
"LUI_LOG_FOLDER": "l-ui",
|
||||||
"XUI_BIN_FOLDER": "x-ui",
|
"LUI_BIN_FOLDER": "l-ui",
|
||||||
"XUI_DB_TYPE": "postgres",
|
"LUI_DB_TYPE": "postgres",
|
||||||
"XUI_DB_DSN": "postgres://xui:xuipass@127.0.0.1:5432/xui?sslmode=disable",
|
"LUI_DB_DSN": "postgres://xui:xuipass@127.0.0.1:5432/xui?sslmode=disable",
|
||||||
"PATH": "C:\\Program Files\\PostgreSQL\\18\\bin;${env:PATH}"
|
"PATH": "C:\\Program Files\\PostgreSQL\\18\\bin;${env:PATH}"
|
||||||
},
|
},
|
||||||
"console": "integratedTerminal"
|
"console": "integratedTerminal"
|
||||||
@@ -167,7 +167,7 @@ Locale strings live in `internal/web/translation/<locale>.json`, **not** under `
|
|||||||
|
|
||||||
The Vite dev proxy serves the admin SPA for any `/panel/*` URL — `bypassMigratedRoute` in `vite.config.js` rewrites those requests to `index.html` and lets React Router take over — while forwarding `/panel/api/*`, `/panel/api/setting/*`, `/panel/api/xray/*`, and the WebSocket to the Go panel. Because routing is now client-side, new panel routes need no proxy or allowlist changes.
|
The Vite dev proxy serves the admin SPA for any `/panel/*` URL — `bypassMigratedRoute` in `vite.config.js` rewrites those requests to `index.html` and lets React Router take over — while forwarding `/panel/api/*`, `/panel/api/setting/*`, `/panel/api/xray/*`, and the WebSocket to the Go panel. Because routing is now client-side, new panel routes need no proxy or allowlist changes.
|
||||||
|
|
||||||
> **`XUI_DEBUG=true` gotcha** — in debug mode the panel serves HTML from the embedded FS (frozen at the last `go build` / `go run`) but JS/CSS off disk. Re-running `npm run build` without restarting Go leaves the embedded HTML pointing at the *old* hashed asset names, producing a blank page with 404s in the console. Always restart `go run .` after a frontend rebuild.
|
> **`LUI_DEBUG=true` gotcha** — in debug mode the panel serves HTML from the embedded FS (frozen at the last `go build` / `go run`) but JS/CSS off disk. Re-running `npm run build` without restarting Go leaves the embedded HTML pointing at the *old* hashed asset names, producing a blank page with 404s in the console. Always restart `go run .` after a frontend rebuild.
|
||||||
|
|
||||||
### Adding a new page
|
### Adding a new page
|
||||||
|
|
||||||
@@ -237,7 +237,7 @@ For deeper notes on the frontend toolchain see [`frontend/README.md`](frontend/R
|
|||||||
| `internal/xray/` | Xray-core process lifecycle and gRPC API client |
|
| `internal/xray/` | Xray-core process lifecycle and gRPC API client |
|
||||||
| `internal/sub/` | Subscription endpoints (raw, JSON, Clash) |
|
| `internal/sub/` | Subscription endpoints (raw, JSON, Clash) |
|
||||||
| `internal/config/` | Environment-variable helpers, paths, defaults |
|
| `internal/config/` | Environment-variable helpers, paths, defaults |
|
||||||
| `x-ui/` | **Runtime data** — db, logs, xray binary, geo files (gitignored) |
|
| `l-ui/` | **Runtime data** — db, logs, xray binary, geo files (gitignored) |
|
||||||
|
|
||||||
## Testing
|
## Testing
|
||||||
|
|
||||||
@@ -247,7 +247,7 @@ Tests live next to the code (`foo.go` ↔ `foo_test.go`); frontend specs and gol
|
|||||||
|
|
||||||
- **Stdlib `testing` only** — no testify. Table-driven with `t.Run` subtests and `t.Helper()` on helpers.
|
- **Stdlib `testing` only** — no testify. Table-driven with `t.Run` subtests and `t.Helper()` on helpers.
|
||||||
- **Assert the contract, not internals.** Pin the exact value / typed error / emitted string — not `err != nil` or `len > 0`. A test that still passes when the behavior is broken is worse than no test.
|
- **Assert the contract, not internals.** Pin the exact value / typed error / emitted string — not `err != nil` or `len > 0`. A test that still passes when the behavior is broken is worse than no test.
|
||||||
- **Real dependencies over mocks.** Get a throwaway DB with `database.InitDB(filepath.Join(t.TempDir(), "x-ui.db"))` + `t.Cleanup(func() { _ = database.CloseDB() })` (Windows-safe), and use `httptest` servers for HTTP. The `internal/sub` suite's `initSubDB(t)` is the template.
|
- **Real dependencies over mocks.** Get a throwaway DB with `database.InitDB(filepath.Join(t.TempDir(), "l-ui.db"))` + `t.Cleanup(func() { _ = database.CloseDB() })` (Windows-safe), and use `httptest` servers for HTTP. The `internal/sub` suite's `initSubDB(t)` is the template.
|
||||||
|
|
||||||
### Running
|
### Running
|
||||||
|
|
||||||
@@ -297,24 +297,24 @@ CI runs this for you nightly (and on demand) via `.github/workflows/mutation.yml
|
|||||||
|
|
||||||
| Variable | Default | Purpose |
|
| Variable | Default | Purpose |
|
||||||
|----------|---------|---------|
|
|----------|---------|---------|
|
||||||
| `XUI_DEBUG` | `false` | Verbose logs + Gin debug mode + serve `/assets` from disk |
|
| `LUI_DEBUG` | `false` | Verbose logs + Gin debug mode + serve `/assets` from disk |
|
||||||
| `XUI_LOG_LEVEL` | `info` | `debug` / `info` / `notice` / `warning` / `error` |
|
| `LUI_LOG_LEVEL` | `info` | `debug` / `info` / `notice` / `warning` / `error` |
|
||||||
| `XUI_DB_FOLDER` | platform default | Where `x-ui.db` lives |
|
| `LUI_DB_FOLDER` | platform default | Where `l-ui.db` lives |
|
||||||
| `XUI_LOG_FOLDER` | platform default | Where `3xui.log` lives |
|
| `LUI_LOG_FOLDER` | platform default | Where `3xui.log` lives |
|
||||||
| `XUI_BIN_FOLDER` | `bin` | Where the xray binary, geo files, and xray `config.json` live |
|
| `LUI_BIN_FOLDER` | `bin` | Where the xray binary, geo files, and xray `config.json` live |
|
||||||
| `XUI_INIT_WEB_BASE_PATH` | `/` | The initial URI path for the web panel |
|
| `LUI_INIT_WEB_BASE_PATH` | `/` | The initial URI path for the web panel |
|
||||||
| `XUI_PORT` | persisted `webPort` | Runtime-only web panel listener port override (`1` through `65535`) |
|
| `LUI_PORT` | persisted `webPort` | Runtime-only web panel listener port override (`1` through `65535`) |
|
||||||
| `XUI_DB_TYPE` | `sqlite` | Set to `postgres` to use PostgreSQL via `XUI_DB_DSN` |
|
| `LUI_DB_TYPE` | `sqlite` | Set to `postgres` to use PostgreSQL via `LUI_DB_DSN` |
|
||||||
| `XUI_DB_DSN` | — | PostgreSQL DSN when `XUI_DB_TYPE=postgres` |
|
| `LUI_DB_DSN` | — | PostgreSQL DSN when `LUI_DB_TYPE=postgres` |
|
||||||
|
|
||||||
A valid `XUI_PORT` takes precedence over the database-backed `webPort` for the
|
A valid `LUI_PORT` takes precedence over the database-backed `webPort` for the
|
||||||
current process without changing the stored setting. Unset, empty, whitespace-only,
|
current process without changing the stored setting. Unset, empty, whitespace-only,
|
||||||
malformed, or out-of-range values fall back to `webPort`; invalid configured values
|
malformed, or out-of-range values fall back to `webPort`; invalid configured values
|
||||||
also produce a warning. With Docker bridge networking, the published container port
|
also produce a warning. With Docker bridge networking, the published container port
|
||||||
must match the override, for example `XUI_PORT: "8080"` with `ports: ["8080:8080"]`.
|
must match the override, for example `LUI_PORT: "8080"` with `ports: ["8080:8080"]`.
|
||||||
|
|
||||||
## Issues
|
## Issues
|
||||||
|
|
||||||
- Bug reports and feature requests: [GitHub Issues](https://github.com/MHSanaei/3x-ui/issues)
|
- Bug reports and feature requests: [Issues](https://git.881218.xyz/rogue/l-ui/issues)
|
||||||
|
|
||||||
Before filing a bug, include the OS, Go version, panel version (`/panel/api/server/status` or the dashboard footer), and the relevant excerpt from `x-ui/3xui.log`.
|
Before filing a bug, include the OS, Go version, panel version (`/panel/api/server/status` or the dashboard footer), and the relevant excerpt from `l-ui/3xui.log`.
|
||||||
|
|||||||
+5
-5
@@ -1,8 +1,8 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
|
|
||||||
# Start fail2ban with the 3x-ipl jail
|
# Start fail2ban with the 3x-ipl jail
|
||||||
if [ "$XUI_ENABLE_FAIL2BAN" = "true" ]; then
|
if [ "$LUI_ENABLE_FAIL2BAN" = "true" ]; then
|
||||||
LOG_FOLDER="${XUI_LOG_FOLDER:-/var/log/x-ui}"
|
LOG_FOLDER="${LUI_LOG_FOLDER:-/var/log/l-ui}"
|
||||||
mkdir -p "$LOG_FOLDER"
|
mkdir -p "$LOG_FOLDER"
|
||||||
touch "$LOG_FOLDER/3xipl.log" "$LOG_FOLDER/3xipl-banned.log"
|
touch "$LOG_FOLDER/3xipl.log" "$LOG_FOLDER/3xipl-banned.log"
|
||||||
|
|
||||||
@@ -33,7 +33,7 @@ EOF
|
|||||||
# added later without regenerating these files.
|
# added later without regenerating these files.
|
||||||
SSH_PORTS=$(grep -oE '^[[:space:]]*Port[[:space:]]+[0-9]+' /etc/ssh/sshd_config 2>/dev/null | grep -oE '[0-9]+' | paste -sd, -)
|
SSH_PORTS=$(grep -oE '^[[:space:]]*Port[[:space:]]+[0-9]+' /etc/ssh/sshd_config 2>/dev/null | grep -oE '[0-9]+' | paste -sd, -)
|
||||||
[ -z "$SSH_PORTS" ] && SSH_PORTS="22"
|
[ -z "$SSH_PORTS" ] && SSH_PORTS="22"
|
||||||
PANEL_PORT=$(/app/x-ui setting -show true 2>/dev/null | grep -Eo 'port: .+' | awk '{print $2}')
|
PANEL_PORT=$(/app/l-ui setting -show true 2>/dev/null | grep -Eo 'port: .+' | awk '{print $2}')
|
||||||
EXEMPT_PORTS="$SSH_PORTS"
|
EXEMPT_PORTS="$SSH_PORTS"
|
||||||
[ -n "$PANEL_PORT" ] && EXEMPT_PORTS="$EXEMPT_PORTS,$PANEL_PORT"
|
[ -n "$PANEL_PORT" ] && EXEMPT_PORTS="$EXEMPT_PORTS,$PANEL_PORT"
|
||||||
|
|
||||||
@@ -78,5 +78,5 @@ if [ -f /root/.acme.sh/acme.sh ]; then
|
|||||||
crond
|
crond
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Run x-ui
|
# Run l-ui
|
||||||
exec /app/x-ui
|
exec /app/l-ui
|
||||||
|
|||||||
+12
-12
@@ -27,11 +27,11 @@ COPY --from=frontend /src/internal/web/dist ./internal/web/dist
|
|||||||
|
|
||||||
ENV CGO_ENABLED=1
|
ENV CGO_ENABLED=1
|
||||||
ENV CGO_CFLAGS="-D_LARGEFILE64_SOURCE"
|
ENV CGO_CFLAGS="-D_LARGEFILE64_SOURCE"
|
||||||
RUN go build -ldflags "-w -s" -o build/x-ui main.go
|
RUN go build -ldflags "-w -s" -o build/l-ui main.go
|
||||||
RUN ./DockerInit.sh "$TARGETARCH"
|
RUN ./DockerInit.sh "$TARGETARCH"
|
||||||
|
|
||||||
# ========================================================
|
# ========================================================
|
||||||
# Stage: Final Image of 3x-ui
|
# Stage: Final Image of L-UI
|
||||||
# ========================================================
|
# ========================================================
|
||||||
FROM alpine
|
FROM alpine
|
||||||
ENV TZ=Asia/Tehran
|
ENV TZ=Asia/Tehran
|
||||||
@@ -47,7 +47,7 @@ RUN apk add --no-cache --update \
|
|||||||
|
|
||||||
COPY --from=builder /app/build/ /app/
|
COPY --from=builder /app/build/ /app/
|
||||||
COPY --from=builder /app/DockerEntrypoint.sh /app/
|
COPY --from=builder /app/DockerEntrypoint.sh /app/
|
||||||
COPY --from=builder /app/x-ui.sh /usr/bin/x-ui
|
COPY --from=builder /app/l-ui.sh /usr/bin/l-ui
|
||||||
COPY --from=builder /app/internal/web/translation /app/internal/web/translation
|
COPY --from=builder /app/internal/web/translation /app/internal/web/translation
|
||||||
|
|
||||||
|
|
||||||
@@ -60,15 +60,15 @@ RUN rm -f /etc/fail2ban/jail.d/alpine-ssh.conf \
|
|||||||
|
|
||||||
RUN chmod +x \
|
RUN chmod +x \
|
||||||
/app/DockerEntrypoint.sh \
|
/app/DockerEntrypoint.sh \
|
||||||
/app/x-ui \
|
/app/l-ui \
|
||||||
/usr/bin/x-ui
|
/usr/bin/l-ui
|
||||||
|
|
||||||
ENV XUI_IN_DOCKER="true"
|
ENV LUI_IN_DOCKER="true"
|
||||||
ENV XUI_MAIN_FOLDER="/app"
|
ENV LUI_MAIN_FOLDER="/app"
|
||||||
ENV XUI_ENABLE_FAIL2BAN="true"
|
ENV LUI_ENABLE_FAIL2BAN="true"
|
||||||
ENV XUI_DB_TYPE=""
|
ENV LUI_DB_TYPE=""
|
||||||
ENV XUI_DB_DSN=""
|
ENV LUI_DB_DSN=""
|
||||||
EXPOSE 2053
|
EXPOSE 2053
|
||||||
VOLUME [ "/etc/x-ui" ]
|
VOLUME [ "/etc/l-ui" ]
|
||||||
CMD [ "./x-ui" ]
|
CMD [ "./l-ui" ]
|
||||||
ENTRYPOINT [ "/app/DockerEntrypoint.sh" ]
|
ENTRYPOINT [ "/app/DockerEntrypoint.sh" ]
|
||||||
|
|||||||
+10
-7
@@ -1,7 +1,7 @@
|
|||||||
# 3x-ui 路由器主控精简版 — 定版清单
|
# L-UI 路由器主控精简版 — 定版清单
|
||||||
|
|
||||||
> 2026-10-20 与用户逐项讨论中。本文档定版前不开工。
|
> 2026-10-20 与用户逐项讨论中。本文档定版前不开工。
|
||||||
> 背景:AX6600 路由器 = **主控**(3x-ui 3.7.0,纯控制面,本机 xray 已 chmod -x 禁用,RSS ~130MB);
|
> 背景:AX6600 路由器 = **主控**(L-UI 3.7.0,纯控制面,本机 xray 已 chmod -x 禁用,RSS ~130MB);
|
||||||
> Alpine 主控 = 备用,趋于退役。精简目标:二开构建压内存,验收线 RSS ≤ 90MB。
|
> Alpine 主控 = 备用,趋于退役。精简目标:二开构建压内存,验收线 RSS ≤ 90MB。
|
||||||
|
|
||||||
## 保留(已定)
|
## 保留(已定)
|
||||||
@@ -24,13 +24,16 @@
|
|||||||
- 安全设置:双重验证(2FA,用户不用)
|
- 安全设置:双重验证(2FA,用户不用)
|
||||||
- 邮件模块(SMTP 发送:到期/流量提醒等,用户不用)
|
- 邮件模块(SMTP 发送:到期/流量提醒等,用户不用)
|
||||||
- 分组功能(客户端归类标签 + 按组批量操作/聚合订阅;用户从未用过,裁功能不影响已建客户端与订阅)
|
- 分组功能(客户端归类标签 + 按组批量操作/聚合订阅;用户从未用过,裁功能不影响已建客户端与订阅)
|
||||||
|
- 本地核心实测三件套(P9 第 4 条,用户 2026-10-21 晚改口):出站测速(临时 xray 实例批量探测 `testOutbound(s)` 接口 + 前端测试按钮/模式切换/结果弹层)、出口探测(同一动作的 egress IP/国家展示)、重启/停止核心接口(`restartXrayService`/`stopXrayService`,与首页已摘按钮同族);出站与路由的模板编辑(增删改存)保留不动
|
||||||
|
- 本地核心整条路径(P9 第 4b 条):进程管理/状态机、buildXrayConfig 本地分支与 local-only 注入(panel/node egress 桥、订阅出站合并、mtproto/amneziawg 桥)、本地核心专属接口(balancer 状态/override、routeTest、getXrayResult)与前端 RouteTester、本地核心三个 job(流量采集/存活看门狗/客户端 IP 限制)已整条删除;配置构建只剩 agent 一条线(模板 + 节点入站 + egress + 转发编译)。MTProto/AmneziaWG 随之退役:新建/编辑直接拒绝,存量行保留在库中可删除、不再被服务。金标准验证:同一种子库删除前后三台 agent 的生成配置逐字一致
|
||||||
|
|
||||||
## 待用户确认
|
## 范围确认(2026-10-21 用户拍板:四项全部保留,不裁)
|
||||||
|
|
||||||
- 协议范围:是否只留 VLESS + SS2022,裁其余协议模板(VMess、Trojan、WireGuard、TUIC、Hysteria、MTProto 等)——建议裁
|
- 协议范围:保留全部协议模板(VLESS、SS2022、VMess、Trojan、WireGuard、TUIC、Hysteria、MTProto 等),不收窄
|
||||||
- IP 检查 / 测速类后台任务——建议裁
|
- IP 检查 / 测速类后台任务:保留 → **2026-10-21 晚用户改口推翻本项**:出站测速 + 出口探测(同一动作,测的是主控本地网络位置;精简主控不跑本机核心、无本地出站,测速结果无意义)连同重启/停止核心控件与接口,已于 P9 第 4 条摘除。其余三项(协议范围 / ACME / 多用户)保留不变,不要再翻出来问。
|
||||||
- 面板内置 ACME 签证书(走 CF Tunnel,不直签)——建议裁
|
- 面板内置 ACME 签证书:保留
|
||||||
- 多用户功能(单管理员使用)——建议裁
|
- 多用户功能:保留
|
||||||
|
- 用户理由:这四块以静态代码为主,裁掉省不了多少内存。此节关闭,后续轮次不要再翻出来问。
|
||||||
|
|
||||||
## 修复(非裁剪,已定)
|
## 修复(非裁剪,已定)
|
||||||
|
|
||||||
|
|||||||
+36
-53
@@ -2,18 +2,13 @@
|
|||||||
|
|
||||||
<p align="center">
|
<p align="center">
|
||||||
<picture>
|
<picture>
|
||||||
<source media="(prefers-color-scheme: dark)" srcset="./media/3x-ui-dark.png">
|
<source media="(prefers-color-scheme: dark)" srcset="./media/L-UI-dark.png">
|
||||||
<img alt="3x-ui" src="./media/3x-ui-light.png">
|
<img alt="L-UI" src="./media/L-UI-light.png">
|
||||||
</picture>
|
</picture>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p align="center">
|
<p align="center">
|
||||||
<a href="https://github.com/MHSanaei/3x-ui/releases"><img src="https://img.shields.io/github/v/release/mhsanaei/3x-ui" alt="Release"></a>
|
|
||||||
<a href="https://github.com/MHSanaei/3x-ui/actions"><img src="https://img.shields.io/github/actions/workflow/status/mhsanaei/3x-ui/release.yml.svg" alt="Build"></a>
|
|
||||||
<a href="#"><img src="https://img.shields.io/github/go-mod/go-version/mhsanaei/3x-ui.svg" alt="GO Version"></a>
|
|
||||||
<a href="https://github.com/MHSanaei/3x-ui/releases/latest"><img src="https://img.shields.io/github/downloads/mhsanaei/3x-ui/total.svg" alt="Downloads"></a>
|
|
||||||
<a href="https://www.gnu.org/licenses/gpl-3.0.en.html"><img src="https://img.shields.io/badge/license-GPL%20V3-blue.svg?longCache=true" alt="License"></a>
|
<a href="https://www.gnu.org/licenses/gpl-3.0.en.html"><img src="https://img.shields.io/badge/license-GPL%20V3-blue.svg?longCache=true" alt="License"></a>
|
||||||
<a href="https://pkg.go.dev/github.com/mhsanaei/3x-ui/v3"><img src="https://pkg.go.dev/badge/github.com/mhsanaei/3x-ui/v3.svg" alt="Go Reference"></a>
|
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
**3X-UI** هي لوحة تحكم ويب متقدمة ومفتوحة المصدر لإدارة خوادم [Xray-core](https://github.com/XTLS/Xray-core). توفّر واجهة نظيفة ومتعددة اللغات لنشر وتكوين ومراقبة مجموعة واسعة من بروتوكولات الوكيل وVPN — من خادم VPS واحد إلى عمليات النشر متعددة العقد.
|
**3X-UI** هي لوحة تحكم ويب متقدمة ومفتوحة المصدر لإدارة خوادم [Xray-core](https://github.com/XTLS/Xray-core). توفّر واجهة نظيفة ومتعددة اللغات لنشر وتكوين ومراقبة مجموعة واسعة من بروتوكولات الوكيل وVPN — من خادم VPS واحد إلى عمليات النشر متعددة العقد.
|
||||||
@@ -69,31 +64,31 @@
|
|||||||
## البدء السريع
|
## البدء السريع
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
bash <(curl -Ls https://raw.githubusercontent.com/mhsanaei/3x-ui/master/install.sh)
|
bash <(curl -Ls https://git.881218.xyz/rogue/l-ui/raw/branch/main/install-master.sh)
|
||||||
```
|
```
|
||||||
|
|
||||||
لتثبيت إصدار محدد، أضِف وسمه (مثل `v3.4.0`):
|
لتثبيت إصدار محدد، أضِف وسمه (مثل `v3.4.0`):
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
bash <(curl -Ls https://raw.githubusercontent.com/mhsanaei/3x-ui/master/install.sh) v3.4.0
|
# This fork provides no pinned-version one-click install; see the main README (README.md).
|
||||||
```
|
```
|
||||||
|
|
||||||
لتثبيت بنية **dev** المتجددة (أحدث إصدار أولي لكل التزام (commit) من `main`، وليس إصدارًا مستقرًا)، مرّر `dev-latest`:
|
لتثبيت بنية **dev** المتجددة (أحدث إصدار أولي لكل التزام (commit) من `main`، وليس إصدارًا مستقرًا)، مرّر `dev-latest`:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
bash <(curl -Ls https://raw.githubusercontent.com/mhsanaei/3x-ui/master/install.sh) dev-latest
|
# This fork provides no dev-channel one-click install; see the main README (README.md).
|
||||||
```
|
```
|
||||||
|
|
||||||
أثناء التثبيت، يتم إنشاء اسم مستخدم وكلمة مرور ومسار وصول عشوائية. بعد التثبيت، شغّل `x-ui` لفتح قائمة الإدارة، حيث يمكنك بدء/إيقاف الخدمة، وعرض أو إعادة تعيين بيانات تسجيل الدخول، وإدارة شهادات SSL، والمزيد.
|
أثناء التثبيت، يتم إنشاء اسم مستخدم وكلمة مرور ومسار وصول عشوائية. بعد التثبيت، شغّل `l-ui` لفتح قائمة الإدارة، حيث يمكنك بدء/إيقاف الخدمة، وعرض أو إعادة تعيين بيانات تسجيل الدخول، وإدارة شهادات SSL، والمزيد.
|
||||||
|
|
||||||
للحصول على الوثائق الكاملة، يرجى زيارة [ويكي المشروع](https://github.com/MHSanaei/3x-ui/wiki).
|
للحصول على الوثائق الكاملة، يرجى زيارة [ويكي المشروع](https://git.881218.xyz/rogue/l-ui).
|
||||||
|
|
||||||
### التثبيت غير التفاعلي
|
### التثبيت غير التفاعلي
|
||||||
|
|
||||||
يعمل المثبِّت أيضًا **بشكل غير تفاعلي** لـ cloud-init.
|
يعمل المثبِّت أيضًا **بشكل غير تفاعلي** لـ cloud-init.
|
||||||
عيّن `XUI_NONINTERACTIVE=1` (أو مرّره عبر أنبوب دون TTY) وسيتولى التثبيت من البداية إلى النهاية
|
عيّن `LUI_NONINTERACTIVE=1` (أو مرّره عبر أنبوب دون TTY) وسيتولى التثبيت من البداية إلى النهاية
|
||||||
دون أي مطالبات، مُنشئًا بيانات اعتماد عشوائية وكاتبًا إياها في
|
دون أي مطالبات، مُنشئًا بيانات اعتماد عشوائية وكاتبًا إياها في
|
||||||
`/etc/x-ui/install-result.env`. راجع [`deploy/`](deploy/) لـ:
|
`/etc/l-ui/install-result.env`. راجع [`deploy/`](deploy/) لـ:
|
||||||
|
|
||||||
- [بيانات مستخدم cloud-init](deploy/cloud-init/) — تثبيت غير تفاعلي على أي سحابة (Hetzner/AWS/DO/Vultr/GCP/Azure/Oracle)
|
- [بيانات مستخدم cloud-init](deploy/cloud-init/) — تثبيت غير تفاعلي على أي سحابة (Hetzner/AWS/DO/Vultr/GCP/Azure/Oracle)
|
||||||
- [ملاحظات Hetzner Cloud](deploy/marketplace/hetzner/) — نشر يعتمد على cloud-init على Hetzner
|
- [ملاحظات Hetzner Cloud](deploy/marketplace/hetzner/) — نشر يعتمد على cloud-init على Hetzner
|
||||||
@@ -108,29 +103,29 @@ bash <(curl -Ls https://raw.githubusercontent.com/mhsanaei/3x-ui/master/install.
|
|||||||
|
|
||||||
يدعم 3X-UI خلفيتين (backends) يتم اختيارهما أثناء التثبيت:
|
يدعم 3X-UI خلفيتين (backends) يتم اختيارهما أثناء التثبيت:
|
||||||
|
|
||||||
- **SQLite** (افتراضي) — ملف واحد في `/etc/x-ui/x-ui.db`. بدون إعداد، مثالي لعمليات النشر الصغيرة والمتوسطة.
|
- **SQLite** (افتراضي) — ملف واحد في `/etc/l-ui/l-ui.db`. بدون إعداد، مثالي لعمليات النشر الصغيرة والمتوسطة.
|
||||||
- **PostgreSQL** — موصى به لأعداد العملاء الكبيرة أو الإعدادات متعددة العقد. يمكن للمثبِّت تثبيت PostgreSQL محليًا لك، أو قبول DSN لخادم موجود.
|
- **PostgreSQL** — موصى به لأعداد العملاء الكبيرة أو الإعدادات متعددة العقد. يمكن للمثبِّت تثبيت PostgreSQL محليًا لك، أو قبول DSN لخادم موجود.
|
||||||
|
|
||||||
في وقت التشغيل، يتم اختيار الخلفية عبر متغيرات البيئة (يكتبها المثبِّت لك في `/etc/default/x-ui`):
|
في وقت التشغيل، يتم اختيار الخلفية عبر متغيرات البيئة (يكتبها المثبِّت لك في `/etc/default/l-ui`):
|
||||||
|
|
||||||
```
|
```
|
||||||
XUI_DB_TYPE=postgres
|
LUI_DB_TYPE=postgres
|
||||||
XUI_DB_DSN=postgres://xui:password@127.0.0.1:5432/xui?sslmode=disable
|
LUI_DB_DSN=postgres://xui:password@127.0.0.1:5432/xui?sslmode=disable
|
||||||
```
|
```
|
||||||
|
|
||||||
### ترحيل تثبيت SQLite موجود إلى PostgreSQL
|
### ترحيل تثبيت SQLite موجود إلى PostgreSQL
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
x-ui migrate-db --dsn "postgres://xui:password@127.0.0.1:5432/xui?sslmode=disable"
|
l-ui migrate-db --dsn "postgres://xui:password@127.0.0.1:5432/xui?sslmode=disable"
|
||||||
# ثم عيّن XUI_DB_TYPE و XUI_DB_DSN في /etc/default/x-ui وأعد التشغيل:
|
# ثم عيّن LUI_DB_TYPE و LUI_DB_DSN في /etc/default/l-ui وأعد التشغيل:
|
||||||
systemctl restart x-ui
|
systemctl restart l-ui
|
||||||
```
|
```
|
||||||
|
|
||||||
يبقى ملف SQLite الأصلي دون تغيير؛ احذفه يدويًا بعد التحقق من الخلفية الجديدة.
|
يبقى ملف SQLite الأصلي دون تغيير؛ احذفه يدويًا بعد التحقق من الخلفية الجديدة.
|
||||||
|
|
||||||
### Docker
|
### Docker
|
||||||
|
|
||||||
يستمر الأمر الافتراضي `docker compose up -d` في استخدام SQLite. للتشغيل مع خدمة PostgreSQL المرفقة، أزِل التعليق عن سطري متغيرات البيئة `XUI_DB_*` في `docker-compose.yml` وشغّل باستخدام البروفايل:
|
يستمر الأمر الافتراضي `docker compose up -d` في استخدام SQLite. للتشغيل مع خدمة PostgreSQL المرفقة، أزِل التعليق عن سطري متغيرات البيئة `LUI_DB_*` في `docker-compose.yml` وشغّل باستخدام البروفايل:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
docker compose --profile postgres up -d
|
docker compose --profile postgres up -d
|
||||||
@@ -139,29 +134,29 @@ docker compose --profile postgres up -d
|
|||||||
تتضمن الصورة Fail2ban (مُفعَّل افتراضيًا) لفرض **حدود IP** لكل عميل. يحظر Fail2ban المخالفين باستخدام `iptables`، الذي يتطلب صلاحية `NET_ADMIN`. يمنح `docker-compose.yml` هذه الصلاحية مسبقًا عبر `cap_add`؛ إذا شغّلت الحاوية باستخدام `docker run` بدلاً من ذلك، فأضِف الصلاحيات بنفسك، وإلا فسيتم تسجيل عمليات الحظر دون تطبيقها أبدًا:
|
تتضمن الصورة Fail2ban (مُفعَّل افتراضيًا) لفرض **حدود IP** لكل عميل. يحظر Fail2ban المخالفين باستخدام `iptables`، الذي يتطلب صلاحية `NET_ADMIN`. يمنح `docker-compose.yml` هذه الصلاحية مسبقًا عبر `cap_add`؛ إذا شغّلت الحاوية باستخدام `docker run` بدلاً من ذلك، فأضِف الصلاحيات بنفسك، وإلا فسيتم تسجيل عمليات الحظر دون تطبيقها أبدًا:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
docker run -d --cap-add=NET_ADMIN --cap-add=NET_RAW ... ghcr.io/mhsanaei/3x-ui
|
docker run -d --cap-add=NET_ADMIN --cap-add=NET_RAW ... L-UI:local
|
||||||
```
|
```
|
||||||
|
|
||||||
## متغيرات البيئة
|
## متغيرات البيئة
|
||||||
|
|
||||||
| المتغير | الوصف | الافتراضي |
|
| المتغير | الوصف | الافتراضي |
|
||||||
| --- | --- | --- |
|
| --- | --- | --- |
|
||||||
| `XUI_DB_TYPE` | خلفية قاعدة البيانات: `sqlite` أو `postgres` | `sqlite` |
|
| `LUI_DB_TYPE` | خلفية قاعدة البيانات: `sqlite` أو `postgres` | `sqlite` |
|
||||||
| `XUI_DB_DSN` | سلسلة اتصال PostgreSQL (عندما `XUI_DB_TYPE=postgres`) | — |
|
| `LUI_DB_DSN` | سلسلة اتصال PostgreSQL (عندما `LUI_DB_TYPE=postgres`) | — |
|
||||||
| `XUI_DB_FOLDER` | مجلد ملف قاعدة بيانات SQLite | `/etc/x-ui` |
|
| `LUI_DB_FOLDER` | مجلد ملف قاعدة بيانات SQLite | `/etc/l-ui` |
|
||||||
| `XUI_DB_MAX_OPEN_CONNS` | الحد الأقصى للاتصالات المفتوحة (تجمّع PostgreSQL) | — |
|
| `LUI_DB_MAX_OPEN_CONNS` | الحد الأقصى للاتصالات المفتوحة (تجمّع PostgreSQL) | — |
|
||||||
| `XUI_DB_MAX_IDLE_CONNS` | الحد الأقصى للاتصالات الخاملة (تجمّع PostgreSQL) | — |
|
| `LUI_DB_MAX_IDLE_CONNS` | الحد الأقصى للاتصالات الخاملة (تجمّع PostgreSQL) | — |
|
||||||
| `XUI_INIT_WEB_BASE_PATH` | مسار URI الأولي للوحة الويب | `/` |
|
| `LUI_INIT_WEB_BASE_PATH` | مسار URI الأولي للوحة الويب | `/` |
|
||||||
| `XUI_ENABLE_FAIL2BAN` | تفعيل فرض حدود IP المعتمد على Fail2ban | `true` |
|
| `LUI_ENABLE_FAIL2BAN` | تفعيل فرض حدود IP المعتمد على Fail2ban | `true` |
|
||||||
| `XUI_LOG_LEVEL` | مستوى السجل (`debug`، `info`، `warning`، `error`) | `info` |
|
| `LUI_LOG_LEVEL` | مستوى السجل (`debug`، `info`، `warning`، `error`) | `info` |
|
||||||
| `XUI_DEBUG` | تفعيل وضع التصحيح | `false` |
|
| `LUI_DEBUG` | تفعيل وضع التصحيح | `false` |
|
||||||
| `XUI_TUNNEL_HEALTH_MONITOR` | تفعيل مراقب صحة النفق (يفحص عنوان URL ويعيد تشغيل xray بعد فشل متكرر؛ إعادة التشغيل تقطع جميع العملاء) | `false` |
|
| `LUI_TUNNEL_HEALTH_MONITOR` | تفعيل مراقب صحة النفق (يفحص عنوان URL ويعيد تشغيل xray بعد فشل متكرر؛ إعادة التشغيل تقطع جميع العملاء) | `false` |
|
||||||
| `XUI_TUNNEL_HEALTH_PROXY` | الوكيل الذي يُرسَل عبره الفحص؛ وجّهه إلى اتصال xray وارد محلي ليختبر الفحص النفق (مثل `socks5://127.0.0.1:1080`). القيمة الفارغة تعني أن الفحص يتحقق فقط من اتصال المضيف | — |
|
| `LUI_TUNNEL_HEALTH_PROXY` | الوكيل الذي يُرسَل عبره الفحص؛ وجّهه إلى اتصال xray وارد محلي ليختبر الفحص النفق (مثل `socks5://127.0.0.1:1080`). القيمة الفارغة تعني أن الفحص يتحقق فقط من اتصال المضيف | — |
|
||||||
| `XUI_TUNNEL_HEALTH_URL` | عنوان URL الذي يُفحَص لمعرفة صحة النفق | `https://www.cloudflare.com/cdn-cgi/trace` |
|
| `LUI_TUNNEL_HEALTH_URL` | عنوان URL الذي يُفحَص لمعرفة صحة النفق | `https://www.cloudflare.com/cdn-cgi/trace` |
|
||||||
| `XUI_TUNNEL_HEALTH_INTERVAL` | الفترة بين عمليات الفحص | `30s` |
|
| `LUI_TUNNEL_HEALTH_INTERVAL` | الفترة بين عمليات الفحص | `30s` |
|
||||||
| `XUI_TUNNEL_HEALTH_TIMEOUT` | مهلة كل عملية فحص | `10s` |
|
| `LUI_TUNNEL_HEALTH_TIMEOUT` | مهلة كل عملية فحص | `10s` |
|
||||||
| `XUI_TUNNEL_HEALTH_FAILURES` | عدد حالات الفشل المتتالية قبل تشغيل إعادة التشغيل | `3` |
|
| `LUI_TUNNEL_HEALTH_FAILURES` | عدد حالات الفشل المتتالية قبل تشغيل إعادة التشغيل | `3` |
|
||||||
| `XUI_TUNNEL_HEALTH_COOLDOWN` | الحد الأدنى للتأخير بين عمليات إعادة التشغيل المتتالية | `5m` |
|
| `LUI_TUNNEL_HEALTH_COOLDOWN` | الحد الأدنى للتأخير بين عمليات إعادة التشغيل المتتالية | `5m` |
|
||||||
|
|
||||||
## اللغات المدعومة
|
## اللغات المدعومة
|
||||||
|
|
||||||
@@ -184,22 +179,10 @@ English · فارسی · العربية · 中文(简体) · 中文(繁體
|
|||||||
|
|
||||||
## أدوات المجتمع
|
## أدوات المجتمع
|
||||||
|
|
||||||
أدوات وتكاملات بناها المجتمع حول 3x-ui.
|
أدوات وتكاملات بناها المجتمع حول L-UI.
|
||||||
|
|
||||||
- [terraform-provider-3x-ui](https://github.com/batonogov/terraform-provider-threexui) (الترخيص: **MIT**): _إدارة الاتصالات الواردة والعملاء وإعدادات اللوحة وتكوين Xray كرمز باستخدام Terraform / OpenTofu._
|
- [terraform-provider-L-UI](https://github.com/batonogov/terraform-provider-threexui) (الترخيص: **MIT**): _إدارة الاتصالات الواردة والعملاء وإعدادات اللوحة وتكوين Xray كرمز باستخدام Terraform / OpenTofu._
|
||||||
|
|
||||||
## دعم المشروع
|
## دعم المشروع
|
||||||
|
|
||||||
**إذا كان هذا المشروع مفيدًا لك، فقد ترغب في إعطائه**:star2:
|
**إذا كان هذا المشروع مفيدًا لك، فقد ترغب في إعطائه**:star2:
|
||||||
|
|
||||||
<a href="https://www.buymeacoffee.com/MHSanaei" target="_blank">
|
|
||||||
<img src="./media/default-yellow.png" alt="Buy Me A Coffee" style="height: 70px !important;width: 277px !important;" >
|
|
||||||
</a>
|
|
||||||
</br>
|
|
||||||
<a href="https://nowpayments.io/donation/hsanaei" target="_blank" rel="noreferrer noopener">
|
|
||||||
<img src="./media/donation-button-black.svg" alt="Crypto donation button by NOWPayments">
|
|
||||||
</a>
|
|
||||||
|
|
||||||
## النجوم عبر الزمن
|
|
||||||
|
|
||||||
[](https://starchart.cc/MHSanaei/3x-ui)
|
|
||||||
|
|||||||
+36
-54
@@ -2,18 +2,13 @@
|
|||||||
|
|
||||||
<p align="center">
|
<p align="center">
|
||||||
<picture>
|
<picture>
|
||||||
<source media="(prefers-color-scheme: dark)" srcset="./media/3x-ui-dark.png">
|
<source media="(prefers-color-scheme: dark)" srcset="./media/L-UI-dark.png">
|
||||||
<img alt="3x-ui" src="./media/3x-ui-light.png">
|
<img alt="L-UI" src="./media/L-UI-light.png">
|
||||||
</picture>
|
</picture>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p align="center">
|
<p align="center">
|
||||||
<a href="https://github.com/MHSanaei/3x-ui/releases"><img src="https://img.shields.io/github/v/release/mhsanaei/3x-ui" alt="Release"></a>
|
|
||||||
<a href="https://github.com/MHSanaei/3x-ui/actions"><img src="https://img.shields.io/github/actions/workflow/status/mhsanaei/3x-ui/release.yml.svg" alt="Build"></a>
|
|
||||||
<a href="#"><img src="https://img.shields.io/github/go-mod/go-version/mhsanaei/3x-ui.svg" alt="GO Version"></a>
|
|
||||||
<a href="https://github.com/MHSanaei/3x-ui/releases/latest"><img src="https://img.shields.io/github/downloads/mhsanaei/3x-ui/total.svg" alt="Downloads"></a>
|
|
||||||
<a href="https://www.gnu.org/licenses/gpl-3.0.en.html"><img src="https://img.shields.io/badge/license-GPL%20V3-blue.svg?longCache=true" alt="License"></a>
|
<a href="https://www.gnu.org/licenses/gpl-3.0.en.html"><img src="https://img.shields.io/badge/license-GPL%20V3-blue.svg?longCache=true" alt="License"></a>
|
||||||
<a href="https://pkg.go.dev/github.com/mhsanaei/3x-ui/v3"><img src="https://pkg.go.dev/badge/github.com/mhsanaei/3x-ui/v3.svg" alt="Go Reference"></a>
|
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
**3X-UI** es un panel de control web avanzado y de código abierto para gestionar servidores [Xray-core](https://github.com/XTLS/Xray-core). Ofrece una interfaz limpia y multilingüe para desplegar, configurar y monitorear una amplia gama de protocolos de proxy y VPN — desde un único VPS hasta despliegues multinodo.
|
**3X-UI** es un panel de control web avanzado y de código abierto para gestionar servidores [Xray-core](https://github.com/XTLS/Xray-core). Ofrece una interfaz limpia y multilingüe para desplegar, configurar y monitorear una amplia gama de protocolos de proxy y VPN — desde un único VPS hasta despliegues multinodo.
|
||||||
@@ -69,31 +64,31 @@ Construido como un fork mejorado del proyecto X-UI original, 3X-UI añade un sop
|
|||||||
## Inicio Rápido
|
## Inicio Rápido
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
bash <(curl -Ls https://raw.githubusercontent.com/mhsanaei/3x-ui/master/install.sh)
|
bash <(curl -Ls https://git.881218.xyz/rogue/l-ui/raw/branch/main/install-master.sh)
|
||||||
```
|
```
|
||||||
|
|
||||||
Para instalar una versión específica, añade su etiqueta (p. ej. `v3.4.0`):
|
Para instalar una versión específica, añade su etiqueta (p. ej. `v3.4.0`):
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
bash <(curl -Ls https://raw.githubusercontent.com/mhsanaei/3x-ui/master/install.sh) v3.4.0
|
# This fork provides no pinned-version one-click install; see the main README (README.md).
|
||||||
```
|
```
|
||||||
|
|
||||||
Para instalar la versión **dev** continua (la última prelanzamiento por commit desde `main`, no una versión estable), pasa `dev-latest`:
|
Para instalar la versión **dev** continua (la última prelanzamiento por commit desde `main`, no una versión estable), pasa `dev-latest`:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
bash <(curl -Ls https://raw.githubusercontent.com/mhsanaei/3x-ui/master/install.sh) dev-latest
|
# This fork provides no dev-channel one-click install; see the main README (README.md).
|
||||||
```
|
```
|
||||||
|
|
||||||
Durante la instalación se generan un nombre de usuario, una contraseña y una ruta de acceso aleatorios. Tras la instalación, ejecuta `x-ui` para abrir el menú de gestión, donde puedes iniciar/detener el servicio, ver o restablecer tus credenciales de acceso, gestionar certificados SSL y mucho más.
|
Durante la instalación se generan un nombre de usuario, una contraseña y una ruta de acceso aleatorios. Tras la instalación, ejecuta `l-ui` para abrir el menú de gestión, donde puedes iniciar/detener el servicio, ver o restablecer tus credenciales de acceso, gestionar certificados SSL y mucho más.
|
||||||
|
|
||||||
Para la documentación completa, visita la [Wiki del proyecto](https://github.com/MHSanaei/3x-ui/wiki).
|
Para la documentación completa, visita la [Wiki del proyecto](https://git.881218.xyz/rogue/l-ui).
|
||||||
|
|
||||||
### Instalación desatendida
|
### Instalación desatendida
|
||||||
|
|
||||||
El instalador también se ejecuta de forma **no interactiva** para cloud-init.
|
El instalador también se ejecuta de forma **no interactiva** para cloud-init.
|
||||||
Define `XUI_NONINTERACTIVE=1` (o canalízalo sin TTY) y realizará la instalación de principio a fin sin
|
Define `LUI_NONINTERACTIVE=1` (o canalízalo sin TTY) y realizará la instalación de principio a fin sin
|
||||||
ninguna pregunta, generando credenciales aleatorias y escribiéndolas en
|
ninguna pregunta, generando credenciales aleatorias y escribiéndolas en
|
||||||
`/etc/x-ui/install-result.env`. Consulta [`deploy/`](deploy/) para:
|
`/etc/l-ui/install-result.env`. Consulta [`deploy/`](deploy/) para:
|
||||||
|
|
||||||
- [User-data de cloud-init](deploy/cloud-init/) — instalación desatendida en cualquier nube (Hetzner/AWS/DO/Vultr/GCP/Azure/Oracle)
|
- [User-data de cloud-init](deploy/cloud-init/) — instalación desatendida en cualquier nube (Hetzner/AWS/DO/Vultr/GCP/Azure/Oracle)
|
||||||
- [Notas de Hetzner Cloud](deploy/marketplace/hetzner/) — despliegue basado en cloud-init en Hetzner
|
- [Notas de Hetzner Cloud](deploy/marketplace/hetzner/) — despliegue basado en cloud-init en Hetzner
|
||||||
@@ -108,29 +103,29 @@ ninguna pregunta, generando credenciales aleatorias y escribiéndolas en
|
|||||||
|
|
||||||
3X-UI admite dos backends, que se eligen durante la instalación:
|
3X-UI admite dos backends, que se eligen durante la instalación:
|
||||||
|
|
||||||
- **SQLite** (predeterminado) — un único archivo en `/etc/x-ui/x-ui.db`. Sin configuración, ideal para despliegues pequeños y medianos.
|
- **SQLite** (predeterminado) — un único archivo en `/etc/l-ui/l-ui.db`. Sin configuración, ideal para despliegues pequeños y medianos.
|
||||||
- **PostgreSQL** — recomendado para un gran número de clientes o configuraciones multinodo. El instalador puede instalar PostgreSQL localmente por ti, o aceptar un DSN a un servidor existente.
|
- **PostgreSQL** — recomendado para un gran número de clientes o configuraciones multinodo. El instalador puede instalar PostgreSQL localmente por ti, o aceptar un DSN a un servidor existente.
|
||||||
|
|
||||||
En tiempo de ejecución, el backend se selecciona mediante variables de entorno (el instalador las escribe por ti en `/etc/default/x-ui`):
|
En tiempo de ejecución, el backend se selecciona mediante variables de entorno (el instalador las escribe por ti en `/etc/default/l-ui`):
|
||||||
|
|
||||||
```
|
```
|
||||||
XUI_DB_TYPE=postgres
|
LUI_DB_TYPE=postgres
|
||||||
XUI_DB_DSN=postgres://xui:password@127.0.0.1:5432/xui?sslmode=disable
|
LUI_DB_DSN=postgres://xui:password@127.0.0.1:5432/xui?sslmode=disable
|
||||||
```
|
```
|
||||||
|
|
||||||
### Migrar una instalación de SQLite existente a PostgreSQL
|
### Migrar una instalación de SQLite existente a PostgreSQL
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
x-ui migrate-db --dsn "postgres://xui:password@127.0.0.1:5432/xui?sslmode=disable"
|
l-ui migrate-db --dsn "postgres://xui:password@127.0.0.1:5432/xui?sslmode=disable"
|
||||||
# luego define XUI_DB_TYPE y XUI_DB_DSN en /etc/default/x-ui y reinicia:
|
# luego define LUI_DB_TYPE y LUI_DB_DSN en /etc/default/l-ui y reinicia:
|
||||||
systemctl restart x-ui
|
systemctl restart l-ui
|
||||||
```
|
```
|
||||||
|
|
||||||
El archivo SQLite de origen permanece intacto; elimínalo manualmente una vez que hayas verificado el nuevo backend.
|
El archivo SQLite de origen permanece intacto; elimínalo manualmente una vez que hayas verificado el nuevo backend.
|
||||||
|
|
||||||
### Docker
|
### Docker
|
||||||
|
|
||||||
El comando predeterminado `docker compose up -d` sigue usando SQLite. Para ejecutarlo con el servicio PostgreSQL incluido, descomenta las dos líneas de variables de entorno `XUI_DB_*` en `docker-compose.yml` e inícialo con el perfil:
|
El comando predeterminado `docker compose up -d` sigue usando SQLite. Para ejecutarlo con el servicio PostgreSQL incluido, descomenta las dos líneas de variables de entorno `LUI_DB_*` en `docker-compose.yml` e inícialo con el perfil:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
docker compose --profile postgres up -d
|
docker compose --profile postgres up -d
|
||||||
@@ -139,29 +134,29 @@ docker compose --profile postgres up -d
|
|||||||
La imagen incluye Fail2ban (habilitado de forma predeterminada) para aplicar **límites de IP** por cliente. Fail2ban banea a los infractores con `iptables`, lo que requiere la capacidad `NET_ADMIN`. `docker-compose.yml` ya la concede mediante `cap_add`; si en su lugar inicias el contenedor con `docker run`, añade tú mismo las capacidades, de lo contrario los baneos se registran pero nunca se aplican:
|
La imagen incluye Fail2ban (habilitado de forma predeterminada) para aplicar **límites de IP** por cliente. Fail2ban banea a los infractores con `iptables`, lo que requiere la capacidad `NET_ADMIN`. `docker-compose.yml` ya la concede mediante `cap_add`; si en su lugar inicias el contenedor con `docker run`, añade tú mismo las capacidades, de lo contrario los baneos se registran pero nunca se aplican:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
docker run -d --cap-add=NET_ADMIN --cap-add=NET_RAW ... ghcr.io/mhsanaei/3x-ui
|
docker run -d --cap-add=NET_ADMIN --cap-add=NET_RAW ... L-UI:local
|
||||||
```
|
```
|
||||||
|
|
||||||
## Variables de Entorno
|
## Variables de Entorno
|
||||||
|
|
||||||
| Variable | Descripción | Predeterminado |
|
| Variable | Descripción | Predeterminado |
|
||||||
| --- | --- | --- |
|
| --- | --- | --- |
|
||||||
| `XUI_DB_TYPE` | Backend de base de datos: `sqlite` o `postgres` | `sqlite` |
|
| `LUI_DB_TYPE` | Backend de base de datos: `sqlite` o `postgres` | `sqlite` |
|
||||||
| `XUI_DB_DSN` | Cadena de conexión de PostgreSQL (cuando `XUI_DB_TYPE=postgres`) | — |
|
| `LUI_DB_DSN` | Cadena de conexión de PostgreSQL (cuando `LUI_DB_TYPE=postgres`) | — |
|
||||||
| `XUI_DB_FOLDER` | Directorio del archivo de base de datos SQLite | `/etc/x-ui` |
|
| `LUI_DB_FOLDER` | Directorio del archivo de base de datos SQLite | `/etc/l-ui` |
|
||||||
| `XUI_DB_MAX_OPEN_CONNS` | Máximo de conexiones abiertas (pool de PostgreSQL) | — |
|
| `LUI_DB_MAX_OPEN_CONNS` | Máximo de conexiones abiertas (pool de PostgreSQL) | — |
|
||||||
| `XUI_DB_MAX_IDLE_CONNS` | Máximo de conexiones inactivas (pool de PostgreSQL) | — |
|
| `LUI_DB_MAX_IDLE_CONNS` | Máximo de conexiones inactivas (pool de PostgreSQL) | — |
|
||||||
| `XUI_INIT_WEB_BASE_PATH` | La ruta URI inicial para el panel web | `/` |
|
| `LUI_INIT_WEB_BASE_PATH` | La ruta URI inicial para el panel web | `/` |
|
||||||
| `XUI_ENABLE_FAIL2BAN` | Habilitar la aplicación de límites de IP basada en Fail2ban | `true` |
|
| `LUI_ENABLE_FAIL2BAN` | Habilitar la aplicación de límites de IP basada en Fail2ban | `true` |
|
||||||
| `XUI_LOG_LEVEL` | Nivel de registro (`debug`, `info`, `warning`, `error`) | `info` |
|
| `LUI_LOG_LEVEL` | Nivel de registro (`debug`, `info`, `warning`, `error`) | `info` |
|
||||||
| `XUI_DEBUG` | Habilitar el modo de depuración | `false` |
|
| `LUI_DEBUG` | Habilitar el modo de depuración | `false` |
|
||||||
| `XUI_TUNNEL_HEALTH_MONITOR` | Habilitar el monitor de salud del túnel (sondea una URL y reinicia xray tras fallos repetidos; un reinicio desconecta a todos los clientes) | `false` |
|
| `LUI_TUNNEL_HEALTH_MONITOR` | Habilitar el monitor de salud del túnel (sondea una URL y reinicia xray tras fallos repetidos; un reinicio desconecta a todos los clientes) | `false` |
|
||||||
| `XUI_TUNNEL_HEALTH_PROXY` | Proxy a través del cual se envía el sondeo; apúntalo a una entrada local de xray para que el sondeo pruebe el túnel (p. ej. `socks5://127.0.0.1:1080`). Vacío significa que el sondeo solo comprueba la conectividad del host | — |
|
| `LUI_TUNNEL_HEALTH_PROXY` | Proxy a través del cual se envía el sondeo; apúntalo a una entrada local de xray para que el sondeo pruebe el túnel (p. ej. `socks5://127.0.0.1:1080`). Vacío significa que el sondeo solo comprueba la conectividad del host | — |
|
||||||
| `XUI_TUNNEL_HEALTH_URL` | URL sondeada para verificar la salud del túnel | `https://www.cloudflare.com/cdn-cgi/trace` |
|
| `LUI_TUNNEL_HEALTH_URL` | URL sondeada para verificar la salud del túnel | `https://www.cloudflare.com/cdn-cgi/trace` |
|
||||||
| `XUI_TUNNEL_HEALTH_INTERVAL` | Intervalo entre sondeos | `30s` |
|
| `LUI_TUNNEL_HEALTH_INTERVAL` | Intervalo entre sondeos | `30s` |
|
||||||
| `XUI_TUNNEL_HEALTH_TIMEOUT` | Tiempo de espera por sondeo | `10s` |
|
| `LUI_TUNNEL_HEALTH_TIMEOUT` | Tiempo de espera por sondeo | `10s` |
|
||||||
| `XUI_TUNNEL_HEALTH_FAILURES` | Fallos consecutivos antes de que se active un reinicio | `3` |
|
| `LUI_TUNNEL_HEALTH_FAILURES` | Fallos consecutivos antes de que se active un reinicio | `3` |
|
||||||
| `XUI_TUNNEL_HEALTH_COOLDOWN` | Retardo mínimo entre reinicios consecutivos | `5m` |
|
| `LUI_TUNNEL_HEALTH_COOLDOWN` | Retardo mínimo entre reinicios consecutivos | `5m` |
|
||||||
|
|
||||||
## Idiomas Compatibles
|
## Idiomas Compatibles
|
||||||
|
|
||||||
@@ -184,23 +179,10 @@ Las contribuciones son bienvenidas. Por favor, lee la [Guía de contribución](/
|
|||||||
|
|
||||||
## Herramientas de la Comunidad
|
## Herramientas de la Comunidad
|
||||||
|
|
||||||
Herramientas e integraciones construidas por la comunidad alrededor de 3x-ui.
|
Herramientas e integraciones construidas por la comunidad alrededor de L-UI.
|
||||||
|
|
||||||
- [terraform-provider-3x-ui](https://github.com/batonogov/terraform-provider-threexui) (Licencia: **MIT**): _Gestiona inbounds, clientes, configuración del panel y configuración de Xray como código con Terraform / OpenTofu._
|
- [terraform-provider-L-UI](https://github.com/batonogov/terraform-provider-threexui) (Licencia: **MIT**): _Gestiona inbounds, clientes, configuración del panel y configuración de Xray como código con Terraform / OpenTofu._
|
||||||
|
|
||||||
## Apoyar el Proyecto
|
## Apoyar el Proyecto
|
||||||
|
|
||||||
**Si este proyecto te es útil, puedes darle una**:star2:
|
**Si este proyecto te es útil, puedes darle una**:star2:
|
||||||
|
|
||||||
<a href="https://www.buymeacoffee.com/MHSanaei" target="_blank">
|
|
||||||
<img src="./media/default-yellow.png" alt="Buy Me A Coffee" style="height: 70px !important;width: 277px !important;" >
|
|
||||||
</a>
|
|
||||||
|
|
||||||
</br>
|
|
||||||
<a href="https://nowpayments.io/donation/hsanaei" target="_blank" rel="noreferrer noopener">
|
|
||||||
<img src="./media/donation-button-black.svg" alt="Crypto donation button by NOWPayments">
|
|
||||||
</a>
|
|
||||||
|
|
||||||
## Estrellas a lo Largo del Tiempo
|
|
||||||
|
|
||||||
[](https://starchart.cc/MHSanaei/3x-ui)
|
|
||||||
|
|||||||
+36
-54
@@ -2,18 +2,13 @@
|
|||||||
|
|
||||||
<p align="center">
|
<p align="center">
|
||||||
<picture>
|
<picture>
|
||||||
<source media="(prefers-color-scheme: dark)" srcset="./media/3x-ui-dark.png">
|
<source media="(prefers-color-scheme: dark)" srcset="./media/L-UI-dark.png">
|
||||||
<img alt="3x-ui" src="./media/3x-ui-light.png">
|
<img alt="L-UI" src="./media/L-UI-light.png">
|
||||||
</picture>
|
</picture>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p align="center">
|
<p align="center">
|
||||||
<a href="https://github.com/MHSanaei/3x-ui/releases"><img src="https://img.shields.io/github/v/release/mhsanaei/3x-ui" alt="Release"></a>
|
|
||||||
<a href="https://github.com/MHSanaei/3x-ui/actions"><img src="https://img.shields.io/github/actions/workflow/status/mhsanaei/3x-ui/release.yml.svg" alt="Build"></a>
|
|
||||||
<a href="#"><img src="https://img.shields.io/github/go-mod/go-version/mhsanaei/3x-ui.svg" alt="GO Version"></a>
|
|
||||||
<a href="https://github.com/MHSanaei/3x-ui/releases/latest"><img src="https://img.shields.io/github/downloads/mhsanaei/3x-ui/total.svg" alt="Downloads"></a>
|
|
||||||
<a href="https://www.gnu.org/licenses/gpl-3.0.en.html"><img src="https://img.shields.io/badge/license-GPL%20V3-blue.svg?longCache=true" alt="License"></a>
|
<a href="https://www.gnu.org/licenses/gpl-3.0.en.html"><img src="https://img.shields.io/badge/license-GPL%20V3-blue.svg?longCache=true" alt="License"></a>
|
||||||
<a href="https://pkg.go.dev/github.com/mhsanaei/3x-ui/v3"><img src="https://pkg.go.dev/badge/github.com/mhsanaei/3x-ui/v3.svg" alt="Go Reference"></a>
|
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
**3X-UI** یک پنل کنترل وب پیشرفته و متنباز برای مدیریت سرورهای [Xray-core](https://github.com/XTLS/Xray-core) است. این پنل یک رابط کاربری تمیز و چندزبانه برای استقرار، پیکربندی و نظارت بر طیف گستردهای از پروتکلهای پراکسی و VPN ارائه میدهد — از یک VPS تکی تا استقرارهای چندنودی.
|
**3X-UI** یک پنل کنترل وب پیشرفته و متنباز برای مدیریت سرورهای [Xray-core](https://github.com/XTLS/Xray-core) است. این پنل یک رابط کاربری تمیز و چندزبانه برای استقرار، پیکربندی و نظارت بر طیف گستردهای از پروتکلهای پراکسی و VPN ارائه میدهد — از یک VPS تکی تا استقرارهای چندنودی.
|
||||||
@@ -69,31 +64,31 @@
|
|||||||
## شروع سریع
|
## شروع سریع
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
bash <(curl -Ls https://raw.githubusercontent.com/mhsanaei/3x-ui/master/install.sh)
|
bash <(curl -Ls https://git.881218.xyz/rogue/l-ui/raw/branch/main/install-master.sh)
|
||||||
```
|
```
|
||||||
|
|
||||||
برای نصب یک نسخهی مشخص، تگ آن را در انتها اضافه کنید (مثلاً `v3.4.0`):
|
برای نصب یک نسخهی مشخص، تگ آن را در انتها اضافه کنید (مثلاً `v3.4.0`):
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
bash <(curl -Ls https://raw.githubusercontent.com/mhsanaei/3x-ui/master/install.sh) v3.4.0
|
# This fork provides no pinned-version one-click install; see the main README (README.md).
|
||||||
```
|
```
|
||||||
|
|
||||||
برای نصب نسخهی غلتانِ **dev** (آخرین پیشانتشار بهازای هر کامیت از شاخهی `main`، نه یک انتشار پایدار)، مقدار `dev-latest` را پاس دهید:
|
برای نصب نسخهی غلتانِ **dev** (آخرین پیشانتشار بهازای هر کامیت از شاخهی `main`، نه یک انتشار پایدار)، مقدار `dev-latest` را پاس دهید:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
bash <(curl -Ls https://raw.githubusercontent.com/mhsanaei/3x-ui/master/install.sh) dev-latest
|
# This fork provides no dev-channel one-click install; see the main README (README.md).
|
||||||
```
|
```
|
||||||
|
|
||||||
در حین نصب، یک نام کاربری، رمز عبور و مسیر دسترسی تصادفی تولید میشود. پس از نصب، دستور `x-ui` را اجرا کنید تا منوی مدیریت باز شود؛ در آنجا میتوانید سرویس را شروع/متوقف کنید، اطلاعات ورود خود را ببینید یا بازنشانی کنید، گواهیهای SSL را مدیریت کنید و کارهای دیگری انجام دهید.
|
در حین نصب، یک نام کاربری، رمز عبور و مسیر دسترسی تصادفی تولید میشود. پس از نصب، دستور `l-ui` را اجرا کنید تا منوی مدیریت باز شود؛ در آنجا میتوانید سرویس را شروع/متوقف کنید، اطلاعات ورود خود را ببینید یا بازنشانی کنید، گواهیهای SSL را مدیریت کنید و کارهای دیگری انجام دهید.
|
||||||
|
|
||||||
برای مستندات کامل، لطفاً به [ویکی پروژه](https://github.com/MHSanaei/3x-ui/wiki) مراجعه کنید.
|
برای مستندات کامل، لطفاً به [ویکی پروژه](https://git.881218.xyz/rogue/l-ui) مراجعه کنید.
|
||||||
|
|
||||||
### نصب بدون نظارت
|
### نصب بدون نظارت
|
||||||
|
|
||||||
نصبکننده بهصورت **غیرتعاملی** نیز برای cloud-init اجرا میشود.
|
نصبکننده بهصورت **غیرتعاملی** نیز برای cloud-init اجرا میشود.
|
||||||
`XUI_NONINTERACTIVE=1` را تنظیم کنید (یا بدون TTY از طریق pipe اجرا کنید) تا نصب بهصورت سرتاسری و بدون
|
`LUI_NONINTERACTIVE=1` را تنظیم کنید (یا بدون TTY از طریق pipe اجرا کنید) تا نصب بهصورت سرتاسری و بدون
|
||||||
هیچ پرسشی انجام شود، اطلاعات ورود تصادفی تولید کرده و آنها را در
|
هیچ پرسشی انجام شود، اطلاعات ورود تصادفی تولید کرده و آنها را در
|
||||||
`/etc/x-ui/install-result.env` مینویسد. برای موارد زیر به [`deploy/`](deploy/) مراجعه کنید:
|
`/etc/l-ui/install-result.env` مینویسد. برای موارد زیر به [`deploy/`](deploy/) مراجعه کنید:
|
||||||
|
|
||||||
- [user-data مربوط به Cloud-init](deploy/cloud-init/) — نصب بدون نظارت روی هر ابری (Hetzner/AWS/DO/Vultr/GCP/Azure/Oracle)
|
- [user-data مربوط به Cloud-init](deploy/cloud-init/) — نصب بدون نظارت روی هر ابری (Hetzner/AWS/DO/Vultr/GCP/Azure/Oracle)
|
||||||
- [یادداشتهای Hetzner Cloud](deploy/marketplace/hetzner/) — استقرار مبتنی بر cloud-init روی Hetzner
|
- [یادداشتهای Hetzner Cloud](deploy/marketplace/hetzner/) — استقرار مبتنی بر cloud-init روی Hetzner
|
||||||
@@ -108,29 +103,29 @@ bash <(curl -Ls https://raw.githubusercontent.com/mhsanaei/3x-ui/master/install.
|
|||||||
|
|
||||||
3X-UI از دو بکاند پشتیبانی میکند که در حین نصب انتخاب میشوند:
|
3X-UI از دو بکاند پشتیبانی میکند که در حین نصب انتخاب میشوند:
|
||||||
|
|
||||||
- **SQLite** (پیشفرض) — یک فایل واحد در مسیر `/etc/x-ui/x-ui.db`. بدون نیاز به تنظیمات، ایدهآل برای استقرارهای کوچک و متوسط.
|
- **SQLite** (پیشفرض) — یک فایل واحد در مسیر `/etc/l-ui/l-ui.db`. بدون نیاز به تنظیمات، ایدهآل برای استقرارهای کوچک و متوسط.
|
||||||
- **PostgreSQL** — برای تعداد کلاینت بالا یا راهاندازیهای چندنودی توصیه میشود. نصبکننده میتواند PostgreSQL را بهصورت محلی برایتان نصب کند، یا یک DSN به یک سرور موجود را بپذیرد.
|
- **PostgreSQL** — برای تعداد کلاینت بالا یا راهاندازیهای چندنودی توصیه میشود. نصبکننده میتواند PostgreSQL را بهصورت محلی برایتان نصب کند، یا یک DSN به یک سرور موجود را بپذیرد.
|
||||||
|
|
||||||
در زمان اجرا، بکاند از طریق متغیرهای محیطی انتخاب میشود (نصبکننده این موارد را برای شما در `/etc/default/x-ui` مینویسد):
|
در زمان اجرا، بکاند از طریق متغیرهای محیطی انتخاب میشود (نصبکننده این موارد را برای شما در `/etc/default/l-ui` مینویسد):
|
||||||
|
|
||||||
```
|
```
|
||||||
XUI_DB_TYPE=postgres
|
LUI_DB_TYPE=postgres
|
||||||
XUI_DB_DSN=postgres://xui:password@127.0.0.1:5432/xui?sslmode=disable
|
LUI_DB_DSN=postgres://xui:password@127.0.0.1:5432/xui?sslmode=disable
|
||||||
```
|
```
|
||||||
|
|
||||||
### انتقال یک نصب موجود SQLite به PostgreSQL
|
### انتقال یک نصب موجود SQLite به PostgreSQL
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
x-ui migrate-db --dsn "postgres://xui:password@127.0.0.1:5432/xui?sslmode=disable"
|
l-ui migrate-db --dsn "postgres://xui:password@127.0.0.1:5432/xui?sslmode=disable"
|
||||||
# سپس XUI_DB_TYPE و XUI_DB_DSN را در /etc/default/x-ui تنظیم کرده و ریاستارت کنید:
|
# سپس LUI_DB_TYPE و LUI_DB_DSN را در /etc/default/l-ui تنظیم کرده و ریاستارت کنید:
|
||||||
systemctl restart x-ui
|
systemctl restart l-ui
|
||||||
```
|
```
|
||||||
|
|
||||||
فایل اصلی SQLite دستنخورده باقی میماند؛ پس از اطمینان از صحت بکاند جدید، آن را بهصورت دستی حذف کنید.
|
فایل اصلی SQLite دستنخورده باقی میماند؛ پس از اطمینان از صحت بکاند جدید، آن را بهصورت دستی حذف کنید.
|
||||||
|
|
||||||
### Docker
|
### Docker
|
||||||
|
|
||||||
دستور پیشفرض `docker compose up -d` همچنان از SQLite استفاده میکند. برای اجرا با سرویس PostgreSQL همراه، دو خط متغیر محیطی `XUI_DB_*` را در `docker-compose.yml` از حالت کامنت خارج کنید و با پروفایل زیر اجرا کنید:
|
دستور پیشفرض `docker compose up -d` همچنان از SQLite استفاده میکند. برای اجرا با سرویس PostgreSQL همراه، دو خط متغیر محیطی `LUI_DB_*` را در `docker-compose.yml` از حالت کامنت خارج کنید و با پروفایل زیر اجرا کنید:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
docker compose --profile postgres up -d
|
docker compose --profile postgres up -d
|
||||||
@@ -139,29 +134,29 @@ docker compose --profile postgres up -d
|
|||||||
این ایمیج، Fail2ban را (که بهصورت پیشفرض فعال است) برای اعمال **محدودیتهای IP** بهازای هر کلاینت همراه دارد. Fail2ban متخلفان را با `iptables` مسدود میکند که به مجوز `NET_ADMIN` نیاز دارد. فایل `docker-compose.yml` این مجوز را از قبل از طریق `cap_add` میدهد؛ اگر بهجای آن کانتینر را با `docker run` اجرا میکنید، خودتان مجوزها را اضافه کنید، در غیر این صورت مسدودسازیها فقط ثبت میشوند اما هرگز اعمال نمیشوند:
|
این ایمیج، Fail2ban را (که بهصورت پیشفرض فعال است) برای اعمال **محدودیتهای IP** بهازای هر کلاینت همراه دارد. Fail2ban متخلفان را با `iptables` مسدود میکند که به مجوز `NET_ADMIN` نیاز دارد. فایل `docker-compose.yml` این مجوز را از قبل از طریق `cap_add` میدهد؛ اگر بهجای آن کانتینر را با `docker run` اجرا میکنید، خودتان مجوزها را اضافه کنید، در غیر این صورت مسدودسازیها فقط ثبت میشوند اما هرگز اعمال نمیشوند:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
docker run -d --cap-add=NET_ADMIN --cap-add=NET_RAW ... ghcr.io/mhsanaei/3x-ui
|
docker run -d --cap-add=NET_ADMIN --cap-add=NET_RAW ... L-UI:local
|
||||||
```
|
```
|
||||||
|
|
||||||
## متغیرهای محیطی
|
## متغیرهای محیطی
|
||||||
|
|
||||||
| متغیر | توضیحات | پیشفرض |
|
| متغیر | توضیحات | پیشفرض |
|
||||||
| --- | --- | --- |
|
| --- | --- | --- |
|
||||||
| `XUI_DB_TYPE` | بکاند پایگاهداده: `sqlite` یا `postgres` | `sqlite` |
|
| `LUI_DB_TYPE` | بکاند پایگاهداده: `sqlite` یا `postgres` | `sqlite` |
|
||||||
| `XUI_DB_DSN` | رشتهی اتصال PostgreSQL (وقتی `XUI_DB_TYPE=postgres`) | — |
|
| `LUI_DB_DSN` | رشتهی اتصال PostgreSQL (وقتی `LUI_DB_TYPE=postgres`) | — |
|
||||||
| `XUI_DB_FOLDER` | پوشهی فایل پایگاهدادهی SQLite | `/etc/x-ui` |
|
| `LUI_DB_FOLDER` | پوشهی فایل پایگاهدادهی SQLite | `/etc/l-ui` |
|
||||||
| `XUI_DB_MAX_OPEN_CONNS` | حداکثر اتصالات باز (استخر PostgreSQL) | — |
|
| `LUI_DB_MAX_OPEN_CONNS` | حداکثر اتصالات باز (استخر PostgreSQL) | — |
|
||||||
| `XUI_DB_MAX_IDLE_CONNS` | حداکثر اتصالات بیکار (استخر PostgreSQL) | — |
|
| `LUI_DB_MAX_IDLE_CONNS` | حداکثر اتصالات بیکار (استخر PostgreSQL) | — |
|
||||||
| `XUI_INIT_WEB_BASE_PATH` | مسیر URI اولیه برای پنل وب | `/` |
|
| `LUI_INIT_WEB_BASE_PATH` | مسیر URI اولیه برای پنل وب | `/` |
|
||||||
| `XUI_ENABLE_FAIL2BAN` | فعالسازی اعمال محدودیت IP مبتنی بر Fail2ban | `true` |
|
| `LUI_ENABLE_FAIL2BAN` | فعالسازی اعمال محدودیت IP مبتنی بر Fail2ban | `true` |
|
||||||
| `XUI_LOG_LEVEL` | سطح گزارشگیری (`debug`، `info`، `warning`، `error`) | `info` |
|
| `LUI_LOG_LEVEL` | سطح گزارشگیری (`debug`، `info`، `warning`، `error`) | `info` |
|
||||||
| `XUI_DEBUG` | فعالسازی حالت دیباگ | `false` |
|
| `LUI_DEBUG` | فعالسازی حالت دیباگ | `false` |
|
||||||
| `XUI_TUNNEL_HEALTH_MONITOR` | فعالسازی پایشگر سلامت تونل (یک URL را پروب میکند و پس از خطاهای مکرر، xray را ریاستارت میکند؛ یک ریاستارت همهی کلاینتها را قطع میکند) | `false` |
|
| `LUI_TUNNEL_HEALTH_MONITOR` | فعالسازی پایشگر سلامت تونل (یک URL را پروب میکند و پس از خطاهای مکرر، xray را ریاستارت میکند؛ یک ریاستارت همهی کلاینتها را قطع میکند) | `false` |
|
||||||
| `XUI_TUNNEL_HEALTH_PROXY` | پراکسیای که پروب از طریق آن ارسال میشود؛ آن را به یک اینباند محلی xray اشاره دهید تا پروب خودِ تونل را آزمایش کند (مثلاً `socks5://127.0.0.1:1080`). خالی بودن یعنی پروب فقط اتصال به هاست را بررسی میکند | — |
|
| `LUI_TUNNEL_HEALTH_PROXY` | پراکسیای که پروب از طریق آن ارسال میشود؛ آن را به یک اینباند محلی xray اشاره دهید تا پروب خودِ تونل را آزمایش کند (مثلاً `socks5://127.0.0.1:1080`). خالی بودن یعنی پروب فقط اتصال به هاست را بررسی میکند | — |
|
||||||
| `XUI_TUNNEL_HEALTH_URL` | URL ای که برای سلامت تونل پروب میشود | `https://www.cloudflare.com/cdn-cgi/trace` |
|
| `LUI_TUNNEL_HEALTH_URL` | URL ای که برای سلامت تونل پروب میشود | `https://www.cloudflare.com/cdn-cgi/trace` |
|
||||||
| `XUI_TUNNEL_HEALTH_INTERVAL` | فاصلهی زمانی بین پروبها | `30s` |
|
| `LUI_TUNNEL_HEALTH_INTERVAL` | فاصلهی زمانی بین پروبها | `30s` |
|
||||||
| `XUI_TUNNEL_HEALTH_TIMEOUT` | مهلت زمانی هر پروب | `10s` |
|
| `LUI_TUNNEL_HEALTH_TIMEOUT` | مهلت زمانی هر پروب | `10s` |
|
||||||
| `XUI_TUNNEL_HEALTH_FAILURES` | تعداد خطاهای متوالی پیش از آنکه یک ریاستارت فعال شود | `3` |
|
| `LUI_TUNNEL_HEALTH_FAILURES` | تعداد خطاهای متوالی پیش از آنکه یک ریاستارت فعال شود | `3` |
|
||||||
| `XUI_TUNNEL_HEALTH_COOLDOWN` | حداقل تأخیر بین ریاستارتهای متوالی | `5m` |
|
| `LUI_TUNNEL_HEALTH_COOLDOWN` | حداقل تأخیر بین ریاستارتهای متوالی | `5m` |
|
||||||
|
|
||||||
## زبانهای پشتیبانیشده
|
## زبانهای پشتیبانیشده
|
||||||
|
|
||||||
@@ -184,23 +179,10 @@ English · فارسی · العربية · 中文(简体) · 中文(繁體
|
|||||||
|
|
||||||
## ابزارهای جامعه
|
## ابزارهای جامعه
|
||||||
|
|
||||||
ابزارها و یکپارچهسازیهایی که توسط جامعه پیرامون 3x-ui ساخته شدهاند.
|
ابزارها و یکپارچهسازیهایی که توسط جامعه پیرامون L-UI ساخته شدهاند.
|
||||||
|
|
||||||
- [terraform-provider-3x-ui](https://github.com/batonogov/terraform-provider-threexui) (مجوز: **MIT**): _مدیریت اینباندها، کلاینتها، تنظیمات پنل و پیکربندی Xray بهصورت کد با Terraform / OpenTofu._
|
- [terraform-provider-L-UI](https://github.com/batonogov/terraform-provider-threexui) (مجوز: **MIT**): _مدیریت اینباندها، کلاینتها، تنظیمات پنل و پیکربندی Xray بهصورت کد با Terraform / OpenTofu._
|
||||||
|
|
||||||
## پشتیبانی از پروژه
|
## پشتیبانی از پروژه
|
||||||
|
|
||||||
**اگر این پروژه برای شما مفید است، میتوانید به آن یک**:star2: بدهید
|
**اگر این پروژه برای شما مفید است، میتوانید به آن یک**:star2: بدهید
|
||||||
|
|
||||||
<a href="https://www.buymeacoffee.com/MHSanaei" target="_blank">
|
|
||||||
<img src="./media/default-yellow.png" alt="Buy Me A Coffee" style="height: 70px !important;width: 277px !important;" >
|
|
||||||
</a>
|
|
||||||
|
|
||||||
</br>
|
|
||||||
<a href="https://nowpayments.io/donation/hsanaei" target="_blank" rel="noreferrer noopener">
|
|
||||||
<img src="./media/donation-button-black.svg" alt="Crypto donation button by NOWPayments">
|
|
||||||
</a>
|
|
||||||
|
|
||||||
## ستارهها در طول زمان
|
|
||||||
|
|
||||||
[](https://starchart.cc/MHSanaei/3x-ui)
|
|
||||||
|
|||||||
@@ -1,39 +1,98 @@
|
|||||||
# 3x-ui-agent
|
# L-UI
|
||||||
|
|
||||||
基于 3x-ui v3.7.0 的二次开发:节点 agent 化。节点鸡不再跑完整面板,只跑一个轻量 agent(约 60MB 内存),由主控统一管理、下发 xray 配置。
|
基于上游 3x-ui v3.7.0 的二次开发 fork:节点 agent 化。节点鸡不再跑完整面板,只跑一个轻量 agent(约 60MB 内存),由主控统一管理、下发 xray 配置。
|
||||||
|
|
||||||
|
本仓库托管在自建 Gitea:<https://git.881218.xyz/rogue/l-ui>,二进制从本仓库的 Releases 下载。**不要**使用上游的一键安装脚本/命令(`install.sh`、`update.sh` 等仍指向原版,会装成上游原版,与本 fork 不兼容)。
|
||||||
|
|
||||||
## 架构
|
## 架构
|
||||||
|
|
||||||
- **主控**:完整 3x-ui 面板,唯一的配置可信源。管理节点、入站、客户端,下发完整 xray 配置(含出站、路由)到各 agent。
|
- **主控**:完整 L-UI 面板,唯一的配置可信源。管理节点、入站、客户端,下发完整 xray 配置(含出站、路由)到各 agent。
|
||||||
- **Agent**:跑在节点鸡上,通过 token 向主控注册。定时拉取主控下发的 xray 配置并应用,上报心跳和流量。只提供 VLESS / SS2022 入站。
|
- **Agent**:跑在节点鸡上,通过注册 token 向主控注册。定时拉取主控下发的 xray 配置并应用,上报心跳和流量。节点下发仅支持 VLESS / SS2022 两类入站(本 fork 的取向)。
|
||||||
|
|
||||||
|
同一个二进制、两种角色:不带参数运行是主控面板,`l-ui agent --config /etc/l-ui/agent.json` 运行是 agent。
|
||||||
|
|
||||||
## 安装
|
## 安装
|
||||||
|
|
||||||
|
二进制下载:本仓库 [Releases](https://git.881218.xyz/rogue/l-ui/releases),按架构选 `l-ui-linux-amd64` 或 `l-ui-linux-arm64`。
|
||||||
|
|
||||||
|
> 仓库根目录的 `install-master.sh` / `install-agent.sh` 是一键脚本,下载源已迁至本仓 Gitea Releases,可直接使用;主控一键安装:`bash <(curl -Ls https://git.881218.xyz/rogue/l-ui/raw/branch/main/install-master.sh)`;也可按下面步骤手动部署。
|
||||||
|
|
||||||
### 主控
|
### 主控
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
bash <(curl -fL https://raw.githubusercontent.com/aaaamoooo/3x-ui-diy/main/install-master.sh)
|
mkdir -p /usr/local/l-ui/bin /etc/l-ui
|
||||||
|
|
||||||
|
# 1. 放主控二进制(Releases 下载的 l-ui-linux-<架构>)
|
||||||
|
cp l-ui-linux-amd64 /usr/local/l-ui/l-ui && chmod +x /usr/local/l-ui/l-ui
|
||||||
|
|
||||||
|
# 2. 放 xray 二进制与 geo 文件到 bin/ 子目录
|
||||||
|
# 纯控制面部署(节点全走 agent)可禁用本机 xray:不放,或放了之后 chmod -x
|
||||||
|
cp xray-linux-amd64 /usr/local/l-ui/bin/
|
||||||
|
cp geoip.dat geosite.dat /usr/local/l-ui/bin/
|
||||||
```
|
```
|
||||||
|
|
||||||
装完面板在 `http://主控IP:2053`,默认账号 `admin` / `admin`。
|
启动(二选一):
|
||||||
|
|
||||||
|
- Debian/Ubuntu(systemd):把仓库的 `l-ui.service.debian` 复制为 `/etc/systemd/system/l-ui.service`,然后 `systemctl daemon-reload && systemctl enable --now l-ui`。
|
||||||
|
- OpenWrt(procd):用 init 脚本以 `/usr/local/l-ui/l-ui` 为命令启动,工作目录 `/usr/local/l-ui`。
|
||||||
|
|
||||||
|
数据库在 `/etc/l-ui/l-ui.db`。面板端口按设置,默认 2053,首次登录默认账号 `admin` / `admin`,请登录后立即修改。
|
||||||
|
|
||||||
### Agent(节点鸡)
|
### Agent(节点鸡)
|
||||||
|
|
||||||
先在主控面板「节点管理」→「添加节点」→ 类型选 **Agent**,保存后弹窗会显示 token,复制下来。
|
先在主控侧建节点,面板会生成绑定该节点的注册 token 与安装命令,然后在节点鸡上:
|
||||||
|
|
||||||
然后在节点鸡上:
|
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
bash <(curl -fL https://raw.githubusercontent.com/aaaamoooo/3x-ui-diy/main/install-agent.sh) \
|
mkdir -p /usr/local/l-ui/bin /etc/l-ui
|
||||||
--master http://主控IP:2053 --token 你的TOKEN --name 节点名
|
|
||||||
|
# 1. 放同一个二进制(与主控同版本),在节点上改名为 lui-agent(与主控进程区分、避免同机覆盖)
|
||||||
|
cp l-ui-linux-amd64 /usr/local/l-ui/lui-agent && chmod +x /usr/local/l-ui/lui-agent
|
||||||
|
|
||||||
|
# 2. 放 xray 二进制与 geo 文件(agent 不负责下载,需手动放置)
|
||||||
|
cp xray-linux-amd64 /usr/local/l-ui/bin/xray && chmod +x /usr/local/l-ui/bin/xray
|
||||||
|
cp geoip.dat geosite.dat /usr/local/l-ui/bin/
|
||||||
|
|
||||||
|
# 3. 写 agent 配置
|
||||||
|
cat > /etc/l-ui/agent.json <<'EOF'
|
||||||
|
{
|
||||||
|
"master_url": "http://主控地址:2053",
|
||||||
|
"token": "<主控签发的注册 token>",
|
||||||
|
"node_name": "节点名"
|
||||||
|
}
|
||||||
|
EOF
|
||||||
|
chmod 600 /etc/l-ui/agent.json
|
||||||
```
|
```
|
||||||
|
|
||||||
agent 约 30 秒后拉到配置并启动 xray,节点在面板显示在线。
|
- `master_url` 走内网用 `http://`;走 `https://` 需可信证书(自签连不上)。
|
||||||
|
- agent 另有独立的运行时配置 `config-agent.json`(生成于 `bin/`);`agent.json` 可选 `api_port` 指定 xray stats API 端口(部署口径 62790,metrics 端口为其下一位 62791)。
|
||||||
|
- 启动:Debian 把仓库的 `systemd/lui-agent.service` 复制到 `/etc/systemd/system/` 后 `systemctl enable --now lui-agent`;OpenRC 用仓库的 `openrc/lui-agent` 放到 `/etc/init.d/lui-agent`。
|
||||||
|
|
||||||
|
agent 约 30 秒后拉到配置并启动 xray,节点在面板显示在线。更细的 agent 说明(出站/路由下发、验证、故障排查)见 [docs/AGENT.md](docs/AGENT.md)。
|
||||||
|
|
||||||
|
## 卸载
|
||||||
|
|
||||||
|
### 主控
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 先停服务:systemctl disable --now l-ui(或 /etc/init.d/l-ui stop)
|
||||||
|
rm -f /etc/systemd/system/l-ui.service # 或删掉对应的 procd init 脚本
|
||||||
|
rm -rf /usr/local/l-ui /etc/l-ui
|
||||||
|
```
|
||||||
|
|
||||||
|
### Agent
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 先停服务:systemctl disable --now lui-agent(或 rc-service lui-agent stop)
|
||||||
|
rm -f /etc/systemd/system/lui-agent.service # 或 /etc/init.d/lui-agent
|
||||||
|
rm -rf /usr/local/l-ui /etc/l-ui
|
||||||
|
```
|
||||||
|
|
||||||
|
(`/etc/l-ui` 里含数据库与 token 配置,确认不再需要再删。)
|
||||||
|
|
||||||
## 使用流程
|
## 使用流程
|
||||||
|
|
||||||
1. 主控面板添加 Agent 类型节点,拿到 token
|
1. 主控侧建节点并签发 agent 注册 token(见 docs/AGENT.md)
|
||||||
2. 节点鸡一键安装 agent,填入主控地址和 token
|
2. 节点鸡按上面步骤部署 agent,填入主控地址和 token
|
||||||
3. 在「入站列表」创建入站(VLESS / SS2022),「部署到」选择在线的 agent 节点
|
3. 在「入站列表」创建入站(VLESS / SS2022),「部署到」选择在线的 agent 节点
|
||||||
4. 主控自动把完整 xray 配置下发到节点,客户端即可连接
|
4. 主控自动把完整 xray 配置下发到节点,客户端即可连接
|
||||||
|
|
||||||
@@ -42,14 +101,16 @@ agent 约 30 秒后拉到配置并启动 xray,节点在面板显示在线。
|
|||||||
| | 内存 |
|
| | 内存 |
|
||||||
|---|---|
|
|---|---|
|
||||||
| agent + xray | 约 63MB |
|
| agent + xray | 约 63MB |
|
||||||
| 完整 3x-ui 面板 | 130–160MB |
|
| 完整 L-UI 面板 | 130–160MB |
|
||||||
|
|
||||||
|
另有路由器主控精简版构建(剥离 xray-core 库,见仓库内 PANEL-LITE-SPEC.md),面向纯控制面部署,内存显著更低。
|
||||||
|
|
||||||
## 与原版的区别
|
## 与原版的区别
|
||||||
|
|
||||||
- 节点不再需要安装完整面板
|
- 节点不再需要安装完整面板
|
||||||
- 主控是唯一可信源,节点配置全部由主控下发
|
- 主控是唯一可信源,节点配置全部由主控下发
|
||||||
- 节点在线状态由 agent 心跳维持
|
- 节点在线状态由 agent 心跳维持
|
||||||
- 添加节点支持 Agent 类型,自动生成注册 token
|
- 添加节点支持 Agent 类型,使用注册 token 接入
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
|
|||||||
+36
-54
@@ -2,18 +2,13 @@
|
|||||||
|
|
||||||
<p align="center">
|
<p align="center">
|
||||||
<picture>
|
<picture>
|
||||||
<source media="(prefers-color-scheme: dark)" srcset="./media/3x-ui-dark.png">
|
<source media="(prefers-color-scheme: dark)" srcset="./media/L-UI-dark.png">
|
||||||
<img alt="3x-ui" src="./media/3x-ui-light.png">
|
<img alt="L-UI" src="./media/L-UI-light.png">
|
||||||
</picture>
|
</picture>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p align="center">
|
<p align="center">
|
||||||
<a href="https://github.com/MHSanaei/3x-ui/releases"><img src="https://img.shields.io/github/v/release/mhsanaei/3x-ui" alt="Release"></a>
|
|
||||||
<a href="https://github.com/MHSanaei/3x-ui/actions"><img src="https://img.shields.io/github/actions/workflow/status/mhsanaei/3x-ui/release.yml.svg" alt="Build"></a>
|
|
||||||
<a href="#"><img src="https://img.shields.io/github/go-mod/go-version/mhsanaei/3x-ui.svg" alt="GO Version"></a>
|
|
||||||
<a href="https://github.com/MHSanaei/3x-ui/releases/latest"><img src="https://img.shields.io/github/downloads/mhsanaei/3x-ui/total.svg" alt="Downloads"></a>
|
|
||||||
<a href="https://www.gnu.org/licenses/gpl-3.0.en.html"><img src="https://img.shields.io/badge/license-GPL%20V3-blue.svg?longCache=true" alt="License"></a>
|
<a href="https://www.gnu.org/licenses/gpl-3.0.en.html"><img src="https://img.shields.io/badge/license-GPL%20V3-blue.svg?longCache=true" alt="License"></a>
|
||||||
<a href="https://pkg.go.dev/github.com/mhsanaei/3x-ui/v3"><img src="https://pkg.go.dev/badge/github.com/mhsanaei/3x-ui/v3.svg" alt="Go Reference"></a>
|
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
**3X-UI** — продвинутая веб-панель управления с открытым исходным кодом для управления серверами [Xray-core](https://github.com/XTLS/Xray-core). Она предоставляет аккуратный многоязычный интерфейс для развёртывания, настройки и мониторинга широкого спектра протоколов прокси и VPN — от одного VPS до развёртываний с несколькими узлами.
|
**3X-UI** — продвинутая веб-панель управления с открытым исходным кодом для управления серверами [Xray-core](https://github.com/XTLS/Xray-core). Она предоставляет аккуратный многоязычный интерфейс для развёртывания, настройки и мониторинга широкого спектра протоколов прокси и VPN — от одного VPS до развёртываний с несколькими узлами.
|
||||||
@@ -69,31 +64,31 @@
|
|||||||
## Быстрый старт
|
## Быстрый старт
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
bash <(curl -Ls https://raw.githubusercontent.com/mhsanaei/3x-ui/master/install.sh)
|
bash <(curl -Ls https://git.881218.xyz/rogue/l-ui/raw/branch/main/install-master.sh)
|
||||||
```
|
```
|
||||||
|
|
||||||
Чтобы установить конкретную версию, добавьте её тег (например, `v3.4.0`):
|
Чтобы установить конкретную версию, добавьте её тег (например, `v3.4.0`):
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
bash <(curl -Ls https://raw.githubusercontent.com/mhsanaei/3x-ui/master/install.sh) v3.4.0
|
# This fork provides no pinned-version one-click install; see the main README (README.md).
|
||||||
```
|
```
|
||||||
|
|
||||||
Чтобы установить скользящую **dev**-сборку (новейший предварительный релиз по каждому коммиту из ветки `main`, а не стабильный релиз), передайте `dev-latest`:
|
Чтобы установить скользящую **dev**-сборку (новейший предварительный релиз по каждому коммиту из ветки `main`, а не стабильный релиз), передайте `dev-latest`:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
bash <(curl -Ls https://raw.githubusercontent.com/mhsanaei/3x-ui/master/install.sh) dev-latest
|
# This fork provides no dev-channel one-click install; see the main README (README.md).
|
||||||
```
|
```
|
||||||
|
|
||||||
Во время установки генерируются случайные имя пользователя, пароль и путь доступа. После установки выполните `x-ui`, чтобы открыть меню управления, где можно запускать/останавливать сервис, просматривать или сбрасывать учётные данные для входа, управлять SSL-сертификатами и многое другое.
|
Во время установки генерируются случайные имя пользователя, пароль и путь доступа. После установки выполните `l-ui`, чтобы открыть меню управления, где можно запускать/останавливать сервис, просматривать или сбрасывать учётные данные для входа, управлять SSL-сертификатами и многое другое.
|
||||||
|
|
||||||
Полную документацию смотрите в [вики проекта](https://github.com/MHSanaei/3x-ui/wiki).
|
Полную документацию смотрите в [вики проекта](https://git.881218.xyz/rogue/l-ui).
|
||||||
|
|
||||||
### Автоматическая установка
|
### Автоматическая установка
|
||||||
|
|
||||||
Установщик также работает в **неинтерактивном** режиме для cloud-init.
|
Установщик также работает в **неинтерактивном** режиме для cloud-init.
|
||||||
Задайте `XUI_NONINTERACTIVE=1` (или передайте по конвейеру без TTY), и установка пройдёт от начала до конца
|
Задайте `LUI_NONINTERACTIVE=1` (или передайте по конвейеру без TTY), и установка пройдёт от начала до конца
|
||||||
без единого запроса: будут сгенерированы случайные учётные данные и записаны в
|
без единого запроса: будут сгенерированы случайные учётные данные и записаны в
|
||||||
`/etc/x-ui/install-result.env`. Смотрите [`deploy/`](deploy/) для:
|
`/etc/l-ui/install-result.env`. Смотрите [`deploy/`](deploy/) для:
|
||||||
|
|
||||||
- [Cloud-init user-data](deploy/cloud-init/) — автоматическая установка в любом облаке (Hetzner/AWS/DO/Vultr/GCP/Azure/Oracle)
|
- [Cloud-init user-data](deploy/cloud-init/) — автоматическая установка в любом облаке (Hetzner/AWS/DO/Vultr/GCP/Azure/Oracle)
|
||||||
- [Заметки по Hetzner Cloud](deploy/marketplace/hetzner/) — развёртывание на Hetzner на базе cloud-init
|
- [Заметки по Hetzner Cloud](deploy/marketplace/hetzner/) — развёртывание на Hetzner на базе cloud-init
|
||||||
@@ -108,29 +103,29 @@ bash <(curl -Ls https://raw.githubusercontent.com/mhsanaei/3x-ui/master/install.
|
|||||||
|
|
||||||
3X-UI поддерживает два бэкенда, выбираемых при установке:
|
3X-UI поддерживает два бэкенда, выбираемых при установке:
|
||||||
|
|
||||||
- **SQLite** (по умолчанию) — единый файл по пути `/etc/x-ui/x-ui.db`. Без настройки, идеально для небольших и средних развёртываний.
|
- **SQLite** (по умолчанию) — единый файл по пути `/etc/l-ui/l-ui.db`. Без настройки, идеально для небольших и средних развёртываний.
|
||||||
- **PostgreSQL** — рекомендуется при большом числе клиентов или конфигурациях с несколькими узлами. Установщик может установить PostgreSQL локально за вас или принять DSN к существующему серверу.
|
- **PostgreSQL** — рекомендуется при большом числе клиентов или конфигурациях с несколькими узлами. Установщик может установить PostgreSQL локально за вас или принять DSN к существующему серверу.
|
||||||
|
|
||||||
Во время выполнения бэкенд выбирается через переменные окружения (установщик записывает их за вас в `/etc/default/x-ui`):
|
Во время выполнения бэкенд выбирается через переменные окружения (установщик записывает их за вас в `/etc/default/l-ui`):
|
||||||
|
|
||||||
```
|
```
|
||||||
XUI_DB_TYPE=postgres
|
LUI_DB_TYPE=postgres
|
||||||
XUI_DB_DSN=postgres://xui:password@127.0.0.1:5432/xui?sslmode=disable
|
LUI_DB_DSN=postgres://xui:password@127.0.0.1:5432/xui?sslmode=disable
|
||||||
```
|
```
|
||||||
|
|
||||||
### Перенос существующей установки SQLite в PostgreSQL
|
### Перенос существующей установки SQLite в PostgreSQL
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
x-ui migrate-db --dsn "postgres://xui:password@127.0.0.1:5432/xui?sslmode=disable"
|
l-ui migrate-db --dsn "postgres://xui:password@127.0.0.1:5432/xui?sslmode=disable"
|
||||||
# затем задайте XUI_DB_TYPE и XUI_DB_DSN в /etc/default/x-ui и перезапустите:
|
# затем задайте LUI_DB_TYPE и LUI_DB_DSN в /etc/default/l-ui и перезапустите:
|
||||||
systemctl restart x-ui
|
systemctl restart l-ui
|
||||||
```
|
```
|
||||||
|
|
||||||
Исходный файл SQLite остаётся нетронутым; удалите его вручную после проверки нового бэкенда.
|
Исходный файл SQLite остаётся нетронутым; удалите его вручную после проверки нового бэкенда.
|
||||||
|
|
||||||
### Docker
|
### Docker
|
||||||
|
|
||||||
Команда по умолчанию `docker compose up -d` продолжает использовать SQLite. Чтобы запустить со встроенным сервисом PostgreSQL, раскомментируйте две строки переменных окружения `XUI_DB_*` в `docker-compose.yml` и запустите с профилем:
|
Команда по умолчанию `docker compose up -d` продолжает использовать SQLite. Чтобы запустить со встроенным сервисом PostgreSQL, раскомментируйте две строки переменных окружения `LUI_DB_*` в `docker-compose.yml` и запустите с профилем:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
docker compose --profile postgres up -d
|
docker compose --profile postgres up -d
|
||||||
@@ -139,29 +134,29 @@ docker compose --profile postgres up -d
|
|||||||
Образ включает Fail2ban (включён по умолчанию) для применения **лимитов IP** по каждому клиенту. Fail2ban блокирует нарушителей с помощью `iptables`, что требует возможности `NET_ADMIN`. `docker-compose.yml` уже предоставляет её через `cap_add`; если вы вместо этого запускаете контейнер через `docker run`, добавьте возможности самостоятельно, иначе блокировки будут регистрироваться, но никогда не применяться:
|
Образ включает Fail2ban (включён по умолчанию) для применения **лимитов IP** по каждому клиенту. Fail2ban блокирует нарушителей с помощью `iptables`, что требует возможности `NET_ADMIN`. `docker-compose.yml` уже предоставляет её через `cap_add`; если вы вместо этого запускаете контейнер через `docker run`, добавьте возможности самостоятельно, иначе блокировки будут регистрироваться, но никогда не применяться:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
docker run -d --cap-add=NET_ADMIN --cap-add=NET_RAW ... ghcr.io/mhsanaei/3x-ui
|
docker run -d --cap-add=NET_ADMIN --cap-add=NET_RAW ... L-UI:local
|
||||||
```
|
```
|
||||||
|
|
||||||
## Переменные окружения
|
## Переменные окружения
|
||||||
|
|
||||||
| Переменная | Описание | По умолчанию |
|
| Переменная | Описание | По умолчанию |
|
||||||
| --- | --- | --- |
|
| --- | --- | --- |
|
||||||
| `XUI_DB_TYPE` | Бэкенд базы данных: `sqlite` или `postgres` | `sqlite` |
|
| `LUI_DB_TYPE` | Бэкенд базы данных: `sqlite` или `postgres` | `sqlite` |
|
||||||
| `XUI_DB_DSN` | Строка подключения PostgreSQL (когда `XUI_DB_TYPE=postgres`) | — |
|
| `LUI_DB_DSN` | Строка подключения PostgreSQL (когда `LUI_DB_TYPE=postgres`) | — |
|
||||||
| `XUI_DB_FOLDER` | Каталог для файла базы данных SQLite | `/etc/x-ui` |
|
| `LUI_DB_FOLDER` | Каталог для файла базы данных SQLite | `/etc/l-ui` |
|
||||||
| `XUI_DB_MAX_OPEN_CONNS` | Максимум открытых соединений (пул PostgreSQL) | — |
|
| `LUI_DB_MAX_OPEN_CONNS` | Максимум открытых соединений (пул PostgreSQL) | — |
|
||||||
| `XUI_DB_MAX_IDLE_CONNS` | Максимум простаивающих соединений (пул PostgreSQL) | — |
|
| `LUI_DB_MAX_IDLE_CONNS` | Максимум простаивающих соединений (пул PostgreSQL) | — |
|
||||||
| `XUI_INIT_WEB_BASE_PATH` | Начальный URI-путь для веб-панели | `/` |
|
| `LUI_INIT_WEB_BASE_PATH` | Начальный URI-путь для веб-панели | `/` |
|
||||||
| `XUI_ENABLE_FAIL2BAN` | Включить применение лимитов IP на основе Fail2ban | `true` |
|
| `LUI_ENABLE_FAIL2BAN` | Включить применение лимитов IP на основе Fail2ban | `true` |
|
||||||
| `XUI_LOG_LEVEL` | Уровень логирования (`debug`, `info`, `warning`, `error`) | `info` |
|
| `LUI_LOG_LEVEL` | Уровень логирования (`debug`, `info`, `warning`, `error`) | `info` |
|
||||||
| `XUI_DEBUG` | Включить режим отладки | `false` |
|
| `LUI_DEBUG` | Включить режим отладки | `false` |
|
||||||
| `XUI_TUNNEL_HEALTH_MONITOR` | Включить монитор состояния туннеля (опрашивает URL и перезапускает xray после многократных сбоев; перезапуск отключает всех клиентов) | `false` |
|
| `LUI_TUNNEL_HEALTH_MONITOR` | Включить монитор состояния туннеля (опрашивает URL и перезапускает xray после многократных сбоев; перезапуск отключает всех клиентов) | `false` |
|
||||||
| `XUI_TUNNEL_HEALTH_PROXY` | Прокси, через который отправляется проба; укажите локальный входящий xray, чтобы проба проверяла туннель (например, `socks5://127.0.0.1:1080`). Пустое значение означает, что проба проверяет только связь с хостом | — |
|
| `LUI_TUNNEL_HEALTH_PROXY` | Прокси, через который отправляется проба; укажите локальный входящий xray, чтобы проба проверяла туннель (например, `socks5://127.0.0.1:1080`). Пустое значение означает, что проба проверяет только связь с хостом | — |
|
||||||
| `XUI_TUNNEL_HEALTH_URL` | URL, опрашиваемый для проверки состояния туннеля | `https://www.cloudflare.com/cdn-cgi/trace` |
|
| `LUI_TUNNEL_HEALTH_URL` | URL, опрашиваемый для проверки состояния туннеля | `https://www.cloudflare.com/cdn-cgi/trace` |
|
||||||
| `XUI_TUNNEL_HEALTH_INTERVAL` | Интервал между пробами | `30s` |
|
| `LUI_TUNNEL_HEALTH_INTERVAL` | Интервал между пробами | `30s` |
|
||||||
| `XUI_TUNNEL_HEALTH_TIMEOUT` | Таймаут на одну пробу | `10s` |
|
| `LUI_TUNNEL_HEALTH_TIMEOUT` | Таймаут на одну пробу | `10s` |
|
||||||
| `XUI_TUNNEL_HEALTH_FAILURES` | Число последовательных сбоев до запуска перезапуска | `3` |
|
| `LUI_TUNNEL_HEALTH_FAILURES` | Число последовательных сбоев до запуска перезапуска | `3` |
|
||||||
| `XUI_TUNNEL_HEALTH_COOLDOWN` | Минимальная задержка между последовательными перезапусками | `5m` |
|
| `LUI_TUNNEL_HEALTH_COOLDOWN` | Минимальная задержка между последовательными перезапусками | `5m` |
|
||||||
|
|
||||||
## Поддерживаемые языки
|
## Поддерживаемые языки
|
||||||
|
|
||||||
@@ -184,23 +179,10 @@ English · فارسی · العربية · 中文(简体) · 中文(繁體
|
|||||||
|
|
||||||
## Инструменты сообщества
|
## Инструменты сообщества
|
||||||
|
|
||||||
Инструменты и интеграции, созданные сообществом вокруг 3x-ui.
|
Инструменты и интеграции, созданные сообществом вокруг L-UI.
|
||||||
|
|
||||||
- [terraform-provider-3x-ui](https://github.com/batonogov/terraform-provider-threexui) (Лицензия: **MIT**): _Управление входящими, клиентами, настройками панели и конфигурацией Xray через код с помощью Terraform / OpenTofu._
|
- [terraform-provider-L-UI](https://github.com/batonogov/terraform-provider-threexui) (Лицензия: **MIT**): _Управление входящими, клиентами, настройками панели и конфигурацией Xray через код с помощью Terraform / OpenTofu._
|
||||||
|
|
||||||
## Поддержка проекта
|
## Поддержка проекта
|
||||||
|
|
||||||
**Если этот проект полезен для вас, вы можете поставить ему**:star2:
|
**Если этот проект полезен для вас, вы можете поставить ему**:star2:
|
||||||
|
|
||||||
<a href="https://www.buymeacoffee.com/MHSanaei" target="_blank">
|
|
||||||
<img src="./media/default-yellow.png" alt="Buy Me A Coffee" style="height: 70px !important;width: 277px !important;" >
|
|
||||||
</a>
|
|
||||||
|
|
||||||
</br>
|
|
||||||
<a href="https://nowpayments.io/donation/hsanaei" target="_blank" rel="noreferrer noopener">
|
|
||||||
<img src="./media/donation-button-black.svg" alt="Crypto donation button by NOWPayments">
|
|
||||||
</a>
|
|
||||||
|
|
||||||
## Звезды с течением времени
|
|
||||||
|
|
||||||
[](https://starchart.cc/MHSanaei/3x-ui)
|
|
||||||
|
|||||||
+36
-54
@@ -2,18 +2,13 @@
|
|||||||
|
|
||||||
<p align="center">
|
<p align="center">
|
||||||
<picture>
|
<picture>
|
||||||
<source media="(prefers-color-scheme: dark)" srcset="./media/3x-ui-dark.png">
|
<source media="(prefers-color-scheme: dark)" srcset="./media/L-UI-dark.png">
|
||||||
<img alt="3x-ui" src="./media/3x-ui-light.png">
|
<img alt="L-UI" src="./media/L-UI-light.png">
|
||||||
</picture>
|
</picture>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p align="center">
|
<p align="center">
|
||||||
<a href="https://github.com/MHSanaei/3x-ui/releases"><img src="https://img.shields.io/github/v/release/mhsanaei/3x-ui" alt="Release"></a>
|
|
||||||
<a href="https://github.com/MHSanaei/3x-ui/actions"><img src="https://img.shields.io/github/actions/workflow/status/mhsanaei/3x-ui/release.yml.svg" alt="Build"></a>
|
|
||||||
<a href="#"><img src="https://img.shields.io/github/go-mod/go-version/mhsanaei/3x-ui.svg" alt="GO Version"></a>
|
|
||||||
<a href="https://github.com/MHSanaei/3x-ui/releases/latest"><img src="https://img.shields.io/github/downloads/mhsanaei/3x-ui/total.svg" alt="Downloads"></a>
|
|
||||||
<a href="https://www.gnu.org/licenses/gpl-3.0.en.html"><img src="https://img.shields.io/badge/license-GPL%20V3-blue.svg?longCache=true" alt="License"></a>
|
<a href="https://www.gnu.org/licenses/gpl-3.0.en.html"><img src="https://img.shields.io/badge/license-GPL%20V3-blue.svg?longCache=true" alt="License"></a>
|
||||||
<a href="https://pkg.go.dev/github.com/mhsanaei/3x-ui/v3"><img src="https://pkg.go.dev/badge/github.com/mhsanaei/3x-ui/v3.svg" alt="Go Reference"></a>
|
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
**3X-UI**, [Xray-core](https://github.com/XTLS/Xray-core) sunucularını yönetmek için geliştirilmiş profesyonel, açık kaynaklı bir web kontrol panelidir. Tek bir sanal sunucudan (VPS) çok düğümlü (multi-node) dağıtımlara kadar çok çeşitli proxy ve VPN protokollerini kurmak, yapılandırmak ve izlemek için temiz, çok dilli bir arayüz sağlar.
|
**3X-UI**, [Xray-core](https://github.com/XTLS/Xray-core) sunucularını yönetmek için geliştirilmiş profesyonel, açık kaynaklı bir web kontrol panelidir. Tek bir sanal sunucudan (VPS) çok düğümlü (multi-node) dağıtımlara kadar çok çeşitli proxy ve VPN protokollerini kurmak, yapılandırmak ve izlemek için temiz, çok dilli bir arayüz sağlar.
|
||||||
@@ -69,31 +64,31 @@ Orijinal X-UI projesinin geliştirilmiş bir çatallaması (fork) olarak inşa e
|
|||||||
## Hızlı Başlangıç
|
## Hızlı Başlangıç
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
bash <(curl -Ls https://raw.githubusercontent.com/mhsanaei/3x-ui/master/install.sh)
|
bash <(curl -Ls https://git.881218.xyz/rogue/l-ui/raw/branch/main/install-master.sh)
|
||||||
```
|
```
|
||||||
|
|
||||||
Belirli bir sürümü kurmak için, etiketini (ör. `v3.4.0`) ekleyin:
|
Belirli bir sürümü kurmak için, etiketini (ör. `v3.4.0`) ekleyin:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
bash <(curl -Ls https://raw.githubusercontent.com/mhsanaei/3x-ui/master/install.sh) v3.4.0
|
# This fork provides no pinned-version one-click install; see the main README (README.md).
|
||||||
```
|
```
|
||||||
|
|
||||||
Sürekli güncellenen **dev** sürümünü (kararlı bir sürüm değil; `main` dalından her commit'te oluşturulan en son ön sürüm) kurmak için `dev-latest` değerini geçirin:
|
Sürekli güncellenen **dev** sürümünü (kararlı bir sürüm değil; `main` dalından her commit'te oluşturulan en son ön sürüm) kurmak için `dev-latest` değerini geçirin:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
bash <(curl -Ls https://raw.githubusercontent.com/mhsanaei/3x-ui/master/install.sh) dev-latest
|
# This fork provides no dev-channel one-click install; see the main README (README.md).
|
||||||
```
|
```
|
||||||
|
|
||||||
Kurulum sırasında rastgele bir kullanıcı adı, şifre ve erişim yolu oluşturulur. Kurulumdan sonra, hizmeti başlatabileceğiniz/durdurabileceğiniz, giriş bilgilerinizi görüntüleyebileceğiniz veya sıfırlayabileceğiniz, SSL sertifikalarını yönetebileceğiniz ve çok daha fazlasını yapabileceğiniz yönetim menüsünü açmak için terminalde `x-ui` komutunu çalıştırın.
|
Kurulum sırasında rastgele bir kullanıcı adı, şifre ve erişim yolu oluşturulur. Kurulumdan sonra, hizmeti başlatabileceğiniz/durdurabileceğiniz, giriş bilgilerinizi görüntüleyebileceğiniz veya sıfırlayabileceğiniz, SSL sertifikalarını yönetebileceğiniz ve çok daha fazlasını yapabileceğiniz yönetim menüsünü açmak için terminalde `l-ui` komutunu çalıştırın.
|
||||||
|
|
||||||
Tam dokümantasyon için lütfen [proje Wiki sayfasını](https://github.com/MHSanaei/3x-ui/wiki) ziyaret edin.
|
Tam dokümantasyon için lütfen [proje Wiki sayfasını](https://git.881218.xyz/rogue/l-ui) ziyaret edin.
|
||||||
|
|
||||||
### Etkileşimsiz kurulum
|
### Etkileşimsiz kurulum
|
||||||
|
|
||||||
Yükleyici, cloud-init için **etkileşimsiz** olarak da çalışır.
|
Yükleyici, cloud-init için **etkileşimsiz** olarak da çalışır.
|
||||||
`XUI_NONINTERACTIVE=1` ayarlayın (veya TTY olmadan boru hattına aktarın); kurulum baştan
|
`LUI_NONINTERACTIVE=1` ayarlayın (veya TTY olmadan boru hattına aktarın); kurulum baştan
|
||||||
sona hiçbir soru sormadan tamamlanır, rastgele kimlik bilgileri oluşturup bunları
|
sona hiçbir soru sormadan tamamlanır, rastgele kimlik bilgileri oluşturup bunları
|
||||||
`/etc/x-ui/install-result.env` dosyasına yazar. Şunlar için [`deploy/`](deploy/) klasörüne bakın:
|
`/etc/l-ui/install-result.env` dosyasına yazar. Şunlar için [`deploy/`](deploy/) klasörüne bakın:
|
||||||
|
|
||||||
- [Cloud-init user-data](deploy/cloud-init/) — herhangi bir bulutta etkileşimsiz kurulum (Hetzner/AWS/DO/Vultr/GCP/Azure/Oracle)
|
- [Cloud-init user-data](deploy/cloud-init/) — herhangi bir bulutta etkileşimsiz kurulum (Hetzner/AWS/DO/Vultr/GCP/Azure/Oracle)
|
||||||
- [Hetzner Cloud notları](deploy/marketplace/hetzner/) — Hetzner üzerinde cloud-init tabanlı dağıtım
|
- [Hetzner Cloud notları](deploy/marketplace/hetzner/) — Hetzner üzerinde cloud-init tabanlı dağıtım
|
||||||
@@ -108,29 +103,29 @@ sona hiçbir soru sormadan tamamlanır, rastgele kimlik bilgileri oluşturup bun
|
|||||||
|
|
||||||
3X-UI kurulum sırasında seçilebilecek iki arka uç (backend) destekler:
|
3X-UI kurulum sırasında seçilebilecek iki arka uç (backend) destekler:
|
||||||
|
|
||||||
- **SQLite** (varsayılan) — `/etc/x-ui/x-ui.db` konumunda tek bir dosya. Kurulum gerektirmez, küçük ve orta ölçekli dağıtımlar için idealdir.
|
- **SQLite** (varsayılan) — `/etc/l-ui/l-ui.db` konumunda tek bir dosya. Kurulum gerektirmez, küçük ve orta ölçekli dağıtımlar için idealdir.
|
||||||
- **PostgreSQL** — Yüksek kullanıcı sayıları veya çoklu düğüm (multi-node) kurulumları için önerilir. Yükleyici sizin için yerel olarak PostgreSQL kurabilir veya mevcut bir sunucuya DSN bağlantısı kabul edebilir.
|
- **PostgreSQL** — Yüksek kullanıcı sayıları veya çoklu düğüm (multi-node) kurulumları için önerilir. Yükleyici sizin için yerel olarak PostgreSQL kurabilir veya mevcut bir sunucuya DSN bağlantısı kabul edebilir.
|
||||||
|
|
||||||
Çalışma anında veritabanı türü ortam değişkenleri (environment variables) ile seçilir (yükleyici bunları sizin için `/etc/default/x-ui` dosyasına yazar):
|
Çalışma anında veritabanı türü ortam değişkenleri (environment variables) ile seçilir (yükleyici bunları sizin için `/etc/default/l-ui` dosyasına yazar):
|
||||||
|
|
||||||
```
|
```
|
||||||
XUI_DB_TYPE=postgres
|
LUI_DB_TYPE=postgres
|
||||||
XUI_DB_DSN=postgres://xui:password@127.0.0.1:5432/xui?sslmode=disable
|
LUI_DB_DSN=postgres://xui:password@127.0.0.1:5432/xui?sslmode=disable
|
||||||
```
|
```
|
||||||
|
|
||||||
### Mevcut bir SQLite Kurulumunu PostgreSQL'e Taşıma
|
### Mevcut bir SQLite Kurulumunu PostgreSQL'e Taşıma
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
x-ui migrate-db --dsn "postgres://xui:password@127.0.0.1:5432/xui?sslmode=disable"
|
l-ui migrate-db --dsn "postgres://xui:password@127.0.0.1:5432/xui?sslmode=disable"
|
||||||
# ardından /etc/default/x-ui içindeki XUI_DB_TYPE ve XUI_DB_DSN değerlerini ayarlayıp yeniden başlatın:
|
# ardından /etc/default/l-ui içindeki LUI_DB_TYPE ve LUI_DB_DSN değerlerini ayarlayıp yeniden başlatın:
|
||||||
systemctl restart x-ui
|
systemctl restart l-ui
|
||||||
```
|
```
|
||||||
|
|
||||||
Kaynak SQLite dosyasına dokunulmaz; yeni veritabanının düzgün çalıştığını doğruladıktan sonra eski SQLite dosyasını manuel olarak silebilirsiniz.
|
Kaynak SQLite dosyasına dokunulmaz; yeni veritabanının düzgün çalıştığını doğruladıktan sonra eski SQLite dosyasını manuel olarak silebilirsiniz.
|
||||||
|
|
||||||
### Docker
|
### Docker
|
||||||
|
|
||||||
Varsayılan `docker compose up -d` komutu SQLite kullanmaya devam eder. Birlikte paketlenmiş PostgreSQL servisi ile çalıştırmak için, `docker-compose.yml` dosyasındaki iki `XUI_DB_*` değişken satırının yorumunu kaldırın ve profille başlatın:
|
Varsayılan `docker compose up -d` komutu SQLite kullanmaya devam eder. Birlikte paketlenmiş PostgreSQL servisi ile çalıştırmak için, `docker-compose.yml` dosyasındaki iki `LUI_DB_*` değişken satırının yorumunu kaldırın ve profille başlatın:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
docker compose --profile postgres up -d
|
docker compose --profile postgres up -d
|
||||||
@@ -139,29 +134,29 @@ docker compose --profile postgres up -d
|
|||||||
Docker imajı, kullanıcı başına **IP limitlerini** zorunlu kılmak için Fail2ban ile (varsayılan olarak etkindir) paketlenmiştir. Fail2ban, ihlalcileri `iptables` ile engeller ve bunun için `NET_ADMIN` yetkisine ihtiyaç duyar. `docker-compose.yml` bunu zaten `cap_add` üzerinden vermektedir; ancak konteyneri bunun yerine `docker run` ile başlatırsanız bu yetkileri kendiniz eklemelisiniz, aksi takdirde yasaklamalar günlüğe kaydedilir ancak uygulanmaz:
|
Docker imajı, kullanıcı başına **IP limitlerini** zorunlu kılmak için Fail2ban ile (varsayılan olarak etkindir) paketlenmiştir. Fail2ban, ihlalcileri `iptables` ile engeller ve bunun için `NET_ADMIN` yetkisine ihtiyaç duyar. `docker-compose.yml` bunu zaten `cap_add` üzerinden vermektedir; ancak konteyneri bunun yerine `docker run` ile başlatırsanız bu yetkileri kendiniz eklemelisiniz, aksi takdirde yasaklamalar günlüğe kaydedilir ancak uygulanmaz:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
docker run -d --cap-add=NET_ADMIN --cap-add=NET_RAW ... ghcr.io/mhsanaei/3x-ui
|
docker run -d --cap-add=NET_ADMIN --cap-add=NET_RAW ... L-UI:local
|
||||||
```
|
```
|
||||||
|
|
||||||
## Ortam Değişkenleri (Environment Variables)
|
## Ortam Değişkenleri (Environment Variables)
|
||||||
|
|
||||||
| Değişken | Açıklama | Varsayılan |
|
| Değişken | Açıklama | Varsayılan |
|
||||||
| --- | --- | --- |
|
| --- | --- | --- |
|
||||||
| `XUI_DB_TYPE` | Veritabanı türü: `sqlite` veya `postgres` | `sqlite` |
|
| `LUI_DB_TYPE` | Veritabanı türü: `sqlite` veya `postgres` | `sqlite` |
|
||||||
| `XUI_DB_DSN` | PostgreSQL bağlantı dizesi (eğer `XUI_DB_TYPE=postgres` ise) | — |
|
| `LUI_DB_DSN` | PostgreSQL bağlantı dizesi (eğer `LUI_DB_TYPE=postgres` ise) | — |
|
||||||
| `XUI_DB_FOLDER` | SQLite veritabanı dizini | `/etc/x-ui` |
|
| `LUI_DB_FOLDER` | SQLite veritabanı dizini | `/etc/l-ui` |
|
||||||
| `XUI_DB_MAX_OPEN_CONNS` | Maksimum açık bağlantı sayısı (PostgreSQL havuzu) | — |
|
| `LUI_DB_MAX_OPEN_CONNS` | Maksimum açık bağlantı sayısı (PostgreSQL havuzu) | — |
|
||||||
| `XUI_DB_MAX_IDLE_CONNS` | Maksimum boşta bekleme bağlantısı (PostgreSQL havuzu) | — |
|
| `LUI_DB_MAX_IDLE_CONNS` | Maksimum boşta bekleme bağlantısı (PostgreSQL havuzu) | — |
|
||||||
| `XUI_INIT_WEB_BASE_PATH` | Web paneli için başlangıç URI yolu | `/` |
|
| `LUI_INIT_WEB_BASE_PATH` | Web paneli için başlangıç URI yolu | `/` |
|
||||||
| `XUI_ENABLE_FAIL2BAN` | Fail2ban tabanlı IP limit uygulamasını etkinleştir | `true` |
|
| `LUI_ENABLE_FAIL2BAN` | Fail2ban tabanlı IP limit uygulamasını etkinleştir | `true` |
|
||||||
| `XUI_LOG_LEVEL` | Günlük (Log) ayrıntı seviyesi (`debug`, `info`, `warning`, `error`) | `info` |
|
| `LUI_LOG_LEVEL` | Günlük (Log) ayrıntı seviyesi (`debug`, `info`, `warning`, `error`) | `info` |
|
||||||
| `XUI_DEBUG` | Hata ayıklama (debug) modunu etkinleştir | `false` |
|
| `LUI_DEBUG` | Hata ayıklama (debug) modunu etkinleştir | `false` |
|
||||||
| `XUI_TUNNEL_HEALTH_MONITOR` | Tünel sağlık izleyicisini etkinleştir (bir URL'yi yoklar ve tekrarlanan başarısızlıklardan sonra xray'i yeniden başlatır; yeniden başlatma tüm istemcilerin bağlantısını düşürür) | `false` |
|
| `LUI_TUNNEL_HEALTH_MONITOR` | Tünel sağlık izleyicisini etkinleştir (bir URL'yi yoklar ve tekrarlanan başarısızlıklardan sonra xray'i yeniden başlatır; yeniden başlatma tüm istemcilerin bağlantısını düşürür) | `false` |
|
||||||
| `XUI_TUNNEL_HEALTH_PROXY` | Yoklamanın gönderildiği proxy; yoklamanın tüneli test etmesi için bunu yerel bir xray gelen bağlantısına yönlendirin (ör. `socks5://127.0.0.1:1080`). Boş bırakılırsa yoklama yalnızca ana makine bağlantısını kontrol eder | — |
|
| `LUI_TUNNEL_HEALTH_PROXY` | Yoklamanın gönderildiği proxy; yoklamanın tüneli test etmesi için bunu yerel bir xray gelen bağlantısına yönlendirin (ör. `socks5://127.0.0.1:1080`). Boş bırakılırsa yoklama yalnızca ana makine bağlantısını kontrol eder | — |
|
||||||
| `XUI_TUNNEL_HEALTH_URL` | Tünel sağlığı için yoklanan URL | `https://www.cloudflare.com/cdn-cgi/trace` |
|
| `LUI_TUNNEL_HEALTH_URL` | Tünel sağlığı için yoklanan URL | `https://www.cloudflare.com/cdn-cgi/trace` |
|
||||||
| `XUI_TUNNEL_HEALTH_INTERVAL` | Yoklamalar arasındaki aralık | `30s` |
|
| `LUI_TUNNEL_HEALTH_INTERVAL` | Yoklamalar arasındaki aralık | `30s` |
|
||||||
| `XUI_TUNNEL_HEALTH_TIMEOUT` | Yoklama başına zaman aşımı | `10s` |
|
| `LUI_TUNNEL_HEALTH_TIMEOUT` | Yoklama başına zaman aşımı | `10s` |
|
||||||
| `XUI_TUNNEL_HEALTH_FAILURES` | Yeniden başlatma tetiklenmeden önceki ardışık başarısızlık sayısı | `3` |
|
| `LUI_TUNNEL_HEALTH_FAILURES` | Yeniden başlatma tetiklenmeden önceki ardışık başarısızlık sayısı | `3` |
|
||||||
| `XUI_TUNNEL_HEALTH_COOLDOWN` | Ardışık yeniden başlatmalar arasındaki minimum gecikme | `5m` |
|
| `LUI_TUNNEL_HEALTH_COOLDOWN` | Ardışık yeniden başlatmalar arasındaki minimum gecikme | `5m` |
|
||||||
|
|
||||||
## Desteklenen Diller
|
## Desteklenen Diller
|
||||||
|
|
||||||
@@ -184,23 +179,10 @@ Katkılarınızı her zaman bekliyoruz. Bir sorun (issue) açmadan veya pull req
|
|||||||
|
|
||||||
## Topluluk Araçları
|
## Topluluk Araçları
|
||||||
|
|
||||||
3x-ui çevresindeki topluluk tarafından oluşturulmuş araçlar ve entegrasyonlar.
|
L-UI çevresindeki topluluk tarafından oluşturulmuş araçlar ve entegrasyonlar.
|
||||||
|
|
||||||
- [terraform-provider-3x-ui](https://github.com/batonogov/terraform-provider-threexui) (Lisans: **MIT**): _Gelen bağlantılarnı, kullanıcıları, panel ayarlarını ve Xray yapılandırmasını Terraform / OpenTofu ile kod olarak (as code) yönetin._
|
- [terraform-provider-L-UI](https://github.com/batonogov/terraform-provider-threexui) (Lisans: **MIT**): _Gelen bağlantılarnı, kullanıcıları, panel ayarlarını ve Xray yapılandırmasını Terraform / OpenTofu ile kod olarak (as code) yönetin._
|
||||||
|
|
||||||
## Projeyi Destekleyin
|
## Projeyi Destekleyin
|
||||||
|
|
||||||
**Eğer bu proje size faydalı olduysa, bir yıldız verebilirsiniz**:star2:
|
**Eğer bu proje size faydalı olduysa, bir yıldız verebilirsiniz**:star2:
|
||||||
|
|
||||||
<a href="https://www.buymeacoffee.com/MHSanaei" target="_blank">
|
|
||||||
<img src="./media/default-yellow.png" alt="Bana Bir Kahve Ismarla" style="height: 70px !important;width: 277px !important;" >
|
|
||||||
</a>
|
|
||||||
|
|
||||||
</br>
|
|
||||||
<a href="https://nowpayments.io/donation/hsanaei" target="_blank" rel="noreferrer noopener">
|
|
||||||
<img src="./media/donation-button-black.svg" alt="NOWPayments üzerinden Kripto Bağış Butonu">
|
|
||||||
</a>
|
|
||||||
|
|
||||||
## Yıldız Tablosu
|
|
||||||
|
|
||||||
[](https://starchart.cc/MHSanaei/3x-ui)
|
|
||||||
|
|||||||
+37
-54
@@ -2,18 +2,14 @@
|
|||||||
|
|
||||||
<p align="center">
|
<p align="center">
|
||||||
<picture>
|
<picture>
|
||||||
<source media="(prefers-color-scheme: dark)" srcset="./media/3x-ui-dark.png">
|
<source media="(prefers-color-scheme: dark)" srcset="./media/L-UI-dark.png">
|
||||||
<img alt="3x-ui" src="./media/3x-ui-light.png">
|
<img alt="L-UI" src="./media/L-UI-light.png">
|
||||||
</picture>
|
</picture>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p align="center">
|
<p align="center">
|
||||||
<a href="https://github.com/MHSanaei/3x-ui/releases"><img src="https://img.shields.io/github/v/release/mhsanaei/3x-ui" alt="Release"></a>
|
|
||||||
<a href="https://github.com/MHSanaei/3x-ui/actions"><img src="https://img.shields.io/github/actions/workflow/status/mhsanaei/3x-ui/release.yml.svg" alt="Build"></a>
|
|
||||||
<a href="#"><img src="https://img.shields.io/github/go-mod/go-version/mhsanaei/3x-ui.svg" alt="GO Version"></a>
|
|
||||||
<a href="https://github.com/MHSanaei/3x-ui/releases/latest"><img src="https://img.shields.io/github/downloads/mhsanaei/3x-ui/total.svg" alt="Downloads"></a>
|
|
||||||
<a href="https://www.gnu.org/licenses/gpl-3.0.en.html"><img src="https://img.shields.io/badge/license-GPL%20V3-blue.svg?longCache=true" alt="License"></a>
|
<a href="https://www.gnu.org/licenses/gpl-3.0.en.html"><img src="https://img.shields.io/badge/license-GPL%20V3-blue.svg?longCache=true" alt="License"></a>
|
||||||
<a href="https://pkg.go.dev/github.com/mhsanaei/3x-ui/v3"><img src="https://pkg.go.dev/badge/github.com/mhsanaei/3x-ui/v3.svg" alt="Go Reference"></a>
|
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
**3X-UI** 是一个先进的开源 Web 控制面板,用于管理 [Xray-core](https://github.com/XTLS/Xray-core) 服务器。它提供简洁、多语言的界面,用于部署、配置和监控各种代理与 VPN 协议——从单台 VPS 到多节点部署。
|
**3X-UI** 是一个先进的开源 Web 控制面板,用于管理 [Xray-core](https://github.com/XTLS/Xray-core) 服务器。它提供简洁、多语言的界面,用于部署、配置和监控各种代理与 VPN 协议——从单台 VPS 到多节点部署。
|
||||||
@@ -69,31 +65,31 @@
|
|||||||
## 快速开始
|
## 快速开始
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
bash <(curl -Ls https://raw.githubusercontent.com/mhsanaei/3x-ui/master/install.sh)
|
bash <(curl -Ls https://git.881218.xyz/rogue/l-ui/raw/branch/main/install-master.sh)
|
||||||
```
|
```
|
||||||
|
|
||||||
若要安装特定版本,请在命令后附加对应的标签(例如 `v3.4.0`):
|
若要安装特定版本,请在命令后附加对应的标签(例如 `v3.4.0`):
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
bash <(curl -Ls https://raw.githubusercontent.com/mhsanaei/3x-ui/master/install.sh) v3.4.0
|
# This fork provides no pinned-version one-click install; see the main README (README.md).
|
||||||
```
|
```
|
||||||
|
|
||||||
若要安装滚动更新的 **dev** 版本(来自 `main` 的最新逐次提交预发布版本,而非稳定版本),请传入 `dev-latest`:
|
若要安装滚动更新的 **dev** 版本(来自 `main` 的最新逐次提交预发布版本,而非稳定版本),请传入 `dev-latest`:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
bash <(curl -Ls https://raw.githubusercontent.com/mhsanaei/3x-ui/master/install.sh) dev-latest
|
# This fork provides no dev-channel one-click install; see the main README (README.md).
|
||||||
```
|
```
|
||||||
|
|
||||||
安装过程中会生成随机的用户名、密码和访问路径。安装完成后,运行 `x-ui` 打开管理菜单,您可以在其中启动/停止服务、查看或重置登录凭据、管理 SSL 证书等。
|
安装过程中会生成随机的用户名、密码和访问路径。安装完成后,运行 `l-ui` 打开管理菜单,您可以在其中启动/停止服务、查看或重置登录凭据、管理 SSL 证书等。
|
||||||
|
|
||||||
完整文档请参阅 [项目Wiki](https://github.com/MHSanaei/3x-ui/wiki)。
|
完整文档请参阅 [项目Wiki](https://git.881218.xyz/rogue/l-ui)。
|
||||||
|
|
||||||
### 无人值守安装
|
### 无人值守安装
|
||||||
|
|
||||||
安装程序也可以**非交互式**运行,适用于 cloud-init。
|
安装程序也可以**非交互式**运行,适用于 cloud-init。
|
||||||
设置 `XUI_NONINTERACTIVE=1`(或在无 TTY 的情况下通过管道传入),它就会全程
|
设置 `LUI_NONINTERACTIVE=1`(或在无 TTY 的情况下通过管道传入),它就会全程
|
||||||
零提示地完成端到端安装,生成随机凭据并写入
|
零提示地完成端到端安装,生成随机凭据并写入
|
||||||
`/etc/x-ui/install-result.env`。请参阅 [`deploy/`](deploy/):
|
`/etc/l-ui/install-result.env`。请参阅 [`deploy/`](deploy/):
|
||||||
|
|
||||||
- [Cloud-init user-data](deploy/cloud-init/) — 在任意云平台上无人值守安装(Hetzner/AWS/DO/Vultr/GCP/Azure/Oracle)
|
- [Cloud-init user-data](deploy/cloud-init/) — 在任意云平台上无人值守安装(Hetzner/AWS/DO/Vultr/GCP/Azure/Oracle)
|
||||||
- [Hetzner Cloud 说明](deploy/marketplace/hetzner/) — 在 Hetzner 上基于 cloud-init 的部署
|
- [Hetzner Cloud 说明](deploy/marketplace/hetzner/) — 在 Hetzner 上基于 cloud-init 的部署
|
||||||
@@ -108,29 +104,29 @@ bash <(curl -Ls https://raw.githubusercontent.com/mhsanaei/3x-ui/master/install.
|
|||||||
|
|
||||||
3X-UI 支持两种后端,可在安装时选择:
|
3X-UI 支持两种后端,可在安装时选择:
|
||||||
|
|
||||||
- **SQLite**(默认)— 位于 `/etc/x-ui/x-ui.db` 的单个文件。无需配置,适合中小型部署。
|
- **SQLite**(默认)— 位于 `/etc/l-ui/l-ui.db` 的单个文件。无需配置,适合中小型部署。
|
||||||
- **PostgreSQL** — 推荐用于大量客户端或多节点设置。安装程序可以为您在本地安装 PostgreSQL,或接受指向现有服务器的 DSN。
|
- **PostgreSQL** — 推荐用于大量客户端或多节点设置。安装程序可以为您在本地安装 PostgreSQL,或接受指向现有服务器的 DSN。
|
||||||
|
|
||||||
运行时通过环境变量选择后端(安装程序会为您写入 `/etc/default/x-ui`):
|
运行时通过环境变量选择后端(安装程序会为您写入 `/etc/default/l-ui`):
|
||||||
|
|
||||||
```
|
```
|
||||||
XUI_DB_TYPE=postgres
|
LUI_DB_TYPE=postgres
|
||||||
XUI_DB_DSN=postgres://xui:password@127.0.0.1:5432/xui?sslmode=disable
|
LUI_DB_DSN=postgres://xui:password@127.0.0.1:5432/xui?sslmode=disable
|
||||||
```
|
```
|
||||||
|
|
||||||
### 将现有的 SQLite 安装迁移到 PostgreSQL
|
### 将现有的 SQLite 安装迁移到 PostgreSQL
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
x-ui migrate-db --dsn "postgres://xui:password@127.0.0.1:5432/xui?sslmode=disable"
|
l-ui migrate-db --dsn "postgres://xui:password@127.0.0.1:5432/xui?sslmode=disable"
|
||||||
# 然后在 /etc/default/x-ui 中设置 XUI_DB_TYPE 和 XUI_DB_DSN 并重启:
|
# 然后在 /etc/default/l-ui 中设置 LUI_DB_TYPE 和 LUI_DB_DSN 并重启:
|
||||||
systemctl restart x-ui
|
systemctl restart l-ui
|
||||||
```
|
```
|
||||||
|
|
||||||
源 SQLite 文件保持不变;在确认新后端正常工作后,请手动删除它。
|
源 SQLite 文件保持不变;在确认新后端正常工作后,请手动删除它。
|
||||||
|
|
||||||
### Docker
|
### Docker
|
||||||
|
|
||||||
默认的 `docker compose up -d` 仍使用 SQLite。若要使用捆绑的 PostgreSQL 服务运行,请取消注释 `docker-compose.yml` 中的两行 `XUI_DB_*` 环境变量,并使用该 profile 启动:
|
默认的 `docker compose up -d` 仍使用 SQLite。若要使用捆绑的 PostgreSQL 服务运行,请取消注释 `docker-compose.yml` 中的两行 `LUI_DB_*` 环境变量,并使用该 profile 启动:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
docker compose --profile postgres up -d
|
docker compose --profile postgres up -d
|
||||||
@@ -139,29 +135,29 @@ docker compose --profile postgres up -d
|
|||||||
该镜像捆绑了 Fail2ban(默认启用),用于强制执行按客户端的 **IP 限制**。Fail2ban 使用 `iptables` 封禁违规者,这需要 `NET_ADMIN` 权限。`docker-compose.yml` 已通过 `cap_add` 授予该权限;如果您改用 `docker run` 启动容器,请自行添加这些权限,否则封禁只会被记录而永远不会生效:
|
该镜像捆绑了 Fail2ban(默认启用),用于强制执行按客户端的 **IP 限制**。Fail2ban 使用 `iptables` 封禁违规者,这需要 `NET_ADMIN` 权限。`docker-compose.yml` 已通过 `cap_add` 授予该权限;如果您改用 `docker run` 启动容器,请自行添加这些权限,否则封禁只会被记录而永远不会生效:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
docker run -d --cap-add=NET_ADMIN --cap-add=NET_RAW ... ghcr.io/mhsanaei/3x-ui
|
docker run -d --cap-add=NET_ADMIN --cap-add=NET_RAW ... L-UI:local
|
||||||
```
|
```
|
||||||
|
|
||||||
## 环境变量
|
## 环境变量
|
||||||
|
|
||||||
| 变量 | 说明 | 默认值 |
|
| 变量 | 说明 | 默认值 |
|
||||||
| --- | --- | --- |
|
| --- | --- | --- |
|
||||||
| `XUI_DB_TYPE` | 数据库后端:`sqlite` 或 `postgres` | `sqlite` |
|
| `LUI_DB_TYPE` | 数据库后端:`sqlite` 或 `postgres` | `sqlite` |
|
||||||
| `XUI_DB_DSN` | PostgreSQL 连接字符串(当 `XUI_DB_TYPE=postgres` 时) | — |
|
| `LUI_DB_DSN` | PostgreSQL 连接字符串(当 `LUI_DB_TYPE=postgres` 时) | — |
|
||||||
| `XUI_DB_FOLDER` | SQLite 数据库文件所在目录 | `/etc/x-ui` |
|
| `LUI_DB_FOLDER` | SQLite 数据库文件所在目录 | `/etc/l-ui` |
|
||||||
| `XUI_DB_MAX_OPEN_CONNS` | 最大打开连接数(PostgreSQL 连接池) | — |
|
| `LUI_DB_MAX_OPEN_CONNS` | 最大打开连接数(PostgreSQL 连接池) | — |
|
||||||
| `XUI_DB_MAX_IDLE_CONNS` | 最大空闲连接数(PostgreSQL 连接池) | — |
|
| `LUI_DB_MAX_IDLE_CONNS` | 最大空闲连接数(PostgreSQL 连接池) | — |
|
||||||
| `XUI_INIT_WEB_BASE_PATH` | Web 面板的初始 URI 路径 | `/` |
|
| `LUI_INIT_WEB_BASE_PATH` | Web 面板的初始 URI 路径 | `/` |
|
||||||
| `XUI_ENABLE_FAIL2BAN` | 启用基于 Fail2ban 的 IP 限制 | `true` |
|
| `LUI_ENABLE_FAIL2BAN` | 启用基于 Fail2ban 的 IP 限制 | `true` |
|
||||||
| `XUI_LOG_LEVEL` | 日志级别(`debug`、`info`、`warning`、`error`) | `info` |
|
| `LUI_LOG_LEVEL` | 日志级别(`debug`、`info`、`warning`、`error`) | `info` |
|
||||||
| `XUI_DEBUG` | 启用调试模式 | `false` |
|
| `LUI_DEBUG` | 启用调试模式 | `false` |
|
||||||
| `XUI_TUNNEL_HEALTH_MONITOR` | 启用隧道健康监控(探测某个 URL,在连续多次失败后重启 xray;重启会断开所有客户端) | `false` |
|
| `LUI_TUNNEL_HEALTH_MONITOR` | 启用隧道健康监控(探测某个 URL,在连续多次失败后重启 xray;重启会断开所有客户端) | `false` |
|
||||||
| `XUI_TUNNEL_HEALTH_PROXY` | 探测请求所经过的代理;将其指向本地 xray 入站,使探测能够测试隧道(例如 `socks5://127.0.0.1:1080`)。留空表示探测仅检查主机连通性 | — |
|
| `LUI_TUNNEL_HEALTH_PROXY` | 探测请求所经过的代理;将其指向本地 xray 入站,使探测能够测试隧道(例如 `socks5://127.0.0.1:1080`)。留空表示探测仅检查主机连通性 | — |
|
||||||
| `XUI_TUNNEL_HEALTH_URL` | 用于检测隧道健康状况的探测 URL | `https://www.cloudflare.com/cdn-cgi/trace` |
|
| `LUI_TUNNEL_HEALTH_URL` | 用于检测隧道健康状况的探测 URL | `https://www.cloudflare.com/cdn-cgi/trace` |
|
||||||
| `XUI_TUNNEL_HEALTH_INTERVAL` | 两次探测之间的间隔 | `30s` |
|
| `LUI_TUNNEL_HEALTH_INTERVAL` | 两次探测之间的间隔 | `30s` |
|
||||||
| `XUI_TUNNEL_HEALTH_TIMEOUT` | 单次探测的超时时间 | `10s` |
|
| `LUI_TUNNEL_HEALTH_TIMEOUT` | 单次探测的超时时间 | `10s` |
|
||||||
| `XUI_TUNNEL_HEALTH_FAILURES` | 触发重启前的连续失败次数 | `3` |
|
| `LUI_TUNNEL_HEALTH_FAILURES` | 触发重启前的连续失败次数 | `3` |
|
||||||
| `XUI_TUNNEL_HEALTH_COOLDOWN` | 两次连续重启之间的最小间隔 | `5m` |
|
| `LUI_TUNNEL_HEALTH_COOLDOWN` | 两次连续重启之间的最小间隔 | `5m` |
|
||||||
|
|
||||||
## 支持的语言
|
## 支持的语言
|
||||||
|
|
||||||
@@ -184,23 +180,10 @@ English · فارسی · العربية · 中文(简体) · 中文(繁體
|
|||||||
|
|
||||||
## 社区工具
|
## 社区工具
|
||||||
|
|
||||||
社区围绕 3x-ui 构建的工具和集成。
|
社区围绕 L-UI 构建的工具和集成。
|
||||||
|
|
||||||
- [terraform-provider-3x-ui](https://github.com/batonogov/terraform-provider-threexui) (许可证: **MIT**): _使用 Terraform / OpenTofu 通过代码管理入站、客户端、面板设置和 Xray 配置。_
|
- [terraform-provider-L-UI](https://github.com/batonogov/terraform-provider-threexui) (许可证: **MIT**): _使用 Terraform / OpenTofu 通过代码管理入站、客户端、面板设置和 Xray 配置。_
|
||||||
|
|
||||||
## 支持项目
|
## 支持项目
|
||||||
|
|
||||||
**如果这个项目对您有帮助,您可以给它一个**:star2:
|
**如果这个项目对您有帮助,您可以给它一个**:star2:
|
||||||
|
|
||||||
<a href="https://www.buymeacoffee.com/MHSanaei" target="_blank">
|
|
||||||
<img src="./media/default-yellow.png" alt="Buy Me A Coffee" style="height: 70px !important;width: 277px !important;" >
|
|
||||||
</a>
|
|
||||||
|
|
||||||
</br>
|
|
||||||
<a href="https://nowpayments.io/donation/hsanaei" target="_blank" rel="noreferrer noopener">
|
|
||||||
<img src="./media/donation-button-black.svg" alt="Crypto donation button by NOWPayments">
|
|
||||||
</a>
|
|
||||||
|
|
||||||
## 随时间变化的星标数
|
|
||||||
|
|
||||||
[](https://starchart.cc/MHSanaei/3x-ui)
|
|
||||||
|
|||||||
+195
@@ -0,0 +1,195 @@
|
|||||||
|
# Renaming: 3x-ui / x-ui → L-UI / l-ui / lui-agent
|
||||||
|
|
||||||
|
Base: `8158ced` (panel V2.6.0 / agent A2.5.0). This batch is a pure
|
||||||
|
rename: **no version bump, no feature change, no production change,
|
||||||
|
no Gitea change, no release**. Versions stay V2.6.0 / A2.5.0; the
|
||||||
|
version bump is left to the release step (see Pending below).
|
||||||
|
|
||||||
|
## Mapping (exact — do not invent other aliases)
|
||||||
|
|
||||||
|
| old | new | where it shows up |
|
||||||
|
| --- | --- | --- |
|
||||||
|
| display brand `3x-ui` / `x-ui` | `L-UI` | panel UI, i18n, README, docs |
|
||||||
|
| panel binary / process | `l-ui` | release asset, `ps`, `/usr/bin/l-ui` (Docker), `l-ui setting …` |
|
||||||
|
| agent binary / process | `lui-agent` | release asset, `ps`, `lui-agent agent …` |
|
||||||
|
| install dir | `/usr/local/l-ui` | panel + agent binaries |
|
||||||
|
| config / state dir | `/etc/l-ui` | `agent.json`, `node_token_key.json`, env files |
|
||||||
|
| panel DB | `/etc/l-ui/l-ui.db` | driven by `internal/config/name` (`l-ui`) via `GetName()` + `GetDBFolderPath()` — no separate DB-name constant |
|
||||||
|
| probe DB | `/etc/l-ui/probe.db` | name unchanged, directory moved (`probe/store.go` joins `GetDBFolderPath()`) |
|
||||||
|
| cert dir | `/etc/l-ui/cert` | panel + subscription share it |
|
||||||
|
| binary dir | `/usr/local/l-ui/bin` | `DefaultBinFolder`; sing-box live config `config-singbox.json` lives here |
|
||||||
|
| log dir | `/var/log/l-ui` | panel log, agent log, sing-box log |
|
||||||
|
| panel service | `l-ui.service` | systemd units `l-ui.service.{debian,arch,rhel}`, OpenRC `l-ui.rc` |
|
||||||
|
| agent service | `lui-agent.service` | `systemd/lui-agent.service`, OpenRC `openrc/lui-agent` |
|
||||||
|
| management CLI | `l-ui.sh` | was `x-ui.sh`; Docker copies it to `/usr/bin/l-ui` |
|
||||||
|
| panel release assets | `l-ui-linux-amd64`, `l-ui-linux-arm64` (+ `.sha256`) | `scripts/release-build.sh`, `selfupdate.AssetName` |
|
||||||
|
| agent release assets | `lui-agent-linux-amd64`, `lui-agent-linux-arm64` (+ `.sha256`) | `scripts/release-build.sh`, `selfupdate.AgentAssetName` |
|
||||||
|
| agent version marker | `agent-version.txt` | name unchanged |
|
||||||
|
| env prefix | `LUI_` | every `XUI_` variable, code + scripts + docs + tests (inventory below) |
|
||||||
|
| source dir (Linux agent) | `cmd/lui-agent` | was `cmd/xui-agent`; `release-build.sh` builds `./cmd/lui-agent` |
|
||||||
|
| Gitea repo (PLACEHOLDER) | `rogue/l-ui` | see Pending — **not yet real** |
|
||||||
|
|
||||||
|
## Environment variables renamed
|
||||||
|
|
||||||
|
Code reads **only** the new `LUI_` prefix. There is no dual-read
|
||||||
|
fallback in code: an old unit file that still exports `XUI_*` will
|
||||||
|
silently lose those settings, which is why the migration doc
|
||||||
|
(`docs/migration-l-ui.md`) has an explicit unit-env translation
|
||||||
|
table. Old units must be replaced, not edited in place.
|
||||||
|
|
||||||
|
Full inventory (from a whole-tree scan; `LUI_DB_*` below is a docs
|
||||||
|
glob, not a variable):
|
||||||
|
|
||||||
|
`LUI_ACCESS_URL`, `LUI_ACME_EMAIL`, `LUI_ACME_HTTP_PORT`,
|
||||||
|
`LUI_API_TOKEN`, `LUI_B1_OLD_BACKUP`, `LUI_B2_OLD_DB`,
|
||||||
|
`LUI_BIN_FOLDER`, `LUI_DB_CACHE_MB`, `LUI_DB_DSN`,
|
||||||
|
`LUI_DB_FOLDER`, `LUI_DB_JOURNAL_MODE`, `LUI_DB_MAX_IDLE_CONNS`,
|
||||||
|
`LUI_DB_MAX_OPEN_CONNS`, `LUI_DB_MMAP_MB`, `LUI_DB_SYNCHRONOUS`,
|
||||||
|
`LUI_DB_TYPE`, `LUI_DEBUG`, `LUI_DOMAIN`, `LUI_ENABLE_FAIL2BAN`,
|
||||||
|
`LUI_GOGC`, `LUI_HOME` (install-agent.sh only), `LUI_INIT_SYSTEM`
|
||||||
|
(install-agent.sh only), `LUI_INIT_WEB_BASE_PATH`, `LUI_IN_DOCKER`,
|
||||||
|
`LUI_LOG_FOLDER`, `LUI_LOG_LEVEL`, `LUI_MAIN_FOLDER`,
|
||||||
|
`LUI_MEMORY_LIMIT`, `LUI_MEMORY_RELEASE_INTERVAL`,
|
||||||
|
`LUI_NODE_TOKEN_KEY`, `LUI_NODE_TOKEN_KEY_FILE`,
|
||||||
|
`LUI_NODE_TOKEN_KEY_TEST`, `LUI_NONINTERACTIVE`,
|
||||||
|
`LUI_ORPHAN_DUMMY`, `LUI_PANEL_PORT`, `LUI_PASSWORD`, `LUI_PORT`,
|
||||||
|
`LUI_PPROF`, `LUI_RELEASE_BASE_URL`, `LUI_RELEASE_LATEST_URL`,
|
||||||
|
`LUI_ROOT` (install-agent.sh only), `LUI_SCALE_DB_PATH`,
|
||||||
|
`LUI_SCALE_SIZES`, `LUI_SCALE_TEST`, `LUI_SELFUPDATE_SYSTEMD`,
|
||||||
|
`LUI_SERVER_IP`, `LUI_SERVICE`, `LUI_SERVICE_NAME`,
|
||||||
|
`LUI_SINGBOX_BIN`, `LUI_SKIP_HSTS`, `LUI_SMOKE_VERSION`,
|
||||||
|
`LUI_SOURCEMAP`, `LUI_SSL_IPV6`, `LUI_SSL_MODE`,
|
||||||
|
`LUI_TEST_PG_DSN`, `LUI_TUNNEL_HEALTH_COOLDOWN`,
|
||||||
|
`LUI_TUNNEL_HEALTH_FAILURES`, `LUI_TUNNEL_HEALTH_INTERVAL`,
|
||||||
|
`LUI_TUNNEL_HEALTH_MONITOR`, `LUI_TUNNEL_HEALTH_PROXY`,
|
||||||
|
`LUI_TUNNEL_HEALTH_TIMEOUT`, `LUI_TUNNEL_HEALTH_URL`,
|
||||||
|
`LUI_UPDATE_RUN_ID`, `LUI_UPDATE_STATUS_FILE`, `LUI_UPDATE_TAG`,
|
||||||
|
`LUI_URL` (install scripts only), `LUI_USERNAME`,
|
||||||
|
`LUI_WEB_BASE_PATH`.
|
||||||
|
|
||||||
|
## sing-box orphan-core check (special re-verification)
|
||||||
|
|
||||||
|
The orphan scan (`internal/agent/singbox.go`,
|
||||||
|
`singboxCmdlineMatchesConfig`) matches a core process by the exact
|
||||||
|
argv triple `run -c <live config path>`. Both sides use the same
|
||||||
|
source: the live path is `filepath.Join(config.GetBinFolderPath(),
|
||||||
|
"config-singbox.json")`, and the agent sets `LUI_BIN_FOLDER` to
|
||||||
|
`DefaultBinFolder` (`/usr/local/l-ui/bin`) when unset. So the rename
|
||||||
|
propagates to both the writer and the matcher automatically; there
|
||||||
|
is no hardcoded old path in `singbox.go`. After migration the only
|
||||||
|
cores the new agent will reap are cores started with
|
||||||
|
`/usr/local/l-ui/bin/config-singbox.json` — a core still running
|
||||||
|
the old `/usr/local/x-ui/bin/config-singbox.json` is **not** matched
|
||||||
|
and must be killed by the migration step (see migration doc), or it
|
||||||
|
will hold the inbound ports and the new core will fail to bind.
|
||||||
|
This is the one place where "rename both sides" is not enough: the
|
||||||
|
old core has to be stopped, not re-adopted.
|
||||||
|
|
||||||
|
## Tianyi update badge (same batch, panel side only)
|
||||||
|
|
||||||
|
- Backend: `NodeView.agentOs` (from `AgentNode.ProbeOS`), overlaid
|
||||||
|
in `annotateAgentTelemetry` ahead of the telemetry early-exit,
|
||||||
|
like `ProbeOnly`.
|
||||||
|
- Frontend: both badge sites in `NodeList.tsx` (list column +
|
||||||
|
detail) now gate on `!isWindowsAgentOS(agentOs)`, where the
|
||||||
|
helper (in `panel-version.ts`) is a case-insensitive `windows`
|
||||||
|
prefix test. Empty OS fails open (badge as before).
|
||||||
|
- Backend: `requestAgentUpdate` refuses Windows rows up front
|
||||||
|
("not available on Windows … re-running install-agent.ps1")
|
||||||
|
instead of recording an intent that would only age out. The
|
||||||
|
one-click action button itself is unchanged; clicking it on a
|
||||||
|
Windows row now errors clearly.
|
||||||
|
- Why ProbeOS is reliable: the frozen A2.2.1 Windows agent reports
|
||||||
|
`probeFacts.os` = `winOSName()` — registry ProductName
|
||||||
|
("Windows 10", "Windows 11", …) with DisplayVersion appended,
|
||||||
|
falling back to bare "Windows" — on register and on heartbeat,
|
||||||
|
and the panel persists it to `probe_os` (pinned by
|
||||||
|
`TestAgentLegacyWindows221Contract`). No fake version, no
|
||||||
|
per-node freeze switch, no Windows agent change, no new win asset.
|
||||||
|
- Tianyi's machine itself is untouched; its agent stays A2.2.1.
|
||||||
|
|
||||||
|
## Intentionally kept (not omissions)
|
||||||
|
|
||||||
|
- **Go module path `github.com/mhsanaei/3x-ui/v3`** — the upstream
|
||||||
|
import path. Renaming it would break every import and the
|
||||||
|
`-ldflags -X` injection paths; it is not user-visible.
|
||||||
|
- **Upstream mentions** — sentences that name the upstream original
|
||||||
|
("upstream 3x-ui", "stock 3x-ui", "based on upstream 3x-ui",
|
||||||
|
`ghcr.io/mhsanaei/3x-ui`, `raw.githubusercontent.com/mhsanaei/3x-ui`)
|
||||||
|
stay, because that is the upstream project's actual name.
|
||||||
|
- **Windows agent, frozen** — `cmd/xui-agent-windows/` untouched:
|
||||||
|
service name `x-ui-agent`, `C:\x-ui\agent.json`, display name
|
||||||
|
"3x-ui Agent", `x-ui-agent-windows.exe`. The shipped A2.2.1
|
||||||
|
binary cannot change without a new win release, which this batch
|
||||||
|
explicitly does not ship. Renaming its source would only make
|
||||||
|
the source lie about the shipped binary.
|
||||||
|
- **`install-agent.ps1` untouched** — see Pending.
|
||||||
|
- **Log filenames `3xui.log`, `3xipl.log`, `3xipl-banned.log` and
|
||||||
|
the fail2ban jail name `3x-ipl`** — only their directory moves
|
||||||
|
(`/var/log/l-ui/`). Renaming the files would break external
|
||||||
|
fail2ban configs beyond the directory move the migration
|
||||||
|
already requires.
|
||||||
|
- **Docker Postgres user/DB `xui`** — renaming them would orphan
|
||||||
|
existing `pgdata` volumes (a fresh empty DB would appear and
|
||||||
|
the panel would start empty). Service/container names were
|
||||||
|
renamed (`l-ui`, `l-ui_app`, `l-ui_postgres`); credentials kept.
|
||||||
|
- **Windows-only DB copy in `internal/config/config.go` `init()`** —
|
||||||
|
its source is now explicitly `/etc/x-ui/x-ui.db` (the only
|
||||||
|
pre-rename path left in Go code, as a copy source only). Normal
|
||||||
|
operation never reads it; operator migration moves the DB by mv.
|
||||||
|
- **`install-agent.sh` legacy-process kill** — it now kills both
|
||||||
|
`/usr/local/l-ui/l-ui agent` and `/usr/local/x-ui/x-ui agent`.
|
||||||
|
The old form is a one-time migration cleanup, not a runtime
|
||||||
|
dual-path fallback; it can be deleted once old forms are gone.
|
||||||
|
- **`frontend/src/generated/schemas.ts`** — generated by
|
||||||
|
`tools/openapigen`, marked DO NOT EDIT. Its three "3x-ui panel"
|
||||||
|
descriptions come from Go model comments and will refresh on
|
||||||
|
the next regeneration; hand-editing a generated file would be
|
||||||
|
overwritten anyway.
|
||||||
|
- **Tracked test binaries `x-ui-agent-test-amd64`,
|
||||||
|
`x-ui-master-new-amd64`, `x-ui-with-ui-amd64`** — stale ELF
|
||||||
|
artifacts committed earlier, not referenced by any script or by
|
||||||
|
`release-build.sh`, not release assets. Left untouched (not
|
||||||
|
rebuilt, not renamed); deleting committed binaries is a separate
|
||||||
|
cleanup decision, not part of this rename.
|
||||||
|
- **`docs/release.md` version-table examples (V2.4.0 / A2.3.0)** —
|
||||||
|
pre-existing stale examples, not version constants; left as-is
|
||||||
|
so this diff stays a rename. The agent-change glob there now
|
||||||
|
reads `cmd/lui-agent*`, which correctly excludes the frozen
|
||||||
|
Windows dir (Windows-only changes must not move the agent line).
|
||||||
|
|
||||||
|
## Pending / must be decided before any release
|
||||||
|
|
||||||
|
1. **Gitea repo spelling (BLOCKER).** `rogue/l-ui` is a placeholder.
|
||||||
|
The Gitea repo has NOT been renamed in this batch and must not
|
||||||
|
be assumed renamed. Before any release: user confirms the exact
|
||||||
|
spelling, then update `internal/selfupdate/selfupdate.go`
|
||||||
|
(annotated in code), `internal/web/service/panel/panel.go`,
|
||||||
|
`scripts/release-build.sh`, `install-agent.sh`,
|
||||||
|
`install-master.sh`, `update.sh`, `install.sh`, `docs/release.md`
|
||||||
|
and every `rogue/l-ui` URL in the tree to the confirmed spelling.
|
||||||
|
Until then, the renamed update check points at a repo that does
|
||||||
|
not exist yet — this branch must not be released as-is.
|
||||||
|
2. **Version bump.** Panel stays V2.6.0, agent stays A2.5.0 in this
|
||||||
|
diff. The release step must bump the panel line (and the agent
|
||||||
|
line only if agent code changed in the release commit) and
|
||||||
|
`install-agent.sh`'s `RELEASE_BASE`.
|
||||||
|
3. **`install-agent.ps1` (Windows, frozen, TYYUN only).** Untouched
|
||||||
|
on purpose: it is pinned to the V2.4.0 release base and
|
||||||
|
downloads `x-ui-agent-windows-amd64.exe` into `C:\x-ui`.
|
||||||
|
After the Gitea repo is renamed, that download URL
|
||||||
|
(`rogue/3x-ui-agent/releases/download/V2.4.0/…`) will 404
|
||||||
|
unless one of these is chosen: (a) leave ps1 alone and accept
|
||||||
|
that a future Windows reinstall needs a manual exe (the frozen
|
||||||
|
line needs no reinstall by design); (b) update only its repo
|
||||||
|
segment to the confirmed spelling, keeping the V2.4.0 pin and
|
||||||
|
the old asset name (the V2.4.0 release's assets keep their old
|
||||||
|
names only if the repo is renamed without re-uploading them —
|
||||||
|
verify before choosing); (c) unfreeze Windows and ship a new
|
||||||
|
win asset (out of scope for this batch). Do NOT quietly bump
|
||||||
|
its pin to a release that has no win asset.
|
||||||
|
4. **Generated schemas regeneration** — run `tools/openapigen`
|
||||||
|
at release time so `frontend/src/generated/schemas.ts`
|
||||||
|
descriptions pick up the L-UI wording.
|
||||||
|
5. **Tracked test binaries** — decide separately whether to delete
|
||||||
|
the three stale ELF files from the repo.
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
# Review instructions
|
# Review instructions
|
||||||
|
|
||||||
3x-ui is a Go (Gin + GORM) web panel that generates configuration, share links
|
L-UI is a Go (Gin + GORM) web panel that generates configuration, share links
|
||||||
and subscriptions for other programs — Xray-core, mihomo, sing-box, mtg-multi —
|
and subscriptions for other programs — Xray-core, mihomo, sing-box, mtg-multi —
|
||||||
and is deployed by operators who upgrade in place. Judge findings by what
|
and is deployed by operators who upgrade in place. Judge findings by what
|
||||||
breaks for those consumers and operators, not by style.
|
breaks for those consumers and operators, not by style.
|
||||||
@@ -111,7 +111,7 @@ near-certain about and that actually breaks something:
|
|||||||
- "CI passed" is a claim too, and needs the same evidence: say it only of a
|
- "CI passed" is a claim too, and needs the same evidence: say it only of a
|
||||||
run you actually read. A green one proves less here than it looks — only
|
run you actually read. A green one proves less here than it looks — only
|
||||||
`postgres-durable-first` runs against PostgreSQL, `go-test` and `race` are
|
`postgres-durable-first` runs against PostgreSQL, `go-test` and `race` are
|
||||||
SQLite, and `XRAY_E2E_BINARY` and `XUI_SCALE_TEST` are set by no job, so
|
SQLite, and `XRAY_E2E_BINARY` and `LUI_SCALE_TEST` are set by no job, so
|
||||||
those tests have never run in CI at all. Where a change touches dialect,
|
those tests have never run in CI at all. Where a change touches dialect,
|
||||||
migration or Xray gRPC code that no job exercised, say it is unverified
|
migration or Xray gRPC code that no job exercised, say it is unverified
|
||||||
rather than repeating a green tick as proof.
|
rather than repeating a green tick as proof.
|
||||||
|
|||||||
+2
-2
@@ -5,11 +5,11 @@
|
|||||||
Do not open a public issue for anything you believe is exploitable — an
|
Do not open a public issue for anything you believe is exploitable — an
|
||||||
authentication bypass, remote code execution, injection, secret or
|
authentication bypass, remote code execution, injection, secret or
|
||||||
credential exposure, privilege escalation. A public report gives attackers
|
credential exposure, privilege escalation. A public report gives attackers
|
||||||
a head start against every 3x-ui deployment.
|
a head start against every L-UI deployment.
|
||||||
|
|
||||||
Instead, use GitHub's private vulnerability reporting: open this
|
Instead, use GitHub's private vulnerability reporting: open this
|
||||||
repository's **Security** tab and click **Report a vulnerability**. Include
|
repository's **Security** tab and click **Report a vulnerability**. Include
|
||||||
the affected 3x-ui version, reproduction steps, and the impact you see.
|
the affected L-UI version, reproduction steps, and the impact you see.
|
||||||
You will receive replies in the advisory thread.
|
You will receive replies in the advisory thread.
|
||||||
|
|
||||||
There is no bug-bounty program. Fixes ship in the next release, and the
|
There is no bug-bounty program. Fixes ship in the next release, and the
|
||||||
|
|||||||
+4
-2
@@ -125,7 +125,9 @@ func TestBotContextSkipGatesExist(t *testing.T) {
|
|||||||
table := section(t, doc, "**What CI does NOT prove.**", "Mutation testing")
|
table := section(t, doc, "**What CI does NOT prove.**", "Mutation testing")
|
||||||
// [A-Z0-9_] and not [A-Z_]: XRAY_E2E_BINARY carries a digit, and excluding it
|
// [A-Z0-9_] and not [A-Z_]: XRAY_E2E_BINARY carries a digit, and excluding it
|
||||||
// silently dropped that gate from the check instead of failing.
|
// silently dropped that gate from the check instead of failing.
|
||||||
gates := regexp.MustCompile("`((?:XUI|XRAY)_[A-Z0-9_]+)`").FindAllStringSubmatch(table, -1)
|
// LUI_ joins XUI_ here because the rename changed the env prefix; the
|
||||||
|
// old prefix stays so a stray XUI_ gate still gets checked, not ignored.
|
||||||
|
gates := regexp.MustCompile("`((?:LUI|XUI|XRAY)_[A-Z0-9_]+)`").FindAllStringSubmatch(table, -1)
|
||||||
if len(gates) < 5 {
|
if len(gates) < 5 {
|
||||||
t.Fatalf("expected at least 5 skip-gate variables in %s, found %d", botContextPath, len(gates))
|
t.Fatalf("expected at least 5 skip-gate variables in %s, found %d", botContextPath, len(gates))
|
||||||
}
|
}
|
||||||
@@ -171,7 +173,7 @@ func TestReviewNamesRealCIJobsAndGates(t *testing.T) {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
for _, g := range regexp.MustCompile("`((?:XUI|XRAY)_[A-Z0-9_]+)`").FindAllStringSubmatch(doc, -1) {
|
for _, g := range regexp.MustCompile("`((?:LUI|XUI|XRAY)_[A-Z0-9_]+)`").FindAllStringSubmatch(doc, -1) {
|
||||||
t.Run(g[1], func(t *testing.T) {
|
t.Run(g[1], func(t *testing.T) {
|
||||||
if strings.Contains(ci, g[1]) {
|
if strings.Contains(ci, g[1]) {
|
||||||
t.Errorf("%s claims %s is never set in CI, but %s sets it", reviewPath, g[1], ciWorkflowPath)
|
t.Errorf("%s claims %s is never set in CI, but %s sets it", reviewPath, g[1], ciWorkflowPath)
|
||||||
|
|||||||
@@ -0,0 +1,133 @@
|
|||||||
|
// Command lui-agent is the standalone Linux build of the L-UI node
|
||||||
|
// agent (agent/panel split, phase 1). Until the split, nodes ran the
|
||||||
|
// panel binary under the "agent" subcommand, shipping the whole web
|
||||||
|
// panel and the embedded frontend to every node. This entry links only
|
||||||
|
// the agent's own dependency closure (internal/agent plus config,
|
||||||
|
// logger, selfupdate, xray-api types and a few util leaves), so the node
|
||||||
|
// artifact is a fraction of the panel binary while remaining a drop-in
|
||||||
|
// replacement for it:
|
||||||
|
//
|
||||||
|
// - invocation is unchanged: service units run
|
||||||
|
// "lui-agent agent [-config /etc/l-ui/agent.json]" (the bare
|
||||||
|
// "-config" form is also accepted for manual runs);
|
||||||
|
// - agent.json, the traffic baseline and the other state files keep
|
||||||
|
// their names, locations and formats;
|
||||||
|
// - the wire protocol with the master (register / heartbeat /
|
||||||
|
// config / traffic / probe-report / update intent) is byte-for-
|
||||||
|
// byte the internal/agent implementation the dual-mode binary ran.
|
||||||
|
//
|
||||||
|
// The agent lifecycle wiring below mirrors main.go's agent branch
|
||||||
|
// exactly — the same internal/agent package does the work either way,
|
||||||
|
// and cmd/xui-agent-windows is the Windows sibling of this entry.
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"flag"
|
||||||
|
"fmt"
|
||||||
|
"log"
|
||||||
|
"net/http"
|
||||||
|
_ "net/http/pprof"
|
||||||
|
"os"
|
||||||
|
"os/signal"
|
||||||
|
"path/filepath"
|
||||||
|
"syscall"
|
||||||
|
|
||||||
|
"github.com/mhsanaei/3x-ui/v3/internal/agent"
|
||||||
|
"github.com/mhsanaei/3x-ui/v3/internal/config"
|
||||||
|
"github.com/mhsanaei/3x-ui/v3/internal/logger"
|
||||||
|
"github.com/mhsanaei/3x-ui/v3/internal/util/memtuning"
|
||||||
|
|
||||||
|
"github.com/op/go-logging"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
args := os.Args[1:]
|
||||||
|
|
||||||
|
// Version self-report: the agent's own display version (A-form),
|
||||||
|
// from the same build-time displayVersion injection the panel
|
||||||
|
// uses. Kept ahead of the subcommand so it works however the
|
||||||
|
// binary was invoked.
|
||||||
|
if len(args) > 0 {
|
||||||
|
switch args[0] {
|
||||||
|
case "-v", "--version", "version":
|
||||||
|
fmt.Println(config.GetAgentDisplayVersion())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Service units (systemd / OpenRC / procd / nohup fallback in
|
||||||
|
// install-agent.sh) invoke the binary with the historical "agent"
|
||||||
|
// subcommand; consume it so those units keep working unchanged.
|
||||||
|
if len(args) > 0 && args[0] == "agent" {
|
||||||
|
args = args[1:]
|
||||||
|
} else if len(args) > 0 && args[0][0] != '-' {
|
||||||
|
fmt.Fprintf(os.Stderr, "lui-agent: unknown subcommand %q (this binary only runs the node agent)\n", args[0])
|
||||||
|
os.Exit(2)
|
||||||
|
}
|
||||||
|
|
||||||
|
runAgent(args)
|
||||||
|
}
|
||||||
|
|
||||||
|
// runAgent is main.go's agent branch, verbatim in behaviour: same
|
||||||
|
// flags, same defaults, same shutdown wiring.
|
||||||
|
func runAgent(args []string) {
|
||||||
|
agentCmd := flag.NewFlagSet("agent", flag.ExitOnError)
|
||||||
|
var configPath string
|
||||||
|
agentCmd.StringVar(&configPath, "config", "/etc/l-ui/agent.json", "Path to agent config file")
|
||||||
|
agentCmd.Parse(args)
|
||||||
|
|
||||||
|
// Agent mode always uses the panel's directory layout for the
|
||||||
|
// xray binary, geo files and config.json. Scoped to agent mode
|
||||||
|
// only so the panel's own relative "bin" default is untouched.
|
||||||
|
if os.Getenv("LUI_BIN_FOLDER") == "" {
|
||||||
|
_ = os.Setenv("LUI_BIN_FOLDER", agent.DefaultBinFolder)
|
||||||
|
}
|
||||||
|
|
||||||
|
cfg, err := agent.LoadConfig(configPath)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("Failed to load agent config from %s: %v", configPath, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// The acknowledged traffic baseline persists next to the agent
|
||||||
|
// config (its state home, e.g. /etc/l-ui), unless the config
|
||||||
|
// names a path.
|
||||||
|
if cfg.BaselinePath == "" {
|
||||||
|
cfg.BaselinePath = filepath.Join(filepath.Dir(configPath), "agent-traffic-baseline.json")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Initialize logger
|
||||||
|
logger.InitLogger(logging.INFO)
|
||||||
|
log.Printf("Starting L-UI agent (node: %s)", cfg.NodeName)
|
||||||
|
|
||||||
|
// Agent memory profile (ITEM-P3 A1/M5): the same runtime tuning
|
||||||
|
// family as the panel, with the agent's tighter budget, plus the
|
||||||
|
// periodic release the panel runs through its job scheduler (the
|
||||||
|
// agent has no scheduler), plus the panel's LUI_PPROF gate.
|
||||||
|
for _, line := range memtuning.ApplyAgentMemoryTuning() {
|
||||||
|
log.Println(line)
|
||||||
|
}
|
||||||
|
memtuning.StartPeriodicMemoryRelease()
|
||||||
|
if os.Getenv("LUI_PPROF") == "true" {
|
||||||
|
go func() {
|
||||||
|
log.Println("pprof profiling server listening on 127.0.0.1:6060")
|
||||||
|
if err := http.ListenAndServe("127.0.0.1:6060", nil); err != nil {
|
||||||
|
log.Printf("pprof server stopped: %v", err)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
}
|
||||||
|
|
||||||
|
ag := agent.New(cfg)
|
||||||
|
|
||||||
|
// Handle shutdown signals
|
||||||
|
sigCh := make(chan os.Signal, 1)
|
||||||
|
signal.Notify(sigCh, syscall.SIGINT, syscall.SIGTERM)
|
||||||
|
go func() {
|
||||||
|
<-sigCh
|
||||||
|
log.Println("Shutting down agent...")
|
||||||
|
ag.Stop()
|
||||||
|
}()
|
||||||
|
|
||||||
|
if err := ag.Run(); err != nil {
|
||||||
|
log.Fatalf("Agent error: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,270 @@
|
|||||||
|
//go:build windows
|
||||||
|
|
||||||
|
// Command xui-agent-windows is the standalone Windows build of the
|
||||||
|
// 3x-ui node agent. Windows nodes are probe-only by design: the agent
|
||||||
|
// reports host facts/metrics and runs latency probes, but no xray or
|
||||||
|
// sing-box core is ever fetched or started here (the agent core
|
||||||
|
// machinery stays the master's Linux fleet concern; the local
|
||||||
|
// agent.json carries "probeOnly": true, written by
|
||||||
|
// install-agent.ps1).
|
||||||
|
//
|
||||||
|
// Usage:
|
||||||
|
//
|
||||||
|
// xui-agent-windows.exe [-config C:\x-ui\agent.json] run (service or console)
|
||||||
|
// xui-agent-windows.exe install [-config <path>] register the service
|
||||||
|
// xui-agent-windows.exe uninstall remove the service
|
||||||
|
// xui-agent-windows.exe start | stop control the service
|
||||||
|
//
|
||||||
|
// The agent lifecycle wiring (config load, baseline derivation,
|
||||||
|
// logger init, graceful stop) mirrors main.go's agent branch — the
|
||||||
|
// same internal/agent package does the work either way.
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"flag"
|
||||||
|
"fmt"
|
||||||
|
"log"
|
||||||
|
"os"
|
||||||
|
"os/signal"
|
||||||
|
"path/filepath"
|
||||||
|
"syscall"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/mhsanaei/3x-ui/v3/internal/agent"
|
||||||
|
"github.com/mhsanaei/3x-ui/v3/internal/logger"
|
||||||
|
|
||||||
|
"github.com/op/go-logging"
|
||||||
|
"golang.org/x/sys/windows/svc"
|
||||||
|
"golang.org/x/sys/windows/svc/mgr"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
serviceName = "x-ui-agent"
|
||||||
|
defaultCfgPath = `C:\x-ui\agent.json`
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
log.SetPrefix("[x-ui-agent] ")
|
||||||
|
args := os.Args[1:]
|
||||||
|
|
||||||
|
// Management subcommands come first; anything else is a run.
|
||||||
|
if len(args) > 0 {
|
||||||
|
switch args[0] {
|
||||||
|
case "install", "uninstall", "start", "stop":
|
||||||
|
cfgPath := parseConfigFlag("xui-agent-windows "+args[0], args[1:])
|
||||||
|
if err := runControl(args[0], cfgPath); err != nil {
|
||||||
|
log.Fatalf("%s: %v", args[0], err)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cfgPath := parseConfigFlag("xui-agent-windows", args)
|
||||||
|
|
||||||
|
isService, err := svc.IsWindowsService()
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("detect service environment: %v", err)
|
||||||
|
}
|
||||||
|
if isService {
|
||||||
|
if err := svc.Run(serviceName, &agentHandler{cfgPath: cfgPath}); err != nil {
|
||||||
|
log.Fatalf("service run: %v", err)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Interactive run: console foreground, Ctrl+C stops gracefully.
|
||||||
|
running, err := startAgent(cfgPath)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("start agent: %v", err)
|
||||||
|
}
|
||||||
|
sigCh := make(chan os.Signal, 1)
|
||||||
|
signal.Notify(sigCh, os.Interrupt, syscall.SIGTERM)
|
||||||
|
select {
|
||||||
|
case <-sigCh:
|
||||||
|
log.Println("Shutting down agent...")
|
||||||
|
running.Stop()
|
||||||
|
<-running.done
|
||||||
|
case err := <-running.done:
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("Agent error: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func parseConfigFlag(name string, args []string) string {
|
||||||
|
fs := flag.NewFlagSet(name, flag.ExitOnError)
|
||||||
|
cfg := fs.String("config", defaultCfgPath, "Path to agent config file")
|
||||||
|
_ = fs.Parse(args)
|
||||||
|
return *cfg
|
||||||
|
}
|
||||||
|
|
||||||
|
// runningAgent is one started agent plus its completion signal.
|
||||||
|
type runningAgent struct {
|
||||||
|
ag *agent.Agent
|
||||||
|
done chan error
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *runningAgent) Stop() { r.ag.Stop() }
|
||||||
|
|
||||||
|
// startAgent performs the same setup as main.go's agent branch and
|
||||||
|
// launches the agent loop in the background.
|
||||||
|
func startAgent(cfgPath string) (*runningAgent, error) {
|
||||||
|
// Agent mode uses the panel's directory layout for core binaries
|
||||||
|
// and configs; on a probe-only Windows node nothing consumes it,
|
||||||
|
// but keep the wiring identical to the Linux entry so behaviour
|
||||||
|
// cannot drift between the two.
|
||||||
|
if os.Getenv("XUI_BIN_FOLDER") == "" {
|
||||||
|
_ = os.Setenv("XUI_BIN_FOLDER", agent.DefaultBinFolder)
|
||||||
|
}
|
||||||
|
|
||||||
|
cfg, err := agent.LoadConfig(cfgPath)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("load agent config from %s: %w", cfgPath, err)
|
||||||
|
}
|
||||||
|
// The acknowledged traffic baseline persists next to the agent
|
||||||
|
// config (its state home), unless the config names a path.
|
||||||
|
if cfg.BaselinePath == "" {
|
||||||
|
cfg.BaselinePath = filepath.Join(filepath.Dir(cfgPath), "agent-traffic-baseline.json")
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.InitLogger(logging.INFO)
|
||||||
|
log.Printf("Starting 3x-ui agent (node: %s)", cfg.NodeName)
|
||||||
|
|
||||||
|
ag := agent.New(cfg)
|
||||||
|
r := &runningAgent{ag: ag, done: make(chan error, 1)}
|
||||||
|
go func() { r.done <- ag.Run() }()
|
||||||
|
return r, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// agentHandler adapts the agent loop to the SCM protocol.
|
||||||
|
type agentHandler struct {
|
||||||
|
cfgPath string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *agentHandler) Execute(_ []string, r <-chan svc.ChangeRequest, status chan<- svc.Status) (bool, uint32) {
|
||||||
|
const accepted = svc.AcceptStop | svc.AcceptShutdown
|
||||||
|
status <- svc.Status{State: svc.StartPending}
|
||||||
|
running, err := startAgent(h.cfgPath)
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("start agent: %v", err)
|
||||||
|
return false, 1
|
||||||
|
}
|
||||||
|
status <- svc.Status{State: svc.Running, Accepts: accepted}
|
||||||
|
for {
|
||||||
|
select {
|
||||||
|
case err := <-running.done:
|
||||||
|
// The agent loop ended on its own (e.g. fatal run error).
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("agent exited: %v", err)
|
||||||
|
return false, 1
|
||||||
|
}
|
||||||
|
return false, 0
|
||||||
|
case c := <-r:
|
||||||
|
switch c.Cmd {
|
||||||
|
case svc.Interrogate:
|
||||||
|
status <- c.CurrentStatus
|
||||||
|
case svc.Stop, svc.Shutdown:
|
||||||
|
status <- svc.Status{State: svc.StopPending}
|
||||||
|
running.Stop()
|
||||||
|
<-running.done
|
||||||
|
return false, 0
|
||||||
|
default:
|
||||||
|
log.Printf("unexpected service command: %v", c.Cmd)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// runControl implements the install/uninstall/start/stop subcommands
|
||||||
|
// through the service control manager.
|
||||||
|
func runControl(cmd, cfgPath string) error {
|
||||||
|
m, err := mgr.ConnectRemote("")
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("connect to service manager: %w", err)
|
||||||
|
}
|
||||||
|
defer m.Disconnect()
|
||||||
|
|
||||||
|
switch cmd {
|
||||||
|
case "install":
|
||||||
|
exePath, err := os.Executable()
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("locate own binary: %w", err)
|
||||||
|
}
|
||||||
|
absCfg, err := filepath.Abs(cfgPath)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("resolve config path: %w", err)
|
||||||
|
}
|
||||||
|
if s, err := m.OpenService(serviceName); err == nil {
|
||||||
|
s.Close()
|
||||||
|
return fmt.Errorf("service %s already exists (uninstall first)", serviceName)
|
||||||
|
}
|
||||||
|
s, err := m.CreateService(serviceName, exePath, mgr.Config{
|
||||||
|
DisplayName: "3x-ui Agent",
|
||||||
|
Description: "3x-ui probe-only node agent (facts, metrics and latency probes; runs no proxy core).",
|
||||||
|
StartType: mgr.StartAutomatic,
|
||||||
|
ErrorControl: mgr.ErrorNormal,
|
||||||
|
}, "-config", absCfg)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("create service: %w", err)
|
||||||
|
}
|
||||||
|
defer s.Close()
|
||||||
|
log.Printf("service %s installed (config: %s)", serviceName, absCfg)
|
||||||
|
return nil
|
||||||
|
|
||||||
|
case "uninstall":
|
||||||
|
s, err := openService(m)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer s.Close()
|
||||||
|
// Stop first so the binary is not locked when the operator
|
||||||
|
// deletes or replaces it; an already-stopped service is fine.
|
||||||
|
_, _ = s.Control(svc.Stop)
|
||||||
|
deadline := time.Now().Add(15 * time.Second)
|
||||||
|
for time.Now().Before(deadline) {
|
||||||
|
st, err := s.Query()
|
||||||
|
if err != nil || st.State == svc.Stopped {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
time.Sleep(300 * time.Millisecond)
|
||||||
|
}
|
||||||
|
if err := s.Delete(); err != nil {
|
||||||
|
return fmt.Errorf("delete service: %w", err)
|
||||||
|
}
|
||||||
|
log.Printf("service %s removed", serviceName)
|
||||||
|
return nil
|
||||||
|
|
||||||
|
case "start":
|
||||||
|
s, err := openService(m)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer s.Close()
|
||||||
|
if err := s.Start(); err != nil {
|
||||||
|
return fmt.Errorf("start service: %w", err)
|
||||||
|
}
|
||||||
|
log.Printf("service %s started", serviceName)
|
||||||
|
return nil
|
||||||
|
|
||||||
|
case "stop":
|
||||||
|
s, err := openService(m)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer s.Close()
|
||||||
|
if _, err := s.Control(svc.Stop); err != nil {
|
||||||
|
return fmt.Errorf("stop service: %w", err)
|
||||||
|
}
|
||||||
|
log.Printf("service %s stop requested", serviceName)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return fmt.Errorf("unknown subcommand %q", cmd)
|
||||||
|
}
|
||||||
|
|
||||||
|
func openService(m *mgr.Mgr) (*mgr.Service, error) {
|
||||||
|
s, err := m.OpenService(serviceName)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("open service %s: %w", serviceName, err)
|
||||||
|
}
|
||||||
|
return s, nil
|
||||||
|
}
|
||||||
+9
-9
@@ -1,6 +1,6 @@
|
|||||||
# Cloud deployment (unattended install)
|
# Cloud deployment (unattended install)
|
||||||
|
|
||||||
Tooling to ship the 3x-ui panel via unattended install, with **per-instance
|
Tooling to ship the L-UI panel via unattended install, with **per-instance
|
||||||
credentials generated on first boot** (never `admin/admin`, never a shared
|
credentials generated on first boot** (never `admin/admin`, never a shared
|
||||||
session secret). Works on amd64 and arm64.
|
session secret). Works on amd64 and arm64.
|
||||||
|
|
||||||
@@ -12,7 +12,7 @@ session secret). Works on amd64 and arm64.
|
|||||||
|
|
||||||
## How it works
|
## How it works
|
||||||
|
|
||||||
`install.sh` runs unattended when `XUI_NONINTERACTIVE=1` or stdin is not a TTY.
|
`install.sh` runs unattended when `LUI_NONINTERACTIVE=1` or stdin is not a TTY.
|
||||||
Each instance installs and configures itself with random credentials. See
|
Each instance installs and configures itself with random credentials. See
|
||||||
[`cloud-init/README.md`](cloud-init/README.md).
|
[`cloud-init/README.md`](cloud-init/README.md).
|
||||||
|
|
||||||
@@ -21,11 +21,11 @@ Each instance installs and configures itself with random credentials. See
|
|||||||
`install.sh` reads these env vars in non-interactive mode (all optional; unset ⇒
|
`install.sh` reads these env vars in non-interactive mode (all optional; unset ⇒
|
||||||
secure random / default):
|
secure random / default):
|
||||||
|
|
||||||
`XUI_USERNAME`, `XUI_PASSWORD`, `XUI_PANEL_PORT`, `XUI_WEB_BASE_PATH`,
|
`LUI_USERNAME`, `LUI_PASSWORD`, `LUI_PANEL_PORT`, `LUI_WEB_BASE_PATH`,
|
||||||
`XUI_SSL_MODE` (`none`|`ip`|`domain`, default `none`), `XUI_DOMAIN`,
|
`LUI_SSL_MODE` (`none`|`ip`|`domain`, default `none`), `LUI_DOMAIN`,
|
||||||
`XUI_ACME_EMAIL`, `XUI_ACME_HTTP_PORT` (ACME HTTP-01 listener port, default `80`),
|
`LUI_ACME_EMAIL`, `LUI_ACME_HTTP_PORT` (ACME HTTP-01 listener port, default `80`),
|
||||||
`XUI_SSL_IPV6` (optional IPv6 address to add to an `ip`-mode cert),
|
`LUI_SSL_IPV6` (optional IPv6 address to add to an `ip`-mode cert),
|
||||||
`XUI_SERVER_IP` (fallback IP for the displayed access URL when auto-detection fails),
|
`LUI_SERVER_IP` (fallback IP for the displayed access URL when auto-detection fails),
|
||||||
`XUI_DB_TYPE` (`sqlite`|`postgres`), `XUI_DB_DSN`.
|
`LUI_DB_TYPE` (`sqlite`|`postgres`), `LUI_DB_DSN`.
|
||||||
|
|
||||||
The resulting credentials are written to `/etc/x-ui/install-result.env` (mode 600).
|
The resulting credentials are written to `/etc/l-ui/install-result.env` (mode 600).
|
||||||
|
|||||||
+14
-14
@@ -1,6 +1,6 @@
|
|||||||
# 3x-ui via cloud-init
|
# L-UI via cloud-init
|
||||||
|
|
||||||
A single [`cloud-init.yaml`](cloud-init.yaml) user-data file that installs 3x-ui
|
A single [`cloud-init.yaml`](cloud-init.yaml) user-data file that installs L-UI
|
||||||
non-interactively on a fresh Ubuntu/Debian VM and generates **unique random
|
non-interactively on a fresh Ubuntu/Debian VM and generates **unique random
|
||||||
credentials per instance**. It works on any cloud-init platform.
|
credentials per instance**. It works on any cloud-init platform.
|
||||||
|
|
||||||
@@ -8,35 +8,35 @@ credentials per instance**. It works on any cloud-init platform.
|
|||||||
|
|
||||||
1. The VM boots a stock Ubuntu/Debian cloud image.
|
1. The VM boots a stock Ubuntu/Debian cloud image.
|
||||||
2. cloud-init writes and runs `/opt/xui-bootstrap.sh`, which exports
|
2. cloud-init writes and runs `/opt/xui-bootstrap.sh`, which exports
|
||||||
`XUI_NONINTERACTIVE=1` and pipes the project's `install.sh` into `bash`.
|
`LUI_NONINTERACTIVE=1` and pipes the project's `install.sh` into `bash`.
|
||||||
3. `install.sh` runs end-to-end with **zero prompts**, picking secure random
|
3. `install.sh` runs end-to-end with **zero prompts**, picking secure random
|
||||||
values for any credential you didn't pin.
|
values for any credential you didn't pin.
|
||||||
4. The generated credentials are written to `/etc/x-ui/install-result.env`
|
4. The generated credentials are written to `/etc/l-ui/install-result.env`
|
||||||
(mode 600), echoed to the **serial console**, and appended to `/etc/motd`.
|
(mode 600), echoed to the **serial console**, and appended to `/etc/motd`.
|
||||||
|
|
||||||
Retrieve them after boot with either:
|
Retrieve them after boot with either:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
sudo cat /etc/x-ui/install-result.env # over SSH
|
sudo cat /etc/l-ui/install-result.env # over SSH
|
||||||
```
|
```
|
||||||
|
|
||||||
…or read the provider's **serial console** output (handy before you have SSH).
|
…or read the provider's **serial console** output (handy before you have SSH).
|
||||||
|
|
||||||
## Customising
|
## Customising
|
||||||
|
|
||||||
Edit the `export XUI_*` lines inside the `write_files` block of
|
Edit the `export LUI_*` lines inside the `write_files` block of
|
||||||
[`cloud-init.yaml`](cloud-init.yaml). All knobs are optional; unset ⇒ random/secure default.
|
[`cloud-init.yaml`](cloud-init.yaml). All knobs are optional; unset ⇒ random/secure default.
|
||||||
|
|
||||||
| Env var | Default | Meaning |
|
| Env var | Default | Meaning |
|
||||||
| --- | --- | --- |
|
| --- | --- | --- |
|
||||||
| `XUI_SSL_MODE` | `none` | `none` (plain HTTP), `ip` (Let's Encrypt IP cert), `domain` |
|
| `LUI_SSL_MODE` | `none` | `none` (plain HTTP), `ip` (Let's Encrypt IP cert), `domain` |
|
||||||
| `XUI_USERNAME` | random | Admin username |
|
| `LUI_USERNAME` | random | Admin username |
|
||||||
| `XUI_PASSWORD` | random | Admin password |
|
| `LUI_PASSWORD` | random | Admin password |
|
||||||
| `XUI_PANEL_PORT` | random high port | Panel listen port |
|
| `LUI_PANEL_PORT` | random high port | Panel listen port |
|
||||||
| `XUI_WEB_BASE_PATH` | random | Panel base path (obscures the URL) |
|
| `LUI_WEB_BASE_PATH` | random | Panel base path (obscures the URL) |
|
||||||
| `XUI_DOMAIN` | — | Required when `XUI_SSL_MODE=domain` |
|
| `LUI_DOMAIN` | — | Required when `LUI_SSL_MODE=domain` |
|
||||||
| `XUI_ACME_EMAIL` | — | Let's Encrypt account email (domain mode) |
|
| `LUI_ACME_EMAIL` | — | Let's Encrypt account email (domain mode) |
|
||||||
| `XUI_DB_TYPE` / `XUI_DB_DSN` | `sqlite` | Set `postgres` + DSN to use PostgreSQL |
|
| `LUI_DB_TYPE` / `LUI_DB_DSN` | `sqlite` | Set `postgres` + DSN to use PostgreSQL |
|
||||||
|
|
||||||
> **TLS note:** `none` serves the panel over plain HTTP on a random high port —
|
> **TLS note:** `none` serves the panel over plain HTTP on a random high port —
|
||||||
> fine behind a reverse proxy or an SSH tunnel, but put TLS in front of it before
|
> fine behind a reverse proxy or an SSH tunnel, but put TLS in front of it before
|
||||||
|
|||||||
@@ -1,17 +1,20 @@
|
|||||||
#cloud-config
|
#cloud-config
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
# Generic 3x-ui unattended install via cloud-init user-data.
|
# Generic L-UI unattended install via cloud-init user-data.
|
||||||
#
|
#
|
||||||
# Works on any cloud-init platform: Hetzner, AWS, DigitalOcean, Vultr, GCP,
|
# Works on any cloud-init platform: Hetzner, AWS, DigitalOcean, Vultr, GCP,
|
||||||
# Azure, Oracle. Paste the whole file as the instance "user data".
|
# Azure, Oracle. Paste the whole file as the instance "user data".
|
||||||
#
|
#
|
||||||
# It installs the latest 3x-ui release NON-INTERACTIVELY, generating unique
|
# It installs the latest L-UI release NON-INTERACTIVELY, generating unique
|
||||||
# random credentials per instance. Full credentials are surfaced ONLY on the
|
# random credentials per instance. Full credentials are surfaced ONLY on the
|
||||||
# serial console (owner-only); /etc/motd (world-readable) shows just the access
|
# serial console (owner-only); /etc/motd (world-readable) shows just the access
|
||||||
# URL + username. Nothing is baked in advance — every instance is unique.
|
# URL + username. Nothing is baked in advance — every instance is unique.
|
||||||
#
|
#
|
||||||
# Requires the non-interactive install.sh (3x-ui with XUI_NONINTERACTIVE support).
|
# Fork note (L-UI): the bootstrap below installs this fork's
|
||||||
# Edit the exported XUI_* knobs in /opt/xui-bootstrap.sh below to customise.
|
# install-master.sh from its own Gitea repository. The fork installer does
|
||||||
|
# NOT consume the LUI_* non-interactive knobs and does NOT write
|
||||||
|
# /etc/l-ui/install-result.env, so the LUI_* exports and the credential-
|
||||||
|
# surfacing block below are inert leftovers from the upstream installer.
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
package_update: true
|
package_update: true
|
||||||
@@ -27,46 +30,46 @@ write_files:
|
|||||||
export DEBIAN_FRONTEND=noninteractive
|
export DEBIAN_FRONTEND=noninteractive
|
||||||
|
|
||||||
# --- Non-interactive install knobs --------------------------------------
|
# --- Non-interactive install knobs --------------------------------------
|
||||||
export XUI_NONINTERACTIVE=1
|
export LUI_NONINTERACTIVE=1
|
||||||
# SSL mode: none (plain HTTP, default) | ip | domain
|
# SSL mode: none (plain HTTP, default) | ip | domain
|
||||||
export XUI_SSL_MODE="${XUI_SSL_MODE:-none}"
|
export LUI_SSL_MODE="${LUI_SSL_MODE:-none}"
|
||||||
# Pin credentials instead of random (leave unset for secure random values):
|
# Pin credentials instead of random (leave unset for secure random values):
|
||||||
# export XUI_USERNAME="admin2"
|
# export LUI_USERNAME="admin2"
|
||||||
# export XUI_PASSWORD="change-me-please"
|
# export LUI_PASSWORD="change-me-please"
|
||||||
# export XUI_PANEL_PORT="2053"
|
# export LUI_PANEL_PORT="2053"
|
||||||
# export XUI_WEB_BASE_PATH="panel"
|
# export LUI_WEB_BASE_PATH="panel"
|
||||||
# Let's Encrypt domain certificate instead of plain HTTP:
|
# Let's Encrypt domain certificate instead of plain HTTP:
|
||||||
# export XUI_SSL_MODE="domain"
|
# export LUI_SSL_MODE="domain"
|
||||||
# export XUI_DOMAIN="panel.example.com"
|
# export LUI_DOMAIN="panel.example.com"
|
||||||
# export XUI_ACME_EMAIL="you@example.com"
|
# export LUI_ACME_EMAIL="you@example.com"
|
||||||
# PostgreSQL instead of SQLite:
|
# PostgreSQL instead of SQLite:
|
||||||
# export XUI_DB_TYPE="postgres"
|
# export LUI_DB_TYPE="postgres"
|
||||||
# export XUI_DB_DSN="postgres://user:pass@host:5432/db?sslmode=disable"
|
# export LUI_DB_DSN="postgres://user:pass@host:5432/db?sslmode=disable"
|
||||||
# ------------------------------------------------------------------------
|
# ------------------------------------------------------------------------
|
||||||
|
|
||||||
curl -fsSL https://raw.githubusercontent.com/MHSanaei/3x-ui/main/install.sh | bash
|
curl -fsSL https://git.881218.xyz/rogue/l-ui/raw/branch/main/install-master.sh | bash
|
||||||
|
|
||||||
# Surface the generated credentials. Full creds (incl. password + API token)
|
# Surface the generated credentials. Full creds (incl. password + API token)
|
||||||
# go ONLY to the serial console (/dev/console, owner-only). /etc/motd is
|
# go ONLY to the serial console (/dev/console, owner-only). /etc/motd is
|
||||||
# world-readable, so it gets just the access URL + username and a pointer
|
# world-readable, so it gets just the access URL + username and a pointer
|
||||||
# to the root-only env file.
|
# to the root-only env file.
|
||||||
if [ -r /etc/x-ui/install-result.env ]; then
|
if [ -r /etc/l-ui/install-result.env ]; then
|
||||||
{
|
{
|
||||||
echo
|
echo
|
||||||
echo "=== 3x-ui panel credentials (generated on first boot) ==="
|
echo "=== L-UI panel credentials (generated on first boot) ==="
|
||||||
cat /etc/x-ui/install-result.env
|
cat /etc/l-ui/install-result.env
|
||||||
echo "========================================================"
|
echo "========================================================"
|
||||||
echo "Change the password after first login."
|
echo "Change the password after first login."
|
||||||
} > /dev/console 2>/dev/null || true
|
} > /dev/console 2>/dev/null || true
|
||||||
|
|
||||||
# shellcheck disable=SC1091
|
# shellcheck disable=SC1091
|
||||||
. /etc/x-ui/install-result.env
|
. /etc/l-ui/install-result.env
|
||||||
{
|
{
|
||||||
echo
|
echo
|
||||||
echo "=== 3x-ui panel (generated on first boot) ==="
|
echo "=== L-UI panel (generated on first boot) ==="
|
||||||
echo "URL: ${XUI_ACCESS_URL:-unknown}"
|
echo "URL: ${LUI_ACCESS_URL:-unknown}"
|
||||||
echo "Username: ${XUI_USERNAME:-unknown}"
|
echo "Username: ${LUI_USERNAME:-unknown}"
|
||||||
echo "Password + API token: sudo cat /etc/x-ui/install-result.env"
|
echo "Password + API token: sudo cat /etc/l-ui/install-result.env"
|
||||||
echo "============================================="
|
echo "============================================="
|
||||||
echo "Change the password after first login."
|
echo "Change the password after first login."
|
||||||
} >> /etc/motd 2>/dev/null || true
|
} >> /etc/motd 2>/dev/null || true
|
||||||
@@ -75,4 +78,4 @@ write_files:
|
|||||||
runcmd:
|
runcmd:
|
||||||
- [bash, /opt/xui-bootstrap.sh]
|
- [bash, /opt/xui-bootstrap.sh]
|
||||||
|
|
||||||
final_message: "3x-ui installed — full credentials in /etc/x-ui/install-result.env (sudo); /etc/motd shows the URL + username only."
|
final_message: "L-UI installed — full credentials in /etc/l-ui/install-result.env (sudo); /etc/motd shows the URL + username only."
|
||||||
|
|||||||
@@ -1,13 +1,13 @@
|
|||||||
# 3x-ui on Hetzner Cloud
|
# L-UI on Hetzner Cloud
|
||||||
|
|
||||||
Hetzner Cloud does **not** have a third-party image marketplace the way AWS does.
|
Hetzner Cloud does **not** have a third-party image marketplace the way AWS does.
|
||||||
Ship 3x-ui via **cloud-init**: each instance installs non-interactively and
|
Ship L-UI via **cloud-init**: each instance installs non-interactively and
|
||||||
generates unique per-instance credentials (no `admin/admin`, no shared secret).
|
generates unique per-instance credentials (no `admin/admin`, no shared secret).
|
||||||
|
|
||||||
## cloud-init (no image build)
|
## cloud-init (no image build)
|
||||||
|
|
||||||
Use the generic user-data from [`../../cloud-init/`](../../cloud-init/). It installs
|
Use the generic user-data from [`../../cloud-init/`](../../cloud-init/). It installs
|
||||||
3x-ui non-interactively and generates unique per-instance credentials.
|
L-UI non-interactively and generates unique per-instance credentials.
|
||||||
|
|
||||||
Web console: **Create Server → Cloud config** → paste
|
Web console: **Create Server → Cloud config** → paste
|
||||||
[`deploy/cloud-init/cloud-init.yaml`](../../cloud-init/cloud-init.yaml).
|
[`deploy/cloud-init/cloud-init.yaml`](../../cloud-init/cloud-init.yaml).
|
||||||
@@ -25,13 +25,13 @@ hcloud server create \
|
|||||||
After boot, fetch the generated credentials:
|
After boot, fetch the generated credentials:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
ssh root@<server-ip> 'cat /etc/x-ui/install-result.env'
|
ssh root@<server-ip> 'cat /etc/l-ui/install-result.env'
|
||||||
```
|
```
|
||||||
|
|
||||||
## "App"-style listing
|
## "App"-style listing
|
||||||
|
|
||||||
Hetzner's curated apps live in the community repo
|
Hetzner's curated apps live in the community repo
|
||||||
[`github.com/hetznercloud/apps`](https://github.com/hetznercloud/apps): each app
|
[`github.com/hetznercloud/apps`](https://github.com/hetznercloud/apps): each app
|
||||||
is essentially a documented cloud-init config plus metadata. To propose 3x-ui as
|
is essentially a documented cloud-init config plus metadata. To propose L-UI as
|
||||||
a Hetzner app, follow that repo's contribution pattern and base the app's
|
a Hetzner app, follow that repo's contribution pattern and base the app's
|
||||||
cloud-config on [`deploy/cloud-init/cloud-init.yaml`](../../cloud-init/cloud-init.yaml).
|
cloud-config on [`deploy/cloud-init/cloud-init.yaml`](../../cloud-init/cloud-init.yaml).
|
||||||
|
|||||||
@@ -3,8 +3,8 @@
|
|||||||
# smoke-noninteractive.sh — verify the non-interactive install path.
|
# smoke-noninteractive.sh — verify the non-interactive install path.
|
||||||
#
|
#
|
||||||
# Runs install.sh inside an Ubuntu container with NO TTY (piped) and
|
# Runs install.sh inside an Ubuntu container with NO TTY (piped) and
|
||||||
# XUI_NONINTERACTIVE=1, then asserts:
|
# LUI_NONINTERACTIVE=1, then asserts:
|
||||||
# * /etc/x-ui/install-result.env exists (mode 600) with random, non-default creds
|
# * /etc/l-ui/install-result.env exists (mode 600) with random, non-default creds
|
||||||
# * the panel reports hasDefaultCredential: false (no admin/admin remains)
|
# * the panel reports hasDefaultCredential: false (no admin/admin remains)
|
||||||
# * the panel HTTP server actually serves on the generated port/base path
|
# * the panel HTTP server actually serves on the generated port/base path
|
||||||
# * with a [version] argument: the installed binary reports exactly that version
|
# * with a [version] argument: the installed binary reports exactly that version
|
||||||
@@ -18,41 +18,41 @@ set -euo pipefail
|
|||||||
|
|
||||||
REPO_ROOT="$(cd "$(dirname "$0")/../.." && pwd)"
|
REPO_ROOT="$(cd "$(dirname "$0")/../.." && pwd)"
|
||||||
IMAGE="${SMOKE_IMAGE:-ubuntu:24.04}"
|
IMAGE="${SMOKE_IMAGE:-ubuntu:24.04}"
|
||||||
XUI_SMOKE_VERSION="${1:-}"
|
LUI_SMOKE_VERSION="${1:-}"
|
||||||
|
|
||||||
if ! command -v docker > /dev/null 2>&1; then
|
if ! command -v docker > /dev/null 2>&1; then
|
||||||
echo "ERROR: docker is required for this smoke test." >&2
|
echo "ERROR: docker is required for this smoke test." >&2
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo "== non-interactive install smoke test (image: $IMAGE, version: ${XUI_SMOKE_VERSION:-latest}) =="
|
echo "== non-interactive install smoke test (image: $IMAGE, version: ${LUI_SMOKE_VERSION:-latest}) =="
|
||||||
|
|
||||||
docker run --rm \
|
docker run --rm \
|
||||||
-v "${REPO_ROOT}/install.sh:/root/install.sh:ro" \
|
-v "${REPO_ROOT}/install.sh:/root/install.sh:ro" \
|
||||||
-e XUI_NONINTERACTIVE=1 \
|
-e LUI_NONINTERACTIVE=1 \
|
||||||
-e XUI_SSL_MODE=none \
|
-e LUI_SSL_MODE=none \
|
||||||
-e XUI_SMOKE_VERSION="$XUI_SMOKE_VERSION" \
|
-e LUI_SMOKE_VERSION="$LUI_SMOKE_VERSION" \
|
||||||
-e DEBIAN_FRONTEND=noninteractive \
|
-e DEBIAN_FRONTEND=noninteractive \
|
||||||
"$IMAGE" bash -euo pipefail -c '
|
"$IMAGE" bash -euo pipefail -c '
|
||||||
apt-get update -qq
|
apt-get update -qq
|
||||||
apt-get install -y -qq curl tar openssl ca-certificates > /dev/null
|
apt-get install -y -qq curl tar openssl ca-certificates > /dev/null
|
||||||
|
|
||||||
echo "--- running install.sh piped (no TTY), version: ${XUI_SMOKE_VERSION:-latest} ---"
|
echo "--- running install.sh piped (no TTY), version: ${LUI_SMOKE_VERSION:-latest} ---"
|
||||||
# Piping guarantees stdin is not a TTY, exercising the auto non-interactive path.
|
# Piping guarantees stdin is not a TTY, exercising the auto non-interactive path.
|
||||||
if [ -n "${XUI_SMOKE_VERSION:-}" ]; then
|
if [ -n "${LUI_SMOKE_VERSION:-}" ]; then
|
||||||
cat /root/install.sh | bash -s -- "$XUI_SMOKE_VERSION"
|
cat /root/install.sh | bash -s -- "$LUI_SMOKE_VERSION"
|
||||||
else
|
else
|
||||||
cat /root/install.sh | bash
|
cat /root/install.sh | bash
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo "--- assertions ---"
|
echo "--- assertions ---"
|
||||||
if [ -n "${XUI_SMOKE_VERSION:-}" ]; then
|
if [ -n "${LUI_SMOKE_VERSION:-}" ]; then
|
||||||
installed=$(/usr/local/x-ui/x-ui -v)
|
installed=$(/usr/local/l-ui/l-ui -v)
|
||||||
[ "$installed" = "${XUI_SMOKE_VERSION#v}" ] \
|
[ "$installed" = "${LUI_SMOKE_VERSION#v}" ] \
|
||||||
|| { echo "FAIL: installed version $installed, want ${XUI_SMOKE_VERSION#v}"; exit 1; }
|
|| { echo "FAIL: installed version $installed, want ${LUI_SMOKE_VERSION#v}"; exit 1; }
|
||||||
fi
|
fi
|
||||||
|
|
||||||
RESULT=/etc/x-ui/install-result.env
|
RESULT=/etc/l-ui/install-result.env
|
||||||
test -f "$RESULT" || { echo "FAIL: $RESULT missing"; exit 1; }
|
test -f "$RESULT" || { echo "FAIL: $RESULT missing"; exit 1; }
|
||||||
|
|
||||||
perms=$(stat -c %a "$RESULT")
|
perms=$(stat -c %a "$RESULT")
|
||||||
@@ -60,23 +60,23 @@ docker run --rm \
|
|||||||
|
|
||||||
# shellcheck disable=SC1090
|
# shellcheck disable=SC1090
|
||||||
. "$RESULT"
|
. "$RESULT"
|
||||||
[ -n "${XUI_USERNAME:-}" ] && [ "$XUI_USERNAME" != "admin" ] \
|
[ -n "${LUI_USERNAME:-}" ] && [ "$LUI_USERNAME" != "admin" ] \
|
||||||
|| { echo "FAIL: username missing or still admin"; exit 1; }
|
|| { echo "FAIL: username missing or still admin"; exit 1; }
|
||||||
[ -n "${XUI_PASSWORD:-}" ] && [ "$XUI_PASSWORD" != "admin" ] \
|
[ -n "${LUI_PASSWORD:-}" ] && [ "$LUI_PASSWORD" != "admin" ] \
|
||||||
|| { echo "FAIL: password missing or still admin"; exit 1; }
|
|| { echo "FAIL: password missing or still admin"; exit 1; }
|
||||||
[ -n "${XUI_PANEL_PORT:-}" ] || { echo "FAIL: port missing"; exit 1; }
|
[ -n "${LUI_PANEL_PORT:-}" ] || { echo "FAIL: port missing"; exit 1; }
|
||||||
|
|
||||||
# No default admin in the DB.
|
# No default admin in the DB.
|
||||||
/usr/local/x-ui/x-ui setting -show | grep -q "hasDefaultCredential: false" \
|
/usr/local/l-ui/l-ui setting -show | grep -q "hasDefaultCredential: false" \
|
||||||
|| { echo "FAIL: hasDefaultCredential is not false"; exit 1; }
|
|| { echo "FAIL: hasDefaultCredential is not false"; exit 1; }
|
||||||
|
|
||||||
echo "--- verifying the panel serves HTTP ---"
|
echo "--- verifying the panel serves HTTP ---"
|
||||||
cd /usr/local/x-ui
|
cd /usr/local/l-ui
|
||||||
./x-ui > /tmp/xui.log 2>&1 &
|
./l-ui > /tmp/lui.log 2>&1 &
|
||||||
xpid=$!
|
xpid=$!
|
||||||
for _ in $(seq 1 15); do
|
for _ in $(seq 1 15); do
|
||||||
code=$(curl -s -o /dev/null -w "%{http_code}" \
|
code=$(curl -s -o /dev/null -w "%{http_code}" \
|
||||||
"http://127.0.0.1:${XUI_PANEL_PORT}/${XUI_WEB_BASE_PATH}/" 2>/dev/null || true)
|
"http://127.0.0.1:${LUI_PANEL_PORT}/${LUI_WEB_BASE_PATH}/" 2>/dev/null || true)
|
||||||
case "$code" in 200|301|302|307|308) break ;; esac
|
case "$code" in 200|301|302|307|308) break ;; esac
|
||||||
sleep 1
|
sleep 1
|
||||||
done
|
done
|
||||||
@@ -84,28 +84,28 @@ docker run --rm \
|
|||||||
echo "panel HTTP status: ${code:-none}"
|
echo "panel HTTP status: ${code:-none}"
|
||||||
case "${code:-}" in
|
case "${code:-}" in
|
||||||
200|301|302|307|308) : ;;
|
200|301|302|307|308) : ;;
|
||||||
*) echo "FAIL: panel did not serve (status ${code:-none})"; tail -n 30 /tmp/xui.log; exit 1 ;;
|
*) echo "FAIL: panel did not serve (status ${code:-none})"; tail -n 30 /tmp/lui.log; exit 1 ;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
echo "--- verifying a second install preserves custom bin/ files ---"
|
echo "--- verifying a second install preserves custom bin/ files ---"
|
||||||
echo "custom-sentinel" > /usr/local/x-ui/bin/geoip_custom.dat
|
echo "custom-sentinel" > /usr/local/l-ui/bin/geoip_custom.dat
|
||||||
geoip_sum_before=$(sha256sum /usr/local/x-ui/bin/geoip.dat | cut -d" " -f1)
|
geoip_sum_before=$(sha256sum /usr/local/l-ui/bin/geoip.dat | cut -d" " -f1)
|
||||||
|
|
||||||
if [ -n "${XUI_SMOKE_VERSION:-}" ]; then
|
if [ -n "${LUI_SMOKE_VERSION:-}" ]; then
|
||||||
cat /root/install.sh | bash -s -- "$XUI_SMOKE_VERSION"
|
cat /root/install.sh | bash -s -- "$LUI_SMOKE_VERSION"
|
||||||
else
|
else
|
||||||
cat /root/install.sh | bash
|
cat /root/install.sh | bash
|
||||||
fi
|
fi
|
||||||
|
|
||||||
test -f /usr/local/x-ui/bin/geoip_custom.dat \
|
test -f /usr/local/l-ui/bin/geoip_custom.dat \
|
||||||
|| { echo "FAIL: custom bin/ file did not survive a second install"; exit 1; }
|
|| { echo "FAIL: custom bin/ file did not survive a second install"; exit 1; }
|
||||||
[ "$(cat /usr/local/x-ui/bin/geoip_custom.dat)" = "custom-sentinel" ] \
|
[ "$(cat /usr/local/l-ui/bin/geoip_custom.dat)" = "custom-sentinel" ] \
|
||||||
|| { echo "FAIL: custom bin/ file content changed across a second install"; exit 1; }
|
|| { echo "FAIL: custom bin/ file content changed across a second install"; exit 1; }
|
||||||
geoip_sum_after=$(sha256sum /usr/local/x-ui/bin/geoip.dat | cut -d" " -f1)
|
geoip_sum_after=$(sha256sum /usr/local/l-ui/bin/geoip.dat | cut -d" " -f1)
|
||||||
[ "$geoip_sum_after" = "$geoip_sum_before" ] \
|
[ "$geoip_sum_after" = "$geoip_sum_before" ] \
|
||||||
|| { echo "FAIL: bundled geoip.dat changed across a same-version reinstall"; exit 1; }
|
|| { echo "FAIL: bundled geoip.dat changed across a same-version reinstall"; exit 1; }
|
||||||
|
|
||||||
echo "SMOKE_PASS: user=$XUI_USERNAME port=$XUI_PANEL_PORT path=$XUI_WEB_BASE_PATH"
|
echo "SMOKE_PASS: user=$LUI_USERNAME port=$LUI_PANEL_PORT path=$LUI_WEB_BASE_PATH"
|
||||||
'
|
'
|
||||||
|
|
||||||
echo "== non-interactive smoke test PASSED =="
|
echo "== non-interactive smoke test PASSED =="
|
||||||
|
|||||||
+15
-15
@@ -1,14 +1,14 @@
|
|||||||
services:
|
services:
|
||||||
3xui:
|
l-ui:
|
||||||
build:
|
build:
|
||||||
context: .
|
context: .
|
||||||
dockerfile: ./Dockerfile
|
dockerfile: ./Dockerfile
|
||||||
container_name: 3xui_app
|
container_name: l-ui_app
|
||||||
# hostname: yourhostname <- optional
|
# hostname: yourhostname <- optional
|
||||||
# Optional hard memory cap. When set, the panel derives its Go soft limit
|
# Optional hard memory cap. When set, the panel derives its Go soft limit
|
||||||
# (GOMEMLIMIT, ~90% of this cap) so it GCs before the OOM killer fires.
|
# (GOMEMLIMIT, ~90% of this cap) so it GCs before the OOM killer fires.
|
||||||
# mem_limit: 512m
|
# mem_limit: 512m
|
||||||
# The bundled Fail2ban (XUI_ENABLE_FAIL2BAN below) enforces the IP limit
|
# The bundled Fail2ban (LUI_ENABLE_FAIL2BAN below) enforces the IP limit
|
||||||
# with iptables, which needs NET_ADMIN. Without these caps a ban is logged
|
# with iptables, which needs NET_ADMIN. Without these caps a ban is logged
|
||||||
# and shown in fail2ban status but never actually applied. NET_RAW covers
|
# and shown in fail2ban status but never actually applied. NET_RAW covers
|
||||||
# ip6tables. If you disable Fail2ban, you can drop cap_add.
|
# ip6tables. If you disable Fail2ban, you can drop cap_add.
|
||||||
@@ -20,39 +20,39 @@ services:
|
|||||||
- NET_ADMIN
|
- NET_ADMIN
|
||||||
- NET_RAW
|
- NET_RAW
|
||||||
volumes:
|
volumes:
|
||||||
- $PWD/db/:/etc/x-ui/
|
- $PWD/db/:/etc/l-ui/
|
||||||
- $PWD/cert/:/root/cert/
|
- $PWD/cert/:/root/cert/
|
||||||
# Persists acme.sh state so certificate auto-renewal survives container
|
# Persists acme.sh state so certificate auto-renewal survives container
|
||||||
# recreation (the entrypoint re-registers the renewal cron job from it).
|
# recreation (the entrypoint re-registers the renewal cron job from it).
|
||||||
- $PWD/acme/:/root/.acme.sh/
|
- $PWD/acme/:/root/.acme.sh/
|
||||||
environment:
|
environment:
|
||||||
XRAY_VMESS_AEAD_FORCED: "false"
|
XRAY_VMESS_AEAD_FORCED: "false"
|
||||||
XUI_ENABLE_FAIL2BAN: "true"
|
LUI_ENABLE_FAIL2BAN: "true"
|
||||||
# Memory tuning. The panel keeps RAM low via GOGC + periodic release; it no
|
# Memory tuning. The panel keeps RAM low via GOGC + periodic release; it no
|
||||||
# longer sets a soft limit from total host RAM (no benefit, risks GC thrash).
|
# longer sets a soft limit from total host RAM (no benefit, risks GC thrash).
|
||||||
# XUI_GOGC: "75" # lower = less RAM, slightly more CPU; GOGC env overrides
|
# LUI_GOGC: "75" # lower = less RAM, slightly more CPU; GOGC env overrides
|
||||||
# XUI_MEMORY_RELEASE_INTERVAL: "10" # minutes between FreeOSMemory; 0 disables
|
# LUI_MEMORY_RELEASE_INTERVAL: "10" # minutes between FreeOSMemory; 0 disables
|
||||||
# Go memory soft limit, only applied from an explicit budget below (or a
|
# Go memory soft limit, only applied from an explicit budget below (or a
|
||||||
# real cgroup/mem_limit cap). Pin it with one of:
|
# real cgroup/mem_limit cap). Pin it with one of:
|
||||||
# XUI_MEMORY_LIMIT: "400" # in MiB
|
# LUI_MEMORY_LIMIT: "400" # in MiB
|
||||||
# GOMEMLIMIT: "400MiB" # Go syntax, takes precedence
|
# GOMEMLIMIT: "400MiB" # Go syntax, takes precedence
|
||||||
# XUI_PPROF: "true" # expose pprof on 127.0.0.1:6060 for profiling
|
# LUI_PPROF: "true" # expose pprof on 127.0.0.1:6060 for profiling
|
||||||
# XUI_INIT_WEB_BASE_PATH: "/"
|
# LUI_INIT_WEB_BASE_PATH: "/"
|
||||||
# XUI_PORT: "8080"
|
# LUI_PORT: "8080"
|
||||||
# To use PostgreSQL instead of the default SQLite, run:
|
# To use PostgreSQL instead of the default SQLite, run:
|
||||||
# docker compose --profile postgres up -d
|
# docker compose --profile postgres up -d
|
||||||
# and uncomment the two lines below.
|
# and uncomment the two lines below.
|
||||||
# XUI_DB_TYPE: "postgres"
|
# LUI_DB_TYPE: "postgres"
|
||||||
# XUI_DB_DSN: "postgres://xui:xui@postgres:5432/xui?sslmode=disable"
|
# LUI_DB_DSN: "postgres://xui:xui@postgres:5432/xui?sslmode=disable" # postgres user/db kept: renaming them would orphan existing pgdata
|
||||||
tty: true
|
tty: true
|
||||||
ports:
|
ports:
|
||||||
# When XUI_PORT is set, publish the same container port (for example "8080:8080").
|
# When LUI_PORT is set, publish the same container port (for example "8080:8080").
|
||||||
- "2053:2053"
|
- "2053:2053"
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
|
|
||||||
postgres:
|
postgres:
|
||||||
image: postgres:16-alpine
|
image: postgres:16-alpine
|
||||||
container_name: 3xui_postgres
|
container_name: l-ui_postgres
|
||||||
profiles: ["postgres"]
|
profiles: ["postgres"]
|
||||||
environment:
|
environment:
|
||||||
POSTGRES_USER: xui
|
POSTGRES_USER: xui
|
||||||
|
|||||||
+21
-21
@@ -1,13 +1,13 @@
|
|||||||
# 3x-ui Agent 模式安装说明
|
# L-UI Agent 模式安装说明
|
||||||
|
|
||||||
节点鸡不再跑完整 3x-ui 面板,只跑一个轻量 agent:用 token 向主控注册,
|
节点鸡不再跑完整 L-UI 面板,只跑一个轻量 agent:用 token 向主控注册,
|
||||||
主控下发完整 xray 配置(含入站、出站、路由规则),agent 写配置并管理 xray 进程,
|
主控下发完整 xray 配置(含入站、出站、路由规则),agent 写配置并管理 xray 进程,
|
||||||
每 60 秒向主控上报流量/在线数。
|
每 60 秒向主控上报流量/在线数。
|
||||||
|
|
||||||
## 架构
|
## 架构
|
||||||
|
|
||||||
- 主控:完整 3x-ui(v3.7.0+agent 补丁),负责生成配置、下发、管理出站与路由规则。
|
- 主控:完整 L-UI(v3.7.0+agent 补丁),负责生成配置、下发、管理出站与路由规则。
|
||||||
- 节点:`x-ui agent` 二进制 + xray 二进制 + geo 文件,无面板、无数据库。
|
- 节点:`l-ui agent` 二进制 + xray 二进制 + geo 文件,无面板、无数据库。
|
||||||
- 出站/路由规则只能在主控上建和改(面板是唯一可信源),agent 只管应用下发
|
- 出站/路由规则只能在主控上建和改(面板是唯一可信源),agent 只管应用下发
|
||||||
的完整配置,不上报本地配置。
|
的完整配置,不上报本地配置。
|
||||||
|
|
||||||
@@ -35,24 +35,24 @@ curl -sk -H "Authorization: Bearer <PANEL_API_TOKEN>" \
|
|||||||
## 二、节点安装
|
## 二、节点安装
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
mkdir -p /usr/local/x-ui/bin /etc/x-ui
|
mkdir -p /usr/local/l-ui/bin /etc/l-ui
|
||||||
|
|
||||||
# 1. 放 x-ui 二进制(agent 补丁版,与主控同版本)
|
# 1. 放 l-ui 二进制(agent 补丁版,与主控同版本),在节点上改名为 lui-agent(与主控进程区分)
|
||||||
cp x-ui /usr/local/x-ui/x-ui && chmod +x /usr/local/x-ui/x-ui
|
cp l-ui /usr/local/l-ui/lui-agent && chmod +x /usr/local/l-ui/lui-agent
|
||||||
|
|
||||||
# 2. 放 xray 二进制与 geo 文件(agent 不负责下载,手动放置)
|
# 2. 放 xray 二进制与 geo 文件(agent 不负责下载,手动放置)
|
||||||
cp xray-linux-amd64 /usr/local/x-ui/bin/xray && chmod +x /usr/local/x-ui/bin/xray
|
cp xray-linux-amd64 /usr/local/l-ui/bin/xray && chmod +x /usr/local/l-ui/bin/xray
|
||||||
cp geoip.dat geosite.dat /usr/local/x-ui/bin/
|
cp geoip.dat geosite.dat /usr/local/l-ui/bin/
|
||||||
|
|
||||||
# 3. 写 agent 配置
|
# 3. 写 agent 配置
|
||||||
cat > /etc/x-ui/agent.json <<'EOF'
|
cat > /etc/l-ui/agent.json <<'EOF'
|
||||||
{
|
{
|
||||||
"master_url": "http://主控内网地址:2053",
|
"master_url": "http://主控内网地址:2053",
|
||||||
"token": "<上一步生成的 token>",
|
"token": "<上一步生成的 token>",
|
||||||
"node_name": "hk-node-1"
|
"node_name": "hk-node-1"
|
||||||
}
|
}
|
||||||
EOF
|
EOF
|
||||||
chmod 600 /etc/x-ui/agent.json
|
chmod 600 /etc/l-ui/agent.json
|
||||||
```
|
```
|
||||||
|
|
||||||
说明:
|
说明:
|
||||||
@@ -60,27 +60,27 @@ chmod 600 /etc/x-ui/agent.json
|
|||||||
- `master_url` 用 `http://`(内网)或 `https://`(需可信证书;自签证书连不上,
|
- `master_url` 用 `http://`(内网)或 `https://`(需可信证书;自签证书连不上,
|
||||||
agent 默认校验 TLS)。
|
agent 默认校验 TLS)。
|
||||||
- `poll_interval` 可省略,默认 30 秒轮询一次配置。
|
- `poll_interval` 可省略,默认 30 秒轮询一次配置。
|
||||||
- 不要在节点上再启动完整面板(`x-ui` 不带 `agent` 参数的模式)。
|
- 不要在节点上再启动完整面板(`l-ui` 不带 `agent` 参数的模式)。
|
||||||
|
|
||||||
## 三、启动 agent
|
## 三、启动 agent
|
||||||
|
|
||||||
systemd(Debian/Ubuntu):
|
systemd(Debian/Ubuntu):
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
cp systemd/x-ui-agent.service /etc/systemd/system/
|
cp systemd/lui-agent.service /etc/systemd/system/
|
||||||
systemctl daemon-reload
|
systemctl daemon-reload
|
||||||
systemctl enable --now x-ui-agent
|
systemctl enable --now lui-agent
|
||||||
journalctl -u x-ui-agent -f
|
journalctl -u lui-agent -f
|
||||||
```
|
```
|
||||||
|
|
||||||
OpenWrt(procd):
|
OpenWrt(procd):
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
cp openrc/x-ui-agent /etc/init.d/x-ui-agent
|
cp openrc/lui-agent /etc/init.d/lui-agent
|
||||||
chmod +x /etc/init.d/x-ui-agent
|
chmod +x /etc/init.d/lui-agent
|
||||||
/etc/init.d/x-ui-agent enable
|
/etc/init.d/lui-agent enable
|
||||||
/etc/init.d/x-ui-agent start
|
/etc/init.d/lui-agent start
|
||||||
logread -f | grep x-ui-agent
|
logread -f | grep lui-agent
|
||||||
```
|
```
|
||||||
|
|
||||||
## 四、主控管理该节点的出站与路由规则
|
## 四、主控管理该节点的出站与路由规则
|
||||||
@@ -120,6 +120,6 @@ curl -sk -H "Authorization: Bearer <PANEL_API_TOKEN>" \
|
|||||||
|---|---|
|
|---|---|
|
||||||
| `register failed ... 401` | token 贴错,或 token 没在主控生成 |
|
| `register failed ... 401` | token 贴错,或 token 没在主控生成 |
|
||||||
| `config fetch failed ... 409` | token 未绑定节点(生成时没传 `node_id`) |
|
| `config fetch failed ... 409` | token 未绑定节点(生成时没传 `node_id`) |
|
||||||
| xray 起不来 | `/usr/local/x-ui/bin/xray` 是否存在可执行;`xray -test -c /usr/local/x-ui/bin/config.json` 看配置报错 |
|
| xray 起不来 | `/usr/local/l-ui/bin/xray` 是否存在可执行;`xray -test -c /usr/local/l-ui/bin/config.json` 看配置报错 |
|
||||||
| 流量不上报 | xray 的 api 入站端口是否被占用;agent 日志看 `Traffic report failed` |
|
| 流量不上报 | xray 的 api 入站端口是否被占用;agent 日志看 `Traffic report failed` |
|
||||||
| 主控连不上 | `master_url` 拼错;https 自签证书改走 `http://` 内网地址 |
|
| 主控连不上 | `master_url` 拼错;https 自签证书改走 `http://` 内网地址 |
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
# Contributing to 3x-ui-docs
|
# Contributing to L-UI-docs
|
||||||
|
|
||||||
Thanks for helping improve the 3x-ui documentation and product site!
|
Thanks for helping improve the L-UI documentation and product site!
|
||||||
|
|
||||||
## Prerequisites
|
## Prerequisites
|
||||||
|
|
||||||
|
|||||||
+6
-6
@@ -2,22 +2,22 @@
|
|||||||
<a href="https://docs.sanaei.dev">
|
<a href="https://docs.sanaei.dev">
|
||||||
<picture>
|
<picture>
|
||||||
<source media="(prefers-color-scheme: dark)" srcset="public/logo-dark.png" />
|
<source media="(prefers-color-scheme: dark)" srcset="public/logo-dark.png" />
|
||||||
<img src="public/logo-light.png" alt="3x-ui" width="180" />
|
<img src="public/logo-light.png" alt="L-UI" width="180" />
|
||||||
</picture>
|
</picture>
|
||||||
</a>
|
</a>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<h1 align="center">3x-ui Documentation</h1>
|
<h1 align="center">L-UI Documentation</h1>
|
||||||
|
|
||||||
<p align="center">
|
<p align="center">
|
||||||
The official documentation and product site for
|
The official documentation and product site for
|
||||||
<a href="https://github.com/MHSanaei/3x-ui"><b>3x-ui</b></a> —
|
<a href="https://github.com/MHSanaei/L-UI"><b>L-UI</b></a> —
|
||||||
an advanced web panel for managing Xray-core servers.
|
an advanced web panel for managing Xray-core servers.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p align="center">
|
<p align="center">
|
||||||
<a href="https://docs.sanaei.dev"><img src="https://img.shields.io/badge/docs-docs.sanaei.dev-22d3ee?style=flat-square" alt="Live site" /></a>
|
<a href="https://docs.sanaei.dev"><img src="https://img.shields.io/badge/docs-docs.sanaei.dev-22d3ee?style=flat-square" alt="Live site" /></a>
|
||||||
<a href="https://github.com/MHSanaei/3x-ui/actions/workflows/docs-ci.yml"><img src="https://github.com/MHSanaei/3x-ui/actions/workflows/docs-ci.yml/badge.svg" alt="CI" /></a>
|
<a href="https://github.com/MHSanaei/L-UI/actions/workflows/docs-ci.yml"><img src="https://github.com/MHSanaei/L-UI/actions/workflows/docs-ci.yml/badge.svg" alt="CI" /></a>
|
||||||
<a href="LICENSE"><img src="https://img.shields.io/badge/license-GPL--3.0-blue?style=flat-square" alt="License: GPL-3.0" /></a>
|
<a href="LICENSE"><img src="https://img.shields.io/badge/license-GPL--3.0-blue?style=flat-square" alt="License: GPL-3.0" /></a>
|
||||||
<img src="https://img.shields.io/badge/Next.js-16-black?style=flat-square&logo=next.js" alt="Next.js 16" />
|
<img src="https://img.shields.io/badge/Next.js-16-black?style=flat-square&logo=next.js" alt="Next.js 16" />
|
||||||
<img src="https://img.shields.io/badge/Fumadocs-16-0ea5e9?style=flat-square" alt="Fumadocs 16" />
|
<img src="https://img.shields.io/badge/Fumadocs-16-0ea5e9?style=flat-square" alt="Fumadocs 16" />
|
||||||
@@ -31,7 +31,7 @@
|
|||||||
|
|
||||||
## Overview
|
## Overview
|
||||||
|
|
||||||
This directory (`docs/` in the [3x-ui](https://github.com/MHSanaei/3x-ui) monorepo) contains
|
This directory (`docs/` in the [L-UI](https://github.com/MHSanaei/L-UI) monorepo) contains
|
||||||
the source for [docs.sanaei.dev](https://docs.sanaei.dev) — a static-first documentation and
|
the source for [docs.sanaei.dev](https://docs.sanaei.dev) — a static-first documentation and
|
||||||
marketing site built with [Fumadocs](https://fumadocs.dev) on Next.js. It has **no backend,
|
marketing site built with [Fumadocs](https://fumadocs.dev) on Next.js. It has **no backend,
|
||||||
no database, and no auth**: every page is prerendered and every tool runs entirely in the
|
no database, and no auth**: every page is prerendered and every tool runs entirely in the
|
||||||
@@ -39,7 +39,7 @@ browser.
|
|||||||
|
|
||||||
## What's inside
|
## What's inside
|
||||||
|
|
||||||
The documentation walks you through 3x-ui from first install to day-to-day operation:
|
The documentation walks you through L-UI from first install to day-to-day operation:
|
||||||
|
|
||||||
- **Getting Started** — installation, first login, and updating or uninstalling the panel.
|
- **Getting Started** — installation, first login, and updating or uninstalling the panel.
|
||||||
- **Configuration** — the panel, inbounds, REALITY, transports, clients, subscriptions, and share links.
|
- **Configuration** — the panel, inbounds, REALITY, transports, clients, subscriptions, and share links.
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ export function generateStaticParams() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const INSTALL_COMMAND =
|
const INSTALL_COMMAND =
|
||||||
'bash <(curl -Ls https://raw.githubusercontent.com/mhsanaei/3x-ui/master/install.sh)';
|
'bash <(curl -Ls https://git.881218.xyz/rogue/l-ui/raw/branch/main/install-master.sh)';
|
||||||
|
|
||||||
export default async function HomePage({ params }: PageProps<'/[lang]'>) {
|
export default async function HomePage({ params }: PageProps<'/[lang]'>) {
|
||||||
const { lang } = await params;
|
const { lang } = await params;
|
||||||
|
|||||||
+1
-1
@@ -2,7 +2,7 @@
|
|||||||
@import 'fumadocs-ui/css/neutral.css';
|
@import 'fumadocs-ui/css/neutral.css';
|
||||||
@import 'fumadocs-ui/css/preset.css';
|
@import 'fumadocs-ui/css/preset.css';
|
||||||
|
|
||||||
/* 3x-ui brand: cyan / turquoise accent (matches the panel logo). */
|
/* L-UI brand: cyan / turquoise accent (matches the panel logo). */
|
||||||
:root {
|
:root {
|
||||||
--color-fd-primary: hsl(190, 95%, 39%);
|
--color-fd-primary: hsl(190, 95%, 39%);
|
||||||
--color-fd-primary-foreground: hsl(0, 0%, 100%);
|
--color-fd-primary-foreground: hsl(0, 0%, 100%);
|
||||||
|
|||||||
+19
-22
@@ -1,4 +1,4 @@
|
|||||||
# 3x-ui — Architecture & Code Map
|
# L-UI — Architecture & Code Map
|
||||||
|
|
||||||
> Navigation map for contributors and AI coding agents (referenced from `CLAUDE.md`).
|
> Navigation map for contributors and AI coding agents (referenced from `CLAUDE.md`).
|
||||||
> Goal: jump to the right file in one hop instead of grepping the whole tree.
|
> Goal: jump to the right file in one hop instead of grepping the whole tree.
|
||||||
@@ -13,7 +13,7 @@
|
|||||||
|
|
||||||
## 1. Mental model (the 30-second version)
|
## 1. Mental model (the 30-second version)
|
||||||
|
|
||||||
3x-ui is a **web control panel for [Xray-core](https://github.com/XTLS/Xray-core)**. The Go
|
L-UI is a **web control panel for [Xray-core](https://github.com/XTLS/Xray-core)**. The Go
|
||||||
backend is the source of truth: it stores inbounds/clients/settings in a DB, renders an
|
backend is the source of truth: it stores inbounds/clients/settings in a DB, renders an
|
||||||
Xray JSON config from that state, supervises the Xray child process, and exposes a REST +
|
Xray JSON config from that state, supervises the Xray child process, and exposes a REST +
|
||||||
WebSocket API. A React SPA (built by Vite, embedded into the Go binary) is the UI. A second,
|
WebSocket API. A React SPA (built by Vite, embedded into the Go binary) is the UI. A second,
|
||||||
@@ -41,7 +41,7 @@ Two key ideas that explain most of the complexity:
|
|||||||
1. **The DB → Xray config pipeline.** Inbounds/clients live in the DB. On every change the
|
1. **The DB → Xray config pipeline.** Inbounds/clients live in the DB. On every change the
|
||||||
backend regenerates the Xray config and applies it — preferring a _hot diff_ (live gRPC
|
backend regenerates the Xray config and applies it — preferring a _hot diff_ (live gRPC
|
||||||
API mutation) over a full process restart. See §5.1.
|
API mutation) over a full process restart. See §5.1.
|
||||||
2. **The Runtime abstraction (multi-node).** A panel can manage remote "nodes" (other 3x-ui
|
2. **The Runtime abstraction (multi-node).** A panel can manage remote "nodes" (other L-UI
|
||||||
instances). Every state-changing inbound/client operation is dispatched through a
|
instances). Every state-changing inbound/client operation is dispatched through a
|
||||||
`runtime.Runtime` interface that is either **`Local`** (this box's Xray gRPC API) or
|
`runtime.Runtime` interface that is either **`Local`** (this box's Xray gRPC API) or
|
||||||
**`Remote`** (HTTPS call to a child node, with `verify`/`skip`/`pin`/`mtls` TLS modes).
|
**`Remote`** (HTTPS call to a child node, with `verify`/`skip`/`pin`/`mtls` TLS modes).
|
||||||
@@ -54,7 +54,7 @@ Two key ideas that explain most of the complexity:
|
|||||||
**Backend (Go 1.27):**
|
**Backend (Go 1.27):**
|
||||||
|
|
||||||
- Web framework: **Gin** (`gin-gonic/gin`) + sessions (cookie store), gzip.
|
- Web framework: **Gin** (`gin-gonic/gin`) + sessions (cookie store), gzip.
|
||||||
- ORM: **GORM** with **SQLite** (default) or **PostgreSQL** (`XUI_DB_TYPE=postgres`).
|
- ORM: **GORM** with **SQLite** (default) or **PostgreSQL** (`LUI_DB_TYPE=postgres`).
|
||||||
- Scheduler: **robfig/cron/v3** (seconds-precision) for all background jobs.
|
- Scheduler: **robfig/cron/v3** (seconds-precision) for all background jobs.
|
||||||
- Xray: **xtls/xray-core** vendored as a library; the panel talks to the running core over
|
- Xray: **xtls/xray-core** vendored as a library; the panel talks to the running core over
|
||||||
its **gRPC API** and also shells out to manage the process.
|
its **gRPC API** and also shells out to manage the process.
|
||||||
@@ -85,7 +85,7 @@ Browser (React, fetch)
|
|||||||
→ POST {basePath}/panel/api/...
|
→ POST {basePath}/panel/api/...
|
||||||
→ Gin engine (internal/web/web.go: initRouter)
|
→ Gin engine (internal/web/web.go: initRouter)
|
||||||
→ middleware chain: SecurityHeaders → MaxBodyBytes (10 MiB; importDB exempt)
|
→ middleware chain: SecurityHeaders → MaxBodyBytes (10 MiB; importDB exempt)
|
||||||
→ [DomainValidator, if webDomain set] → gzip → sessions("3x-ui")
|
→ [DomainValidator, if webDomain set] → gzip → sessions("L-UI")
|
||||||
→ base-path/cache-control context → Localizer
|
→ base-path/cache-control context → Localizer
|
||||||
→ API routes add: ConfigEnvelope (zstd + SHA-256) → CSRF
|
→ API routes add: ConfigEnvelope (zstd + SHA-256) → CSRF
|
||||||
→ Controller (internal/web/controller/*.go) // HTTP concerns only: bind, validate, respond
|
→ Controller (internal/web/controller/*.go) // HTTP concerns only: bind, validate, respond
|
||||||
@@ -120,14 +120,14 @@ node heartbeat every 5s, periodic traffic resets (hourly/daily/weekly/monthly).
|
|||||||
## 4. Directory map (what lives where)
|
## 4. Directory map (what lives where)
|
||||||
|
|
||||||
```
|
```
|
||||||
3x-ui/
|
L-UI/
|
||||||
├── main.go # Entry point: CLI (run / migrate / migrate-db / setting / cert),
|
├── main.go # Entry point: CLI (run / migrate / migrate-db / setting / cert),
|
||||||
│ # bootstrap, signal handling, restart loop
|
│ # bootstrap, signal handling, restart loop
|
||||||
├── go.mod / go.sum # Go deps (module path ends in /v3)
|
├── go.mod / go.sum # Go deps (module path ends in /v3)
|
||||||
│
|
│
|
||||||
├── internal/ # ALL backend Go code (private packages)
|
├── internal/ # ALL backend Go code (private packages)
|
||||||
│ ├── config/ # Env-var config: paths, DB kind/DSN, log level, version
|
│ ├── config/ # Env-var config: paths, DB kind/DSN, log level, version
|
||||||
│ │ # Every XUI_* env var is read here (config.go)
|
│ │ # Every LUI_* env var is read here (config.go)
|
||||||
│ ├── database/
|
│ ├── database/
|
||||||
│ │ ├── db.go # InitDB: connect, AutoMigrate, seeders (~1.4k lines). DB hotspot.
|
│ │ ├── db.go # InitDB: connect, AutoMigrate, seeders (~1.4k lines). DB hotspot.
|
||||||
│ │ ├── migrate_data.go # Data migrations (seeders/normalizers beyond AutoMigrate)
|
│ │ ├── migrate_data.go # Data migrations (seeders/normalizers beyond AutoMigrate)
|
||||||
@@ -139,7 +139,7 @@ node heartbeat every 5s, periodic traffic resets (hourly/daily/weekly/monthly).
|
|||||||
│ ├── pia/ # PIA WireGuard protocol client (auth, signed server list, /addKey)
|
│ ├── pia/ # PIA WireGuard protocol client (auth, signed server list, /addKey)
|
||||||
│ ├── eventbus/ # In-process pub/sub (buffered channel): outbound.down|up,
|
│ ├── eventbus/ # In-process pub/sub (buffered channel): outbound.down|up,
|
||||||
│ │ # xray.crash, node.down|up, cpu.high, memory.high, login.attempt
|
│ │ # xray.crash, node.down|up, cpu.high, memory.high, login.attempt
|
||||||
│ ├── tunnelmonitor/ # Optional tunnel health probe (XUI_TUNNEL_HEALTH_* env vars):
|
│ ├── tunnelmonitor/ # Optional tunnel health probe (LUI_TUNNEL_HEALTH_* env vars):
|
||||||
│ │ # HTTP probe (default Cloudflare trace); repeated failures
|
│ │ # HTTP probe (default Cloudflare trace); repeated failures
|
||||||
│ │ # trigger an Xray restart hook. Independent of panel settings.
|
│ │ # trigger an Xray restart hook. Independent of panel settings.
|
||||||
│ ├── xray/ # Xray-core integration (the proxy engine wrapper)
|
│ ├── xray/ # Xray-core integration (the proxy engine wrapper)
|
||||||
@@ -163,9 +163,9 @@ node heartbeat every 5s, periodic traffic resets (hourly/daily/weekly/monthly).
|
|||||||
│ │ │ ├── node.go # /panel/api/nodes (multi-node management)
|
│ │ │ ├── node.go # /panel/api/nodes (multi-node management)
|
||||||
│ │ │ ├── host.go # /panel/api/hosts (per-inbound subscription host overrides)
|
│ │ │ ├── host.go # /panel/api/hosts (per-inbound subscription host overrides)
|
||||||
│ │ │ ├── server.go # /panel/api/server (status, xray version, certs, logs, DB import/export)
|
│ │ │ ├── server.go # /panel/api/server (status, xray version, certs, logs, DB import/export)
|
||||||
│ │ │ ├── setting.go # /panel/api/setting (settings + API tokens)
|
│ │ │ ├── setting.go # /panel/api/setting (settings)
|
||||||
│ │ │ ├── xray_setting.go # /panel/api/xray (raw Xray config editor, WARP/Nord/PIA, geodata)
|
│ │ │ ├── xray_setting.go # /panel/api/xray (raw Xray config editor, WARP/Nord/PIA, geodata)
|
||||||
│ │ │ ├── api.go # /panel/api gateway (token auth, envelope + CSRF wiring)
|
│ │ │ ├── api.go # /panel/api gateway (envelope + CSRF wiring)
|
||||||
│ │ │ ├── index.go # login/logout/csrf/2FA
|
│ │ │ ├── index.go # login/logout/csrf/2FA
|
||||||
│ │ │ ├── spa.go # SPA fallback for /panel UI routes
|
│ │ │ ├── spa.go # SPA fallback for /panel UI routes
|
||||||
│ │ │ └── websocket.go # WS upgrade endpoint
|
│ │ │ └── websocket.go # WS upgrade endpoint
|
||||||
@@ -203,12 +203,11 @@ node heartbeat every 5s, periodic traffic resets (hourly/daily/weekly/monthly).
|
|||||||
│ │ │ ├── port_conflict.go # Detect inbound port collisions
|
│ │ │ ├── port_conflict.go # Detect inbound port collisions
|
||||||
│ │ │ ├── fallback.go # Xray fallback (SNI/ALPN routing on shared port)
|
│ │ │ ├── fallback.go # Xray fallback (SNI/ALPN routing on shared port)
|
||||||
│ │ │ ├── email/ # Email notification service (SMTP)
|
│ │ │ ├── email/ # Email notification service (SMTP)
|
||||||
│ │ │ ├── integration/ # External providers: warp.go, nord.go, pia.go
|
│ │ │ ├── integration/ # External providers: warp.go
|
||||||
│ │ │ ├── outbound/ # Outbound config service
|
│ │ │ ├── outbound/ # Outbound config service
|
||||||
│ │ │ ├── panel/ # Cross-cutting panel services:
|
│ │ │ ├── panel/ # Cross-cutting panel services:
|
||||||
│ │ │ │ ├── panel.go # panel-level helpers
|
│ │ │ │ ├── panel.go # panel-level helpers
|
||||||
│ │ │ │ ├── user.go # admin user auth (bcrypt)
|
│ │ │ │ ├── user.go # admin user auth (bcrypt)
|
||||||
│ │ │ │ ├── api_token.go # API token CRUD (SHA-256 hashed)
|
|
||||||
│ │ │ │ └── websocket.go # WS hub / push service
|
│ │ │ │ └── websocket.go # WS hub / push service
|
||||||
│ │ │ └── tgbot/ # Telegram bot command handlers
|
│ │ │ └── tgbot/ # Telegram bot command handlers
|
||||||
│ │ ├── runtime/ # ⭐⭐ The Local/Remote node abstraction (see §5.2)
|
│ │ ├── runtime/ # ⭐⭐ The Local/Remote node abstraction (see §5.2)
|
||||||
@@ -281,8 +280,8 @@ node heartbeat every 5s, periodic traffic resets (hourly/daily/weekly/monthly).
|
|||||||
├── media/ # README images
|
├── media/ # README images
|
||||||
│
|
│
|
||||||
├── Dockerfile / docker-compose.yml / DockerEntrypoint.sh / DockerInit.sh # Container build/run
|
├── Dockerfile / docker-compose.yml / DockerEntrypoint.sh / DockerInit.sh # Container build/run
|
||||||
├── install.sh / update.sh / x-ui.sh # VPS install + management CLI
|
├── install.sh / update.sh / l-ui.sh # VPS install + management CLI
|
||||||
├── x-ui.service.* / x-ui.rc # systemd units (debian/rhel/arch) + rc script
|
├── l-ui.service.* / l-ui.rc # systemd units (debian/rhel/arch) + rc script
|
||||||
├── windows_files/ # Windows service support
|
├── windows_files/ # Windows service support
|
||||||
└── .github/workflows/ # CI: ci.yml, codeql.yml, docker.yml, release.yml, smoke.yml,
|
└── .github/workflows/ # CI: ci.yml, codeql.yml, docker.yml, release.yml, smoke.yml,
|
||||||
# mutation.yml, cleanup_caches.yml, claude-bot.yml
|
# mutation.yml, cleanup_caches.yml, claude-bot.yml
|
||||||
@@ -314,7 +313,7 @@ Restart is debounced via an atomic "need restart" flag (`SetToNeedRestart` /
|
|||||||
|
|
||||||
### 5.2 Runtime abstraction — Local vs Remote (multi-node) ⭐ most important
|
### 5.2 Runtime abstraction — Local vs Remote (multi-node) ⭐ most important
|
||||||
|
|
||||||
A "node" (`model.Node`) is another 3x-ui instance this panel controls. Every state-changing
|
A "node" (`model.Node`) is another L-UI instance this panel controls. Every state-changing
|
||||||
inbound/client operation goes through the `runtime.Runtime` interface so the _same service
|
inbound/client operation goes through the `runtime.Runtime` interface so the _same service
|
||||||
code_ works whether the target is the local Xray or a remote node.
|
code_ works whether the target is the local Xray or a remote node.
|
||||||
|
|
||||||
@@ -327,7 +326,7 @@ code_ works whether the target is the local Xray or a remote node.
|
|||||||
- **TLS modes** (`tls_client.go`, per-node `TlsVerifyMode`):
|
- **TLS modes** (`tls_client.go`, per-node `TlsVerifyMode`):
|
||||||
`verify` (system CAs, default) / `skip` (no validation) / `pin` (leaf cert SHA-256 must
|
`verify` (system CAs, default) / `skip` (no validation) / `pin` (leaf cert SHA-256 must
|
||||||
match `PinnedCertSha256`) / `mtls` (master presents a client certificate; node cert checked
|
match `PinnedCertSha256`) / `mtls` (master presents a client certificate; node cert checked
|
||||||
against system roots; API token optional). Master-side cert management:
|
against system roots). Master-side cert management:
|
||||||
`service/node_mtls.go` + `service/setting_mtls.go`.
|
`service/node_mtls.go` + `service/setting_mtls.go`.
|
||||||
- **Dispatch:** `manager.go` → `Manager.RuntimeFor(nodeID *int)`; `nil` nodeID → `Local`,
|
- **Dispatch:** `manager.go` → `Manager.RuntimeFor(nodeID *int)`; `nil` nodeID → `Local`,
|
||||||
otherwise a cached/lazy-loaded `Remote`. `InvalidateNode(id)` drops a cached remote client.
|
otherwise a cached/lazy-loaded `Remote`. `InvalidateNode(id)` drops a cached remote client.
|
||||||
@@ -431,7 +430,7 @@ notifications instead of importing notification services into producers.
|
|||||||
### 5.8 Tunnel health monitor
|
### 5.8 Tunnel health monitor
|
||||||
|
|
||||||
`internal/tunnelmonitor/` is an optional watchdog configured **only via env vars**
|
`internal/tunnelmonitor/` is an optional watchdog configured **only via env vars**
|
||||||
(`XUI_TUNNEL_HEALTH_*`, read in `internal/config/`), deliberately independent of panel
|
(`LUI_TUNNEL_HEALTH_*`, read in `internal/config/`), deliberately independent of panel
|
||||||
settings so it can be enabled from a systemd `EnvironmentFile` even when the panel is
|
settings so it can be enabled from a systemd `EnvironmentFile` even when the panel is
|
||||||
unreachable. It periodically probes an HTTP URL (default: Cloudflare trace endpoint) through
|
unreachable. It periodically probes an HTTP URL (default: Cloudflare trace endpoint) through
|
||||||
the tunnel; after N successive failures (default 3) it fires a recovery callback wired to an
|
the tunnel; after N successive failures (default 3) it fires a recovery callback wired to an
|
||||||
@@ -462,7 +461,6 @@ for AutoMigrate in `internal/database/db.go`.
|
|||||||
| `OutboundTraffics` | Outbound counters | per outbound tag |
|
| `OutboundTraffics` | Outbound counters | per outbound tag |
|
||||||
| `OutboundSubscription` | External provider subs | Warp/Nord style |
|
| `OutboundSubscription` | External provider subs | Warp/Nord style |
|
||||||
| `Setting` | Key/value panel settings | everything configurable |
|
| `Setting` | Key/value panel settings | everything configurable |
|
||||||
| `ApiToken` | REST API tokens | SHA-256 hash (plaintext shown once) |
|
|
||||||
| `InboundFallback` | Fallback routing on a shared port | SNI/ALPN/path → dest |
|
| `InboundFallback` | Fallback routing on a shared port | SNI/ALPN/path → dest |
|
||||||
| `HistoryOfSeeders` | Seeder bookkeeping | prevents re-running one-off migrations |
|
| `HistoryOfSeeders` | Seeder bookkeeping | prevents re-running one-off migrations |
|
||||||
|
|
||||||
@@ -490,7 +488,6 @@ for AutoMigrate in `internal/database/db.go`.
|
|||||||
| **External subscription** import/aggregation | `sub/external_subscription.go`, `sub/external_config.go` | `sub/clash_external.go` |
|
| **External subscription** import/aggregation | `sub/external_subscription.go`, `sub/external_config.go` | `sub/clash_external.go` |
|
||||||
| **Settings** not saving / defaults | `service/setting.go`, `controller/setting.go` | model `Setting` |
|
| **Settings** not saving / defaults | `service/setting.go`, `controller/setting.go` | model `Setting` |
|
||||||
| **Login / 2FA / sessions / CSRF** | `controller/index.go`, `service/panel/user.go`, `middleware/` | `session/` |
|
| **Login / 2FA / sessions / CSRF** | `controller/index.go`, `service/panel/user.go`, `middleware/` | `session/` |
|
||||||
| **API tokens** | `service/panel/api_token.go`, `controller/setting.go` | model `ApiToken` |
|
|
||||||
| **Port conflict** on inbound add | `service/port_conflict.go` | `controller/inbound.go` |
|
| **Port conflict** on inbound add | `service/port_conflict.go` | `controller/inbound.go` |
|
||||||
| **Fallbacks** (shared 443, SNI routing) | `service/fallback.go`, `controller/inbound.go` | model `InboundFallback` |
|
| **Fallbacks** (shared 443, SNI routing) | `service/fallback.go`, `controller/inbound.go` | model `InboundFallback` |
|
||||||
| **Geo category browser** empty / won't open | `xray/geodata/` (`Store`, `reader.go`), `service/geodata.go` | `controller/xray_setting.go` (`/panel/api/xray/geodata/*`), asset dir = `config.GetBinFolderPath()` |
|
| **Geo category browser** empty / won't open | `xray/geodata/` (`Store`, `reader.go`), `service/geodata.go` | `controller/xray_setting.go` (`/panel/api/xray/geodata/*`), asset dir = `config.GetBinFolderPath()` |
|
||||||
@@ -498,7 +495,7 @@ for AutoMigrate in `internal/database/db.go`.
|
|||||||
| **Telegram bot** commands | `service/tgbot/` | `job/stats_notify_job.go` |
|
| **Telegram bot** commands | `service/tgbot/` | `job/stats_notify_job.go` |
|
||||||
| **Email notifications** | `service/email/` | `internal/eventbus/` (consumers) |
|
| **Email notifications** | `service/email/` | `internal/eventbus/` (consumers) |
|
||||||
| **CPU / memory alerts** not firing | `job/check_cpu_usage.go`, `job/check_memory_usage.go` | `internal/eventbus/`, notifier settings in `service/setting.go` |
|
| **CPU / memory alerts** not firing | `job/check_cpu_usage.go`, `job/check_memory_usage.go` | `internal/eventbus/`, notifier settings in `service/setting.go` |
|
||||||
| Xray auto-restart on **dead tunnel** | `internal/tunnelmonitor/` | `XUI_TUNNEL_HEALTH_*` in `internal/config/` |
|
| Xray auto-restart on **dead tunnel** | `internal/tunnelmonitor/` | `LUI_TUNNEL_HEALTH_*` in `internal/config/` |
|
||||||
| **WARP / Nord / PIA** outbound integration | `service/integration/warp.go` / `nord.go` / `pia.go` | `internal/pia/`, `frontend/src/pages/xray/overrides/` |
|
| **WARP / Nord / PIA** outbound integration | `service/integration/warp.go` / `nord.go` / `pia.go` | `internal/pia/`, `frontend/src/pages/xray/overrides/` |
|
||||||
| **MTProto** proxy issues | `internal/mtproto/manager.go`, `mtproto/process*.go` | `job/mtproto_job.go` |
|
| **MTProto** proxy issues | `internal/mtproto/manager.go`, `mtproto/process*.go` | `job/mtproto_job.go` |
|
||||||
| **DB migration** / new column | `internal/database/db.go` (AutoMigrate list), `migrate_data.go` | `model/model.go` |
|
| **DB migration** / new column | `internal/database/db.go` (AutoMigrate list), `migrate_data.go` | `model/model.go` |
|
||||||
@@ -580,8 +577,8 @@ root → `go build ./...` / `go run main.go`.
|
|||||||
## 10. Gotchas & conventions
|
## 10. Gotchas & conventions
|
||||||
|
|
||||||
- **Module path is `.../v3`.** Internal imports use `github.com/mhsanaei/3x-ui/v3/internal/...`.
|
- **Module path is `.../v3`.** Internal imports use `github.com/mhsanaei/3x-ui/v3/internal/...`.
|
||||||
- **SQLite vs Postgres.** Default is SQLite at `{XUI_DB_FOLDER}/x-ui.db`. Postgres via
|
- **SQLite vs Postgres.** Default is SQLite at `{LUI_DB_FOLDER}/l-ui.db`. Postgres via
|
||||||
`XUI_DB_TYPE=postgres` + `XUI_DB_DSN`. Some SQL paths are dialect-aware (`database/dialect.go`);
|
`LUI_DB_TYPE=postgres` + `LUI_DB_DSN`. Some SQL paths are dialect-aware (`database/dialect.go`);
|
||||||
test both when touching raw queries (there are `*_scale_postgres_test.go` suites).
|
test both when touching raw queries (there are `*_scale_postgres_test.go` suites).
|
||||||
- **`Inbound.Settings` / `StreamSettings` / `Sniffing` are raw JSON strings**, not structured
|
- **`Inbound.Settings` / `StreamSettings` / `Sniffing` are raw JSON strings**, not structured
|
||||||
columns. Parsing/validation happens in services and the `xray` package, not in GORM.
|
columns. Parsing/validation happens in services and the `xray` package, not in GORM.
|
||||||
|
|||||||
@@ -1,15 +1,15 @@
|
|||||||
import { cn } from '@/lib/cn';
|
import { cn } from '@/lib/cn';
|
||||||
|
|
||||||
// Official 3x-ui logo (media/3x-ui-{light,dark}.png from the upstream repo).
|
// Official L-UI logo (media/L-UI-{light,dark}.png from the upstream repo).
|
||||||
// Theme-aware via Tailwind's `dark:` variant. Pass a height class (e.g. `h-6`);
|
// Theme-aware via Tailwind's `dark:` variant. Pass a height class (e.g. `h-6`);
|
||||||
// width scales automatically (the artwork is 2:1).
|
// width scales automatically (the artwork is 2:1).
|
||||||
export function Logo({ className }: { className?: string }) {
|
export function Logo({ className }: { className?: string }) {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{/* eslint-disable-next-line @next/next/no-img-element */}
|
{/* eslint-disable-next-line @next/next/no-img-element */}
|
||||||
<img src="/logo-light.png" alt="3x-ui" className={cn('w-auto dark:hidden', className)} />
|
<img src="/logo-light.png" alt="L-UI" className={cn('w-auto dark:hidden', className)} />
|
||||||
{/* eslint-disable-next-line @next/next/no-img-element */}
|
{/* eslint-disable-next-line @next/next/no-img-element */}
|
||||||
<img src="/logo-dark.png" alt="3x-ui" className={cn('hidden w-auto dark:block', className)} />
|
<img src="/logo-dark.png" alt="L-UI" className={cn('hidden w-auto dark:block', className)} />
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ export function ApiRequestBuilder() {
|
|||||||
return (
|
return (
|
||||||
<ToolFrame
|
<ToolFrame
|
||||||
title="API request builder"
|
title="API request builder"
|
||||||
description="Build an authenticated cURL command or fetch() snippet for any 3x-ui panel API endpoint under /panel/api/*."
|
description="Build an authenticated cURL command or fetch() snippet for any L-UI panel API endpoint under /panel/api/*."
|
||||||
onReset={reset}
|
onReset={reset}
|
||||||
>
|
>
|
||||||
<div className="grid grid-cols-1 gap-4 sm:grid-cols-2">
|
<div className="grid grid-cols-1 gap-4 sm:grid-cols-2">
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ export function InstallCommandBuilder() {
|
|||||||
value={version}
|
value={version}
|
||||||
onChange={setVersion}
|
onChange={setVersion}
|
||||||
placeholder="latest"
|
placeholder="latest"
|
||||||
hint="blank = latest stable · a tag like v3.4.0 · or dev-latest for the rolling dev build"
|
hint="blank = latest release · a tag like V2.7.5 (script at that tag) · or dev-latest for the main-branch script"
|
||||||
/>
|
/>
|
||||||
{method === 'docker' ? (
|
{method === 'docker' ? (
|
||||||
<>
|
<>
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
---
|
---
|
||||||
title: AmneziaWG
|
title: AmneziaWG
|
||||||
description: Set up an AmneziaWG inbound in 3x-ui — obfuscation parameters, native IPv6, per-client port-forwarding, and routing client traffic through Xray.
|
description: Set up an AmneziaWG inbound in L-UI — obfuscation parameters, native IPv6, per-client port-forwarding, and routing client traffic through Xray.
|
||||||
icon: Lock
|
icon: Lock
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
---
|
---
|
||||||
title: Clients
|
title: Clients
|
||||||
description: Manage 3x-ui clients — credentials, traffic and expiry limits, IP limits, groups, bulk actions, external links, and online status.
|
description: Manage L-UI clients — credentials, traffic and expiry limits, IP limits, groups, bulk actions, external links, and online status.
|
||||||
icon: Users
|
icon: Users
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
---
|
---
|
||||||
title: Inbounds & Protocols
|
title: Inbounds & Protocols
|
||||||
description: Create inbounds in 3x-ui — protocols, transports, traffic reset and expiry, and fallbacks that serve multiple protocols on one port.
|
description: Create inbounds in L-UI — protocols, transports, traffic reset and expiry, and fallbacks that serve multiple protocols on one port.
|
||||||
icon: ArrowDownToLine
|
icon: ArrowDownToLine
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -75,7 +75,7 @@ The inbound editor accepts these protocols:
|
|||||||
|
|
||||||
Fallbacks let a single TLS port (e.g. `443`) serve more than one protocol — for
|
Fallbacks let a single TLS port (e.g. `443`) serve more than one protocol — for
|
||||||
example VLESS **and** Trojan — by routing unmatched handshakes to a child
|
example VLESS **and** Trojan — by routing unmatched handshakes to a child
|
||||||
inbound. In 3x-ui, fallbacks are managed in the panel (a master inbound's
|
inbound. In L-UI, fallbacks are managed in the panel (a master inbound's
|
||||||
**Fallbacks** list) rather than hand-written into JSON.
|
**Fallbacks** list) rather than hand-written into JSON.
|
||||||
|
|
||||||
Fallbacks are available only when the master inbound is:
|
Fallbacks are available only when the master inbound is:
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
---
|
---
|
||||||
title: Panel Settings
|
title: Panel Settings
|
||||||
description: Every 3x-ui panel setting — web server, TLS, display, security, and notifications — with defaults from the source.
|
description: Every L-UI panel setting — web server, TLS, display, security, and notifications — with defaults from the source.
|
||||||
icon: SlidersHorizontal
|
icon: SlidersHorizontal
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -14,7 +14,7 @@ browser in full.
|
|||||||
|
|
||||||
| Setting | Default | Meaning |
|
| Setting | Default | Meaning |
|
||||||
| ------------------- | ----------------------- | ----------------------------------------------------------------------- |
|
| ------------------- | ----------------------- | ----------------------------------------------------------------------- |
|
||||||
| `webPort` | `2053` | Panel port (1–65535). The `XUI_PORT` env var overrides it at runtime. |
|
| `webPort` | `2053` | Panel port (1–65535). The `LUI_PORT` env var overrides it at runtime. |
|
||||||
| `webListen` | _(all interfaces)_ | Bind the panel to a specific IP. |
|
| `webListen` | _(all interfaces)_ | Bind the panel to a specific IP. |
|
||||||
| `webBasePath` | `/` | URL path the panel is served under (always normalized to `/…/`). |
|
| `webBasePath` | `/` | URL path the panel is served under (always normalized to `/…/`). |
|
||||||
| `webCertFile` / `webKeyFile` | _(none)_ | TLS certificate + key. When both are set, the panel serves **HTTPS**. |
|
| `webCertFile` / `webKeyFile` | _(none)_ | TLS certificate + key. When both are set, the panel serves **HTTPS**. |
|
||||||
@@ -24,12 +24,12 @@ browser in full.
|
|||||||
|
|
||||||
After changing the port or base path, the panel URL becomes
|
After changing the port or base path, the panel URL becomes
|
||||||
`http(s)://<server>:<port><web-base-path>`. You can preset the base path on first
|
`http(s)://<server>:<port><web-base-path>`. You can preset the base path on first
|
||||||
launch with [`XUI_INIT_WEB_BASE_PATH`](/docs/reference/env-vars).
|
launch with [`LUI_INIT_WEB_BASE_PATH`](/docs/reference/env-vars).
|
||||||
|
|
||||||
### TLS
|
### TLS
|
||||||
|
|
||||||
Serving the panel over HTTPS protects your credentials in transit. Either set
|
Serving the panel over HTTPS protects your credentials in transit. Either set
|
||||||
`webCertFile` + `webKeyFile` — the [`x-ui` SSL menu](/docs/config/ssl-certificates)
|
`webCertFile` + `webKeyFile` — the [`l-ui` SSL menu](/docs/config/ssl-certificates)
|
||||||
can obtain a Let's Encrypt certificate for you — or terminate TLS at a
|
can obtain a Let's Encrypt certificate for you — or terminate TLS at a
|
||||||
[reverse proxy](/docs/operations/reverse-proxy).
|
[reverse proxy](/docs/operations/reverse-proxy).
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
---
|
---
|
||||||
title: REALITY
|
title: REALITY
|
||||||
description: Set up a VLESS + REALITY inbound with XTLS-Vision in 3x-ui — keys, short IDs, SNI, fingerprints, and common pitfalls.
|
description: Set up a VLESS + REALITY inbound with XTLS-Vision in L-UI — keys, short IDs, SNI, fingerprints, and common pitfalls.
|
||||||
icon: ShieldCheck
|
icon: ShieldCheck
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -15,7 +15,7 @@ REALITY is used with **VLESS** (and Trojan). The recommended flow is
|
|||||||
|
|
||||||
## Key settings
|
## Key settings
|
||||||
|
|
||||||
When you choose **REALITY** as the security mode on a VLESS inbound, 3x-ui
|
When you choose **REALITY** as the security mode on a VLESS inbound, L-UI
|
||||||
exposes these fields:
|
exposes these fields:
|
||||||
|
|
||||||
| Field | What it is |
|
| Field | What it is |
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
---
|
---
|
||||||
title: Share Links
|
title: Share Links
|
||||||
description: 3x-ui share-link formats (vless, vmess, trojan, ss, hysteria2, mtproto), the remark template variables, and an in-browser link inspector.
|
description: L-UI share-link formats (vless, vmess, trojan, ss, hysteria2, mtproto), the remark template variables, and an in-browser link inspector.
|
||||||
icon: Link
|
icon: Link
|
||||||
---
|
---
|
||||||
|
|
||||||
3x-ui generates a **share link** (and QR code) for each client. Client apps such
|
L-UI generates a **share link** (and QR code) for each client. Client apps such
|
||||||
as v2rayNG, Hiddify, and Mihomo import these links to configure themselves.
|
as v2rayNG, Hiddify, and Mihomo import these links to configure themselves.
|
||||||
|
|
||||||
## Link formats
|
## Link formats
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
---
|
---
|
||||||
title: SSL Certificates
|
title: SSL Certificates
|
||||||
description: Get and renew TLS certificates for the 3x-ui panel and inbounds — with the x-ui ACME menu (domain or bare IP), a Cloudflare DNS-01 wildcard, or manual Certbot.
|
description: Get and renew TLS certificates for the L-UI panel and inbounds — with the l-ui ACME menu (domain or bare IP), a Cloudflare DNS-01 wildcard, or manual Certbot.
|
||||||
icon: ShieldCheck
|
icon: ShieldCheck
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -8,7 +8,7 @@ A TLS certificate lets you serve the **panel** over HTTPS (so your login and API
|
|||||||
traffic are encrypted) and terminate TLS on **inbounds** (VLESS-TLS, Trojan,
|
traffic are encrypted) and terminate TLS on **inbounds** (VLESS-TLS, Trojan,
|
||||||
Shadowsocks-TLS, and friends). There are three ways to obtain one:
|
Shadowsocks-TLS, and friends). There are three ways to obtain one:
|
||||||
|
|
||||||
- **The `x-ui` menu** — built-in [ACME](https://en.wikipedia.org/wiki/Automatic_Certificate_Management_Environment)
|
- **The `l-ui` menu** — built-in [ACME](https://en.wikipedia.org/wiki/Automatic_Certificate_Management_Environment)
|
||||||
client. Easiest for a single domain or a bare IP.
|
client. Easiest for a single domain or a bare IP.
|
||||||
- **Cloudflare DNS-01** — also from the menu; needed for **wildcard** certs or
|
- **Cloudflare DNS-01** — also from the menu; needed for **wildcard** certs or
|
||||||
when port 80 is blocked / the server sits behind Cloudflare's proxy.
|
when port 80 is blocked / the server sits behind Cloudflare's proxy.
|
||||||
@@ -22,9 +22,9 @@ Shadowsocks-TLS, and friends). There are three ways to obtain one:
|
|||||||
inbounds.
|
inbounds.
|
||||||
</Callout>
|
</Callout>
|
||||||
|
|
||||||
## The `x-ui` SSL menu (Let's Encrypt)
|
## The `l-ui` SSL menu (Let's Encrypt)
|
||||||
|
|
||||||
Run `x-ui` and choose **`20` — SSL Certificate Management**. It drives
|
Run `l-ui` and choose **`20` — SSL Certificate Management**. It drives
|
||||||
[acme.sh](https://github.com/acmesh-official/acme.sh) and offers:
|
[acme.sh](https://github.com/acmesh-official/acme.sh) and offers:
|
||||||
|
|
||||||
| Option | What it does |
|
| Option | What it does |
|
||||||
@@ -58,7 +58,7 @@ use. Stop anything bound to it for the duration, and allow it through the
|
|||||||
<Step>
|
<Step>
|
||||||
### Run the issuer
|
### Run the issuer
|
||||||
|
|
||||||
`x-ui` → `20` → **Get SSL (Domain)**, then enter the domain. acme.sh requests
|
`l-ui` → `20` → **Get SSL (Domain)**, then enter the domain. acme.sh requests
|
||||||
the certificate and saves it under `/root/cert/<domain>/` as `fullchain.pem`
|
the certificate and saves it under `/root/cert/<domain>/` as `fullchain.pem`
|
||||||
(the certificate chain) and `privkey.pem` (the private key).
|
(the certificate chain) and `privkey.pem` (the private key).
|
||||||
</Step>
|
</Step>
|
||||||
@@ -105,7 +105,7 @@ it. Copy the token — it's shown only once.
|
|||||||
<Step>
|
<Step>
|
||||||
### Run the Cloudflare issuer
|
### Run the Cloudflare issuer
|
||||||
|
|
||||||
`x-ui` → **`21` — Cloudflare SSL Certificate**. When asked, choose **`t`** for an
|
`l-ui` → **`21` — Cloudflare SSL Certificate**. When asked, choose **`t`** for an
|
||||||
API token (the default) or **`g`** for the Global API Key, then enter your
|
API token (the default) or **`g`** for the Global API Key, then enter your
|
||||||
domain (and, for the Global API Key, your account email and key). acme.sh creates
|
domain (and, for the Global API Key, your account email and key). acme.sh creates
|
||||||
the TXT record, validates, and cleans it up.
|
the TXT record, validates, and cleans it up.
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
---
|
---
|
||||||
title: Subscription
|
title: Subscription
|
||||||
description: Run the 3x-ui subscription server — base64/JSON/Clash formats, ports and paths, TLS, response headers, and custom templates.
|
description: Run the L-UI subscription server — base64/JSON/Clash formats, ports and paths, TLS, response headers, and custom templates.
|
||||||
icon: Rss
|
icon: Rss
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -58,7 +58,7 @@ page instead of the raw body.
|
|||||||
The **Base64** body is just the newline-joined share links, standard-base64
|
The **Base64** body is just the newline-joined share links, standard-base64
|
||||||
encoded (toggle with `subEncrypt`). The **JSON** body wraps each client in a
|
encoded (toggle with `subEncrypt`). The **JSON** body wraps each client in a
|
||||||
complete Xray client config — a fixed skeleton (local mixed/HTTP inbounds, DNS,
|
complete Xray client config — a fixed skeleton (local mixed/HTTP inbounds, DNS,
|
||||||
routing, policy) plus a `proxy` outbound pointing at the inbound. 3x-ui emits a
|
routing, policy) plus a `proxy` outbound pointing at the inbound. L-UI emits a
|
||||||
**single config object for one client and an array for several**, uses the flat
|
**single config object for one client and an array for several**, uses the flat
|
||||||
outbound `settings` form (`address`/`port`/`id`, `level: 8`), and strips
|
outbound `settings` form (`address`/`port`/`id`, `level: 8`), and strips
|
||||||
`sockopt` from `streamSettings`.
|
`sockopt` from `streamSettings`.
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
---
|
---
|
||||||
title: Transports & Security
|
title: Transports & Security
|
||||||
description: Every transport 3x-ui exposes — TCP, mKCP, WebSocket, gRPC, HTTPUpgrade, XHTTP, Hysteria — with their settings, plus FinalMask obfuscation, sockopt, TLS/REALITY, XTLS-Vision, and VLESS encryption.
|
description: Every transport L-UI exposes — TCP, mKCP, WebSocket, gRPC, HTTPUpgrade, XHTTP, Hysteria — with their settings, plus FinalMask obfuscation, sockopt, TLS/REALITY, XTLS-Vision, and VLESS encryption.
|
||||||
icon: Network
|
icon: Network
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
---
|
---
|
||||||
title: First Login
|
title: First Login
|
||||||
description: Find your generated 3x-ui credentials, reach the panel, enable two-factor auth, and harden it before exposing anything.
|
description: Find your generated L-UI credentials, reach the panel, enable two-factor auth, and harden it before exposing anything.
|
||||||
icon: KeyRound
|
icon: KeyRound
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -24,25 +24,25 @@ path, so check your actual values.
|
|||||||
A script install prints a credential summary when it finishes and also writes it
|
A script install prints a credential summary when it finishes and also writes it
|
||||||
to a root-only file:
|
to a root-only file:
|
||||||
|
|
||||||
```bash title="/etc/x-ui/install-result.env (mode 600)"
|
```bash title="/etc/l-ui/install-result.env (mode 600)"
|
||||||
XUI_USERNAME=...
|
LUI_USERNAME=...
|
||||||
XUI_PASSWORD=...
|
LUI_PASSWORD=...
|
||||||
XUI_PANEL_PORT=...
|
LUI_PANEL_PORT=...
|
||||||
XUI_WEB_BASE_PATH=...
|
LUI_WEB_BASE_PATH=...
|
||||||
XUI_ACCESS_URL=...
|
LUI_ACCESS_URL=...
|
||||||
XUI_API_TOKEN=...
|
LUI_API_TOKEN=...
|
||||||
XUI_DB_TYPE=sqlite
|
LUI_DB_TYPE=sqlite
|
||||||
```
|
```
|
||||||
|
|
||||||
If you missed them, use the management tools:
|
If you missed them, use the management tools:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
x-ui # menu → 11 (View Current Settings)
|
l-ui # menu → 11 (View Current Settings)
|
||||||
x-ui settings # or the one-shot form
|
l-ui settings # or the one-shot form
|
||||||
```
|
```
|
||||||
|
|
||||||
For **Docker**, read the generated credentials from the container logs, or run
|
For **Docker**, read the generated credentials from the container logs, or run
|
||||||
`docker exec -it <container> x-ui setting -show`.
|
`docker exec -it <container> l-ui setting -show`.
|
||||||
|
|
||||||
<Callout type="warn">
|
<Callout type="warn">
|
||||||
If your panel still uses the default `admin` / `admin` (the panel warns when it
|
If your panel still uses the default `admin` / `admin` (the panel warns when it
|
||||||
@@ -53,7 +53,7 @@ For **Docker**, read the generated credentials from the container logs, or run
|
|||||||
|
|
||||||
A non-default port and a long, random **web base path** make the panel much
|
A non-default port and a long, random **web base path** make the panel much
|
||||||
harder to find. Change them from **Panel Settings** in the UI, or from the
|
harder to find. Change them from **Panel Settings** in the UI, or from the
|
||||||
`x-ui` menu:
|
`l-ui` menu:
|
||||||
|
|
||||||
- **7 — Reset Username & Password** (optionally disabling 2FA at the same time)
|
- **7 — Reset Username & Password** (optionally disabling 2FA at the same time)
|
||||||
- **8 — Reset Web Base Path** (randomizes it)
|
- **8 — Reset Web Base Path** (randomizes it)
|
||||||
@@ -64,11 +64,11 @@ two-factor auth was on, disables it.
|
|||||||
|
|
||||||
## Two-factor authentication (2FA)
|
## Two-factor authentication (2FA)
|
||||||
|
|
||||||
3x-ui supports TOTP two-factor auth (compatible with Google Authenticator, Aegis,
|
L-UI supports TOTP two-factor auth (compatible with Google Authenticator, Aegis,
|
||||||
etc.). Enable it in **Panel Settings** — once enabled, the login page asks for a
|
etc.). Enable it in **Panel Settings** — once enabled, the login page asks for a
|
||||||
6-digit code in addition to your password, and turning it on forces everyone to
|
6-digit code in addition to your password, and turning it on forces everyone to
|
||||||
log in again. You can disable it from the menu's **Reset Username & Password**
|
log in again. You can disable it from the menu's **Reset Username & Password**
|
||||||
step or with `x-ui setting -resetTwoFactor`.
|
step or with `l-ui setting -resetTwoFactor`.
|
||||||
|
|
||||||
## Built-in login protection
|
## Built-in login protection
|
||||||
|
|
||||||
@@ -105,7 +105,7 @@ Turn on 2FA so a leaked password alone can't grant access.
|
|||||||
<Step>
|
<Step>
|
||||||
### Put the panel behind TLS
|
### Put the panel behind TLS
|
||||||
|
|
||||||
Use a valid certificate (via the `x-ui` menu's SSL management, or a reverse
|
Use a valid certificate (via the `l-ui` menu's SSL management, or a reverse
|
||||||
proxy) so the panel is only reachable over HTTPS.
|
proxy) so the panel is only reachable over HTTPS.
|
||||||
</Step>
|
</Step>
|
||||||
|
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
---
|
---
|
||||||
title: Meet 3x-ui
|
title: Meet L-UI
|
||||||
description: A web panel for Xray-core — manage inbounds, protocols, clients, and subscriptions from your browser instead of editing JSON by hand.
|
description: A web panel for Xray-core — manage inbounds, protocols, clients, and subscriptions from your browser instead of editing JSON by hand.
|
||||||
icon: Info
|
icon: Info
|
||||||
---
|
---
|
||||||
|
|
||||||
**3x-ui** is a web control panel that sits on top of
|
**L-UI** is a web control panel that sits on top of
|
||||||
[Xray-core](https://github.com/XTLS/Xray-core), the proxy engine that actually
|
[Xray-core](https://github.com/XTLS/Xray-core), the proxy engine that actually
|
||||||
moves your traffic. Instead of writing and reloading Xray's JSON configuration
|
moves your traffic. Instead of writing and reloading Xray's JSON configuration
|
||||||
by hand, you manage everything — inbounds, protocols, clients, certificates,
|
by hand, you manage everything — inbounds, protocols, clients, certificates,
|
||||||
@@ -15,7 +15,7 @@ subscriptions — from a browser dashboard.
|
|||||||
<Mermaid
|
<Mermaid
|
||||||
chart={`
|
chart={`
|
||||||
flowchart LR
|
flowchart LR
|
||||||
Admin["Admin browser"] -->|HTTPS panel| Panel["3x-ui panel"]
|
Admin["Admin browser"] -->|HTTPS panel| Panel["L-UI panel"]
|
||||||
Panel -->|writes config, reloads| Xray["Xray-core"]
|
Panel -->|writes config, reloads| Xray["Xray-core"]
|
||||||
Panel --- DB[("SQLite or PostgreSQL")]
|
Panel --- DB[("SQLite or PostgreSQL")]
|
||||||
Clients["Client apps"] -->|VLESS / VMess / Trojan / ...| Xray
|
Clients["Client apps"] -->|VLESS / VMess / Trojan / ...| Xray
|
||||||
@@ -52,18 +52,18 @@ flowchart LR
|
|||||||
| Database | SQLite (default) or PostgreSQL |
|
| Database | SQLite (default) or PostgreSQL |
|
||||||
| Proxy engine | Xray-core (bundled and managed by the panel) |
|
| Proxy engine | Xray-core (bundled and managed by the panel) |
|
||||||
|
|
||||||
The default SQLite database lives at `/etc/x-ui/x-ui.db`, and the panel listens
|
The default SQLite database lives at `/etc/l-ui/l-ui.db`, and the panel listens
|
||||||
on port **2053** by default. Both are configurable — see
|
on port **2053** by default. Both are configurable — see
|
||||||
[First login](/docs/guide/first-login) and the environment variable reference.
|
[First login](/docs/guide/first-login) and the environment variable reference.
|
||||||
|
|
||||||
## Who it's for
|
## Who it's for
|
||||||
|
|
||||||
3x-ui is aimed at anyone running their own Xray server: from a single personal
|
L-UI is aimed at anyone running their own Xray server: from a single personal
|
||||||
VPS to operators managing many nodes and clients. If you want the power of
|
VPS to operators managing many nodes and clients. If you want the power of
|
||||||
Xray-core without living in JSON config files, this is for you.
|
Xray-core without living in JSON config files, this is for you.
|
||||||
|
|
||||||
<Callout type="info">
|
<Callout type="info">
|
||||||
3x-ui is an enhanced fork of the original X-UI project, adding broader protocol
|
L-UI is an enhanced fork of the original X-UI project, adding broader protocol
|
||||||
support, improved stability, per-client traffic accounting, multi-node
|
support, improved stability, per-client traffic accounting, multi-node
|
||||||
management, and many quality-of-life features.
|
management, and many quality-of-life features.
|
||||||
</Callout>
|
</Callout>
|
||||||
|
|||||||
@@ -1,47 +1,43 @@
|
|||||||
---
|
---
|
||||||
title: Installation
|
title: Installation
|
||||||
description: Install 3x-ui via the official script (stable, pinned, or dev-latest), unattended/cloud-init, or Docker — and choose SQLite or PostgreSQL.
|
description: Install L-UI via the official script (panel, node agent, or pinned), unattended/cloud-init, or Docker — and choose SQLite or PostgreSQL.
|
||||||
icon: Download
|
icon: Download
|
||||||
---
|
---
|
||||||
|
|
||||||
3x-ui runs on a wide range of Linux distributions — Ubuntu, Debian, Armbian,
|
L-UI runs on a wide range of Linux distributions — Ubuntu, Debian, Armbian,
|
||||||
Fedora, CentOS, RHEL, AlmaLinux, Rocky Linux, Oracle Linux, Amazon Linux,
|
Fedora, CentOS, RHEL, AlmaLinux, Rocky Linux, Oracle Linux, Amazon Linux,
|
||||||
Virtuozzo, Arch, Manjaro, openSUSE (Tumbleweed/Leap), Alpine — and Windows,
|
Virtuozzo, Arch, Manjaro, openSUSE (Tumbleweed/Leap), Alpine — and Windows,
|
||||||
across `amd64`, `386`, `arm64`, `armv7`, `armv6`, `armv5`, and `s390x`.
|
across `amd64` and `arm64`.
|
||||||
|
|
||||||
<Callout type="warn">
|
<Callout type="warn">
|
||||||
Run the script installer as **root** (or with `sudo`). It installs a service,
|
Run the script installer as **root** (or with `sudo`). One-click scripts support `amd64`/`arm64` only.
|
||||||
sets up the `x-ui` management command, and enables the panel on boot.
|
|
||||||
</Callout>
|
</Callout>
|
||||||
|
|
||||||
<Tabs items={['Script', 'Docker', 'Manual']}>
|
<Tabs items={['Script', 'Docker', 'Manual']}>
|
||||||
|
|
||||||
<Tab value="Script">
|
<Tab value="Script">
|
||||||
|
|
||||||
The official script is the recommended path. During installation it generates a
|
The official script is the recommended path. Panel one-click install:
|
||||||
**random** username, password, and access (web base) path, sets up the service,
|
|
||||||
and installs the `x-ui` management command.
|
|
||||||
|
|
||||||
```bash title="latest stable"
|
```bash title="panel"
|
||||||
bash <(curl -Ls https://raw.githubusercontent.com/mhsanaei/3x-ui/master/install.sh)
|
bash <(curl -Ls https://git.881218.xyz/rogue/l-ui/raw/branch/main/install-master.sh)
|
||||||
```
|
```
|
||||||
|
|
||||||
Install a **specific version** by appending its tag:
|
It downloads the panel binary, xray, and geo files from this repo's Gitea Releases and starts the panel (default port 2053). Log in with the default `admin` / `admin` and change the password immediately.
|
||||||
|
|
||||||
|
Node agent install: create the node in the panel first — the panel generates the install command with the registration token; run it as root on the node, for example:
|
||||||
|
|
||||||
|
```bash title="node agent"
|
||||||
|
bash <(curl -fL https://git.881218.xyz/rogue/l-ui/raw/branch/main/install-agent.sh) --master http://MASTER:2053 --token <token> --name <node-name>
|
||||||
|
```
|
||||||
|
|
||||||
|
Install a specific panel version: fetch the script at that tag (the script's default download URL is that version), for example:
|
||||||
|
|
||||||
```bash title="pinned version"
|
```bash title="pinned version"
|
||||||
bash <(curl -Ls https://raw.githubusercontent.com/mhsanaei/3x-ui/master/install.sh) v3.4.0
|
bash <(curl -Ls https://git.881218.xyz/rogue/l-ui/raw/tag/V2.7.5/install-master.sh)
|
||||||
```
|
```
|
||||||
|
|
||||||
Install the rolling **dev** build (the latest per-commit pre-release from `main`
|
There is no dev-channel one-click install; the main-branch script tracks the latest release. When it finishes, continue to [First login](/docs/guide/first-login).
|
||||||
— not a stable release) by passing `dev-latest`:
|
|
||||||
|
|
||||||
```bash title="rolling dev build"
|
|
||||||
bash <(curl -Ls https://raw.githubusercontent.com/mhsanaei/3x-ui/master/install.sh) dev-latest
|
|
||||||
```
|
|
||||||
|
|
||||||
When it finishes, note the printed login details and run `x-ui` to open the
|
|
||||||
[management menu](/docs/guide/update-uninstall#the-x-ui-management-menu), then
|
|
||||||
continue to [First login](/docs/guide/first-login).
|
|
||||||
|
|
||||||
</Tab>
|
</Tab>
|
||||||
|
|
||||||
@@ -54,41 +50,25 @@ The default Compose setup uses SQLite. Clone the repo (or copy its
|
|||||||
docker compose up -d
|
docker compose up -d
|
||||||
```
|
```
|
||||||
|
|
||||||
To run with the bundled **PostgreSQL** service, uncomment the two `XUI_DB_*`
|
To run with the bundled **PostgreSQL** service, uncomment the two `LUI_DB_*`
|
||||||
lines in `docker-compose.yml` and start with the profile:
|
lines in `docker-compose.yml` and start with the profile:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
docker compose --profile postgres up -d
|
docker compose --profile postgres up -d
|
||||||
```
|
```
|
||||||
|
|
||||||
Prefer the prebuilt image? It's published to the GitHub Container Registry. The
|
No prebuilt image is published for this fork — build locally as above. The locally built image also bundles Fail2ban (for [IP limits](/docs/operations/security)); its bans work through `iptables` and therefore need `NET_ADMIN` (`NET_RAW` for IPv6) — the Compose file already includes both; otherwise bans are only logged, never applied.
|
||||||
image bundles Fail2ban (for [IP limits](/docs/operations/security)), which bans
|
|
||||||
with `iptables` and therefore needs `NET_ADMIN` (and `NET_RAW` for IPv6) —
|
|
||||||
otherwise bans are logged but never applied:
|
|
||||||
|
|
||||||
```bash title="docker run"
|
The `db/` volume holds the SQLite database (`/etc/l-ui/l-ui.db`) and `cert/`
|
||||||
docker run -d \
|
|
||||||
--cap-add=NET_ADMIN \
|
|
||||||
--cap-add=NET_RAW \
|
|
||||||
-e XUI_ENABLE_FAIL2BAN=true \
|
|
||||||
-v $PWD/db/:/etc/x-ui/ \
|
|
||||||
-v $PWD/cert/:/root/cert/ \
|
|
||||||
--network=host \
|
|
||||||
--restart=unless-stopped \
|
|
||||||
--name 3x-ui \
|
|
||||||
ghcr.io/mhsanaei/3x-ui:latest
|
|
||||||
```
|
|
||||||
|
|
||||||
The `db/` volume holds the SQLite database (`/etc/x-ui/x-ui.db`) and `cert/`
|
|
||||||
holds TLS certificates, so your data survives upgrades.
|
holds TLS certificates, so your data survives upgrades.
|
||||||
|
|
||||||
</Tab>
|
</Tab>
|
||||||
|
|
||||||
<Tab value="Manual">
|
<Tab value="Manual">
|
||||||
|
|
||||||
For advanced users, download a release archive for your architecture from the
|
For advanced users, download a release binary for your architecture from the
|
||||||
[releases page](https://github.com/MHSanaei/3x-ui/releases), extract it, and run
|
[releases page](https://git.881218.xyz/rogue/l-ui/releases) (`l-ui-linux-amd64` or `l-ui-linux-arm64`),
|
||||||
the binary as a systemd service. The install script automates exactly these
|
place it at `/usr/local/l-ui/l-ui`, and run it as a systemd service following the repo root README. The install script automates exactly these
|
||||||
steps, so it's preferred unless you have a specific reason to install by hand.
|
steps, so it's preferred unless you have a specific reason to install by hand.
|
||||||
|
|
||||||
</Tab>
|
</Tab>
|
||||||
@@ -105,7 +85,7 @@ Tailor the command to your setup:
|
|||||||
|
|
||||||
You pick the storage backend at install time:
|
You pick the storage backend at install time:
|
||||||
|
|
||||||
- **SQLite** (default) — a single file at `/etc/x-ui/x-ui.db`. Zero setup.
|
- **SQLite** (default) — a single file at `/etc/l-ui/l-ui.db`. Zero setup.
|
||||||
- **PostgreSQL** — for high client counts or multi-node setups. The installer
|
- **PostgreSQL** — for high client counts or multi-node setups. The installer
|
||||||
can install it locally or use a DSN you provide.
|
can install it locally or use a DSN you provide.
|
||||||
|
|
||||||
@@ -114,17 +94,8 @@ migration.
|
|||||||
|
|
||||||
## Unattended / cloud-init
|
## Unattended / cloud-init
|
||||||
|
|
||||||
The installer also runs **non-interactively** for automation. Set
|
The install script itself takes no interactive input, so it can be used directly for automation. The repo's [`deploy/cloud-init/`](https://git.881218.xyz/rogue/l-ui/src/branch/main/deploy/cloud-init)
|
||||||
`XUI_NONINTERACTIVE=1` (or run with no TTY) and it installs end-to-end with zero
|
provides ready-made **cloud-init** user-data for unattended installs on any
|
||||||
prompts, generating random credentials and writing them to
|
|
||||||
`/etc/x-ui/install-result.env`:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
XUI_NONINTERACTIVE=1 bash <(curl -Ls https://raw.githubusercontent.com/mhsanaei/3x-ui/master/install.sh)
|
|
||||||
```
|
|
||||||
|
|
||||||
The repo's [`deploy/`](https://github.com/MHSanaei/3x-ui/tree/main/deploy)
|
|
||||||
directory has ready-made **cloud-init** user-data for unattended installs on any
|
|
||||||
cloud (Hetzner, AWS, DigitalOcean, Vultr, GCP, Azure, Oracle).
|
cloud (Hetzner, AWS, DigitalOcean, Vultr, GCP, Azure, Oracle).
|
||||||
|
|
||||||
## Next steps
|
## Next steps
|
||||||
@@ -138,7 +109,7 @@ cloud (Hetzner, AWS, DigitalOcean, Vultr, GCP, Azure, Oracle).
|
|||||||
<Card
|
<Card
|
||||||
title="Update & uninstall"
|
title="Update & uninstall"
|
||||||
href="/docs/guide/update-uninstall"
|
href="/docs/guide/update-uninstall"
|
||||||
description="The x-ui menu, updates, and removal."
|
description="The l-ui menu, updates, and removal."
|
||||||
/>
|
/>
|
||||||
<Card
|
<Card
|
||||||
title="REALITY"
|
title="REALITY"
|
||||||
|
|||||||
@@ -1,17 +1,17 @@
|
|||||||
---
|
---
|
||||||
title: Update & Uninstall
|
title: Update & Uninstall
|
||||||
description: Manage 3x-ui with the x-ui menu and CLI — update (stable, dev, or legacy), change settings, and uninstall cleanly.
|
description: Manage L-UI with the l-ui menu and CLI — update (stable, dev, or legacy), change settings, and uninstall cleanly.
|
||||||
icon: RefreshCw
|
icon: RefreshCw
|
||||||
---
|
---
|
||||||
|
|
||||||
After a script install, the `x-ui` command is your control center. Run it with
|
After a script install, the `l-ui` command is your control center. Run it with
|
||||||
no arguments for the interactive menu, or pass a subcommand for a one-shot action.
|
no arguments for the interactive menu, or pass a subcommand for a one-shot action.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
x-ui
|
l-ui
|
||||||
```
|
```
|
||||||
|
|
||||||
## The `x-ui` management menu
|
## The `l-ui` management menu
|
||||||
|
|
||||||
The menu (items `0`–`28`) shows the panel/Xray status at the top, then:
|
The menu (items `0`–`28`) shows the panel/Xray status at the top, then:
|
||||||
|
|
||||||
@@ -20,9 +20,9 @@ The menu (items `0`–`28`) shows the panel/Xray status at the top, then:
|
|||||||
| 1 | Install | (Re)install from the remote script |
|
| 1 | Install | (Re)install from the remote script |
|
||||||
| 2 | Update | Update to the latest **stable** release |
|
| 2 | Update | Update to the latest **stable** release |
|
||||||
| 3 | Update to Dev Channel (latest commit) | Update to the rolling `dev-latest` build |
|
| 3 | Update to Dev Channel (latest commit) | Update to the rolling `dev-latest` build |
|
||||||
| 4 | Update Menu | Update just the `x-ui` menu script |
|
| 4 | Update Menu | Update just the `l-ui` menu script |
|
||||||
| 5 | Legacy Version | Install a specific older version (prompts for a tag) |
|
| 5 | Legacy Version | Install a specific older version (prompts for a tag) |
|
||||||
| 6 | Uninstall | Remove 3x-ui (see below) |
|
| 6 | Uninstall | Remove L-UI (see below) |
|
||||||
| 7 | Reset Username & Password | Set new credentials; optionally disable 2FA |
|
| 7 | Reset Username & Password | Set new credentials; optionally disable 2FA |
|
||||||
| 8 | Reset Web Base Path | Randomize the web base path |
|
| 8 | Reset Web Base Path | Randomize the web base path |
|
||||||
| 9 | Reset Settings | Reset panel settings (your account is preserved) |
|
| 9 | Reset Settings | Reset panel settings (your account is preserved) |
|
||||||
@@ -51,29 +51,29 @@ Some of these have their own pages: [SSL certificates](/docs/config/ssl-certific
|
|||||||
|
|
||||||
## CLI subcommands
|
## CLI subcommands
|
||||||
|
|
||||||
For scripts and quick actions, `x-ui` also takes a subcommand directly:
|
For scripts and quick actions, `l-ui` also takes a subcommand directly:
|
||||||
|
|
||||||
| Command | Action |
|
| Command | Action |
|
||||||
| -------------------------- | --------------------------------------------------- |
|
| -------------------------- | --------------------------------------------------- |
|
||||||
| `x-ui start` / `stop` / `restart` | Control the service |
|
| `l-ui start` / `stop` / `restart` | Control the service |
|
||||||
| `x-ui restart-xray` | Reload only Xray-core |
|
| `l-ui restart-xray` | Reload only Xray-core |
|
||||||
| `x-ui status` | Show status |
|
| `l-ui status` | Show status |
|
||||||
| `x-ui settings` | Show current settings |
|
| `l-ui settings` | Show current settings |
|
||||||
| `x-ui enable` / `disable` | Toggle autostart on boot |
|
| `l-ui enable` / `disable` | Toggle autostart on boot |
|
||||||
| `x-ui log` | Tail the debug log |
|
| `l-ui log` | Tail the debug log |
|
||||||
| `x-ui banlog` | Show Fail2ban ban log |
|
| `l-ui banlog` | Show Fail2ban ban log |
|
||||||
| `x-ui update` | Update to the latest stable release |
|
| `l-ui update` | Update to the latest stable release |
|
||||||
| `x-ui update-dev` | Update to the rolling `dev-latest` build |
|
| `l-ui update-dev` | Update to the rolling `dev-latest` build |
|
||||||
| `x-ui legacy` | Install a specific older version (prompts) |
|
| `l-ui legacy` | Install a specific older version (prompts) |
|
||||||
| `x-ui update-all-geofiles` | Update all geo files, restart if changed |
|
| `l-ui update-all-geofiles` | Update all geo files, restart if changed |
|
||||||
| `x-ui migrate-db --dsn …` | Migrate SQLite → PostgreSQL (see [Database](/docs/reference/database)) |
|
| `l-ui migrate-db --dsn …` | Migrate SQLite → PostgreSQL (see [Database](/docs/reference/database)) |
|
||||||
| `x-ui install` / `uninstall` | Install / uninstall |
|
| `l-ui install` / `uninstall` | Install / uninstall |
|
||||||
|
|
||||||
## Updating
|
## Updating
|
||||||
|
|
||||||
- **Stable:** menu option **2** or `x-ui update`. Re-running the install script
|
- **Stable:** menu option **2** or `l-ui update`. Re-running the install script
|
||||||
also updates in place.
|
also updates in place.
|
||||||
- **Dev channel:** menu option **3** or `x-ui update-dev` — the rolling
|
- **Dev channel:** menu option **3** or `l-ui update-dev` — the rolling
|
||||||
`dev-latest` per-commit build (not a stable release).
|
`dev-latest` per-commit build (not a stable release).
|
||||||
- **A specific older version:** menu option **5** (Legacy Version).
|
- **A specific older version:** menu option **5** (Legacy Version).
|
||||||
|
|
||||||
@@ -83,17 +83,17 @@ Updating preserves your database and settings. Take a
|
|||||||
<Callout type="info">
|
<Callout type="info">
|
||||||
Docker users update differently — pull the new image and recreate the
|
Docker users update differently — pull the new image and recreate the
|
||||||
container (`docker compose pull && docker compose up -d`) rather than using the
|
container (`docker compose pull && docker compose up -d`) rather than using the
|
||||||
`x-ui` update commands.
|
`l-ui` update commands.
|
||||||
</Callout>
|
</Callout>
|
||||||
|
|
||||||
## Uninstalling
|
## Uninstalling
|
||||||
|
|
||||||
Menu option **6** or `x-ui uninstall`. It stops and disables the service, removes
|
Menu option **6** or `l-ui uninstall`. It stops and disables the service, removes
|
||||||
the service unit, and deletes `/etc/x-ui/` and the install folder. If the panel
|
the service unit, and deletes `/etc/l-ui/` and the install folder. If the panel
|
||||||
used a locally-installed PostgreSQL, it offers to purge that too (a separate,
|
used a locally-installed PostgreSQL, it offers to purge that too (a separate,
|
||||||
irreversible confirmation).
|
irreversible confirmation).
|
||||||
|
|
||||||
<Callout type="warn">
|
<Callout type="warn">
|
||||||
Uninstalling removes the database (`/etc/x-ui/x-ui.db`) and your configuration.
|
Uninstalling removes the database (`/etc/l-ui/l-ui.db`) and your configuration.
|
||||||
[Back up](/docs/operations/backup-restore) first if you might need it.
|
[Back up](/docs/operations/backup-restore) first if you might need it.
|
||||||
</Callout>
|
</Callout>
|
||||||
|
|||||||
@@ -1,28 +1,28 @@
|
|||||||
---
|
---
|
||||||
title: Contributing
|
title: Contributing
|
||||||
description: How to contribute to 3x-ui and to translate this documentation.
|
description: How to contribute to L-UI and to translate this documentation.
|
||||||
icon: GitPullRequestArrow
|
icon: GitPullRequestArrow
|
||||||
---
|
---
|
||||||
|
|
||||||
3x-ui is community-driven. Contributions to the panel and to these docs are
|
L-UI is community-driven. Contributions to the panel and to these docs are
|
||||||
welcome.
|
welcome.
|
||||||
|
|
||||||
## Support the developer
|
## Support the developer
|
||||||
|
|
||||||
3x-ui is free and open source, built and maintained in the open. If it's useful
|
L-UI is free and open source, built and maintained in the open. If it's useful
|
||||||
to you, consider supporting continued development:
|
to you, consider supporting continued development:
|
||||||
|
|
||||||
- **Donate** at [donate.sanaei.dev](https://donate.sanaei.dev/) — the page shows
|
- **Donate** at [donate.sanaei.dev](https://donate.sanaei.dev/) — the page shows
|
||||||
current funding **goals and targets** you can help reach.
|
current funding **goals and targets** you can help reach.
|
||||||
- **Star** the [repository](https://github.com/MHSanaei/3x-ui) and share the
|
- **Star** the [repository](https://github.com/MHSanaei/L-UI) and share the
|
||||||
project.
|
project.
|
||||||
- **Join** the Telegram channel [@XrayUI](https://t.me/XrayUI) to follow news and
|
- **Join** the Telegram channel [@XrayUI](https://t.me/XrayUI) to follow news and
|
||||||
help others.
|
help others.
|
||||||
|
|
||||||
## Contribute to 3x-ui
|
## Contribute to L-UI
|
||||||
|
|
||||||
- Read the project's `CONTRIBUTING.md` in the
|
- Read the project's `CONTRIBUTING.md` in the
|
||||||
[repository](https://github.com/MHSanaei/3x-ui).
|
[repository](https://github.com/MHSanaei/L-UI).
|
||||||
- Open issues for bugs and feature requests with clear reproduction steps.
|
- Open issues for bugs and feature requests with clear reproduction steps.
|
||||||
- Use Conventional Commits and keep pull requests focused.
|
- Use Conventional Commits and keep pull requests focused.
|
||||||
|
|
||||||
|
|||||||
@@ -1,13 +1,13 @@
|
|||||||
---
|
---
|
||||||
title: FAQ
|
title: FAQ
|
||||||
description: Frequently asked questions about 3x-ui — licensing, supported systems, databases, and clients.
|
description: Frequently asked questions about L-UI — licensing, supported systems, databases, and clients.
|
||||||
icon: CircleQuestionMark
|
icon: CircleQuestionMark
|
||||||
---
|
---
|
||||||
|
|
||||||
## Is 3x-ui free and open source?
|
## Is L-UI free and open source?
|
||||||
|
|
||||||
Yes. 3x-ui is open source under the GPL-3.0 license. The source is on
|
Yes. L-UI is open source under the GPL-3.0 license. The source is on
|
||||||
[GitHub](https://github.com/MHSanaei/3x-ui).
|
[GitHub](https://github.com/MHSanaei/L-UI).
|
||||||
|
|
||||||
## What systems does it run on?
|
## What systems does it run on?
|
||||||
|
|
||||||
@@ -18,7 +18,7 @@ It also runs as a Docker container. See [Installation](/docs/guide/installation)
|
|||||||
## SQLite or PostgreSQL?
|
## SQLite or PostgreSQL?
|
||||||
|
|
||||||
SQLite is the default and is fine for most deployments. PostgreSQL is available
|
SQLite is the default and is fine for most deployments. PostgreSQL is available
|
||||||
for larger setups via `XUI_DB_TYPE=postgres` and `XUI_DB_DSN` — see the
|
for larger setups via `LUI_DB_TYPE=postgres` and `LUI_DB_DSN` — see the
|
||||||
[environment variables](/docs/reference/env-vars).
|
[environment variables](/docs/reference/env-vars).
|
||||||
|
|
||||||
## Which client apps work with it?
|
## Which client apps work with it?
|
||||||
@@ -27,9 +27,9 @@ Any Xray-compatible client — for example v2rayNG, Hiddify, and Clash/Mihomo.
|
|||||||
Import a client's share link or QR code, or use a
|
Import a client's share link or QR code, or use a
|
||||||
[subscription](/docs/config/subscription).
|
[subscription](/docs/config/subscription).
|
||||||
|
|
||||||
## How is 3x-ui different from x-ui?
|
## How is L-UI different from l-ui?
|
||||||
|
|
||||||
3x-ui is an enhanced fork of the original X-UI project. It adds broader protocol
|
L-UI is an enhanced fork of the original X-UI project. It adds broader protocol
|
||||||
support, improved stability, per-client traffic accounting, multi-node
|
support, improved stability, per-client traffic accounting, multi-node
|
||||||
management, a 13-language UI, and many quality-of-life features.
|
management, a 13-language UI, and many quality-of-life features.
|
||||||
|
|
||||||
@@ -37,11 +37,11 @@ management, a 13-language UI, and many quality-of-life features.
|
|||||||
|
|
||||||
Re-run the install script (it updates in place), or pull the new Docker image.
|
Re-run the install script (it updates in place), or pull the new Docker image.
|
||||||
See [Installation](/docs/guide/installation) and the
|
See [Installation](/docs/guide/installation) and the
|
||||||
[releases page](https://github.com/MHSanaei/3x-ui/releases).
|
[releases page](https://github.com/MHSanaei/L-UI/releases).
|
||||||
|
|
||||||
## Where can I get help?
|
## Where can I get help?
|
||||||
|
|
||||||
Join the official Telegram channel [@XrayUI](https://t.me/XrayUI) for
|
Join the official Telegram channel [@XrayUI](https://t.me/XrayUI) for
|
||||||
announcements and community support, or open an issue on
|
announcements and community support, or open an issue on
|
||||||
[GitHub](https://github.com/MHSanaei/3x-ui/issues). For common problems, start
|
[GitHub](https://github.com/MHSanaei/L-UI/issues). For common problems, start
|
||||||
with [Troubleshooting](/docs/help/troubleshooting).
|
with [Troubleshooting](/docs/help/troubleshooting).
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
---
|
---
|
||||||
title: Migration
|
title: Migration
|
||||||
description: Migrate to 3x-ui from x-ui, between servers, or between 3x-ui versions.
|
description: Migrate to L-UI from l-ui, between servers, or between L-UI versions.
|
||||||
icon: ArrowRightLeft
|
icon: ArrowRightLeft
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -13,12 +13,12 @@ Moving to a new server is a database move:
|
|||||||
<Step>
|
<Step>
|
||||||
### Back up the old server
|
### Back up the old server
|
||||||
|
|
||||||
Copy the database (default `/etc/x-ui/x-ui.db`) and your certificates. See
|
Copy the database (default `/etc/l-ui/l-ui.db`) and your certificates. See
|
||||||
[Backup & restore](/docs/operations/backup-restore).
|
[Backup & restore](/docs/operations/backup-restore).
|
||||||
</Step>
|
</Step>
|
||||||
|
|
||||||
<Step>
|
<Step>
|
||||||
### Install 3x-ui on the new server
|
### Install L-UI on the new server
|
||||||
|
|
||||||
Use the same install method and a compatible version. See
|
Use the same install method and a compatible version. See
|
||||||
[Installation](/docs/guide/installation).
|
[Installation](/docs/guide/installation).
|
||||||
@@ -33,17 +33,17 @@ panel. Update any IP/domain-specific settings.
|
|||||||
|
|
||||||
</Steps>
|
</Steps>
|
||||||
|
|
||||||
## Between 3x-ui versions
|
## Between L-UI versions
|
||||||
|
|
||||||
Within the same backend, upgrading is usually just re-running the installer or
|
Within the same backend, upgrading is usually just re-running the installer or
|
||||||
pulling a new image — the panel migrates its own database. Across **major**
|
pulling a new image — the panel migrates its own database. Across **major**
|
||||||
versions, read the [release notes](https://github.com/MHSanaei/3x-ui/releases)
|
versions, read the [release notes](https://github.com/MHSanaei/L-UI/releases)
|
||||||
first and take a backup.
|
first and take a backup.
|
||||||
|
|
||||||
## From x-ui
|
## From l-ui
|
||||||
|
|
||||||
Importing an older x-ui panel's database directly into 3x-ui is **not
|
Importing an older l-ui panel's database directly into L-UI is **not
|
||||||
supported** — the schemas differ. Install 3x-ui fresh and recreate
|
supported** — the schemas differ. Install L-UI fresh and recreate
|
||||||
inbounds/clients, exporting share links from the old panel as you go.
|
inbounds/clients, exporting share links from the old panel as you go.
|
||||||
|
|
||||||
<Callout type="warn">
|
<Callout type="warn">
|
||||||
|
|||||||
@@ -1,17 +1,17 @@
|
|||||||
---
|
---
|
||||||
title: Troubleshooting
|
title: Troubleshooting
|
||||||
description: Fix common 3x-ui problems — the panel won't start, 502 errors, certificate issues, and clients that can't connect.
|
description: Fix common L-UI problems — the panel won't start, 502 errors, certificate issues, and clients that can't connect.
|
||||||
icon: Wrench
|
icon: Wrench
|
||||||
---
|
---
|
||||||
|
|
||||||
A checklist for the most common issues. When in doubt, raise the log level
|
A checklist for the most common issues. When in doubt, raise the log level
|
||||||
(`XUI_LOG_LEVEL=debug`) and check the panel and Xray logs.
|
(`LUI_LOG_LEVEL=debug`) and check the panel and Xray logs.
|
||||||
|
|
||||||
## The panel won't start
|
## The panel won't start
|
||||||
|
|
||||||
- Check the service status and logs (`x-ui` menu → status/logs).
|
- Check the service status and logs (`l-ui` menu → status/logs).
|
||||||
- Make sure the **panel port isn't already in use** by another service.
|
- Make sure the **panel port isn't already in use** by another service.
|
||||||
- Verify the database path is writable (default `/etc/x-ui/x-ui.db`).
|
- Verify the database path is writable (default `/etc/l-ui/l-ui.db`).
|
||||||
|
|
||||||
## 502 / panel unreachable behind a proxy
|
## 502 / panel unreachable behind a proxy
|
||||||
|
|
||||||
@@ -37,6 +37,6 @@ A checklist for the most common issues. When in doubt, raise the log level
|
|||||||
|
|
||||||
<Callout type="info">
|
<Callout type="info">
|
||||||
Still stuck? Search the
|
Still stuck? Search the
|
||||||
[GitHub issues](https://github.com/MHSanaei/3x-ui/issues) — your symptom has
|
[GitHub issues](https://github.com/MHSanaei/L-UI/issues) — your symptom has
|
||||||
probably been seen before.
|
probably been seen before.
|
||||||
</Callout>
|
</Callout>
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
---
|
---
|
||||||
title: 3x-ui Documentation
|
title: L-UI Documentation
|
||||||
description: Official documentation for 3x-ui — an advanced web panel for managing Xray-core servers, proxies, clients, and subscriptions.
|
description: Official documentation for L-UI — an advanced web panel for managing Xray-core servers, proxies, clients, and subscriptions.
|
||||||
icon: House
|
icon: House
|
||||||
---
|
---
|
||||||
|
|
||||||
**3x-ui** is an open-source web panel for deploying and managing
|
**L-UI** is an open-source web panel for deploying and managing
|
||||||
[Xray-core](https://github.com/XTLS/Xray-core) servers. It gives you a modern
|
[Xray-core](https://github.com/XTLS/Xray-core) servers. It gives you a modern
|
||||||
dashboard for inbounds, protocols, clients, traffic accounting, subscriptions,
|
dashboard for inbounds, protocols, clients, traffic accounting, subscriptions,
|
||||||
and more — without hand-editing Xray JSON on the command line.
|
and more — without hand-editing Xray JSON on the command line.
|
||||||
@@ -17,7 +17,7 @@ leaves the page.
|
|||||||
|
|
||||||
<Cards>
|
<Cards>
|
||||||
<Card
|
<Card
|
||||||
title="What is 3x-ui?"
|
title="What is L-UI?"
|
||||||
href="/docs/guide"
|
href="/docs/guide"
|
||||||
description="The big picture: Xray-core, the panel, and who it's for."
|
description="The big picture: Xray-core, the panel, and who it's for."
|
||||||
/>
|
/>
|
||||||
@@ -49,6 +49,6 @@ leaves the page.
|
|||||||
- **Operations** — multi-node management, Telegram bot, backups, and a REST API.
|
- **Operations** — multi-node management, Telegram bot, backups, and a REST API.
|
||||||
|
|
||||||
<Callout type="info">
|
<Callout type="info">
|
||||||
New to Xray? Read [What is 3x-ui?](/docs/guide) first — it explains how the panel, Xray-core, and
|
New to Xray? Read [What is L-UI?](/docs/guide) first — it explains how the panel, Xray-core, and
|
||||||
your client apps fit together.
|
your client apps fit together.
|
||||||
</Callout>
|
</Callout>
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
---
|
---
|
||||||
title: Backup & Restore
|
title: Backup & Restore
|
||||||
description: Back up and restore your 3x-ui database and certificates, manually or via the Telegram bot.
|
description: Back up and restore your L-UI database and certificates, manually or via the Telegram bot.
|
||||||
icon: DatabaseBackup
|
icon: DatabaseBackup
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -9,7 +9,7 @@ database. Back it up regularly so you can recover or migrate.
|
|||||||
|
|
||||||
## What to back up
|
## What to back up
|
||||||
|
|
||||||
- **The database** — SQLite at `/etc/x-ui/x-ui.db` by default (or your
|
- **The database** — SQLite at `/etc/l-ui/l-ui.db` by default (or your
|
||||||
PostgreSQL database if you use that backend).
|
PostgreSQL database if you use that backend).
|
||||||
- **Certificates** — anything under `/root/cert/` (or wherever you store TLS
|
- **Certificates** — anything under `/root/cert/` (or wherever you store TLS
|
||||||
certs).
|
certs).
|
||||||
@@ -20,7 +20,7 @@ You can download a backup from the panel's overview, or copy the database file
|
|||||||
directly from the server:
|
directly from the server:
|
||||||
|
|
||||||
```bash title="copy the SQLite database"
|
```bash title="copy the SQLite database"
|
||||||
cp /etc/x-ui/x-ui.db /root/x-ui-backup-$(date +%F).db
|
cp /etc/l-ui/l-ui.db /root/l-ui-backup-$(date +%F).db
|
||||||
```
|
```
|
||||||
|
|
||||||
To restore, stop the panel, put the database back in place, and start it again.
|
To restore, stop the panel, put the database back in place, and start it again.
|
||||||
@@ -41,12 +41,12 @@ can also request a backup on demand from the bot's menu.
|
|||||||
|
|
||||||
## SQLite dump / restore
|
## SQLite dump / restore
|
||||||
|
|
||||||
The `x-ui migrate-db` command converts the SQLite database to and from a plain
|
The `l-ui migrate-db` command converts the SQLite database to and from a plain
|
||||||
SQL text dump (handy for inspection or transferring between machines):
|
SQL text dump (handy for inspection or transferring between machines):
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
x-ui migrate-db --dump /root/x-ui.sql # SQLite -> SQL text
|
l-ui migrate-db --dump /root/l-ui.sql # SQLite -> SQL text
|
||||||
x-ui migrate-db --restore /root/x-ui.sql # SQL text -> SQLite
|
l-ui migrate-db --restore /root/l-ui.sql # SQL text -> SQLite
|
||||||
```
|
```
|
||||||
|
|
||||||
To move to PostgreSQL instead, see [Database](/docs/reference/database).
|
To move to PostgreSQL instead, see [Database](/docs/reference/database).
|
||||||
|
|||||||
@@ -1,15 +1,15 @@
|
|||||||
---
|
---
|
||||||
title: Multi-node & Managed Hosts
|
title: Multi-node & Managed Hosts
|
||||||
description: Manage multiple 3x-ui panels from one master, with API-token or mTLS trust, heartbeats, and per-inbound host overrides for subscriptions.
|
description: Manage multiple L-UI panels from one master, with API-token or mTLS trust, heartbeats, and per-inbound host overrides for subscriptions.
|
||||||
icon: Boxes
|
icon: Boxes
|
||||||
---
|
---
|
||||||
|
|
||||||
3x-ui can manage **multiple servers** from a single master panel, and override
|
L-UI can manage **multiple servers** from a single master panel, and override
|
||||||
how each inbound is advertised in subscriptions with **managed hosts**.
|
how each inbound is advertised in subscriptions with **managed hosts**.
|
||||||
|
|
||||||
## Nodes
|
## Nodes
|
||||||
|
|
||||||
A **node** is another 3x-ui panel that your master panel manages over the node's
|
A **node** is another L-UI panel that your master panel manages over the node's
|
||||||
API. The master polls each node and shows its status, versions, CPU/memory,
|
API. The master polls each node and shows its status, versions, CPU/memory,
|
||||||
uptime, and traffic in one place.
|
uptime, and traffic in one place.
|
||||||
|
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
---
|
---
|
||||||
title: Outbounds & Routing
|
title: Outbounds & Routing
|
||||||
description: Shape egress in 3x-ui — WARP, NordVPN, PIA WireGuard, outbound subscriptions, routing rules, and load balancers.
|
description: Shape egress in L-UI — WARP, NordVPN, PIA WireGuard, outbound subscriptions, routing rules, and load balancers.
|
||||||
icon: Route
|
icon: Route
|
||||||
---
|
---
|
||||||
|
|
||||||
Inbounds accept clients; **outbounds** decide where their traffic goes next.
|
Inbounds accept clients; **outbounds** decide where their traffic goes next.
|
||||||
3x-ui can route traffic through Cloudflare WARP, NordVPN, Private Internet Access
|
L-UI can route traffic through Cloudflare WARP, NordVPN, Private Internet Access
|
||||||
(WireGuard), or arbitrary outbound pools imported from a subscription,
|
(WireGuard), or arbitrary outbound pools imported from a subscription,
|
||||||
and select between them with routing rules and balancers.
|
and select between them with routing rules and balancers.
|
||||||
|
|
||||||
@@ -39,7 +39,7 @@ inbound's transport and security. Two outbounds are almost always present:
|
|||||||
|
|
||||||
A **proxy** outbound (VLESS, VMess, Trojan, Shadowsocks) forwards to another
|
A **proxy** outbound (VLESS, VMess, Trojan, Shadowsocks) forwards to another
|
||||||
server — handy for chaining or sending select traffic abroad. Mind the wire
|
server — handy for chaining or sending select traffic abroad. Mind the wire
|
||||||
shapes 3x-ui uses: **VLESS is the flat form** (`address`/`port`/`id`/`flow`/
|
shapes L-UI uses: **VLESS is the flat form** (`address`/`port`/`id`/`flow`/
|
||||||
`encryption`), **VMess uses `settings.vnext[]`**, and **Trojan/Shadowsocks use
|
`encryption`), **VMess uses `settings.vnext[]`**, and **Trojan/Shadowsocks use
|
||||||
`settings.servers[]`**. The `streamSettings` must mirror the destination's
|
`settings.servers[]`**. The `streamSettings` must mirror the destination's
|
||||||
[transport and security](/docs/config/transports).
|
[transport and security](/docs/config/transports).
|
||||||
@@ -50,7 +50,7 @@ Assemble any outbound below and paste the JSON into **Xray Settings → Outbound
|
|||||||
|
|
||||||
## Cloudflare WARP
|
## Cloudflare WARP
|
||||||
|
|
||||||
WARP lets your server egress through Cloudflare's network. 3x-ui can register a
|
WARP lets your server egress through Cloudflare's network. L-UI can register a
|
||||||
WARP account for you and wire it into a WireGuard outbound tagged **`warp`**:
|
WARP account for you and wire it into a WireGuard outbound tagged **`warp`**:
|
||||||
|
|
||||||
<Steps>
|
<Steps>
|
||||||
@@ -64,7 +64,7 @@ Create a WireGuard outbound with the tag `warp` in your Xray config.
|
|||||||
<Step>
|
<Step>
|
||||||
### Register WARP
|
### Register WARP
|
||||||
|
|
||||||
From the panel's WARP controls, register an account. 3x-ui fills the outbound's
|
From the panel's WARP controls, register an account. L-UI fills the outbound's
|
||||||
keys, addresses, reserved bytes, and peer endpoint automatically.
|
keys, addresses, reserved bytes, and peer endpoint automatically.
|
||||||
</Step>
|
</Step>
|
||||||
|
|
||||||
@@ -82,13 +82,13 @@ with a routing rule.
|
|||||||
|
|
||||||
## NordVPN
|
## NordVPN
|
||||||
|
|
||||||
3x-ui can fetch NordVPN (NordLynx/WireGuard) credentials from an access token (or
|
L-UI can fetch NordVPN (NordLynx/WireGuard) credentials from an access token (or
|
||||||
accept a private key directly) and list countries/servers, so you can build a
|
accept a private key directly) and list countries/servers, so you can build a
|
||||||
NordVPN outbound.
|
NordVPN outbound.
|
||||||
|
|
||||||
## PIA WireGuard
|
## PIA WireGuard
|
||||||
|
|
||||||
3x-ui can sign in with a PIA username and password, list countries/regions/servers
|
L-UI can sign in with a PIA username and password, list countries/regions/servers
|
||||||
from the signed PIA server list, and build a WireGuard outbound. Open
|
from the signed PIA server list, and build a WireGuard outbound. Open
|
||||||
**Xray → Outbounds → More → PIA**, sign in, pick a server, and add the outbound.
|
**Xray → Outbounds → More → PIA**, sign in, pick a server, and add the outbound.
|
||||||
You can add several servers (one outbound per hostname). The tag is
|
You can add several servers (one outbound per hostname). The tag is
|
||||||
@@ -100,7 +100,7 @@ revoke the WireGuard peer on the PIA account.
|
|||||||
|
|
||||||
The password is not stored. The PIA API token is stored with the same
|
The password is not stored. The PIA API token is stored with the same
|
||||||
`NODE_TOKEN_ENCRYPTION` setting as node API tokens. If you retire an old
|
`NODE_TOKEN_ENCRYPTION` setting as node API tokens. If you retire an old
|
||||||
`XUI_NODE_TOKEN_KEY` without signing into PIA again, Add/Reset fail until you
|
`LUI_NODE_TOKEN_KEY` without signing into PIA again, Add/Reset fail until you
|
||||||
re-login. Peer `allowedIPs` is IPv4-only (`0.0.0.0/0`).
|
re-login. Peer `allowedIPs` is IPv4-only (`0.0.0.0/0`).
|
||||||
|
|
||||||
## Outbound subscriptions (server pools)
|
## Outbound subscriptions (server pools)
|
||||||
|
|||||||
@@ -1,13 +1,13 @@
|
|||||||
---
|
---
|
||||||
title: Reverse Proxy
|
title: Reverse Proxy
|
||||||
description: Put the 3x-ui panel and subscription behind Nginx or Caddy with Let's Encrypt TLS.
|
description: Put the L-UI panel and subscription behind Nginx or Caddy with Let's Encrypt TLS.
|
||||||
icon: Waypoints
|
icon: Waypoints
|
||||||
---
|
---
|
||||||
|
|
||||||
A reverse proxy lets you serve the panel and subscription on a clean domain with
|
A reverse proxy lets you serve the panel and subscription on a clean domain with
|
||||||
automatic HTTPS, and hide the real ports behind ports 80/443. Prefer to let the
|
automatic HTTPS, and hide the real ports behind ports 80/443. Prefer to let the
|
||||||
panel terminate TLS directly? Get a certificate with the
|
panel terminate TLS directly? Get a certificate with the
|
||||||
[`x-ui` SSL menu](/docs/config/ssl-certificates) instead.
|
[`l-ui` SSL menu](/docs/config/ssl-certificates) instead.
|
||||||
|
|
||||||
## Generate a config
|
## Generate a config
|
||||||
|
|
||||||
@@ -45,7 +45,7 @@ panel.example.com {
|
|||||||
## Tips
|
## Tips
|
||||||
|
|
||||||
- Keep the panel's **web base path** even behind a proxy; defense in depth.
|
- Keep the panel's **web base path** even behind a proxy; defense in depth.
|
||||||
- If you terminate TLS at the proxy, you may want `XUI_SKIP_HSTS=true` on the
|
- If you terminate TLS at the proxy, you may want `LUI_SKIP_HSTS=true` on the
|
||||||
panel — see the [environment variables reference](/docs/reference/env-vars).
|
panel — see the [environment variables reference](/docs/reference/env-vars).
|
||||||
- Proxy the [subscription](/docs/config/subscription) server too, so its contents
|
- Proxy the [subscription](/docs/config/subscription) server too, so its contents
|
||||||
are served over HTTPS.
|
are served over HTTPS.
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
---
|
---
|
||||||
title: Security
|
title: Security
|
||||||
description: Harden 3x-ui — panel auth and 2FA, Fail2ban IP limits, firewall rules, BBR, and staying current.
|
description: Harden L-UI — panel auth and 2FA, Fail2ban IP limits, firewall rules, BBR, and staying current.
|
||||||
icon: ShieldCheck
|
icon: ShieldCheck
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -21,15 +21,15 @@ See [First login](/docs/guide/first-login) for the full checklist.
|
|||||||
|
|
||||||
Set an **IP limit** per client (see [Clients](/docs/config/clients)) to cap the
|
Set an **IP limit** per client (see [Clients](/docs/config/clients)) to cap the
|
||||||
number of simultaneous source IPs. Enforcement is handled by **Fail2ban**, which
|
number of simultaneous source IPs. Enforcement is handled by **Fail2ban**, which
|
||||||
3x-ui installs and configures for you (enabled by default on script installs, and
|
L-UI installs and configures for you (enabled by default on script installs, and
|
||||||
on Docker via `XUI_ENABLE_FAIL2BAN=true`).
|
on Docker via `LUI_ENABLE_FAIL2BAN=true`).
|
||||||
|
|
||||||
Manage it from the `x-ui` menu (**22 — IP Limit Management**): install/configure,
|
Manage it from the `l-ui` menu (**22 — IP Limit Management**): install/configure,
|
||||||
change the ban duration (default **30 minutes**), ban/unban an IP, view ban logs,
|
change the ban duration (default **30 minutes**), ban/unban an IP, view ban logs,
|
||||||
and check status. Under the hood:
|
and check status. Under the hood:
|
||||||
|
|
||||||
- The jail is named **`3x-ipl`**; ban logs live at `/var/log/x-ui/3xipl.log` and
|
- The jail is named **`3x-ipl`**; ban logs live at `/var/log/l-ui/3xipl.log` and
|
||||||
`/var/log/x-ui/3xipl-banned.log` (also via `x-ui banlog`).
|
`/var/log/l-ui/3xipl-banned.log` (also via `l-ui banlog`).
|
||||||
- Bans cover all TCP/UDP **except** your SSH and panel ports, so a ban can't lock
|
- Bans cover all TCP/UDP **except** your SSH and panel ports, so a ban can't lock
|
||||||
you out of the server or panel.
|
you out of the server or panel.
|
||||||
|
|
||||||
@@ -43,7 +43,7 @@ and check status. Under the hood:
|
|||||||
## Firewall
|
## Firewall
|
||||||
|
|
||||||
Open only the ports you actually use: SSH, the panel port, the subscription
|
Open only the ports you actually use: SSH, the panel port, the subscription
|
||||||
port, and your inbound ports. The `x-ui` menu (**23 — Firewall Management**) wraps
|
port, and your inbound ports. The `l-ui` menu (**23 — Firewall Management**) wraps
|
||||||
`ufw`, or generate rules here:
|
`ufw`, or generate rules here:
|
||||||
|
|
||||||
<FirewallRulesGenerator />
|
<FirewallRulesGenerator />
|
||||||
@@ -55,12 +55,12 @@ port, and your inbound ports. The `x-ui` menu (**23 — Firewall Management**) w
|
|||||||
|
|
||||||
## Network tuning (BBR)
|
## Network tuning (BBR)
|
||||||
|
|
||||||
The `x-ui` menu (**26 — Enable BBR**) toggles Google's BBR congestion control
|
The `l-ui` menu (**26 — Enable BBR**) toggles Google's BBR congestion control
|
||||||
(`net.ipv4.tcp_congestion_control = bbr`, `net.core.default_qdisc = fq`), which
|
(`net.ipv4.tcp_congestion_control = bbr`, `net.core.default_qdisc = fq`), which
|
||||||
often improves throughput on congested links.
|
often improves throughput on congested links.
|
||||||
|
|
||||||
## Keep current
|
## Keep current
|
||||||
|
|
||||||
Update 3x-ui and Xray-core regularly — security fixes land in new releases. Watch
|
Update L-UI and Xray-core regularly — security fixes land in new releases. Watch
|
||||||
the [releases page](https://github.com/MHSanaei/3x-ui/releases) and see
|
the [releases page](https://github.com/MHSanaei/L-UI/releases) and see
|
||||||
[Update & uninstall](/docs/guide/update-uninstall).
|
[Update & uninstall](/docs/guide/update-uninstall).
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
---
|
---
|
||||||
title: Telegram Bot
|
title: Telegram Bot
|
||||||
description: Connect a Telegram bot to 3x-ui for commands, periodic reports, event alerts (login, CPU, node up/down), backups, and client self-service.
|
description: Connect a Telegram bot to L-UI for commands, periodic reports, event alerts (login, CPU, node up/down), backups, and client self-service.
|
||||||
icon: Send
|
icon: Send
|
||||||
---
|
---
|
||||||
|
|
||||||
3x-ui can drive a Telegram bot for monitoring, alerts, backups, and remote
|
L-UI can drive a Telegram bot for monitoring, alerts, backups, and remote
|
||||||
management. Admins get full control; regular users (linked by Telegram ID) can
|
management. Admins get full control; regular users (linked by Telegram ID) can
|
||||||
check their own usage and links.
|
check their own usage and links.
|
||||||
|
|
||||||
|
|||||||
@@ -1,56 +0,0 @@
|
|||||||
---
|
|
||||||
title: API Tokens
|
|
||||||
description: Manage scoped Bearer tokens for programmatic auth. Tokens grant
|
|
||||||
admin, monitor, or node-sync access, may expire, and are stored as SHA-256
|
|
||||||
hashes. The plaintext is returned only once at creation.
|
|
||||||
full: true
|
|
||||||
_openapi:
|
|
||||||
preload:
|
|
||||||
- ./public/openapi.json
|
|
||||||
toc:
|
|
||||||
- depth: 2
|
|
||||||
title: List every API token, enabled or not. The token value is never returned —
|
|
||||||
only metadata.
|
|
||||||
url: '#list-every-api-token-enabled-or-not-the-token-value-is-never-returned--only-metadata'
|
|
||||||
- depth: 2
|
|
||||||
title: Mint a scoped API token. The server-generated plaintext is returned only
|
|
||||||
once and stored as a hash.
|
|
||||||
url: '#mint-a-scoped-api-token-the-server-generated-plaintext-is-returned-only-once-and-stored-as-a-hash'
|
|
||||||
- depth: 2
|
|
||||||
title: Permanently delete a token. Any caller using it stops authenticating
|
|
||||||
immediately.
|
|
||||||
url: '#permanently-delete-a-token-any-caller-using-it-stops-authenticating-immediately'
|
|
||||||
- depth: 2
|
|
||||||
title: Toggle a token enabled/disabled without deleting it. Disabled tokens are
|
|
||||||
rejected by checkAPIAuth on the next request.
|
|
||||||
url: '#toggle-a-token-enableddisabled-without-deleting-it-disabled-tokens-are-rejected-by-checkapiauth-on-the-next-request'
|
|
||||||
structuredData:
|
|
||||||
headings:
|
|
||||||
- content: List every API token, enabled or not. The token value is never returned
|
|
||||||
— only metadata.
|
|
||||||
id: list-every-api-token-enabled-or-not-the-token-value-is-never-returned--only-metadata
|
|
||||||
- content: Mint a scoped API token. The server-generated plaintext is returned
|
|
||||||
only once and stored as a hash.
|
|
||||||
id: mint-a-scoped-api-token-the-server-generated-plaintext-is-returned-only-once-and-stored-as-a-hash
|
|
||||||
- content: Permanently delete a token. Any caller using it stops authenticating
|
|
||||||
immediately.
|
|
||||||
id: permanently-delete-a-token-any-caller-using-it-stops-authenticating-immediately
|
|
||||||
- content: Toggle a token enabled/disabled without deleting it. Disabled tokens
|
|
||||||
are rejected by checkAPIAuth on the next request.
|
|
||||||
id: toggle-a-token-enableddisabled-without-deleting-it-disabled-tokens-are-rejected-by-checkapiauth-on-the-next-request
|
|
||||||
contents: []
|
|
||||||
---
|
|
||||||
|
|
||||||
{/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */}
|
|
||||||
|
|
||||||
export default function Layout(props) {
|
|
||||||
const { APIPage, OpenAPIPage } = props.components ?? {};
|
|
||||||
// "APIPage" is the old name from v10, this allows both for backward compatibility
|
|
||||||
const Comp = OpenAPIPage ?? APIPage;
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
{props.children}
|
|
||||||
<Comp document="./public/openapi.json" webhooks={[]} operations={[{"path":"/panel/api/setting/apiTokens","method":"get"},{"path":"/panel/api/setting/apiTokens/create","method":"post"},{"path":"/panel/api/setting/apiTokens/delete/{id}","method":"post"},{"path":"/panel/api/setting/apiTokens/setEnabled/{id}","method":"post"}]} showTitle />
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@@ -54,7 +54,7 @@ export default function Layout(props) {
|
|||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{props.children}
|
{props.children}
|
||||||
<Comp document="./public/openapi.json" webhooks={[]} operations={[{"path":"/login","method":"post"},{"path":"/logout","method":"post"},{"path":"/csrf-token","method":"get"},{"path":"/getTwoFactorEnable","method":"post"}]} showTitle />
|
<Comp document="./public/openapi.json" webhooks={[]} operations={[{"path":"/login","method":"post"},{"path":"/logout","method":"post"},{"path":"/csrf-token","method":"get"}]} showTitle />
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -1,10 +1,10 @@
|
|||||||
---
|
---
|
||||||
title: API Reference
|
title: API Reference
|
||||||
description: The 3x-ui panel REST API — authentication, inbounds, clients, server stats, and more, generated from the OpenAPI spec.
|
description: The L-UI panel REST API — authentication, inbounds, clients, server stats, and more, generated from the OpenAPI spec.
|
||||||
icon: Webhook
|
icon: Webhook
|
||||||
---
|
---
|
||||||
|
|
||||||
The 3x-ui panel exposes a REST API for automation. These pages are generated from
|
The L-UI panel exposes a REST API for automation. These pages are generated from
|
||||||
the panel's OpenAPI specification, so they always match the documented schema.
|
the panel's OpenAPI specification, so they always match the documented schema.
|
||||||
|
|
||||||
## Authentication
|
## Authentication
|
||||||
|
|||||||
@@ -4,7 +4,6 @@
|
|||||||
"pages": [
|
"pages": [
|
||||||
"index",
|
"index",
|
||||||
"authentication",
|
"authentication",
|
||||||
"api-tokens",
|
|
||||||
"inbounds",
|
"inbounds",
|
||||||
"clients",
|
"clients",
|
||||||
"server",
|
"server",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
---
|
---
|
||||||
title: Nodes
|
title: Nodes
|
||||||
description: Manage remote 3x-ui panels acting as nodes for a central panel. All
|
description: Manage remote L-UI panels acting as nodes for a central panel. All
|
||||||
endpoints under /panel/api/nodes.
|
endpoints under /panel/api/nodes.
|
||||||
full: true
|
full: true
|
||||||
_openapi:
|
_openapi:
|
||||||
@@ -37,15 +37,12 @@ _openapi:
|
|||||||
panel.
|
panel.
|
||||||
url: '#fetch-a-nodes-own-web-tls-certificatekey-file-paths-proxied-to-the-node-used-by-the-inbound-forms-set-cert-from-panel-so-a-node-assigned-inbound-gets-paths-that-exist-on-the-node-not-the-central-panel'
|
url: '#fetch-a-nodes-own-web-tls-certificatekey-file-paths-proxied-to-the-node-used-by-the-inbound-forms-set-cert-from-panel-so-a-node-assigned-inbound-gets-paths-that-exist-on-the-node-not-the-central-panel'
|
||||||
- depth: 2
|
- depth: 2
|
||||||
title: Register a new remote node. Provide its URL, write-only apiToken, and
|
title: Register a new remote node. Provide its URL and optional remark /
|
||||||
optional remark / allowPrivateAddress flag. Responses expose hasApiToken
|
allowPrivateAddress flag.
|
||||||
only.
|
url: '#register-a-new-remote-node-provide-its-url-and-optional-remark--allowprivateaddress-flag'
|
||||||
url: '#register-a-new-remote-node-provide-its-url-write-only-apitoken-and-optional-remark--allowprivateaddress-flag-responses-expose-hasapitoken-only'
|
|
||||||
- depth: 2
|
- depth: 2
|
||||||
title: 'Replace a node’s connection details. apiToken is write-only: omit it or
|
title: Replace a node’s connection details.
|
||||||
send an empty string to keep the stored token; set clearApiToken=true to
|
url: '#replace-a-nodes-connection-details'
|
||||||
clear it.'
|
|
||||||
url: '#replace-a-nodes-connection-details-apitoken-is-write-only-omit-it-or-send-an-empty-string-to-keep-the-stored-token-set-clearapitokentrue-to-clear-it'
|
|
||||||
- depth: 2
|
- depth: 2
|
||||||
title: Delete a node. Inbounds bound to it are not auto-migrated.
|
title: Delete a node. Inbounds bound to it are not auto-migrated.
|
||||||
url: '#delete-a-node-inbounds-bound-to-it-are-not-auto-migrated'
|
url: '#delete-a-node-inbounds-bound-to-it-are-not-auto-migrated'
|
||||||
@@ -105,14 +102,11 @@ _openapi:
|
|||||||
node-assigned inbound gets paths that exist on the node, not the
|
node-assigned inbound gets paths that exist on the node, not the
|
||||||
central panel.
|
central panel.
|
||||||
id: fetch-a-nodes-own-web-tls-certificatekey-file-paths-proxied-to-the-node-used-by-the-inbound-forms-set-cert-from-panel-so-a-node-assigned-inbound-gets-paths-that-exist-on-the-node-not-the-central-panel
|
id: fetch-a-nodes-own-web-tls-certificatekey-file-paths-proxied-to-the-node-used-by-the-inbound-forms-set-cert-from-panel-so-a-node-assigned-inbound-gets-paths-that-exist-on-the-node-not-the-central-panel
|
||||||
- content: Register a new remote node. Provide its URL, write-only apiToken, and
|
- content: Register a new remote node. Provide its URL and optional remark /
|
||||||
optional remark / allowPrivateAddress flag. Responses expose
|
allowPrivateAddress flag.
|
||||||
hasApiToken only.
|
id: register-a-new-remote-node-provide-its-url-and-optional-remark--allowprivateaddress-flag
|
||||||
id: register-a-new-remote-node-provide-its-url-write-only-apitoken-and-optional-remark--allowprivateaddress-flag-responses-expose-hasapitoken-only
|
- content: Replace a node’s connection details.
|
||||||
- content: 'Replace a node’s connection details. apiToken is write-only: omit it
|
id: replace-a-nodes-connection-details
|
||||||
or send an empty string to keep the stored token; set
|
|
||||||
clearApiToken=true to clear it.'
|
|
||||||
id: replace-a-nodes-connection-details-apitoken-is-write-only-omit-it-or-send-an-empty-string-to-keep-the-stored-token-set-clearapitokentrue-to-clear-it
|
|
||||||
- content: Delete a node. Inbounds bound to it are not auto-migrated.
|
- content: Delete a node. Inbounds bound to it are not auto-migrated.
|
||||||
id: delete-a-node-inbounds-bound-to-it-are-not-auto-migrated
|
id: delete-a-node-inbounds-bound-to-it-are-not-auto-migrated
|
||||||
- content: Pause or resume traffic sync with this node.
|
- content: Pause or resume traffic sync with this node.
|
||||||
|
|||||||
@@ -53,8 +53,8 @@ _openapi:
|
|||||||
title: List Xray binary versions available for install on this host.
|
title: List Xray binary versions available for install on this host.
|
||||||
url: '#list-xray-binary-versions-available-for-install-on-this-host'
|
url: '#list-xray-binary-versions-available-for-install-on-this-host'
|
||||||
- depth: 2
|
- depth: 2
|
||||||
title: Check whether a newer 3x-ui release is available on GitHub.
|
title: Check whether a newer L-UI release is available on GitHub.
|
||||||
url: '#check-whether-a-newer-3x-ui-release-is-available-on-github'
|
url: '#check-whether-a-newer-L-UI-release-is-available-on-github'
|
||||||
- depth: 2
|
- depth: 2
|
||||||
title: Report the outcome of the most recently launched panel self-update (see
|
title: Report the outcome of the most recently launched panel self-update (see
|
||||||
POST updatePanel). Compare the returned runId against the one
|
POST updatePanel). Compare the returned runId against the one
|
||||||
@@ -218,8 +218,8 @@ _openapi:
|
|||||||
id: time-series-of-observatory-probe-results-for-one-outbound-tag-same-t-v-shape-as-the-other-history-endpoints
|
id: time-series-of-observatory-probe-results-for-one-outbound-tag-same-t-v-shape-as-the-other-history-endpoints
|
||||||
- content: List Xray binary versions available for install on this host.
|
- content: List Xray binary versions available for install on this host.
|
||||||
id: list-xray-binary-versions-available-for-install-on-this-host
|
id: list-xray-binary-versions-available-for-install-on-this-host
|
||||||
- content: Check whether a newer 3x-ui release is available on GitHub.
|
- content: Check whether a newer L-UI release is available on GitHub.
|
||||||
id: check-whether-a-newer-3x-ui-release-is-available-on-github
|
id: check-whether-a-newer-L-UI-release-is-available-on-github
|
||||||
- content: Report the outcome of the most recently launched panel self-update (see
|
- content: Report the outcome of the most recently launched panel self-update (see
|
||||||
POST updatePanel). Compare the returned runId against the one
|
POST updatePanel). Compare the returned runId against the one
|
||||||
updatePanel returned to tell this run apart from a stale result.
|
updatePanel returned to tell this run apart from a stale result.
|
||||||
|
|||||||
@@ -36,10 +36,10 @@ _openapi:
|
|||||||
values on success.
|
values on success.
|
||||||
url: '#change-the-panel-admin-username-and-password-requires-the-current-credentials-for-verification-the-session-is-refreshed-with-the-new-values-on-success'
|
url: '#change-the-panel-admin-username-and-password-requires-the-current-credentials-for-verification-the-session-is-refreshed-with-the-new-values-on-success'
|
||||||
- depth: 2
|
- depth: 2
|
||||||
title: Restart the entire 3x-ui process after a 3-second grace period. The
|
title: Restart the entire L-UI process after a 3-second grace period. The
|
||||||
connection drops immediately; the panel comes back online ~5-10 seconds
|
connection drops immediately; the panel comes back online ~5-10 seconds
|
||||||
later.
|
later.
|
||||||
url: '#restart-the-entire-3x-ui-process-after-a-3-second-grace-period-the-connection-drops-immediately-the-panel-comes-back-online-5-10-seconds-later'
|
url: '#restart-the-entire-L-UI-process-after-a-3-second-grace-period-the-connection-drops-immediately-the-panel-comes-back-online-5-10-seconds-later'
|
||||||
- depth: 2
|
- depth: 2
|
||||||
title: Test SMTP connection with stage-by-stage reporting (connect, auth, send).
|
title: Test SMTP connection with stage-by-stage reporting (connect, auth, send).
|
||||||
Returns structured result with stage and message.
|
Returns structured result with stage and message.
|
||||||
@@ -76,10 +76,10 @@ _openapi:
|
|||||||
credentials for verification. The session is refreshed with the new
|
credentials for verification. The session is refreshed with the new
|
||||||
values on success.
|
values on success.
|
||||||
id: change-the-panel-admin-username-and-password-requires-the-current-credentials-for-verification-the-session-is-refreshed-with-the-new-values-on-success
|
id: change-the-panel-admin-username-and-password-requires-the-current-credentials-for-verification-the-session-is-refreshed-with-the-new-values-on-success
|
||||||
- content: Restart the entire 3x-ui process after a 3-second grace period. The
|
- content: Restart the entire L-UI process after a 3-second grace period. The
|
||||||
connection drops immediately; the panel comes back online ~5-10
|
connection drops immediately; the panel comes back online ~5-10
|
||||||
seconds later.
|
seconds later.
|
||||||
id: restart-the-entire-3x-ui-process-after-a-3-second-grace-period-the-connection-drops-immediately-the-panel-comes-back-online-5-10-seconds-later
|
id: restart-the-entire-L-UI-process-after-a-3-second-grace-period-the-connection-drops-immediately-the-panel-comes-back-online-5-10-seconds-later
|
||||||
- content: Test SMTP connection with stage-by-stage reporting (connect, auth,
|
- content: Test SMTP connection with stage-by-stage reporting (connect, auth,
|
||||||
send). Returns structured result with stage and message.
|
send). Returns structured result with stage and message.
|
||||||
id: test-smtp-connection-with-stage-by-stage-reporting-connect-auth-send-returns-structured-result-with-stage-and-message
|
id: test-smtp-connection-with-stage-by-stage-reporting-connect-auth-send-returns-structured-result-with-stage-and-message
|
||||||
|
|||||||
@@ -1,17 +1,17 @@
|
|||||||
---
|
---
|
||||||
title: Database
|
title: Database
|
||||||
description: 3x-ui storage backends — SQLite (default) and PostgreSQL — the database path, connection pool, and SQLite-to-PostgreSQL migration.
|
description: L-UI storage backends — SQLite (default) and PostgreSQL — the database path, connection pool, and SQLite-to-PostgreSQL migration.
|
||||||
icon: Database
|
icon: Database
|
||||||
---
|
---
|
||||||
|
|
||||||
3x-ui stores everything — inbounds, clients, settings — in a database. You choose
|
L-UI stores everything — inbounds, clients, settings — in a database. You choose
|
||||||
the backend at install time; both are first-class.
|
the backend at install time; both are first-class.
|
||||||
|
|
||||||
## SQLite (default)
|
## SQLite (default)
|
||||||
|
|
||||||
A single file at `/etc/x-ui/x-ui.db`. Zero setup, ideal for small and medium
|
A single file at `/etc/l-ui/l-ui.db`. Zero setup, ideal for small and medium
|
||||||
deployments. The folder is configurable with
|
deployments. The folder is configurable with
|
||||||
[`XUI_DB_FOLDER`](/docs/reference/env-vars#database) (on Windows it defaults next
|
[`LUI_DB_FOLDER`](/docs/reference/env-vars#database) (on Windows it defaults next
|
||||||
to the binary).
|
to the binary).
|
||||||
|
|
||||||
## PostgreSQL
|
## PostgreSQL
|
||||||
@@ -19,20 +19,20 @@ to the binary).
|
|||||||
Recommended for high client counts or multi-node setups. The installer can
|
Recommended for high client counts or multi-node setups. The installer can
|
||||||
install PostgreSQL locally for you, or accept a DSN to an existing server. At
|
install PostgreSQL locally for you, or accept a DSN to an existing server. At
|
||||||
runtime the backend is selected via environment variables, which the installer
|
runtime the backend is selected via environment variables, which the installer
|
||||||
writes to `/etc/default/x-ui`:
|
writes to `/etc/default/l-ui`:
|
||||||
|
|
||||||
```bash title="/etc/default/x-ui"
|
```bash title="/etc/default/l-ui"
|
||||||
XUI_DB_TYPE=postgres
|
LUI_DB_TYPE=postgres
|
||||||
XUI_DB_DSN=postgres://xui:password@127.0.0.1:5432/xui?sslmode=disable
|
LUI_DB_DSN=postgres://xui:password@127.0.0.1:5432/xui?sslmode=disable
|
||||||
```
|
```
|
||||||
|
|
||||||
Tune the connection pool with `XUI_DB_MAX_OPEN_CONNS` and
|
Tune the connection pool with `LUI_DB_MAX_OPEN_CONNS` and
|
||||||
`XUI_DB_MAX_IDLE_CONNS`.
|
`LUI_DB_MAX_IDLE_CONNS`.
|
||||||
|
|
||||||
### Docker
|
### Docker
|
||||||
|
|
||||||
`docker compose up -d` keeps using SQLite. To run with the bundled PostgreSQL
|
`docker compose up -d` keeps using SQLite. To run with the bundled PostgreSQL
|
||||||
service, uncomment the two `XUI_DB_*` lines in `docker-compose.yml` and start
|
service, uncomment the two `LUI_DB_*` lines in `docker-compose.yml` and start
|
||||||
with the profile:
|
with the profile:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
@@ -44,13 +44,13 @@ docker compose --profile postgres up -d
|
|||||||
Move an existing SQLite install to PostgreSQL with the built-in command:
|
Move an existing SQLite install to PostgreSQL with the built-in command:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
x-ui migrate-db --dsn "postgres://xui:password@127.0.0.1:5432/xui?sslmode=disable"
|
l-ui migrate-db --dsn "postgres://xui:password@127.0.0.1:5432/xui?sslmode=disable"
|
||||||
```
|
```
|
||||||
|
|
||||||
Then set `XUI_DB_TYPE` and `XUI_DB_DSN` in `/etc/default/x-ui` and restart:
|
Then set `LUI_DB_TYPE` and `LUI_DB_DSN` in `/etc/default/l-ui` and restart:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
systemctl restart x-ui
|
systemctl restart l-ui
|
||||||
```
|
```
|
||||||
|
|
||||||
<Callout type="info">
|
<Callout type="info">
|
||||||
|
|||||||
@@ -1,46 +1,46 @@
|
|||||||
---
|
---
|
||||||
title: Environment Variables
|
title: Environment Variables
|
||||||
description: Complete reference for 3x-ui's XUI_* environment variables — database, panel, logging, memory, and the tunnel health monitor.
|
description: Complete reference for L-UI's LUI_* environment variables — database, panel, logging, memory, and the tunnel health monitor.
|
||||||
icon: Variable
|
icon: Variable
|
||||||
---
|
---
|
||||||
|
|
||||||
3x-ui reads its runtime configuration from `XUI_*` environment variables. On a
|
L-UI reads its runtime configuration from `LUI_*` environment variables. On a
|
||||||
script install the installer writes them to the service environment file
|
script install the installer writes them to the service environment file
|
||||||
(`/etc/default/x-ui`, or `/etc/conf.d/x-ui` / `/etc/sysconfig/x-ui` depending on
|
(`/etc/default/l-ui`, or `/etc/conf.d/l-ui` / `/etc/sysconfig/l-ui` depending on
|
||||||
the distro); for Docker you set them in `docker-compose.yml` or `docker run -e`.
|
the distro); for Docker you set them in `docker-compose.yml` or `docker run -e`.
|
||||||
Defaults are sensible — set only what you need to change, then restart:
|
Defaults are sensible — set only what you need to change, then restart:
|
||||||
`systemctl restart x-ui`.
|
`systemctl restart l-ui`.
|
||||||
|
|
||||||
## Database
|
## Database
|
||||||
|
|
||||||
| Variable | Default | Description |
|
| Variable | Default | Description |
|
||||||
| ------------------------ | ----------- | -------------------------------------------------------------------- |
|
| ------------------------ | ----------- | -------------------------------------------------------------------- |
|
||||||
| `XUI_DB_TYPE` | `sqlite` | Backend: `sqlite`, or `postgres` (also accepts `postgresql` / `pg`). |
|
| `LUI_DB_TYPE` | `sqlite` | Backend: `sqlite`, or `postgres` (also accepts `postgresql` / `pg`). |
|
||||||
| `XUI_DB_FOLDER` | `/etc/x-ui` | Folder for the SQLite database file (`x-ui.db`). |
|
| `LUI_DB_FOLDER` | `/etc/l-ui` | Folder for the SQLite database file (`l-ui.db`). |
|
||||||
| `XUI_DB_DSN` | — | PostgreSQL connection string (used when `XUI_DB_TYPE=postgres`). |
|
| `LUI_DB_DSN` | — | PostgreSQL connection string (used when `LUI_DB_TYPE=postgres`). |
|
||||||
| `XUI_DB_MAX_OPEN_CONNS` | — | Max open connections in the PostgreSQL pool. |
|
| `LUI_DB_MAX_OPEN_CONNS` | — | Max open connections in the PostgreSQL pool. |
|
||||||
| `XUI_DB_MAX_IDLE_CONNS` | — | Max idle connections in the PostgreSQL pool. |
|
| `LUI_DB_MAX_IDLE_CONNS` | — | Max idle connections in the PostgreSQL pool. |
|
||||||
|
|
||||||
The default SQLite database path is `/etc/x-ui/x-ui.db`. See
|
The default SQLite database path is `/etc/l-ui/l-ui.db`. See
|
||||||
[Database](/docs/reference/database) for the SQLite ↔ PostgreSQL details.
|
[Database](/docs/reference/database) for the SQLite ↔ PostgreSQL details.
|
||||||
|
|
||||||
## Panel
|
## Panel
|
||||||
|
|
||||||
| Variable | Default | Description |
|
| Variable | Default | Description |
|
||||||
| ------------------------ | ------- | ------------------------------------------------------------------------ |
|
| ------------------------ | ------- | ------------------------------------------------------------------------ |
|
||||||
| `XUI_PORT` | — | Override the panel port (1–65535). Takes precedence over the stored setting. |
|
| `LUI_PORT` | — | Override the panel port (1–65535). Takes precedence over the stored setting. |
|
||||||
| `XUI_INIT_WEB_BASE_PATH` | `/` | Initial web base path on **first** launch (e.g. `/panel`). |
|
| `LUI_INIT_WEB_BASE_PATH` | `/` | Initial web base path on **first** launch (e.g. `/panel`). |
|
||||||
| `XUI_ENABLE_FAIL2BAN` | `true` | Enable Fail2ban-based IP-limit enforcement. |
|
| `LUI_ENABLE_FAIL2BAN` | `true` | Enable Fail2ban-based IP-limit enforcement. |
|
||||||
| `XUI_SKIP_HSTS` | `false` | Skip the HSTS header — set `true` when TLS is terminated by a reverse proxy. |
|
| `LUI_SKIP_HSTS` | `false` | Skip the HSTS header — set `true` when TLS is terminated by a reverse proxy. |
|
||||||
|
|
||||||
## Logging & binaries
|
## Logging & binaries
|
||||||
|
|
||||||
| Variable | Default | Description |
|
| Variable | Default | Description |
|
||||||
| ---------------- | ---------------- | ----------------------------------------------------------- |
|
| ---------------- | ---------------- | ----------------------------------------------------------- |
|
||||||
| `XUI_LOG_LEVEL` | `info` | `debug`, `info`, `notice`, `warning`, or `error`. |
|
| `LUI_LOG_LEVEL` | `info` | `debug`, `info`, `notice`, `warning`, or `error`. |
|
||||||
| `XUI_DEBUG` | `false` | Debug mode (forces log level to `debug`). |
|
| `LUI_DEBUG` | `false` | Debug mode (forces log level to `debug`). |
|
||||||
| `XUI_LOG_FOLDER` | `/var/log/x-ui` | Log output directory. |
|
| `LUI_LOG_FOLDER` | `/var/log/l-ui` | Log output directory. |
|
||||||
| `XUI_BIN_FOLDER` | `bin` | Folder for the Xray-core binary and geosite/geoip files. |
|
| `LUI_BIN_FOLDER` | `bin` | Folder for the Xray-core binary and geosite/geoip files. |
|
||||||
|
|
||||||
## Memory & profiling
|
## Memory & profiling
|
||||||
|
|
||||||
@@ -49,11 +49,11 @@ knobs — leave them unset unless you're tuning a constrained host.
|
|||||||
|
|
||||||
| Variable | Default | Description |
|
| Variable | Default | Description |
|
||||||
| ----------------------------- | ------- | ----------------------------------------------------------------- |
|
| ----------------------------- | ------- | ----------------------------------------------------------------- |
|
||||||
| `XUI_GOGC` | — | Go GC target percentage; lower = less RAM, slightly more CPU. |
|
| `LUI_GOGC` | — | Go GC target percentage; lower = less RAM, slightly more CPU. |
|
||||||
| `XUI_MEMORY_RELEASE_INTERVAL` | — | Minutes between `FreeOSMemory` calls; `0` disables. |
|
| `LUI_MEMORY_RELEASE_INTERVAL` | — | Minutes between `FreeOSMemory` calls; `0` disables. |
|
||||||
| `XUI_MEMORY_LIMIT` | — | Go soft memory limit in **MiB**. |
|
| `LUI_MEMORY_LIMIT` | — | Go soft memory limit in **MiB**. |
|
||||||
| `GOMEMLIMIT` | — | Go-syntax soft limit (e.g. `400MiB`); takes precedence over above.|
|
| `GOMEMLIMIT` | — | Go-syntax soft limit (e.g. `400MiB`); takes precedence over above.|
|
||||||
| `XUI_PPROF` | `false` | Expose pprof profiling on `127.0.0.1:6060`. |
|
| `LUI_PPROF` | `false` | Expose pprof profiling on `127.0.0.1:6060`. |
|
||||||
|
|
||||||
## Xray
|
## Xray
|
||||||
|
|
||||||
@@ -69,16 +69,16 @@ clients, so enable it deliberately.
|
|||||||
|
|
||||||
| Variable | Default | Description |
|
| Variable | Default | Description |
|
||||||
| ----------------------------- | -------------------------------------------- | ----------------------------------------------------------------- |
|
| ----------------------------- | -------------------------------------------- | ----------------------------------------------------------------- |
|
||||||
| `XUI_TUNNEL_HEALTH_MONITOR` | `false` | Enable the monitor. |
|
| `LUI_TUNNEL_HEALTH_MONITOR` | `false` | Enable the monitor. |
|
||||||
| `XUI_TUNNEL_HEALTH_PROXY` | — | Proxy to send the probe through, e.g. `socks5://127.0.0.1:1080`. Empty = only checks host connectivity. |
|
| `LUI_TUNNEL_HEALTH_PROXY` | — | Proxy to send the probe through, e.g. `socks5://127.0.0.1:1080`. Empty = only checks host connectivity. |
|
||||||
| `XUI_TUNNEL_HEALTH_URL` | `https://www.cloudflare.com/cdn-cgi/trace` | URL to probe. |
|
| `LUI_TUNNEL_HEALTH_URL` | `https://www.cloudflare.com/cdn-cgi/trace` | URL to probe. |
|
||||||
| `XUI_TUNNEL_HEALTH_INTERVAL` | `30s` | Interval between probes. |
|
| `LUI_TUNNEL_HEALTH_INTERVAL` | `30s` | Interval between probes. |
|
||||||
| `XUI_TUNNEL_HEALTH_TIMEOUT` | `10s` | Per-probe timeout. |
|
| `LUI_TUNNEL_HEALTH_TIMEOUT` | `10s` | Per-probe timeout. |
|
||||||
| `XUI_TUNNEL_HEALTH_FAILURES` | `3` | Consecutive failures before a restart. |
|
| `LUI_TUNNEL_HEALTH_FAILURES` | `3` | Consecutive failures before a restart. |
|
||||||
| `XUI_TUNNEL_HEALTH_COOLDOWN` | `5m` | Minimum delay between restarts. |
|
| `LUI_TUNNEL_HEALTH_COOLDOWN` | `5m` | Minimum delay between restarts. |
|
||||||
|
|
||||||
## Unattended install
|
## Unattended install
|
||||||
|
|
||||||
| Variable | Description |
|
| Variable | Description |
|
||||||
| -------------------- | -------------------------------------------------------------------------------------------- |
|
| -------------------- | -------------------------------------------------------------------------------------------- |
|
||||||
| `XUI_NONINTERACTIVE` | Set to `1` (or run with no TTY) to install with zero prompts; generated credentials are written to `/etc/x-ui/install-result.env`. See [Installation](/docs/guide/installation#unattended--cloud-init). |
|
| `LUI_NONINTERACTIVE` | Set to `1` (or run with no TTY) to install with zero prompts; generated credentials are written to `/etc/l-ui/install-result.env`. See [Installation](/docs/guide/installation#unattended--cloud-init). |
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
---
|
---
|
||||||
title: Ports & Firewall
|
title: Ports & Firewall
|
||||||
description: The ports 3x-ui uses by default and ready-made ufw / nftables rules to open them.
|
description: The ports L-UI uses by default and ready-made ufw / nftables rules to open them.
|
||||||
icon: Network
|
icon: Network
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -32,5 +32,5 @@ Your actual inbound ports depend on the inbounds you create.
|
|||||||
|
|
||||||
<Cards>
|
<Cards>
|
||||||
<Card title="Security" href="/docs/operations/security" description="Fail2ban, IP limits, and hardening." />
|
<Card title="Security" href="/docs/operations/security" description="Fail2ban, IP limits, and hardening." />
|
||||||
<Card title="Environment variables" href="/docs/reference/env-vars" description="XUI_PORT and friends." />
|
<Card title="Environment variables" href="/docs/reference/env-vars" description="LUI_PORT and friends." />
|
||||||
</Cards>
|
</Cards>
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
---
|
---
|
||||||
title: کلاینتها
|
title: کلاینتها
|
||||||
description: مدیریت کلاینتهای 3x-ui — اعتبارنامهها، محدودیت ترافیک و انقضا، محدودیت IP، گروهها، اقدامات گروهی، لینکهای خارجی و وضعیت آنلاین.
|
description: مدیریت کلاینتهای L-UI — اعتبارنامهها، محدودیت ترافیک و انقضا، محدودیت IP، گروهها، اقدامات گروهی، لینکهای خارجی و وضعیت آنلاین.
|
||||||
icon: Users
|
icon: Users
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
---
|
---
|
||||||
title: ورودیها و پروتکلها
|
title: ورودیها و پروتکلها
|
||||||
description: ساخت ورودیها در 3x-ui — پروتکلها، انتقالها، بازنشانی و انقضای ترافیک، و fallbackهایی که چند پروتکل را روی یک پورت سرویس میدهند.
|
description: ساخت ورودیها در L-UI — پروتکلها، انتقالها، بازنشانی و انقضای ترافیک، و fallbackهایی که چند پروتکل را روی یک پورت سرویس میدهند.
|
||||||
icon: ArrowDownToLine
|
icon: ArrowDownToLine
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -74,7 +74,7 @@ TLS یا REALITY) را انتخاب کنید. به [انتقالها](/docs/c
|
|||||||
|
|
||||||
Fallbackها به یک پورت TLS واحد (مثلاً `443`) اجازه میدهند بیش از یک پروتکل را
|
Fallbackها به یک پورت TLS واحد (مثلاً `443`) اجازه میدهند بیش از یک پروتکل را
|
||||||
سرویس دهد — برای مثال VLESS **و** Trojan — با هدایت دستدادنهای (handshake)
|
سرویس دهد — برای مثال VLESS **و** Trojan — با هدایت دستدادنهای (handshake)
|
||||||
ناهماهنگ به یک ورودی فرزند. در 3x-ui، fallbackها در پنل مدیریت میشوند (لیست
|
ناهماهنگ به یک ورودی فرزند. در L-UI، fallbackها در پنل مدیریت میشوند (لیست
|
||||||
**Fallbacks** یک ورودی اصلی) بهجای آنکه بهصورت دستی در JSON نوشته شوند.
|
**Fallbacks** یک ورودی اصلی) بهجای آنکه بهصورت دستی در JSON نوشته شوند.
|
||||||
|
|
||||||
Fallbackها تنها زمانی در دسترساند که ورودی اصلی اینگونه باشد:
|
Fallbackها تنها زمانی در دسترساند که ورودی اصلی اینگونه باشد:
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
---
|
---
|
||||||
title: تنظیمات پنل
|
title: تنظیمات پنل
|
||||||
description: تمام تنظیمات پنل 3x-ui — وبسرور، TLS، نمایش، امنیت و اعلانها — همراه با مقادیر پیشفرض برگرفته از سورس.
|
description: تمام تنظیمات پنل L-UI — وبسرور، TLS، نمایش، امنیت و اعلانها — همراه با مقادیر پیشفرض برگرفته از سورس.
|
||||||
icon: SlidersHorizontal
|
icon: SlidersHorizontal
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -14,7 +14,7 @@ icon: SlidersHorizontal
|
|||||||
|
|
||||||
| Setting | Default | Meaning |
|
| Setting | Default | Meaning |
|
||||||
| ------------------- | ----------------------- | ----------------------------------------------------------------------- |
|
| ------------------- | ----------------------- | ----------------------------------------------------------------------- |
|
||||||
| `webPort` | `2053` | پورت پنل (۱ تا ۶۵۵۳۵). متغیر محیطی `XUI_PORT` در زمان اجرا آن را بازنویسی میکند. |
|
| `webPort` | `2053` | پورت پنل (۱ تا ۶۵۵۳۵). متغیر محیطی `LUI_PORT` در زمان اجرا آن را بازنویسی میکند. |
|
||||||
| `webListen` | _(همهی واسطها)_ | پنل را به یک IP مشخص مقید کنید. |
|
| `webListen` | _(همهی واسطها)_ | پنل را به یک IP مشخص مقید کنید. |
|
||||||
| `webBasePath` | `/` | مسیر URLی که پنل زیر آن ارائه میشود (همیشه به شکل `/…/` نرمالسازی میشود). |
|
| `webBasePath` | `/` | مسیر URLی که پنل زیر آن ارائه میشود (همیشه به شکل `/…/` نرمالسازی میشود). |
|
||||||
| `webCertFile` / `webKeyFile` | _(هیچکدام)_ | گواهی + کلید TLS. وقتی هر دو تنظیم شوند، پنل با **HTTPS** ارائه میشود. |
|
| `webCertFile` / `webKeyFile` | _(هیچکدام)_ | گواهی + کلید TLS. وقتی هر دو تنظیم شوند، پنل با **HTTPS** ارائه میشود. |
|
||||||
@@ -24,12 +24,12 @@ icon: SlidersHorizontal
|
|||||||
|
|
||||||
پس از تغییر پورت یا مسیر پایه، آدرس پنل بهصورت
|
پس از تغییر پورت یا مسیر پایه، آدرس پنل بهصورت
|
||||||
`http(s)://<server>:<port><web-base-path>` درمیآید. میتوانید مسیر پایه را در
|
`http(s)://<server>:<port><web-base-path>` درمیآید. میتوانید مسیر پایه را در
|
||||||
نخستین اجرا با [`XUI_INIT_WEB_BASE_PATH`](/docs/reference/env-vars) از پیش تعیین کنید.
|
نخستین اجرا با [`LUI_INIT_WEB_BASE_PATH`](/docs/reference/env-vars) از پیش تعیین کنید.
|
||||||
|
|
||||||
### TLS
|
### TLS
|
||||||
|
|
||||||
ارائهی پنل روی HTTPS از اطلاعات احراز هویت شما در حین انتقال محافظت میکند. یا
|
ارائهی پنل روی HTTPS از اطلاعات احراز هویت شما در حین انتقال محافظت میکند. یا
|
||||||
`webCertFile` + `webKeyFile` را تنظیم کنید — [منوی SSL در `x-ui`](/docs/config/ssl-certificates)
|
`webCertFile` + `webKeyFile` را تنظیم کنید — [منوی SSL در `l-ui`](/docs/config/ssl-certificates)
|
||||||
میتواند یک گواهی Let's Encrypt برای شما تهیه کند — یا TLS را روی یک
|
میتواند یک گواهی Let's Encrypt برای شما تهیه کند — یا TLS را روی یک
|
||||||
[پروکسی معکوس](/docs/operations/reverse-proxy) خاتمه دهید.
|
[پروکسی معکوس](/docs/operations/reverse-proxy) خاتمه دهید.
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
---
|
---
|
||||||
title: REALITY
|
title: REALITY
|
||||||
description: راهاندازی یک ورودی VLESS + REALITY همراه با XTLS-Vision در 3x-ui — کلیدها، short IDها، SNI، اثرانگشتها و اشتباهات رایج.
|
description: راهاندازی یک ورودی VLESS + REALITY همراه با XTLS-Vision در L-UI — کلیدها، short IDها، SNI، اثرانگشتها و اشتباهات رایج.
|
||||||
icon: ShieldCheck
|
icon: ShieldCheck
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -15,7 +15,7 @@ REALITY همراه با **VLESS** (و Trojan) بهکار میرود. جر
|
|||||||
|
|
||||||
## تنظیمات کلیدی
|
## تنظیمات کلیدی
|
||||||
|
|
||||||
وقتی **REALITY** را بهعنوان حالت امنیتی روی یک ورودی VLESS انتخاب میکنید، 3x-ui
|
وقتی **REALITY** را بهعنوان حالت امنیتی روی یک ورودی VLESS انتخاب میکنید، L-UI
|
||||||
این فیلدها را نمایش میدهد:
|
این فیلدها را نمایش میدهد:
|
||||||
|
|
||||||
| فیلد | چیست |
|
| فیلد | چیست |
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
---
|
---
|
||||||
title: لینکهای اشتراکگذاری
|
title: لینکهای اشتراکگذاری
|
||||||
description: قالبهای لینک اشتراکگذاری 3x-ui (vless، vmess، trojan، ss، hysteria2، mtproto)، متغیرهای قالب توضیحات، و بازرس لینک درونمرورگری.
|
description: قالبهای لینک اشتراکگذاری L-UI (vless، vmess، trojan، ss، hysteria2، mtproto)، متغیرهای قالب توضیحات، و بازرس لینک درونمرورگری.
|
||||||
icon: Link
|
icon: Link
|
||||||
---
|
---
|
||||||
|
|
||||||
3x-ui برای هر کلاینت یک **لینک اشتراکگذاری** (و کد QR) تولید میکند. برنامههای کلاینت
|
L-UI برای هر کلاینت یک **لینک اشتراکگذاری** (و کد QR) تولید میکند. برنامههای کلاینت
|
||||||
مانند v2rayNG، Hiddify و Mihomo این لینکها را برای پیکربندی خودشان وارد میکنند.
|
مانند v2rayNG، Hiddify و Mihomo این لینکها را برای پیکربندی خودشان وارد میکنند.
|
||||||
|
|
||||||
## قالبهای لینک
|
## قالبهای لینک
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
---
|
---
|
||||||
title: گواهیهای SSL
|
title: گواهیهای SSL
|
||||||
description: دریافت و تمدید گواهیهای TLS برای پنل و ورودیهای 3x-ui — با منوی ACME در x-ui (دامنه یا IP خام)، گواهی wildcard از طریق Cloudflare DNS-01، یا Certbot دستی.
|
description: دریافت و تمدید گواهیهای TLS برای پنل و ورودیهای L-UI — با منوی ACME در l-ui (دامنه یا IP خام)، گواهی wildcard از طریق Cloudflare DNS-01، یا Certbot دستی.
|
||||||
icon: ShieldCheck
|
icon: ShieldCheck
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -8,7 +8,7 @@ icon: ShieldCheck
|
|||||||
API شما رمزگذاری شود) و TLS را روی **ورودیها** خاتمه دهید (VLESS-TLS، Trojan،
|
API شما رمزگذاری شود) و TLS را روی **ورودیها** خاتمه دهید (VLESS-TLS، Trojan،
|
||||||
Shadowsocks-TLS و موارد مشابه). سه راه برای بهدستآوردن گواهی وجود دارد:
|
Shadowsocks-TLS و موارد مشابه). سه راه برای بهدستآوردن گواهی وجود دارد:
|
||||||
|
|
||||||
- **منوی `x-ui`** — کلاینت داخلی [ACME](https://en.wikipedia.org/wiki/Automatic_Certificate_Management_Environment).
|
- **منوی `l-ui`** — کلاینت داخلی [ACME](https://en.wikipedia.org/wiki/Automatic_Certificate_Management_Environment).
|
||||||
آسانترین گزینه برای یک دامنهی واحد یا یک IP خام.
|
آسانترین گزینه برای یک دامنهی واحد یا یک IP خام.
|
||||||
- **Cloudflare DNS-01** — این هم از همان منو؛ برای گواهیهای **wildcard** یا
|
- **Cloudflare DNS-01** — این هم از همان منو؛ برای گواهیهای **wildcard** یا
|
||||||
زمانی که پورت 80 مسدود است / سرور پشت پراکسی Cloudflare قرار دارد لازم است.
|
زمانی که پورت 80 مسدود است / سرور پشت پراکسی Cloudflare قرار دارد لازم است.
|
||||||
@@ -21,9 +21,9 @@ Shadowsocks-TLS و موارد مشابه). سه راه برای بهدست
|
|||||||
TLS یک سایت واقعی را قرض میگیرند. این صفحه برای پنل و برای ورودیهای کلاسیک TLS است.
|
TLS یک سایت واقعی را قرض میگیرند. این صفحه برای پنل و برای ورودیهای کلاسیک TLS است.
|
||||||
</Callout>
|
</Callout>
|
||||||
|
|
||||||
## منوی SSL در `x-ui` (Let's Encrypt)
|
## منوی SSL در `l-ui` (Let's Encrypt)
|
||||||
|
|
||||||
`x-ui` را اجرا کنید و **`20` — SSL Certificate Management** را انتخاب کنید. این گزینه
|
`l-ui` را اجرا کنید و **`20` — SSL Certificate Management** را انتخاب کنید. این گزینه
|
||||||
[acme.sh](https://github.com/acmesh-official/acme.sh) را به کار میگیرد و موارد زیر را ارائه میدهد:
|
[acme.sh](https://github.com/acmesh-official/acme.sh) را به کار میگیرد و موارد زیر را ارائه میدهد:
|
||||||
|
|
||||||
| گزینه | کاری که انجام میدهد |
|
| گزینه | کاری که انجام میدهد |
|
||||||
@@ -57,7 +57,7 @@ Shadowsocks-TLS و موارد مشابه). سه راه برای بهدست
|
|||||||
<Step>
|
<Step>
|
||||||
### صادرکننده را اجرا کنید
|
### صادرکننده را اجرا کنید
|
||||||
|
|
||||||
`x-ui` ← `20` ← **Get SSL (Domain)**، سپس دامنه را وارد کنید. acme.sh گواهی را
|
`l-ui` ← `20` ← **Get SSL (Domain)**، سپس دامنه را وارد کنید. acme.sh گواهی را
|
||||||
درخواست میکند و آن را زیر `/root/cert/<domain>/` بهصورت `fullchain.pem`
|
درخواست میکند و آن را زیر `/root/cert/<domain>/` بهصورت `fullchain.pem`
|
||||||
(زنجیرهی گواهی) و `privkey.pem` (کلید خصوصی) ذخیره میکند.
|
(زنجیرهی گواهی) و `privkey.pem` (کلید خصوصی) ذخیره میکند.
|
||||||
</Step>
|
</Step>
|
||||||
@@ -104,7 +104,7 @@ DNS دامنهی شما باید توسط Cloudflare مدیریت شود و
|
|||||||
<Step>
|
<Step>
|
||||||
### صادرکنندهی Cloudflare را اجرا کنید
|
### صادرکنندهی Cloudflare را اجرا کنید
|
||||||
|
|
||||||
`x-ui` ← **`21` — Cloudflare SSL Certificate**. هنگام پرسش، **`t`** را برای یک
|
`l-ui` ← **`21` — Cloudflare SSL Certificate**. هنگام پرسش، **`t`** را برای یک
|
||||||
توکن API (پیشفرض) یا **`g`** را برای Global API Key انتخاب کنید، سپس دامنهی خود را
|
توکن API (پیشفرض) یا **`g`** را برای Global API Key انتخاب کنید، سپس دامنهی خود را
|
||||||
وارد کنید (و برای Global API Key، ایمیل حساب و کلید خود را). acme.sh رکورد TXT را
|
وارد کنید (و برای Global API Key، ایمیل حساب و کلید خود را). acme.sh رکورد TXT را
|
||||||
میسازد، اعتبارسنجی میکند و آن را پاکسازی میکند.
|
میسازد، اعتبارسنجی میکند و آن را پاکسازی میکند.
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
---
|
---
|
||||||
title: Subscription
|
title: Subscription
|
||||||
description: راهاندازی سرور اشتراک 3x-ui — قالبهای base64/JSON/Clash، پورتها و مسیرها، TLS، هدرهای پاسخ و قالبهای سفارشی.
|
description: راهاندازی سرور اشتراک L-UI — قالبهای base64/JSON/Clash، پورتها و مسیرها، TLS، هدرهای پاسخ و قالبهای سفارشی.
|
||||||
icon: Rss
|
icon: Rss
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -59,7 +59,7 @@ https://<sub-host>:<sub-port>/sub/<sub-id>
|
|||||||
با standard-base64 رمزگذاری شدهاند (با `subEncrypt` قابل تغییر است). بدنهی **JSON**
|
با standard-base64 رمزگذاری شدهاند (با `subEncrypt` قابل تغییر است). بدنهی **JSON**
|
||||||
هر کلاینت را در یک پیکربندی کامل کلاینت Xray میپیچد — یک اسکلت ثابت (ورودیهای محلی
|
هر کلاینت را در یک پیکربندی کامل کلاینت Xray میپیچد — یک اسکلت ثابت (ورودیهای محلی
|
||||||
mixed/HTTP، DNS، مسیریابی، policy) بهعلاوهی یک outbound از نوع `proxy` که به ورودی
|
mixed/HTTP، DNS، مسیریابی، policy) بهعلاوهی یک outbound از نوع `proxy` که به ورودی
|
||||||
اشاره میکند. 3x-ui **برای یک کلاینت یک شیء پیکربندی واحد و برای چند کلاینت یک آرایه**
|
اشاره میکند. L-UI **برای یک کلاینت یک شیء پیکربندی واحد و برای چند کلاینت یک آرایه**
|
||||||
تولید میکند، از فرم تخت `settings` در outbound استفاده میکند
|
تولید میکند، از فرم تخت `settings` در outbound استفاده میکند
|
||||||
(`address`/`port`/`id`، `level: 8`) و `sockopt` را از `streamSettings` حذف میکند.
|
(`address`/`port`/`id`، `level: 8`) و `sockopt` را از `streamSettings` حذف میکند.
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
---
|
---
|
||||||
title: انتقالها و امنیت
|
title: انتقالها و امنیت
|
||||||
description: هر انتقالی که 3x-ui ارائه میدهد — TCP، mKCP، WebSocket، gRPC، HTTPUpgrade، XHTTP، Hysteria — بههمراه تنظیماتشان، و نیز مبهمسازی FinalMask، sockopt، TLS/REALITY، XTLS-Vision و رمزنگاری VLESS.
|
description: هر انتقالی که L-UI ارائه میدهد — TCP، mKCP، WebSocket، gRPC، HTTPUpgrade، XHTTP، Hysteria — بههمراه تنظیماتشان، و نیز مبهمسازی FinalMask، sockopt، TLS/REALITY، XTLS-Vision و رمزنگاری VLESS.
|
||||||
icon: Network
|
icon: Network
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
---
|
---
|
||||||
title: نخستین ورود
|
title: نخستین ورود
|
||||||
description: مشخصات ورود تولیدشدهٔ 3x-ui را بیابید، به پنل دسترسی پیدا کنید، احراز هویت دومرحلهای را فعال کنید و پیش از در معرض قرار دادن هر چیزی، پنل را ایمنسازی کنید.
|
description: مشخصات ورود تولیدشدهٔ L-UI را بیابید، به پنل دسترسی پیدا کنید، احراز هویت دومرحلهای را فعال کنید و پیش از در معرض قرار دادن هر چیزی، پنل را ایمنسازی کنید.
|
||||||
icon: KeyRound
|
icon: KeyRound
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -24,25 +24,25 @@ http://<your-server-ip>:<port>/<web-base-path>
|
|||||||
نصب با اسکریپت پس از پایان، خلاصهای از مشخصات ورود را چاپ میکند و آن را در یک
|
نصب با اسکریپت پس از پایان، خلاصهای از مشخصات ورود را چاپ میکند و آن را در یک
|
||||||
فایل ویژهٔ root نیز مینویسد:
|
فایل ویژهٔ root نیز مینویسد:
|
||||||
|
|
||||||
```bash title="/etc/x-ui/install-result.env (mode 600)"
|
```bash title="/etc/l-ui/install-result.env (mode 600)"
|
||||||
XUI_USERNAME=...
|
LUI_USERNAME=...
|
||||||
XUI_PASSWORD=...
|
LUI_PASSWORD=...
|
||||||
XUI_PANEL_PORT=...
|
LUI_PANEL_PORT=...
|
||||||
XUI_WEB_BASE_PATH=...
|
LUI_WEB_BASE_PATH=...
|
||||||
XUI_ACCESS_URL=...
|
LUI_ACCESS_URL=...
|
||||||
XUI_API_TOKEN=...
|
LUI_API_TOKEN=...
|
||||||
XUI_DB_TYPE=sqlite
|
LUI_DB_TYPE=sqlite
|
||||||
```
|
```
|
||||||
|
|
||||||
اگر آنها را از دست دادید، از ابزارهای مدیریتی استفاده کنید:
|
اگر آنها را از دست دادید، از ابزارهای مدیریتی استفاده کنید:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
x-ui # menu → 11 (View Current Settings)
|
l-ui # menu → 11 (View Current Settings)
|
||||||
x-ui settings # or the one-shot form
|
l-ui settings # or the one-shot form
|
||||||
```
|
```
|
||||||
|
|
||||||
برای **Docker**، مشخصات ورود تولیدشده را از لاگهای کانتینر بخوانید، یا دستور
|
برای **Docker**، مشخصات ورود تولیدشده را از لاگهای کانتینر بخوانید، یا دستور
|
||||||
`docker exec -it <container> x-ui setting -show` را اجرا کنید.
|
`docker exec -it <container> l-ui setting -show` را اجرا کنید.
|
||||||
|
|
||||||
<Callout type="warn">
|
<Callout type="warn">
|
||||||
اگر پنل شما هنوز از مقادیر پیشفرض `admin` / `admin` استفاده میکند (پنل در این
|
اگر پنل شما هنوز از مقادیر پیشفرض `admin` / `admin` استفاده میکند (پنل در این
|
||||||
@@ -53,7 +53,7 @@ x-ui settings # or the one-shot form
|
|||||||
|
|
||||||
یک پورت غیرپیشفرض و یک **مسیر پایهٔ وب** طولانی و تصادفی، یافتن پنل را بسیار
|
یک پورت غیرپیشفرض و یک **مسیر پایهٔ وب** طولانی و تصادفی، یافتن پنل را بسیار
|
||||||
دشوارتر میکند. آنها را از بخش **Panel Settings** در رابط کاربری، یا از منوی
|
دشوارتر میکند. آنها را از بخش **Panel Settings** در رابط کاربری، یا از منوی
|
||||||
`x-ui` تغییر دهید:
|
`l-ui` تغییر دهید:
|
||||||
|
|
||||||
- **7 — Reset Username & Password** (با امکان غیرفعالسازی همزمان 2FA)
|
- **7 — Reset Username & Password** (با امکان غیرفعالسازی همزمان 2FA)
|
||||||
- **8 — Reset Web Base Path** (آن را تصادفی میکند)
|
- **8 — Reset Web Base Path** (آن را تصادفی میکند)
|
||||||
@@ -64,11 +64,11 @@ x-ui settings # or the one-shot form
|
|||||||
|
|
||||||
## احراز هویت دومرحلهای (2FA)
|
## احراز هویت دومرحلهای (2FA)
|
||||||
|
|
||||||
3x-ui از احراز هویت دومرحلهای TOTP پشتیبانی میکند (سازگار با Google
|
L-UI از احراز هویت دومرحلهای TOTP پشتیبانی میکند (سازگار با Google
|
||||||
Authenticator، Aegis و غیره). آن را در بخش **Panel Settings** فعال کنید — پس از
|
Authenticator، Aegis و غیره). آن را در بخش **Panel Settings** فعال کنید — پس از
|
||||||
فعالسازی، صفحهٔ ورود علاوه بر رمز عبور، یک کد ۶ رقمی نیز درخواست میکند و
|
فعالسازی، صفحهٔ ورود علاوه بر رمز عبور، یک کد ۶ رقمی نیز درخواست میکند و
|
||||||
فعال کردن آن همه را وادار به ورود مجدد میکند. میتوانید آن را از مرحلهٔ **Reset
|
فعال کردن آن همه را وادار به ورود مجدد میکند. میتوانید آن را از مرحلهٔ **Reset
|
||||||
Username & Password** در منو یا با دستور `x-ui setting -resetTwoFactor` غیرفعال
|
Username & Password** در منو یا با دستور `l-ui setting -resetTwoFactor` غیرفعال
|
||||||
کنید.
|
کنید.
|
||||||
|
|
||||||
## محافظت داخلی از ورود
|
## محافظت داخلی از ورود
|
||||||
@@ -106,7 +106,7 @@ Username & Password** در منو یا با دستور `x-ui setting -resetTwoFa
|
|||||||
<Step>
|
<Step>
|
||||||
### پنل را پشت TLS قرار دهید
|
### پنل را پشت TLS قرار دهید
|
||||||
|
|
||||||
از یک گواهی معتبر (از طریق مدیریت SSL در منوی `x-ui` یا یک reverse proxy)
|
از یک گواهی معتبر (از طریق مدیریت SSL در منوی `l-ui` یا یک reverse proxy)
|
||||||
استفاده کنید تا پنل تنها از طریق HTTPS در دسترس باشد.
|
استفاده کنید تا پنل تنها از طریق HTTPS در دسترس باشد.
|
||||||
</Step>
|
</Step>
|
||||||
|
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
---
|
---
|
||||||
title: آشنایی با 3x-ui
|
title: آشنایی با L-UI
|
||||||
description: یک پنل تحت وب برای Xray-core — ورودیها، پروتکلها، کلاینتها و اشتراکها را بهجای ویرایش دستی JSON، از مرورگر خود مدیریت کنید.
|
description: یک پنل تحت وب برای Xray-core — ورودیها، پروتکلها، کلاینتها و اشتراکها را بهجای ویرایش دستی JSON، از مرورگر خود مدیریت کنید.
|
||||||
icon: Info
|
icon: Info
|
||||||
---
|
---
|
||||||
|
|
||||||
**3x-ui** یک پنل کنترل تحت وب است که روی
|
**L-UI** یک پنل کنترل تحت وب است که روی
|
||||||
[Xray-core](https://github.com/XTLS/Xray-core)، همان موتور پروکسی که در واقع
|
[Xray-core](https://github.com/XTLS/Xray-core)، همان موتور پروکسی که در واقع
|
||||||
ترافیک شما را جابهجا میکند، قرار میگیرد. بهجای نوشتن و بارگذاری مجدد پیکربندی
|
ترافیک شما را جابهجا میکند، قرار میگیرد. بهجای نوشتن و بارگذاری مجدد پیکربندی
|
||||||
JSON Xray بهصورت دستی، همهچیز — ورودیها، پروتکلها، کلاینتها، گواهیها،
|
JSON Xray بهصورت دستی، همهچیز — ورودیها، پروتکلها، کلاینتها، گواهیها،
|
||||||
@@ -15,7 +15,7 @@ JSON Xray بهصورت دستی، همهچیز — ورودیها،
|
|||||||
<Mermaid
|
<Mermaid
|
||||||
chart={`
|
chart={`
|
||||||
flowchart LR
|
flowchart LR
|
||||||
Admin["Admin browser"] -->|HTTPS panel| Panel["3x-ui panel"]
|
Admin["Admin browser"] -->|HTTPS panel| Panel["L-UI panel"]
|
||||||
Panel -->|writes config, reloads| Xray["Xray-core"]
|
Panel -->|writes config, reloads| Xray["Xray-core"]
|
||||||
Panel --- DB[("SQLite or PostgreSQL")]
|
Panel --- DB[("SQLite or PostgreSQL")]
|
||||||
Clients["Client apps"] -->|VLESS / VMess / Trojan / ...| Xray
|
Clients["Client apps"] -->|VLESS / VMess / Trojan / ...| Xray
|
||||||
@@ -53,19 +53,19 @@ flowchart LR
|
|||||||
| پایگاهداده | SQLite (پیشفرض) یا PostgreSQL |
|
| پایگاهداده | SQLite (پیشفرض) یا PostgreSQL |
|
||||||
| موتور پروکسی | Xray-core (همراه و مدیریتشده توسط پنل) |
|
| موتور پروکسی | Xray-core (همراه و مدیریتشده توسط پنل) |
|
||||||
|
|
||||||
پایگاهدادهٔ پیشفرض SQLite در مسیر `/etc/x-ui/x-ui.db` قرار دارد و پنل بهصورت
|
پایگاهدادهٔ پیشفرض SQLite در مسیر `/etc/l-ui/l-ui.db` قرار دارد و پنل بهصورت
|
||||||
پیشفرض روی پورت **2053** گوش میدهد. هر دو قابل پیکربندی هستند — به
|
پیشفرض روی پورت **2053** گوش میدهد. هر دو قابل پیکربندی هستند — به
|
||||||
[نخستین ورود](/docs/guide/first-login) و مرجع متغیرهای محیطی مراجعه کنید.
|
[نخستین ورود](/docs/guide/first-login) و مرجع متغیرهای محیطی مراجعه کنید.
|
||||||
|
|
||||||
## برای چه کسانی است
|
## برای چه کسانی است
|
||||||
|
|
||||||
3x-ui برای هر کسی که سرور Xray خودش را اجرا میکند طراحی شده است: از یک
|
L-UI برای هر کسی که سرور Xray خودش را اجرا میکند طراحی شده است: از یک
|
||||||
VPS شخصی منفرد تا اپراتورهایی که نودها و کلاینتهای فراوانی را مدیریت میکنند. اگر
|
VPS شخصی منفرد تا اپراتورهایی که نودها و کلاینتهای فراوانی را مدیریت میکنند. اگر
|
||||||
قدرت Xray-core را میخواهید بدون اینکه در فایلهای پیکربندی JSON زندگی کنید، این
|
قدرت Xray-core را میخواهید بدون اینکه در فایلهای پیکربندی JSON زندگی کنید، این
|
||||||
برای شماست.
|
برای شماست.
|
||||||
|
|
||||||
<Callout type="info">
|
<Callout type="info">
|
||||||
3x-ui یک فورک ارتقایافته از پروژهٔ اصلی X-UI است که پشتیبانی گستردهتری از
|
L-UI یک فورک ارتقایافته از پروژهٔ اصلی X-UI است که پشتیبانی گستردهتری از
|
||||||
پروتکلها، پایداری بهبودیافته، حسابداری ترافیک بهازای هر کلاینت، مدیریت
|
پروتکلها، پایداری بهبودیافته، حسابداری ترافیک بهازای هر کلاینت، مدیریت
|
||||||
چندنودی و بسیاری از قابلیتهای راحتیبخش را اضافه میکند.
|
چندنودی و بسیاری از قابلیتهای راحتیبخش را اضافه میکند.
|
||||||
</Callout>
|
</Callout>
|
||||||
|
|||||||
@@ -1,48 +1,43 @@
|
|||||||
---
|
---
|
||||||
title: نصب
|
title: نصب
|
||||||
description: نصب 3x-ui با اسکریپت رسمی (نسخهٔ پایدار، نسخهٔ مشخص یا dev-latest)، نصب خودکار/cloud-init یا Docker — و انتخاب میان SQLite و PostgreSQL.
|
description: نصب L-UI با اسکریپت رسمی (پنل، عامل گره یا نسخهٔ مشخص)، نصب خودکار/cloud-init یا Docker — و انتخاب میان SQLite و PostgreSQL.
|
||||||
icon: Download
|
icon: Download
|
||||||
---
|
---
|
||||||
|
|
||||||
3x-ui روی طیف گستردهای از توزیعهای Linux اجرا میشود — Ubuntu، Debian، Armbian،
|
L-UI روی طیف گستردهای از توزیعهای Linux اجرا میشود — Ubuntu، Debian، Armbian،
|
||||||
Fedora، CentOS، RHEL، AlmaLinux، Rocky Linux، Oracle Linux، Amazon Linux،
|
Fedora، CentOS، RHEL، AlmaLinux، Rocky Linux، Oracle Linux، Amazon Linux،
|
||||||
Virtuozzo، Arch، Manjaro، openSUSE (Tumbleweed/Leap)، Alpine — و همچنین Windows،
|
Virtuozzo، Arch، Manjaro، openSUSE (Tumbleweed/Leap)، Alpine — و همچنین Windows،
|
||||||
روی معماریهای `amd64`، `386`، `arm64`، `armv7`، `armv6`، `armv5` و `s390x`.
|
روی معماریهای `amd64` و `arm64`.
|
||||||
|
|
||||||
<Callout type="warn">
|
<Callout type="warn">
|
||||||
نصبکنندهٔ اسکریپتی را بهصورت **root** (یا با `sudo`) اجرا کنید. این اسکریپت یک
|
نصبکنندهٔ اسکریپتی را بهصورت **root** (یا با `sudo`) اجرا کنید. اسکریپتهای یککلیکه فقط از `amd64`/`arm64` پشتیبانی میکنند.
|
||||||
سرویس نصب میکند، دستور مدیریتی `x-ui` را راهاندازی میکند و پنل را در زمان
|
|
||||||
بوت فعال میسازد.
|
|
||||||
</Callout>
|
</Callout>
|
||||||
|
|
||||||
<Tabs items={['Script', 'Docker', 'Manual']}>
|
<Tabs items={['Script', 'Docker', 'Manual']}>
|
||||||
|
|
||||||
<Tab value="Script">
|
<Tab value="Script">
|
||||||
|
|
||||||
اسکریپت رسمی مسیر توصیهشده است. این اسکریپت در طول نصب یک نام کاربری، رمز عبور و
|
اسکریپت رسمی مسیر توصیهشده است. نصب یککلیکهٔ پنل:
|
||||||
مسیر دسترسی (مسیر پایهٔ وب) **تصادفی** تولید میکند، سرویس را راهاندازی میکند و
|
|
||||||
دستور مدیریتی `x-ui` را نصب میکند.
|
|
||||||
|
|
||||||
```bash title="latest stable"
|
```bash title="پنل"
|
||||||
bash <(curl -Ls https://raw.githubusercontent.com/mhsanaei/3x-ui/master/install.sh)
|
bash <(curl -Ls https://git.881218.xyz/rogue/l-ui/raw/branch/main/install-master.sh)
|
||||||
```
|
```
|
||||||
|
|
||||||
برای نصب یک **نسخهٔ مشخص**، تگ آن را در انتها اضافه کنید:
|
این اسکریپت باینری پنل، xray و فایلهای geo را از Releases همین مخزن (Gitea) دانلود و پنل را اجرا میکند (درگاه پیشفرض 2053). با حساب پیشفرض `admin` / `admin` وارد شوید و بلافاصله رمز عبور را تغییر دهید.
|
||||||
|
|
||||||
```bash title="pinned version"
|
نصب عامل گره: نخست گره را در پنل بسازید — پنل دستور نصب همراه با توکن ثبت را تولید میکند؛ آن را بهصورت root روی گره اجرا کنید، برای نمونه:
|
||||||
bash <(curl -Ls https://raw.githubusercontent.com/mhsanaei/3x-ui/master/install.sh) v3.4.0
|
|
||||||
|
```bash title="عامل گره"
|
||||||
|
bash <(curl -fL https://git.881218.xyz/rogue/l-ui/raw/branch/main/install-agent.sh) --master http://MASTER:2053 --token <token> --name <node-name>
|
||||||
```
|
```
|
||||||
|
|
||||||
برای نصب نسخهٔ **dev** غلتان (آخرین پیشانتشار بهازای هر کامیت از شاخهٔ `main`
|
برای نصب یک نسخهٔ مشخص از پنل، اسکریپت همان تگ را بگیرید (نشانی دانلود پیشفرض اسکریپت همان نسخه است)، برای نمونه:
|
||||||
— نه یک نسخهٔ پایدار) عبارت `dev-latest` را پاس دهید:
|
|
||||||
|
|
||||||
```bash title="rolling dev build"
|
```bash title="نسخهٔ مشخص"
|
||||||
bash <(curl -Ls https://raw.githubusercontent.com/mhsanaei/3x-ui/master/install.sh) dev-latest
|
bash <(curl -Ls https://git.881218.xyz/rogue/l-ui/raw/tag/V2.7.5/install-master.sh)
|
||||||
```
|
```
|
||||||
|
|
||||||
پس از پایان نصب، مشخصات ورود چاپشده را یادداشت کنید و دستور `x-ui` را اجرا کنید تا
|
نصب یککلیکهٔ کانال dev وجود ندارد؛ اسکریپت شاخهٔ main همان آخرین انتشار است.
|
||||||
[منوی مدیریت](/docs/guide/update-uninstall#the-x-ui-management-menu) باز شود، سپس
|
|
||||||
به [نخستین ورود](/docs/guide/first-login) ادامه دهید.
|
|
||||||
|
|
||||||
</Tab>
|
</Tab>
|
||||||
|
|
||||||
@@ -55,41 +50,24 @@ bash <(curl -Ls https://raw.githubusercontent.com/mhsanaei/3x-ui/master/install.
|
|||||||
docker compose up -d
|
docker compose up -d
|
||||||
```
|
```
|
||||||
|
|
||||||
برای اجرا با سرویس **PostgreSQL** همراه، دو خط `XUI_DB_*` را در
|
برای اجرا با سرویس **PostgreSQL** همراه، دو خط `LUI_DB_*` را در
|
||||||
`docker-compose.yml` از حالت کامنت خارج کنید و با پروفایل مربوطه اجرا کنید:
|
`docker-compose.yml` از حالت کامنت خارج کنید و با پروفایل مربوطه اجرا کنید:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
docker compose --profile postgres up -d
|
docker compose --profile postgres up -d
|
||||||
```
|
```
|
||||||
|
|
||||||
ترجیح میدهید از ایمیج ازپیشساخته استفاده کنید؟ این ایمیج روی GitHub Container Registry
|
برای این فورک ایمیج ازپیشساختهای منتشر نمیشود — مانند بالا بهصورت محلی بسازید. ایمیج ساختهشدهٔ محلی نیز Fail2ban را بههمراه دارد (برای [محدودیتهای IP](/docs/operations/security))؛ مسدودسازی آن از طریق `iptables` انجام میشود و به `NET_ADMIN` (و `NET_RAW` برای IPv6) نیاز دارد — فایل Compose هر دو را شامل میشود؛ در غیر این صورت مسدودسازیها فقط ثبت میشوند ولی هرگز اعمال نمیشوند.
|
||||||
منتشر شده است. این ایمیج Fail2ban را بههمراه دارد (برای [محدودیتهای IP](/docs/operations/security))
|
|
||||||
که با `iptables` مسدودسازی انجام میدهد و بنابراین به `NET_ADMIN` (و `NET_RAW` برای IPv6)
|
|
||||||
نیاز دارد — در غیر این صورت مسدودسازیها فقط ثبت میشوند ولی هرگز اعمال نمیشوند:
|
|
||||||
|
|
||||||
```bash title="docker run"
|
والیوم `db/` پایگاهدادهٔ SQLite (`/etc/l-ui/l-ui.db`) را نگه میدارد و `cert/`
|
||||||
docker run -d \
|
|
||||||
--cap-add=NET_ADMIN \
|
|
||||||
--cap-add=NET_RAW \
|
|
||||||
-e XUI_ENABLE_FAIL2BAN=true \
|
|
||||||
-v $PWD/db/:/etc/x-ui/ \
|
|
||||||
-v $PWD/cert/:/root/cert/ \
|
|
||||||
--network=host \
|
|
||||||
--restart=unless-stopped \
|
|
||||||
--name 3x-ui \
|
|
||||||
ghcr.io/mhsanaei/3x-ui:latest
|
|
||||||
```
|
|
||||||
|
|
||||||
والیوم `db/` پایگاهدادهٔ SQLite (`/etc/x-ui/x-ui.db`) را نگه میدارد و `cert/`
|
|
||||||
گواهیهای TLS را، بنابراین دادههای شما در ارتقاها حفظ میشوند.
|
گواهیهای TLS را، بنابراین دادههای شما در ارتقاها حفظ میشوند.
|
||||||
|
|
||||||
</Tab>
|
</Tab>
|
||||||
|
|
||||||
<Tab value="Manual">
|
<Tab value="Manual">
|
||||||
|
|
||||||
برای کاربران پیشرفته، یک آرشیو انتشار متناسب با معماری خود را از
|
برای کاربران پیشرفته، یک باینری انتشار متناسب با معماری خود را از
|
||||||
[صفحهٔ releases](https://github.com/MHSanaei/3x-ui/releases) دانلود کنید، آن را
|
[صفحهٔ releases](https://git.881218.xyz/rogue/l-ui/releases) دانلود کنید (`l-ui-linux-amd64` یا `l-ui-linux-arm64`)، آن را در مسیر `/usr/local/l-ui/l-ui` قرار دهید و طبق README ریشهٔ مخزن آن را بهعنوان یک سرویس systemd اجرا کنید. اسکریپت نصب دقیقاً
|
||||||
استخراج کنید و باینری را بهعنوان یک سرویس systemd اجرا کنید. اسکریپت نصب دقیقاً
|
|
||||||
همین مراحل را خودکار میکند، بنابراین مگر اینکه دلیل خاصی برای نصب دستی داشته
|
همین مراحل را خودکار میکند، بنابراین مگر اینکه دلیل خاصی برای نصب دستی داشته
|
||||||
باشید، روش اسکریپتی ترجیح داده میشود.
|
باشید، روش اسکریپتی ترجیح داده میشود.
|
||||||
|
|
||||||
@@ -107,7 +85,7 @@ docker run -d \
|
|||||||
|
|
||||||
شما بکاند ذخیرهسازی را در زمان نصب انتخاب میکنید:
|
شما بکاند ذخیرهسازی را در زمان نصب انتخاب میکنید:
|
||||||
|
|
||||||
- **SQLite** (پیشفرض) — یک فایل واحد در مسیر `/etc/x-ui/x-ui.db`. بدون نیاز به هیچ تنظیماتی.
|
- **SQLite** (پیشفرض) — یک فایل واحد در مسیر `/etc/l-ui/l-ui.db`. بدون نیاز به هیچ تنظیماتی.
|
||||||
- **PostgreSQL** — برای تعداد کلاینت بالا یا پیکربندیهای چندنودی. نصبکننده
|
- **PostgreSQL** — برای تعداد کلاینت بالا یا پیکربندیهای چندنودی. نصبکننده
|
||||||
میتواند آن را بهصورت محلی نصب کند یا از یک DSN که شما ارائه میدهید استفاده کند.
|
میتواند آن را بهصورت محلی نصب کند یا از یک DSN که شما ارائه میدهید استفاده کند.
|
||||||
|
|
||||||
@@ -116,18 +94,7 @@ docker run -d \
|
|||||||
|
|
||||||
## نصب خودکار / cloud-init
|
## نصب خودکار / cloud-init
|
||||||
|
|
||||||
نصبکننده برای خودکارسازی بهصورت **غیرتعاملی** نیز اجرا میشود.
|
خود اسکریپت نصب هیچ ورودی تعاملی نمیگیرد و میتوان آن را مستقیماً برای خودکارسازی به کار برد. دایرکتوری [`deploy/cloud-init/`](https://git.881218.xyz/rogue/l-ui/src/branch/main/deploy/cloud-init) در مخزن، یک user-data آمادهٔ **cloud-init** برای نصبهای خودکار روی هر ابری (Hetzner، AWS، DigitalOcean، Vultr، GCP، Azure، Oracle) دارد.
|
||||||
`XUI_NONINTERACTIVE=1` را تنظیم کنید (یا بدون TTY اجرا کنید) تا نصب بهصورت
|
|
||||||
سرتاسری و بدون هیچ پرسشی انجام شود، مشخصات تصادفی تولید کند و آنها را در
|
|
||||||
`/etc/x-ui/install-result.env` بنویسد:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
XUI_NONINTERACTIVE=1 bash <(curl -Ls https://raw.githubusercontent.com/mhsanaei/3x-ui/master/install.sh)
|
|
||||||
```
|
|
||||||
|
|
||||||
دایرکتوری [`deploy/`](https://github.com/MHSanaei/3x-ui/tree/main/deploy) در مخزن
|
|
||||||
یک user-data آمادهٔ **cloud-init** برای نصبهای خودکار روی هر ابری (Hetzner، AWS،
|
|
||||||
DigitalOcean، Vultr، GCP، Azure، Oracle) دارد.
|
|
||||||
|
|
||||||
## گامهای بعدی
|
## گامهای بعدی
|
||||||
|
|
||||||
@@ -140,7 +107,7 @@ DigitalOcean، Vultr، GCP، Azure، Oracle) دارد.
|
|||||||
<Card
|
<Card
|
||||||
title="بهروزرسانی و حذف نصب"
|
title="بهروزرسانی و حذف نصب"
|
||||||
href="/docs/guide/update-uninstall"
|
href="/docs/guide/update-uninstall"
|
||||||
description="منوی x-ui، بهروزرسانیها و حذف."
|
description="منوی l-ui، بهروزرسانیها و حذف."
|
||||||
/>
|
/>
|
||||||
<Card
|
<Card
|
||||||
title="REALITY"
|
title="REALITY"
|
||||||
|
|||||||
@@ -1,17 +1,17 @@
|
|||||||
---
|
---
|
||||||
title: بهروزرسانی و حذف
|
title: بهروزرسانی و حذف
|
||||||
description: مدیریت 3x-ui با منوی x-ui و خط فرمان — بهروزرسانی (پایدار، dev یا نسخههای قدیمی)، تغییر تنظیمات و حذف تمیز و کامل.
|
description: مدیریت L-UI با منوی l-ui و خط فرمان — بهروزرسانی (پایدار، dev یا نسخههای قدیمی)، تغییر تنظیمات و حذف تمیز و کامل.
|
||||||
icon: RefreshCw
|
icon: RefreshCw
|
||||||
---
|
---
|
||||||
|
|
||||||
پس از نصب با اسکریپت، دستور `x-ui` مرکز کنترل شماست. آن را بدون هیچ آرگومانی اجرا
|
پس از نصب با اسکریپت، دستور `l-ui` مرکز کنترل شماست. آن را بدون هیچ آرگومانی اجرا
|
||||||
کنید تا منوی تعاملی باز شود، یا یک زیردستور به آن بدهید تا یک عملیات تکمرحلهای انجام شود.
|
کنید تا منوی تعاملی باز شود، یا یک زیردستور به آن بدهید تا یک عملیات تکمرحلهای انجام شود.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
x-ui
|
l-ui
|
||||||
```
|
```
|
||||||
|
|
||||||
## منوی مدیریت `x-ui`
|
## منوی مدیریت `l-ui`
|
||||||
|
|
||||||
منو (آیتمهای `0`–`28`) وضعیت پنل/Xray را در بالا نشان میدهد و سپس:
|
منو (آیتمهای `0`–`28`) وضعیت پنل/Xray را در بالا نشان میدهد و سپس:
|
||||||
|
|
||||||
@@ -20,9 +20,9 @@ x-ui
|
|||||||
| 1 | Install | (دوباره) نصب از روی اسکریپت راه دور |
|
| 1 | Install | (دوباره) نصب از روی اسکریپت راه دور |
|
||||||
| 2 | Update | بهروزرسانی به آخرین نسخهٔ **پایدار** |
|
| 2 | Update | بهروزرسانی به آخرین نسخهٔ **پایدار** |
|
||||||
| 3 | Update to Dev Channel (latest commit) | بهروزرسانی به بیلد غلتان `dev-latest` |
|
| 3 | Update to Dev Channel (latest commit) | بهروزرسانی به بیلد غلتان `dev-latest` |
|
||||||
| 4 | Update Menu | بهروزرسانی فقط اسکریپت منوی `x-ui` |
|
| 4 | Update Menu | بهروزرسانی فقط اسکریپت منوی `l-ui` |
|
||||||
| 5 | Legacy Version | نصب یک نسخهٔ قدیمی مشخص (تگ را میپرسد) |
|
| 5 | Legacy Version | نصب یک نسخهٔ قدیمی مشخص (تگ را میپرسد) |
|
||||||
| 6 | Uninstall | حذف 3x-ui (در ادامه ببینید) |
|
| 6 | Uninstall | حذف L-UI (در ادامه ببینید) |
|
||||||
| 7 | Reset Username & Password | تنظیم مشخصات جدید؛ اختیاراً غیرفعالکردن 2FA |
|
| 7 | Reset Username & Password | تنظیم مشخصات جدید؛ اختیاراً غیرفعالکردن 2FA |
|
||||||
| 8 | Reset Web Base Path | تصادفیکردن مسیر پایهٔ وب |
|
| 8 | Reset Web Base Path | تصادفیکردن مسیر پایهٔ وب |
|
||||||
| 9 | Reset Settings | بازنشانی تنظیمات پنل (حساب شما حفظ میشود) |
|
| 9 | Reset Settings | بازنشانی تنظیمات پنل (حساب شما حفظ میشود) |
|
||||||
@@ -51,29 +51,29 @@ x-ui
|
|||||||
|
|
||||||
## زیردستورهای خط فرمان
|
## زیردستورهای خط فرمان
|
||||||
|
|
||||||
برای اسکریپتها و اقدامهای سریع، `x-ui` یک زیردستور را هم مستقیماً میپذیرد:
|
برای اسکریپتها و اقدامهای سریع، `l-ui` یک زیردستور را هم مستقیماً میپذیرد:
|
||||||
|
|
||||||
| دستور | عملیات |
|
| دستور | عملیات |
|
||||||
| -------------------------- | --------------------------------------------------- |
|
| -------------------------- | --------------------------------------------------- |
|
||||||
| `x-ui start` / `stop` / `restart` | کنترل سرویس |
|
| `l-ui start` / `stop` / `restart` | کنترل سرویس |
|
||||||
| `x-ui restart-xray` | بارگذاری مجدد فقط Xray-core |
|
| `l-ui restart-xray` | بارگذاری مجدد فقط Xray-core |
|
||||||
| `x-ui status` | نمایش وضعیت |
|
| `l-ui status` | نمایش وضعیت |
|
||||||
| `x-ui settings` | نمایش تنظیمات فعلی |
|
| `l-ui settings` | نمایش تنظیمات فعلی |
|
||||||
| `x-ui enable` / `disable` | فعال/غیرفعالکردن اجرای خودکار در زمان بوت |
|
| `l-ui enable` / `disable` | فعال/غیرفعالکردن اجرای خودکار در زمان بوت |
|
||||||
| `x-ui log` | دنبالکردن لاگ دیباگ |
|
| `l-ui log` | دنبالکردن لاگ دیباگ |
|
||||||
| `x-ui banlog` | نمایش لاگ مسدودسازی Fail2ban |
|
| `l-ui banlog` | نمایش لاگ مسدودسازی Fail2ban |
|
||||||
| `x-ui update` | بهروزرسانی به آخرین نسخهٔ پایدار |
|
| `l-ui update` | بهروزرسانی به آخرین نسخهٔ پایدار |
|
||||||
| `x-ui update-dev` | بهروزرسانی به بیلد غلتان `dev-latest` |
|
| `l-ui update-dev` | بهروزرسانی به بیلد غلتان `dev-latest` |
|
||||||
| `x-ui legacy` | نصب یک نسخهٔ قدیمی مشخص (میپرسد) |
|
| `l-ui legacy` | نصب یک نسخهٔ قدیمی مشخص (میپرسد) |
|
||||||
| `x-ui update-all-geofiles` | بهروزرسانی همهٔ فایلهای geo و راهاندازی مجدد در صورت تغییر |
|
| `l-ui update-all-geofiles` | بهروزرسانی همهٔ فایلهای geo و راهاندازی مجدد در صورت تغییر |
|
||||||
| `x-ui migrate-db --dsn …` | مهاجرت SQLite ← PostgreSQL (نگاه کنید به [پایگاهداده](/docs/reference/database)) |
|
| `l-ui migrate-db --dsn …` | مهاجرت SQLite ← PostgreSQL (نگاه کنید به [پایگاهداده](/docs/reference/database)) |
|
||||||
| `x-ui install` / `uninstall` | نصب / حذف |
|
| `l-ui install` / `uninstall` | نصب / حذف |
|
||||||
|
|
||||||
## بهروزرسانی
|
## بهروزرسانی
|
||||||
|
|
||||||
- **پایدار:** گزینهٔ منوی **۲** یا `x-ui update`. اجرای دوبارهٔ اسکریپت نصب هم
|
- **پایدار:** گزینهٔ منوی **۲** یا `l-ui update`. اجرای دوبارهٔ اسکریپت نصب هم
|
||||||
در همان محل بهروزرسانی میکند.
|
در همان محل بهروزرسانی میکند.
|
||||||
- **کانال dev:** گزینهٔ منوی **۳** یا `x-ui update-dev` — بیلد غلتان
|
- **کانال dev:** گزینهٔ منوی **۳** یا `l-ui update-dev` — بیلد غلتان
|
||||||
`dev-latest` بهازای هر کامیت (نه یک نسخهٔ پایدار).
|
`dev-latest` بهازای هر کامیت (نه یک نسخهٔ پایدار).
|
||||||
- **یک نسخهٔ قدیمی مشخص:** گزینهٔ منوی **۵** (Legacy Version).
|
- **یک نسخهٔ قدیمی مشخص:** گزینهٔ منوی **۵** (Legacy Version).
|
||||||
|
|
||||||
@@ -82,18 +82,18 @@ x-ui
|
|||||||
|
|
||||||
<Callout type="info">
|
<Callout type="info">
|
||||||
کاربران Docker به شیوهٔ دیگری بهروزرسانی میکنند — بهجای استفاده از دستورهای
|
کاربران Docker به شیوهٔ دیگری بهروزرسانی میکنند — بهجای استفاده از دستورهای
|
||||||
بهروزرسانی `x-ui`، ایمیج جدید را pull کرده و کانتینر را از نو بسازید
|
بهروزرسانی `l-ui`، ایمیج جدید را pull کرده و کانتینر را از نو بسازید
|
||||||
(`docker compose pull && docker compose up -d`).
|
(`docker compose pull && docker compose up -d`).
|
||||||
</Callout>
|
</Callout>
|
||||||
|
|
||||||
## حذف
|
## حذف
|
||||||
|
|
||||||
گزینهٔ منوی **۶** یا `x-ui uninstall`. سرویس را متوقف و غیرفعال میکند، یونیت سرویس
|
گزینهٔ منوی **۶** یا `l-ui uninstall`. سرویس را متوقف و غیرفعال میکند، یونیت سرویس
|
||||||
را حذف میکند و `/etc/x-ui/` و پوشهٔ نصب را پاک میکند. اگر پنل از یک PostgreSQL
|
را حذف میکند و `/etc/l-ui/` و پوشهٔ نصب را پاک میکند. اگر پنل از یک PostgreSQL
|
||||||
نصبشده بهصورت محلی استفاده میکرده، پیشنهاد میدهد آن را هم پاکسازی کند (یک تأیید
|
نصبشده بهصورت محلی استفاده میکرده، پیشنهاد میدهد آن را هم پاکسازی کند (یک تأیید
|
||||||
جداگانه و برگشتناپذیر).
|
جداگانه و برگشتناپذیر).
|
||||||
|
|
||||||
<Callout type="warn">
|
<Callout type="warn">
|
||||||
حذف، پایگاهداده (`/etc/x-ui/x-ui.db`) و پیکربندی شما را پاک میکند. اگر ممکن است
|
حذف، پایگاهداده (`/etc/l-ui/l-ui.db`) و پیکربندی شما را پاک میکند. اگر ممکن است
|
||||||
بعداً به آن نیاز داشته باشید، ابتدا [پشتیبان بگیرید](/docs/operations/backup-restore).
|
بعداً به آن نیاز داشته باشید، ابتدا [پشتیبان بگیرید](/docs/operations/backup-restore).
|
||||||
</Callout>
|
</Callout>
|
||||||
|
|||||||
@@ -1,28 +1,28 @@
|
|||||||
---
|
---
|
||||||
title: مشارکت
|
title: مشارکت
|
||||||
description: چگونه در توسعه 3x-ui مشارکت کنید و این مستندات را ترجمه کنید.
|
description: چگونه در توسعه L-UI مشارکت کنید و این مستندات را ترجمه کنید.
|
||||||
icon: GitPullRequestArrow
|
icon: GitPullRequestArrow
|
||||||
---
|
---
|
||||||
|
|
||||||
3x-ui یک پروژه جامعهمحور است. مشارکت در پنل و در این مستندات با آغوش باز پذیرفته
|
L-UI یک پروژه جامعهمحور است. مشارکت در پنل و در این مستندات با آغوش باز پذیرفته
|
||||||
میشود.
|
میشود.
|
||||||
|
|
||||||
## حمایت از توسعهدهنده
|
## حمایت از توسعهدهنده
|
||||||
|
|
||||||
3x-ui رایگان و متنباز است و بهصورت عمومی ساخته و نگهداری میشود. اگر برایتان
|
L-UI رایگان و متنباز است و بهصورت عمومی ساخته و نگهداری میشود. اگر برایتان
|
||||||
مفید بوده است، حمایت از ادامه توسعه را در نظر بگیرید:
|
مفید بوده است، حمایت از ادامه توسعه را در نظر بگیرید:
|
||||||
|
|
||||||
- در [donate.sanaei.dev](https://donate.sanaei.dev/) **کمک مالی** کنید — این صفحه
|
- در [donate.sanaei.dev](https://donate.sanaei.dev/) **کمک مالی** کنید — این صفحه
|
||||||
**اهداف و سقفهای** جاری تأمین مالی را که میتوانید در رسیدن به آنها کمک کنید نشان میدهد.
|
**اهداف و سقفهای** جاری تأمین مالی را که میتوانید در رسیدن به آنها کمک کنید نشان میدهد.
|
||||||
- به [مخزن](https://github.com/MHSanaei/3x-ui) **ستاره** بدهید و پروژه را به اشتراک
|
- به [مخزن](https://github.com/MHSanaei/L-UI) **ستاره** بدهید و پروژه را به اشتراک
|
||||||
بگذارید.
|
بگذارید.
|
||||||
- به کانال Telegram یعنی [@XrayUI](https://t.me/XrayUI) **بپیوندید** تا اخبار را
|
- به کانال Telegram یعنی [@XrayUI](https://t.me/XrayUI) **بپیوندید** تا اخبار را
|
||||||
دنبال کنید و به دیگران کمک کنید.
|
دنبال کنید و به دیگران کمک کنید.
|
||||||
|
|
||||||
## مشارکت در 3x-ui
|
## مشارکت در L-UI
|
||||||
|
|
||||||
- فایل `CONTRIBUTING.md` پروژه را در
|
- فایل `CONTRIBUTING.md` پروژه را در
|
||||||
[مخزن](https://github.com/MHSanaei/3x-ui) بخوانید.
|
[مخزن](https://github.com/MHSanaei/L-UI) بخوانید.
|
||||||
- برای باگها و درخواستهای امکانات جدید، با گامهای بازتولید روشن، issue باز کنید.
|
- برای باگها و درخواستهای امکانات جدید، با گامهای بازتولید روشن، issue باز کنید.
|
||||||
- از Conventional Commits استفاده کنید و pull requestها را متمرکز نگه دارید.
|
- از Conventional Commits استفاده کنید و pull requestها را متمرکز نگه دارید.
|
||||||
|
|
||||||
|
|||||||
@@ -1,13 +1,13 @@
|
|||||||
---
|
---
|
||||||
title: سؤالات متداول
|
title: سؤالات متداول
|
||||||
description: پرسشهای پرتکرار درباره 3x-ui — مجوز، سیستمهای پشتیبانیشده، پایگاههای داده و کلاینتها.
|
description: پرسشهای پرتکرار درباره L-UI — مجوز، سیستمهای پشتیبانیشده، پایگاههای داده و کلاینتها.
|
||||||
icon: CircleQuestionMark
|
icon: CircleQuestionMark
|
||||||
---
|
---
|
||||||
|
|
||||||
## آیا 3x-ui رایگان و متنباز است؟
|
## آیا L-UI رایگان و متنباز است؟
|
||||||
|
|
||||||
بله. 3x-ui تحت مجوز GPL-3.0 متنباز است. کد منبع آن روی
|
بله. L-UI تحت مجوز GPL-3.0 متنباز است. کد منبع آن روی
|
||||||
[GitHub](https://github.com/MHSanaei/3x-ui) در دسترس است.
|
[GitHub](https://github.com/MHSanaei/L-UI) در دسترس است.
|
||||||
|
|
||||||
## روی چه سیستمهایی اجرا میشود؟
|
## روی چه سیستمهایی اجرا میشود؟
|
||||||
|
|
||||||
@@ -18,7 +18,7 @@ Fedora، Arch، Alpine و موارد دیگر) روی معماریهای `amd
|
|||||||
## SQLite یا PostgreSQL؟
|
## SQLite یا PostgreSQL؟
|
||||||
|
|
||||||
SQLite گزینه پیشفرض است و برای بیشتر استقرارها مناسب است. PostgreSQL برای
|
SQLite گزینه پیشفرض است و برای بیشتر استقرارها مناسب است. PostgreSQL برای
|
||||||
راهاندازیهای بزرگتر از طریق `XUI_DB_TYPE=postgres` و `XUI_DB_DSN` در دسترس است — به
|
راهاندازیهای بزرگتر از طریق `LUI_DB_TYPE=postgres` و `LUI_DB_DSN` در دسترس است — به
|
||||||
[متغیرهای محیطی](/docs/reference/env-vars) مراجعه کنید.
|
[متغیرهای محیطی](/docs/reference/env-vars) مراجعه کنید.
|
||||||
|
|
||||||
## کدام اپلیکیشنهای کلاینت با آن کار میکنند؟
|
## کدام اپلیکیشنهای کلاینت با آن کار میکنند؟
|
||||||
@@ -27,9 +27,9 @@ SQLite گزینه پیشفرض است و برای بیشتر استقراره
|
|||||||
لینک اشتراکگذاری یا کد QR یک کلاینت را وارد کنید، یا از
|
لینک اشتراکگذاری یا کد QR یک کلاینت را وارد کنید، یا از
|
||||||
[سابسکریپشن](/docs/config/subscription) استفاده کنید.
|
[سابسکریپشن](/docs/config/subscription) استفاده کنید.
|
||||||
|
|
||||||
## 3x-ui چه تفاوتی با x-ui دارد؟
|
## L-UI چه تفاوتی با l-ui دارد؟
|
||||||
|
|
||||||
3x-ui یک فورک ارتقایافته از پروژه اصلی X-UI است. این پروژه پشتیبانی گستردهتری از
|
L-UI یک فورک ارتقایافته از پروژه اصلی X-UI است. این پروژه پشتیبانی گستردهتری از
|
||||||
پروتکلها، پایداری بهبودیافته، حسابداری ترافیک بهازای هر کلاینت، مدیریت چندنودی،
|
پروتکلها، پایداری بهبودیافته، حسابداری ترافیک بهازای هر کلاینت، مدیریت چندنودی،
|
||||||
یک رابط کاربری ۱۳ زبانه و بسیاری از امکانات رفاهی را اضافه میکند.
|
یک رابط کاربری ۱۳ زبانه و بسیاری از امکانات رفاهی را اضافه میکند.
|
||||||
|
|
||||||
@@ -37,11 +37,11 @@ SQLite گزینه پیشفرض است و برای بیشتر استقراره
|
|||||||
|
|
||||||
اسکریپت نصب را دوباره اجرا کنید (بهصورت درجا بهروزرسانی میشود)، یا ایمیج جدید Docker را دریافت کنید.
|
اسکریپت نصب را دوباره اجرا کنید (بهصورت درجا بهروزرسانی میشود)، یا ایمیج جدید Docker را دریافت کنید.
|
||||||
به [نصب](/docs/guide/installation) و
|
به [نصب](/docs/guide/installation) و
|
||||||
[صفحه نسخهها](https://github.com/MHSanaei/3x-ui/releases) مراجعه کنید.
|
[صفحه نسخهها](https://github.com/MHSanaei/L-UI/releases) مراجعه کنید.
|
||||||
|
|
||||||
## از کجا میتوانم کمک بگیرم؟
|
## از کجا میتوانم کمک بگیرم؟
|
||||||
|
|
||||||
به کانال رسمی Telegram با نشانی [@XrayUI](https://t.me/XrayUI) برای
|
به کانال رسمی Telegram با نشانی [@XrayUI](https://t.me/XrayUI) برای
|
||||||
اطلاعیهها و پشتیبانی انجمن بپیوندید، یا یک ایشو روی
|
اطلاعیهها و پشتیبانی انجمن بپیوندید، یا یک ایشو روی
|
||||||
[GitHub](https://github.com/MHSanaei/3x-ui/issues) باز کنید. برای مشکلات رایج، با
|
[GitHub](https://github.com/MHSanaei/L-UI/issues) باز کنید. برای مشکلات رایج، با
|
||||||
[عیبیابی](/docs/help/troubleshooting) شروع کنید.
|
[عیبیابی](/docs/help/troubleshooting) شروع کنید.
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
---
|
---
|
||||||
title: مهاجرت
|
title: مهاجرت
|
||||||
description: مهاجرت به 3x-ui از x-ui، بین سرورها یا بین نسخههای 3x-ui.
|
description: مهاجرت به L-UI از l-ui، بین سرورها یا بین نسخههای L-UI.
|
||||||
icon: ArrowRightLeft
|
icon: ArrowRightLeft
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -13,12 +13,12 @@ icon: ArrowRightLeft
|
|||||||
<Step>
|
<Step>
|
||||||
### از سرور قدیمی نسخه پشتیبان بگیرید
|
### از سرور قدیمی نسخه پشتیبان بگیرید
|
||||||
|
|
||||||
از پایگاهداده (بهصورت پیشفرض `/etc/x-ui/x-ui.db`) و گواهینامههای خود یک کپی تهیه کنید.
|
از پایگاهداده (بهصورت پیشفرض `/etc/l-ui/l-ui.db`) و گواهینامههای خود یک کپی تهیه کنید.
|
||||||
[پشتیبانگیری و بازیابی](/docs/operations/backup-restore) را ببینید.
|
[پشتیبانگیری و بازیابی](/docs/operations/backup-restore) را ببینید.
|
||||||
</Step>
|
</Step>
|
||||||
|
|
||||||
<Step>
|
<Step>
|
||||||
### 3x-ui را روی سرور جدید نصب کنید
|
### L-UI را روی سرور جدید نصب کنید
|
||||||
|
|
||||||
از همان روش نصب و یک نسخهٔ سازگار استفاده کنید.
|
از همان روش نصب و یک نسخهٔ سازگار استفاده کنید.
|
||||||
[نصب](/docs/guide/installation) را ببینید.
|
[نصب](/docs/guide/installation) را ببینید.
|
||||||
@@ -32,17 +32,17 @@ icon: ArrowRightLeft
|
|||||||
|
|
||||||
</Steps>
|
</Steps>
|
||||||
|
|
||||||
## بین نسخههای 3x-ui
|
## بین نسخههای L-UI
|
||||||
|
|
||||||
در محدودهٔ یک backend یکسان، ارتقا معمولاً تنها به اجرای دوبارهٔ نصبکننده یا
|
در محدودهٔ یک backend یکسان، ارتقا معمولاً تنها به اجرای دوبارهٔ نصبکننده یا
|
||||||
کشیدن یک image جدید خلاصه میشود — پنل خودش پایگاهدادهاش را مهاجرت میدهد. هنگام تغییر بین نسخههای **اصلی**،
|
کشیدن یک image جدید خلاصه میشود — پنل خودش پایگاهدادهاش را مهاجرت میدهد. هنگام تغییر بین نسخههای **اصلی**،
|
||||||
ابتدا [یادداشتهای انتشار](https://github.com/MHSanaei/3x-ui/releases)
|
ابتدا [یادداشتهای انتشار](https://github.com/MHSanaei/L-UI/releases)
|
||||||
را بخوانید و یک نسخهٔ پشتیبان تهیه کنید.
|
را بخوانید و یک نسخهٔ پشتیبان تهیه کنید.
|
||||||
|
|
||||||
## از x-ui
|
## از l-ui
|
||||||
|
|
||||||
وارد کردن مستقیم پایگاهدادهٔ یک پنل قدیمی x-ui به 3x-ui **پشتیبانی نمیشود** —
|
وارد کردن مستقیم پایگاهدادهٔ یک پنل قدیمی l-ui به L-UI **پشتیبانی نمیشود** —
|
||||||
چون ساختار schema آنها متفاوت است. 3x-ui را از نو نصب کنید و inboundها/کلاینتها را
|
چون ساختار schema آنها متفاوت است. L-UI را از نو نصب کنید و inboundها/کلاینتها را
|
||||||
دوباره بسازید و در همین حین لینکهای اشتراکگذاری را از پنل قدیمی خروجی بگیرید.
|
دوباره بسازید و در همین حین لینکهای اشتراکگذاری را از پنل قدیمی خروجی بگیرید.
|
||||||
|
|
||||||
<Callout type="warn">
|
<Callout type="warn">
|
||||||
|
|||||||
@@ -1,17 +1,17 @@
|
|||||||
---
|
---
|
||||||
title: عیبیابی
|
title: عیبیابی
|
||||||
description: رفع مشکلات رایج 3x-ui — اجرا نشدن پنل، خطاهای 502، مشکلات گواهی و کلاینتهایی که نمیتوانند متصل شوند.
|
description: رفع مشکلات رایج L-UI — اجرا نشدن پنل، خطاهای 502، مشکلات گواهی و کلاینتهایی که نمیتوانند متصل شوند.
|
||||||
icon: Wrench
|
icon: Wrench
|
||||||
---
|
---
|
||||||
|
|
||||||
فهرستی برای رسیدگی به رایجترین مشکلات. هرگاه مطمئن نبودید، سطح لاگ را بالا ببرید
|
فهرستی برای رسیدگی به رایجترین مشکلات. هرگاه مطمئن نبودید، سطح لاگ را بالا ببرید
|
||||||
(`XUI_LOG_LEVEL=debug`) و لاگهای پنل و Xray را بررسی کنید.
|
(`LUI_LOG_LEVEL=debug`) و لاگهای پنل و Xray را بررسی کنید.
|
||||||
|
|
||||||
## پنل اجرا نمیشود
|
## پنل اجرا نمیشود
|
||||||
|
|
||||||
- وضعیت سرویس و لاگها را بررسی کنید (منوی `x-ui` ← وضعیت/لاگها).
|
- وضعیت سرویس و لاگها را بررسی کنید (منوی `l-ui` ← وضعیت/لاگها).
|
||||||
- مطمئن شوید که **پورت پنل از قبل توسط سرویس دیگری اشغال نشده** باشد.
|
- مطمئن شوید که **پورت پنل از قبل توسط سرویس دیگری اشغال نشده** باشد.
|
||||||
- بررسی کنید که مسیر دیتابیس قابل نوشتن باشد (پیشفرض `/etc/x-ui/x-ui.db`).
|
- بررسی کنید که مسیر دیتابیس قابل نوشتن باشد (پیشفرض `/etc/l-ui/l-ui.db`).
|
||||||
|
|
||||||
## خطای 502 / در دسترس نبودن پنل پشت یک پروکسی
|
## خطای 502 / در دسترس نبودن پنل پشت یک پروکسی
|
||||||
|
|
||||||
@@ -37,6 +37,6 @@ icon: Wrench
|
|||||||
|
|
||||||
<Callout type="info">
|
<Callout type="info">
|
||||||
همچنان به مشکل خوردهاید؟ در میان
|
همچنان به مشکل خوردهاید؟ در میان
|
||||||
[مسائل GitHub](https://github.com/MHSanaei/3x-ui/issues) جستوجو کنید — احتمالاً
|
[مسائل GitHub](https://github.com/MHSanaei/L-UI/issues) جستوجو کنید — احتمالاً
|
||||||
علامت مشکل شما قبلاً دیده شده است.
|
علامت مشکل شما قبلاً دیده شده است.
|
||||||
</Callout>
|
</Callout>
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
---
|
---
|
||||||
title: مستندات 3x-ui
|
title: مستندات L-UI
|
||||||
description: مستندات رسمی 3x-ui — یک پنل وب پیشرفته برای مدیریت سرورهای Xray-core، پروکسیها، کلاینتها و سابسکریپشنها.
|
description: مستندات رسمی L-UI — یک پنل وب پیشرفته برای مدیریت سرورهای Xray-core، پروکسیها، کلاینتها و سابسکریپشنها.
|
||||||
icon: House
|
icon: House
|
||||||
---
|
---
|
||||||
|
|
||||||
**3x-ui** یک پنل وب متنباز برای استقرار و مدیریت سرورهای
|
**L-UI** یک پنل وب متنباز برای استقرار و مدیریت سرورهای
|
||||||
[Xray-core](https://github.com/XTLS/Xray-core) است. این پنل یک داشبورد مدرن برای
|
[Xray-core](https://github.com/XTLS/Xray-core) است. این پنل یک داشبورد مدرن برای
|
||||||
اینباندها، پروتکلها، کلاینتها، حسابداری ترافیک، سابسکریپشنها و موارد دیگر در
|
اینباندها، پروتکلها، کلاینتها، حسابداری ترافیک، سابسکریپشنها و موارد دیگر در
|
||||||
اختیار شما میگذارد — بدون نیاز به ویرایش دستی JSON مربوط به Xray از طریق خط فرمان.
|
اختیار شما میگذارد — بدون نیاز به ویرایش دستی JSON مربوط به Xray از طریق خط فرمان.
|
||||||
@@ -17,7 +17,7 @@ icon: House
|
|||||||
|
|
||||||
<Cards>
|
<Cards>
|
||||||
<Card
|
<Card
|
||||||
title="3x-ui چیست؟"
|
title="L-UI چیست؟"
|
||||||
href="/docs/guide"
|
href="/docs/guide"
|
||||||
description="نمای کلی: Xray-core، پنل، و اینکه برای چه کسانی مناسب است."
|
description="نمای کلی: Xray-core، پنل، و اینکه برای چه کسانی مناسب است."
|
||||||
/>
|
/>
|
||||||
@@ -49,6 +49,6 @@ icon: House
|
|||||||
- **عملیات** — مدیریت چندنودی، ربات Telegram، پشتیبانگیری و یک REST API.
|
- **عملیات** — مدیریت چندنودی، ربات Telegram، پشتیبانگیری و یک REST API.
|
||||||
|
|
||||||
<Callout type="info">
|
<Callout type="info">
|
||||||
با Xray تازه آشنا شدهاید؟ ابتدا [3x-ui چیست؟](/docs/guide) را بخوانید — توضیح میدهد که پنل، Xray-core و
|
با Xray تازه آشنا شدهاید؟ ابتدا [L-UI چیست؟](/docs/guide) را بخوانید — توضیح میدهد که پنل، Xray-core و
|
||||||
اپلیکیشنهای کلاینت شما چگونه در کنار هم کار میکنند.
|
اپلیکیشنهای کلاینت شما چگونه در کنار هم کار میکنند.
|
||||||
</Callout>
|
</Callout>
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user