Compare commits

...

5 commits

Author SHA1 Message Date
Igor Kamyshnikov
b747730211
vless: use Inbound Listen address in Subscription service (#3610)
Some checks are pending
Release 3X-UI / build (386) (push) Waiting to run
Release 3X-UI / build (amd64) (push) Waiting to run
Release 3X-UI / build (arm64) (push) Waiting to run
Release 3X-UI / build (armv5) (push) Waiting to run
Release 3X-UI / build (armv6) (push) Waiting to run
Release 3X-UI / build (armv7) (push) Waiting to run
Release 3X-UI / build (s390x) (push) Waiting to run
Release 3X-UI / Build for Windows (push) Waiting to run
* vless: use Inbound Listen address in Subscription service

vless manual connection link and subscription produced connection link are aligned.
subscription service now returns an IP address configured on Inbound, instead of subscription service IP,
which is consistent when the address, returned by QR code for manual vless link distribution.
2026-01-03 04:39:30 +01:00
Nebulosa
692a73788a
Set variables for packaging purposes (#3600)
* Set Variables for settings
2026-01-03 03:57:19 +01:00
Mikhail Grigorev
3287fa4d80
Added EnvironmentFile to systemd unit (#3606)
* Added EnvironmentFile to systemd unit

* Added support for older releases

* Remove ARGS

* Fixed copy unit

* Fixed unit filename

* Update update.sh
2026-01-03 03:37:48 +01:00
weekend sorrow
1393f981bc
feat: Add etckeeper compatibility (#3602) 2026-01-03 03:13:00 +01:00
Ilya Kryuchkov
9a2c1c6b43
Fix: panel redirecting to old port after restart (#3594)
* Fix panel redirect logic

* Fix panel redirect logic

* remove duplicate code

* Cr fixes
2026-01-03 03:05:10 +01:00
8 changed files with 245 additions and 98 deletions

View file

@ -17,7 +17,8 @@ on:
- '**.go' - '**.go'
- 'go.mod' - 'go.mod'
- 'go.sum' - 'go.sum'
- 'x-ui.service' - 'x-ui.service.debian'
- 'x-ui.service.rhel'
jobs: jobs:
build: build:
@ -78,7 +79,8 @@ jobs:
mkdir x-ui mkdir x-ui
cp xui-release x-ui/ cp xui-release x-ui/
cp x-ui.service x-ui/ cp x-ui.service.debian x-ui/
cp x-ui.service.rhel x-ui/
cp x-ui.sh x-ui/ cp x-ui.sh x-ui/
mv x-ui/xui-release x-ui/x-ui mv x-ui/xui-release x-ui/x-ui
mkdir x-ui/bin mkdir x-ui/bin

View file

@ -8,6 +8,9 @@ plain='\033[0m'
cur_dir=$(pwd) cur_dir=$(pwd)
xui_folder="${XUI_MAIN_FOLDER:=/usr/local/x-ui}"
xui_service="${XUI_SERVICE:=/etc/systemd/system}"
# check root # check root
[[ $EUID -ne 0 ]] && echo -e "${red}Fatal error: ${plain} Please run this script with root privilege \n " && exit 1 [[ $EUID -ne 0 ]] && echo -e "${red}Fatal error: ${plain} Please run this script with root privilege \n " && exit 1
@ -158,7 +161,7 @@ setup_ssl_certificate() {
local webKeyFile="/root/cert/${domain}/privkey.pem" local webKeyFile="/root/cert/${domain}/privkey.pem"
if [[ -f "$webCertFile" && -f "$webKeyFile" ]]; then if [[ -f "$webCertFile" && -f "$webKeyFile" ]]; then
/usr/local/x-ui/x-ui cert -webCert "$webCertFile" -webCertKey "$webKeyFile" >/dev/null 2>&1 ${xui_folder}/x-ui cert -webCert "$webCertFile" -webCertKey "$webKeyFile" >/dev/null 2>&1
echo -e "${green}SSL certificate installed and configured successfully!${plain}" echo -e "${green}SSL certificate installed and configured successfully!${plain}"
return 0 return 0
else else
@ -215,15 +218,15 @@ EOF
fi fi
chmod 755 ${certDir}/* 2>/dev/null chmod 755 ${certDir}/* 2>/dev/null
/usr/local/x-ui/x-ui cert -webCert "${certDir}/fullchain.pem" -webCertKey "${certDir}/privkey.pem" >/dev/null 2>&1 ${xui_folder}/x-ui cert -webCert "${certDir}/fullchain.pem" -webCertKey "${certDir}/privkey.pem" >/dev/null 2>&1
echo -e "${yellow}Self-signed certificate configured. Browsers will show a warning.${plain}" echo -e "${yellow}Self-signed certificate configured. Browsers will show a warning.${plain}"
return 0 return 0
} }
# Comprehensive manual SSL certificate issuance via acme.sh # Comprehensive manual SSL certificate issuance via acme.sh
ssl_cert_issue() { ssl_cert_issue() {
local existing_webBasePath=$(/usr/local/x-ui/x-ui setting -show true | grep 'webBasePath:' | awk -F': ' '{print $2}' | tr -d '[:space:]' | sed 's#^/##') local existing_webBasePath=$(${xui_folder}/x-ui setting -show true | grep 'webBasePath:' | awk -F': ' '{print $2}' | tr -d '[:space:]' | sed 's#^/##')
local existing_port=$(/usr/local/x-ui/x-ui setting -show true | grep 'port:' | awk -F': ' '{print $2}' | tr -d '[:space:]') local existing_port=$(${xui_folder}/x-ui setting -show true | grep 'port:' | awk -F': ' '{print $2}' | tr -d '[:space:]')
# check for acme.sh first # check for acme.sh first
if ! command -v ~/.acme.sh/acme.sh &>/dev/null; then if ! command -v ~/.acme.sh/acme.sh &>/dev/null; then
@ -366,7 +369,7 @@ ssl_cert_issue() {
local webKeyFile="/root/cert/${domain}/privkey.pem" local webKeyFile="/root/cert/${domain}/privkey.pem"
if [[ -f "$webCertFile" && -f "$webKeyFile" ]]; then if [[ -f "$webCertFile" && -f "$webKeyFile" ]]; then
/usr/local/x-ui/x-ui cert -webCert "$webCertFile" -webCertKey "$webKeyFile" ${xui_folder}/x-ui cert -webCert "$webCertFile" -webCertKey "$webKeyFile"
echo -e "${green}Certificate paths set for the panel${plain}" echo -e "${green}Certificate paths set for the panel${plain}"
echo -e "${green}Certificate File: $webCertFile${plain}" echo -e "${green}Certificate File: $webCertFile${plain}"
echo -e "${green}Private Key File: $webKeyFile${plain}" echo -e "${green}Private Key File: $webKeyFile${plain}"
@ -451,11 +454,11 @@ prompt_and_setup_ssl() {
} }
config_after_install() { config_after_install() {
local existing_hasDefaultCredential=$(/usr/local/x-ui/x-ui setting -show true | grep -Eo 'hasDefaultCredential: .+' | awk '{print $2}') local existing_hasDefaultCredential=$(${xui_folder}/x-ui setting -show true | grep -Eo 'hasDefaultCredential: .+' | awk '{print $2}')
local existing_webBasePath=$(/usr/local/x-ui/x-ui setting -show true | grep -Eo 'webBasePath: .+' | awk '{print $2}' | sed 's#^/##') local existing_webBasePath=$(${xui_folder}/x-ui setting -show true | grep -Eo 'webBasePath: .+' | awk '{print $2}' | sed 's#^/##')
local existing_port=$(/usr/local/x-ui/x-ui setting -show true | grep -Eo 'port: .+' | awk '{print $2}') local existing_port=$(${xui_folder}/x-ui setting -show true | grep -Eo 'port: .+' | awk '{print $2}')
# Properly detect empty cert by checking if cert: line exists and has content after it # Properly detect empty cert by checking if cert: line exists and has content after it
local existing_cert=$(/usr/local/x-ui/x-ui setting -getCert true | grep 'cert:' | awk -F': ' '{print $2}' | tr -d '[:space:]') local existing_cert=$(${xui_folder}/x-ui setting -getCert true | grep 'cert:' | awk -F': ' '{print $2}' | tr -d '[:space:]')
local URL_lists=( local URL_lists=(
"https://api4.ipify.org" "https://api4.ipify.org"
"https://ipv4.icanhazip.com" "https://ipv4.icanhazip.com"
@ -487,7 +490,7 @@ config_after_install() {
echo -e "${yellow}Generated random port: ${config_port}${plain}" echo -e "${yellow}Generated random port: ${config_port}${plain}"
fi fi
/usr/local/x-ui/x-ui setting -username "${config_username}" -password "${config_password}" -port "${config_port}" -webBasePath "${config_webBasePath}" ${xui_folder}/x-ui setting -username "${config_username}" -password "${config_password}" -port "${config_port}" -webBasePath "${config_webBasePath}"
echo "" echo ""
echo -e "${green}═══════════════════════════════════════════${plain}" echo -e "${green}═══════════════════════════════════════════${plain}"
@ -515,7 +518,7 @@ config_after_install() {
else else
local config_webBasePath=$(gen_random_string 18) local config_webBasePath=$(gen_random_string 18)
echo -e "${yellow}WebBasePath is missing or too short. Generating a new one...${plain}" echo -e "${yellow}WebBasePath is missing or too short. Generating a new one...${plain}"
/usr/local/x-ui/x-ui setting -webBasePath "${config_webBasePath}" ${xui_folder}/x-ui setting -webBasePath "${config_webBasePath}"
echo -e "${green}New WebBasePath: ${config_webBasePath}${plain}" echo -e "${green}New WebBasePath: ${config_webBasePath}${plain}"
# If the panel is already installed but no certificate is configured, prompt for SSL now # If the panel is already installed but no certificate is configured, prompt for SSL now
@ -539,7 +542,7 @@ config_after_install() {
local config_password=$(gen_random_string 10) local config_password=$(gen_random_string 10)
echo -e "${yellow}Default credentials detected. Security update required...${plain}" echo -e "${yellow}Default credentials detected. Security update required...${plain}"
/usr/local/x-ui/x-ui setting -username "${config_username}" -password "${config_password}" ${xui_folder}/x-ui setting -username "${config_username}" -password "${config_password}"
echo -e "Generated new random login credentials:" echo -e "Generated new random login credentials:"
echo -e "###############################################" echo -e "###############################################"
echo -e "${green}Username: ${config_username}${plain}" echo -e "${green}Username: ${config_username}${plain}"
@ -551,7 +554,7 @@ config_after_install() {
# Existing install: if no cert configured, prompt user to set domain or self-signed # Existing install: if no cert configured, prompt user to set domain or self-signed
# Properly detect empty cert by checking if cert: line exists and has content after it # Properly detect empty cert by checking if cert: line exists and has content after it
existing_cert=$(/usr/local/x-ui/x-ui setting -getCert true | grep 'cert:' | awk -F': ' '{print $2}' | tr -d '[:space:]') existing_cert=$(${xui_folder}/x-ui setting -getCert true | grep 'cert:' | awk -F': ' '{print $2}' | tr -d '[:space:]')
if [[ -z "$existing_cert" ]]; then if [[ -z "$existing_cert" ]]; then
echo "" echo ""
echo -e "${green}═══════════════════════════════════════════${plain}" echo -e "${green}═══════════════════════════════════════════${plain}"
@ -566,11 +569,11 @@ config_after_install() {
fi fi
fi fi
/usr/local/x-ui/x-ui migrate ${xui_folder}/x-ui migrate
} }
install_x-ui() { install_x-ui() {
cd /usr/local/ cd ${xui_folder%/x-ui}/
# Download resources # Download resources
if [ $# == 0 ]; then if [ $# == 0 ]; then
@ -584,7 +587,7 @@ install_x-ui() {
fi fi
fi fi
echo -e "Got x-ui latest version: ${tag_version}, beginning the installation..." echo -e "Got x-ui latest version: ${tag_version}, beginning the installation..."
wget --inet4-only -N -O /usr/local/x-ui-linux-$(arch).tar.gz https://github.com/MHSanaei/3x-ui/releases/download/${tag_version}/x-ui-linux-$(arch).tar.gz wget --inet4-only -N -O ${xui_folder}-linux-$(arch).tar.gz https://github.com/MHSanaei/3x-ui/releases/download/${tag_version}/x-ui-linux-$(arch).tar.gz
if [[ $? -ne 0 ]]; then if [[ $? -ne 0 ]]; then
echo -e "${red}Downloading x-ui failed, please be sure that your server can access GitHub ${plain}" echo -e "${red}Downloading x-ui failed, please be sure that your server can access GitHub ${plain}"
exit 1 exit 1
@ -601,7 +604,7 @@ install_x-ui() {
url="https://github.com/MHSanaei/3x-ui/releases/download/${tag_version}/x-ui-linux-$(arch).tar.gz" url="https://github.com/MHSanaei/3x-ui/releases/download/${tag_version}/x-ui-linux-$(arch).tar.gz"
echo -e "Beginning to install x-ui $1" echo -e "Beginning to install x-ui $1"
wget --inet4-only -N -O /usr/local/x-ui-linux-$(arch).tar.gz ${url} wget --inet4-only -N -O ${xui_folder}-linux-$(arch).tar.gz ${url}
if [[ $? -ne 0 ]]; then if [[ $? -ne 0 ]]; then
echo -e "${red}Download x-ui $1 failed, please check if the version exists ${plain}" echo -e "${red}Download x-ui $1 failed, please check if the version exists ${plain}"
exit 1 exit 1
@ -614,13 +617,13 @@ install_x-ui() {
fi fi
# Stop x-ui service and remove old resources # Stop x-ui service and remove old resources
if [[ -e /usr/local/x-ui/ ]]; then if [[ -e ${xui_folder}/ ]]; then
if [[ $release == "alpine" ]]; then if [[ $release == "alpine" ]]; then
rc-service x-ui stop rc-service x-ui stop
else else
systemctl stop x-ui systemctl stop x-ui
fi fi
rm /usr/local/x-ui/ -rf rm ${xui_folder}/ -rf
fi fi
# Extract resources and set permissions # Extract resources and set permissions
@ -644,6 +647,20 @@ install_x-ui() {
mkdir -p /var/log/x-ui mkdir -p /var/log/x-ui
config_after_install config_after_install
# Etckeeper compatibility
if [ -d "/etc/.git" ]; then
if [ -f "/etc/.gitignore" ]; then
if ! grep -q "x-ui/x-ui.db" "/etc/.gitignore"; then
echo "" >> "/etc/.gitignore"
echo "x-ui/x-ui.db" >> "/etc/.gitignore"
echo -e "${green}Added x-ui.db to /etc/.gitignore for etckeeper${plain}"
fi
else
echo "x-ui/x-ui.db" > "/etc/.gitignore"
echo -e "${green}Created /etc/.gitignore and added x-ui.db for etckeeper${plain}"
fi
fi
if [[ $release == "alpine" ]]; then if [[ $release == "alpine" ]]; then
wget --inet4-only -O /etc/init.d/x-ui https://raw.githubusercontent.com/MHSanaei/3x-ui/main/x-ui.rc wget --inet4-only -O /etc/init.d/x-ui https://raw.githubusercontent.com/MHSanaei/3x-ui/main/x-ui.rc
if [[ $? -ne 0 ]]; then if [[ $? -ne 0 ]]; then
@ -654,7 +671,18 @@ install_x-ui() {
rc-update add x-ui rc-update add x-ui
rc-service x-ui start rc-service x-ui start
else else
cp -f x-ui.service /etc/systemd/system/ if [ -f "x-ui.service" ]; then
cp -f x-ui.service ${xui_service}/
else
case "${release}" in
ubuntu | debian | armbian)
cp -f x-ui.service.debian ${xui_service}/x-ui.service
;;
*)
cp -f x-ui.service.rhel ${xui_service}/x-ui.service
;;
esac
fi
systemctl daemon-reload systemctl daemon-reload
systemctl enable x-ui systemctl enable x-ui
systemctl start x-ui systemctl start x-ui

View file

@ -179,9 +179,15 @@ func (s *SubService) genVmessLink(inbound *model.Inbound, email string) string {
if inbound.Protocol != model.VMESS { if inbound.Protocol != model.VMESS {
return "" return ""
} }
var address string
if inbound.Listen == "" || inbound.Listen == "0.0.0.0" || inbound.Listen == "::" || inbound.Listen == "::0" {
address = s.address
} else {
address = inbound.Listen
}
obj := map[string]any{ obj := map[string]any{
"v": "2", "v": "2",
"add": s.address, "add": address,
"port": inbound.Port, "port": inbound.Port,
"type": "none", "type": "none",
} }
@ -317,7 +323,13 @@ func (s *SubService) genVmessLink(inbound *model.Inbound, email string) string {
} }
func (s *SubService) genVlessLink(inbound *model.Inbound, email string) string { func (s *SubService) genVlessLink(inbound *model.Inbound, email string) string {
address := s.address var address string
if inbound.Listen == "" || inbound.Listen == "0.0.0.0" || inbound.Listen == "::" || inbound.Listen == "::0" {
address = s.address
} else {
address = inbound.Listen
}
if inbound.Protocol != model.VLESS { if inbound.Protocol != model.VLESS {
return "" return ""
} }
@ -523,7 +535,12 @@ func (s *SubService) genVlessLink(inbound *model.Inbound, email string) string {
} }
func (s *SubService) genTrojanLink(inbound *model.Inbound, email string) string { func (s *SubService) genTrojanLink(inbound *model.Inbound, email string) string {
address := s.address var address string
if inbound.Listen == "" || inbound.Listen == "0.0.0.0" || inbound.Listen == "::" || inbound.Listen == "::0" {
address = s.address
} else {
address = inbound.Listen
}
if inbound.Protocol != model.Trojan { if inbound.Protocol != model.Trojan {
return "" return ""
} }
@ -719,7 +736,12 @@ func (s *SubService) genTrojanLink(inbound *model.Inbound, email string) string
} }
func (s *SubService) genShadowsocksLink(inbound *model.Inbound, email string) string { func (s *SubService) genShadowsocksLink(inbound *model.Inbound, email string) string {
address := s.address var address string
if inbound.Listen == "" || inbound.Listen == "0.0.0.0" || inbound.Listen == "::" || inbound.Listen == "::0" {
address = s.address
} else {
address = inbound.Listen
}
if inbound.Protocol != model.Shadowsocks { if inbound.Protocol != model.Shadowsocks {
return "" return ""
} }

View file

@ -6,6 +6,9 @@ blue='\033[0;34m'
yellow='\033[0;33m' yellow='\033[0;33m'
plain='\033[0m' plain='\033[0m'
xui_folder="${XUI_MAIN_FOLDER:=/usr/local/x-ui}"
xui_service="${XUI_SERVICE:=/etc/systemd/system}"
# Don't edit this config # Don't edit this config
b_source="${BASH_SOURCE[0]}" b_source="${BASH_SOURCE[0]}"
while [ -h "$b_source" ]; do while [ -h "$b_source" ]; do
@ -190,7 +193,7 @@ setup_ssl_certificate() {
local webKeyFile="/root/cert/${domain}/privkey.pem" local webKeyFile="/root/cert/${domain}/privkey.pem"
if [[ -f "$webCertFile" && -f "$webKeyFile" ]]; then if [[ -f "$webCertFile" && -f "$webKeyFile" ]]; then
/usr/local/x-ui/x-ui cert -webCert "$webCertFile" -webCertKey "$webKeyFile" >/dev/null 2>&1 ${xui_folder}/x-ui cert -webCert "$webCertFile" -webCertKey "$webKeyFile" >/dev/null 2>&1
echo -e "${green}SSL certificate installed and configured successfully!${plain}" echo -e "${green}SSL certificate installed and configured successfully!${plain}"
return 0 return 0
else else
@ -246,14 +249,14 @@ EOF
fi fi
chmod 755 ${certDir}/* 2>/dev/null chmod 755 ${certDir}/* 2>/dev/null
/usr/local/x-ui/x-ui cert -webCert "${certDir}/fullchain.pem" -webCertKey "${certDir}/privkey.pem" >/dev/null 2>&1 ${xui_folder}/x-ui cert -webCert "${certDir}/fullchain.pem" -webCertKey "${certDir}/privkey.pem" >/dev/null 2>&1
echo -e "${yellow}Self-signed certificate configured. Browsers will show a warning.${plain}" echo -e "${yellow}Self-signed certificate configured. Browsers will show a warning.${plain}"
return 0 return 0
} }
# Comprehensive manual SSL certificate issuance via acme.sh # Comprehensive manual SSL certificate issuance via acme.sh
ssl_cert_issue() { ssl_cert_issue() {
local existing_webBasePath=$(/usr/local/x-ui/x-ui setting -show true | grep 'webBasePath:' | awk -F': ' '{print $2}' | tr -d '[:space:]' | sed 's#^/##') local existing_webBasePath=$(${xui_folder}/x-ui setting -show true | grep 'webBasePath:' | awk -F': ' '{print $2}' | tr -d '[:space:]' | sed 's#^/##')
local existing_port=$(/usr/local/x-ui/x-ui setting -show true | grep 'port:' | awk -F': ' '{print $2}' | tr -d '[:space:]') local existing_port=$(${xui_folder}/x-ui setting -show true | grep 'port:' | awk -F': ' '{print $2}' | tr -d '[:space:]')
# check for acme.sh first # check for acme.sh first
if ! command -v ~/.acme.sh/acme.sh &>/dev/null; then if ! command -v ~/.acme.sh/acme.sh &>/dev/null; then
@ -396,7 +399,7 @@ ssl_cert_issue() {
local webKeyFile="/root/cert/${domain}/privkey.pem" local webKeyFile="/root/cert/${domain}/privkey.pem"
if [[ -f "$webCertFile" && -f "$webKeyFile" ]]; then if [[ -f "$webCertFile" && -f "$webKeyFile" ]]; then
/usr/local/x-ui/x-ui cert -webCert "$webCertFile" -webCertKey "$webKeyFile" ${xui_folder}/x-ui cert -webCert "$webCertFile" -webCertKey "$webKeyFile"
echo -e "${green}Certificate paths set for the panel${plain}" echo -e "${green}Certificate paths set for the panel${plain}"
echo -e "${green}Certificate File: $webCertFile${plain}" echo -e "${green}Certificate File: $webCertFile${plain}"
echo -e "${green}Private Key File: $webKeyFile${plain}" echo -e "${green}Private Key File: $webKeyFile${plain}"
@ -485,13 +488,13 @@ prompt_and_setup_ssl() {
config_after_update() { config_after_update() {
echo -e "${yellow}x-ui settings:${plain}" echo -e "${yellow}x-ui settings:${plain}"
/usr/local/x-ui/x-ui setting -show true ${xui_folder}/x-ui setting -show true
/usr/local/x-ui/x-ui migrate ${xui_folder}/x-ui migrate
# Properly detect empty cert by checking if cert: line exists and has content after it # Properly detect empty cert by checking if cert: line exists and has content after it
local existing_cert=$(/usr/local/x-ui/x-ui setting -getCert true 2>/dev/null | grep 'cert:' | awk -F': ' '{print $2}' | tr -d '[:space:]') local existing_cert=$(${xui_folder}/x-ui setting -getCert true 2>/dev/null | grep 'cert:' | awk -F': ' '{print $2}' | tr -d '[:space:]')
local existing_port=$(/usr/local/x-ui/x-ui setting -show true | grep -Eo 'port: .+' | awk '{print $2}') local existing_port=$(${xui_folder}/x-ui setting -show true | grep -Eo 'port: .+' | awk '{print $2}')
local existing_webBasePath=$(/usr/local/x-ui/x-ui setting -show true | grep -Eo 'webBasePath: .+' | awk '{print $2}' | sed 's#^/##') local existing_webBasePath=$(${xui_folder}/x-ui setting -show true | grep -Eo 'webBasePath: .+' | awk '{print $2}' | sed 's#^/##')
# Get server IP # Get server IP
local URL_lists=( local URL_lists=(
@ -514,7 +517,7 @@ config_after_update() {
if [[ ${#existing_webBasePath} -lt 4 ]]; then if [[ ${#existing_webBasePath} -lt 4 ]]; then
echo -e "${yellow}WebBasePath is missing or too short. Generating a new one...${plain}" echo -e "${yellow}WebBasePath is missing or too short. Generating a new one...${plain}"
local config_webBasePath=$(gen_random_string 18) local config_webBasePath=$(gen_random_string 18)
/usr/local/x-ui/x-ui setting -webBasePath "${config_webBasePath}" ${xui_folder}/x-ui setting -webBasePath "${config_webBasePath}"
existing_webBasePath="${config_webBasePath}" existing_webBasePath="${config_webBasePath}"
echo -e "${green}New WebBasePath: ${config_webBasePath}${plain}" echo -e "${green}New WebBasePath: ${config_webBasePath}${plain}"
fi fi
@ -559,10 +562,10 @@ config_after_update() {
} }
update_x-ui() { update_x-ui() {
cd /usr/local/ cd ${xui_folder%/x-ui}/
if [ -f "/usr/local/x-ui/x-ui" ]; then if [ -f "${xui_folder}/x-ui" ]; then
current_xui_version=$(/usr/local/x-ui/x-ui -v) current_xui_version=$(${xui_folder}/x-ui -v)
echo -e "${green}Current x-ui version: ${current_xui_version}${plain}" echo -e "${green}Current x-ui version: ${current_xui_version}${plain}"
else else
_fail "ERROR: Current x-ui version: unknown" _fail "ERROR: Current x-ui version: unknown"
@ -579,16 +582,16 @@ update_x-ui() {
fi fi
fi fi
echo -e "Got x-ui latest version: ${tag_version}, beginning the installation..." echo -e "Got x-ui latest version: ${tag_version}, beginning the installation..."
${wget_bin} -N -O /usr/local/x-ui-linux-$(arch).tar.gz https://github.com/MHSanaei/3x-ui/releases/download/${tag_version}/x-ui-linux-$(arch).tar.gz 2>/dev/null ${wget_bin} -N -O ${xui_folder}-linux-$(arch).tar.gz https://github.com/MHSanaei/3x-ui/releases/download/${tag_version}/x-ui-linux-$(arch).tar.gz 2>/dev/null
if [[ $? -ne 0 ]]; then if [[ $? -ne 0 ]]; then
echo -e "${yellow}Trying to fetch version with IPv4...${plain}" echo -e "${yellow}Trying to fetch version with IPv4...${plain}"
${wget_bin} --inet4-only -N -O /usr/local/x-ui-linux-$(arch).tar.gz https://github.com/MHSanaei/3x-ui/releases/download/${tag_version}/x-ui-linux-$(arch).tar.gz 2>/dev/null ${wget_bin} --inet4-only -N -O ${xui_folder}-linux-$(arch).tar.gz https://github.com/MHSanaei/3x-ui/releases/download/${tag_version}/x-ui-linux-$(arch).tar.gz 2>/dev/null
if [[ $? -ne 0 ]]; then if [[ $? -ne 0 ]]; then
_fail "ERROR: Failed to download x-ui, please be sure that your server can access GitHub" _fail "ERROR: Failed to download x-ui, please be sure that your server can access GitHub"
fi fi
fi fi
if [[ -e /usr/local/x-ui/ ]]; then if [[ -e ${xui_folder}/ ]]; then
echo -e "${green}Stopping x-ui...${plain}" echo -e "${green}Stopping x-ui...${plain}"
if [[ $release == "alpine" ]]; then if [[ $release == "alpine" ]]; then
if [ -f "/etc/init.d/x-ui" ]; then if [ -f "/etc/init.d/x-ui" ]; then
@ -601,11 +604,11 @@ update_x-ui() {
_fail "ERROR: x-ui service unit not installed." _fail "ERROR: x-ui service unit not installed."
fi fi
else else
if [ -f "/etc/systemd/system/x-ui.service" ]; then if [ -f "${xui_service}/x-ui.service" ]; then
systemctl stop x-ui >/dev/null 2>&1 systemctl stop x-ui >/dev/null 2>&1
systemctl disable x-ui >/dev/null 2>&1 systemctl disable x-ui >/dev/null 2>&1
echo -e "${green}Removing old systemd unit version...${plain}" echo -e "${green}Removing old systemd unit version...${plain}"
rm /etc/systemd/system/x-ui.service -f >/dev/null 2>&1 rm ${xui_service}/x-ui.service -f >/dev/null 2>&1
systemctl daemon-reload >/dev/null 2>&1 systemctl daemon-reload >/dev/null 2>&1
else else
rm x-ui-linux-$(arch).tar.gz -f >/dev/null 2>&1 rm x-ui-linux-$(arch).tar.gz -f >/dev/null 2>&1
@ -613,15 +616,17 @@ update_x-ui() {
fi fi
fi fi
echo -e "${green}Removing old x-ui version...${plain}" echo -e "${green}Removing old x-ui version...${plain}"
rm /usr/bin/x-ui -f >/dev/null 2>&1 rm ${xui_folder} -f >/dev/null 2>&1
rm /usr/local/x-ui/x-ui.service -f >/dev/null 2>&1 rm ${xui_folder}/x-ui.service -f >/dev/null 2>&1
rm /usr/local/x-ui/x-ui -f >/dev/null 2>&1 rm ${xui_folder}/x-ui.service.debian -f >/dev/null 2>&1
rm /usr/local/x-ui/x-ui.sh -f >/dev/null 2>&1 rm ${xui_folder}/x-ui.service.rhel -f >/dev/null 2>&1
rm ${xui_folder}/x-ui -f >/dev/null 2>&1
rm ${xui_folder}/x-ui.sh -f >/dev/null 2>&1
echo -e "${green}Removing old xray version...${plain}" echo -e "${green}Removing old xray version...${plain}"
rm /usr/local/x-ui/bin/xray-linux-amd64 -f >/dev/null 2>&1 rm ${xui_folder}/bin/xray-linux-amd64 -f >/dev/null 2>&1
echo -e "${green}Removing old README and LICENSE file...${plain}" echo -e "${green}Removing old README and LICENSE file...${plain}"
rm /usr/local/x-ui/bin/README.md -f >/dev/null 2>&1 rm ${xui_folder}/bin/README.md -f >/dev/null 2>&1
rm /usr/local/x-ui/bin/LICENSE -f >/dev/null 2>&1 rm ${xui_folder}/bin/LICENSE -f >/dev/null 2>&1
else else
rm x-ui-linux-$(arch).tar.gz -f >/dev/null 2>&1 rm x-ui-linux-$(arch).tar.gz -f >/dev/null 2>&1
_fail "ERROR: x-ui not installed." _fail "ERROR: x-ui not installed."
@ -651,16 +656,16 @@ update_x-ui() {
fi fi
fi fi
chmod +x /usr/local/x-ui/x-ui.sh >/dev/null 2>&1 chmod +x ${xui_folder}/x-ui.sh >/dev/null 2>&1
chmod +x /usr/bin/x-ui >/dev/null 2>&1 chmod +x /usr/bin/x-ui >/dev/null 2>&1
mkdir -p /var/log/x-ui >/dev/null 2>&1 mkdir -p /var/log/x-ui >/dev/null 2>&1
echo -e "${green}Changing owner...${plain}" echo -e "${green}Changing owner...${plain}"
chown -R root:root /usr/local/x-ui >/dev/null 2>&1 chown -R root:root ${xui_folder} >/dev/null 2>&1
if [ -f "/usr/local/x-ui/bin/config.json" ]; then if [ -f "${xui_folder}/bin/config.json" ]; then
echo -e "${green}Changing on config file permissions...${plain}" echo -e "${green}Changing on config file permissions...${plain}"
chmod 640 /usr/local/x-ui/bin/config.json >/dev/null 2>&1 chmod 640 ${xui_folder}/bin/config.json >/dev/null 2>&1
fi fi
if [[ $release == "alpine" ]]; then if [[ $release == "alpine" ]]; then
@ -677,9 +682,22 @@ update_x-ui() {
rc-update add x-ui >/dev/null 2>&1 rc-update add x-ui >/dev/null 2>&1
rc-service x-ui start >/dev/null 2>&1 rc-service x-ui start >/dev/null 2>&1
else else
if [ -f "x-ui.service" ]; then
echo -e "${green}Installing systemd unit...${plain}" echo -e "${green}Installing systemd unit...${plain}"
cp -f x-ui.service /etc/systemd/system/ >/dev/null 2>&1 cp -f x-ui.service ${xui_service}/ >/dev/null 2>&1
chown root:root /etc/systemd/system/x-ui.service >/dev/null 2>&1 else
case "${release}" in
ubuntu | debian | armbian)
echo -e "${green}Installing debian-like systemd unit...${plain}"
cp -f x-ui.service.debian ${xui_service}/x-ui.service >/dev/null 2>&1
;;
*)
echo -e "${green}Installing rhel-like systemd unit...${plain}"
cp -f x-ui.service.rhel ${xui_service}/x-ui.service >/dev/null 2>&1
;;
esac
fi
chown root:root ${xui_service}/x-ui.service >/dev/null 2>&1
systemctl daemon-reload >/dev/null 2>&1 systemctl daemon-reload >/dev/null 2>&1
systemctl enable x-ui >/dev/null 2>&1 systemctl enable x-ui >/dev/null 2>&1
systemctl start x-ui >/dev/null 2>&1 systemctl start x-ui >/dev/null 2>&1

View file

@ -120,6 +120,10 @@
oldAllSetting: new AllSetting(), oldAllSetting: new AllSetting(),
allSetting: new AllSetting(), allSetting: new AllSetting(),
saveBtnDisable: true, saveBtnDisable: true,
entryHost: null,
entryPort: null,
entryProtocol: null,
entryIsIP: false,
user: {}, user: {},
lang: LanguageManager.getLanguage(), lang: LanguageManager.getLanguage(),
inboundOptions: [], inboundOptions: [],
@ -233,6 +237,31 @@
loading(spinning = true) { loading(spinning = true) {
this.loadingStates.spinning = spinning; this.loadingStates.spinning = spinning;
}, },
_isIp(h) {
if (typeof h !== "string") return false;
// IPv4: four dot-separated octets 0-255
const v4 = h.split(".");
if (
v4.length === 4 &&
v4.every(p => /^\d{1,3}$/.test(p) && Number(p) <= 255)
) return true;
// IPv6: hex groups, optional single :: compression
if (!h.includes(":") || h.includes(":::")) return false;
const parts = h.split("::");
if (parts.length > 2) return false;
const splitGroups = s => (s ? s.split(":").filter(Boolean) : []);
const head = splitGroups(parts[0]);
const tail = splitGroups(parts[1]);
const validGroup = seg => /^[0-9a-fA-F]{1,4}$/.test(seg);
if (![...head, ...tail].every(validGroup)) return false;
const groups = head.length + tail.length;
return parts.length === 2 ? groups < 8 : groups === 8;
},
async getAllSetting() { async getAllSetting() {
const msg = await HttpUtil.post("/panel/setting/all"); const msg = await HttpUtil.post("/panel/setting/all");
@ -307,16 +336,41 @@
this.loading(true); this.loading(true);
const msg = await HttpUtil.post("/panel/setting/restartPanel"); const msg = await HttpUtil.post("/panel/setting/restartPanel");
this.loading(false); this.loading(false);
if (msg.success) { if (!msg.success) return;
this.loading(true); this.loading(true);
await PromiseUtil.sleep(5000); await PromiseUtil.sleep(5000);
var { webCertFile, webKeyFile, webDomain: host, webPort: port, webBasePath: base } = this.allSetting;
if (host == this.oldAllSetting.webDomain) host = null; const { webDomain, webPort, webBasePath, webCertFile, webKeyFile } = this.allSetting;
if (port == this.oldAllSetting.webPort) port = null; const newProtocol = (webCertFile || webKeyFile) ? "https:" : "http:";
const isTLS = webCertFile !== "" || webKeyFile !== "";
const url = URLBuilder.buildURL({ host, port, isTLS, base, path: "panel/settings" }); let base = webBasePath ? webBasePath.replace(/^\//, "") : "";
window.location.replace(url); if (base && !base.endsWith("/")) base += "/";
if (!this.entryIsIP) {
const url = new URL(window.location.href);
url.pathname = `/${base}panel/settings`;
url.protocol = newProtocol;
window.location.replace(url.toString());
return;
} }
let finalHost = this.entryHost;
let finalPort = this.entryPort || "";
if (webDomain && this._isIp(webDomain)) {
finalHost = webDomain;
}
if (webPort && Number(webPort) !== Number(this.entryPort)) {
finalPort = String(webPort);
}
const url = new URL(`${newProtocol}//${finalHost}`);
if (finalPort) url.port = finalPort;
url.pathname = `/${base}panel/settings`;
window.location.replace(url.toString());
}, },
toggleTwoFactor(newValue) { toggleTwoFactor(newValue) {
if (newValue) { if (newValue) {
@ -568,6 +622,10 @@
} }
}, },
async mounted() { async mounted() {
this.entryHost = window.location.hostname;
this.entryPort = window.location.port;
this.entryProtocol = window.location.protocol;
this.entryIsIP = this._isIp(this.entryHost);
await this.getAllSetting(); await this.getAllSetting();
await this.loadInboundTags(); await this.loadInboundTags();
while (true) { while (true) {

View file

@ -4,6 +4,7 @@ After=network.target
Wants=network.target Wants=network.target
[Service] [Service]
EnvironmentFile=-/etc/default/x-ui
Environment="XRAY_VMESS_AEAD_FORCED=false" Environment="XRAY_VMESS_AEAD_FORCED=false"
Type=simple Type=simple
WorkingDirectory=/usr/local/x-ui/ WorkingDirectory=/usr/local/x-ui/

16
x-ui.service.rhel Normal file
View file

@ -0,0 +1,16 @@
[Unit]
Description=x-ui Service
After=network.target
Wants=network.target
[Service]
EnvironmentFile=-/etc/sysconfig/x-ui
Environment="XRAY_VMESS_AEAD_FORCED=false"
Type=simple
WorkingDirectory=/usr/local/x-ui/
ExecStart=/usr/local/x-ui/x-ui
Restart=on-failure
RestartSec=5s
[Install]
WantedBy=multi-user.target

62
x-ui.sh
View file

@ -53,6 +53,8 @@ os_version=""
os_version=$(grep "^VERSION_ID" /etc/os-release | cut -d '=' -f2 | tr -d '"' | tr -d '.') os_version=$(grep "^VERSION_ID" /etc/os-release | cut -d '=' -f2 | tr -d '"' | tr -d '.')
# Declare Variables # Declare Variables
xui_folder="${XUI_MAIN_FOLDER:=/usr/local/x-ui}"
xui_service="${XUI_SERVICE:=/etc/systemd/system}"
log_folder="${XUI_LOG_FOLDER:=/var/log/x-ui}" log_folder="${XUI_LOG_FOLDER:=/var/log/x-ui}"
mkdir -p "${log_folder}" mkdir -p "${log_folder}"
iplimit_log_path="${log_folder}/3xipl.log" iplimit_log_path="${log_folder}/3xipl.log"
@ -127,7 +129,7 @@ update_menu() {
fi fi
wget -O /usr/bin/x-ui https://raw.githubusercontent.com/MHSanaei/3x-ui/main/x-ui.sh wget -O /usr/bin/x-ui https://raw.githubusercontent.com/MHSanaei/3x-ui/main/x-ui.sh
chmod +x /usr/local/x-ui/x-ui.sh chmod +x ${xui_folder}/x-ui.sh
chmod +x /usr/bin/x-ui chmod +x /usr/bin/x-ui
if [[ $? == 0 ]]; then if [[ $? == 0 ]]; then
@ -176,13 +178,13 @@ uninstall() {
else else
systemctl stop x-ui systemctl stop x-ui
systemctl disable x-ui systemctl disable x-ui
rm /etc/systemd/system/x-ui.service -f rm ${xui_service}/x-ui.service -f
systemctl daemon-reload systemctl daemon-reload
systemctl reset-failed systemctl reset-failed
fi fi
rm /etc/x-ui/ -rf rm /etc/x-ui/ -rf
rm /usr/local/x-ui/ -rf rm ${xui_folder}/ -rf
echo "" echo ""
echo -e "Uninstalled Successfully.\n" echo -e "Uninstalled Successfully.\n"
@ -210,9 +212,9 @@ reset_user() {
read -rp "Do you want to disable currently configured two-factor authentication? (y/n): " twoFactorConfirm read -rp "Do you want to disable currently configured two-factor authentication? (y/n): " twoFactorConfirm
if [[ $twoFactorConfirm != "y" && $twoFactorConfirm != "Y" ]]; then if [[ $twoFactorConfirm != "y" && $twoFactorConfirm != "Y" ]]; then
/usr/local/x-ui/x-ui setting -username ${config_account} -password ${config_password} -resetTwoFactor false >/dev/null 2>&1 ${xui_folder}/x-ui setting -username ${config_account} -password ${config_password} -resetTwoFactor false >/dev/null 2>&1
else else
/usr/local/x-ui/x-ui setting -username ${config_account} -password ${config_password} -resetTwoFactor true >/dev/null 2>&1 ${xui_folder}/x-ui setting -username ${config_account} -password ${config_password} -resetTwoFactor true >/dev/null 2>&1
echo -e "Two factor authentication has been disabled." echo -e "Two factor authentication has been disabled."
fi fi
@ -274,7 +276,7 @@ EOF
fi fi
chmod 755 ${certDir}/* >/dev/null 2>&1 chmod 755 ${certDir}/* >/dev/null 2>&1
/usr/local/x-ui/x-ui cert -webCert "${certDir}/fullchain.pem" -webCertKey "${certDir}/privkey.pem" >/dev/null 2>&1 ${xui_folder}/x-ui cert -webCert "${certDir}/fullchain.pem" -webCertKey "${certDir}/privkey.pem" >/dev/null 2>&1
LOGI "Self-signed certificate configured. Browsers will show a warning." LOGI "Self-signed certificate configured. Browsers will show a warning."
return 0 return 0
} }
@ -291,7 +293,7 @@ reset_webbasepath() {
config_webBasePath=$(gen_random_string 18) config_webBasePath=$(gen_random_string 18)
# Apply the new web base path setting # Apply the new web base path setting
/usr/local/x-ui/x-ui setting -webBasePath "${config_webBasePath}" >/dev/null 2>&1 ${xui_folder}/x-ui setting -webBasePath "${config_webBasePath}" >/dev/null 2>&1
echo -e "Web base path has been reset to: ${green}${config_webBasePath}${plain}" echo -e "Web base path has been reset to: ${green}${config_webBasePath}${plain}"
echo -e "${green}Please use the new web base path to access the panel.${plain}" echo -e "${green}Please use the new web base path to access the panel.${plain}"
@ -306,13 +308,13 @@ reset_config() {
fi fi
return 0 return 0
fi fi
/usr/local/x-ui/x-ui setting -reset ${xui_folder}/x-ui setting -reset
echo -e "All panel settings have been reset to default." echo -e "All panel settings have been reset to default."
restart restart
} }
check_config() { check_config() {
local info=$(/usr/local/x-ui/x-ui setting -show true) local info=$(${xui_folder}/x-ui setting -show true)
if [[ $? != 0 ]]; then if [[ $? != 0 ]]; then
LOGE "get current settings error, please check logs" LOGE "get current settings error, please check logs"
show_menu show_menu
@ -322,7 +324,7 @@ check_config() {
local existing_webBasePath=$(echo "$info" | grep -Eo 'webBasePath: .+' | awk '{print $2}') local existing_webBasePath=$(echo "$info" | grep -Eo 'webBasePath: .+' | awk '{print $2}')
local existing_port=$(echo "$info" | grep -Eo 'port: .+' | awk '{print $2}') local existing_port=$(echo "$info" | grep -Eo 'port: .+' | awk '{print $2}')
local existing_cert=$(/usr/local/x-ui/x-ui setting -getCert true | grep 'cert:' | awk -F': ' '{print $2}' | tr -d '[:space:]') local existing_cert=$(${xui_folder}/x-ui setting -getCert true | grep 'cert:' | awk -F': ' '{print $2}' | tr -d '[:space:]')
local server_ip=$(curl -s --max-time 3 https://api.ipify.org) local server_ip=$(curl -s --max-time 3 https://api.ipify.org)
if [ -z "$server_ip" ]; then if [ -z "$server_ip" ]; then
server_ip=$(curl -s --max-time 3 https://4.ident.me) server_ip=$(curl -s --max-time 3 https://4.ident.me)
@ -363,7 +365,7 @@ set_port() {
LOGD "Cancelled" LOGD "Cancelled"
before_show_menu before_show_menu
else else
/usr/local/x-ui/x-ui setting -port ${port} ${xui_folder}/x-ui setting -port ${port}
echo -e "The port is set, Please restart the panel now, and use the new port ${green}${port}${plain} to access web panel" echo -e "The port is set, Please restart the panel now, and use the new port ${green}${port}${plain} to access web panel"
confirm_restart confirm_restart
fi fi
@ -655,7 +657,7 @@ check_status() {
return 1 return 1
fi fi
else else
if [[ ! -f /etc/systemd/system/x-ui.service ]]; then if [[ ! -f ${xui_service}/x-ui.service ]]; then
return 2 return 2
fi fi
temp=$(systemctl status x-ui | grep Active | awk '{print $3}' | cut -d "(" -f2 | cut -d ")" -f1) temp=$(systemctl status x-ui | grep Active | awk '{print $3}' | cut -d "(" -f2 | cut -d ")" -f1)
@ -977,7 +979,7 @@ update_geo() {
echo -e "${green}\t0.${plain} Back to Main Menu" echo -e "${green}\t0.${plain} Back to Main Menu"
read -rp "Choose an option: " choice read -rp "Choose an option: " choice
cd /usr/local/x-ui/bin cd ${xui_folder}/bin
case "$choice" in case "$choice" in
0) 0)
@ -1119,7 +1121,7 @@ ssl_cert_issue_main() {
local webKeyFile="/root/cert/${domain}/privkey.pem" local webKeyFile="/root/cert/${domain}/privkey.pem"
if [[ -f "${webCertFile}" && -f "${webKeyFile}" ]]; then if [[ -f "${webCertFile}" && -f "${webKeyFile}" ]]; then
/usr/local/x-ui/x-ui cert -webCert "$webCertFile" -webCertKey "$webKeyFile" ${xui_folder}/x-ui cert -webCert "$webCertFile" -webCertKey "$webKeyFile"
echo "Panel paths set for domain: $domain" echo "Panel paths set for domain: $domain"
echo " - Certificate File: $webCertFile" echo " - Certificate File: $webCertFile"
echo " - Private Key File: $webKeyFile" echo " - Private Key File: $webKeyFile"
@ -1154,8 +1156,8 @@ ssl_cert_issue_main() {
ssl_cert_issue_for_ip() { ssl_cert_issue_for_ip() {
LOGI "Starting automatic SSL certificate generation for server IP..." LOGI "Starting automatic SSL certificate generation for server IP..."
local existing_webBasePath=$(/usr/local/x-ui/x-ui setting -show true | grep -Eo 'webBasePath: .+' | awk '{print $2}') local existing_webBasePath=$(${xui_folder}/x-ui setting -show true | grep -Eo 'webBasePath: .+' | awk '{print $2}')
local existing_port=$(/usr/local/x-ui/x-ui setting -show true | grep -Eo 'port: .+' | awk '{print $2}') local existing_port=$(${xui_folder}/x-ui setting -show true | grep -Eo 'port: .+' | awk '{print $2}')
# Get server IP # Get server IP
local server_ip=$(curl -s --max-time 3 https://api.ipify.org) local server_ip=$(curl -s --max-time 3 https://api.ipify.org)
@ -1265,7 +1267,7 @@ ssl_cert_issue_for_ip() {
local webKeyFile="/root/cert/${server_ip}/privkey.pem" local webKeyFile="/root/cert/${server_ip}/privkey.pem"
if [[ -f "$webCertFile" && -f "$webKeyFile" ]]; then if [[ -f "$webCertFile" && -f "$webKeyFile" ]]; then
/usr/local/x-ui/x-ui cert -webCert "$webCertFile" -webCertKey "$webKeyFile" ${xui_folder}/x-ui cert -webCert "$webCertFile" -webCertKey "$webKeyFile"
LOGI "Certificate configured for panel" LOGI "Certificate configured for panel"
LOGI " - Certificate File: $webCertFile" LOGI " - Certificate File: $webCertFile"
LOGI " - Private Key File: $webKeyFile" LOGI " - Private Key File: $webKeyFile"
@ -1280,8 +1282,8 @@ ssl_cert_issue_for_ip() {
} }
ssl_cert_issue() { ssl_cert_issue() {
local existing_webBasePath=$(/usr/local/x-ui/x-ui setting -show true | grep -Eo 'webBasePath: .+' | awk '{print $2}') local existing_webBasePath=$(${xui_folder}/x-ui setting -show true | grep -Eo 'webBasePath: .+' | awk '{print $2}')
local existing_port=$(/usr/local/x-ui/x-ui setting -show true | grep -Eo 'port: .+' | awk '{print $2}') local existing_port=$(${xui_folder}/x-ui setting -show true | grep -Eo 'port: .+' | awk '{print $2}')
# check for acme.sh first # check for acme.sh first
if ! command -v ~/.acme.sh/acme.sh &>/dev/null; then if ! command -v ~/.acme.sh/acme.sh &>/dev/null; then
echo "acme.sh could not be found. we will install it" echo "acme.sh could not be found. we will install it"
@ -1446,7 +1448,7 @@ ssl_cert_issue() {
local webKeyFile="/root/cert/${domain}/privkey.pem" local webKeyFile="/root/cert/${domain}/privkey.pem"
if [[ -f "$webCertFile" && -f "$webKeyFile" ]]; then if [[ -f "$webCertFile" && -f "$webKeyFile" ]]; then
/usr/local/x-ui/x-ui cert -webCert "$webCertFile" -webCertKey "$webKeyFile" ${xui_folder}/x-ui cert -webCert "$webCertFile" -webCertKey "$webKeyFile"
LOGI "Panel paths set for domain: $domain" LOGI "Panel paths set for domain: $domain"
LOGI " - Certificate File: $webCertFile" LOGI " - Certificate File: $webCertFile"
LOGI " - Private Key File: $webKeyFile" LOGI " - Private Key File: $webKeyFile"
@ -1461,8 +1463,8 @@ ssl_cert_issue() {
} }
ssl_cert_issue_CF() { ssl_cert_issue_CF() {
local existing_webBasePath=$(/usr/local/x-ui/x-ui setting -show true | grep -Eo 'webBasePath: .+' | awk '{print $2}') local existing_webBasePath=$(${xui_folder}/x-ui setting -show true | grep -Eo 'webBasePath: .+' | awk '{print $2}')
local existing_port=$(/usr/local/x-ui/x-ui setting -show true | grep -Eo 'port: .+' | awk '{print $2}') local existing_port=$(${xui_folder}/x-ui setting -show true | grep -Eo 'port: .+' | awk '{print $2}')
LOGI "****** Instructions for Use ******" LOGI "****** Instructions for Use ******"
LOGI "Follow the steps below to complete the process:" LOGI "Follow the steps below to complete the process:"
LOGI "1. Cloudflare Registered E-mail." LOGI "1. Cloudflare Registered E-mail."
@ -1586,7 +1588,7 @@ ssl_cert_issue_CF() {
local webKeyFile="${certPath}/privkey.pem" local webKeyFile="${certPath}/privkey.pem"
if [[ -f "$webCertFile" && -f "$webKeyFile" ]]; then if [[ -f "$webCertFile" && -f "$webKeyFile" ]]; then
/usr/local/x-ui/x-ui cert -webCert "$webCertFile" -webCertKey "$webKeyFile" ${xui_folder}/x-ui cert -webCert "$webCertFile" -webCertKey "$webKeyFile"
LOGI "Panel paths set for domain: $CF_Domain" LOGI "Panel paths set for domain: $CF_Domain"
LOGI " - Certificate File: $webCertFile" LOGI " - Certificate File: $webCertFile"
LOGI " - Private Key File: $webKeyFile" LOGI " - Private Key File: $webKeyFile"
@ -2050,11 +2052,11 @@ SSH_port_forwarding() {
break break
fi fi
done done
local existing_webBasePath=$(/usr/local/x-ui/x-ui setting -show true | grep -Eo 'webBasePath: .+' | awk '{print $2}') local existing_webBasePath=$(${xui_folder}/x-ui setting -show true | grep -Eo 'webBasePath: .+' | awk '{print $2}')
local existing_port=$(/usr/local/x-ui/x-ui setting -show true | grep -Eo 'port: .+' | awk '{print $2}') local existing_port=$(${xui_folder}/x-ui setting -show true | grep -Eo 'port: .+' | awk '{print $2}')
local existing_listenIP=$(/usr/local/x-ui/x-ui setting -getListen true | grep -Eo 'listenIP: .+' | awk '{print $2}') local existing_listenIP=$(${xui_folder}/x-ui setting -getListen true | grep -Eo 'listenIP: .+' | awk '{print $2}')
local existing_cert=$(/usr/local/x-ui/x-ui setting -getCert true | grep -Eo 'cert: .+' | awk '{print $2}') local existing_cert=$(${xui_folder}/x-ui setting -getCert true | grep -Eo 'cert: .+' | awk '{print $2}')
local existing_key=$(/usr/local/x-ui/x-ui setting -getCert true | grep -Eo 'key: .+' | awk '{print $2}') local existing_key=$(${xui_folder}/x-ui setting -getCert true | grep -Eo 'key: .+' | awk '{print $2}')
local config_listenIP="" local config_listenIP=""
local listen_choice="" local listen_choice=""
@ -2095,7 +2097,7 @@ SSH_port_forwarding() {
config_listenIP="127.0.0.1" config_listenIP="127.0.0.1"
[[ "$listen_choice" == "2" ]] && read -rp "Enter custom IP to listen on: " config_listenIP [[ "$listen_choice" == "2" ]] && read -rp "Enter custom IP to listen on: " config_listenIP
/usr/local/x-ui/x-ui setting -listenIP "${config_listenIP}" >/dev/null 2>&1 ${xui_folder}/x-ui setting -listenIP "${config_listenIP}" >/dev/null 2>&1
echo -e "${green}listen IP has been set to ${config_listenIP}.${plain}" echo -e "${green}listen IP has been set to ${config_listenIP}.${plain}"
echo -e "\n${green}SSH Port Forwarding Configuration:${plain}" echo -e "\n${green}SSH Port Forwarding Configuration:${plain}"
echo -e "Standard SSH command:" echo -e "Standard SSH command:"
@ -2111,7 +2113,7 @@ SSH_port_forwarding() {
fi fi
;; ;;
2) 2)
/usr/local/x-ui/x-ui setting -listenIP 0.0.0.0 >/dev/null 2>&1 ${xui_folder}/x-ui setting -listenIP 0.0.0.0 >/dev/null 2>&1
echo -e "${green}Listen IP has been cleared.${plain}" echo -e "${green}Listen IP has been cleared.${plain}"
restart restart
;; ;;