65.9K
CodeProject 正在变化。 阅读更多。
Home

使用 Let’s Encrypt 获取免费自动 SSL 证书

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.45/5 (5投票s)

2016年9月1日

CPOL

9分钟阅读

viewsIcon

17371

如何使用 Let’s Encrypt 获取免费自动 SSL 证书

如果您自己维护带有 SSL 证书的服务器或服务器集群,您可能会知道更新这些证书有多么令人头疼。特别是当您拥有大量服务器,其中一些甚至可能使用相同的证书时,管理起来会非常麻烦。幸运的是,有一个解决方案,它叫做 Let’s Encrypt。

介绍 Let’s Encrypt

Let’s Encrypt 是一个证书颁发机构 (CA),它提供一种自动化方法来请求和续订免费的域名验证 (DV) SSL 证书。无法通过 Let’s Encrypt 请求其他证书类型(组织验证 (OV) 和扩展验证 (EV))。这些证书类型需要 CA 进行一些手动工作,因此无法自动化。如果您有充分的理由选择 OV 或 EV 证书,Let’s Encrypt 就不是您的选择。但请记住:每种证书类型对您的网站访问者来说都是同样安全的。

Let’s Encrypt 于 2014 年 11 月启动,并于 2016 年 4 月正式结束 Beta 测试。如今,Mozilla、Google、Facebook 和 Akamai 等一些最大的互联网公司都作为赞助商和董事会成员参与其中。例如,Akamai 在您使用其 CDN 时允许您使用 Let’s Encrypt 证书,这可以从其控制面板进行设置。

与 Let’s Encrypt 密切相关的是自动化证书管理环境 (ACME) 协议。该协议描述了服务器应如何与 Let’s Encrypt 服务器通信以请求和续订证书。任何人都可以创建一个实现该协议并与 Let’s Encrypt 服务器通信的实用程序。请记住:Let’s Encrypt 是 CA,ACME 是请求新证书的协议。在 IETF 的 Github 页面 上阅读有关 ACME 协议的更多信息。

通常,通过 ACME 协议为 example.com 请求证书涉及以下步骤:

  1. 首先,代理需要为 example.com 授权请求证书。它通过以下两种方式之一进行:
    1. 通过为 example.com 创建 DNS 记录进行验证
    2. 通过在 example.com/.well-known/acme-challenge 下创建 HTTP 资源进行验证
  2. 此外,代理和 Let’s Encrypt 会通信一对公钥/私钥。这样,Let’s Encrypt 就可以在将来识别该代理
  3. Let’s Encrypt 会查找提供的资源之一。如果找到,则允许客户端请求此域的证书
  4. 客户端现在可以与 Let’s Encrypt 服务器通信传统的证书签名请求 (CSR)。此请求使用之前通信的公钥/私钥对进行签名,以便 Let’s Encrypt 知道该客户端有权请求此域的证书。
  5. 现在可以在服务器的 /etc/letsencrypt/live/example.com 下找到证书。您所要做的就是将您的 Web 服务器指向这些文件。

Let’s Encrypt 最初创建的实现 ACME 协议的工具是 certbot。还存在多个 其他 客户端 存在,允许您使用多种不同的编程语言请求证书。在这篇博文中,我们将使用 certbot。

为什么挑战文件有固定位置?

在使用 HTTP 方法进行域名验证时,Let’s Encrypt 会在您的服务器上查找“挑战文件”。该文件必须可以通过 example.com/.well-known/acme-challenge/[文件名] 访问。此目录已设置且无法更改。

事实证明,这是一个相当重要的安全细节。今年六月,CA StartSSL 发布了一个与 Let’s Encrypt 类似的工具:StartEncrypt。该工具允许您更改挑战文件的位置,很快就可以为 Dropbox 和 Google 等网站获取有效的 SSL 证书。为什么?因为这些网站允许您以上传文件的公共可访问的原始格式。换句话说:您可以将挑战文件上传到您的 Dropbox 文件夹来请求 Dropbox 证书。有关更多详细信息,请查看突出显示此问题的 原始博文。七月,StartSSL 开始 开发新版本的 StartEncrypt,该版本也实现了 ACME 协议。

配置指南

首先,您需要一个 Web 服务器和一个指向该 Web 服务器的域名(通过 A 记录)。在本文的其余部分,我将继续使用 example.com 作为示例。我将使用的技术是在 CentOS 7.2 服务器上运行的 Nginx。由于我们将使用通用的 webroot 插件,因此收到的证书也可用于 Apache 等其他 Web 服务器。

本文开头将使用的 Nginx 配置可以在 我的 Github 账户 上找到。这是一个 SSL Labs A+ 级配置;详细信息可以在我 之前的博文 中找到。我将假设您对 Nginx 和证书有基本了解。我们将为挑战文件添加一个新的 Nginx location,并且只会稍微更改以下三行配置;

ssl_certificate /etc/ssl/example.com.crt;
ssl_certificate_key /etc/ssl/example.com.key;
ssl_trusted_certificate /etc/ssl/example.com.trusted.pem;

安装 certbot

certbot 已为许多 Linux 发行版打包。有关您操作系统安装的详细信息,请查看 certbot 安装指南:如果您使用的是 CentOS 或 RedHat,可以简单地执行

yum install epel-release
yum install certbot
certbot --version # 0.8.1 at the time of writing

请求证书

我们需要为挑战文件配置 Nginx。为此,请将以下内容添加到您的 Nginx 配置中:

server {
  listen 80;
  server_name example.com www.example.com;

  location ~ /.well-known/acme-challenge {
    root /var/www/example.com;
  }
}

重新加载 Nginx 以应用这些更改。我们将为两个域名创建一个证书,以便可以使用同一个证书将 www 访问者重定向到我们实际的非 www 域(使用 HTTPS)。certbot 将在 /var/www/example.com/.well-known/acme-challenge 中创建挑战文件。

cerbot 包含一个 dry-run 功能,它将从 Let’s Encrypt 服务器获取伪证书。这是在请求“真实”证书之前测试客户端的方法。使用 dry-run 功能很重要,因为 Let’s Encrypt 有一些 速率限制,在测试时很容易超出。在服务器上运行以下命令:

certbot certonly --webroot --dry-run -w /var/www/example.com -d example.com -d www.example.com

您指定的第一个域名将是 SSL 证书的通用名称;其他域名将作为主题备用名称 (SAN) 添加。执行此命令后,您将看到一个蓝色屏幕,要求您提供电子邮件地址,以防紧急通知和丢失密钥恢复。接下来,您必须同意服务条款,之后您将收到证书。默认情况下,这些证书存储在 /etc/letsencrypt/live/example.com 中。此文件夹中的文件是符号链接;实际证书存储在 /etc/letsencrypt/archive/example.com 中。在此目录中,还将放置续订的证书。/live 文件夹将简单地指向您收到的最新证书。这样,您就可以始终简单地将 Web 服务器指向此文件。

恭喜!您刚刚通过 ACME 协议请求了您的第一个(虽然是无效的)SSL 证书。如果您再次运行相同的命令,您将有机会续订证书:查看 /etc/letsencrypt/archive/example.com 文件夹,现在可以看到两组证书文件。另外,为了避免出现蓝色屏幕,将来可以使用以下参数;

--email                Your e-mailaddress (only for first request)
--agree-tos            Agree with the ToS (only for first request)
--keep-until-expiring  Relevant when renewing your certificate; 
                       this will only renew it when its about to expire
--force-renewal        Force to renew the certificate, 
                       even when its not about to expire. Should only be used with --dry-run!

准备好进行真正的操作了吗?再次执行之前的命令,但这次加 –dry-run 选项。这将为您提供有效的证书。编辑您的 Nginx 配置文件以指向新生成的证书文件。您需要在配置中有以下几行:

ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
ssl_trusted_certificate /etc/letsencrypt/live/example.com/fullchain.pem;

如果您的服务器启用了 OCSP 装订,则仅需要最后一行。重新加载您的 Nginx 配置,并检查您的证书是否正常工作,并且现在来自 Let’s Encrypt。在 Google Chrome 中,我的网站显示如下:

a valid ssl certificate with a SAN as seen in Google Chrome

您还可以执行 SSLLabs 服务器测试 来检查一切是否按预期工作。

设置自动证书续订

Let’s Encrypt 证书的有效期为 90 天。与传统 CA 证书一年或两年的有效期相比,这可能显得很短。考虑到我们将自动化证书的续订,这应该无关紧要,对吧?事实上,Let’s Encrypt 正在考虑更短的有效期。我们只需要确保我们足够频繁地续订我们的证书。

续订证书的过程很简单。定期,最方便的是使用 cron 作业,我们检查我们的证书是否需要续订,如果需要,我们就续订。事实上,我们可以通过运行以下命令来检查当前是否需要续订:

certbot renew

这很可能会告诉您,我们刚设置的证书尚未到期。运行此命令将续订此服务器上所有接近到期日期的证书,这些证书最初由 certbot 创建。添加 --force-renewal 标志将强制续订证书,无论其到期日期如何。这样做会产生以下输出:

-------------------------------------------------------------------------------
Processing /etc/letsencrypt/renewal/example.com.conf
-------------------------------------------------------------------------------

-------------------------------------------------------------------------------
new certificate deployed without reload, fullchain is
/etc/letsencrypt/live/example.com/fullchain.pem
-------------------------------------------------------------------------------

Congratulations, all renewals succeeded. The following certs have been renewed:
/etc/letsencrypt/live/example.com/fullchain.pem (success)

您可以自己尝试一下,但请务必牢记速率限制!当新证书创建后,Nginx 并不会立即加载它们,即使其配置指向已覆盖的文件(符号链接)。这是因为 Nginx 已经将证书加载到内存中。因此,我们需要重新加载配置才能使 Nginx 加载新证书。我们可以通过 --post-hook 参数轻松实现这一点,在该参数中我们可以指定重新加载 nginx 的参数。完整的命令如下所示:

certbot renew --post-hook "systemctl reload nginx"

要完全自动化续订,我们只需要确保定期执行此命令。让我们设置一个 cron 作业来完成此任务。

设置 cron 作业

正如我们所见,即使证书尚未到期,调用续订命令也是完全安全的。因此,每周甚至每天执行此命令都没有问题。我们将创建一个每周执行一次的 cron 作业。

请确保您已以 root 用户身份登录,并使用以下命令打开 crontab 编辑文件:

crontab -e

在现在打开的文件中,添加以下行:

@weekly certbot renew --quiet --post-hook "systemctl reload nginx"

@weekly0 0 * * 0 的别名,而且在我看来,比替代写法更容易阅读。它在每周的第一天、第一个小时、第一分钟执行。当然,如果您有更具体的时间要求,请相应地编辑计划。--quiet 标志会隐藏除错误之外的所有输出。每当我阅读 cron 日志时,我都不想在其中看到每周的“证书未到续订期”消息。

保存 crontab 文件:您就完成了!要测试 cron 作业,您可以先设置 cron 作业以每分钟运行一次,使用 * * * * * 计划。不幸的是,没有 @minutely 别名 :-)。

结论

我们已成功生成初始 SSL 证书并配置了 Nginx。然后,我们使用 cron 作业设置了自动续订。如果您期望更多,那我就要让您失望了:就这样!

这篇博文 使用 Let’s Encrypt 获取免费自动 SSL 证书 最初发布在 Sander Knape

© . All rights reserved.