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

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.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。国外网站,检测内容非常的详细,包括证书、协议以及客户端模拟和兼容行。https_test_ssllabs查看测试结果 »

httpsecurityreport

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

myssl

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

posted @ 2020-12-08 16:39  agang_19  阅读(1740)  评论(1编辑  收藏  举报