使用 Certbot 管理来自 Let’s Encrypt 的证书

作为新型的免费、开放、自动化的证书颁发机构,Let’s Encrypt 自 2015 年来为推动互联网 HTTPS 化做出了卓越的贡献。Certbot 是最流行的基于 Let’s Encrypt 的客户端,用于在服务器上简化 HTTPS(SSL/TLS)证书的申请流程。本文中,我们介绍通过 Certbot 客户端为网络服务器添加删除 HTTPS 证书、吊销证书,以及为已有证书添加新域名的操作。

安装 Certbot

Certbot 可以在 UNIX 类系统中基于 Python 2.7 或 Python 3.6+ 环境中运行。近几代 Debian/Ubuntu、RHEL/CentOS/Fedora、openSUSE 等操作系统均受支持。

如果要配置的 HTTP 服务器运行 macOS 或 Windows 操作系统,请按此处的指引配置 Certbot 软件。

Certbot 软件支持通过 snap 软件包或系统自带的软件包管理器安装。官方推荐使用 snap 软件包的方式进行安装。

snap 软件包

Certbot 的 snap 软件包版本支持 x86_64、ARMv7 以及 ARMv8 架构。

要通过 snap 软件包方式安装 Certbot,需首先确保服务器系统中安装有 snap 包管理器:通过这里给出的方式配置 snapd。

使用以下命令在系统中安装 Certbot:

sudo snap install --classic certbot

在大多数系统环境中,该指令应能成功完成。如果在执行过程中遇到任何错误,请参阅此处的详细步骤再试。

系统软件包管理器

Certbot 客户端包含于最新的 apt、dnf 以及 pacman 软件仓库中。如果你使用的发行版支持,则可以使用下述命令之一安装 Certbot 的相关组件:

sudo pacman -S certbot
sudo apt-get install certbot
sudo dnf install certbot

如果系统中已经安装有 Apache 或 Nginx 网络服务器,则可能需要安装额外的软件包,其名称可能为 python3-certbot-apachepython3-certbot-nginxpython2-certbot-apachepython2-certbot-nginx

为服务器添加 HTTPS 证书支持

可以通过多种方法使用 Certbot 在你的服务器上申请证书,其中主要包括以下几种途径:

在进行下述步骤之前,首先需要确保将你拥有的一个或多个域名指向要设置的服务器。该操作需要在你的域名服务商处完成。

通过已有 HTTP 服务器申请证书

如果服务器中已装有 Apache、Nginx 或其他类型的网络服务器,则 Certbot 可以根据配置自动简化这些服务器的证书配置步骤。对于 Apache 或 Nginx 服务器,只需使用以下命令之一即可:

sudo certbot --apache
sudo certbot --nginx

如果服务器上使用除此之外的其他类型服务器,则需要手动指定 wwwroot 的路径,在大多数系统上,网络服务器默认网站的路径通常被设置为 /var/www/html

sudo certbot certonly --webroot -w /var/www/html

我们以 Apache 服务器为例,演示使用 Certbot 获取 HTTPS 证书的具体步骤。首先,我们输入 sudo certbot --apache 命令后,得到如下提示:

Saving debug log to /var/log/letsencrypt/letsencrypt.log
Plugins selected: Authenticator apache, Installer apache
Enter email address (used for urgent renewal and security notices) (Enter 'c' to
cancel):

Certbot 在该步骤要求用户提供电子邮箱地址,以便接收有关证书续期以及安全性方面的重要提示。输入电子邮件后,按回车继续:

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Please read the Terms of Service at
https://letsencrypt.org/documents/LE-SA-v1.2-November-15-2017.pdf. You must
agree in order to register with the ACME server at
https://acme-v02.api.letsencrypt.org/directory
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
(A)gree/(C)ancel:

键入 A 以同意 Let’s Encrypt 的条款与条件后继续:

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
Would you be willing to share your email address with the Electronic Frontier Foundation, a founding partner of the Let's Encrypt project and the non-profit organization that develops Certbot? We'd like to send you email about our work encrypting the web, EFF news, campaigns, and ways to support digital freedom.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - -
(Y)es/(N)o:

该步骤中,Certbot 联合 EFF(电子前哨基金会)询问用户是否愿意收到来自 EFF 的推广邮件,可以根据自身需要选择 YN 后继续:

No names were found in your configuration files. Please enter in your domain name(s) (comma and/or space separated)  (Enter 'c' to cancel):

在该步骤中输入你希望为服务器申请 HTTPS 证书所关联的一个或多个域名。如有多个,可以使用空格或逗号做分隔,然后继续。此处我们以 cert.example.com 举例。

如果验证域名所有权的过程一切顺利,你会看到如下提示:

Please choose whether or not to redirect HTTP traffic to HTTPS, removing HTTP access.
- - - - - - - - - - - - - - - - - - - - - - - - -
1: No redirect - Make no further changes to the webserver configuration.
2: Redirect - Make all requests redirect to secure HTTPS access. Choose this for new sites, or if you're confident your site works on HTTPS. You can undo this change by editing your web server's configuration.
- - - - - - - - - - - - - - - - - - - - - - - - -
Select the appropriate number [1-2] then [enter] (press 'c' to cancel):

该提示询问用户是否希望以后将指向服务器的 HTTP(不安全连接)请求强制重定向到 HTTPS(安全连接)的版本,我们推荐的选项是 2(重定向)。这样做可以增强服务器传输的安全性。特别地,如果在执行完先前一个步骤(输入域名)后由于报错没有看到本步骤的话,则可能是由于所输入的域名并未指向该服务器导致的。

根据为域名提供解析服务(DNS)服务商的设置不同,为已存在的解析设置新的解析地址的操作可能需要一段时间(通常是 10 分钟左右)才能生效。具体请参阅服务商的相关说明。

如果设置一切正常,则可以注意到页面中的 Congratulations(恭喜)字样,代表设置完成。Certbot 默认生成的证书文件一般存储于 /etc/letsencrypt/live/ 目录下。让网站的访客通过 HTTPS 访问吧!

如果系统中没有 HTTP 服务器

如果在申请证书时系统中尚未安装 HTTP 服务器(如 Apache 或 Nginx),可以通过 Certbot 自带简单的 HTTP 服务器临时完成证书的申请步骤。这种情况特别适用于希望通过 SSL/TLS 证书加密其他服务时(而非网站)使用。

如果你不能将希望添加验证的域名指向这台服务器,则应考虑通过 DNS 验证等其他方式申请域名或泛域名证书。

由于 Certbot 软件将会在系统中开启一个用于临时证书申请的 HTTP 服务器,需要确保系统中 TCP 80 端口未被占用。申请证书时,只需执行以下命令:

sudo certbot certonly --standalone

即可。申请证书的步骤和上一小节是类似的。

通过 DNS 记录申请域名或泛域名证书

如果在验证时无法将域名指向服务器本身,又或者希望申请一张包含泛域名的 HTTPS 证书,则应考虑使用 DNS 记录的方式申请证书。

泛域名证书:类似 *.example.com 的证书是泛域名证书,该证书包含所有以 .example.com 结尾的二级域名,如 blog.example.com 或者 ssh.example.com 等。需要注意,主域名 example.com 本身无法被 *.example.com 涵盖,需要在申请证书时单独填写这个一级域名。

通过 DNS 记录的方式申请证书需要申请者拥有域名对应的 DNS 记录的修改权限。Certbot 会通过向给定域名请求 DNS TXT 记录的方式验证域名的所有权。要开始使用这种方式认证,需执行:

sudo certbot certonly --manual

这将进入 Certbot 的手动申请证书模式,前几个步骤和上一小节提及的完全相同,在输入域名步骤时:

Please enter in your domain name(s) (comma and/or space separated)  (Enter 'c' to cancel):

我们以 example.com 为例,如果希望申请泛域名证书,此处应当填写 *.example.com example.com 两项,因为如上所述,二级域名的泛域名证书是无法涵盖 example.com 域名本身的:

- - - - - - - - - - - - - - - - - - - - - - -
NOTE: The IP of this machine will be publicly logged as having requested this certificate. If you're running certbot in manual mode on a machine that is not your server, please ensure you're okay with that.
Are you OK with your IP being logged?
- - - - - - - - - - - - - - - - - - - - - - -
(Y)es/(N)o:

由于申请证书所使用的服务器 IP 地址可能与域名所指向的地址不同,但申请过程中该 IP 地址会将公开。输入 Y 以继续:

- - - - - - - - - - - - - - - - - - - - - - - -
Please deploy a DNS TXT record under the name
_acme-challenge.example.com with the following value:

-jhDFkEl-47iGpvWAgRMHnOsqzMaa-AC6rKeqQDURxY

Before continuing, verify the record is deployed.
- - - - - - - - - - - - - - - - - - - - - - - -
Press Enter to Continue

如上所述,使用 DNS 记录验证域名所有权时,Certbot 会要求你将一个二级域名 _acme-challenge.example.com 设置成如上提示的值。这时你需要在购买域名的解析设置处添加如下设置:

主机记录记录类型记录值
_acme.challenge.example.comTXT-jhDFkEl-47iGpvWAgRMHnOsqzMaa-AC6rKeqQDURxY
上述示例中的域名与记录值需要根据 Certbot 的提示填写,此处仅为示例

设置完成对应的记录后,按回车键继续。正常情况下,在数秒的自动验证完成之后即可完成申请证书的全部步骤。但请注意,由于通过修改 DNS 记录的方式获取 HTTPS 证书的方式是手动的,Certbot 不能完成证书的自动续期工作。

如果你的域名解析服务提供商在受支持的列表中(不含国内),则可以使用 Certbot 的插件自动化完成该验证过程。详见此处

删除与吊销 HTTPS 证书

如果不慎将 HTTPS 证书私钥泄露,则应立即吊销该证书,而非考虑删除。

由 Certbot 成功申请的证书一般会保存至 /etc/letsencrypt/live 中。也可以通过以下命令显示目前由 Certbot 申请并管理的全部证书:

sudo certbot certificates

执行该命令后,会显示所有的证书列表。如果确实不需要某个证书,可以使用 certbot delete 命令删除证书及其相关的配置:

sudo certbot delete --cert-name cert.example.com

其中,cert.example.com 是证书的名称,此处仅作示例之用,请依据实际情况填写。特别注意,如果证书私钥被泄露,应考虑首先吊销证书而非删除。

吊销 HTTPS 证书

对于 HTTPS 所使用的 SSL/TLS 证书而言,目前采用一套名为在线证书状态协议(OCSP)的机制来确保证书的有效性。当证书私钥被不慎泄露时,攻击者有能力伪造你的服务器向用户发送数据。此时应当考虑将对应证书进行吊销操作。这样,浏览器在访问网站时会检查对应证书的有效性,降低攻击者使用无效证书伪造身份的危险性。Certbot 的吊销证书过程非常简单,只需:

sudo certbot revoke --cert-path /etc/letsencrypt/live/CERTNAME/cert.pem --reason keycompromise

其中,–cert-path 选项后接的是证书私钥文件的地址,请使用 certbot certificates 命令查看已有证书的地址。可选项 –reason 后可以填写有关为何吊销该证书的一段说明性文字。

OCSP 为用户浏览互联网提供了额外的安全性,我们推荐阅读此文以了解其详细工作原理。

为已有证书添加或删除域名

我们拥有向已有证书添加或删除新域名,而非为每个域名单独申请证书的需求。这样,我们可以在一张 SSL/TLS 证书中包含多个(而非一个)域名来使用。该操作非常简单,首先我们使用以下命令查看由 Certbot 管理的全部证书列表:

sudo certbot certificates

我们从中选择需要添加或删除域名的证书,记下来证书名称(Certificate Name)字段。使用类似下述命令编辑已有证书所包含的域名:

sudo certbot certonly --cert-name example.com -d example.com -d a.example.com -d b.example.com

上述示例为一个名为 example.com,且包含两个域名的证书 example.com、a.example.com 的证书添加了 b.example.com 域名。–cert-name 参数后包含证书名称。而 -d 选项后紧跟的是希望证书对应的全部新域名。如果我们希望将 a.example.com 域名从该证书中删除,则使用下述命令:

sudo certbot certonly --cert-name example.com -d example.com

这样一来,该证书在重新认证后将会仅包含 example.com 一个域名。

写在最后

Certbot 大幅简化了往常繁琐的 HTTPS 证书申请过程。出于网络或环境因素,如果在申请 HTTPS 证书的过程中遇到任何问题或报错信息,首先建议查看位于 /var/log/letsencrypt 中的日志文件,以查看异常具体发生于何处。大多数在操作证书过程中的常见问题应当容易获得社区支持。