diff --git a/install.sh b/install.sh index 580a9a7..867e06b 100644 --- a/install.sh +++ b/install.sh @@ -1089,36 +1089,112 @@ configure_domain() { # SSL证书配置 ################################################################################ +# 配置acme.sh自动续期 +setup_acme_auto_renew() { + echo "" + print_step "配置SSL证书自动续期..." + + # acme.sh安装时会自动创建cron任务,这里验证并确保其正常工作 + + # 1. 检查cron服务是否运行 + if systemctl is-active --quiet cron 2>/dev/null || systemctl is-active --quiet crond 2>/dev/null; then + print_success "Cron服务运行正常" + else + print_warning "Cron服务未运行,正在启动..." + systemctl start cron 2>/dev/null || systemctl start crond 2>/dev/null || true + systemctl enable cron 2>/dev/null || systemctl enable crond 2>/dev/null || true + fi + + # 2. 检查acme.sh cron任务 + if crontab -l 2>/dev/null | grep -q "acme.sh.*--cron"; then + print_success "acme.sh自动续期任务已配置" + else + print_warning "未检测到acme.sh cron任务,正在添加..." + # acme.sh会自动安装cron,这里手动触发一次 + ~/.acme.sh/acme.sh --install-cronjob 2>/dev/null || true + fi + + # 3. 显示续期信息 + echo "" + print_info "SSL证书自动续期已配置:" + echo " - 检查频率: 每天自动检查" + echo " - 续期时机: 证书到期前30天自动续期" + echo " - 续期后操作: 自动重载Nginx" + echo "" + + # 显示下次续期时间 + if [[ -f ~/.acme.sh/${DOMAIN}/${DOMAIN}.conf ]]; then + NEXT_RENEW=$(grep "Le_NextRenewTime=" ~/.acme.sh/${DOMAIN}/${DOMAIN}.conf 2>/dev/null | cut -d'=' -f2) + if [[ -n "$NEXT_RENEW" ]]; then + RENEW_DATE=$(date -d "@${NEXT_RENEW}" "+%Y年%m月%d日 %H:%M:%S" 2>/dev/null || date -r ${NEXT_RENEW} "+%Y年%m月%d日 %H:%M:%S" 2>/dev/null || echo "未知") + print_info "预计续期时间: ${RENEW_DATE}" + fi + fi + + # 4. 测试续期命令(不实际续期,只检查) + print_info "验证续期配置..." + if ~/.acme.sh/acme.sh --list 2>/dev/null | grep -q "$DOMAIN"; then + print_success "证书续期配置验证通过" + else + print_warning "证书列表中未找到域名,续期可能需要手动配置" + fi + + echo "" +} + choose_ssl_method() { echo "" print_step "选择SSL证书部署方式" echo "" echo -e "${YELLOW}【推荐方案】${NC}" - echo -e "${GREEN}[1]${NC} Certbot (Let's Encrypt官方工具)" - echo " - 最稳定可靠,支持自动续期" + echo -e "${GREEN}[1]${NC} acme.sh + Let's Encrypt" + echo " - 纯Shell脚本,轻量级稳定" + echo " - 自动续期,无需手动操作" echo "" echo -e "${YELLOW}【备选方案】${NC}" - echo -e "${GREEN}[2]${NC} acme.sh + Let's Encrypt" - echo " - 纯Shell脚本,更轻量级" - echo -e "${GREEN}[3]${NC} acme.sh + ZeroSSL" + echo -e "${GREEN}[2]${NC} acme.sh + ZeroSSL" echo " - Let's Encrypt的免费替代品" - echo -e "${GREEN}[5]${NC} acme.sh + Buypass" + echo -e "${GREEN}[3]${NC} acme.sh + Buypass" echo " - 挪威免费CA,有效期180天" echo "" echo -e "${YELLOW}【云服务商证书】${NC}" echo -e "${GREEN}[4]${NC} 阿里云免费证书 (需提供AccessKey)" - echo -e "${GREEN}[6]${NC} 腾讯云免费证书 (需提供SecretKey)" + echo -e "${GREEN}[5]${NC} 腾讯云免费证书 (需提供SecretKey)" echo "" echo -e "${YELLOW}【其他选项】${NC}" - echo -e "${GREEN}[7]${NC} 使用已有证书 (手动上传)" - echo -e "${GREEN}[8]${NC} 暂不配置HTTPS (可后续配置)" + echo -e "${GREEN}[6]${NC} 使用已有证书 (手动上传)" + echo -e "${GREEN}[7]${NC} 暂不配置HTTPS (可后续配置)" echo "" while true; do - read -p "请输入选项 [1-8]: " ssl_choice < /dev/tty + read -p "请输入选项 [1-7]: " ssl_choice < /dev/tty case $ssl_choice in - 1|2|3|4|5|6|7|8) - SSL_METHOD=$ssl_choice + 1) + SSL_METHOD="2" # acme.sh + Let's Encrypt + break + ;; + 2) + SSL_METHOD="3" # acme.sh + ZeroSSL + break + ;; + 3) + SSL_METHOD="5" # acme.sh + Buypass + break + ;; + 4) + SSL_METHOD="4" # 阿里云 + break + ;; + 5) + SSL_METHOD="6" # 腾讯云 + break + ;; + 6) + SSL_METHOD="7" # 手动上传 + break + ;; + 7) + SSL_METHOD="8" # 不配置HTTPS break ;; *) @@ -1135,9 +1211,6 @@ deploy_ssl() { fi case $SSL_METHOD in - 1) - deploy_certbot || ssl_fallback "1" - ;; 2) deploy_acme_letsencrypt || ssl_fallback "2" ;; @@ -1174,12 +1247,6 @@ ssl_fallback() { # 动态显示可用选项(排除已失败的) local available_options=() - # 方案1: Certbot - if [[ "$failed_method" != "1" ]]; then - echo -e "${GREEN}[1]${NC} Certbot (Let's Encrypt官方工具)" - available_options+=("1") - fi - # 方案2: acme.sh + Let's Encrypt if [[ "$failed_method" != "2" ]]; then echo -e "${GREEN}[2]${NC} acme.sh + Let's Encrypt" @@ -1192,24 +1259,12 @@ ssl_fallback() { available_options+=("3") fi - # 方案4: 阿里云(注释掉,未实现) - # if [[ "$failed_method" != "4" ]]; then - # echo -e "${GREEN}[4]${NC} 阿里云免费证书" - # available_options+=("4") - # fi - # 方案5: acme.sh + Buypass if [[ "$failed_method" != "5" ]]; then echo -e "${GREEN}[5]${NC} acme.sh + Buypass" available_options+=("5") fi - # 方案6: 腾讯云(注释掉,未实现) - # if [[ "$failed_method" != "6" ]]; then - # echo -e "${GREEN}[6]${NC} 腾讯云免费证书" - # available_options+=("6") - # fi - # 方案8: 不配置HTTPS echo -e "${GREEN}[8]${NC} 暂不配置HTTPS" available_options+=("8") @@ -1228,12 +1283,6 @@ ssl_fallback() { fi case $retry_choice in - 1) - deploy_certbot && return 0 - # 如果再次失败,继续调用fallback但排除方案1 - ssl_fallback "1" - return $? - ;; 2) deploy_acme_letsencrypt && return 0 # 如果再次失败,继续调用fallback但排除方案2 @@ -1245,11 +1294,6 @@ ssl_fallback() { ssl_fallback "3" return $? ;; - 4) - deploy_aliyun_ssl && return 0 - ssl_fallback "4" - return $? - ;; 5) deploy_acme_buypass && return 0 ssl_fallback "5" @@ -1551,6 +1595,9 @@ deploy_acme_letsencrypt() { print_warning "Nginx未运行,将在后续步骤启动" fi + # 配置自动续期 + setup_acme_auto_renew + return 0 else print_error "证书安装失败" @@ -1707,6 +1754,9 @@ deploy_acme_zerossl() { print_warning "Nginx未运行,将在后续步骤启动" fi + # 配置自动续期 + setup_acme_auto_renew + return 0 else print_error "证书安装失败" @@ -1863,6 +1913,9 @@ deploy_acme_buypass() { print_warning "Nginx未运行,将在后续步骤启动" fi + # 配置自动续期 + setup_acme_auto_renew + return 0 else print_error "证书安装失败" @@ -2810,15 +2863,13 @@ print_completion() { # SSL续期提示 if [[ "$USE_DOMAIN" == "true" ]] && [[ "$SSL_METHOD" != "8" ]]; then - echo -e "${YELLOW}SSL证书:${NC}" - case $SSL_METHOD in - 1) - echo " 自动续期: 已配置Certbot自动续期" - ;; - 2|3|4) - echo " 自动续期: 已配置acme.sh自动续期" - ;; - esac + echo -e "${YELLOW}SSL证书自动续期:${NC}" + echo " - 方式: acme.sh cron任务" + echo " - 频率: 每天自动检查" + echo " - 时机: 证书到期前30天自动续期" + echo " - 检查任务: crontab -l | grep acme" + echo " - 查看证书: ~/.acme.sh/acme.sh --list" + echo " - 手动续期: ~/.acme.sh/acme.sh --renew -d $DOMAIN --force" echo "" fi