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:
mhsanaei
2024-10-08 15:10:03 +02:00
parent a75f4c03a5
commit f758e75a84
4 changed files with 411 additions and 145 deletions

View File

@@ -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
View File

@@ -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()

View File

@@ -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
View File

@@ -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 settingsAccount data will not be lostUsername and password will not change" "n" confirm "Are you sure you want to reset all panel settingsAccount data will not be lostUsername 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
;; ;;