跳到主要内容

· 阅读需 9 分钟
He Wei

前情提要

之前在 V2EX 咨询过阿里云免费 SSL 证书的替代方案(https://v2ex.com/t/999627),考虑到阿里云服务器目前的操作系统是 Windows Server 2012,所以基于 Linux 或者 Docker 的方案就都 pass 了。

再考虑到自动化更新 SSL 证书的需求,所以在经过一番调研之后,最终确定使用 win-acme(https://www.win-acme.com/)来完成这一工作。因为虽然 Caddy 也能完成这项工作,但是还需要把在 IIS 中配置好的网站再重新配置一遍,还不知道会有什么新问题。本着尽量不要增加复杂度的理念,所以就没有采用 Caddy。

由于网站前面还有一层阿里云 WAF(Web 应用防火墙),各网站的流量都是先由 WAF 检查一遍,过滤掉非法请求之后,才能最终到达服务器。而要使用 WAF 的话,各域名的 DNS 都是解析到 WAF 的地址上的,这也给后面的工作和问题排查带来了一些问题,不过这是后话了。

基本流程测试

把 win-acme 下载并解压到服务器上之后,运行程序,按照网上的教程一步步操作。为了不影响现有各域名上的业务,在阿里云服务器的 IIS 上配置了一个新的域名,并且在阿里云 WAF 里面接入了这个二级域名。

按照教程的操作步骤,成功用 win-acme 申请到了这个二级域名的 SSL 证书,但是默认步骤只会生成一个 Windows IIS 所需的 pfx 格式的证书。如果要让阿里云 WAF 能够正常过滤 HTTPS 流量,还需要上传证书和对应的私钥到阿里云的数字证书管理服务中,然后在阿里云 WAF 的网站接入设置中选择所上传的证书才行。这样一来,还需要让 win-acme 生成 PEM 格式的证书和私钥。

所以基础流程就是:申请证书 → 保存 PFX 格式证书 → 保存 PEM 格式证书。

配置阿里云 WAF

在用 win-acme 给各个域名申请证书的时候,在验证域名所有权的那一步,有的域名能够验证成功,有的域名就总会失败。考虑到 IIS 上各个域名的配置是一样的,又看了一下 DNS 解析也是一样的格式,那应该就是阿里云 WAF 的问题了。

对比之后发现,有的域名在阿里云 WAF 的配置中同时勾选了 HTTP 和 HTTPS 协议,但是有的只勾选了 HTTPS 协议。对于只勾选了 HTTPS 协议的域名,有的还没有开启 HTTP 到 HTTPS 的强制跳转。

加上域名的 DNS 解析是指向阿里云 WAF 的,于是猜测是 WAF 这里的设置导致了域名所有权的验证失败。于是给全部域名的 WAF 配置都同时勾选了 HTTP 和 HTTPS 协议,并且禁止了 HTTP 到 HTTPS 的强制跳转,这个时候,各个域名的所有权验证终于都能通过了。

Debug 阿里云 Cli

有了 win-acme,SSL 证书的自动续期就搞定了。但是证书每次续期之后,还需要再把新的证书上传到阿里云的数字证书管理服务中,然后在阿里云 WAF 的网站接入设置中更新证书。既然是 Windows 系统,那就用 PowerShell 写个脚本来实现这个操作好了。

而上面的需求需要调用阿里云的 API,如果想要用脚本来实现这一功能,就还要用到阿里云 Cli。在配置阿里云 Cli 的用户凭证时,AccessKey 凭证和 EcsRamRole 凭证方式一开始都有问题,最后把之前的配置信息都删了,新建了一个具有 管理云盾应用防火墙(WAF)的权限 的用户,然后用该用户的 AccessKey 才终于成功调用了阿里云的 API。

Debug PowerShell

在测试阿里云 API 的调用时,还遇到了一个有些隐蔽的问题,就是在阿里云的 OpenAPI 平台上测试接口调用的时候是没问题的,但是在 PowerShell 脚本中调用就是有问题。到了最后把两种方式的完整命令复制出来对比,才发现 PowerShell 的 Get-Content 命令读取到的 SSL 证书和私钥的文本,换行符都没了,这尼玛!

解决了这个问题后,续期后的新证书和私钥自动上传至阿里云并在 WAF 中更新的功能也就实现了,以后这项工作就不需要自己再手动操作了。

总结

最后再说一下完整的流程和注意事项吧。

  1. 用 win-acme 申请 SSL 证书并实现自动续期。这个程序能够自动把从 IIS 中读取网站信息,申请新证书关联到对应的网站,很省心。
  2. 如果用到了阿里云 WAF 之类的服务,要想防护 HTTPS 流量,就需要上传 SSL 证书和私钥,这样的话需要配置 win-acme 再额外保存一份 PEM 格式的证书和私钥。其中 -chain.pem 后缀的文件是需要导入 WAF 的网站证书及中间证书,-key.pem 后缀的文件则是需要导入 WAF 的私钥文件。
  3. 如果用到了阿里云 WAF 之类的服务,并且各业务域名的 DNS 都解析到了 WAF 上,那么就要在 WAF 配置中同时启用 HTTP 和 HTTPS,并且禁止 HTTP 到 HTTPS 的强制跳转,不然有可能在域名所有权验证那一步失败。
  4. 配置阿里云 Cli 的时候,如果配置的各种凭证方式都不管用,可以尝试把旧的配置都删除,包括 Cli 里的配置和阿里云网页端控制台的配置,然后重新来一遍。
  5. PowerShell Get-Content 命令拿到的证书和私钥的文本会丢失换行符,可以参考 https://stackoverflow.com/a/15041925/2667665 这里的方法来解决。
  6. 上传证书和私钥调用的是 WAF 中的 CreateCertificate 这个 API,将证书关联至 WAF 中接入域名是 CreateCertificateByCertificateId API。

背景知识

· 阅读需 1 分钟
Sébastien Lorber
Yangshun Tay

Docusaurus blogging features are powered by the blog plugin.

Simply add Markdown files (or folders) to the blog directory.

Regular blog authors can be added to authors.yml.

The blog post date can be extracted from filenames, such as:

  • 2019-05-30-welcome.md
  • 2019-05-30-welcome/index.md

A blog post folder can be convenient to co-locate blog post images:

Docusaurus Plushie

The blog supports tags as well!

And if you don't want a blog: just delete this directory, and use blog: false in your Docusaurus config.