mirror of
https://github.com/alireza0/x-ui.git
synced 2026-03-14 05:23:09 +00:00
random path - set cert to panel
random port make random path if empty Show Existing Domains set cert to panel
This commit is contained in:
82
install.sh
82
install.sh
@@ -117,38 +117,76 @@ install_dependencies() {
|
|||||||
esac
|
esac
|
||||||
}
|
}
|
||||||
|
|
||||||
#This function will be called when user installed x-ui out of security
|
gen_random_string() {
|
||||||
|
local length="$1"
|
||||||
|
local random_string=$(LC_ALL=C tr -dc 'a-zA-Z0-9' </dev/urandom | fold -w "$length" | head -n 1)
|
||||||
|
echo "$random_string"
|
||||||
|
}
|
||||||
|
|
||||||
config_after_install() {
|
config_after_install() {
|
||||||
echo -e "${yellow}Install/update finished! For security it's recommended to modify panel settings ${plain}"
|
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
|
read -p "Would you like to customize the panel settings? (If not, random settings will be applied) [y/n]: " config_confirm
|
||||||
|
|
||||||
|
local config_webBasePath=$(gen_random_string 10)
|
||||||
|
|
||||||
if [[ "${config_confirm}" == "y" || "${config_confirm}" == "Y" ]]; then
|
if [[ "${config_confirm}" == "y" || "${config_confirm}" == "Y" ]]; then
|
||||||
read -p "Please set up your username:" config_account
|
|
||||||
echo -e "${yellow}Your username will be:${config_account}${plain}"
|
read -p "Please set up your username: " config_account
|
||||||
read -p "Please set up your password:" config_password
|
echo -e "${yellow}Your username will be: ${config_account}${plain}"
|
||||||
echo -e "${yellow}Your password will be:${config_password}${plain}"
|
|
||||||
read -p "Please set up the panel port:" config_port
|
read -p "Please set up your password: " config_password
|
||||||
echo -e "${yellow}Your panel port is:${config_port}${plain}"
|
echo -e "${yellow}Your password will be: ${config_password}${plain}"
|
||||||
|
|
||||||
|
read -p "Please set up the panel port: " config_port
|
||||||
|
echo -e "${yellow}Your panel port is: ${config_port}${plain}"
|
||||||
|
|
||||||
|
echo -e "${yellow}Your web base path will be generated randomly: ${config_webBasePath}${plain}"
|
||||||
|
|
||||||
echo -e "${yellow}Initializing, please wait...${plain}"
|
echo -e "${yellow}Initializing, please wait...${plain}"
|
||||||
/usr/local/x-ui/x-ui setting -username ${config_account} -password ${config_password}
|
|
||||||
echo -e "${yellow}Account name and password set successfully!${plain}"
|
/usr/local/x-ui/x-ui setting -username "${config_account}" -password "${config_password}" -port "${config_port}" -webBasePath "${config_webBasePath}"
|
||||||
/usr/local/x-ui/x-ui setting -port ${config_port}
|
echo -e "${yellow}Settings applied successfully!${plain}"
|
||||||
echo -e "${yellow}Panel port set successfully!${plain}"
|
|
||||||
|
echo -e "###############################################"
|
||||||
|
echo -e "${green}Username: ${config_account}${plain}"
|
||||||
|
echo -e "${green}Password: ${config_password}${plain}"
|
||||||
|
echo -e "${green}Port: ${config_port}${plain}"
|
||||||
|
echo -e "${green}WebBasePath: ${config_webBasePath}${plain}"
|
||||||
|
echo -e "###############################################"
|
||||||
|
|
||||||
else
|
else
|
||||||
echo -e "${red}cancel...${plain}"
|
|
||||||
|
echo -e "${red}Cancel...${plain}"
|
||||||
|
|
||||||
if [[ ! -f "/etc/x-ui/x-ui.db" ]]; then
|
if [[ ! -f "/etc/x-ui/x-ui.db" ]]; then
|
||||||
local usernameTemp=$(head -c 6 /dev/urandom | base64)
|
|
||||||
local passwordTemp=$(head -c 6 /dev/urandom | base64)
|
local usernameTemp=$(gen_random_string 10)
|
||||||
/usr/local/x-ui/x-ui setting -username ${usernameTemp} -password ${passwordTemp}
|
local passwordTemp=$(gen_random_string 10)
|
||||||
echo -e "this is a fresh installation,will generate random login info for security concerns:"
|
local portTemp=$(shuf -i 1024-62000 -n 1)
|
||||||
|
|
||||||
|
/usr/local/x-ui/x-ui setting -username "${usernameTemp}" -password "${passwordTemp}" -port "${portTemp}" -webBasePath "${config_webBasePath}"
|
||||||
|
echo -e "This is a fresh installation, generating random login info for security concerns:"
|
||||||
echo -e "###############################################"
|
echo -e "###############################################"
|
||||||
echo -e "${green}username:${usernameTemp}${plain}"
|
echo -e "${green}Username: ${usernameTemp}${plain}"
|
||||||
echo -e "${green}password:${passwordTemp}${plain}"
|
echo -e "${green}Password: ${passwordTemp}${plain}"
|
||||||
|
echo -e "${green}Port: ${portTemp}${plain}"
|
||||||
|
echo -e "${green}WebBasePath: ${config_webBasePath}${plain}"
|
||||||
echo -e "###############################################"
|
echo -e "###############################################"
|
||||||
echo -e "${red}if you forgot your login info,you can type x-ui and then type 7 to check after installation${plain}"
|
echo -e "${yellow}If you forgot your login info, you can type 'x-ui settings' to check after installation${plain}"
|
||||||
else
|
else
|
||||||
echo -e "${red} this is your upgrade,will keep old settings,if you forgot your login info,you can type x-ui and then type 7 to check${plain}"
|
echo -e "${yellow}This is your upgrade, keeping old settings. If you forgot your login info, you can type 'x-ui settings' to check${plain}"
|
||||||
|
|
||||||
|
local existing_webBasePath=$(/usr/local/x-ui/x-ui setting -show true | grep -Eo 'webBasePath: .+' | awk '{print $2}')
|
||||||
|
|
||||||
|
if [[ ${#existing_webBasePath} -lt 4 ]]; then
|
||||||
|
echo -e "${yellow}WebBasePath is empty, generating a random one...${plain}"
|
||||||
|
|
||||||
|
/usr/local/x-ui/x-ui setting -webBasePath "${config_webBasePath}"
|
||||||
|
echo -e "${green}New webBasePath: ${config_webBasePath}${plain}"
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
/usr/local/x-ui/x-ui migrate
|
/usr/local/x-ui/x-ui migrate
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
109
main.go
109
main.go
@@ -123,22 +123,35 @@ func showSetting(show bool) {
|
|||||||
settingService := service.SettingService{}
|
settingService := service.SettingService{}
|
||||||
port, err := settingService.GetPort()
|
port, err := settingService.GetPort()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println("get current port failed,error info:", err)
|
fmt.Println("get current port failed, error info:", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
webBasePath, err := settingService.GetBasePath()
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println("get webBasePath failed, error info:", err)
|
||||||
|
}
|
||||||
|
|
||||||
userService := service.UserService{}
|
userService := service.UserService{}
|
||||||
userModel, err := userService.GetFirstUser()
|
userModel, err := userService.GetFirstUser()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println("get current user info failed,error info:", err)
|
fmt.Println("get current user info failed, error info:", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
username := userModel.Username
|
username := userModel.Username
|
||||||
userpasswd := userModel.Password
|
userpasswd := userModel.Password
|
||||||
if (username == "") || (userpasswd == "") {
|
if username == "" || userpasswd == "" {
|
||||||
fmt.Println("current username or password is empty")
|
fmt.Println("current username or password is empty")
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Println("current panel settings as follows:")
|
fmt.Println("current panel settings as follows:")
|
||||||
fmt.Println("username:", username)
|
fmt.Println("username:", username)
|
||||||
fmt.Println("userpasswd:", userpasswd)
|
fmt.Println("password:", userpasswd)
|
||||||
fmt.Println("port:", port)
|
fmt.Println("port:", port)
|
||||||
|
if webBasePath != "" {
|
||||||
|
fmt.Println("webBasePath:", webBasePath)
|
||||||
|
} else {
|
||||||
|
fmt.Println("webBasePath is not set")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -201,31 +214,67 @@ func updateTgbotSetting(tgBotToken string, tgBotChatid string, tgBotRuntime stri
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func updateSetting(port int, username string, password string) {
|
func updateSetting(port int, username string, password string, webBasePath string) {
|
||||||
|
err := database.InitDB(config.GetDBPath())
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println("Database initialization failed:", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
settingService := service.SettingService{}
|
||||||
|
userService := service.UserService{}
|
||||||
|
|
||||||
|
if port > 0 {
|
||||||
|
err := settingService.SetPort(port)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println("Failed to set port:", err)
|
||||||
|
} else {
|
||||||
|
fmt.Printf("Port set successfully: %v\n", port)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if username != "" || password != "" {
|
||||||
|
err := userService.UpdateFirstUser(username, password)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println("Failed to update username and password:", err)
|
||||||
|
} else {
|
||||||
|
fmt.Println("Username and password updated successfully")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if webBasePath != "" {
|
||||||
|
err := settingService.SetBasePath(webBasePath)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println("Failed to set base URI path:", err)
|
||||||
|
} else {
|
||||||
|
fmt.Println("Base URI path set successfully")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
func updateCert(publicKey string, privateKey string) {
|
||||||
err := database.InitDB(config.GetDBPath())
|
err := database.InitDB(config.GetDBPath())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println(err)
|
fmt.Println(err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
settingService := service.SettingService{}
|
if (privateKey != "" && publicKey != "") || (privateKey == "" && publicKey == "") {
|
||||||
|
settingService := service.SettingService{}
|
||||||
|
err = settingService.SetCertFile(publicKey)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println("set certificate public key failed:", err)
|
||||||
|
} else {
|
||||||
|
fmt.Println("set certificate public key success")
|
||||||
|
}
|
||||||
|
|
||||||
if port > 0 {
|
err = settingService.SetKeyFile(privateKey)
|
||||||
err := settingService.SetPort(port)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println("set port failed:", err)
|
fmt.Println("set certificate private key failed:", err)
|
||||||
} else {
|
} else {
|
||||||
fmt.Printf("set port %v success", port)
|
fmt.Println("set certificate private key success")
|
||||||
}
|
|
||||||
}
|
|
||||||
if username != "" || password != "" {
|
|
||||||
userService := service.UserService{}
|
|
||||||
err := userService.UpdateFirstUser(username, password)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println("set username and password failed:", err)
|
|
||||||
} else {
|
|
||||||
fmt.Println("set username and password success")
|
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
fmt.Println("both public and private key should be entered.")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -256,6 +305,9 @@ func main() {
|
|||||||
var port int
|
var port int
|
||||||
var username string
|
var username string
|
||||||
var password string
|
var password string
|
||||||
|
var webBasePath string
|
||||||
|
var webCertFile string
|
||||||
|
var webKeyFile string
|
||||||
var tgbottoken string
|
var tgbottoken string
|
||||||
var tgbotchatid string
|
var tgbotchatid string
|
||||||
var enabletgbot bool
|
var enabletgbot bool
|
||||||
@@ -267,7 +319,10 @@ func main() {
|
|||||||
settingCmd.IntVar(&port, "port", 0, "set panel port")
|
settingCmd.IntVar(&port, "port", 0, "set panel port")
|
||||||
settingCmd.StringVar(&username, "username", "", "set login username")
|
settingCmd.StringVar(&username, "username", "", "set login username")
|
||||||
settingCmd.StringVar(&password, "password", "", "set login password")
|
settingCmd.StringVar(&password, "password", "", "set login password")
|
||||||
settingCmd.StringVar(&tgbottoken, "tgbottoken", "", "set telegram bot token")
|
settingCmd.StringVar(&webBasePath, "webBasePath", "", "Set base path for Panel")
|
||||||
|
settingCmd.StringVar(&webCertFile, "webCert", "", "Set path to public key file for panel")
|
||||||
|
settingCmd.StringVar(&webKeyFile, "webCertKey", "", "Set path to private key file for panel")
|
||||||
|
settingCmd.StringVar(&tgbottoken, "tgbottoken", "", "Set token for Telegram bot")
|
||||||
settingCmd.StringVar(&tgbotRuntime, "tgbotRuntime", "", "set telegram bot cron time")
|
settingCmd.StringVar(&tgbotRuntime, "tgbotRuntime", "", "set telegram bot cron time")
|
||||||
settingCmd.StringVar(&tgbotchatid, "tgbotchatid", "", "set telegram bot chat id")
|
settingCmd.StringVar(&tgbotchatid, "tgbotchatid", "", "set telegram bot chat id")
|
||||||
settingCmd.BoolVar(&enabletgbot, "enabletgbot", false, "enable telegram bot notify")
|
settingCmd.BoolVar(&enabletgbot, "enabletgbot", false, "enable telegram bot notify")
|
||||||
@@ -307,7 +362,7 @@ func main() {
|
|||||||
if reset {
|
if reset {
|
||||||
resetSetting()
|
resetSetting()
|
||||||
} else {
|
} else {
|
||||||
updateSetting(port, username, password)
|
updateSetting(port, username, password, webBasePath)
|
||||||
}
|
}
|
||||||
if show {
|
if show {
|
||||||
showSetting(show)
|
showSetting(show)
|
||||||
@@ -318,6 +373,18 @@ func main() {
|
|||||||
if enabletgbot {
|
if enabletgbot {
|
||||||
updateTgbotEnableSts(enabletgbot)
|
updateTgbotEnableSts(enabletgbot)
|
||||||
}
|
}
|
||||||
|
case "cert":
|
||||||
|
err := settingCmd.Parse(os.Args[2:])
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if reset {
|
||||||
|
updateCert("", "")
|
||||||
|
} else {
|
||||||
|
updateCert(webCertFile, webKeyFile)
|
||||||
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
fmt.Println("Invalid subcommands")
|
fmt.Println("Invalid subcommands")
|
||||||
fmt.Println()
|
fmt.Println()
|
||||||
|
|||||||
@@ -283,10 +283,18 @@ func (s *SettingService) SetPort(port int) error {
|
|||||||
return s.setInt("webPort", port)
|
return s.setInt("webPort", port)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *SettingService) SetCertFile(webCertFile string) error {
|
||||||
|
return s.setString("webCertFile", webCertFile)
|
||||||
|
}
|
||||||
|
|
||||||
func (s *SettingService) GetCertFile() (string, error) {
|
func (s *SettingService) GetCertFile() (string, error) {
|
||||||
return s.getString("webCertFile")
|
return s.getString("webCertFile")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *SettingService) SetKeyFile(webKeyFile string) error {
|
||||||
|
return s.setString("webKeyFile", webKeyFile)
|
||||||
|
}
|
||||||
|
|
||||||
func (s *SettingService) GetKeyFile() (string, error) {
|
func (s *SettingService) GetKeyFile() (string, error) {
|
||||||
return s.getString("webKeyFile")
|
return s.getString("webKeyFile")
|
||||||
}
|
}
|
||||||
@@ -318,6 +326,16 @@ func (s *SettingService) GetSecret() ([]byte, error) {
|
|||||||
return []byte(secret), err
|
return []byte(secret), err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *SettingService) SetBasePath(basePath string) error {
|
||||||
|
if !strings.HasPrefix(basePath, "/") {
|
||||||
|
basePath = "/" + basePath
|
||||||
|
}
|
||||||
|
if !strings.HasSuffix(basePath, "/") {
|
||||||
|
basePath += "/"
|
||||||
|
}
|
||||||
|
return s.setString("webBasePath", basePath)
|
||||||
|
}
|
||||||
|
|
||||||
func (s *SettingService) GetBasePath() (string, error) {
|
func (s *SettingService) GetBasePath() (string, error) {
|
||||||
basePath, err := s.getString("webBasePath")
|
basePath, err := s.getString("webBasePath")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
347
x-ui.sh
347
x-ui.sh
@@ -34,7 +34,6 @@ fi
|
|||||||
|
|
||||||
echo "The OS release is: $release"
|
echo "The OS release is: $release"
|
||||||
|
|
||||||
|
|
||||||
os_version=""
|
os_version=""
|
||||||
os_version=$(grep -i version_id /etc/os-release | cut -d \" -f2 | cut -d . -f1)
|
os_version=$(grep -i version_id /etc/os-release | cut -d \" -f2 | cut -d . -f1)
|
||||||
|
|
||||||
@@ -158,7 +157,7 @@ custom_version() {
|
|||||||
|
|
||||||
if [ -z "$panel_version" ]; then
|
if [ -z "$panel_version" ]; then
|
||||||
echo "Panel version cannot be empty. Exiting."
|
echo "Panel version cannot be empty. Exiting."
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
download_link="https://raw.githubusercontent.com/alireza0/x-ui/master/install.sh"
|
download_link="https://raw.githubusercontent.com/alireza0/x-ui/master/install.sh"
|
||||||
@@ -172,7 +171,7 @@ custom_version() {
|
|||||||
|
|
||||||
# Function to handle the deletion of the script file
|
# Function to handle the deletion of the script file
|
||||||
delete_script() {
|
delete_script() {
|
||||||
rm "$0" # Remove the script file itself
|
rm "$0" # Remove the script file itself
|
||||||
exit 1
|
exit 1
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -214,6 +213,31 @@ reset_user() {
|
|||||||
confirm_restart
|
confirm_restart
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gen_random_string() {
|
||||||
|
local length="$1"
|
||||||
|
local random_string=$(LC_ALL=C tr -dc 'a-zA-Z0-9' </dev/urandom | fold -w "$length" | head -n 1)
|
||||||
|
echo "$random_string"
|
||||||
|
}
|
||||||
|
|
||||||
|
reset_webbasepath() {
|
||||||
|
echo -e "${yellow}Resetting Web Base Path${plain}"
|
||||||
|
|
||||||
|
read -rp "Are you sure you want to reset the web base path? (y/n): " confirm
|
||||||
|
if [[ $confirm != "y" && $confirm != "Y" ]]; then
|
||||||
|
echo -e "${yellow}Operation canceled.${plain}"
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
|
config_webBasePath=$(gen_random_string 10)
|
||||||
|
|
||||||
|
# Apply the new web base path setting
|
||||||
|
/usr/local/x-ui/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 "${green}Please use the new web base path to access the panel.${plain}"
|
||||||
|
restart
|
||||||
|
}
|
||||||
|
|
||||||
reset_config() {
|
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"
|
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
|
||||||
@@ -452,15 +476,23 @@ show_xray_status() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
install_acme() {
|
install_acme() {
|
||||||
cd ~
|
# Check if acme.sh is already installed
|
||||||
LOGI "install acme..."
|
if command -v ~/.acme.sh/acme.sh &>/dev/null; then
|
||||||
curl https://get.acme.sh | sh
|
LOGI "acme.sh is already installed."
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
LOGI "Installing acme.sh..."
|
||||||
|
cd ~ || return 1 # Ensure you can change to the home directory
|
||||||
|
|
||||||
|
curl -s https://get.acme.sh | sh
|
||||||
if [ $? -ne 0 ]; then
|
if [ $? -ne 0 ]; then
|
||||||
LOGE "install acme failed"
|
LOGE "Installation of acme.sh failed."
|
||||||
return 1
|
return 1
|
||||||
else
|
else
|
||||||
LOGI "install acme succeed"
|
LOGI "Installation of acme.sh succeeded."
|
||||||
fi
|
fi
|
||||||
|
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -468,20 +500,100 @@ ssl_cert_issue_main() {
|
|||||||
echo -e "${green}\t1.${plain} Get SSL"
|
echo -e "${green}\t1.${plain} Get SSL"
|
||||||
echo -e "${green}\t2.${plain} Revoke"
|
echo -e "${green}\t2.${plain} Revoke"
|
||||||
echo -e "${green}\t3.${plain} Force Renew"
|
echo -e "${green}\t3.${plain} Force Renew"
|
||||||
|
echo -e "${green}\t4.${plain} Show Existing Domains"
|
||||||
|
echo -e "${green}\t5.${plain} Set Cert paths for the panel"
|
||||||
|
echo -e "${green}\t0.${plain} Back to Main Menu"
|
||||||
|
|
||||||
read -p "Choose an option: " choice
|
read -p "Choose an option: " choice
|
||||||
case "$choice" in
|
case "$choice" in
|
||||||
1) ssl_cert_issue ;;
|
0)
|
||||||
2)
|
show_menu
|
||||||
local domain=""
|
;;
|
||||||
read -p "Please enter your domain name to revoke the certificate: " domain
|
1)
|
||||||
~/.acme.sh/acme.sh --revoke -d ${domain}
|
ssl_cert_issue
|
||||||
LOGI "Certificate revoked"
|
;;
|
||||||
;;
|
2)
|
||||||
3)
|
local domains=$(find /root/cert/ -mindepth 1 -maxdepth 1 -type d -exec basename {} \;)
|
||||||
local domain=""
|
if [ -z "$domains" ]; then
|
||||||
read -p "Please enter your domain name to forcefully renew an SSL certificate: " domain
|
echo "No certificates found to revoke."
|
||||||
~/.acme.sh/acme.sh --renew -d ${domain} --force ;;
|
else
|
||||||
*) echo "Invalid choice" ;;
|
echo "Existing domains:"
|
||||||
|
echo "$domains"
|
||||||
|
read -p "Please enter a domain from the list to revoke the certificate: " domain
|
||||||
|
if echo "$domains" | grep -qw "$domain"; then
|
||||||
|
~/.acme.sh/acme.sh --revoke -d ${domain}
|
||||||
|
LOGI "Certificate revoked for domain: $domain"
|
||||||
|
else
|
||||||
|
echo "Invalid domain entered."
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
3)
|
||||||
|
local domains=$(find /root/cert/ -mindepth 1 -maxdepth 1 -type d -exec basename {} \;)
|
||||||
|
if [ -z "$domains" ]; then
|
||||||
|
echo "No certificates found to renew."
|
||||||
|
else
|
||||||
|
echo "Existing domains:"
|
||||||
|
echo "$domains"
|
||||||
|
read -p "Please enter a domain from the list to renew the SSL certificate: " domain
|
||||||
|
if echo "$domains" | grep -qw "$domain"; then
|
||||||
|
~/.acme.sh/acme.sh --renew -d ${domain} --force
|
||||||
|
LOGI "Certificate forcefully renewed for domain: $domain"
|
||||||
|
else
|
||||||
|
echo "Invalid domain entered."
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
4)
|
||||||
|
local domains=$(find /root/cert/ -mindepth 1 -maxdepth 1 -type d -exec basename {} \;)
|
||||||
|
if [ -z "$domains" ]; then
|
||||||
|
echo "No certificates found."
|
||||||
|
else
|
||||||
|
echo "Existing domains and their paths:"
|
||||||
|
for domain in $domains; do
|
||||||
|
local cert_path="/root/cert/${domain}/fullchain.pem"
|
||||||
|
local key_path="/root/cert/${domain}/privkey.pem"
|
||||||
|
if [[ -f "${cert_path}" && -f "${key_path}" ]]; then
|
||||||
|
echo -e "Domain: ${domain}"
|
||||||
|
echo -e "\tCertificate Path: ${cert_path}"
|
||||||
|
echo -e "\tPrivate Key Path: ${key_path}"
|
||||||
|
else
|
||||||
|
echo -e "Domain: ${domain} - Certificate or Key missing."
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
5)
|
||||||
|
local domains=$(find /root/cert/ -mindepth 1 -maxdepth 1 -type d -exec basename {} \;)
|
||||||
|
if [ -z "$domains" ]; then
|
||||||
|
echo "No certificates found."
|
||||||
|
else
|
||||||
|
echo "Available domains:"
|
||||||
|
echo "$domains"
|
||||||
|
read -p "Please choose a domain to set the panel paths: " domain
|
||||||
|
|
||||||
|
if echo "$domains" | grep -qw "$domain"; then
|
||||||
|
local webCertFile="/root/cert/${domain}/fullchain.pem"
|
||||||
|
local webKeyFile="/root/cert/${domain}/privkey.pem"
|
||||||
|
|
||||||
|
if [[ -f "${webCertFile}" && -f "${webKeyFile}" ]]; then
|
||||||
|
/usr/local/x-ui/x-ui cert -webCert "$webCertFile" -webCertKey "$webKeyFile"
|
||||||
|
echo "Panel paths set for domain: $domain"
|
||||||
|
echo " - Certificate File: $webCertFile"
|
||||||
|
echo " - Private Key File: $webKeyFile"
|
||||||
|
restart
|
||||||
|
else
|
||||||
|
echo "Certificate or private key not found for domain: $domain."
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo "Invalid domain entered."
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
|
||||||
|
*)
|
||||||
|
echo "Invalid choice"
|
||||||
|
;;
|
||||||
esac
|
esac
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -495,6 +607,7 @@ ssl_cert_issue() {
|
|||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# install socat second
|
# install socat second
|
||||||
case "${release}" in
|
case "${release}" in
|
||||||
ubuntu | debian | armbian)
|
ubuntu | debian | armbian)
|
||||||
@@ -503,7 +616,7 @@ ssl_cert_issue() {
|
|||||||
centos | almalinux | rocky | oracle)
|
centos | almalinux | rocky | oracle)
|
||||||
yum -y update && yum -y install socat
|
yum -y update && yum -y install socat
|
||||||
;;
|
;;
|
||||||
fedora)
|
fedora | amzn)
|
||||||
dnf -y update && dnf -y install socat
|
dnf -y update && dnf -y install socat
|
||||||
;;
|
;;
|
||||||
arch | manjaro | parch)
|
arch | manjaro | parch)
|
||||||
@@ -521,23 +634,23 @@ ssl_cert_issue() {
|
|||||||
LOGI "install socat succeed..."
|
LOGI "install socat succeed..."
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# get the domain here,and we need verify it
|
# get the domain here, and we need to verify it
|
||||||
local domain=""
|
local domain=""
|
||||||
read -p "Please enter your domain name:" domain
|
read -p "Please enter your domain name: " domain
|
||||||
LOGD "your domain is:${domain},check it..."
|
LOGD "Your domain is: ${domain}, checking 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
|
# check if there already exists a certificate
|
||||||
|
local currentCert=$(~/.acme.sh/acme.sh --list | tail -1 | awk '{print $1}')
|
||||||
|
if [ "${currentCert}" == "${domain}" ]; then
|
||||||
local certInfo=$(~/.acme.sh/acme.sh --list)
|
local certInfo=$(~/.acme.sh/acme.sh --list)
|
||||||
LOGE "system already has certs here,can not issue again,current certs details:"
|
LOGE "System already has certificates for this domain. Cannot issue again. Current certificate details:"
|
||||||
LOGI "$certInfo"
|
LOGI "$certInfo"
|
||||||
exit 1
|
exit 1
|
||||||
else
|
else
|
||||||
LOGI "your domain is ready for issuing cert now..."
|
LOGI "Your domain is ready for issuing certificates now..."
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# create a directory for install cert
|
# create a directory for the certificate
|
||||||
certPath="/root/cert/${domain}"
|
certPath="/root/cert/${domain}"
|
||||||
if [ ! -d "$certPath" ]; then
|
if [ ! -d "$certPath" ]; then
|
||||||
mkdir -p "$certPath"
|
mkdir -p "$certPath"
|
||||||
@@ -546,48 +659,70 @@ ssl_cert_issue() {
|
|||||||
mkdir -p "$certPath"
|
mkdir -p "$certPath"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# get needed port here
|
# get the port number for the standalone server
|
||||||
local WebPort=80
|
local WebPort=80
|
||||||
read -p "please choose which port do you use,default will be 80 port:" WebPort
|
read -p "Please choose which port to use (default is 80): " WebPort
|
||||||
if [[ ${WebPort} -gt 65535 || ${WebPort} -lt 1 ]]; then
|
if [[ ${WebPort} -gt 65535 || ${WebPort} -lt 1 ]]; then
|
||||||
LOGE "your input ${WebPort} is invalid,will use default port"
|
LOGE "Your input ${WebPort} is invalid, will use default port 80."
|
||||||
|
WebPort=80
|
||||||
fi
|
fi
|
||||||
LOGI "will use port:${WebPort} to issue certs,please make sure this port is open..."
|
LOGI "Will use port: ${WebPort} to issue certificates. Please make sure this port is open."
|
||||||
# NOTE:This should be handled by user
|
|
||||||
# open the port and kill the occupied progress
|
# issue the certificate
|
||||||
~/.acme.sh/acme.sh --set-default-ca --server letsencrypt
|
~/.acme.sh/acme.sh --set-default-ca --server letsencrypt
|
||||||
~/.acme.sh/acme.sh --issue -d ${domain} --standalone --httpport ${WebPort}
|
~/.acme.sh/acme.sh --issue -d ${domain} --listen-v6 --standalone --httpport ${WebPort}
|
||||||
if [ $? -ne 0 ]; then
|
if [ $? -ne 0 ]; then
|
||||||
LOGE "issue certs failed,please check logs"
|
LOGE "Issuing certificate failed, please check logs."
|
||||||
rm -rf ~/.acme.sh/${domain}
|
rm -rf ~/.acme.sh/${domain}
|
||||||
exit 1
|
exit 1
|
||||||
else
|
else
|
||||||
LOGE "issue certs succeed,installing certs..."
|
LOGE "Issuing certificate succeeded, installing certificates..."
|
||||||
fi
|
fi
|
||||||
# install cert
|
|
||||||
|
# install the certificate
|
||||||
~/.acme.sh/acme.sh --installcert -d ${domain} \
|
~/.acme.sh/acme.sh --installcert -d ${domain} \
|
||||||
--key-file /root/cert/${domain}/privkey.pem \
|
--key-file /root/cert/${domain}/privkey.pem \
|
||||||
--fullchain-file /root/cert/${domain}/fullchain.pem
|
--fullchain-file /root/cert/${domain}/fullchain.pem
|
||||||
|
|
||||||
if [ $? -ne 0 ]; then
|
if [ $? -ne 0 ]; then
|
||||||
LOGE "install certs failed,exit"
|
LOGE "Installing certificate failed, exiting."
|
||||||
rm -rf ~/.acme.sh/${domain}
|
rm -rf ~/.acme.sh/${domain}
|
||||||
exit 1
|
exit 1
|
||||||
else
|
else
|
||||||
LOGI "install certs succeed,enable auto renew..."
|
LOGI "Installing certificate succeeded, enabling auto renew..."
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# enable auto-renew
|
||||||
~/.acme.sh/acme.sh --upgrade --auto-upgrade
|
~/.acme.sh/acme.sh --upgrade --auto-upgrade
|
||||||
if [ $? -ne 0 ]; then
|
if [ $? -ne 0 ]; then
|
||||||
LOGE "auto renew failed, certs details:"
|
LOGE "Auto renew failed, certificate details:"
|
||||||
ls -lah cert/*
|
ls -lah cert/*
|
||||||
chmod 755 $certPath/*
|
chmod 755 $certPath/*
|
||||||
exit 1
|
exit 1
|
||||||
else
|
else
|
||||||
LOGI "auto renew succeed, certs details:"
|
LOGI "Auto renew succeeded, certificate details:"
|
||||||
ls -lah cert/*
|
ls -lah cert/*
|
||||||
chmod 755 $certPath/*
|
chmod 755 $certPath/*
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# Prompt user to set panel paths after successful certificate installation
|
||||||
|
read -p "Would you like to set this certificate for the panel? (y/n): " setPanel
|
||||||
|
if [[ "$setPanel" == "y" || "$setPanel" == "Y" ]]; then
|
||||||
|
local webCertFile="/root/cert/${domain}/fullchain.pem"
|
||||||
|
local webKeyFile="/root/cert/${domain}/privkey.pem"
|
||||||
|
|
||||||
|
if [[ -f "$webCertFile" && -f "$webKeyFile" ]]; then
|
||||||
|
/usr/local/x-ui/x-ui cert -webCert "$webCertFile" -webCertKey "$webKeyFile"
|
||||||
|
LOGI "Panel paths set for domain: $domain"
|
||||||
|
LOGI " - Certificate File: $webCertFile"
|
||||||
|
LOGI " - Private Key File: $webKeyFile"
|
||||||
|
restart
|
||||||
|
else
|
||||||
|
LOGE "Error: Certificate or private key file not found for domain: $domain."
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
LOGI "Skipping panel path setting."
|
||||||
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
ssl_cert_issue_CF() {
|
ssl_cert_issue_CF() {
|
||||||
@@ -643,8 +778,8 @@ ssl_cert_issue_CF() {
|
|||||||
LOGI "Certificate issued Successfully, Installing..."
|
LOGI "Certificate issued Successfully, Installing..."
|
||||||
fi
|
fi
|
||||||
~/.acme.sh/acme.sh --installcert -d ${CF_Domain} -d *.${CF_Domain} --ca-file /root/cert/ca.cer \
|
~/.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 \
|
--cert-file /root/cert/${CF_Domain}.cer --key-file /root/cert/${CF_Domain}.key \
|
||||||
--fullchain-file /root/cert/fullchain.cer
|
--fullchain-file /root/cert/fullchain.cer
|
||||||
if [ $? -ne 0 ]; then
|
if [ $? -ne 0 ]; then
|
||||||
LOGE "Certificate installation failed, script exiting..."
|
LOGE "Certificate installation failed, script exiting..."
|
||||||
exit 1
|
exit 1
|
||||||
@@ -867,32 +1002,32 @@ update_geo() {
|
|||||||
read -p "Select: " select
|
read -p "Select: " select
|
||||||
|
|
||||||
case "$select" in
|
case "$select" in
|
||||||
0)
|
0)
|
||||||
show_menu
|
show_menu
|
||||||
;;
|
;;
|
||||||
|
|
||||||
1)
|
1)
|
||||||
wget -N "https://github.com/Loyalsoldier/v2ray-rules-dat/releases/latest/download/geoip.dat" && echo -e "${green}Success${plain}\n" || echo -e "${red}Failure${plain}\n"
|
wget -N "https://github.com/Loyalsoldier/v2ray-rules-dat/releases/latest/download/geoip.dat" && echo -e "${green}Success${plain}\n" || echo -e "${red}Failure${plain}\n"
|
||||||
wget -N "https://github.com/Loyalsoldier/v2ray-rules-dat/releases/latest/download/geosite.dat" && echo -e "${green}Success${plain}\n" || echo -e "${red}Failure${plain}\n"
|
wget -N "https://github.com/Loyalsoldier/v2ray-rules-dat/releases/latest/download/geosite.dat" && echo -e "${green}Success${plain}\n" || echo -e "${red}Failure${plain}\n"
|
||||||
wget "https://github.com/chocolate4u/Iran-v2ray-rules/releases/latest/download/geoip.dat" -O /tmp/wget && mv /tmp/wget geoip_IR.dat && echo -e "${green}Success${plain}\n" || echo -e "${red}Failure${plain}\n"
|
wget "https://github.com/chocolate4u/Iran-v2ray-rules/releases/latest/download/geoip.dat" -O /tmp/wget && mv /tmp/wget geoip_IR.dat && echo -e "${green}Success${plain}\n" || echo -e "${red}Failure${plain}\n"
|
||||||
wget "https://github.com/chocolate4u/Iran-v2ray-rules/releases/latest/download/geosite.dat" -O /tmp/wget && mv /tmp/wget geosite_IR.dat && echo -e "${green}Success${plain}\n" || echo -e "${red}Failure${plain}\n"
|
wget "https://github.com/chocolate4u/Iran-v2ray-rules/releases/latest/download/geosite.dat" -O /tmp/wget && mv /tmp/wget geosite_IR.dat && echo -e "${green}Success${plain}\n" || echo -e "${red}Failure${plain}\n"
|
||||||
echo -e "${green}Files are updated.${plain}"
|
echo -e "${green}Files are updated.${plain}"
|
||||||
confirm_restart
|
confirm_restart
|
||||||
;;
|
;;
|
||||||
|
|
||||||
2)
|
2)
|
||||||
wget -N "https://cdn.jsdelivr.net/gh/Loyalsoldier/v2ray-rules-dat@release/geoip.dat" && echo -e "${green}Success${plain}\n" || echo -e "${red}Failure${plain}\n"
|
wget -N "https://cdn.jsdelivr.net/gh/Loyalsoldier/v2ray-rules-dat@release/geoip.dat" && echo -e "${green}Success${plain}\n" || echo -e "${red}Failure${plain}\n"
|
||||||
wget -N "https://cdn.jsdelivr.net/gh/Loyalsoldier/v2ray-rules-dat@release/geosite.dat" && echo -e "${green}Success${plain}\n" || echo -e "${red}Failure${plain}\n"
|
wget -N "https://cdn.jsdelivr.net/gh/Loyalsoldier/v2ray-rules-dat@release/geosite.dat" && echo -e "${green}Success${plain}\n" || echo -e "${red}Failure${plain}\n"
|
||||||
wget "https://cdn.jsdelivr.net/gh/chocolate4u/Iran-v2ray-rules@release/geoip.dat" -O /tmp/wget && mv /tmp/wget geoip_IR.dat && echo -e "${green}Success${plain}\n" || echo -e "${red}Failure${plain}\n"
|
wget "https://cdn.jsdelivr.net/gh/chocolate4u/Iran-v2ray-rules@release/geoip.dat" -O /tmp/wget && mv /tmp/wget geoip_IR.dat && echo -e "${green}Success${plain}\n" || echo -e "${red}Failure${plain}\n"
|
||||||
wget "https://cdn.jsdelivr.net/gh/chocolate4u/Iran-v2ray-rules@release/geosite.dat" -O /tmp/wget && mv /tmp/wget geosite_IR.dat && echo -e "${green}Success${plain}\n" || echo -e "${red}Failure${plain}\n"
|
wget "https://cdn.jsdelivr.net/gh/chocolate4u/Iran-v2ray-rules@release/geosite.dat" -O /tmp/wget && mv /tmp/wget geosite_IR.dat && echo -e "${green}Success${plain}\n" || echo -e "${red}Failure${plain}\n"
|
||||||
echo -e "${green}Files are updated.${plain}"
|
echo -e "${green}Files are updated.${plain}"
|
||||||
confirm_restart
|
confirm_restart
|
||||||
;;
|
;;
|
||||||
|
|
||||||
*)
|
*)
|
||||||
LOGE "Please enter a correct number [0-2]\n"
|
LOGE "Please enter a correct number [0-2]\n"
|
||||||
update_geo
|
update_geo
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -933,12 +1068,13 @@ run_speedtest() {
|
|||||||
show_usage() {
|
show_usage() {
|
||||||
echo "X-UI Control Menu Usage"
|
echo "X-UI Control Menu Usage"
|
||||||
echo "------------------------------------------"
|
echo "------------------------------------------"
|
||||||
echo "SUBCOMMANDS:"
|
echo "SUBCOMMANDS:"
|
||||||
echo "x-ui - Admin Management Script"
|
echo "x-ui - Admin Management Script"
|
||||||
echo "x-ui start - Start"
|
echo "x-ui start - Start"
|
||||||
echo "x-ui stop - Stop"
|
echo "x-ui stop - Stop"
|
||||||
echo "x-ui restart - Restart"
|
echo "x-ui restart - Restart"
|
||||||
echo "x-ui status - Current Status"
|
echo "x-ui status - Current Status"
|
||||||
|
echo "x-ui settings - Current Settings"
|
||||||
echo "x-ui enable - Enable Autostart on OS Startup"
|
echo "x-ui enable - Enable Autostart on OS Startup"
|
||||||
echo "x-ui disable - Disable Autostart on OS Startup"
|
echo "x-ui disable - Disable Autostart on OS Startup"
|
||||||
echo "x-ui log - Check Logs"
|
echo "x-ui log - Check Logs"
|
||||||
@@ -961,26 +1097,27 @@ show_menu() {
|
|||||||
${green}4.${plain} Uninstall
|
${green}4.${plain} Uninstall
|
||||||
————————————————
|
————————————————
|
||||||
${green}5.${plain} Reset Username and Password
|
${green}5.${plain} Reset Username and Password
|
||||||
${green}6.${plain} Reset Panel Settings
|
${green}6.${plain} Reset Web Base Path
|
||||||
${green}7.${plain} Set Panel Port
|
${green}7.${plain} Reset Panel Settings
|
||||||
${green}8.${plain} View Panel Settings
|
${green}8.${plain} Set Panel Port
|
||||||
|
${green}9.${plain} View Panel Settings
|
||||||
————————————————
|
————————————————
|
||||||
${green}9.${plain} Start
|
${green}10.${plain} Start
|
||||||
${green}10.${plain} Stop
|
${green}11.${plain} Stop
|
||||||
${green}11.${plain} Restart
|
${green}12.${plain} Restart
|
||||||
${green}12.${plain} Check State
|
${green}13.${plain} Check State
|
||||||
${green}13.${plain} Check Logs
|
${green}14.${plain} Check Logs
|
||||||
————————————————
|
————————————————
|
||||||
${green}14.${plain} Enable Autostart
|
${green}15.${plain} Enable Autostart
|
||||||
${green}15.${plain} Disable Autostart
|
${green}16.${plain} Disable Autostart
|
||||||
————————————————
|
————————————————
|
||||||
${green}16.${plain} SSL Certificate Management
|
${green}17.${plain} SSL Certificate Management
|
||||||
${green}17.${plain} Cloudflare SSL Certificate
|
${green}18.${plain} Cloudflare SSL Certificate
|
||||||
${green}18.${plain} Firewall Management
|
${green}19.${plain} Firewall Management
|
||||||
————————————————
|
————————————————
|
||||||
${green}19.${plain} Enable or Disable BBR
|
${green}20.${plain} Enable or Disable BBR
|
||||||
${green}20.${plain} Update Geo Files
|
${green}21.${plain} Update Geo Files
|
||||||
${green}21.${plain} Speedtest by Ookla
|
${green}22.${plain} Speedtest by Ookla
|
||||||
"
|
"
|
||||||
show_status
|
show_status
|
||||||
echo && read -p "Please enter your selection [0-21]: " num
|
echo && read -p "Please enter your selection [0-21]: " num
|
||||||
@@ -1005,55 +1142,58 @@ show_menu() {
|
|||||||
check_install && reset_user
|
check_install && reset_user
|
||||||
;;
|
;;
|
||||||
6)
|
6)
|
||||||
check_install && reset_config
|
check_install && reset_webbasepath
|
||||||
;;
|
;;
|
||||||
7)
|
7)
|
||||||
check_install && set_port
|
check_install && reset_config
|
||||||
;;
|
;;
|
||||||
8)
|
8)
|
||||||
check_install && check_config
|
check_install && set_port
|
||||||
;;
|
;;
|
||||||
9)
|
9)
|
||||||
check_install && start
|
check_install && check_config
|
||||||
;;
|
;;
|
||||||
10)
|
10)
|
||||||
check_install && stop
|
check_install && start
|
||||||
;;
|
;;
|
||||||
11)
|
11)
|
||||||
check_install && restart
|
check_install && stop
|
||||||
;;
|
;;
|
||||||
12)
|
12)
|
||||||
check_install && status
|
check_install && restart
|
||||||
;;
|
;;
|
||||||
13)
|
13)
|
||||||
check_install && show_log
|
check_install && status
|
||||||
;;
|
;;
|
||||||
14)
|
14)
|
||||||
check_install && enable
|
check_install && show_log
|
||||||
;;
|
;;
|
||||||
15)
|
15)
|
||||||
check_install && disable
|
check_install && enable
|
||||||
;;
|
;;
|
||||||
16)
|
16)
|
||||||
ssl_cert_issue_main
|
check_install && disable
|
||||||
;;
|
;;
|
||||||
17)
|
17)
|
||||||
ssl_cert_issue_CF
|
ssl_cert_issue_main
|
||||||
;;
|
;;
|
||||||
18)
|
18)
|
||||||
firewall_menu
|
ssl_cert_issue_CF
|
||||||
;;
|
;;
|
||||||
19)
|
19)
|
||||||
bbr_menu
|
firewall_menu
|
||||||
;;
|
;;
|
||||||
20)
|
20)
|
||||||
update_geo
|
bbr_menu
|
||||||
;;
|
;;
|
||||||
21)
|
21)
|
||||||
|
update_geo
|
||||||
|
;;
|
||||||
|
22)
|
||||||
run_speedtest
|
run_speedtest
|
||||||
;;
|
;;
|
||||||
*)
|
*)
|
||||||
LOGE "Please enter the correct number [0-21]"
|
LOGE "Please enter the correct number [0-22]"
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
}
|
}
|
||||||
@@ -1072,6 +1212,9 @@ if [[ $# > 0 ]]; then
|
|||||||
"status")
|
"status")
|
||||||
check_install 0 && status 0
|
check_install 0 && status 0
|
||||||
;;
|
;;
|
||||||
|
"settings")
|
||||||
|
check_install 0 && check_config 0
|
||||||
|
;;
|
||||||
"enable")
|
"enable")
|
||||||
check_install 0 && enable 0
|
check_install 0 && enable 0
|
||||||
;;
|
;;
|
||||||
|
|||||||
Reference in New Issue
Block a user