笔记:Let’s Encrypt 获取 TLS 证书(Webroot + Nginx)


 拍摄于 2018-02-10,POPSOCKETS
拍摄于 2018-02-10,POPSOCKETS

Standalone vs Webroot

使用 Let’s Encrypt 申请 TLS 证书,抛开官方给的 Apache/Nginx plugin,主要可以分为 StandanloneWebroot 两种认证方式,主要区别在于:

  1. 前者 Standalone 的认证方式需要暂时占用服务器的 80 或者 443 端口,来进行获取和更新证书的操作。换言之,如果服务器上搭建了网站,又不希望因为获取和更新 TLS 证书的过程造成网站暂时下线的状况,Standalone 的方式并不理想;
  2. 如果需要验证的域名本身使用了 CDN,Standalone 的验证方式也会出问题。比如在 DNS 中新建一个 A/AAAA 记录将 site.com 指向了 12.34.56.78 这个 IP,此时使用 Standalone 不会有问题,但一旦打开 CDN,很可能首先 IP 就会变成 CDN 分配的 87.65.43.21,而 Standalone 的验证方式又需要请求 IP 和提供的 IP 完全一致,所以会导致验证失败;

使用 Webroot 认证方式

自己的需求里因为有个已经在运行的 Nginx 作为服务器,所以直接选择了 Webroot 的方式,大致的原理:需要验证的域名配置文件里 server.conf (监听 80 端口那部分)中,添加一个通配规则,使得 certbot 可以生成一个特定的验证文件,同时让之后 Let’s Encrypt 的验证服务器发起的 http-01 请求可以验证到对应文件。

验证通过之后,Let’s Encrypt 就会在特定的文件夹里生成指定域名的 TLS 证书,在对应的 server block 里直接调用就可以。

认证操作的基本步骤

下面做一个完整并且简单的例子,对应自己的情况:现有一个 example.com ,还没有 TLS 证书,Nginx 中的最精简的配置文件如下,对应的文件位置在

建立文件夹,并且在 Nginx 配置文件中加入 Let’s Encrypt 请求验证地址的规则:

然后安装相关 certbot 依赖

接着就是比较关键的一步,通过 certbot 获取 TLS 证书

命令中的几个 flag 大概的解释:

  • certonly:说明我们只需要获取证书,不需要 certbot 为我们去执行自动安装;
  • --webroot:使用 Webroot 的验证方式;
  • --agree-tos:默认同意 Let’s Encrypt 的一些 agreements,不加这个参数在命令执行过程中还是会问用户是否同意;
  • --email:用来获取一些 Let’s Encrypt 的通知,比如证书过期之类;
  • --webroot-path:对应上面 Nginx 设置中的 server 定义区块里的 root 地址;
  • --domains:这个 root 路径需要验证的 SSL/TLS 的域名。这里可以填写多个,比如 example.com 可能会对应 www.example.com,但同时需要在 Nginx 的 server.conf 中加入对应内容,如果按照上文中配置来测试,实际运行命令中不要添加,否则可能会报错。

到这里验证就成功了, certbot 会出现「成功提示」,生成完成的证书文件会保存在固定的 /etc/letsencrypt/ 路径下:

  1. /etc/letsencrypt/live/{{ EXAMPLE.COM }}/fullchain.pem;
  2. /etc/letsencrypt/live/{{ EXAMPLE.COM }}/privkey.pem

完成获取 TLS 证书后,接着就需要更新 Nginx 的配置来让域名的 https:// 生效,这里还是以一个 example.com 的来作为例子(不包含 www.example.com),首先配置从 http:// 自动跳转 https:// :

其次,添加 https://example.com 的配置:

最后,remove 并且重新 ln -s 一下 server.confreload Nginx 使配置生效就可以

不同子域验证

Let’s Encrypt 原计划会在 2018 年第一季度支持 wildcards 证书,目前被推迟,所以如果有需求要对不同子域进行 TLS 认证,现在只能通过类似上面的方式对子域一个一个单独认证,配合 Webroot 大致可以归纳为以下几种方式。

不同子域名 + 相同 Webroot 的验证

类似上面的情况,比如 example.comsubdomain.example.com 都是指向同一个 Webroot,两个域名都需要认证,可以通过如下命令执行:


不同子域 + 不同 Webroot 的验证

类似这样的情况:

  • example.com:对应 /var/www/example.com 目录;
  • subdomain1.example.com:对应 /var/www/subdomain1 目录;
  • subdomain2.example.com:对应 /var/www/subdomain2 目录;

可以通过类似这样的命令来获取证书


在原有证书上追加新子域证书:

比如 example.com 已经有了一个认证完成的证书,这个时候 DNS 解析了一个新的子域名 subdomain.example.com,同时新开了一个 webroot /var/www/subdomain 目录指向新的子域,可以通过 --expand flag 来进行对证书的追加:

测试中关于追加子域到证书,有以下几点:

  1. 在 expand 的操作里,可以使用与已经认证的域名相同的 webroot 路径,即:已经认证的 example.com 使用 webroot 路径是 /var/www/example.com,之后想要追加的域名 subdomain.example.com 可以使用与前者相同的 /var/www/example.com 作为 --webroot-path
  2. 可以不使用 --expand flag。直接在 --domains flag 之后追加新的、需要认证的子域同样 totally fine,certbot 本身会提示是不是需要 expand 操作;

参考 & 扩展阅读

使用 let’s encrypt 启动https

感谢阅读

你们好, 2018 年初把小站从 Jekyll 迁移到 Hugo 的过程中,删除了评论区放的 Disqus 插件,考虑有二:首先无论评论、还是对笔记内容的进一步讨论,读者们更喜欢通过邮件、或者 Twitter 私信的方式来沟通;其次一年多以来 Disqus 后台能看到几乎都是垃圾留言(spam),所以这里直接贴一下邮件、以及 Twitter 账户 地址。

技术发展迭代很快,所以这些笔记内容也有类似新闻的时效性,不免有过时、或者错误的地方,欢迎指正 ^_^。

BEST
Lien(A.K.A 胡椒)
本站总访问量 本站总访客量 本文总阅读量