使用 Let's Encrypt 为域名申请免费 SLL 证书

  小绿锁真香

想要给网站上 https?很简单!不用费心去域名厂商那里寻找免费的证书申请, Let’s Encrypt 真的很香!

首先介绍一下我自己的情况和需求:我的域名是在阿里云买的,www 和 @(裸/根域名)都解析到了自己的 VPS 上,此外还有几个留作他用的子域名也在 VPS 上有对应的网站;而 blog 子域名则解析到了 GitHub Pages 托管的博客,也就是本站上。

SSL 证书颁发的对象是域名,其中根域名(example.com)、不同的一级子域名(a.example.comb.example.com)、二级子域名(a.b.example.com)等都被视为不同的域名,理论上每个域名都需要单独的 SSL 证书。

好在为了避免大量子域名证书的情况,存在通配符证书这种东西,它的颁发对象是泛解析的域名 *.example.com ,也就是一张证书保护了所有的子域名。注意,它仅仅只能覆盖包含 www 在内的一级子域,且一般不包括根域名1

Let’s Encrypt 从 2018 年 3 月起提供通配符证书2。此外,它还提供了一张证书包含多个不同域名的服务。在 Let’s Encrypt 申请证书完全免费,有效期 3 个月,可以续签。

综合考虑,为了包含我所需保护的所有域名,最好的方式是申请一张同时包含根域名和通配符的证书。

如果使用宝塔面板创建网站的话,可以直接在网站设置界面的“SSL”选项卡里勾选所需的域名,然后一键申请 Let’s Encrypt 证书,根据提示进行验证即可。申请成功后,面板还会自动添加续签计划任务。

PS:这里我遇到过一点坑,在试图换证书的时候遇到了问题,无论如何续签服务都针对的都是第一次申请的证书。最后发现需要删除 /www/server/panel/vhost/letsencrypt/ 下的域名文件夹、/www/server/panel/vhost/cert/<网站名> 目录下的两个 pem 文件,以及 /www/server/panel/config/letsencrypt.json 这个配置文件,才能完全重来。

其实完全自己手工操作,申请证书也并不复杂,步骤如下3

注意:仅仅申请一张域名证书可以在任何 Linux 环境下进行,不一定非要在网站服务器上,申请到的证书可以部署于任意一台服务器;但每一台客户端在申请(或续签)证书时生成的密钥是不同的(所谓“续签”,其实类似于申请一张新证书,证书的内容是会变的;同一域名的不同证书是完全独立的,一经签发,任何一张在各自的有效期内都可以正常工作,但它们仍然共享每周的签发数量限制),因此为了便于定时自动续签,最好还是直接在服务器上申请。

  1. 首先,下载官方的 acme.sh 脚本并运行安装:

    1
    wget -O -  https://raw.githubusercontent.com/Neilpang/acme.sh/master/acme.sh | INSTALLONLINE=1  sh
    

    提示 Install success! 即完成。

  2. 然后开始申请证书,需要验证对域名的所有权:

    1
    2
    3
    cd ~/.acme.sh
    ./acme.sh --issue -d  *.example.com  -d example.com --dns \
    --yes-I-know-dns-manual-mode-enough-go-ahead-please
    

    若有更多域名,可以继续加 -d 参数。

    建议把通配符域名写在前面,因为浏览器中小绿锁显示的颁发对象默认是首个域名,通配符域名显得高端大气。另外,在使用宝塔面板 Web 界面直接申请 Let’s Encrypt 证书时,可以在网站的“域名管理”页中先添加通配符域名再添加其他域名,使得通配符域名在此页的最下面一行,这样“SLL”页面中申请时就会以通配符域名为第一个参数啦。这样做还能解决宝塔面板中子目录绑定的子域名 https 访问自动跳转到主页的问题。

    这里的 yes-I-know-dns-manual-mode-enough-go-ahead-please 参数必须加,否则无法继续执行,原因是我们使用了人工 DNS 的验证方式。这种方式现在不被官方推荐使用4,它不支持自动续签。如果你的 DNS 服务提供商提供了 api 密钥来修改 DNS 解析的话,可以使用 DNS API 模式来验证(阿里云是可以使用这种方式的,宝塔面板的自动续签也使用了这种方式)。

    这里为了方便起见,仍然使用了人工方式。等终端显示出:

    Add the following TXT record:

    Domain: ‘_acme-challenge.example.com’

    TXT value: ‘***************************’

    就去 DNS 控制台把相应的 TXT 解析记录填入。

  3. 待解析生效后,继续执行:

    1
    ./acme.sh --renew -d  *.example.com  -d example.com
    

    待验证执行完毕,终端显示如下内容:

    Your cert is in /home/user/.acme.sh/*.example.com/*.example.com.cer

    Your cert key is in /home/user/.acme.sh/*.example.com/*.example.com.key

    The intermediate CA cert is in /home/user/.acme.sh/*.example.com/ca.cer

    And the full chain certs is there: /home/user/.acme.sh/*.example.com/fullchain.cer

    就表示申请成功啦,上述四个文件分别是证书、密钥、CA 根证书和全链证书(证书和根证书的组合)。

需要注意的是证书申请的的速率(数量)限制。这里引用官网文档的说明:

我们主要限制的是每个注册域名的证书数量(每周 50 张)。一般而言,注册域名是您从域名注册商处购买的那一部分域名。例如,在域名 www.example.com 中,注册域名为 example.com;在 new.blog.example.co.uk 中,注册域名为 example.co.uk。我们使用公共后缀列表来确定注册域名。

如果您有许多子域名,您可能希望将它们合并为一张证书。您最多可以在一张证书中包含 100 个域名。结合上述限制,这意味着您每周最多可以获得 5000 个不同子域名的证书。包含多个域名的证书通常称为 SAN 证书,有时也称为 UCC 证书。注意:出于性能和可靠性的原因,每张证书最好包含尽可能少的域名。

续期证书遵守特殊规则:它们不计入您的每个注册域名的证书数量的限制,但它们受到每周最多 5 张重复证书的限制。请注意:在 2019 年 3 月前,续期证书曾计入您的每个注册域名的证书数量的限制,但现在我们不再这么做了。

如果一张证书包含的域名与以前某张证书的完全相同(不论大小写及域名顺序),那么它会被视为对之前证书的续期证书(或重复证书)。例如,如果您申请了仅包含 [www.example.com,example.com] 的证书,那么您在之后的一周内最多可以再申请 4 张仅包含 [www.example.com,example.com] 的证书。如果您在域名列表中添加了 [blog.example.com],那么您就不会受到重复证书的限制,可以申请更多证书。

对续期证书的处理不考虑使用的公钥和请求的扩展。即使您使用新密钥,颁发包含完全一样域名的证书也将被视为续期。

将证书配置到服务器的操作根据服务器软件不同也有所区别,大致都是把 key (全链证书)和 pem 文件上传到 cert 目录中去,这里就不展开了。

最后,如果需要在 GitHub Pages 部署 https,那么很简单,不需要关心证书申请和服务器端配置的问题,因为 GitHub 官方已经与 Let’s Encrypt 进行了合作,可以自动申请自定义域名的 SLL 证书并配置好5。如果你使用的是 CNAME 方式将自定义域名解析到 github.io 域名的话,只需要去仓库设置里开启 Enforce HTTPS 选项即可;如果的用的是 A 记录解析到 GitHub 的 ip,那么先去改成 CNAME 吧!


参考链接

-------------本文结束    感谢您的阅读-------------
0%