mirror of
https://github.com/MHSanaei/3x-ui.git
synced 2026-04-14 19:45:47 +00:00
feat #3910: enhance IP detection method to prioritize local interface and improve reliability
This commit is contained in:
parent
258b08fff3
commit
f438a7dd50
1 changed files with 57 additions and 29 deletions
86
x-ui.sh
86
x-ui.sh
|
|
@ -50,6 +50,59 @@ is_domain() {
|
||||||
[[ "$1" =~ ^([A-Za-z0-9](-*[A-Za-z0-9])*\.)+(xn--[a-z0-9]{2,}|[A-Za-z]{2,})$ ]] && return 0 || return 1
|
[[ "$1" =~ ^([A-Za-z0-9](-*[A-Za-z0-9])*\.)+(xn--[a-z0-9]{2,}|[A-Za-z]{2,})$ ]] && return 0 || return 1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Detect server IP - tries local interface first, then external services
|
||||||
|
# Usage: get_server_ip [interactive]
|
||||||
|
# - No argument: returns IP silently (for scripts)
|
||||||
|
# - "interactive": shows IP and allows user to correct it
|
||||||
|
# Sets global variable: DETECTED_SERVER_IP
|
||||||
|
get_server_ip() {
|
||||||
|
local interactive="${1:-}"
|
||||||
|
local ip=""
|
||||||
|
|
||||||
|
# Method 1: Try to get IP from network interface (avoids proxy issues)
|
||||||
|
if command -v ip >/dev/null 2>&1; then
|
||||||
|
ip=$(ip -4 addr show scope global 2>/dev/null | grep -oP 'inet \K[\d.]+' | head -n1)
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Method 2: Fallback to external services (multiple for reliability)
|
||||||
|
if [ -z "$ip" ]; then
|
||||||
|
local URL_lists=(
|
||||||
|
"https://api.ipify.org"
|
||||||
|
"https://api4.ipify.org"
|
||||||
|
"https://ipv4.icanhazip.com"
|
||||||
|
"https://v4.api.ipinfo.io/ip"
|
||||||
|
"https://ipv4.myexternalip.com/raw"
|
||||||
|
"https://4.ident.me"
|
||||||
|
"https://check-host.net/ip"
|
||||||
|
)
|
||||||
|
for url in "${URL_lists[@]}"; do
|
||||||
|
local response=$(curl -s -w "\n%{http_code}" --max-time 3 "${url}" 2>/dev/null)
|
||||||
|
local http_code=$(echo "$response" | tail -n1)
|
||||||
|
local ip_result=$(echo "$response" | head -n-1 | tr -d '[:space:]')
|
||||||
|
if [[ "${http_code}" == "200" && -n "${ip_result}" ]]; then
|
||||||
|
ip="${ip_result}"
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Interactive mode: show IP and allow user to change
|
||||||
|
if [ "$interactive" = "interactive" ]; then
|
||||||
|
if [ -n "$ip" ]; then
|
||||||
|
echo -e "${green}[INF] Server IP detected: ${ip}${plain}" >&2
|
||||||
|
else
|
||||||
|
echo -e "${yellow}Could not detect server IP automatically.${plain}" >&2
|
||||||
|
fi
|
||||||
|
read -rp "Press Enter to use this IP, or type a different IP: " user_input </dev/tty
|
||||||
|
if [ -n "$user_input" ]; then
|
||||||
|
ip="$user_input"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
DETECTED_SERVER_IP="$ip"
|
||||||
|
echo "$ip"
|
||||||
|
}
|
||||||
|
|
||||||
# check root
|
# check root
|
||||||
[[ $EUID -ne 0 ]] && LOGE "ERROR: You must be root to run this script! \n" && exit 1
|
[[ $EUID -ne 0 ]] && LOGE "ERROR: You must be root to run this script! \n" && exit 1
|
||||||
|
|
||||||
|
|
@ -291,10 +344,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=$(${xui_folder}/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=$(get_server_ip)
|
||||||
if [ -z "$server_ip" ]; then
|
|
||||||
server_ip=$(curl -s --max-time 3 https://4.ident.me)
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [[ -n "$existing_cert" ]]; then
|
if [[ -n "$existing_cert" ]]; then
|
||||||
local domain=$(basename "$(dirname "$existing_cert")")
|
local domain=$(basename "$(dirname "$existing_cert")")
|
||||||
|
|
@ -1128,19 +1178,14 @@ ssl_cert_issue_for_ip() {
|
||||||
local existing_webBasePath=$(${xui_folder}/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=$(${xui_folder}/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 interface first, then external services)
|
||||||
local server_ip=$(curl -s --max-time 3 https://api.ipify.org)
|
local server_ip=$(get_server_ip interactive)
|
||||||
if [ -z "$server_ip" ]; then
|
|
||||||
server_ip=$(curl -s --max-time 3 https://4.ident.me)
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ -z "$server_ip" ]; then
|
if [ -z "$server_ip" ]; then
|
||||||
LOGE "Failed to get server IP address"
|
LOGE "Failed to get server IP address"
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
LOGI "Server IP detected: ${server_ip}"
|
|
||||||
|
|
||||||
# Ask for optional IPv6
|
# Ask for optional IPv6
|
||||||
local ipv6_addr=""
|
local ipv6_addr=""
|
||||||
read -rp "Do you have an IPv6 address to include? (leave empty to skip): " ipv6_addr
|
read -rp "Do you have an IPv6 address to include? (leave empty to skip): " ipv6_addr
|
||||||
|
|
@ -2062,24 +2107,7 @@ iplimit_remove_conflicts() {
|
||||||
}
|
}
|
||||||
|
|
||||||
SSH_port_forwarding() {
|
SSH_port_forwarding() {
|
||||||
local URL_lists=(
|
local server_ip=$(get_server_ip)
|
||||||
"https://api4.ipify.org"
|
|
||||||
"https://ipv4.icanhazip.com"
|
|
||||||
"https://v4.api.ipinfo.io/ip"
|
|
||||||
"https://ipv4.myexternalip.com/raw"
|
|
||||||
"https://4.ident.me"
|
|
||||||
"https://check-host.net/ip"
|
|
||||||
)
|
|
||||||
local server_ip=""
|
|
||||||
for ip_address in "${URL_lists[@]}"; do
|
|
||||||
local response=$(curl -s -w "\n%{http_code}" --max-time 3 "${ip_address}" 2>/dev/null)
|
|
||||||
local http_code=$(echo "$response" | tail -n1)
|
|
||||||
local ip_result=$(echo "$response" | head -n-1 | tr -d '[:space:]')
|
|
||||||
if [[ "${http_code}" == "200" && -n "${ip_result}" ]]; then
|
|
||||||
server_ip="${ip_result}"
|
|
||||||
break
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
|
|
||||||
local existing_webBasePath=$(${xui_folder}/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=$(${xui_folder}/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}')
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue