不知不觉,一年的通配符证书就快到期了。作为一名技术人员,我是不准备续费了。恰巧知道一个 acme.sh 的项目,它是一个实现 ACME 协议的客户端,能够向支持 ACME 协议的 CA 申请证书(如 Letsencrypt)。 最重要的是它对接了大多数的域名服务商,能够通过域名服务商提供的 API,自动的添加 DNS 验证记录进行全自动颁发证书,还可以模拟 HTTP 服务器进行文件验证。so,不管你的证书期限是 90 天,还是更短,再也不用担心证书过期的问题了。
至于 ACME 协议是什么?Automatic Certificate Management Environment 自动化证书管理环境,通过它我们可以实现证书的自动申请以及部署,可以大大的节省人员的管理及额外的配置工作。
ACME 的通信过程通过一系列的 API 进行,你可以通过类似 https://example.com/directory
获取可以请求的 API 列表,如 Letsencrypt。当然再通信过程中采取了很多的安全措施,如在 RFC 文档中你可能会看 JWT、JWS、JOSE、JWK、reply-nonce等名词,看起来就陌生。如果你不是技术人员,也大可不必去研究那些东西,知道怎么用就行。
安装 acme.sh
好了,废话不多说。acme.sh 下载非常的简单,官方提供了 2 中方式:
通过执行在线脚本安装:
$ curl https://get.acme.sh | sh # 或者 $ wget -O - https://get.acme.sh | sh
通过 git 安装:
git clone https://github.com/Neilpang/acme.sh.git cd ./acme.sh ./acme.sh --install
在安装的过程中,做了 3 件事:
- 复制 acme.sh 到你的 HOME 目录($HOME):~/.acme.sh/。之后所有生成的证书也会放在这里。
- 创建别名:
acme.sh=~/.acme.sh/acme.sh
。 - 创建 cron 每日任务去检查是否有证书需要更新。
如:
0 0 * * * "/home/user/.acme.sh"/acme.sh --cron --home "/home/user/.acme.sh" > /dev/null
使用 acme.sh
如何使用?acme.sh 的功能非常的强大,使用方式确非常的简单。提醒,该脚本需要在你的服务器下执行。官方地址:How-to-issue-a-cert。
关于 ECC 证书,你只需要再末尾添加 --keylength ec-256
。如:
$ acme.sh --issue -w /home/wwwroot/example.com -d example.com -d www.example.com --keylength ec-256
可选长度有:
- ec-256 (prime256v1, “ECDSA P-256”)
- ec-384 (secp384r1, “ECDSA P-384”)
- ec-521 (secp521r1, “ECDSA P-521”, which is not supported by Let’s Encrypt yet.)
申请证书
单域名
$ acme.sh --issue -d example.com -w /home/wwwroot/example.com
多域名
$ acme.sh --issue -d example.com -d www.example.com -d cp.example.com -w /home/wwwroot/example.com
这里的 -w
指定的是 web 服务器根目录,请确保有写入权限。example.com 就是你要签发的域名,建议主域放在第一个。颁发好的证书会放在 ~/.acme.sh/example.com/
。证书将会每 60 天自动更新。
注意:这里仅申请颁发证书,之后还有安装步骤。当然这些步骤均可实现自动化。指定 web 根目录是为了写入验证文件,故请保证根目录的文件可以通过 URL 访问到。
Standalone 模式
这个模式会自己启动一个 HTTP/HTTPS 的服务器,供 CA 进行域名验证。所以,你需要确保 80⁄443 端口是没有被占用的。
# 确保你的 80 端口未被占用
$ acme.sh --issue -d example.com --standalone
# 当然你也可以指定端口,但前提是你会通过代理或负载均衡转发到该端口。
# 因为 letsencrypt 可只会访问 80 端口哦。
$ acme.sh --issue -d example.com --standalone --httpport 88
当然还有 --tls
模式,使用 443 端口。
Apache/Nginx 模式
这个模式会检查 apache/nginx 现有的配置。在证书颁发成功后,自动的更改配置文件,达到自动申请自动部署的目的,非常的方便:
$ acme.sh --issue -d example.com --apache
$ acme.sh --issue -d example.com --nginx
DNS 手动模式
$ acme.sh --issue --dns -d example.com -d www.example.com -d cp.example.com
会有类似以下信息:
Add the following txt record:
Domain:_acme-challenge.example.com
Txt value:9ihDbjYfTExAYeDs4DBUeuTo18KBzwvTEjUnSwd32-c
Add the following txt record:
Domain:_acme-challenge.www.example.com
Txt value:9ihDbjxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Please add those txt records to the domains. Waiting for the dns to take effect.
你需要手动添加如上域名记录。
如果你需要更新证书,请执行:
$ acme.sh --renew -d example.com
DNS API模式
通过域名服务商提供的 API 模式,进行动态的添加 DNS 记录,实现自动证书更新及部署。这也是本博客采用的方式(未采用 Nginx 方式也是有原因的)。
DNS API支持列表,涵盖了国内外主流的域名服务商。具体的使用方法你需要根据服务商进行不同设置 How to use DNS API。
这里提一下,阿里云:
- 进入控制台,鼠标指向你的用户名。
- 点击 accesskeys,点击继续 AccessKey。
- 创建 accessKey。
没有用 RAM 子账号,因为我确实没有找到 DNS 那块可授予的权限,如果你找到方法,请告诉我,非常感谢。
混合模式
该模式下,为每个域名指定不同的验证方式,但 example.com
和 www.example.com
必须在同一根目录。
$ acme.sh --issue \
-d example.com -d www.example.com -w /home/wwwroot/ \
-d bb.com --dns dns_cf \
-d cc.com --apache \
-d dd.com -w /home/wwwroot/dd.com
安装证书
再颁发证书之后,我们可能需要将证书拷贝到指定位置。那么我们需要使用到 --install-cert
命令,请尽量避免手动拷贝证书。
# 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"
# 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 force-reload"
这里会将私钥、证书、证书链拷贝到指定位置,成功后执行 --reloadcmd
命令。请确保有执行这些命令的权限。
当然你也不用担心证书更新的问题,在证书 60 天之后,会自动更新,更新后就会执行 --reloadcmd
的命令。
这里还有一些 hook 功能,请查看帮助 $ acme.sh -h
,如,--renew-hook
(每次证书成功更新后执行的命令)等。
更新证书
使用该工具的应该都是冲着其强大的自动更新部署功能来的。当然,如果你想手动更新:
# RSA
$ acme.sh --renew -d example.com --force
# ECC
acme.sh --renew -d example.com --force --ecc
全自动更新
为了实现全自动更新证书,我们需要添加一个 --renew-hook
的命令,它的作用就是能够在证书成功颁发后执行命令。
如:
$ acme.sh --issue --dns dns_ali -d example.com -d www.example.com -k ec-256 \
--renew-hook "acme.sh --install-cert -d example.com --ecc \
--key-file /path/to/keyfile/in/nginx/key.pem \
--fullchain-file /path/to/fullchain/nginx/cert.pem \
--reloadcmd \"service nginx force-reload\""
解读,这里使用 ali_dns
为 example.com
和 www.example.com
颁发 ecc
证书。在证书到期前 30 天,acme.sh
将再次执行这条命令进行证书的更新。更新后执行 --renew-hook
将证书安装到指定地方 /path/to/keyfile/in/nginx/
,安装好之后会执行 --reloadcmd
命令,让 nginx 重新加载证书。这样就完成了证书的自动更新,不过首次证书颁发后,需要你进行证书的安装。
安全测试和评分
当我们证书部署好了之后,如何确定是否已经部署成功(博主部署的是双证书),Nginx 配置是否安全呢。
推荐使用以下三个在线服务来检测站点 HTTPS 配置情况:
ssllabs
网站地址:https://www.ssllabs.com。国外网站,检测内容非常的详细,包括证书、协议以及客户端模拟和兼容行。 查看测试结果 »
httpsecurityreport
网站地址:https://httpsecurityreport.com。检测网站的一些 Header 的设置是否安全等。 查看测试结果 »
myssl
网站地址:https://myssl.com。这个是国内的检测站点,应该是新出来的,和 ssllabs 相似。不过关于证书的功能更多,速度也是快很多。 查看测试结果 »
本文链接:https://deepzz.com/post/acmesh-letsencrypt-cert-auto-renew.html,参与评论 »
--EOF--
发表于 2017-07-01 01:48:00,并被添加「acme.sh、letsencrypt」标签,最后修改于 2018-11-02 14:27:57。
本站使用「署名 4.0 国际」创作共享协议,转载请注明作者及原网址。更多说明 »
提醒:本文最后更新于 2226 天前,文中所描述的信息可能已发生改变,请谨慎使用。
Comments