阿里云 DNS 实现 Certbot 泛域名证书全自动续期
本文最后更新于41 天前,其中的信息可能已经过时,如有错误请发送邮件到big_fw@foxmail.com

阿里云 DNS 实现 Certbot 泛域名证书全自动续期(超详细步骤)

本流程从 “零依赖” 开始,每一步附具体操作、验证方法和注意事项,确保新手也能完成配置,实现证书续期无需手动干预 DNS。

一、准备阿里云 AccessKey(核心前提,100% 必做)

1. 登录阿里云 RAM 控制台

  • 打开浏览器,访问 阿里云 RAM 控制台(需登录你的阿里云主账号)。
  • 若提示 “实名认证”,先完成实名认证(阿里云 API 调用需实名)。

2. 创建仅用于 DNS 操作的子账号(最小权限原则,安全!)

  • 左侧菜单点击 “用户管理”→“创建用户”:
    • 用户名:自定义(如 certbot-dns-user,便于识别用途)。
    • 访问方式:仅勾选 “编程访问”(取消 “控制台访问”,避免子账号登录网页)。
    • 点击 “确定”,弹出 “用户创建成功” 窗口。
  • 保存 AccessKey ID 和 AccessKey Secret:
    • 窗口中会显示 “AccessKey ID” 和 “AccessKey Secret”,立即复制到记事本(Secret 仅显示一次,丢失需重新创建)。
    • 点击 “关闭”,返回用户列表。

3. 为子账号添加 DNS 操作权限(避免超权风险)

  • 在用户列表中,找到刚创建的 certbot-dns-user,点击右侧 “添加权限”:
    • 权限策略搜索框输入 AliyunDNSFullAccess(阿里云官方 DNS 全权限策略)。
    • 勾选搜索结果中的 AliyunDNSFullAccess,点击 “确定”。
  • 验证权限:点击用户名下的 “权限管理”,确认已存在 AliyunDNSFullAccess 权限,否则后续 API 调用会失败。

二、在 A 服务器安装配置阿里云 CLI(证书申请 / 续期的机器)

1. 安装阿里云 CLI(适配 CentOS/Ubuntu 通用)

  • 登录 A 服务器(通过 SSH 工具,如 Xshell、FinalShell,确保用 root 账号)。
  • 执行安装命令(自动下载并配置环境变量):bash# 下载并安装阿里云 CLI(一行命令)
    curl -fsSL https://get.aliyuncli.com | bash
  • 等待安装完成(约 1-2 分钟,取决于服务器网速)。

2. 配置阿里云 CLI(关联刚创建的 AccessKey)

  • 执行配置命令:bashaliyun configure
  • 按提示依次输入信息(每输入一项按回车):
    • Access Key Id:粘贴第一步保存的 AccessKey ID
    • Access Key Secret:粘贴第一步保存的 AccessKey Secret
    • Default Region Id:输入阿里云地域(如 cn-hangzhoucn-beijing,选离服务器近的地域,不影响功能)。
    • Default Output Format:直接回车(默认 json 格式,无需修改)。

3. 验证 CLI 配置是否成功(关键!失败需重新配置)

  • 执行以下命令,测试能否调用阿里云 DNS 接口:bashaliyun dns DescribeDomains
  • 预期结果:返回包含你域名(如 tianyong.icu)的 JSON 数据,无 “权限不足”“InvalidAccessKeyId” 等报错。
  • 若报错:
    • 若提示 “InvalidAccessKeyId”:检查 AccessKey ID/Secret 是否输错,重新执行 aliyun configure 核对。
    • 若提示 “PermissionDenied”:检查子账号是否添加 AliyunDNSFullAccess 权限,回到第一步补充权限。

三、在 A 服务器编写阿里云 DNS 自动验证脚本(核心逻辑)

1. 创建脚本存放目录(规范文件管理,避免混乱)

  • 执行命令创建目录(后续所有证书相关脚本都放这里):bash# 创建目录(若已存在会提示,忽略即可)
    mkdir -p /opt/certbot/scripts
    # 进入目录
    cd /opt/certbot/scripts

2. 编写自动验证脚本(逐行复制,避免手敲错误)

  • 用 vim 编辑器创建脚本文件:bashvim aliyun_dns.sh
  • 按 i 键进入编辑模式,粘贴以下完整脚本(无需修改,脚本会自动适配你的域名):bash#!/bin/bash

    # 阿里云 CLI 路径(默认全局安装,无需修改,若提示找不到可改为 /usr/local/bin/aliyun)
    ALIYUN_CLI=”aliyun”

    # 临时文件:存储 TXT 记录 ID(用于后续删除记录,存放在 /tmp 目录,重启服务器会自动清理)
    RECORD_FILE=”/tmp/_acme-challenge.${CERTBOT_DOMAIN}_${CERTBOT_VALIDATION}”

    # 检查阿里云 CLI 是否安装成功(避免脚本执行到一半报错)
    if ! command -v $ALIYUN_CLI >/dev/null 2>&1; then
       echo “错误:未找到阿里云 CLI,请先执行 ‘curl -fsSL https://get.aliyuncli.com | bash’ 安装” 1>&2
       exit 1
    fi

    # 函数:提取主域名(适配多级域名,如 blog.tianyong.icu → 提取为 tianyong.icu)
    get_main_domain() {
      local DOMAIN=”$1″
       # 用 awk 分割域名,取最后两段(通用逻辑,无需修改)
       echo “$DOMAIN” | awk -F’.’ ‘NF > 2 { print $(NF-1)”.”$NF; next } { print $0 }’
    }

    # 分支1:执行“clean”参数(验证完成后,删除 TXT 记录)
    if [ “$1” = “clean” ]; then
       # 从临时文件读取之前保存的 TXT 记录 ID
       RECORD_ID=$(cat “$RECORD_FILE” 2>/dev/null)
       # 若记录 ID 存在,执行删除操作
       if [ -n “$RECORD_ID” ]; then
           $ALIYUN_CLI dns DeleteDomainRecord \
               –DomainName “$(get_main_domain “$CERTBOT_DOMAIN”)” \
               –RecordId “$RECORD_ID” \
              >/dev/null 2>&1  # 静默执行,不输出多余信息
       fi
       # 删除临时文件(避免残留)
       rm -f “$RECORD_FILE”

    # 分支2:无参数(验证前,添加 TXT 记录)
    else
       # 提取主域名(如 tianyong.icu)
       MAIN_DOMAIN=$(get_main_domain “$CERTBOT_DOMAIN”)
       # 调用阿里云 API 添加 TXT 记录,并提取返回的 RecordId(用于后续删除)
       RECORD_ID=$($ALIYUN_CLI dns AddDomainRecord \
          –DomainName “$MAIN_DOMAIN” \ # 主域名
           –RR “_acme-challenge” \       # 主机记录(固定为 _acme-challenge,Let’s Encrypt 要求)
           –Type “TXT” \                 # 记录类型(固定为 TXT)
           –Value “$CERTBOT_VALIDATION” \# 记录值(Certbot 自动生成的验证字符串)
           –TTL 600 \                    # 生效时间(600秒=10分钟,阿里云最小支持600)
          | grep “RecordId” \            # 过滤返回结果中的 RecordId 字段
          | grep -Eo “[0-9]+” \          # 提取 RecordId 的数字部分
      )
       # 将 RecordId 保存到临时文件(供后续删除用)
       echo “$RECORD_ID” > “$RECORD_FILE”
       
       # 等待 DNS 记录全球生效(关键!阿里云 DNS 同步到全球节点需要时间,太短会验证失败)
       sleep 30  # 30秒足够,若多次验证失败可改为 60
    fi
  • Esc 键退出编辑模式,输入 :wq 并回车(保存并退出 vim)。

3. 给脚本添加执行权限(否则 Certbot 无法调用)

  • 执行命令:bashchmod +x /opt/certbot/scripts/aliyun_dns.sh
  • 验证权限:执行 ls -l aliyun_dns.sh,确保权限显示为 -rwxr-xr-x(开头有 x,表示可执行)。

四、修改 Certbot 配置(让续期调用自动脚本)

场景 1:尚未申请证书(首次申请,直接用自动脚本)

  • 执行以下命令申请泛域名证书(替换 your-email@example.com 为你的邮箱,用于证书过期提醒):bashcertbot certonly –manual \
    –preferred-challenges=dns \ # 强制使用 DNS-01 验证(泛域名必需)
    –email your-email@example.com \ # 替换为你的邮箱(如 123456@qq.com)
    –server https://acme-v02.api.letsencrypt.org/directory \ # Let’s Encrypt 泛域名证书服务器
    –domain tianyong.icu \ # 主域名
    –domain “*.tianyong.icu” \ # 泛域名(覆盖所有子域名)
    –manual-auth-hook “/opt/certbot/scripts/aliyun_dns.sh” \ # 验证前调用添加 TXT 脚本
    –manual-cleanup-hook “/opt/certbot/scripts/aliyun_dns.sh clean” \ # 验证后调用删除 TXT 脚本
    –config-dir /opt/certbot/config \ # 证书配置文件存放目录(之前创建的)
    –work-dir /opt/certbot/work \ # Certbot 工作目录
    –logs-dir /opt/certbot/logs # 日志目录(后续排查问题用)
  • 执行过程中需确认两次:
    1. 提示 “是否同意 Let’s Encrypt 的服务条款”:输入 A 并回车(同意)。
    2. 提示 “是否共享邮箱用于推广”:输入 N 并回车(不共享)。
  • 预期结果:最后显示 “Successfully received certificate”,证书保存到 /opt/certbot/config/live/tianyong.icu/ 目录。

场景 2:已申请过证书(仅需修改续期配置,无需重新申请)

  • 直接修改之前的续期脚本 renew_and_sync.sh(确保续期时调用自动验证脚本):
    1. 编辑续期脚本:bashvim /opt/certbot/renew_and_sync.sh
    2. 找到 “1. 自动续期证书” 部分,补充 –manual、–preferred-challenges=dns 等参数,完整内容如下:bash#!/bin/bash
      # 1. 自动续期(调用阿里云自动验证脚本,关键参数不能少)
      certbot renew \
      –config-dir /opt/certbot/config \ # 原目录不变
      –work-dir /opt/certbot/work \ # 原目录不变
      –logs-dir /opt/certbot/logs \ # 原目录不变
      –quiet \ # 静默执行,无多余输出(适合定时任务)
      –manual \ # 启用手动模式(才能调用自定义脚本)
      –preferred-challenges=dns \ # 强制 DNS-01 验证
      –manual-auth-hook “/opt/certbot/scripts/aliyun_dns.sh” \ # 添加 TXT 记录
      –manual-cleanup-hook “/opt/certbot/scripts/aliyun_dns.sh clean” # 删除 TXT 记录

      # 2. 同步证书到 B 服务器(原逻辑不变,无需修改)
      ssh root@B服务器IP “mkdir -p /etc/letsencrypt/live/tianyong.icu/”
      scp -r /opt/certbot/config/live/tianyong.icu/* root@B服务器IP:/etc/letsencrypt/live/tianyong.icu/

      # 3. 重启 B 服务器 Nginx(原逻辑不变,无需修改)
      ssh root@B服务器IP “docker restart nginx-tianyong || systemctl restart nginx”
    3. 保存退出:按 Esc,输入 :wq 回车。

场景 3:修改定时任务(若之前直接用 Crontab 续期,未用脚本)

  • 编辑 Crontab 定时任务:bashcrontab -e
  • 找到原续期任务行,补充 –manual、–manual-auth-hook 等参数,完整内容如下(替换 B服务器IP 为实际地址):bash# 每 10 天凌晨 3 点执行续期(时间不变,补充验证参数)
    0 3 */10 * * certbot renew \
    –config-dir /opt/certbot/config \
    –work-dir /opt/certbot/work \
    –logs-dir /opt/certbot/logs \
    –quiet \
    –manual \
    –preferred-challenges=dns \
    –manual-auth-hook “/opt/certbot/scripts/aliyun_dns.sh” \
    –manual-cleanup-hook “/opt/certbot/scripts/aliyun_dns.sh clean” \
    –deploy-hook “/opt/certbot/scripts/renew_and_reload_nginx.sh” \ # 原部署钩子不变
    >> /var/log/certbot-renew.log 2>&1 # 日志输出不变
  • 保存退出:按 Esc,输入 :wq 回车(Crontab 会自动生效,无需重启服务)。

五、测试自动续期(关键!确保后续续期不失败)

1. 执行模拟续期(–dry-run 模式,不实际更新证书)

  • 执行以下命令(和续期命令一致,仅多 –dry-run 参数):bashcertbot renew \
    –config-dir /opt/certbot/config \
    –work-dir /opt/certbot/work \
    –logs-dir /opt/certbot/logs \
    –dry-run \ # 模拟续期,不修改实际证书
    –manual \
    –preferred-challenges=dns \
    –manual-auth-hook “/opt/certbot/scripts/aliyun_dns.sh” \
    –manual-cleanup-hook “/opt/certbot/scripts/aliyun_dns.sh clean”

2. 观察执行过程(确认脚本自动调用)

  • 正常流程会显示:
    1. Running manual-auth-hook:调用脚本添加 TXT 记录。
    2. Waiting for verification:等待 DNS 生效(脚本中 sleep 30 的时间)。
    3. Running manual-cleanup-hook:调用脚本删除 TXT 记录。
    4. 最后显示 The dry run was successful(模拟续期成功)。

3. 验证 DNS 记录自动添加 / 删除(眼见为实)

  • 打开阿里云 DNS 控制台(https://dns.console.aliyun.com/),找到tianyong.icu 域名:
    1. 在脚本执行到 Waiting for verification 时(约 30 秒内),刷新页面,会看到 _acme-challenge 的 TXT 记录(存在时间约 30 秒)。
    2. 等待脚本执行到 Running manual-cleanup-hook 后,再次刷新页面,_acme-challenge 记录消失(自动删除成功)。

4. 若测试失败,按以下步骤排查

报错信息可能原因解决方法
manual-auth-hook script exited with error code 1脚本无执行权限重新执行 chmod +x /opt/certbot/scripts/aliyun_dns.sh
AddDomainRecord failed: PermissionDeniedAccessKey 权限不足回到第一步,确认子账号已添加 AliyunDNSFullAccess 权限
DNS problem: NXDOMAIN looking up TXT for _acme-challenge.tianyong.icuDNS 生效时间不足修改脚本中 sleep 30sleep 60,重新测试
aliyun: command not foundCLI 未安装或环境变量未加载重新执行 curl -fsSL [https://get.aliyuncli.com](https://get.aliyuncli.com/) | bash,并退出 SSH 重新登录

六、最终确认(确保全自动续期生效)

  1. 检查证书目录:执行 ls /opt/certbot/config/live/tianyong.icu/,确认有 fullchain.pem(证书链)和 privkey.pem(私钥)。
  2. 检查定时任务:执行 crontab -l,确认续期任务包含 `–manual-auth-h
文末附加内容
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇