🎉 恭喜你发现了宝藏!

于 ACME.sh 自动签发 CoreDNS SSL TLS 证书

文章最后更新时间:2025-12-15 13:11:14

ACME.sh 简介

​ACME 是 “Automatic Certificate Management Environment”(自动证书管理环境)的缩写,ACME 协议由 Internet 工程任务组(IETF)定义,并由 Let's Encrypt 等证书颁发机构广泛采用。ACME 是一种用于自动化管理和获取 SSL/TLS 证书的协议。ACME 提供了一种标准化的方式,使其能够自动请求、验证和获取证书,而无需人工干预。完成标准化获取证书流程需要 ACME 客户端与 ACME 服务器端进行通信。常见的 ACME 客户端有 acme.sh、certbot 等,而今天我们要介绍的正是 acme.sh。

acme.sh 是一个由 acmesh-official 在 GitHub 上维护的开源项目,拥有超过 39.4k Star。该项目的主要作用是提供一个纯 Shell 脚本实现的 ACME 协议客户端,用于自动化获取和更新 SSL/TLS 证书。支持 Windows、GNU/Linux、FreeBSD、Solaris、macOS 等操作系统。免费的 Let's Encrypt 证书,确保网站的安全性和 HTTPS 支持。

GitHub: GitHub - acmesh-official/acme.sh: A pure Unix shell script implementing ACME client protocol
Wiki: https://github.com/acmesh-official/acme.sh/wiki
Docker: acme.sh Docker

在官方 Wiki 中包含了关于各种部署模式、证书类型和操作系统的详细文档。强烈建议您阅读官方 Wiki。

主要功能:

  1. 获取证书: 使用 ACME 协议从 Let’s Encrypt 或者其他 ACME 兼容的 CA(证书颁发机构)获取免费 SSL/TLS 证书。
  2. 自动续期: 自动更新接近过期的证书,确保网站和服务持续运行在安全的 HTTPS 协议上。
  3. 多 DNS API 支持: acme.sh 支持各种 DNS 提供商的 API,以便可以通过 DNS-01 验证为域名获取证书。

主要特点:

  1. 纯 Shell 语言编写的 ACME 协议客户端。
  2. 完整的 ACME 协议实现。
  3. 支持 ECDSA 证书。
  4. 支持 SAN 和通配符证书。
  5. 支持 Docker 部署。
  6. 支持 IPv6。
  7. 计划任务 (cron) 更新报错通知。
  8. 多操作系统支持。

支持的证书颁发机构(CA):

支持的模式:

  • Webroot 模式
  • Standalone 模式
  • Standalone tls-alpn 模式
  • Apache 模式
  • Nginx 模式
  • DNS 模式
  • DNS 别名模式
  • 无状态模式

支持的 DNS 服务提供商 API:

目前几乎支持所有主流的 DNS 服务提供商,包括:CloudFlare、DNSPod、GoDaddy、Aliyun 等,详细参考:dnsapi · acmesh-official/acme.sh Wiki · GitHub

Let's Encrypt

前面提到 Let's Encrypt,这是简单介绍一下,Let's Encrypt 是一个由互联网安全研究组织(ISRG)运营的免费、自动化、开放的证书颁发机构(CA)。它的主要目标是通过提供易用的数字证书服务来推动全网 HTTPS 加密,实现更安全的互联网。目前有超过 4.5 亿网站使用 Let's Encrypt 提供的证书服务。

主要特点:

  1. 免费: Let's Encrypt 提供的 SSL/TLS 证书是免费的,对于网站所有者来说,是一个经济实惠的选择。
  2. 自动化: 通过 ACME 协议,Let's Encrypt 实现了自动化的证书获取和续期,减少了人力操作的复杂性(证书有效期 3 个月,可以通过 ACME.sh 自动续期)。
  3. 开放: Let's Encrypt 是一个开放的服务,任何人都可以使用它来获取和续期证书。
  4. 安全: 使用 Let's Encrypt 提供的证书,有助于确保数据在传输过程中的加密,提升网站的安全性和可信度。

主要作用:

  1. 增强安全性: 通过提供 SSL/TLS 证书,确保网站与用户之间的数据传输加密,防止信息被窃取或篡改。
  2. 提升 SEO 排名: 搜索引擎(如 Google)更倾向于排名采用 HTTPS 的网站,从而提升网站的搜索引擎排名。
  3. 提高用户信任度: 使用 HTTPS 能让用户看到绿色锁图标或“安全”字样,增加对网站的信任。

运作方式:

  1. ACME 协议: Let's Encrypt 使用 ACME(Automatic Certificate Management Environment)协议来自动管理证书的颁发和续期。用户可以使用 ACME 客户端(如 acme.sh、Certbot)与 Let's Encrypt 服务器通信以完成证书的获取和管理。
  2. 域名验证: 在颁发证书之前,Let's Encrypt 需要验证用户对特定域名的所有权。通常有以下两种验证方式:
  • HTTP-01 验证: 通过在服务器上放置一个特殊的文件来证明对域名的控制权。
  • DNS-01 验证: 通过在域名的 DNS 记录中添加一个特定的 TXT 记录来验证。

通过提供免费、自动化的证书管理服务,Let's Encrypt 大大降低了网站使用 HTTPS 的门槛,促进了整个互联网的安全性提升。

ACME.sh 验证方式

在使用 acme.sh 获取 SSL/TLS 证书的过程中,验证域名所有权是一个关键步骤。acme.sh 支持两种主要的验证方式:HTTP 验证(HTTP-01) 和 DNS 验证(DNS-01) 。这两种方式各有优缺点,适用于不同的场景。

HTTP 验证(HTTP-01):

  • 工作机制: 通过在域名 Web 服务下的指定路径放置一个验证文件,证书颁发机构(CA)通过 HTTP 请求访问这个文件来验证域名所有权。
  • 适用场景: 适用于可以方便地在 web 服务器上放置验证文件的情况。常用于简易部署的单网站或虚拟主机环境。

DNS 验证(DNS-01):

  • 工作机制: 通过在域名的 DNS 记录中添加一个特定的 TXT 记录,CA 通过查询该 TXT 记录来验证域名所有权。
  • 适用场景: 适用于难以通过 HTTP 方法验证、或者需要为动态 DNS 环境、子域名、大量域名等情况获取证书的情况。

实现方式的区别:

  1. 配置复杂度:
  • HTTP-01: 通常较为简单,只需要访问 web 服务器和设置目录权限即可。
  • DNS-01: 可能较为复杂,需要手动在 DNS 提供商的管理界面添加 TXT 记录,或者使用其 API 自动添加 TXT 记录。
  1. 适用环境:
  • HTTP-01: 适用于在运行 web 服务器且可以控制网站根目录的情景。
  • DNS-01: 更加通用,适用于无法通过 HTTP 方式验证的情况,比如泛域名证书(例如:*.example.com),以及在 CDN 或代理服务器前的场景。
  1. 验证的简易性与安全性:
  • HTTP-01: 直接在 web 服务器上操作,较为直观,但有时可能面临代理、负载均衡等的配置挑战。
  • DNS-01: 可以避免许多网络层面的复杂问题,但依赖于 DNS 提供商的 API 和配置,初次设置时可能更为困难。

选择哪种验证方式取决于具体的使用场景和可操作的环境,acme.sh 通过简洁的命令和插件机制,使得这两种验证方式的使用都相对简单和易于管理。

证书类型

数字证书有多种类型,以下为多种常见的类型:

  1. DSA 证书(Digital Signature Algorithm)
  2. ECC 证书(Elliptic Curve Cryptography,椭圆曲线密码学)
  3. RSA 证书(Rivest–Shamir–Adleman)
  4. ED25519 证书

这些证书类型的主要区别在于它们使用的加密算法:

  1. RSA 证书
  • 基于 RSA 加密算法,广泛使用在 SSL/TLS 证书中。
  • 使用公开密钥加密算法,通常需要较大密钥长度(2048 位或以上),以确保安全性。
  • 在性能上,RSA 通常需要更多的计算资源,特别是在高负载应用中,其速度较慢。
  1. ECC 证书
  • 使用椭圆曲线密码学 (Elliptic Curve Cryptography) 算法。
  • 与 RSA 相比,可以在提供同等安全级别的情况下使用一个更小的密钥长度(Let's Encrypt 默认为 256 位),从而提高性能和效率。
  • 由于计算复杂度低,在资源有限的环境中非常适合,特别是在移动设备上表现优秀。
  1. DSA 证书
  • 基于数字签名算法 (Digital Signature Algorithm)。
  • 通常用于数字签名而不是加密,特点是速度快,特别是在签名生成上表现良好。
  • 目前使用较少,因为 ECC 在许多情况下表现更好。
  1. ED25519 证书
  • 使用 Edwards-curve Digital Signature Algorithm (EdDSA),具体为 Ed25519 曲线。
  • 提供极高的速度和安全性,适合需要高速签名处理的场景。
  • 尤其适用于高性能敏感应用,如:SSH 公钥认证。

总体来说:

  • 安全性:ECC 和 RSA 都能提供高安全级别,但基于 ECC 的证书可以使用更小的密钥实现相同的安全级别。
  • 性能:ECC 在性能上通常比 RSA 更高效,适用于需要大量加密、解密操作的场景。
  • 应用场景:RSA 仍然是最流行和广泛使用的加密算法尤其是在 HTTPS/SSL/TLS 证书上,而 ECC 因其高效率近年来得到更多关注,特别是在资源受限或需要高性能的设备上。

[admonition title="注意" icon="info-circle" color="indigo"]很多旧系统、浏览器对于 ECC 证书的支持并不好,具体参考:letsencrypt.org/docs/ce,Let's Encrypt 默认签发 ECC 证书。
[/admonition]

不同类型的证书各有优劣,选择合适的证书类型应依据具体应用场景的需求和优先级来决定。

[admonition title="思考" icon="question-circle" color="green"]具体怎样验证证书是哪种类型了? [/admonition]

[root@coredns-001 ~]# openssl x509 -in /etc/coredns/certs/fullchain.pem  -text -noout | grep -E "Key|ASN1"
        Subject Public Key Info:
            Public Key Algorithm: id-ecPublicKey # ECC 证书
                Public-Key: (256 bit) # 公开密钥加密算法密钥长度为 256 位
                ASN1 OID: prime256v1 # 指明使用的具体椭圆曲线


[root@coredns-001 ~]# openssl x509 -in /etc/coredns/certs/fullchain.pem  -text -noout | grep Key
  Subject Public Key Info:
      Public Key Algorithm: rsaEncryption # RSA 证书
      RSA Public-Key: (2048 bit) # 公开密钥加密算法密钥长度为 2048 位
  • RSA 证书 :如果看到 Public Key Algorithm: rsaEncryption,表示该证书使用的是 RSA 加密算法。RSA Public-Key: (2048 bit) 表示公开密钥加密算法密钥长度为 2048 位。
  • ECC 证书 :如果看到 Public Key Algorithm: id-ecPublicKey,表示该证书使用的是 ECC 加密算法。Public-Key: (256 bit) 表示公开密钥加密算法密钥长度为 256 位。

如下图所示 http://rockylinux.cn 采用的是 RSA 证书,公开密钥加密算法密钥长度为 4096 位。

图片[1] - 于 ACME.sh 自动签发 CoreDNS SSL TLS 证书 - 诺守博客
图片[2] - 于 ACME.sh 自动签发 CoreDNS SSL TLS 证书 - 诺守博客

ACME.sh 申请 CoreDNS 证书

前面介绍了 ACME.sh 验证证书所有权的方式有两种,因为 CoreDNS 本身不提供 HTTP 服务,所以选择 DNS-01 验证方式,来进行 CoreDNS 证书申请。

安装 ACME.sh

acme.sh 官方提供了多种安装方式,包括:curl 自动安装、git clone 安装、高级安装等,具体安装文档参考:How to install · acmesh-official/acme.sh Wiki · GitHub

curl 自动安装

如果您使用 curl 自动安装,将执行以下 3 个操作:

  1. 创建并复制 acme.sh 目录至您的主目录 ($HOME): ~/.acme.sh/。所有证书、帐号、配置文件都存放在此目录中。
  2. 在 ~/.bashrc~/.cshrc 或 ~/.tcshrc 添加别名 . "/root/.acme.sh/acme.sh.env"
  3. 在计划任务中创建每日 cron 作业来检查并更新证书。
# 安装 acme.sh,邮箱替换成自己邮箱,用于接收 SSL/TLS 证书续期通知
[root@coredns-001 ~]# curl https://get.acme.sh | sh -s email=muzi@vip.rockylinux.cn

# 查看安装目录信息
[root@coredns-001 ~]# ls -la ~/.acme.sh/
total 264
drwx------  7 root root    187 Nov 15 21:43 .
dr-xr-x---. 4 root root   4096 Nov 18 23:28 ..
-rw-r--r--  1 root root    440 Nov 18 21:43 account.conf
-rwxr-xr-x  1 root root 226255 Nov 15 21:43 acme.sh
-rw-r--r--  1 root root     78 Oct 12 15:33 acme.sh.csh
-rw-r--r--  1 root root     78 Oct 12 15:33 acme.sh.env
drwxr-xr-x  3 root root     42 Oct 12 16:16 ca
drwxr-xr-x  2 root root   4096 Nov 15 21:43 deploy
drwxr-xr-x  2 root root   8192 Nov 15 21:43 dnsapi
-rw-r--r--  1 root root   1304 Nov 18 21:43 http.header
drwxr-xr-x  2 root root   4096 Nov 15 21:43 notify

# 加载 /etc/acme/acme.sh.env 文件(命令别名)
[root@coredns-001 ~]# tail -n 1 ~/.bashrc
. "/root/.acme.sh/acme.sh.env"

# 对应文件内容如下
[root@coredns-001 ~]# cat /root/.acme.sh/acme.sh.env
export LE_WORKING_DIR="/root/.acme.sh"
alias acme.sh="/root/.acme.sh/acme.sh"

# 计划任务
[root@coredns-001 ~]# crontab -l
59 20 * * * "/root/.acme.sh"/acme.sh --cron --home "/root/.acme.sh" > /dev/null

# 重新加载 ~/.bashrc 文件
[root@coredns-001 ~]# source ~/.bashrc

# 验证是否安装成功
[root@coredns-001 ~]# acme.sh -v
https://github.com/acmesh-official/acme.sh
v3.1.0

# 如果是采用 Cloudflare Global API Key,通过 export 导入环境变量,申请一次证书成功以后,会自动将 CF_Key、CF_Email 保存至 account.conf 文件
[root@coredns-001 ~]# cat /root/.acme.sh/account.conf 
#LOG_FILE="/root/.acme.sh/acme.sh.log"
#LOG_LEVEL=1
AUTO_UPGRADE='1'
#NO_TIMESTAMP=1
ACCOUNT_EMAIL='muzi@vip.rockylinux.cn'
UPGRADE_HASH='35xxx6c'
DEFAULT_ACME_SERVER='https://acme-v02.api.letsencrypt.org/directory'
SAVED_CF_Key='35xxx6e'
SAVED_CF_Email='muzi@vip.rockylinux.cn'
USER_PATH='/root/.local/bin:/root/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin'

高级安装

# 克隆 acme.sh 仓库
[root@coredns-001 ~]# git clone --depth 1 https://github.com/acmesh-official/acme.sh.git

# 进入目录
[root@coredns-001 ~]# cd acme.sh

# 安装 acme.sh
[root@coredns-001 ~]# ./acme.sh --install  \
--home /etc/acme \
--config-home /etc/acme/data \
--cert-home /etc/acme/certs \
--accountemail  "muzi@vip.rockylinux.cn" \
--accountkey  /etc/acme/account.key \
--accountconf /etc/acme/account.conf \
--useragent  "Rocky Linux 9 CoreDNS Client"

[Sun Nov 10 18:02:34 CST 2024] It is recommended to install socat first.
[Sun Nov 10 18:02:34 CST 2024] We use socat for the standalone server, which is used for standalone mode.
[Sun Nov 10 18:02:34 CST 2024] If you dont want to use standalone mode, you may ignore this warning.
[Sun Nov 10 18:02:34 CST 2024] Installing to /etc/acme
[Sun Nov 10 18:02:34 CST 2024] Installed to /etc/acme/acme.sh
[Sun Nov 10 18:02:34 CST 2024] Installing alias to '/root/.bashrc' # 提示已经将 acme.sh 别名至 /root/.bashrc 文件夹
[Sun Nov 10 18:02:34 CST 2024] Close and reopen your terminal to start using acme.sh
[Sun Nov 10 18:02:34 CST 2024] Installing alias to '/root/.cshrc'
[Sun Nov 10 18:02:34 CST 2024] Installing alias to '/root/.tcshrc'
[Sun Nov 10 18:48:35 CST 2024] Installing cron job # 添加计划任务成功
[Sun Nov 10 18:02:35 CST 2024] bash has been found. Changing the shebang to use bash as preferred.
[Sun Nov 10 18:02:38 CST 2024] OK

# 加载 /etc/acme/acme.sh.env 文件
[root@coredns-001 ~]# tail -n 1 ~/.bashrc 
. "/etc/acme/acme.sh.env"

# 对应文件内容如下
[root@coredns-001 ~]# cat /etc/acme/acme.sh.env
export LE_WORKING_DIR="/etc/acme"
export LE_CONFIG_HOME="/etc/acme/data"
alias acme.sh="/etc/acme/acme.sh --config-home '/etc/acme/data'"

# 重新加载并执行 ~/.bashrc 文件
[root@coredns-001 ~]# source ~/.bashrc

# 验证是否安装成功
[root@coredns-001 ~]# acme.sh -v
https://github.com/acmesh-official/acme.sh
v3.1.0

# 默认会自动设置一个计划任务,每天 0 点 35 分执行,用于证书自动续期管理
[root@coredns-001 ~]# crontab -l
35 0 * * * "/etc/acme"/acme.sh --cron --home "/etc/acme" --config-home "/etc/acme/data" > /dev/null

参数说明:

  • --home:自定义 acme.sh 安装目录。默认情况下安装在 ~/.acme.sh 目录。
  • --config-home:配置文件目录,acme.sh 会将所有文件(包括:cert、keys、configs)写入其中。默认情况下位于 --home 参数指定目录。
  • --cert-home:证书目录,用于保存您颁发的证书。默认情况下保存在 --config-home 参数指定目录。
  • --accountemail:用于注册 Let's Encrypt 账号的电子邮件,您将在这里收到续订通知邮件。
  • --accountkey:保存您帐户私钥的文件。默认情况下保存在 --config-home 参数指定目录。
  • --useragent:设置请求 Let's Encrypt 的 UA 标头。
  • --nocron:不配置 cron 计划任务,用于证书自动续期。

常用命令

获取帮助信息

[root@coredns-001 ~]# acme.sh -h
https://github.com/acmesh-official/acme.sh
v3.1.0
Usage: acme.sh <command> ... [parameters ...]
Commands:
  -h, --help               Show this help message.
  -v, --version            Show version info.
  --install                Install acme.sh to your system.
  --uninstall              Uninstall acme.sh, and uninstall the cron job.
  --upgrade                Upgrade acme.sh to the latest code from https://github.com/acmesh-official/acme.sh.
  --issue                  Issue a cert.
  --deploy                 Deploy the cert to your server.
  -i, --install-cert       Install the issued cert to Apache/nginx or any other server.
  -r, --renew              Renew a cert.
  --renew-all              Renew all the certs.
  --revoke                 Revoke a cert.
  --remove                 Remove the cert from list of certs known to acme.sh.
  --list                   List all the certs.
  --info                   Show the acme.sh configs, or the configs for a domain with [-d domain] parameter.
  --to-pkcs12              Export the certificate and key to a pfx file.
  --to-pkcs8               Convert to pkcs8 format.
  --sign-csr               Issue a cert from an existing csr.
  --show-csr               Show the content of a csr.
  -ccr, --create-csr       Create CSR, professional use.
  --create-domain-key      Create an domain private key, professional use.
  --update-account         Update account info.
  --register-account       Register account key.
  --deactivate-account     Deactivate the account.
  --create-account-key     Create an account private key, professional use.
  --install-cronjob        Install the cron job to renew certs, you dont need to call this. The 'install' command can automatically install the cron job.
  --uninstall-cronjob      Uninstall the cron job. The 'uninstall' command can do this automatically.
  --cron                   Run cron job to renew all the certs.
  --set-notify             Set the cron notification hook, level or mode.
  --deactivate             Deactivate the domain authz, professional use.
  --set-default-ca         Used with '--server', Set the default CA to use.
                           See: https://github.com/acmesh-official/acme.sh/wiki/Server
  --set-default-chain      Set the default preferred chain for a CA.
                           See: https://github.com/acmesh-official/acme.sh/wiki/Preferred-Chain

设置 acme.sh 自动更新

由于 ACME 协议和 Let's Encrypt CA 都会频繁更新,因此 acme.sh 也经常更新,所以建议开启 acme.sh 自动更新,保持最新版本。

# 启用 acme.sh 自动更新
[root@coredns-001 ~]# acme.sh --upgrade --auto-upgrade
[Wed Nov 20 14:58:12 CST 2024] Already up to date!
[Wed Nov 20 14:58:12 CST 2024] Upgrade successful!

[root@coredns-001 ~]# cat /etc/acme/account.conf  | grep AUTO_UPGRADE
AUTO_UPGRADE='1'

# 禁用 acme.sh 自动更新
[root@coredns-001 ~]# acme.sh --upgrade --auto-upgrade 0
[Wed Nov 20 14:58:29 CST 2024] Already up to date!
[Wed Nov 20 14:58:29 CST 2024] Upgrade successful!

[root@coredns-001 ~]# cat /etc/acme/account.conf  | grep AUTO_UPGRADE
AUTO_UPGRADE='0'

设置证书颁发机构 (CA)

目前 acme.sh 支持 5 个正式环境证书颁发机构 (CA),分别是:Let's EncryptBuypassZeroSSLSSL.com 和 Google Public CA,默认使用 ZeroSSL。可以使用以下命令进行切换:

# 切换 Let's Encrypt
[root@coredns-001 ~]# acme.sh --set-default-ca --server letsencrypt

# 切换 Buypass
[root@coredns-001 ~]# acme.sh --set-default-ca --server buypass

# 切换 ZeroSSL
[root@coredns-001 ~]# acme.sh --set-default-ca --server zerossl

# 切换 SSL.com
[root@coredns-001 ~]# acme.sh --set-default-ca --server ssl.com

# 切换 Google Public CA
[root@coredns-001 ~]# acme.sh --set-default-ca --server google

对应证书颁发机构 (CA) 功能对比,参考:CA · acmesh-official/acme.sh Wiki · GitHub

简单来说,如果没有特殊需求无脑选择 Let's Encrypt,如果面向欧盟用户,也可以选择 ZeroSSL 或 Buypass,如果愿意付费得到更好的服务和保障,可以选择 ZeroSSL 和 http://SSL.com

各证书颁发机构 (CA) ACME URL

每个证书颁发机构 (CA) 都有自己的 ACME URL,具体参考:Server · acmesh-official/acme.sh Wiki · GitHub

Short NameACME server URLUsage Wiki
letsencrypthttps://acme-v02.api.letsencrypt.org/directoryN/A
letsencrypt_testhttps://acme-staging-v02.api.letsencrypt.org/directoryN/A
buypasshttps://api.buypass.com/acme/directoryBuyPass.com CA
buypass_testhttps://api.test4.buypass.no/acme/directoryhttp://BuyPass.com CA
zerosslhttps://acme.zerossl.com/v2/DV90http://ZeroSSL.com CA
sslcomhttps://acme.ssl.com/sslcom-dv-rsa
https://acme.ssl.com/sslcom-dv-ecc
http://SSL.com CA
googlehttps://dv.acme-v02.api.pki.goog/directoryGoogle Public CA
googletesthttps://dv.acme-v02.test-api.pki.goog/directoryGoogle Public CA

比如:如果需要使用 letsencrypt,可以直接在申请证书的时候指定 --server,也可以参考【设置证书颁发机构 (CA)】修改默认设置。

[root@coredns-001 ~]# acme.sh  --issue --server letsencrypt

证书续期

Let’s Encrypt 的证书有效期为 3 个月,每 3 个月得重新申请一次证书。添加 cron 定时作业后,acme.sh 会在证书到期前 30 天,自动续签 SSL/TLS 证书,一般情况下无需手动续期,当然也可以强制签发证书。

# 正常签收证书
[root@coredns-001 ~]# acme.sh --renew -d example.com

# 强制签发证书
[root@coredns-001 ~]# acme.sh --renew -d example.com --force

# 强制签发 ECC 证书
[root@coredns-001 ~]# acme.sh --renew -d example.com --force --ecc

取消证书自动续期

如果您需要移除特定域名的自动续签,可以使用下面的命令让 acme.sh 取消特定域名的自动续期。当然已申请的证书仍然有效(直到有效期结束)。

[root@coredns-001 ~]# acme.sh --remove -d example.com --ecc

创建 Cloudflare API Key

因为木子的域名托管在 Cloudflare,所以这里以 Cloudflare API Key 申请为例。

登录 Cloudflare,进入 用户 API 令牌 管理页面,点击“创建令牌”。

图片[3] - 于 ACME.sh 自动签发 CoreDNS SSL TLS 证书 - 诺守博客

选择使用“编辑区域 DNS” 模板

图片[4] - 于 ACME.sh 自动签发 CoreDNS SSL TLS 证书 - 诺守博客

区域资源:实际就是这个 API 令牌可以管理哪些域名的 DNS 解析记录的编辑功能(增加 TXT 记录需要此权限)。

  • 所有区域:可以管理所有域名。
  • 账户的所有区域:指定账号可以管理所有域名。
  • 特定区域:只能管理指定域名。

客户端 IP 地址筛选:主要用于控制 IP 黑白名单,即哪些 IP 地址可以调用这个 API 接口(提高接口安全性)。

图片[5] - 于 ACME.sh 自动签发 CoreDNS SSL TLS 证书 - 诺守博客

点击“继续以显示摘要”,确认无误后,点击“创建令牌”。

图片[6] - 于 ACME.sh 自动签发 CoreDNS SSL TLS 证书 - 诺守博客

创建 API 令牌成功,API 令牌即 ACME.sh 的 CF_Token 参数值。

[admonition title="警告" icon="exclamation-triangle" color="orange"]此令牌只会显示一次,记牢对应令牌。令牌信息请妥善保存, 请勿外泄。 [/admonition]

图片[7] - 于 ACME.sh 自动签发 CoreDNS SSL TLS 证书 - 诺守博客

然后进入域名管理页面,在右侧 API 列找到 帐户 ID 和 区域 ID ,单击以复制。

  • 帐户 ID 即 ACME.sh 中 CF_Account_ID 参数值。
  • 区域 ID 即 ACME.sh 中 CF_Zone_ID 参考值。

很多教程里面,为了贪图方便,直接使用 Cloudflare 的 Global API Key,权限太大强烈不建议。

图片[8] - 于 ACME.sh 自动签发 CoreDNS SSL TLS 证书 - 诺守博客

其它 DNS 服务提供商 API Key 申请

ACME.sh 目前几乎支持所有主流的 DNS 服务提供商,包括:CloudFlare、DNSPod、GoDaddy、Aliyun 等,详细参考:dnsapi · acmesh-official/acme.sh Wiki · GitHub

DNSPod:Token

图片[9] - 于 ACME.sh 自动签发 CoreDNS SSL TLS 证书 - 诺守博客
export DP_Id="xxx"
export DP_Key="xxx"
acme.sh --issue --dns dns_dp -d xxx

阿里云:Token

图片[10] - 于 ACME.sh 自动签发 CoreDNS SSL TLS 证书 - 诺守博客
export Ali_Key="xxx"
export Ali_Secret="xxx"
acme.sh --issue --dns dns_ali -d xxx

基于 DNS-01 申请证书

目前 DNS-01 方式申请证书,支持 Aliyun、DNSPod、CloudFlare、 GoDaddy、Azure、AWS、CloudXNS 等国内外大多数主流 DNS 服务提供商。详见:dnsapi · acmesh-official/acme.sh Wiki · GitHub

ACME dnsChallenge 证书签发、续期一般都经过以下几个步骤:

  1. 获取对应 DNS 提供商 ID、Token(AK、SK)。
  2. ACME 至 DNS 提供商进行授权认证。
  3. 认证通过添加 TXT 解析记录,进行域名所有权验证。
  4. 验证通过,签发证书。
  5. 删除 TXT 解析记录。
  6. 将对应 DNS 提供商 ID、Token(AK、SK)等信息添加至 account.conf 或 account.key 。
图片[11] - 于 ACME.sh 自动签发 CoreDNS SSL TLS 证书 - 诺守博客

登录 CoreDNS 服务器,通过以下命令申请 SSL/TLS 证书。

[root@coredns-001 ~]# export CF_Token="上面生成的 API 令牌"
[root@coredns-001 ~]# export CF_Account_ID="上面复制的 帐户 ID"
[root@coredns-001 ~]# export CF_Zone_ID="上面复制的 区域 ID"

# 默认证书颁发机构为 ZeroSSL,这里切换至 Let's Encrypt。执行此命令时,同时会将配置写入 account.conf 文件。
[root@coredns-001 ~]# acme.sh --set-default-ca --server letsencrypt
[Sun Nov 10 19:29:24 CST 2024] Changed default CA to: https://acme-v02.api.letsencrypt.org/directory

# 开启 acme.sh 自动更新功能,这时候会修改 account.conf 文件参数 AUTO_UPGRADE 值为 1
[root@coredns-001 ~]# acme.sh --upgrade --auto-upgrade
[Sun Nov 10 19:29:32 CST 2024] Already up to date!
[Sun Nov 10 19:29:32 CST 2024] Upgrade successful!

# 申请证书
[root@coredns-001 ~]# acme.sh --issue --dns dns_cf -d dns.rockylinux.cn
[Sun Nov 10 19:32:40 CST 2024] Using CA: https://acme-v02.api.letsencrypt.org/directory
[Sun Nov 10 19:32:40 CST 2024] Single domain='dns.rockylinux.cn'
[Sun Nov 10 19:32:44 CST 2024] Getting webroot for domain='dns.rockylinux.cn'
[Sun Nov 10 19:32:44 CST 2024] Adding TXT value: lK47z2qlh0N8y4hrMxYtRxEDRVx_RG9gNIvP0cpeZrc for domain: _acme-challenge.dns.rockylinux.cn # 添加 TXT 记录,验证域名所有权
[Sun Nov 10 19:32:48 CST 2024] Adding record
[Sun Nov 10 19:32:48 CST 2024] Added, OK
[Sun Nov 10 19:32:48 CST 2024] The TXT record has been successfully added.
[Sun Nov 10 19:32:48 CST 2024] Lets check each DNS record now. Sleeping for 20 seconds first.
[Sun Nov 10 19:33:09 CST 2024] You can use '--dnssleep' to disable public dns checks.
[Sun Nov 10 19:33:09 CST 2024] See: https://github.com/acmesh-official/acme.sh/wiki/dnscheck
[Sun Nov 10 19:33:09 CST 2024] Checking dns.rockylinux.cn for _acme-challenge.dns.rockylinux.cn
[Sun Nov 10 19:33:11 CST 2024] Please refer to https://curl.haxx.se/libcurl/c/libcurl-errors.html for error code: 35
[Sun Nov 10 19:33:11 CST 2024] Success for domain dns.rockylinux.cn '_acme-challenge.dns.rockylinux.cn'.
[Sun Nov 10 19:33:11 CST 2024] All checks succeeded
[Sun Nov 10 19:33:11 CST 2024] Verifying: dns.rockylinux.cn
[Sun Nov 10 19:33:13 CST 2024] Pending. The CA is processing your order, please wait. (1/30)
[Sun Nov 10 19:33:17 CST 2024] Pending. The CA is processing your order, please wait. (2/30)
[Sun Nov 10 19:33:21 CST 2024] Pending. The CA is processing your order, please wait. (3/30)
[Sun Nov 10 19:33:26 CST 2024] Success
[Sun Nov 10 19:33:26 CST 2024] Removing DNS records.
[Sun Nov 10 19:33:26 CST 2024] Removing txt: lK47z2qlh0N8y4hrMxYtRxEDRVx_RG9gNIvP0cpeZrc for domain: _acme-challenge.dns.rockylinux.cn # 删除 TXT 记录
[Sun Nov 10 19:33:28 CST 2024] Successfully removed
[Sun Nov 10 19:33:28 CST 2024] Verification finished, beginning signing.
[Sun Nov 10 19:33:28 CST 2024] Lets finalize the order.
[Sun Nov 10 19:33:28 CST 2024] Le_OrderFinalize='https://acme-v02.api.letsencrypt.org/acme/finalize/2065427157/324650019527'
[Sun Nov 10 19:33:30 CST 2024] Downloading cert.
[Sun Nov 10 19:33:30 CST 2024] Le_LinkCert='https://acme-v02.api.letsencrypt.org/acme/cert/03f21e3e2266ee7ce4a4407d49e1f47589cd'
[Sun Nov 10 19:33:32 CST 2024] Cert success.
-----BEGIN CERTIFICATE-----
MIIDgzCCAwqgAwIBAgISA/IePiJm7nzkpEB9SeH0dYnNMAoGCCqGSM49BAMDMDIx
...(略)
fa01l6Ld/7eUXOsx4CHJfaylKhYhQZp4gk5zNqXE279RDGObdQIwFlBiopL9u1jL
jt6qkYsKRxpzuKYwPEt/4AUSu/g568Td7gnlzn0sOA41cUZLgi8Z
-----END CERTIFICATE-----
[Sun Nov 10 19:33:32 CST 2024] Your cert is in: /etc/acme/certs/dns.rockylinux.cn_ecc/dns.rockylinux.cn.cer # cert.pem
[Sun Nov 10 19:33:32 CST 2024] Your cert key is in: /etc/acme/certs/dns.rockylinux.cn_ecc/dns.rockylinux.cn.key # key.pem
[Sun Nov 10 19:33:32 CST 2024] The intermediate CA cert is in: /etc/acme/certs/dns.rockylinux.cn_ecc/ca.cer # ca.pem
[Sun Nov 10 19:33:32 CST 2024] And the full-chain cert is in: /etc/acme/certs/dns.rockylinux.cn_ecc/fullchain.cer # fullchain.pem

# 因为 CoreDNS 配置的证书目录为 /etc/coredns/certs/,所以这里指定证书安装目录为 /etc/coredns/certs/,acme.sh 会将生成的证书文件复制一份至 /etc/coredns/certs/ 目录。同时添加 --reloadcmd 在证书更新后,重启 coredns 服务,生效证书文件。
[root@coredns-001 ~]# acme.sh --issue -d dns.rockylinux.cn --dns dns_cf --install-cert --cert-file /etc/coredns/certs/cert.pem --key-file /etc/coredns/certs/key.pem --ca-file /etc/coredns/certs/ca.pem --fullchain-file /etc/coredns/certs/fullchain.pem --reloadcmd "systemctl restart coredns"
[Sun Nov 10 19:29:54 CST 2024] Using CA: https://acme-v02.api.letsencrypt.org/directory
[Sun Nov 10 19:29:55 CST 2024] Single domain='dns.rockylinux.cn'
[Sun Nov 10 19:29:58 CST 2024] Getting webroot for domain='dns.rockylinux.cn'
[Sun Nov 10 19:29:58 CST 2024] Adding TXT value: -X8_BnceeAWqrUnGnSzksnuzQbt1FRhoy4VxsU_dbUw for domain: _acme-challenge.dns.rockylinux.cn # 添加 TXT 记录,验证域名所有权
[Sun Nov 10 19:30:01 CST 2024] Adding record
[Sun Nov 10 19:30:04 CST 2024] Added, OK
[Sun Nov 10 19:30:04 CST 2024] The TXT record has been successfully added.
[Sun Nov 10 19:30:04 CST 2024] Lets check each DNS record now. Sleeping for 20 seconds first.
[Sun Nov 10 19:30:25 CST 2024] You can use '--dnssleep' to disable public dns checks.
[Sun Nov 10 19:30:25 CST 2024] See: https://github.com/acmesh-official/acme.sh/wiki/dnscheck
[Sun Nov 10 19:30:25 CST 2024] Checking dns.rockylinux.cn for _acme-challenge.dns.rockylinux.cn
[Sun Nov 10 19:30:28 CST 2024] Please refer to https://curl.haxx.se/libcurl/c/libcurl-errors.html for error code: 35
[Sun Nov 10 19:30:28 CST 2024] Success for domain dns.rockylinux.cn '_acme-challenge.dns.rockylinux.cn'.
[Sun Nov 10 19:30:28 CST 2024] All checks succeeded
[Sun Nov 10 19:30:28 CST 2024] Verifying: dns.rockylinux.cn
[Sun Nov 10 19:30:29 CST 2024] Pending. The CA is processing your order, please wait. (1/30)
[Sun Nov 10 19:30:34 CST 2024] Success
[Sun Nov 10 19:30:34 CST 2024] Removing DNS records.
[Sun Nov 10 19:30:34 CST 2024] Removing txt: -X8_BnceeAWqrUnGnSzksnuzQbt1FRhoy4VxsU_dbUw for domain: _acme-challenge.dns.rockylinux.cn # 删除 TXT 记录
[Sun Nov 10 19:30:36 CST 2024] Successfully removed
[Sun Nov 10 19:30:36 CST 2024] Verification finished, beginning signing.
[Sun Nov 10 19:30:36 CST 2024] Lets finalize the order.
[Sun Nov 10 19:30:36 CST 2024] Le_OrderFinalize='https://acme-v02.api.letsencrypt.org/acme/finalize/1996015447/322699651947'
[Sun Nov 10 19:30:39 CST 2024] Downloading cert.
[Sun Nov 10 19:30:39 CST 2024] Le_LinkCert='https://acme-v02.api.letsencrypt.org/acme/cert/045875c53f319ec0a0172f0e9029c855bdaf'
[Sun Nov 10 19:30:40 CST 2024] Cert success.
-----BEGIN CERTIFICATE-----
MIIDkzCCAxmgAwIBAgISBFh1xT8xnsCgFy8OkCnIVb2vMAoGCCqGSM49BAMDMDIx
...(略)
GRcvyRICMDVZOeEDC9tFkKuOhfzx5w3KbsgBqScXvEyrULDzxUQXH7MMrA5d5llV
6zLi/Sarfw==
-----END CERTIFICATE-----
[Sun Nov 10 19:30:40 CST 2024] Your cert is in: /etc/acme/certs/dns.rockylinux.cn_ecc/dns.rockylinux.cn.cer
[Sun Nov 10 19:30:40 CST 2024] Your cert key is in: /etc/acme/certs/dns.rockylinux.cn_ecc/dns.rockylinux.cn.key
[Sun Nov 10 19:30:40 CST 2024] The intermediate CA cert is in: /etc/acme/certs/dns.rockylinux.cn_ecc/ca.cer
[Sun Nov 10 19:30:40 CST 2024] And the full-chain cert is in: /etc/acme/certs/dns.rockylinux.cn_ecc/fullchain.cer
[Sun Nov 10 19:30:40 CST 2024] Installing cert to: /etc/coredns/certs/cert.pem
[Sun Nov 10 19:30:40 CST 2024] Installing CA to: /etc/coredns/certs/ca.pem
[Sun Nov 10 19:30:40 CST 2024] Installing key to: /etc/coredns/certs/key.pem
[Sun Nov 10 19:30:40 CST 2024] Installing full chain to: /etc/coredns/certs/fullchain.pem
[Sun Nov 10 19:30:40 CST 2024] Running reload cmd: systemctl restart coredns # 重启 CoreDNS 服务
[Sun Nov 10 19:30:40 CST 2024] Reload successful

# 查看已安装证书信息
[root@coredns-001 ~]# acme.sh --info -d  dns.rockylinux.cn
[Wed Nov 20 21:02:20 CST 2024] The domain 'dns.rockylinux.cn' seems to already have an ECC cert, lets use it.
DOMAIN_CONF=/root/.acme.sh/dns.rockylinux.cn_ecc/dns.rockylinux.cn.conf
Le_Domain=dns.rockylinux.cn
Le_Alt=no
Le_Webroot=dns_cf
Le_PreHook=
Le_PostHook=
Le_RenewHook=
Le_API=https://acme-v02.api.letsencrypt.org/directory
Le_Keylength=ec-256
Le_OrderFinalize=https://acme-v02.api.letsencrypt.org/acme/finalize/1996015447/322915061567
Le_LinkOrder=https://acme-v02.api.letsencrypt.org/acme/order/1996015447/322915061567
Le_LinkCert=https://acme-v02.api.letsencrypt.org/acme/cert/03df04db442be6d17705113edd9dd2aaf94c
Le_CertCreateTime=1731555097
Le_CertCreateTimeStr=2024-11-10T03:31:37Z
Le_NextRenewTimeStr=2025-01-12T03:31:37Z
Le_NextRenewTime=1736652697
Le_RealCertPath=/etc/coredns/certs/cert.pem
Le_RealCACertPath=/etc/coredns/certs/ca.pem
Le_RealKeyPath=/etc/coredns/certs/key.pem
Le_ReloadCmd=systemctl restart coredns
Le_RealFullChainPath=/etc/coredns/certs/fullchain.pem

# 查看证书信息
[root@coredns-001 ~]# acme.sh --list
Main_Domain                KeyLength  SAN_Domains  CA               Created               Renew
dns.rockylinux.cn          "ec-256"   no           LetsEncrypt.org  2024-11-10T03:31:37Z  2025-01-08T03:31:37Z

acme.sh 参数说明:

  • --issue:申请证书。
  • --dns:指定 DNS 服务提供商,比如:dns_cf (Cloudflare)、dns_dp (DNSPod)、dns_ali (Aliyun) 等等。
  • --install-cert:指定安装证书,其实当您指定 --key-file 、--cert-file 、--fullchain-file 后,默认会自动安装证书至指定目录。
  • -d:指定需要申请证书的域名,泛证书申请 *.rockylinux.cn 。
  • –-key-file:将证书私钥复制至该参数指定目录。
  • --cert-file:将证书复制至该参数指定目录。
  • –-fullchain-file:将证书链复制至该参数指定目录。
  • –-reloadcmd:指定证书复制至指定目录后,执行的命令。
  • --ecc:指定申请的证书类型为 ECC 证书,现在 Let's Encrypt 默认签发 ECC 证书
  • --keylength:指定公开密钥加密算法密钥长度,ECC 证书可以指定:ec-256、ec-384、ec-521,RSA 证书可以指定:2048、3072、4096、8192 。

在验证域名所有权时,会自动添加一条 TXT 记录,但验证通过以后,证书下发成功以后,将自动删除对应 TXT 记录。

图片[12] - 于 ACME.sh 自动签发 CoreDNS SSL TLS 证书 - 诺守博客

Web 服务器证书

Apache、Nginx、Haproxy 待续 ……

Nginx 示例:
acme.sh --install-cert -d example.com \
--key-file       /path/to/keyfile/in/nginx/key.pem  \
--fullchain-file /path/to/fullchain/nginx/cert.pem \
--reloadcmd     "service nginx reload"
Nginx 的配置项 ssl_certificate 需要使用 /etc/nginx/ssl/fullchain.cer ,而非 /etc/nginx/ssl/<domain>.cer ,否则 SSL Labs 的测试会报证书链问题(Chain issues Incomplete)。

默认情况下,证书每 60 天更新一次(可自定义)。更新证书后,Apache 或者 Nginx 服务会通过 reloadcmd 传递的命令自动重载配置。

注意:reloadcmd 非常重要。证书会自动申请续签,但是如果没有正确的 reloadcmd 命令,证书可能无法被重新应用到 Apache 或者 Nginx,因为配置没有被重载。

--reloadcmd     "service nginx reload"要改成--reloadcmd     "service nginx force-reload
© 版权声明
THE END
点赞5赞赏 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容