使用 acme.sh 自动为IP/域名配置证书

SSL 证书作为一个在市场上应用十几年的玩意,任何一个做 Web 相关技术的都不大可能不知道这是个啥。

常见的国内个人站长使用的 SSL 证书基本都是 Let’s Encrypt、 TrustAsia、CloudFlare SSL 等,它们都提供免费的 DV SSL 域名证书。而本文中主要的应用场景是基于 ACME 协议和其实现 acme.sh 进行自动化证书签发。

 环境须知
因作者个人爱好原因,本文所提供的命令均为 Ubuntu 22.04 LTS 系统下测试完成的命令,截图也将为此系统环境的截图。
如使用 Debian 等与此兼容的系统环境,可直接使用。
如使用RHEL、Cent OS等不兼容的系统环境,需要自行替换部分目录,例如:apt

关于 SSL

做网络,要是连 SSL 都不知道是啥,快去投胎吧……

SSL:一个让你花钱的同时感受到极度的快乐的玩意,尽管你花的钱通常没啥用。

Secure Sockets Layer,即 SSL,中文翻译为 安全套接层。我们目前所使用的被称之为 SSL 加密的并非是原本的 SSL,而是更新更安全的 TLS (Transport Layer Security, 传输层安全性协议)加密。

这是是一种安全协议,目的是为互联网通信提供安全及数据完整性保障。网景公司(Netscape)在1994年推出首版网页浏览器-网景导航者时,推出HTTPS协议,以SSL进行加密,这是SSL的起源。

IETF将SSL进行标准化,1999年公布TLS 1.0标准文件(RFC 2246)。随后又公布TLS 1.1(RFC 4346,2006年)、TLS 1.2(RFC 5246,2008年)和TLS 1.3(RFC 8446,2018年)。

SSL包含记录层(Record Layer)和传输层,记录层协议确定传输层数据的封装格式。传输层安全协议使用X.509[1]认证,之后利用非对称加密[2]演算来对通信方做身份认证,之后交换对称密匙作为会谈密匙(Session key)[3]

这个会谈密匙是用来将通信两方交换的资料做加密,保证两个应用间通信的保密性和可靠性,使客户与服务器应用之间的通信不被攻击者窃听。

在 Web 应用程序中,我们常将 TLS 搭配 HTTP 协议进行使用(它们之间无耦合),即 HTTP Over TLS[4]

ACME 协议

自动证书管理环境(英语:Automatic Certificate Management Environment,缩写ACME)是一种通信协议,用于证书颁发机构与其用户的Web服务器之间的自动化交互,允许以极低成本自动化部署公钥基础设施。

该协议由互联网安全研究小组(ISRG)为 Let’s Encrypt 服务设计。

是的,就是第一个做免费 SSL 的神奇非盈利性组织。

acme.sh

acme.sh 是通过 bash 对 ACME 协议进行的实现,可以通过调用 ACME Endpoint 生成证书。

安装

我们不会提供 Windows 环境的相关教程
# 安装依赖(Debian、Ubuntu)
apt install curl socat

# 调用脚本安装
curl https://get.acme.sh | sh -s [email protected]

# 添加别名命令
alias acme.sh=~/.acme.sh/acme.sh

更高级、详细的安装过程请参考:https://github.com/acmesh-official/acme.sh/wiki/How-to-install

CA 选择

acme.sh 的 wiki 提供了一些可供选择的 CA:

CAMaxLifetimeECCDomain CountWildcardIPv4IPv6NotAfterIDNCN
Let’s Encrypt[5]90Yes100YesNoNoNoYesR3
ZeroSSL[6]90Yes100YesNoNoYesYesZeroSSL RSA Domain Secure Site CA
Google[7]90Yes100YesNoNoYesNoGTS
Buypass[8]180Yes5PaidNoNoNoYesBuypass Class 2 CA 5
SSL.com90Yes2PaidNoNoNoYes
HiCA[9]180Paid10 (1 if Wildcard)YesYesYesNoYesSectigo RSA Domain Validation Secure Server CA
来自 https://github.com/acmesh-official/acme.sh/wiki/CA
GTS 证书需注意
申请 GTS 证书需要在 Google Cloud 获取对应 Token,请参考:Automate Public Certificates Lifecycle Management via RFC 8555 (ACME) & Google Public CA

你可通过 --server <acme_endpoint> 指定CA,例如:

acme.sh --issue \
        -d example.com \
        --server https://acme.hi.cn/directory

签发证书

文件验证

# 文件验证签发证书
acme.sh --issue \
        -d example.com \
        -d www.example.com \
        --webroot /data/wwwroot/example.com/

# e.q.
acme.sh --issue \
        -d ssl-test.ah-dark.tech \
        -d ssl-test2.ah-dark.tech \
        --webroot /data/wwwroot/ssl-test.ah-dark.tech/

# 使用内置 HTTP 服务器
acme.sh --issue \
        -d example.com \
        --standalone
  • 通过 --issue 指定要执行的操作是签发证书。
  • 通过 -d <domain> 指定要包含的域名,此处可以包含多个域名,若包含不支持的域名会有报错提示。
  • 通过 --webroot <path> 指定 web 服务器的根路径,你也可以不使用这项而选择使用 --standalone 让 acme.sh 自己创建一个80端口的HTTP服务器进行监听。

指定 --webroot 后,脚本会访问 <path>/.well-known/ 创建验证文件,请确保其用户权限和 Web Server 权限配置正确。

随后你可以在以下位置找到你的证书文件等信息(当然你也可以后续使用自动安装证书):

  • ~/.acme.sh/<domain>/fullchain.cer 全链证书公钥(部署请使用这个)
  • ~/.acme.sh/<domain>/<domain>.csr 单域名公钥
  • ~/.acme.sh/<domain>/ca.cer CA证书公钥
  • ~/.acme.sh/<domain>/<domain>.key 证书私钥(部署请使用这个)

DNS 验证

首先,acme.sh 会请求 pki 获取对应域名需添加的 txt 记录:

acme.sh --issue --dns \
        -d example.com \
        --yes-I-know-dns-manual-mode-enough-go-ahead-please

# e.q.
acme.sh --issue --dns \
        -d ssl-test.ah-dark.tech \
        --yes-I-know-dns-manual-mode-enough-go-ahead-please
第一步操作反馈

而后,你需要等待 txt 记录添加并解析完成,然后执行下一步操作:

# 注意这里是 renew
acme.sh --renew \
        -d example.com \
        --yes-I-know-dns-manual-mode-enough-go-ahead-please

# e.q.
acme.sh --renew \
        -d ssl-test.ah-dark.tech \
        --yes-I-know-dns-manual-mode-enough-go-ahead-please
第二步操作反馈

随后你可以在以下位置找到你的证书文件等信息(当然你也可以后续使用自动安装证书):

  • ~/.acme.sh/<domain>/fullchain.cer 全链证书公钥(部署请使用这个)
  • ~/.acme.sh/<domain>/<domain>.csr 单域名公钥
  • ~/.acme.sh/<domain>/ca.cer CA证书公钥
  • ~/.acme.sh/<domain>/<domain>.key 证书私钥(部署请使用这个)

需要注意的是,dns 方式的真正强大之处在于可以使用域名解析商提供的 api 自动添加 txt 记录完成验证。

acme.sh 目前支持 cloudflare, dnspod, cloudxns, godaddy 以及 ovh 等数十种解析商的自动集成,具体请自行查阅 https://github.com/acmesh-official/acme.sh/blob/master/dnsapi/README.md

安装证书

前面证书生成以后,接下来需要把证书复制到真正需要用它的地方。

默认生成的证书都放在安装目录下: ~/.acme.sh/ ,请不要直接使用此目录下的文件,例如:不要直接让 Nginx / Apache 的配置文件使用这下面的文件。这里面的文件都是内部使用,而且目录结构可能会变化。

正确的使用方法是使用 --install-cert 命令,并指定目标位置,然后证书文件会被copy到相应的位置。

Nginx

acme.sh --install-cert -d ssl-test.ah-dark.tech \
        --key-file       /path/to/keyfile/in/nginx/key.pem  \
        --fullchain-file /path/to/fullchain/nginx/cert.pem \
        --reloadcmd     "service nginx force-reload"

# e.q.
acme.sh --install-cert -d ssl-test.ah-dark.tech \
        --key-file       /usr/local/nginx/conf/ssl/ssl-test.ah-dark.tech.key  \
        --fullchain-file /usr/local/nginx/conf/ssl/ssl-test.ah-dark.tech.pem \
        --reloadcmd     "service nginx force-reload"
这里用的是 service nginx force-reload 而不是 service nginx reload
据测试,reload 并不会重新加载证书,所以用的 force-reload

Nginx 的配置 ssl_certificate 使用 /etc/nginx/ssl/fullchain.cer ,而非 /etc/nginx/ssl/<domain>.cer ,否则 SSL Labs 的测试会报 Chain issues Incomplete 错误。

--install-cert 命令可以携带很多参数,来指定目标文件。并且可以指定 --reloadcmd ,即证书更新后执行的命令。

详细参数请参考: https://github.com/Neilpang/acme.sh#3-install-the-issued-cert-to-apachenginx-etc

值得注意的是:这里指定的所有参数都会被自动记录下来,并在将来证书自动更新以后被再次自动调用。

Apache

acme.sh --install-cert -d example.com \
        --cert-file      /path/to/certfile/in/apache/cert.pem  \
        --key-file       /path/to/keyfile/in/apache/key.pem  \
        --fullchain-file /path/to/fullchain/certfile/apache/fullchain.pem \
        --reloadcmd     "service apache2 force-reload"

查询证书信息

对于已签发的证书,可以通过下述命令查询其证书信息:

acme.sh --info -d example.com

# e.q.
acme.sh --info -d ssl-test.ah-dark.tech

自动化

使用上述安装方法安装的 acme.sh 会自动添加 crontab 条目。

你也可以自行添加:

15 0 * * * "/root/.acme.sh"/acme.sh --cron --home "/root/.acme.sh" > /dev/null

IP 证书

目前 acme.sh 提供的支持 IP SSL ACME 签发的CA仅有 HiCA。

IP SSL

请务必注意,IP SSL仅能使用 PTR 反向查询记录 和 文件验证 进行签发,本人不清楚 acme.sh 是否支持PTR验证,因此建议使用文件验证。

Reference

  1. ^X.509是密码学里公钥证书的格式标准。X.509证书已应用在包括TLS/SSL在内的众多网络协议里,同时它也用在很多非在线应用场景里,比如电子签名服务。
  2. ^非对称式密码学(Asymmetric cryptography)是密码学的一种算法,它需要两个密钥,一个是公开密钥,另一个是私有密钥;公钥用作加密,私钥则用作解密。使用公钥把明文加密后所得的密文,只能用相对应的私钥才能解密并得到原本的明文,最初用来加密的公钥不能用作解密。由于加密和解密需要两个不同的密钥,故被称为非对称加密。
  3. ^一次性用于会话中加密用的对称式密钥,所有成员使用同一把密钥来加密明文、解密密文,在此次连线结束该密钥即无效,如需重新通信则需要再重新进行一次密钥的产生及交换等步骤。
  4. ^别问我为啥不和 DNS Over TLS 一样叫 HOT,我也不知道……
  5. ^因 ISRG Root X3 过期,很多老版本系统设备无法正常使用配备例如Let’s Encrypt R3等基于新根证书的证书。
  6. ^acme.sh 目前默认使用此 CA
  7. ^允许使用IP作为证书
使用 acme.sh 自动为IP/域名配置证书 的发布基于协议 AHdark Blog License。如欲对此文章内容此文章转载、修改或行使任何超出预览和分享性质的行为,请参考此协议。

评论

  1. ferry
    Macintosh Chrome
    8月前
    2023-1-23 18:01:34

    这篇讲得好详细👍

  2. York
    Macintosh Safari
    12月前
    2022-10-12 22:11:26

    然而很悲哀的是在Let’s Encrypt替换成自己的根证书后就遭受不住防火墙的打击,大批封杀。它的创始人因癌症去世了,却没有在这里起到一点重视。唉。

发送评论 编辑评论


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