mirror of
https://github.com/MHSanaei/3x-ui.git
synced 2025-03-01 01:20:49 +03:00

* Update x-ui.sh with ufw port settings It really costs time when adding rules for a large range, if for loop is used in bash. Changed it to built-in port range support in ufw. This commit is to correct the previous one, which cannot handle port range settings correctly. Corrected the confirmation of the deleted ports.
1411 lines
41 KiB
Bash
1411 lines
41 KiB
Bash
#!/bin/bash
|
|
|
|
red='\033[0;31m'
|
|
green='\033[0;32m'
|
|
yellow='\033[0;33m'
|
|
plain='\033[0m'
|
|
|
|
#Add some basic function here
|
|
function LOGD() {
|
|
echo -e "${yellow}[DEG] $* ${plain}"
|
|
}
|
|
|
|
function LOGE() {
|
|
echo -e "${red}[ERR] $* ${plain}"
|
|
}
|
|
|
|
function LOGI() {
|
|
echo -e "${green}[INF] $* ${plain}"
|
|
}
|
|
|
|
# check root
|
|
[[ $EUID -ne 0 ]] && LOGE "ERROR: You must be root to run this script! \n" && exit 1
|
|
|
|
# Check OS and set release variable
|
|
if [[ -f /etc/os-release ]]; then
|
|
source /etc/os-release
|
|
release=$ID
|
|
elif [[ -f /usr/lib/os-release ]]; then
|
|
source /usr/lib/os-release
|
|
release=$ID
|
|
else
|
|
echo "Failed to check the system OS, please contact the author!" >&2
|
|
exit 1
|
|
fi
|
|
|
|
echo "The OS release is: $release"
|
|
|
|
os_version=""
|
|
os_version=$(grep -i version_id /etc/os-release | cut -d \" -f2 | cut -d . -f1)
|
|
|
|
if [[ "${release}" == "arch" ]]; then
|
|
echo "Your OS is Arch Linux"
|
|
elif [[ "${release}" == "manjaro" ]]; then
|
|
echo "Your OS is Manjaro"
|
|
elif [[ "${release}" == "armbian" ]]; then
|
|
echo "Your OS is Armbian"
|
|
elif [[ "${release}" == "centos" ]]; then
|
|
if [[ ${os_version} -lt 8 ]]; then
|
|
echo -e "${red} Please use CentOS 8 or higher ${plain}\n" && exit 1
|
|
fi
|
|
elif [[ "${release}" == "ubuntu" ]]; then
|
|
if [[ ${os_version} -lt 20 ]]; then
|
|
echo -e "${red} Please use Ubuntu 20 or higher version!${plain}\n" && exit 1
|
|
fi
|
|
elif [[ "${release}" == "fedora" ]]; then
|
|
if [[ ${os_version} -lt 36 ]]; then
|
|
echo -e "${red} Please use Fedora 36 or higher version!${plain}\n" && exit 1
|
|
fi
|
|
elif [[ "${release}" == "debian" ]]; then
|
|
if [[ ${os_version} -lt 11 ]]; then
|
|
echo -e "${red} Please use Debian 11 or higher ${plain}\n" && exit 1
|
|
fi
|
|
elif [[ "${release}" == "almalinux" ]]; then
|
|
if [[ ${os_version} -lt 9 ]]; then
|
|
echo -e "${red} Please use AlmaLinux 9 or higher ${plain}\n" && exit 1
|
|
fi
|
|
elif [[ "${release}" == "rocky" ]]; then
|
|
if [[ ${os_version} -lt 9 ]]; then
|
|
echo -e "${red} Please use Rocky Linux 9 or higher ${plain}\n" && exit 1
|
|
fi
|
|
elif [[ "${release}" == "oracle" ]]; then
|
|
if [[ ${os_version} -lt 8 ]]; then
|
|
echo -e "${red} Please use Oracle Linux 8 or higher ${plain}\n" && exit 1
|
|
fi
|
|
else
|
|
echo -e "${red}Your operating system is not supported by this script.${plain}\n"
|
|
echo "Please ensure you are using one of the following supported operating systems:"
|
|
echo "- Ubuntu 20.04+"
|
|
echo "- Debian 11+"
|
|
echo "- CentOS 8+"
|
|
echo "- Fedora 36+"
|
|
echo "- Arch Linux"
|
|
echo "- Manjaro"
|
|
echo "- Armbian"
|
|
echo "- AlmaLinux 9+"
|
|
echo "- Rocky Linux 9+"
|
|
echo "- Oracle Linux 8+"
|
|
exit 1
|
|
|
|
fi
|
|
|
|
# Declare Variables
|
|
log_folder="${XUI_LOG_FOLDER:=/var/log}"
|
|
iplimit_log_path="${log_folder}/3xipl.log"
|
|
iplimit_banned_log_path="${log_folder}/3xipl-banned.log"
|
|
|
|
confirm() {
|
|
if [[ $# > 1 ]]; then
|
|
echo && read -p "$1 [Default $2]: " temp
|
|
if [[ "${temp}" == "" ]]; then
|
|
temp=$2
|
|
fi
|
|
else
|
|
read -p "$1 [y/n]: " temp
|
|
fi
|
|
if [[ "${temp}" == "y" || "${temp}" == "Y" ]]; then
|
|
return 0
|
|
else
|
|
return 1
|
|
fi
|
|
}
|
|
|
|
confirm_restart() {
|
|
confirm "Restart the panel, Attention: Restarting the panel will also restart xray" "y"
|
|
if [[ $? == 0 ]]; then
|
|
restart
|
|
else
|
|
show_menu
|
|
fi
|
|
}
|
|
|
|
before_show_menu() {
|
|
echo && echo -n -e "${yellow}Press enter to return to the main menu: ${plain}" && read temp
|
|
show_menu
|
|
}
|
|
|
|
install() {
|
|
bash <(curl -Ls https://raw.githubusercontent.com/MHSanaei/3x-ui/main/install.sh)
|
|
if [[ $? == 0 ]]; then
|
|
if [[ $# == 0 ]]; then
|
|
start
|
|
else
|
|
start 0
|
|
fi
|
|
fi
|
|
}
|
|
|
|
update() {
|
|
confirm "This function will forcefully reinstall the latest version, and the data will not be lost. Do you want to continue?" "y"
|
|
if [[ $? != 0 ]]; then
|
|
LOGE "Cancelled"
|
|
if [[ $# == 0 ]]; then
|
|
before_show_menu
|
|
fi
|
|
return 0
|
|
fi
|
|
bash <(curl -Ls https://raw.githubusercontent.com/MHSanaei/3x-ui/main/install.sh)
|
|
if [[ $? == 0 ]]; then
|
|
LOGI "Update is complete, Panel has automatically restarted "
|
|
exit 0
|
|
fi
|
|
}
|
|
|
|
custom_version() {
|
|
echo "Enter the panel version (like 2.0.0):"
|
|
read panel_version
|
|
|
|
if [ -z "$panel_version" ]; then
|
|
echo "Panel version cannot be empty. Exiting."
|
|
exit 1
|
|
fi
|
|
|
|
download_link="https://raw.githubusercontent.com/mhsanaei/3x-ui/master/install.sh"
|
|
|
|
# Use the entered panel version in the download link
|
|
install_command="bash <(curl -Ls $download_link) v$panel_version"
|
|
|
|
echo "Downloading and installing panel version $panel_version..."
|
|
eval $install_command
|
|
}
|
|
|
|
# Function to handle the deletion of the script file
|
|
delete_script() {
|
|
rm "$0" # Remove the script file itself
|
|
exit 1
|
|
}
|
|
|
|
uninstall() {
|
|
confirm "Are you sure you want to uninstall the panel? xray will also uninstalled!" "n"
|
|
if [[ $? != 0 ]]; then
|
|
if [[ $# == 0 ]]; then
|
|
show_menu
|
|
fi
|
|
return 0
|
|
fi
|
|
systemctl stop x-ui
|
|
systemctl disable x-ui
|
|
rm /etc/systemd/system/x-ui.service -f
|
|
systemctl daemon-reload
|
|
systemctl reset-failed
|
|
rm /etc/x-ui/ -rf
|
|
rm /usr/local/x-ui/ -rf
|
|
|
|
echo ""
|
|
echo -e "Uninstalled Successfully.\n"
|
|
echo "If you need to install this panel again, you can use below command:"
|
|
echo -e "${green}bash <(curl -Ls https://raw.githubusercontent.com/mhsanaei/3x-ui/master/install.sh)${plain}"
|
|
echo ""
|
|
# Trap the SIGTERM signal
|
|
trap delete_script SIGTERM
|
|
delete_script
|
|
}
|
|
|
|
reset_user() {
|
|
confirm "Are you sure to reset the username and password of the panel?" "n"
|
|
if [[ $? != 0 ]]; then
|
|
if [[ $# == 0 ]]; then
|
|
show_menu
|
|
fi
|
|
return 0
|
|
fi
|
|
read -rp "Please set the login username [default is a random username]: " config_account
|
|
[[ -z $config_account ]] && config_account=$(date +%s%N | md5sum | cut -c 1-8)
|
|
read -rp "Please set the login password [default is a random password]: " config_password
|
|
[[ -z $config_password ]] && config_password=$(date +%s%N | md5sum | cut -c 1-8)
|
|
/usr/local/x-ui/x-ui setting -username ${config_account} -password ${config_password} >/dev/null 2>&1
|
|
/usr/local/x-ui/x-ui setting -remove_secret >/dev/null 2>&1
|
|
echo -e "Panel login username has been reset to: ${green} ${config_account} ${plain}"
|
|
echo -e "Panel login password has been reset to: ${green} ${config_password} ${plain}"
|
|
echo -e "${yellow} Panel login secret token disabled ${plain}"
|
|
echo -e "${green} Please use the new login username and password to access the X-UI panel. Also remember them! ${plain}"
|
|
confirm_restart
|
|
}
|
|
|
|
reset_config() {
|
|
confirm "Are you sure you want to reset all panel settings, Account data will not be lost, Username and password will not change" "n"
|
|
if [[ $? != 0 ]]; then
|
|
if [[ $# == 0 ]]; then
|
|
show_menu
|
|
fi
|
|
return 0
|
|
fi
|
|
/usr/local/x-ui/x-ui setting -reset
|
|
echo -e "All panel settings have been reset to default, Please restart the panel now, and use the default ${green}2053${plain} Port to Access the web Panel"
|
|
confirm_restart
|
|
}
|
|
|
|
check_config() {
|
|
info=$(/usr/local/x-ui/x-ui setting -show true)
|
|
if [[ $? != 0 ]]; then
|
|
LOGE "get current settings error, please check logs"
|
|
show_menu
|
|
fi
|
|
LOGI "${info}"
|
|
}
|
|
|
|
set_port() {
|
|
echo && echo -n -e "Enter port number[1-65535]: " && read port
|
|
if [[ -z "${port}" ]]; then
|
|
LOGD "Cancelled"
|
|
before_show_menu
|
|
else
|
|
/usr/local/x-ui/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"
|
|
confirm_restart
|
|
fi
|
|
}
|
|
|
|
start() {
|
|
check_status
|
|
if [[ $? == 0 ]]; then
|
|
echo ""
|
|
LOGI "Panel is running, No need to start again, If you need to restart, please select restart"
|
|
else
|
|
systemctl start x-ui
|
|
sleep 2
|
|
check_status
|
|
if [[ $? == 0 ]]; then
|
|
LOGI "x-ui Started Successfully"
|
|
else
|
|
LOGE "panel Failed to start, Probably because it takes longer than two seconds to start, Please check the log information later"
|
|
fi
|
|
fi
|
|
|
|
if [[ $# == 0 ]]; then
|
|
before_show_menu
|
|
fi
|
|
}
|
|
|
|
stop() {
|
|
check_status
|
|
if [[ $? == 1 ]]; then
|
|
echo ""
|
|
LOGI "Panel stopped, No need to stop again!"
|
|
else
|
|
systemctl stop x-ui
|
|
sleep 2
|
|
check_status
|
|
if [[ $? == 1 ]]; then
|
|
LOGI "x-ui and xray stopped successfully"
|
|
else
|
|
LOGE "Panel stop failed, Probably because the stop time exceeds two seconds, Please check the log information later"
|
|
fi
|
|
fi
|
|
|
|
if [[ $# == 0 ]]; then
|
|
before_show_menu
|
|
fi
|
|
}
|
|
|
|
restart() {
|
|
systemctl restart x-ui
|
|
sleep 2
|
|
check_status
|
|
if [[ $? == 0 ]]; then
|
|
LOGI "x-ui and xray Restarted successfully"
|
|
else
|
|
LOGE "Panel restart failed, Probably because it takes longer than two seconds to start, Please check the log information later"
|
|
fi
|
|
if [[ $# == 0 ]]; then
|
|
before_show_menu
|
|
fi
|
|
}
|
|
|
|
status() {
|
|
systemctl status x-ui -l
|
|
if [[ $# == 0 ]]; then
|
|
before_show_menu
|
|
fi
|
|
}
|
|
|
|
enable() {
|
|
systemctl enable x-ui
|
|
if [[ $? == 0 ]]; then
|
|
LOGI "x-ui Set to boot automatically on startup successfully"
|
|
else
|
|
LOGE "x-ui Failed to set Autostart"
|
|
fi
|
|
|
|
if [[ $# == 0 ]]; then
|
|
before_show_menu
|
|
fi
|
|
}
|
|
|
|
disable() {
|
|
systemctl disable x-ui
|
|
if [[ $? == 0 ]]; then
|
|
LOGI "x-ui Autostart Cancelled successfully"
|
|
else
|
|
LOGE "x-ui Failed to cancel autostart"
|
|
fi
|
|
|
|
if [[ $# == 0 ]]; then
|
|
before_show_menu
|
|
fi
|
|
}
|
|
|
|
show_log() {
|
|
journalctl -u x-ui.service -e --no-pager -f
|
|
if [[ $# == 0 ]]; then
|
|
before_show_menu
|
|
fi
|
|
}
|
|
|
|
show_banlog() {
|
|
if test -f "${iplimit_banned_log_path}"; then
|
|
if [[ -s "${iplimit_banned_log_path}" ]]; then
|
|
cat ${iplimit_banned_log_path}
|
|
else
|
|
echo -e "${red}Log file is empty.${plain}\n"
|
|
fi
|
|
else
|
|
echo -e "${red}Log file not found. Please Install Fail2ban and IP Limit first.${plain}\n"
|
|
fi
|
|
}
|
|
|
|
bbr_menu() {
|
|
echo -e "${green}\t1.${plain} Enable BBR"
|
|
echo -e "${green}\t2.${plain} Disable BBR"
|
|
echo -e "${green}\t0.${plain} Back to Main Menu"
|
|
read -p "Choose an option: " choice
|
|
case "$choice" in
|
|
0)
|
|
show_menu
|
|
;;
|
|
1)
|
|
enable_bbr
|
|
;;
|
|
2)
|
|
disable_bbr
|
|
;;
|
|
*) echo "Invalid choice" ;;
|
|
esac
|
|
}
|
|
|
|
disable_bbr() {
|
|
|
|
if ! grep -q "net.core.default_qdisc=fq" /etc/sysctl.conf || ! grep -q "net.ipv4.tcp_congestion_control=bbr" /etc/sysctl.conf; then
|
|
echo -e "${yellow}BBR is not currently enabled.${plain}"
|
|
exit 0
|
|
fi
|
|
|
|
# Replace BBR with CUBIC configurations
|
|
sed -i 's/net.core.default_qdisc=fq/net.core.default_qdisc=pfifo_fast/' /etc/sysctl.conf
|
|
sed -i 's/net.ipv4.tcp_congestion_control=bbr/net.ipv4.tcp_congestion_control=cubic/' /etc/sysctl.conf
|
|
|
|
# Apply changes
|
|
sysctl -p
|
|
|
|
# Verify that BBR is replaced with CUBIC
|
|
if [[ $(sysctl net.ipv4.tcp_congestion_control | awk '{print $3}') == "cubic" ]]; then
|
|
echo -e "${green}BBR has been replaced with CUBIC successfully.${plain}"
|
|
else
|
|
echo -e "${red}Failed to replace BBR with CUBIC. Please check your system configuration.${plain}"
|
|
fi
|
|
}
|
|
|
|
enable_bbr() {
|
|
if grep -q "net.core.default_qdisc=fq" /etc/sysctl.conf && grep -q "net.ipv4.tcp_congestion_control=bbr" /etc/sysctl.conf; then
|
|
echo -e "${green}BBR is already enabled!${plain}"
|
|
exit 0
|
|
fi
|
|
|
|
# Check the OS and install necessary packages
|
|
case "${release}" in
|
|
ubuntu | debian | armbian)
|
|
apt-get update && apt-get install -yqq --no-install-recommends ca-certificates
|
|
;;
|
|
centos | almalinux | rocky | oracle)
|
|
yum -y update && yum -y install ca-certificates
|
|
;;
|
|
fedora)
|
|
dnf -y update && dnf -y install ca-certificates
|
|
;;
|
|
arch | manjaro | parch)
|
|
pacman -Sy --noconfirm ca-certificates
|
|
;;
|
|
*)
|
|
echo -e "${red}Unsupported operating system. Please check the script and install the necessary packages manually.${plain}\n"
|
|
exit 1
|
|
;;
|
|
esac
|
|
|
|
# Enable BBR
|
|
echo "net.core.default_qdisc=fq" | tee -a /etc/sysctl.conf
|
|
echo "net.ipv4.tcp_congestion_control=bbr" | tee -a /etc/sysctl.conf
|
|
|
|
# Apply changes
|
|
sysctl -p
|
|
|
|
# Verify that BBR is enabled
|
|
if [[ $(sysctl net.ipv4.tcp_congestion_control | awk '{print $3}') == "bbr" ]]; then
|
|
echo -e "${green}BBR has been enabled successfully.${plain}"
|
|
else
|
|
echo -e "${red}Failed to enable BBR. Please check your system configuration.${plain}"
|
|
fi
|
|
}
|
|
|
|
update_shell() {
|
|
wget -O /usr/bin/x-ui -N --no-check-certificate https://github.com/MHSanaei/3x-ui/raw/main/x-ui.sh
|
|
if [[ $? != 0 ]]; then
|
|
echo ""
|
|
LOGE "Failed to download script, Please check whether the machine can connect Github"
|
|
before_show_menu
|
|
else
|
|
chmod +x /usr/bin/x-ui
|
|
LOGI "Upgrade script succeeded, Please rerun the script" && exit 0
|
|
fi
|
|
}
|
|
|
|
# 0: running, 1: not running, 2: not installed
|
|
check_status() {
|
|
if [[ ! -f /etc/systemd/system/x-ui.service ]]; then
|
|
return 2
|
|
fi
|
|
temp=$(systemctl status x-ui | grep Active | awk '{print $3}' | cut -d "(" -f2 | cut -d ")" -f1)
|
|
if [[ "${temp}" == "running" ]]; then
|
|
return 0
|
|
else
|
|
return 1
|
|
fi
|
|
}
|
|
|
|
check_enabled() {
|
|
temp=$(systemctl is-enabled x-ui)
|
|
if [[ "${temp}" == "enabled" ]]; then
|
|
return 0
|
|
else
|
|
return 1
|
|
fi
|
|
}
|
|
|
|
check_uninstall() {
|
|
check_status
|
|
if [[ $? != 2 ]]; then
|
|
echo ""
|
|
LOGE "Panel installed, Please do not reinstall"
|
|
if [[ $# == 0 ]]; then
|
|
before_show_menu
|
|
fi
|
|
return 1
|
|
else
|
|
return 0
|
|
fi
|
|
}
|
|
|
|
check_install() {
|
|
check_status
|
|
if [[ $? == 2 ]]; then
|
|
echo ""
|
|
LOGE "Please install the panel first"
|
|
if [[ $# == 0 ]]; then
|
|
before_show_menu
|
|
fi
|
|
return 1
|
|
else
|
|
return 0
|
|
fi
|
|
}
|
|
|
|
show_status() {
|
|
check_status
|
|
case $? in
|
|
0)
|
|
echo -e "Panel state: ${green}Running${plain}"
|
|
show_enable_status
|
|
;;
|
|
1)
|
|
echo -e "Panel state: ${yellow}Not Running${plain}"
|
|
show_enable_status
|
|
;;
|
|
2)
|
|
echo -e "Panel state: ${red}Not Installed${plain}"
|
|
;;
|
|
esac
|
|
show_xray_status
|
|
}
|
|
|
|
show_enable_status() {
|
|
check_enabled
|
|
if [[ $? == 0 ]]; then
|
|
echo -e "Start automatically: ${green}Yes${plain}"
|
|
else
|
|
echo -e "Start automatically: ${red}No${plain}"
|
|
fi
|
|
}
|
|
|
|
check_xray_status() {
|
|
count=$(ps -ef | grep "xray-linux" | grep -v "grep" | wc -l)
|
|
if [[ count -ne 0 ]]; then
|
|
return 0
|
|
else
|
|
return 1
|
|
fi
|
|
}
|
|
|
|
show_xray_status() {
|
|
check_xray_status
|
|
if [[ $? == 0 ]]; then
|
|
echo -e "xray state: ${green}Running${plain}"
|
|
else
|
|
echo -e "xray state: ${red}Not Running${plain}"
|
|
fi
|
|
}
|
|
|
|
firewall_menu() {
|
|
echo -e "${green}\t1.${plain} Install Firewall & open ports"
|
|
echo -e "${green}\t2.${plain} Allowed List"
|
|
echo -e "${green}\t3.${plain} Delete Ports from List"
|
|
echo -e "${green}\t4.${plain} Disable Firewall"
|
|
echo -e "${green}\t0.${plain} Back to Main Menu"
|
|
read -p "Choose an option: " choice
|
|
case "$choice" in
|
|
0)
|
|
show_menu
|
|
;;
|
|
1)
|
|
open_ports
|
|
;;
|
|
2)
|
|
sudo ufw status
|
|
;;
|
|
3)
|
|
delete_ports
|
|
;;
|
|
4)
|
|
sudo ufw disable
|
|
;;
|
|
*) echo "Invalid choice" ;;
|
|
esac
|
|
}
|
|
|
|
open_ports() {
|
|
if ! command -v ufw &>/dev/null; then
|
|
echo "ufw firewall is not installed. Installing now..."
|
|
apt-get update
|
|
apt-get install -y ufw
|
|
else
|
|
echo "ufw firewall is already installed"
|
|
fi
|
|
|
|
# Check if the firewall is inactive
|
|
if ufw status | grep -q "Status: active"; then
|
|
echo "Firewall is already active"
|
|
else
|
|
echo "Activating firewall..."
|
|
# Open the necessary ports
|
|
ufw allow ssh
|
|
ufw allow http
|
|
ufw allow https
|
|
ufw allow 2053/tcp
|
|
|
|
# Enable the firewall
|
|
ufw --force enable
|
|
fi
|
|
|
|
# Prompt the user to enter a list of ports
|
|
read -p "Enter the ports you want to open (e.g. 80,443,2053 or range 400-500): " ports
|
|
|
|
# Check if the input is valid
|
|
if ! [[ $ports =~ ^([0-9]+|[0-9]+-[0-9]+)(,([0-9]+|[0-9]+-[0-9]+))*$ ]]; then
|
|
echo "Error: Invalid input. Please enter a comma-separated list of ports or a range of ports (e.g. 80,443,2053 or 400-500)." >&2
|
|
exit 1
|
|
fi
|
|
|
|
# Open the specified ports using ufw
|
|
IFS=',' read -ra PORT_LIST <<<"$ports"
|
|
for port in "${PORT_LIST[@]}"; do
|
|
if [[ $port == *-* ]]; then
|
|
# Split the range into start and end ports
|
|
start_port=$(echo $port | cut -d'-' -f1)
|
|
end_port=$(echo $port | cut -d'-' -f2)
|
|
ufw allow $start_port:$end_port/tcp
|
|
ufw allow $start_port:$end_port/udp
|
|
else
|
|
ufw allow "$port"
|
|
fi
|
|
done
|
|
|
|
# Confirm that the ports are open
|
|
echo "The following ports are now open:"
|
|
ufw status | grep "ALLOW" | grep -Eo "[0-9]+(/[a-z]+)?"
|
|
|
|
echo "Firewall status:"
|
|
ufw status verbose
|
|
}
|
|
|
|
delete_ports() {
|
|
# Prompt the user to enter the ports they want to delete
|
|
read -p "Enter the ports you want to delete (e.g. 80,443,2053 or range 400-500): " ports
|
|
|
|
# Check if the input is valid
|
|
if ! [[ $ports =~ ^([0-9]+|[0-9]+-[0-9]+)(,([0-9]+|[0-9]+-[0-9]+))*$ ]]; then
|
|
echo "Error: Invalid input. Please enter a comma-separated list of ports or a range of ports (e.g. 80,443,2053 or 400-500)." >&2
|
|
exit 1
|
|
fi
|
|
|
|
# Delete the specified ports using ufw
|
|
IFS=',' read -ra PORT_LIST <<<"$ports"
|
|
for port in "${PORT_LIST[@]}"; do
|
|
if [[ $port == *-* ]]; then
|
|
# Split the range into start and end ports
|
|
start_port=$(echo $port | cut -d'-' -f1)
|
|
end_port=$(echo $port | cut -d'-' -f2)
|
|
# Delete the port range
|
|
ufw delete allow $start_port:$end_port/tcp
|
|
ufw delete allow $start_port:$end_port/udp
|
|
else
|
|
ufw delete allow "$port"
|
|
fi
|
|
done
|
|
|
|
# Confirm that the ports are deleted
|
|
|
|
echo "Deleted the specified ports:"
|
|
for port in "${PORT_LIST[@]}"; do
|
|
if [[ $port == *-* ]]; then
|
|
start_port=$(echo $port | cut -d'-' -f1)
|
|
end_port=$(echo $port | cut -d'-' -f2)
|
|
# Check if the port range has been successfully deleted
|
|
(ufw status | grep -q "$start_port:$end_port") || echo "$start_port-$end_port"
|
|
else
|
|
# Check if the individual port has been successfully deleted
|
|
(ufw status | grep -q "$port") || echo "$port"
|
|
fi
|
|
done
|
|
}
|
|
|
|
update_geo() {
|
|
local defaultBinFolder="/usr/local/x-ui/bin"
|
|
read -p "Please enter x-ui bin folder path. Leave blank for default. (Default: '${defaultBinFolder}')" binFolder
|
|
binFolder=${binFolder:-${defaultBinFolder}}
|
|
if [[ ! -d ${binFolder} ]]; then
|
|
LOGE "Folder ${binFolder} not exists!"
|
|
LOGI "making bin folder: ${binFolder}..."
|
|
mkdir -p ${binFolder}
|
|
fi
|
|
|
|
systemctl stop x-ui
|
|
cd ${binFolder}
|
|
rm -f geoip.dat geosite.dat geoip_IR.dat geosite_IR.dat geoip_VN.dat geosite_VN.dat
|
|
wget -N https://github.com/Loyalsoldier/v2ray-rules-dat/releases/latest/download/geoip.dat
|
|
wget -N https://github.com/Loyalsoldier/v2ray-rules-dat/releases/latest/download/geosite.dat
|
|
wget -O geoip_IR.dat -N https://github.com/chocolate4u/Iran-v2ray-rules/releases/latest/download/geoip.dat
|
|
wget -O geosite_IR.dat -N https://github.com/chocolate4u/Iran-v2ray-rules/releases/latest/download/geosite.dat
|
|
wget -O geoip_VN.dat https://github.com/vuong2023/vn-v2ray-rules/releases/latest/download/geoip.dat
|
|
wget -O geosite_VN.dat https://github.com/vuong2023/vn-v2ray-rules/releases/latest/download/geosite.dat
|
|
systemctl start x-ui
|
|
echo -e "${green}Geosite.dat + Geoip.dat + geoip_IR.dat + geosite_IR.dat have been updated successfully in bin folder '${binfolder}'!${plain}"
|
|
before_show_menu
|
|
}
|
|
|
|
install_acme() {
|
|
cd ~
|
|
LOGI "install acme..."
|
|
curl https://get.acme.sh | sh
|
|
if [ $? -ne 0 ]; then
|
|
LOGE "install acme failed"
|
|
return 1
|
|
else
|
|
LOGI "install acme succeed"
|
|
fi
|
|
return 0
|
|
}
|
|
|
|
ssl_cert_issue_main() {
|
|
echo -e "${green}\t1.${plain} Get SSL"
|
|
echo -e "${green}\t2.${plain} Revoke"
|
|
echo -e "${green}\t3.${plain} Force Renew"
|
|
echo -e "${green}\t0.${plain} Back to Main Menu"
|
|
read -p "Choose an option: " choice
|
|
case "$choice" in
|
|
0)
|
|
show_menu
|
|
;;
|
|
1)
|
|
ssl_cert_issue
|
|
;;
|
|
2)
|
|
local domain=""
|
|
read -p "Please enter your domain name to revoke the certificate: " domain
|
|
~/.acme.sh/acme.sh --revoke -d ${domain}
|
|
LOGI "Certificate revoked"
|
|
;;
|
|
3)
|
|
local domain=""
|
|
read -p "Please enter your domain name to forcefully renew an SSL certificate: " domain
|
|
~/.acme.sh/acme.sh --renew -d ${domain} --force
|
|
;;
|
|
*) echo "Invalid choice" ;;
|
|
esac
|
|
}
|
|
|
|
ssl_cert_issue() {
|
|
# check for acme.sh first
|
|
if ! command -v ~/.acme.sh/acme.sh &>/dev/null; then
|
|
echo "acme.sh could not be found. we will install it"
|
|
install_acme
|
|
if [ $? -ne 0 ]; then
|
|
LOGE "install acme failed, please check logs"
|
|
exit 1
|
|
fi
|
|
fi
|
|
# install socat second
|
|
case "${release}" in
|
|
ubuntu | debian | armbian)
|
|
apt update && apt install socat -y
|
|
;;
|
|
centos | almalinux | rocky | oracle)
|
|
yum -y update && yum -y install socat
|
|
;;
|
|
fedora)
|
|
dnf -y update && dnf -y install socat
|
|
;;
|
|
arch | manjaro | parch)
|
|
pacman -Sy --noconfirm socat
|
|
;;
|
|
*)
|
|
echo -e "${red}Unsupported operating system. Please check the script and install the necessary packages manually.${plain}\n"
|
|
exit 1
|
|
;;
|
|
esac
|
|
if [ $? -ne 0 ]; then
|
|
LOGE "install socat failed, please check logs"
|
|
exit 1
|
|
else
|
|
LOGI "install socat succeed..."
|
|
fi
|
|
|
|
# get the domain here,and we need verify it
|
|
local domain=""
|
|
read -p "Please enter your domain name:" domain
|
|
LOGD "your domain is:${domain},check it..."
|
|
# here we need to judge whether there exists cert already
|
|
local currentCert=$(~/.acme.sh/acme.sh --list | tail -1 | awk '{print $1}')
|
|
|
|
if [ ${currentCert} == ${domain} ]; then
|
|
local certInfo=$(~/.acme.sh/acme.sh --list)
|
|
LOGE "system already has certs here,can not issue again,current certs details:"
|
|
LOGI "$certInfo"
|
|
exit 1
|
|
else
|
|
LOGI "your domain is ready for issuing cert now..."
|
|
fi
|
|
|
|
# create a directory for install cert
|
|
certPath="/root/cert/${domain}"
|
|
if [ ! -d "$certPath" ]; then
|
|
mkdir -p "$certPath"
|
|
else
|
|
rm -rf "$certPath"
|
|
mkdir -p "$certPath"
|
|
fi
|
|
|
|
# get needed port here
|
|
local WebPort=80
|
|
read -p "please choose which port do you use,default will be 80 port:" WebPort
|
|
if [[ ${WebPort} -gt 65535 || ${WebPort} -lt 1 ]]; then
|
|
LOGE "your input ${WebPort} is invalid,will use default port"
|
|
fi
|
|
LOGI "will use port:${WebPort} to issue certs,please make sure this port is open..."
|
|
# NOTE:This should be handled by user
|
|
# open the port and kill the occupied progress
|
|
~/.acme.sh/acme.sh --set-default-ca --server letsencrypt
|
|
~/.acme.sh/acme.sh --issue -d ${domain} --standalone --httpport ${WebPort}
|
|
if [ $? -ne 0 ]; then
|
|
LOGE "issue certs failed,please check logs"
|
|
rm -rf ~/.acme.sh/${domain}
|
|
exit 1
|
|
else
|
|
LOGE "issue certs succeed,installing certs..."
|
|
fi
|
|
# install cert
|
|
~/.acme.sh/acme.sh --installcert -d ${domain} \
|
|
--key-file /root/cert/${domain}/privkey.pem \
|
|
--fullchain-file /root/cert/${domain}/fullchain.pem
|
|
|
|
if [ $? -ne 0 ]; then
|
|
LOGE "install certs failed,exit"
|
|
rm -rf ~/.acme.sh/${domain}
|
|
exit 1
|
|
else
|
|
LOGI "install certs succeed,enable auto renew..."
|
|
fi
|
|
|
|
~/.acme.sh/acme.sh --upgrade --auto-upgrade
|
|
if [ $? -ne 0 ]; then
|
|
LOGE "auto renew failed, certs details:"
|
|
ls -lah cert/*
|
|
chmod 755 $certPath/*
|
|
exit 1
|
|
else
|
|
LOGI "auto renew succeed, certs details:"
|
|
ls -lah cert/*
|
|
chmod 755 $certPath/*
|
|
fi
|
|
}
|
|
|
|
ssl_cert_issue_CF() {
|
|
echo -E ""
|
|
LOGD "******Instructions for use******"
|
|
LOGI "This Acme script requires the following data:"
|
|
LOGI "1.Cloudflare Registered e-mail"
|
|
LOGI "2.Cloudflare Global API Key"
|
|
LOGI "3.The domain name that has been resolved dns to the current server by Cloudflare"
|
|
LOGI "4.The script applies for a certificate. The default installation path is /root/cert "
|
|
confirm "Confirmed?[y/n]" "y"
|
|
if [ $? -eq 0 ]; then
|
|
# check for acme.sh first
|
|
if ! command -v ~/.acme.sh/acme.sh &>/dev/null; then
|
|
echo "acme.sh could not be found. we will install it"
|
|
install_acme
|
|
if [ $? -ne 0 ]; then
|
|
LOGE "install acme failed, please check logs"
|
|
exit 1
|
|
fi
|
|
fi
|
|
CF_Domain=""
|
|
CF_GlobalKey=""
|
|
CF_AccountEmail=""
|
|
certPath=/root/cert
|
|
if [ ! -d "$certPath" ]; then
|
|
mkdir $certPath
|
|
else
|
|
rm -rf $certPath
|
|
mkdir $certPath
|
|
fi
|
|
LOGD "Please set a domain name:"
|
|
read -p "Input your domain here:" CF_Domain
|
|
LOGD "Your domain name is set to:${CF_Domain}"
|
|
LOGD "Please set the API key:"
|
|
read -p "Input your key here:" CF_GlobalKey
|
|
LOGD "Your API key is:${CF_GlobalKey}"
|
|
LOGD "Please set up registered email:"
|
|
read -p "Input your email here:" CF_AccountEmail
|
|
LOGD "Your registered email address is:${CF_AccountEmail}"
|
|
~/.acme.sh/acme.sh --set-default-ca --server letsencrypt
|
|
if [ $? -ne 0 ]; then
|
|
LOGE "Default CA, Lets'Encrypt fail, script exiting..."
|
|
exit 1
|
|
fi
|
|
export CF_Key="${CF_GlobalKey}"
|
|
export CF_Email=${CF_AccountEmail}
|
|
~/.acme.sh/acme.sh --issue --dns dns_cf -d ${CF_Domain} -d *.${CF_Domain} --log
|
|
if [ $? -ne 0 ]; then
|
|
LOGE "Certificate issuance failed, script exiting..."
|
|
exit 1
|
|
else
|
|
LOGI "Certificate issued Successfully, Installing..."
|
|
fi
|
|
~/.acme.sh/acme.sh --installcert -d ${CF_Domain} -d *.${CF_Domain} --ca-file /root/cert/ca.cer \
|
|
--cert-file /root/cert/${CF_Domain}.cer --key-file /root/cert/${CF_Domain}.key \
|
|
--fullchain-file /root/cert/fullchain.cer
|
|
if [ $? -ne 0 ]; then
|
|
LOGE "Certificate installation failed, script exiting..."
|
|
exit 1
|
|
else
|
|
LOGI "Certificate installed Successfully,Turning on automatic updates..."
|
|
fi
|
|
~/.acme.sh/acme.sh --upgrade --auto-upgrade
|
|
if [ $? -ne 0 ]; then
|
|
LOGE "Auto update setup Failed, script exiting..."
|
|
ls -lah cert
|
|
chmod 755 $certPath
|
|
exit 1
|
|
else
|
|
LOGI "The certificate is installed and auto-renewal is turned on, Specific information is as follows"
|
|
ls -lah cert
|
|
chmod 755 $certPath
|
|
fi
|
|
else
|
|
show_menu
|
|
fi
|
|
}
|
|
|
|
warp_cloudflare() {
|
|
echo -e "${green}\t1.${plain} Install WARP socks5 proxy"
|
|
echo -e "${green}\t2.${plain} Account Type (free, plus, team)"
|
|
echo -e "${green}\t3.${plain} Turn on/off WireProxy"
|
|
echo -e "${green}\t4.${plain} Uninstall WARP"
|
|
echo -e "${green}\t0.${plain} Back to Main Menu"
|
|
read -p "Choose an option: " choice
|
|
case "$choice" in
|
|
0)
|
|
show_menu
|
|
;;
|
|
1)
|
|
bash <(curl -sSL https://raw.githubusercontent.com/hamid-gh98/x-ui-scripts/main/install_warp_proxy.sh)
|
|
;;
|
|
2)
|
|
warp a
|
|
;;
|
|
3)
|
|
warp y
|
|
;;
|
|
4)
|
|
warp u
|
|
;;
|
|
*) echo "Invalid choice" ;;
|
|
esac
|
|
}
|
|
|
|
run_speedtest() {
|
|
# Check if Speedtest is already installed
|
|
if ! command -v speedtest &>/dev/null; then
|
|
# If not installed, install it
|
|
local pkg_manager=""
|
|
local speedtest_install_script=""
|
|
|
|
if command -v dnf &>/dev/null; then
|
|
pkg_manager="dnf"
|
|
speedtest_install_script="https://packagecloud.io/install/repositories/ookla/speedtest-cli/script.rpm.sh"
|
|
elif command -v yum &>/dev/null; then
|
|
pkg_manager="yum"
|
|
speedtest_install_script="https://packagecloud.io/install/repositories/ookla/speedtest-cli/script.rpm.sh"
|
|
elif command -v apt-get &>/dev/null; then
|
|
pkg_manager="apt-get"
|
|
speedtest_install_script="https://packagecloud.io/install/repositories/ookla/speedtest-cli/script.deb.sh"
|
|
elif command -v apt &>/dev/null; then
|
|
pkg_manager="apt"
|
|
speedtest_install_script="https://packagecloud.io/install/repositories/ookla/speedtest-cli/script.deb.sh"
|
|
fi
|
|
|
|
if [[ -z $pkg_manager ]]; then
|
|
echo "Error: Package manager not found. You may need to install Speedtest manually."
|
|
return 1
|
|
else
|
|
curl -s $speedtest_install_script | bash
|
|
$pkg_manager install -y speedtest
|
|
fi
|
|
fi
|
|
|
|
# Run Speedtest
|
|
speedtest
|
|
}
|
|
|
|
create_iplimit_jails() {
|
|
# Use default bantime if not passed => 15 minutes
|
|
local bantime="${1:-15}"
|
|
|
|
# Uncomment 'allowipv6 = auto' in fail2ban.conf
|
|
sed -i 's/#allowipv6 = auto/allowipv6 = auto/g' /etc/fail2ban/fail2ban.conf
|
|
|
|
#On Debian 12+ fail2ban's default backend should be changed to systemd
|
|
if [[ "${release}" == "debian" && ${os_version} -ge 12 ]]; then
|
|
sed -i '0,/action =/s/backend = auto/backend = systemd/' /etc/fail2ban/jail.conf
|
|
fi
|
|
|
|
cat << EOF > /etc/fail2ban/jail.d/3x-ipl.conf
|
|
[3x-ipl]
|
|
enabled=true
|
|
backend=auto
|
|
filter=3x-ipl
|
|
action=3x-ipl
|
|
logpath=${iplimit_log_path}
|
|
maxretry=2
|
|
findtime=32
|
|
bantime=${bantime}m
|
|
EOF
|
|
|
|
cat << EOF > /etc/fail2ban/filter.d/3x-ipl.conf
|
|
[Definition]
|
|
datepattern = ^%%Y/%%m/%%d %%H:%%M:%%S
|
|
failregex = \[LIMIT_IP\]\s*Email\s*=\s*<F-USER>.+</F-USER>\s*\|\|\s*SRC\s*=\s*<ADDR>
|
|
ignoreregex =
|
|
EOF
|
|
|
|
cat << EOF > /etc/fail2ban/action.d/3x-ipl.conf
|
|
[INCLUDES]
|
|
before = iptables-allports.conf
|
|
|
|
[Definition]
|
|
actionstart = <iptables> -N f2b-<name>
|
|
<iptables> -A f2b-<name> -j <returntype>
|
|
<iptables> -I <chain> -p <protocol> -j f2b-<name>
|
|
|
|
actionstop = <iptables> -D <chain> -p <protocol> -j f2b-<name>
|
|
<actionflush>
|
|
<iptables> -X f2b-<name>
|
|
|
|
actioncheck = <iptables> -n -L <chain> | grep -q 'f2b-<name>[ \t]'
|
|
|
|
actionban = <iptables> -I f2b-<name> 1 -s <ip> -j <blocktype>
|
|
echo "\$(date +"%%Y/%%m/%%d %%H:%%M:%%S") BAN [Email] = <F-USER> [IP] = <ip> banned for <bantime> seconds." >> ${iplimit_banned_log_path}
|
|
|
|
actionunban = <iptables> -D f2b-<name> -s <ip> -j <blocktype>
|
|
echo "\$(date +"%%Y/%%m/%%d %%H:%%M:%%S") UNBAN [Email] = <F-USER> [IP] = <ip> unbanned." >> ${iplimit_banned_log_path}
|
|
|
|
[Init]
|
|
EOF
|
|
|
|
echo -e "${green}Ip Limit jail files created with a bantime of ${bantime} minutes.${plain}"
|
|
}
|
|
|
|
iplimit_remove_conflicts() {
|
|
local jail_files=(
|
|
/etc/fail2ban/jail.conf
|
|
/etc/fail2ban/jail.local
|
|
)
|
|
|
|
for file in "${jail_files[@]}"; do
|
|
# Check for [3x-ipl] config in jail file then remove it
|
|
if test -f "${file}" && grep -qw '3x-ipl' ${file}; then
|
|
sed -i "/\[3x-ipl\]/,/^$/d" ${file}
|
|
echo -e "${yellow}Removing conflicts of [3x-ipl] in jail (${file})!${plain}\n"
|
|
fi
|
|
done
|
|
}
|
|
|
|
iplimit_main() {
|
|
echo -e "\n${green}\t1.${plain} Install Fail2ban and configure IP Limit"
|
|
echo -e "${green}\t2.${plain} Change Ban Duration"
|
|
echo -e "${green}\t3.${plain} Unban Everyone"
|
|
echo -e "${green}\t4.${plain} Check Logs"
|
|
echo -e "${green}\t5.${plain} fail2ban status"
|
|
echo -e "${green}\t6.${plain} Uninstall IP Limit"
|
|
echo -e "${green}\t0.${plain} Back to Main Menu"
|
|
read -p "Choose an option: " choice
|
|
case "$choice" in
|
|
0)
|
|
show_menu
|
|
;;
|
|
1)
|
|
confirm "Proceed with installation of Fail2ban & IP Limit?" "y"
|
|
if [[ $? == 0 ]]; then
|
|
install_iplimit
|
|
else
|
|
iplimit_main
|
|
fi
|
|
;;
|
|
2)
|
|
read -rp "Please enter new Ban Duration in Minutes [default 30]: " NUM
|
|
if [[ $NUM =~ ^[0-9]+$ ]]; then
|
|
create_iplimit_jails ${NUM}
|
|
systemctl restart fail2ban
|
|
else
|
|
echo -e "${red}${NUM} is not a number! Please, try again.${plain}"
|
|
fi
|
|
iplimit_main
|
|
;;
|
|
3)
|
|
confirm "Proceed with Unbanning everyone from IP Limit jail?" "y"
|
|
if [[ $? == 0 ]]; then
|
|
fail2ban-client reload --restart --unban 3x-ipl
|
|
truncate -s 0 "${iplimit_banned_log_path}"
|
|
echo -e "${green}All users Unbanned successfully.${plain}"
|
|
iplimit_main
|
|
else
|
|
echo -e "${yellow}Cancelled.${plain}"
|
|
fi
|
|
iplimit_main
|
|
;;
|
|
4)
|
|
show_banlog
|
|
;;
|
|
5)
|
|
service fail2ban status
|
|
;;
|
|
|
|
6)
|
|
remove_iplimit
|
|
;;
|
|
*) echo "Invalid choice" ;;
|
|
esac
|
|
}
|
|
|
|
install_iplimit() {
|
|
if ! command -v fail2ban-client &>/dev/null; then
|
|
echo -e "${green}Fail2ban is not installed. Installing now...!${plain}\n"
|
|
|
|
# Check the OS and install necessary packages
|
|
case "${release}" in
|
|
ubuntu | debian | armbian)
|
|
apt update && apt install fail2ban -y
|
|
;;
|
|
centos | almalinux | rocky | oracle)
|
|
yum update -y && yum install epel-release -y
|
|
yum -y install fail2ban
|
|
;;
|
|
fedora)
|
|
dnf -y update && dnf -y install fail2ban
|
|
;;
|
|
arch | manjaro | parch)
|
|
pacman -Syu --noconfirm fail2ban
|
|
;;
|
|
*)
|
|
echo -e "${red}Unsupported operating system. Please check the script and install the necessary packages manually.${plain}\n"
|
|
exit 1
|
|
;;
|
|
esac
|
|
|
|
if ! command -v fail2ban-client &>/dev/null; then
|
|
echo -e "${red}Fail2ban installation failed.${plain}\n"
|
|
exit 1
|
|
fi
|
|
|
|
echo -e "${green}Fail2ban installed successfully!${plain}\n"
|
|
else
|
|
echo -e "${yellow}Fail2ban is already installed.${plain}\n"
|
|
fi
|
|
|
|
echo -e "${green}Configuring IP Limit...${plain}\n"
|
|
|
|
# make sure there's no conflict for jail files
|
|
iplimit_remove_conflicts
|
|
|
|
# Check if log file exists
|
|
if ! test -f "${iplimit_banned_log_path}"; then
|
|
touch ${iplimit_banned_log_path}
|
|
fi
|
|
|
|
# Check if service log file exists so fail2ban won't return error
|
|
if ! test -f "${iplimit_log_path}"; then
|
|
touch ${iplimit_log_path}
|
|
fi
|
|
|
|
# Create the iplimit jail files
|
|
# we didn't pass the bantime here to use the default value
|
|
create_iplimit_jails
|
|
|
|
# Launching fail2ban
|
|
if ! systemctl is-active --quiet fail2ban; then
|
|
systemctl start fail2ban
|
|
systemctl enable fail2ban
|
|
else
|
|
systemctl restart fail2ban
|
|
fi
|
|
systemctl enable fail2ban
|
|
|
|
echo -e "${green}IP Limit installed and configured successfully!${plain}\n"
|
|
before_show_menu
|
|
}
|
|
|
|
remove_iplimit() {
|
|
echo -e "${green}\t1.${plain} Only remove IP Limit configurations"
|
|
echo -e "${green}\t2.${plain} Uninstall Fail2ban and IP Limit"
|
|
echo -e "${green}\t0.${plain} Abort"
|
|
read -p "Choose an option: " num
|
|
case "$num" in
|
|
1)
|
|
rm -f /etc/fail2ban/filter.d/3x-ipl.conf
|
|
rm -f /etc/fail2ban/action.d/3x-ipl.conf
|
|
rm -f /etc/fail2ban/jail.d/3x-ipl.conf
|
|
systemctl restart fail2ban
|
|
echo -e "${green}IP Limit removed successfully!${plain}\n"
|
|
before_show_menu
|
|
;;
|
|
2)
|
|
rm -rf /etc/fail2ban
|
|
systemctl stop fail2ban
|
|
case "${release}" in
|
|
ubuntu | debian | armbian)
|
|
apt-get remove -y fail2ban
|
|
apt-get purge -y fail2ban -y
|
|
apt-get autoremove -y
|
|
;;
|
|
centos | almalinux | rocky | oracle)
|
|
yum remove fail2ban -y
|
|
yum autoremove -y
|
|
;;
|
|
fedora)
|
|
dnf remove fail2ban -y
|
|
dnf autoremove -y
|
|
;;
|
|
arch | manjaro | parch)
|
|
pacman -Rns --noconfirm fail2ban
|
|
;;
|
|
*)
|
|
echo -e "${red}Unsupported operating system. Please uninstall Fail2ban manually.${plain}\n"
|
|
exit 1
|
|
;;
|
|
esac
|
|
echo -e "${green}Fail2ban and IP Limit removed successfully!${plain}\n"
|
|
before_show_menu
|
|
;;
|
|
0)
|
|
echo -e "${yellow}Cancelled.${plain}\n"
|
|
iplimit_main
|
|
;;
|
|
*)
|
|
echo -e "${red}Invalid option. Please select a valid number.${plain}\n"
|
|
remove_iplimit
|
|
;;
|
|
esac
|
|
}
|
|
|
|
show_usage() {
|
|
echo "x-ui control menu usages: "
|
|
echo "------------------------------------------"
|
|
echo -e "x-ui - Enter control menu"
|
|
echo -e "x-ui start - Start x-ui "
|
|
echo -e "x-ui stop - Stop x-ui "
|
|
echo -e "x-ui restart - Restart x-ui "
|
|
echo -e "x-ui status - Show x-ui status"
|
|
echo -e "x-ui enable - Enable x-ui on system startup"
|
|
echo -e "x-ui disable - Disable x-ui on system startup"
|
|
echo -e "x-ui log - Check x-ui logs"
|
|
echo -e "x-ui banlog - Check Fail2ban ban logs"
|
|
echo -e "x-ui update - Update x-ui "
|
|
echo -e "x-ui install - Install x-ui "
|
|
echo -e "x-ui uninstall - Uninstall x-ui "
|
|
echo "------------------------------------------"
|
|
}
|
|
|
|
show_menu() {
|
|
echo -e "
|
|
${green}3X-ui Panel Management Script${plain}
|
|
${green}0.${plain} Exit Script
|
|
————————————————
|
|
${green}1.${plain} Install
|
|
${green}2.${plain} Update
|
|
${green}3.${plain} Custom Version
|
|
${green}4.${plain} Uninstall
|
|
————————————————
|
|
${green}5.${plain} Reset Username & Password & Secret Token
|
|
${green}6.${plain} Reset Settings
|
|
${green}7.${plain} Change Port
|
|
${green}8.${plain} View Current Settings
|
|
————————————————
|
|
${green}9.${plain} Start
|
|
${green}10.${plain} Stop
|
|
${green}11.${plain} Restart
|
|
${green}12.${plain} Check Status
|
|
${green}13.${plain} Check Logs
|
|
————————————————
|
|
${green}14.${plain} Enable Autostart
|
|
${green}15.${plain} Disable Autostart
|
|
————————————————
|
|
${green}16.${plain} SSL Certificate Management
|
|
${green}17.${plain} Cloudflare SSL Certificate
|
|
${green}18.${plain} IP Limit Management
|
|
${green}19.${plain} WARP Management
|
|
${green}20.${plain} Firewall Management
|
|
————————————————
|
|
${green}21.${plain} Enable BBR
|
|
${green}22.${plain} Update Geo Files
|
|
${green}23.${plain} Speedtest by Ookla
|
|
"
|
|
show_status
|
|
echo && read -p "Please enter your selection [0-23]: " num
|
|
|
|
case "${num}" in
|
|
0)
|
|
exit 0
|
|
;;
|
|
1)
|
|
check_uninstall && install
|
|
;;
|
|
2)
|
|
check_install && update
|
|
;;
|
|
3)
|
|
check_install && custom_version
|
|
;;
|
|
4)
|
|
check_install && uninstall
|
|
;;
|
|
5)
|
|
check_install && reset_user
|
|
;;
|
|
6)
|
|
check_install && reset_config
|
|
;;
|
|
7)
|
|
check_install && set_port
|
|
;;
|
|
8)
|
|
check_install && check_config
|
|
;;
|
|
9)
|
|
check_install && start
|
|
;;
|
|
10)
|
|
check_install && stop
|
|
;;
|
|
11)
|
|
check_install && restart
|
|
;;
|
|
12)
|
|
check_install && status
|
|
;;
|
|
13)
|
|
check_install && show_log
|
|
;;
|
|
14)
|
|
check_install && enable
|
|
;;
|
|
15)
|
|
check_install && disable
|
|
;;
|
|
16)
|
|
ssl_cert_issue_main
|
|
;;
|
|
17)
|
|
ssl_cert_issue_CF
|
|
;;
|
|
18)
|
|
iplimit_main
|
|
;;
|
|
19)
|
|
warp_cloudflare
|
|
;;
|
|
20)
|
|
firewall_menu
|
|
;;
|
|
21)
|
|
bbr_menu
|
|
;;
|
|
22)
|
|
update_geo
|
|
;;
|
|
23)
|
|
run_speedtest
|
|
;;
|
|
*)
|
|
LOGE "Please enter the correct number [0-23]"
|
|
;;
|
|
esac
|
|
}
|
|
|
|
if [[ $# > 0 ]]; then
|
|
case $1 in
|
|
"start")
|
|
check_install 0 && start 0
|
|
;;
|
|
"stop")
|
|
check_install 0 && stop 0
|
|
;;
|
|
"restart")
|
|
check_install 0 && restart 0
|
|
;;
|
|
"status")
|
|
check_install 0 && status 0
|
|
;;
|
|
"enable")
|
|
check_install 0 && enable 0
|
|
;;
|
|
"disable")
|
|
check_install 0 && disable 0
|
|
;;
|
|
"log")
|
|
check_install 0 && show_log 0
|
|
;;
|
|
"banlog")
|
|
check_install 0 && show_banlog 0
|
|
;;
|
|
"update")
|
|
check_install 0 && update 0
|
|
;;
|
|
"install")
|
|
check_uninstall 0 && install 0
|
|
;;
|
|
"uninstall")
|
|
check_install 0 && uninstall 0
|
|
;;
|
|
*) show_usage ;;
|
|
esac
|
|
else
|
|
show_menu
|
|
fi
|