acme.sh 自动更新 RSA、ECC 双证书实践

不知不觉,一年的通配符证书就快到期了。作为一名技术人员,我是不准备续费了。恰巧知道一个 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 进行域名验证。所以,你需要确保 80443 端口是没有被占用的。

# 确保你的 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

这里提一下,阿里云:

  • 进入控制台,鼠标指向你的用户名。 acme_aliyun_1
  • 点击 accesskeys,点击继续 AccessKey。 acme_aliyun_2
  • 创建 accessKey。

没有用 RAM 子账号,因为我确实没有找到 DNS 那块可授予的权限,如果你找到方法,请告诉我,非常感谢。

混合模式
该模式下,为每个域名指定不同的验证方式,但 example.comwww.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_dnsexample.comwww.example.com 颁发 ecc 证书。在证书到期前 30 天,acme.sh 将再次执行这条命令进行证书的更新。更新后执行 --renew-hook 将证书安装到指定地方 /path/to/keyfile/in/nginx/,安装好之后会执行 --reloadcmd 命令,让 nginx 重新加载证书。这样就完成了证书的自动更新,不过首次证书颁发后,需要你进行证书的安装。

安全测试和评分

当我们证书部署好了之后,如何确定是否已经部署成功(博主部署的是双证书),Nginx 配置是否安全呢。

推荐使用以下三个在线服务来检测站点 HTTPS 配置情况:

ssllabs

网站地址:https://www.ssllabs.com。国外网站,检测内容非常的详细,包括证书、协议以及客户端模拟和兼容行。 https_test_ssllabs 查看测试结果 »

httpsecurityreport

网站地址:https://httpsecurityreport.com。检测网站的一些 Header 的设置是否安全等。 https_test_security 查看测试结果 »

myssl

网站地址:https://myssl.com。这个是国内的检测站点,应该是新出来的,和 ssllabs 相似。不过关于证书的功能更多,速度也是快很多。 https_test_myssl 查看测试结果 »

本文链接:参与评论 »

--EOF--

提醒:本文最后更新于 2211 天前,文中所描述的信息可能已发生改变,请谨慎使用。

Comments