From f8c9aac97cfe4bb38c4dad4b1bc5f9bb18a7ec68 Mon Sep 17 00:00:00 2001 From: MHSanaei Date: Sun, 11 Jan 2026 15:28:43 +0100 Subject: Add port selection and checks for ACME HTTP-01 listener Introduces user prompts to select the port for ACME HTTP-01 certificate validation (default 80), checks if the chosen port is available, and provides guidance for port forwarding. Adds is_port_in_use helper to all scripts and improves messaging for certificate issuance and error handling. --- update.sh | 60 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 57 insertions(+), 3 deletions(-) (limited to 'update.sh') diff --git a/update.sh b/update.sh index 9f69f053..800841f5 100755 --- a/update.sh +++ b/update.sh @@ -81,6 +81,23 @@ is_domain() { [[ "$1" =~ ^([A-Za-z0-9](-*[A-Za-z0-9])*\.)+[A-Za-z]{2,}$ ]] && return 0 || return 1 } +# Port helpers +is_port_in_use() { + local port="$1" + if command -v ss >/dev/null 2>&1; then + ss -ltn 2>/dev/null | awk -v p=":${port}$" '$4 ~ p {exit 0} END {exit 1}' + return + fi + if command -v netstat >/dev/null 2>&1; then + netstat -lnt 2>/dev/null | awk -v p=":${port} " '$4 ~ p {exit 0} END {exit 1}' + return + fi + if command -v lsof >/dev/null 2>&1; then + lsof -nP -iTCP:${port} -sTCP:LISTEN >/dev/null 2>&1 && return 0 + fi + return 1 +} + gen_random_string() { local length="$1" local random_string=$(LC_ALL=C tr -dc 'a-zA-Z0-9' /dev/null; then @@ -241,6 +258,43 @@ setup_ip_certificate() { # Set reload command for auto-renewal (add || true so it doesn't fail if service stopped) local reloadCmd="systemctl restart x-ui 2>/dev/null || rc-service x-ui restart 2>/dev/null || true" + # Choose port for HTTP-01 listener (default 80, prompt override) + local WebPort="" + read -rp "Port to use for ACME HTTP-01 listener (default 80): " WebPort + WebPort="${WebPort:-80}" + if ! [[ "${WebPort}" =~ ^[0-9]+$ ]] || ((WebPort < 1 || WebPort > 65535)); then + echo -e "${red}Invalid port provided. Falling back to 80.${plain}" + WebPort=80 + fi + echo -e "${green}Using port ${WebPort} for standalone validation.${plain}" + if [[ "${WebPort}" -ne 80 ]]; then + echo -e "${yellow}Reminder: Let's Encrypt still connects on port 80; forward external port 80 to ${WebPort}.${plain}" + fi + + # Ensure chosen port is available + while true; do + if is_port_in_use "${WebPort}"; then + echo -e "${yellow}Port ${WebPort} is currently in use.${plain}" + + local alt_port="" + read -rp "Enter another port for acme.sh standalone listener (leave empty to abort): " alt_port + alt_port="${alt_port// /}" + if [[ -z "${alt_port}" ]]; then + echo -e "${red}Port ${WebPort} is busy; cannot proceed.${plain}" + return 1 + fi + if ! [[ "${alt_port}" =~ ^[0-9]+$ ]] || ((alt_port < 1 || alt_port > 65535)); then + echo -e "${red}Invalid port provided.${plain}" + return 1 + fi + WebPort="${alt_port}" + continue + else + echo -e "${green}Port ${WebPort} is free and ready for standalone validation.${plain}" + break + fi + done + # Issue certificate with shortlived profile echo -e "${green}Issuing IP certificate for ${ipv4}...${plain}" ~/.acme.sh/acme.sh --set-default-ca --server letsencrypt >/dev/null 2>&1 @@ -251,12 +305,12 @@ setup_ip_certificate() { --server letsencrypt \ --certificate-profile shortlived \ --days 6 \ - --httpport 80 \ + --httpport ${WebPort} \ --force if [ $? -ne 0 ]; then echo -e "${red}Failed to issue IP certificate${plain}" - echo -e "${yellow}Please ensure port 80 is open and accessible from the internet${plain}" + echo -e "${yellow}Please ensure port ${WebPort} is reachable (or forwarded from external port 80)${plain}" # Cleanup acme.sh data for both IPv4 and IPv6 if specified rm -rf ~/.acme.sh/${ipv4} 2>/dev/null [[ -n "$ipv6" ]] && rm -rf ~/.acme.sh/${ipv6} 2>/dev/null -- cgit v1.2.3