From d5fada3a262989063dc19871106f1197697e7122 Mon Sep 17 00:00:00 2001 From: WanWanYun Date: Thu, 13 Nov 2025 15:24:08 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E7=A7=BB=E9=99=A4Certbot=E6=96=B9?= =?UTF-8?q?=E6=A1=88=EF=BC=8C=E7=BB=9F=E4=B8=80=E4=BD=BF=E7=94=A8acme.sh?= =?UTF-8?q?=20+=20=E6=B7=BB=E5=8A=A0=E8=87=AA=E5=8A=A8=E7=BB=AD=E6=9C=9F?= =?UTF-8?q?=E9=85=8D=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 核心改进: 1. 移除Certbot (方案1) - 原因:Python依赖冲突(urllib3)难以解决 - 用户已用acme.sh成功申请证书 - acme.sh更轻量、更可靠 2. 优化SSL方案选择菜单 - 新方案1:acme.sh + Let's Encrypt (推荐) - 新方案2:acme.sh + ZeroSSL - 新方案3:acme.sh + Buypass - 新方案4-5:阿里云/腾讯云 - 新方案6-7:手动上传/暂不配置 3. 添加自动续期配置功能 - 新增setup_acme_auto_renew()函数 - 自动检查并启动cron服务 - 验证acme.sh自动续期任务 - 显示续期时间和配置信息 - 提供续期检查命令 4. 自动续期特性: - ✅ 每天自动检查证书 - ✅ 证书到期前30天自动续期 - ✅ 续期后自动重载Nginx - ✅ 无需手动干预 5. 用户体验改进: - 显示详细的续期配置信息 - 提供手动续期命令 - 统一的续期管理方式 - 完成提示中显示续期检查命令 技术细节: - acme.sh安装时自动创建cron任务 - 兼容cron/crond两种服务名 - 支持systemctl和传统service管理 - 显示预计续期时间(从证书配置文件读取) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- install.sh | 157 +++++++++++++++++++++++++++++++++++------------------ 1 file changed, 104 insertions(+), 53 deletions(-) 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