使用 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认证,之后利用非对称加密 演算来对通信方做身份认证,之后交换对称密匙作为会谈密匙(Session key)。 这个会谈密匙是用来将通信两方交换的资料做加密,保证两个应用间通信的保密性和可靠性,使客户与服务器应用之间的通信不被攻击者窃听。
在 Web 应用程序中,我们常将 TLS 搭配 HTTP 协议进行使用(它们之间无耦合),即 HTTP Over TLS。
ACME 协议
自动证书管理环境(英语:Automatic Certificate Management Environment,缩写ACME )是一种通信协议,用于证书颁发机构与其用户的Web服务器之间的自动化交互,允许以极低成本自动化部署公钥基础设施。
该协议由互联网安全研究小组(ISRG)为 Let's Encrypt 服务设计。
是的,就是第一个做免费 SSL 的神奇非盈利性组织。
acme.sh
Repo: acmesh-official/acme.sh
acme.sh 是通过 bash 对 ACME 协议进行的实现,可以通过调用 ACME Endpoint 生成证书。
安装
我们不会提供 Windows 环境的相关教程
# 安装依赖(Debian、Ubuntu)
apt install curl socat
# 调用脚本安装
curl https://get.acme.sh sh -s email=my@example.com
# 添加别名命令
alias acme.sh=~/.acme.sh/acme.sh
更高级、详细的安装过程请参考:https://github.com/acmesh-official/acme.sh/wiki/How-to-install
CA 选择
acme.sh 的 wiki 提供了一些可供选择的 CA:
CA | MaxLifetime | ECC | Domain Count | Wildcard | IPv4 | IPv6 | NotAfter | IDN | CN |
---|---|---|---|---|---|---|---|---|---|
Let’s Encrypt | 90 | Yes | 100 | Yes | No | No | No | Yes | R3 |
ZeroSSL | 90 | Yes | 100 | Yes | No | No | Yes | Yes | ZeroSSL RSA Domain Secure Site CA |
90 | Yes | 100 | Yes | No | No | Yes | No | GTS | |
Buypass | 180 | Yes | 5 | Paid | No | No | No | Yes | Buypass Class 2 CA 5 |
SSL.com | 90 | Yes | 2 | Paid | No | No | No | Yes | |
HiCA | 180 | Paid | 10 (1 if Wildcard) | Yes | Yes | Yes | No | Yes | Sectigo RSA Domain Validation Secure Server 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验证,因此建议使用文件验证。