From c687a42d7edff0e67ba3d1028d417b08c3cf51c5 Mon Sep 17 00:00:00 2001 From: Alireza Ahmadi Date: Fri, 1 Mar 2024 10:13:02 +0100 Subject: [PATCH] [cli] add s-ui menu Co-Authored-By: Shellgate <128194280+shellgate@users.noreply.github.com> --- install.sh | 58 +++- s-ui.sh | 816 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 869 insertions(+), 5 deletions(-) create mode 100644 s-ui.sh diff --git a/install.sh b/install.sh index 4c97ce1..193e543 100755 --- a/install.sh +++ b/install.sh @@ -77,6 +77,52 @@ install_base() { fi } +config_after_install() { + echo -e "${yellow}Install/update finished! For security it's recommended to modify panel settings ${plain}" + read -p "Do you want to continue with the modification [y/n]? ": config_confirm + if [[ "${config_confirm}" == "y" || "${config_confirm}" == "Y" ]]; then + read -p "Please set up the panel port (leave blank for existing/default value):" config_port + read -p "Please set up the panel path (leave blank for existing/default value):" config_path + + # Sub configuration + read -p "Please set up the subscription port (leave blank for existing/default value):" config_port + read -p "Please set up the subscription path (leave blank for existing/default value):" config_path + + # Set configs + echo -e "${yellow}Initializing, please wait...${plain}" + /usr/local/s-ui/sui setting -port ${config_port} -path ${config_path} -subPort ${config_subPort} -subPath ${config_subPath} + + read -p "Do you want to change admin credentials [y/n]? ": admin_confirm + if [[ "${admin_confirm}" == "y" || "${admin_confirm}" == "Y" ]]; then + # First admin credentials + read -p "Please set up your username:" config_account + read -p "Please set up your password:" config_password + + # Set credentials + echo -e "${yellow}Initializing, please wait...${plain}" + /usr/local/s-ui/sui admin -username ${config_account} -password ${config_password} + else + echo -e "${yellow}Your current admin credentials: ${plain}" + /usr/local/s-ui/sui admin -show + fi + else + echo -e "${red}cancel...${plain}" + if [[ ! -f "/usr/local/s-ui/db/s-ui.db" ]]; then + local usernameTemp=$(head -c 6 /dev/urandom | base64) + local passwordTemp=$(head -c 6 /dev/urandom | base64) + echo -e "this is a fresh installation,will generate random login info for security concerns:" + echo -e "###############################################" + echo -e "${green}username:${usernameTemp}${plain}" + echo -e "${green}password:${passwordTemp}${plain}" + echo -e "###############################################" + echo -e "${red}if you forgot your login info,you can type ${green}s-ui${red} for configuration menu${plain}" + /usr/local/s-ui/sui admin -username ${usernameTemp} -password ${passwordTemp} + else + echo -e "${red} this is your upgrade,will keep old settings,if you forgot your login info,you can type ${green}s-ui${red} for configuration menu${plain}" + fi + fi +} + install_s-ui() { cd /tmp/ @@ -110,21 +156,23 @@ install_s-ui() { tar zxvf s-ui-linux-${arch}.tar.gz rm s-ui-linux-${arch}.tar.gz -f - chmod +x s-ui/sui s-ui/bin/sing-box s-ui/bin/runSingbox.sh + + wget --no-check-certificate -O /usr/bin/s-ui https://raw.githubusercontent.com/alireza0/s-ui/main/s-ui.sh + + chmod +x s-ui/sui s-ui/bin/sing-box s-ui/bin/runSingbox.sh /usr/bin/s-ui cp -rf s-ui /usr/local/ cp -f s-ui/*.service /etc/systemd/system/ rm -rf s-ui + config_after_install + systemctl daemon-reload systemctl enable s-ui --now systemctl enable sing-box --now echo -e "${green}s-ui v${last_version}${plain} installation finished, it is up and running now..." echo -e "" - echo -e "s-ui usages: " - echo -e "----------------------------------------------" - echo -e "s-ui - Enter Run S-UI" - echo -e "----------------------------------------------" + s-ui help } echo -e "${green}Excuting...${plain}" diff --git a/s-ui.sh b/s-ui.sh new file mode 100644 index 0000000..bbab3a2 --- /dev/null +++ b/s-ui.sh @@ -0,0 +1,816 @@ + +#!/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}" == "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 10 ]]; then + echo -e "${red} Please use Debian 10 or higher ${plain}\n" && exit 1 + fi +fi + +confirm() { + if [[ $# > 1 ]]; then + echo && read -p "$1 [Default$2]: " temp + if [[ x"${temp}" == x"" ]]; then + temp=$2 + fi + else + read -p "$1 [y/n]: " temp + fi + if [[ x"${temp}" == x"y" || x"${temp}" == x"Y" ]]; then + return 0 + else + return 1 + fi +} + +confirm_restart() { + confirm "Restart the ${1} service" "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/alireza0/s-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?" "n" + if [[ $? != 0 ]]; then + LOGE "Cancelled" + if [[ $# == 0 ]]; then + before_show_menu + fi + return 0 + fi + bash <(curl -Ls https://raw.githubusercontent.com/alireza0/s-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 0.0.1):" + read panel_version + + if [ -z "$panel_version" ]; then + echo "Panel version cannot be empty. Exiting." + exit 1 + fi + + download_link="https://raw.githubusercontent.com/alireza0/s-ui/master/install.sh" + + # Use the entered panel version in the download link + install_command="bash <(curl -Ls $download_link) $panel_version" + + echo "Downloading and installing panel version $panel_version..." + eval $install_command +} + +uninstall() { + confirm "Are you sure you want to uninstall the panel? sing-box will also uninstalled!" "n" + if [[ $? != 0 ]]; then + if [[ $# == 0 ]]; then + show_menu + fi + return 0 + fi + systemctl stop s-ui + systemctl disable s-ui + systemctl stop sing-box + systemctl disable sing-box + rm /etc/systemd/system/s-ui.service -f + systemctl daemon-reload + systemctl reset-failed + rm /etc/s-ui/ -rf + rm /usr/local/s-ui/ -rf + + echo "" + echo -e "Uninstalled Successfully, If you want to remove this script, then after exiting the script run ${green}rm /usr/local/s-ui -f${plain} to delete it." + echo "" + + if [[ $# == 0 ]]; then + before_show_menu + fi +} + +reset_admin() { + echo "It is not recommended to set admin's credentials to default!" + confirm "Are you sure you want to reset admin's credentials to default ?" "n" + if [[ $? != 0 ]]; then + /usr/local/s-ui/sui admin -reset + fi + before_show_menu +} + +set_admin() { + echo "It is not recommended to set admin's credentials to a complex text." + read -p "Please set up your username:" config_account + read -p "Please set up your password:" config_password + /usr/local/s-ui/sui admin -username ${config_account} -password ${config_password} + before_show_menu +} + +view_admin() { + /usr/local/s-ui/sui admin -show + before_show_menu +} + +reset_setting() { + confirm "Are you sure you want to reset settings to default ?" "n" + if [[ $? != 0 ]]; then + /usr/local/s-ui/sui setting -reset + fi + before_show_menu +} + +set_setting() { + echo "It is not recommended to set admin's credentials to a complex text." + read -p "Please set up the panel port (leave blank for existing/default value):" config_port + read -p "Please set up the panel path (leave blank for existing/default value):" config_path + + # Sub configuration + read -p "Please set up the subscription port (leave blank for existing/default value):" config_port + read -p "Please set up the subscription path (leave blank for existing/default value):" config_path + + # Set configs + echo -e "${yellow}Initializing, please wait...${plain}" + /usr/local/s-ui/sui setting -port ${config_port} -path ${config_path} -subPort ${config_subPort} -subPath ${config_subPath} + before_show_menu +} + +view_setting() { + /usr/local/s-ui/sui setting -show + before_show_menu +} + +start() { + check_status $1 + if [[ $? == 0 ]]; then + echo "" + LOGI -e "${1} is running, No need to start again, If you need to restart, please select restart" + else + systemctl start $1 + sleep 2 + check_status $1 + if [[ $? == 0 ]]; then + LOGI "${1} Started Successfully" + else + LOGE "Failed to start ${1}, Probably because it takes longer than two seconds to start, Please check the log information later" + fi + fi + + if [[ $# == 1 ]]; then + before_show_menu + fi +} + +stop() { + check_status $1 + if [[ $? == 1 ]]; then + echo "" + LOGI "${1} stopped, No need to stop again!" + else + systemctl stop $1 + sleep 2 + check_status + if [[ $? == 1 ]]; then + LOGI "${1} stopped successfully" + else + LOGE "Falied to stop ${1}, Probably because the stop time exceeds two seconds, Please check the log information later" + fi + fi + + if [[ $# == 1 ]]; then + before_show_menu + fi +} + +restart() { + systemctl restart $1 + sleep 2 + check_status $1 + if [[ $? == 0 ]]; then + LOGI "${1} Restarted successfully" + else + LOGE "Failed to restart ${1}, Probably because it takes longer than two seconds to start, Please check the log information later" + fi + if [[ $# == 1 ]]; then + before_show_menu + fi +} + +status() { + systemctl status s-ui -l + systemctl status sing-box -l + if [[ $# == 0 ]]; then + before_show_menu + fi +} + +enable() { + systemctl enable $1 + if [[ $? == 0 ]]; then + LOGI "Set ${1} to boot automatically on startup successfully" + else + LOGE "Failed to set ${1} Autostart" + fi + + if [[ $# == 1 ]]; then + before_show_menu + fi +} + +disable() { + systemctl disable $1 + if [[ $? == 0 ]]; then + LOGI "Autostart ${1} Cancelled successfully" + else + LOGE "Failed to cancel ${1} autostart" + fi + + if [[ $# == 1 ]]; then + before_show_menu + fi +} + +show_log() { + journalctl -u $1.service -e --no-pager -f + if [[ $# == 1 ]]; then + before_show_menu + fi +} + +update_shell() { + wget -O /usr/bin/s-ui -N --no-check-certificate https://github.com/alireza0/s-ui/raw/main/s-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/s-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/$1.service" ]]; then + return 2 + fi + temp=$(systemctl status "$1" | grep Active | awk '{print $3}' | cut -d "(" -f2 | cut -d ")" -f1) + if [[ x"${temp}" == x"running" ]]; then + return 0 + else + return 1 + fi +} + +check_enabled() { + temp=$(systemctl is-enabled $1) + if [[ x"${temp}" == x"enabled" ]]; then + return 0 + else + return 1 + fi +} + +check_uninstall() { + check_status s-ui + if [[ $? != 2 ]]; then + echo "" + LOGE "Panel is already installed, Please do not reinstall" + if [[ $# == 0 ]]; then + before_show_menu + fi + return 1 + else + return 0 + fi +} + +check_install() { + check_status s-ui + 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 $1 + case $? in + 0) + echo -e "${1} state: ${green}Running${plain}" + show_enable_status $1 + ;; + 1) + echo -e "${1} state: ${yellow}Not Running${plain}" + show_enable_status $1 + ;; + 2) + echo -e "${1} state: ${red}Not Installed${plain}" + ;; + esac +} + +show_enable_status() { + check_enabled $1 + if [[ $? == 0 ]]; then + echo -e "Start automatically: ${green}Yes${plain}" + else + echo -e "Start automatically: ${red}No${plain}" + fi +} + +check_s-ui_status() { + count=$(ps -ef | grep "sui" | grep -v "grep" | wc -l) + if [[ count -ne 0 ]]; then + return 0 + else + return 1 + fi +} + +show_s-ui_status() { + check_s-ui_status + if [[ $? == 0 ]]; then + echo -e "s-ui state: ${green}Running${plain}" + else + echo -e "s-ui state: ${red}Not Running${plain}" + fi +} + +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" + read -p "Choose an option: " choice + case "$choice" in + 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) + apt update && apt install socat -y ;; + centos) + yum -y update && yum -y install socat ;; + fedora) + dnf -y update && dnf -y install 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 +} + +show_usage() { + echo -e "S-UI Control Menu Usage" + echo -e "------------------------------------------" + echo -e "SUBCOMMANDS:" + echo -e "s-ui - Admin Management Script" + echo -e "s-ui start - Start s-ui and sing-box" + echo -e "s-ui stop - Stop s-ui and sing-box" + echo -e "s-ui restart - Restart s-ui and sing-box" + echo -e "s-ui status - Current Status of s-ui and sing-box" + echo -e "s-ui enable - Enable Autostart on OS Startup" + echo -e "s-ui disable - Disable Autostart on OS Startup" + echo -e "s-ui log - Check s-ui Logs" + echo -e "s-ui update - Update" + echo -e "s-ui install - Install" + echo -e "s-ui uninstall - Uninstall" + echo -e "s-ui help - Control Menu Usage" + echo -e "------------------------------------------" +} + +show_menu() { + echo -e " + ${green}S-UI Admin Management Script ${plain} +———————————————————————————————— + ${green}0.${plain} Exit +———————————————————————————————— + ${green}1.${plain} Install + ${green}2.${plain} Update + ${green}3.${plain} Custom Version + ${green}4.${plain} Uninstall +———————————————————————————————— + ${green}5.${plain} Reset admin credentials to default + ${green}6.${plain} Set admin credentials + ${green}7.${plain} View admin credentials +———————————————————————————————— + ${green}8.${plain} Reset Panel Settings + ${green}9.${plain} Set Panel settings + ${green}10.${plain} View Panel Settings +———————————————————————————————— + ${green}11.${plain} S-UI Start + ${green}12.${plain} S-UI Stop + ${green}13.${plain} S-UI Restart + ${green}14.${plain} S-UI Check State + ${green}15.${plain} S-UI Check Logs + ${green}16.${plain} S-UI Enable Autostart + ${green}17.${plain} S-UI Disable Autostart +———————————————————————————————— + ${green}18.${plain} Sing-Box Start + ${green}19.${plain} Sing-Box Stop + ${green}20.${plain} Sing-Box Restart + ${green}21.${plain} Sing-Box Check State + ${green}22.${plain} Sing-Box Check Logs + ${green}23.${plain} Sing-Box Enable Autostart + ${green}24.${plain} Sing-Box Disable Autostart +———————————————————————————————— + ${green}25.${plain} A Key Installation BBR (latest kernel) + ${green}26.${plain} SSL Certificate Management + ${green}27.${plain} Cloudflare SSL Certificate +———————————————————————————————— + " + show_status s-ui + show_status sing-box + echo && read -p "Please enter your selection [0-27]: " 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_admin + ;; + 6) + check_install && set_admin + ;; + 7) + check_install && view_admin + ;; + 8) + check_install && reset_setting + ;; + 9) + check_install && set_setting + ;; + 10) + check_install && view_setting + ;; + 11) + check_install && start s-ui + ;; + 12) + check_install && stop s-ui + ;; + 13) + check_install && restart s-ui + ;; + 14) + check_install && status s-ui + ;; + 15) + check_install && show_log s-ui + ;; + 16) + check_install && enable s-ui + ;; + 17) + check_install && disable s-ui + ;; + 18) + check_install && start sing-box + ;; + 19) + check_install && stop sing-box + ;; + 20) + check_install && restart sing-box + ;; + 21) + check_install && status sing-box + ;; + 22) + check_install && show_log sing-box + ;; + 23) + check_install && enable sing-box + ;; + 24) + check_install && disable sing-box + ;; + 25) + install_bbr + ;; + 26) + ssl_cert_issue_main + ;; + 27) + ssl_cert_issue_CF + ;; + *) + LOGE "Please enter the correct number [0-27]" + ;; + esac +} + +if [[ $# > 0 ]]; then + case $1 in + "start") + check_install 0 && start s-ui 0 && start sing-box 0 + ;; + "stop") + check_install 0 && stop s-ui 0 && stop sing-box 0 + ;; + "restart") + check_install 0 && restart s-ui 0 && restart sing-box 0 + ;; + "status") + check_install 0 && status 0 + ;; + "enable") + check_install 0 && enable s-ui 0 && enable sing-box 0 + ;; + "disable") + check_install 0 && disable s-ui 0 && disable sing-box 0 + ;; + "log") + check_install 0 && show_log s-ui 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 \ No newline at end of file