使用 ACME.sh 与阿里云DNS 自动签发免费数字证书

引言

在当今的互联网世界中,网站安全至关重要。使用 HTTPS 不仅可以保护用户的隐私和数据安全,还能提高网站的搜索引擎排名。ZeroSSL 提供了免费的 SSL/TLS 证书,而 acme.sh 则是一个强大的 ACME 客户端,可以自动化证书的申请和续期过程。本文将介绍如何使用 acme.sh 结合阿里云 DNS 来自动签发和续期 ZeroSSL 的免费数字证书。

ZeroSSL 和 acme.sh 简介

ZeroSSL 是一个相对较新的 SSL 证书提供商,为网站所有者提供免费和付费的 SSL/TLS 证书。它成立于 2019 年,旨在简化 SSL 证书的获取和管理过程,使网站加密变得更加容易。

acme.sh 是一个纯 Shell 脚本实现的 ACME 客户端,用于从 ZeroSSL (默认)申请和更新 SSL/TLS 证书。它支持两种验证方式,一种是通过HTTP服务器验证,另一种是通过DNS记录验证。今天我们要介绍的就是后者。它具有以下优势:

  • 纯 Shell 脚本,无需安装依赖
  • 支持多种 DNS 提供商的 API
  • 自动化续期
  • 支持多种服务器软件,Nginx、Apache 等
  • 轻量级且高效

准备工作

在开始之前,我们需要准备以下内容:

  1. 一个运行 Linux 的服务器 (本教程以 Rocky Linux 8.10 版本为例)
  2. 域名及其 DNS 解析,由阿里云管理
  3. 阿里云账号及接口调用访问密钥 ( AccessKey ID 和 AccessKey Secret )
  4. 一个 Nginx 服务及网站配置,用于验证网站 SSL 证书是否生效

安装 acme.sh

首先,我们需要在服务器上安装acme.sh。普通用户和 root 用户都可以安装使用。我们这里使用 root 用户执行以下命令:

curl https://get.acme.sh | sh -s [email protected]

[root@kubecc acme]# curl https://get.acme.sh | sh -s [email protected]
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100  1032    0  1032    0     0    819      0 --:--:--  0:00:01 --:--:--   819
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100  220k  100  220k    0     0    99k      0  0:00:02  0:00:02 --:--:--   99k
[Tue Dec 31 14:50:56 CST 2024] Installing from online archive.
[Tue Dec 31 14:50:56 CST 2024] Downloading https://github.com/acmesh-official/acme.sh/archive/master.tar.gz
[Tue Dec 31 14:50:58 CST 2024] Extracting master.tar.gz
[Tue Dec 31 14:50:58 CST 2024] It is recommended to install socat first.
[Tue Dec 31 14:50:58 CST 2024] We use socat for the standalone server, which is used for standalone mode.
[Tue Dec 31 14:50:58 CST 2024] If you dont want to use standalone mode, you may ignore this warning.
[Tue Dec 31 14:50:58 CST 2024] Installing to /root/.acme.sh
[Tue Dec 31 14:50:58 CST 2024] Installed to /root/.acme.sh/acme.sh
[Tue Dec 31 14:50:58 CST 2024] Installing alias to '/root/.bashrc'
[Tue Dec 31 14:50:58 CST 2024] Close and reopen your terminal to start using acme.sh
[Tue Dec 31 14:50:58 CST 2024] Installing alias to '/root/.cshrc'
[Tue Dec 31 14:50:58 CST 2024] Installing alias to '/root/.tcshrc'
[Tue Dec 31 14:50:58 CST 2024] Installing cron job
[Tue Dec 31 14:50:58 CST 2024] bash has been found. Changing the shebang to use bash as preferred.
[Tue Dec 31 14:51:00 CST 2024] OK
[Tue Dec 31 14:51:00 CST 2024] Install success!

或者

wget -O -  https://get.acme.sh | sh -s [email protected]

上诉命令会将 acme.sh 安装到你的 home 目录下的 .acme.sh 文件夹中,并创建 一个 shell 的 alias,例如 .bashrc,为了方便后续使用你可以: alias acme.sh=~/.acme.sh/acme.sh

安装完成后,请确保重新加载 shell 配置:

source ~/.bashrc

配置阿里云 DNS API

为了让 acme.sh 能够自动添加 DNS 记录,我们需要配置阿里云的 API 密钥。首先登录到阿里云控制台,创建 AccessKey ID 和 AccessKey Secret。( 如何创建 AccessKey )

然后在服务器上设置环境变量:

export Ali_Key="your_access_key_id"
export Ali_Secret="your_access_key_secret"

为了使这些设置永久生效,你可以将它们添加到~/.bashrc~/.profile文件中。

安装信息验证:

[root@kubecc ~]# acme.sh -v
https://github.com/acmesh-official/acme.sh
v3.1.0
[root@kubecc ~]# cat .acme.sh/account.conf 
#LOG_FILE="/root/.acme.sh/acme.sh.log"
#LOG_LEVEL=1
#AUTO_UPGRADE="1"
#NO_TIMESTAMP=1  
ACCOUNT_EMAIL='[email protected]'
UPGRADE_HASH='f981sadsadasdasdasdasdasdasdasd'
SAVED_Ali_Key='LTAI4sdansjdnasAdasndADNKCN'
SAVED_Ali_Secret='Uusadasdas80JNJKNJKNjnkjmnllk'
USER_PATH='/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin'

我们可以看到安装时设置的邮箱地址和阿里云的 API Key。

申请证书

现在我们可以使用 acme.sh 来申请证书了。假设你要为 www.kubecc.com 申请证书,运行以下命令:

acme.sh --issue --dns dns_ali -d www.kubecc.com
[root@kubecc .acme.sh]# acme.sh --issue --dns dns_ali -d www.kubecc.com
[Fri Jan  3 10:33:16 CST 2025] Using CA: https://acme.zerossl.com/v2/DV90
[Fri Jan  3 10:33:16 CST 2025] Creating domain key
[Fri Jan  3 10:33:16 CST 2025] The domain key is here: /root/.acme.sh/www.kubecc.com_ecc/www.kubecc.com.key
[Fri Jan  3 10:33:16 CST 2025] Single domain='www.kubecc.com'
[Fri Jan  3 10:33:25 CST 2025] Getting webroot for domain='www.kubecc.com'
[Fri Jan  3 10:33:25 CST 2025] Adding TXT value: sdasdasdasdaxxxxxxxxxxxxxxxxxx for domain: _acme-challenge.www.kubecc.com
[Fri Jan  3 10:33:26 CST 2025] The TXT record has been successfully added.
[Fri Jan  3 10:33:26 CST 2025] Lets check each DNS record now. Sleeping for 20 seconds first.
[Fri Jan  3 10:33:47 CST 2025] You can use '--dnssleep' to disable public dns checks.
[Fri Jan  3 10:33:47 CST 2025] See: https://github.com/acmesh-official/acme.sh/wiki/dnscheck
[Fri Jan  3 10:33:47 CST 2025] Checking www.kubecc.com for _acme-challenge.www.kubecc.com
[Fri Jan  3 10:33:48 CST 2025] Please refer to https://curl.haxx.se/libcurl/c/libcurl-errors.html for error code: 35
[Fri Jan  3 10:33:58 CST 2025] Please refer to https://curl.haxx.se/libcurl/c/libcurl-errors.html for error code: 28
[Fri Jan  3 10:33:58 CST 2025] Not valid yet, lets wait for 10 seconds then check the next one.
[Fri Jan  3 10:34:15 CST 2025] Lets wait for 10 seconds and check again.
[Fri Jan  3 10:34:26 CST 2025] You can use '--dnssleep' to disable public dns checks.
[Fri Jan  3 10:34:26 CST 2025] See: https://github.com/acmesh-official/acme.sh/wiki/dnscheck
[Fri Jan  3 10:34:26 CST 2025] Checking www.kubecc.com for _acme-challenge.www.kubecc.com
[Fri Jan  3 10:34:26 CST 2025] Success for domain www.kubecc.com '_acme-challenge.www.kubecc.com'.
[Fri Jan  3 10:34:26 CST 2025] All checks succeeded
[Fri Jan  3 10:34:26 CST 2025] Verifying: www.kubecc.com
[Fri Jan  3 10:34:28 CST 2025] Processing. The CA is processing your order, please wait. (1/30)
[Fri Jan  3 10:34:35 CST 2025] Success
[Fri Jan  3 10:34:35 CST 2025] Removing DNS records.
[Fri Jan  3 10:34:35 CST 2025] Removing txt: KCRFVDwS5exxxxxxxxxxxxxxxx for domain: _acme-challenge.www.kubecc.com
[Fri Jan  3 10:34:37 CST 2025] Successfully removed
[Fri Jan  3 10:34:37 CST 2025] Verification finished, beginning signing.
[Fri Jan  3 10:34:37 CST 2025] Lets finalize the order.
[Fri Jan  3 10:34:37 CST 2025] Le_OrderFinalize='https://acme.zerossl.com/v2/DV90/order/xxxxxxx/finalize'
[Fri Jan  3 10:34:42 CST 2025] Order status is 'processing', lets sleep and retry.
[Fri Jan  3 10:34:42 CST 2025] Sleeping for 15 seconds then retrying
[Fri Jan  3 10:34:58 CST 2025] Polling order status: https://acme.zerossl.com/v2/DV90/order/xxxxxxxxxxxxxxkpg
[Fri Jan  3 10:35:01 CST 2025] Downloading cert.
[Fri Jan  3 10:35:01 CST 2025] Le_LinkCert='https://acme.zerossl.com/v2/DV90/cert/xxxxxxxxxxxxxxxx'
[Fri Jan  3 10:35:04 CST 2025] Cert success.
-----BEGIN CERTIFICATE-----
MIID/xxxxxxxxxxxxxxxxxxxxxx/Eq3IkNj+gMlTDlAwCgYIKoZIzj0EAwMwSzEL
MAkGA1UEBhMCQVQxEDAOBgNVBAoTB1plcm9TU0wxKjAoBgNVBAMTIVplcm9TU0wg
RUNDIERvbWFpbiBTZWN1cmUgU2l0ZSBDQTAeFw0yNTAxMDMwMDAwMDBaFw0yNTA0
MDMyMzU5NTlaMBkxFzAVBgNVBAMTDnd3dy5rdWJlY2MuY29tMFkwEwYHKoZIzj0C
AQYIKoZIzj0DAQcDQgAEFyfPwtHh48X9mbgabswxzbEGhBWcLNoVWj8VCIRLni0f
+FTDuyvNl4D9pznBmpX5aYLUKkeU3J+w39b/tmvWeqOCAnowggJ2MB8GA1UdIwQY
MBaAFA9r5kvOOUeu9xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxOlPTT69Xp4i
few0zXUTYTAOBgNVHQ8BAf8EBAMCB4AwDAYDVR0TAQH/BAIwADAdBgNVHSUEFjAU
BggrBgEFBQcDAQYIKwYBBQUHAwIwSQYDVR0gBEIwQDA0BgsrBgEEAbIxAQICTjAl
MCMGCCsGAQUFBwIBFhdodHRwczovL3NlY3RpZ28uY29tL0NQUzAIBgZngQwBAgEw
gYgGCCsGAQUFBwEBBHwwejBLBggrBgEFBQcwAoY/aHR0cDovL3plcm9zc2wuY3J0
LnNlY3RpZ28uY29tLxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxMCsG
CCsGAQUFBzABhh9odHRwOi8vemVyb3NzbC5vY3NwLnNlY3RpZ28uY29tMIIBBAYK
KwYBBAHWeQIEAgSB9QSB8gDwAHYAzxFW7tUufK/zh1vZaS6b6RpxZ0qwF+ysAdJb
d87MOwgAAAGUKgPhDQAABAMARzBFAiEAr8tpj5dw570imSrK7F+/2DG8WL8s+wdc
Yeumc9bDLNMCIGTCvkKHcJdHNFbOkI8idW/Y7zRC+6e5PR7CAcL0WP8VAHYAzPsP
aoVxCWX+lZtTzumyfCLphVwNl422qX5UwP5MDbAAAAGUKgPgzQAABAMARzBFAiAg
S5OsQE+NT07CfCFW1hygWn8JROy2a0jgxv4J0EUDVwIhALs8ZCuE/mjJdvLM2+AN
XCnD84ovDFn8KDfGtXnAWGALMBkGA1UdEQQSMBCCDnd3dy5rdWJlY2MuY29tMAoG
CCqGSM49BAMDA2gAMGUCMQCneaUeF8sFqazFs40/3Psald6j6B9AwE35SRBIIAP+
DO759Keek0t6DjoSAYIN+dUCMEFPG9eqglqkajjHHqW1U1kBFtlsvYjGZLPEjKJR
CTaP2LQ1X6sUmH0JOmTPeftawA==
-----END CERTIFICATE-----
[Fri Jan  3 10:35:04 CST 2025] Your cert is in: /root/.acme.sh/www.kubecc.com_ecc/www.kubecc.com.cer
[Fri Jan  3 10:35:04 CST 2025] Your cert key is in: /root/.acme.sh/www.kubecc.com_ecc/www.kubecc.com.key
[Fri Jan  3 10:35:04 CST 2025] The intermediate CA cert is in: /root/.acme.sh/www.kubecc.com_ecc/ca.cer
[Fri Jan  3 10:35:04 CST 2025] And the full-chain cert is in: /root/.acme.sh/www.kubecc.com_ecc/fullchain.cer

这个命令会执行以下步骤:

  1. 生成证书请求
  2. 通过阿里云 API 添加必要的 DNS TXT 记录
  3. 等待 ZeroSSL 验证 DNS 记录,验证通过后会将 DNS 中用于验证域名所有权的 TXT 解析记录删除
  4. 获取证书

如果一切顺利,你将看到成功信息,证书文件会被保存在 ~/.acme.sh/www.kubecc.com/ 目录下。

安装证书至 Nginx

获取证书后,我们需要将其安装到 Web 服务器中。以 Nginx 为例:

[root@kubecc .acme.sh]# acme.sh --install-cert -d www.kubecc.com  \
> --key-file       /etc/nginx/sslkey/kubecc.com/www.kubecc.com.key  \
> --fullchain-file /etc/nginx/sslkey/kubecc.com/www.kubecc.cer \
> --reloadcmd     "sudo service nginx force-reload"
[Fri Jan  3 10:35:39 CST 2025] The domain 'www.kubecc.com' seems to already have an ECC cert, lets use it.
[Fri Jan  3 10:35:39 CST 2025] Installing key to: /etc/nginx/sslkey/kubecc.com/www.kubecc.com.key
[Fri Jan  3 10:35:39 CST 2025] Installing full chain to: /etc/nginx/sslkey/kubecc.com/www.kubecc.cer
[Fri Jan  3 10:35:39 CST 2025] Running reload cmd: sudo service nginx force-reload
Redirecting to /bin/systemctl force-reload nginx.service
[Fri Jan  3 10:35:39 CST 2025] Reload successful

这个命令会将证书文件复制到指定位置,并在证书更新时重新加载 Nginx,记得提前修改 Nginx 配置文件以使用新的证书:

server {
    listen 443 ssl;
    server_name example.com;
    ssl_certificate /path/to/fullchain/nginx/cert.pem;
    ssl_certificate_key /path/to/keyfile/in/nginx/cert.key;
    # ........
}

验证证书信息:

[root@kubecc ~]# acme.sh --info -d www.kubecc.com
[Fri Jan  3 18:25:16 CST 2025] The domain 'www.kubecc.com' seems to already have an ECC cert, lets use it.
DOMAIN_CONF=/root/.acme.sh/www.kubecc.com_ecc/www.kubecc.com.conf
Le_Domain=www.kubecc.com
Le_Alt=no
Le_Webroot=dns_ali
Le_PreHook=
Le_PostHook=
Le_RenewHook=
Le_API=https://acme.zerossl.com/v2/DV90
Le_Keylength=ec-256
Le_OrderFinalize=https://acme.zerossl.com/v2/DV90/order/kra3C-DVCNbHmoM0lsO11g/finalize
Le_LinkOrder=https://acme.zerossl.com/v2/DV90/order/kra3C-DVCNbHmoM0lsO11g
Le_LinkCert=https://acme.zerossl.com/v2/DV90/cert/AulqYPZhPp70qPYeA1etLg
Le_CertCreateTime=1735893871
Le_CertCreateTimeStr=2025-01-03T08:44:31Z
Le_NextRenewTimeStr=2025-03-03T08:44:31Z
Le_NextRenewTime=1740991471
Le_RealCertPath=
Le_RealCACertPath=
Le_RealKeyPath=/etc/nginx/sslkey/kubecc.com/www.kubecc.com.key
Le_ReloadCmd=sudo service nginx force-reload
Le_RealFullChainPath=/etc/nginx/sslkey/kubecc.com/www.kubecc.com.cer

自动续期

acme.sh 会自动创建一个 cron 作业,每天检查证书是否需要续期。默认情况下,您不需要手动更新证书,所有证书将每 60 天自动更新一次。

你可以通过以下命令查看cron作业:

crontab -l

如果你想手动强制续期,可以运行:

acme.sh --renew -d example.com --force

常见问题及解决方案

  1. DNS 验证失败

    • 检查阿里云API密钥是否正确
    • 确保域名在阿里云 DNS 管理下
    • 检查是否有其他 DNS 记录冲突
  2. 证书安装失败

    • 确保指定的路径存在且有写入权限
    • 检查 Web 服务器配置是否正确
  3. 自动续期不工作

    • 检查 cron 作业是否正确设置
    • 确保 acme.sh 有足够的权限执行更新
  4. 如何升级 acme.sh

    # 您可以将 acme.sh 更新到最新代码
    acme.sh --upgrade
    
    # 您还可以启用自动升级
    acme.sh --upgrade --auto-upgrade
    
    # 禁用自动升级
    acme.sh --upgrade --auto-upgrade 0
  5. API 调用次数限制

    • 阿里云可能会限制 API 调用次数,避免频繁操作
  6. 证书吊销

    如果需要吊销证书:

    acme.sh --remove -d example.com [--ecc]
    # 证书/密钥文件不会从磁盘中删除,您可以手动删除

最佳实践

  1. 定期备份
    定期备份~/.acme.sh目录,以防意外情况发生。
  2. 监控证书状态
    设置监控系统,及时发现证书问题。
  3. 使用强密码学套件
    在 Web 服务器配置中使用强密码学套件,提高安全性。
  4. 启用 HSTS
    考虑启用 HTTP 严格传输安全 (HSTS) ,进一步增强安全性。
  5. 保护私钥
    确保证书私钥的安全,限制访问权限。
  6. 测试续期过程
    定期测试证书续期过程,确保自动化流程正常工作。

总结

通过使用 acme.sh 和阿里云 DNS,我们可以轻松实现免费数字证书的自动签发和续期。这不仅节省了大量时间和精力,还确保了网站始终受到 SSL/TLS 的保护。

参考文献

[1] acmesh-official

用一杯咖啡支持我们,我们的每一篇[文档]都经过实际操作和精心打磨,而不是简单地从网上复制粘贴。期间投入了大量心血,只为能够真正帮助到您。
暂无评论

发送评论 编辑评论


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