diff --git a/install.sh b/install.sh index af6b8a51..4d74c77c 100644 --- a/install.sh +++ b/install.sh @@ -79,26 +79,26 @@ install_base() { apt-get update && apt-get install -y -q cron curl tar tzdata socat ca-certificates openssl ;; fedora | amzn | virtuozzo | rhel | almalinux | rocky | ol) - dnf -y update && dnf install -y -q curl tar tzdata socat ca-certificates openssl + dnf -y update && dnf install -y -q cronie curl tar tzdata socat ca-certificates openssl ;; centos) if [[ "${VERSION_ID}" =~ ^7 ]]; then - yum -y update && yum install -y curl tar tzdata socat ca-certificates openssl + yum -y update && yum install -y cronie curl tar tzdata socat ca-certificates openssl else - dnf -y update && dnf install -y -q curl tar tzdata socat ca-certificates openssl + dnf -y update && dnf install -y -q cronie curl tar tzdata socat ca-certificates openssl fi ;; arch | manjaro | parch) - pacman -Syu && pacman -Syu --noconfirm curl tar tzdata socat ca-certificates openssl + pacman -Syu && pacman -Syu --noconfirm cronie curl tar tzdata socat ca-certificates openssl ;; opensuse-tumbleweed | opensuse-leap) - zypper refresh && zypper -q install -y curl tar timezone socat ca-certificates openssl + zypper refresh && zypper -q install -y cron curl tar timezone socat ca-certificates openssl ;; alpine) - apk update && apk add curl tar tzdata socat ca-certificates openssl + apk update && apk add dcron curl tar tzdata socat ca-certificates openssl ;; *) - apt-get update && apt-get install -y -q curl tar tzdata socat ca-certificates openssl + apt-get update && apt-get install -y -q cron curl tar tzdata socat ca-certificates openssl ;; esac } @@ -379,15 +379,15 @@ ssl_cert_issue() { break done echo -e "${green}Your domain is: ${domain}, checking it...${plain}" + SSL_ISSUED_DOMAIN="${domain}" - # 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) - echo -e "${red}System already has certificates for this domain. Cannot issue again.${plain}" - echo -e "${yellow}Current certificate details:${plain}" - echo "$certInfo" - return 1 + # detect existing certificate and reuse it if present + local cert_exists=0 + if ~/.acme.sh/acme.sh --list 2>/dev/null | awk '{print $1}' | grep -Fxq "${domain}"; then + cert_exists=1 + local certInfo=$(~/.acme.sh/acme.sh --list 2>/dev/null | grep -F "${domain}") + echo -e "${yellow}Existing certificate found for ${domain}, will reuse it.${plain}" + [[ -n "${certInfo}" ]] && echo "$certInfo" else echo -e "${green}Your domain is ready for issuing certificates now...${plain}" fi @@ -414,16 +414,20 @@ ssl_cert_issue() { echo -e "${yellow}Stopping panel temporarily...${plain}" systemctl stop x-ui 2>/dev/null || rc-service x-ui stop 2>/dev/null - # issue the certificate - ~/.acme.sh/acme.sh --set-default-ca --server letsencrypt --force - ~/.acme.sh/acme.sh --issue -d ${domain} --listen-v6 --standalone --httpport ${WebPort} --force - if [ $? -ne 0 ]; then - echo -e "${red}Issuing certificate failed, please check logs.${plain}" - rm -rf ~/.acme.sh/${domain} - systemctl start x-ui 2>/dev/null || rc-service x-ui start 2>/dev/null - return 1 + if [[ ${cert_exists} -eq 0 ]]; then + # issue the certificate + ~/.acme.sh/acme.sh --set-default-ca --server letsencrypt --force + ~/.acme.sh/acme.sh --issue -d ${domain} --listen-v6 --standalone --httpport ${WebPort} --force + if [ $? -ne 0 ]; then + echo -e "${red}Issuing certificate failed, please check logs.${plain}" + rm -rf ~/.acme.sh/${domain} + systemctl start x-ui 2>/dev/null || rc-service x-ui start 2>/dev/null + return 1 + else + echo -e "${green}Issuing certificate succeeded, installing certificates...${plain}" + fi else - echo -e "${green}Issuing certificate succeeded, installing certificates...${plain}" + echo -e "${green}Using existing certificate, installing certificates...${plain}" fi # Setup reload command @@ -453,17 +457,18 @@ ssl_cert_issue() { fi # install the certificate + # acme.sh may exit non-zero when reloadcmd fails even if cert files are installed. ~/.acme.sh/acme.sh --installcert -d ${domain} \ --key-file /root/cert/${domain}/privkey.pem \ - --fullchain-file /root/cert/${domain}/fullchain.pem --reloadcmd "${reloadCmd}" + --fullchain-file /root/cert/${domain}/fullchain.pem --reloadcmd "${reloadCmd}" 2>&1 || true - if [ $? -ne 0 ]; then + if [[ -f "/root/cert/${domain}/privkey.pem" && -f "/root/cert/${domain}/fullchain.pem" ]]; then + echo -e "${green}Installing certificate succeeded, enabling auto renew...${plain}" + else echo -e "${red}Installing certificate failed, exiting.${plain}" rm -rf ~/.acme.sh/${domain} systemctl start x-ui 2>/dev/null || rc-service x-ui start 2>/dev/null return 1 - else - echo -e "${green}Installing certificate succeeded, enabling auto renew...${plain}" fi # enable auto-renew @@ -536,14 +541,21 @@ prompt_and_setup_ssl() { 1) # User chose Let's Encrypt domain option echo -e "${green}Using Let's Encrypt for domain certificate...${plain}" - ssl_cert_issue - # Extract the domain that was used from the certificate - local cert_domain=$(~/.acme.sh/acme.sh --list 2>/dev/null | tail -1 | awk '{print $1}') - if [[ -n "${cert_domain}" ]]; then - SSL_HOST="${cert_domain}" - echo -e "${green}✓ SSL certificate configured successfully with domain: ${cert_domain}${plain}" + if ssl_cert_issue; then + local cert_domain="${SSL_ISSUED_DOMAIN}" + if [[ -z "${cert_domain}" ]]; then + cert_domain=$(~/.acme.sh/acme.sh --list 2>/dev/null | tail -1 | awk '{print $1}') + fi + + if [[ -n "${cert_domain}" ]]; then + SSL_HOST="${cert_domain}" + echo -e "${green}✓ SSL certificate configured successfully with domain: ${cert_domain}${plain}" + else + echo -e "${yellow}SSL setup may have completed, but domain extraction failed${plain}" + SSL_HOST="${server_ip}" + fi else - echo -e "${yellow}SSL setup may have completed, but domain extraction failed${plain}" + echo -e "${red}SSL certificate setup failed for domain mode.${plain}" SSL_HOST="${server_ip}" fi ;; diff --git a/update.sh b/update.sh index b9cb3ddc..ec0c4c26 100755 --- a/update.sh +++ b/update.sh @@ -109,29 +109,29 @@ install_base() { echo -e "${green}Updating and install dependency packages...${plain}" case "${release}" in ubuntu | debian | armbian) - apt-get update >/dev/null 2>&1 && apt-get install -y -q curl tar tzdata socat openssl >/dev/null 2>&1 + apt-get update >/dev/null 2>&1 && apt-get install -y -q cron curl tar tzdata socat openssl >/dev/null 2>&1 ;; fedora | amzn | virtuozzo | rhel | almalinux | rocky | ol) - dnf -y update >/dev/null 2>&1 && dnf install -y -q curl tar tzdata socat openssl >/dev/null 2>&1 + dnf -y update >/dev/null 2>&1 && dnf install -y -q cronie curl tar tzdata socat openssl >/dev/null 2>&1 ;; centos) if [[ "${VERSION_ID}" =~ ^7 ]]; then - yum -y update >/dev/null 2>&1 && yum install -y -q curl tar tzdata socat openssl >/dev/null 2>&1 + yum -y update >/dev/null 2>&1 && yum install -y -q cronie curl tar tzdata socat openssl >/dev/null 2>&1 else - dnf -y update >/dev/null 2>&1 && dnf install -y -q curl tar tzdata socat openssl >/dev/null 2>&1 + dnf -y update >/dev/null 2>&1 && dnf install -y -q cronie curl tar tzdata socat openssl >/dev/null 2>&1 fi ;; arch | manjaro | parch) - pacman -Syu >/dev/null 2>&1 && pacman -Syu --noconfirm curl tar tzdata socat openssl >/dev/null 2>&1 + pacman -Syu >/dev/null 2>&1 && pacman -Syu --noconfirm cronie curl tar tzdata socat openssl >/dev/null 2>&1 ;; opensuse-tumbleweed | opensuse-leap) - zypper refresh >/dev/null 2>&1 && zypper -q install -y curl tar timezone socat openssl >/dev/null 2>&1 + zypper refresh >/dev/null 2>&1 && zypper -q install -y cron curl tar timezone socat openssl >/dev/null 2>&1 ;; alpine) - apk update >/dev/null 2>&1 && apk add curl tar tzdata socat openssl>/dev/null 2>&1 + apk update >/dev/null 2>&1 && apk add dcron curl tar tzdata socat openssl>/dev/null 2>&1 ;; *) - apt-get update >/dev/null 2>&1 && apt install -y -q curl tar tzdata socat openssl >/dev/null 2>&1 + apt-get update >/dev/null 2>&1 && apt install -y -q cron curl tar tzdata socat openssl >/dev/null 2>&1 ;; esac } @@ -402,15 +402,15 @@ ssl_cert_issue() { break done echo -e "${green}Your domain is: ${domain}, checking it...${plain}" + SSL_ISSUED_DOMAIN="${domain}" - # 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) - echo -e "${red}System already has certificates for this domain. Cannot issue again.${plain}" - echo -e "${yellow}Current certificate details:${plain}" - echo "$certInfo" - return 1 + # detect existing certificate and reuse it if present + local cert_exists=0 + if ~/.acme.sh/acme.sh --list 2>/dev/null | awk '{print $1}' | grep -Fxq "${domain}"; then + cert_exists=1 + local certInfo=$(~/.acme.sh/acme.sh --list 2>/dev/null | grep -F "${domain}") + echo -e "${yellow}Existing certificate found for ${domain}, will reuse it.${plain}" + [[ -n "${certInfo}" ]] && echo "$certInfo" else echo -e "${green}Your domain is ready for issuing certificates now...${plain}" fi @@ -437,16 +437,20 @@ ssl_cert_issue() { echo -e "${yellow}Stopping panel temporarily...${plain}" systemctl stop x-ui 2>/dev/null || rc-service x-ui stop 2>/dev/null - # issue the certificate - ~/.acme.sh/acme.sh --set-default-ca --server letsencrypt --force - ~/.acme.sh/acme.sh --issue -d ${domain} --listen-v6 --standalone --httpport ${WebPort} --force - if [ $? -ne 0 ]; then - echo -e "${red}Issuing certificate failed, please check logs.${plain}" - rm -rf ~/.acme.sh/${domain} - systemctl start x-ui 2>/dev/null || rc-service x-ui start 2>/dev/null - return 1 + if [[ ${cert_exists} -eq 0 ]]; then + # issue the certificate + ~/.acme.sh/acme.sh --set-default-ca --server letsencrypt --force + ~/.acme.sh/acme.sh --issue -d ${domain} --listen-v6 --standalone --httpport ${WebPort} --force + if [ $? -ne 0 ]; then + echo -e "${red}Issuing certificate failed, please check logs.${plain}" + rm -rf ~/.acme.sh/${domain} + systemctl start x-ui 2>/dev/null || rc-service x-ui start 2>/dev/null + return 1 + else + echo -e "${green}Issuing certificate succeeded, installing certificates...${plain}" + fi else - echo -e "${green}Issuing certificate succeeded, installing certificates...${plain}" + echo -e "${green}Using existing certificate, installing certificates...${plain}" fi # Setup reload command @@ -476,17 +480,18 @@ ssl_cert_issue() { fi # install the certificate + # acme.sh may exit non-zero when reloadcmd fails even if cert files are installed. ~/.acme.sh/acme.sh --installcert -d ${domain} \ --key-file /root/cert/${domain}/privkey.pem \ - --fullchain-file /root/cert/${domain}/fullchain.pem --reloadcmd "${reloadCmd}" + --fullchain-file /root/cert/${domain}/fullchain.pem --reloadcmd "${reloadCmd}" 2>&1 || true - if [ $? -ne 0 ]; then + if [[ -f "/root/cert/${domain}/privkey.pem" && -f "/root/cert/${domain}/fullchain.pem" ]]; then + echo -e "${green}Installing certificate succeeded, enabling auto renew...${plain}" + else echo -e "${red}Installing certificate failed, exiting.${plain}" rm -rf ~/.acme.sh/${domain} systemctl start x-ui 2>/dev/null || rc-service x-ui start 2>/dev/null return 1 - else - echo -e "${green}Installing certificate succeeded, enabling auto renew...${plain}" fi # enable auto-renew @@ -556,14 +561,21 @@ prompt_and_setup_ssl() { 1) # User chose Let's Encrypt domain option echo -e "${green}Using Let's Encrypt for domain certificate...${plain}" - ssl_cert_issue - # Extract the domain that was used from the certificate - local cert_domain=$(~/.acme.sh/acme.sh --list 2>/dev/null | tail -1 | awk '{print $1}') - if [[ -n "${cert_domain}" ]]; then - SSL_HOST="${cert_domain}" - echo -e "${green}✓ SSL certificate configured successfully with domain: ${cert_domain}${plain}" + if ssl_cert_issue; then + local cert_domain="${SSL_ISSUED_DOMAIN}" + if [[ -z "${cert_domain}" ]]; then + cert_domain=$(~/.acme.sh/acme.sh --list 2>/dev/null | tail -1 | awk '{print $1}') + fi + + if [[ -n "${cert_domain}" ]]; then + SSL_HOST="${cert_domain}" + echo -e "${green}✓ SSL certificate configured successfully with domain: ${cert_domain}${plain}" + else + echo -e "${yellow}SSL setup may have completed, but domain extraction failed${plain}" + SSL_HOST="${server_ip}" + fi else - echo -e "${yellow}SSL setup may have completed, but domain extraction failed${plain}" + echo -e "${red}SSL certificate setup failed for domain mode.${plain}" SSL_HOST="${server_ip}" fi ;; diff --git a/x-ui.sh b/x-ui.sh index e26dcce2..6d980838 100644 --- a/x-ui.sh +++ b/x-ui.sh @@ -1371,14 +1371,15 @@ ssl_cert_issue() { break done LOGD "Your domain is: ${domain}, checking it..." + SSL_ISSUED_DOMAIN="${domain}" - # 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) - LOGE "System already has certificates for this domain. Cannot issue again. Current certificate details:" - LOGI "$certInfo" - exit 1 + # detect existing certificate and reuse it if present + local cert_exists=0 + if ~/.acme.sh/acme.sh --list 2>/dev/null | awk '{print $1}' | grep -Fxq "${domain}"; then + cert_exists=1 + local certInfo=$(~/.acme.sh/acme.sh --list 2>/dev/null | grep -F "${domain}") + LOGI "Existing certificate found for ${domain}, will reuse it." + [[ -n "${certInfo}" ]] && LOGI "${certInfo}" else LOGI "Your domain is ready for issuing certificates now..." fi @@ -1401,15 +1402,19 @@ ssl_cert_issue() { fi LOGI "Will use port: ${WebPort} to issue certificates. Please make sure this port is open." - # issue the certificate - ~/.acme.sh/acme.sh --set-default-ca --server letsencrypt --force - ~/.acme.sh/acme.sh --issue -d ${domain} --listen-v6 --standalone --httpport ${WebPort} --force - if [ $? -ne 0 ]; then - LOGE "Issuing certificate failed, please check logs." - rm -rf ~/.acme.sh/${domain} - exit 1 + if [[ ${cert_exists} -eq 0 ]]; then + # issue the certificate + ~/.acme.sh/acme.sh --set-default-ca --server letsencrypt --force + ~/.acme.sh/acme.sh --issue -d ${domain} --listen-v6 --standalone --httpport ${WebPort} --force + if [ $? -ne 0 ]; then + LOGE "Issuing certificate failed, please check logs." + rm -rf ~/.acme.sh/${domain} + exit 1 + else + LOGE "Issuing certificate succeeded, installing certificates..." + fi else - LOGE "Issuing certificate succeeded, installing certificates..." + LOGI "Using existing certificate, installing certificates..." fi reloadCmd="x-ui restart" @@ -1439,16 +1444,17 @@ ssl_cert_issue() { fi # install the certificate + # acme.sh may exit non-zero when reloadcmd fails even if cert files are installed. ~/.acme.sh/acme.sh --installcert -d ${domain} \ --key-file /root/cert/${domain}/privkey.pem \ - --fullchain-file /root/cert/${domain}/fullchain.pem --reloadcmd "${reloadCmd}" + --fullchain-file /root/cert/${domain}/fullchain.pem --reloadcmd "${reloadCmd}" 2>&1 || true - if [ $? -ne 0 ]; then + if [[ -f "/root/cert/${domain}/privkey.pem" && -f "/root/cert/${domain}/fullchain.pem" ]]; then + LOGI "Installing certificate succeeded, enabling auto renew..." + else LOGE "Installing certificate failed, exiting." rm -rf ~/.acme.sh/${domain} exit 1 - else - LOGI "Installing certificate succeeded, enabling auto renew..." fi # enable auto-renew