Let’s Encrypt 是由互联网安全研究组(ISRG)创建的证书颁发机构。它通过全自动流程提供免费 SSL 证书,旨在消除手动创建、验证、安装和续期证书的工作。

Let’s Encrypt 颁发的证书自签发之日起 90 天内有效,并且目前所有主流浏览器均信任该证书。

本教程将指导你在 Debian 9 上使用 certbot 工具获取免费的 Let’s Encrypt 证书。我们还将展示如何配置 Apache 以使用新的 SSL 证书并启用 HTTP/2。

先决条件

在继续本教程之前,请确保已满足以下先决条件:

  • 以具有 sudo 权限的用户身份登录。
  • 拥有一个指向服务器公网 IP 的域名。我们将使用 example.com。
  • 已安装 Apache,并为你的域名配置了 Apache 虚拟主机。你可以按照这些说明了解如何创建虚拟主机。

安装 Certbot

Certbot 是一款功能齐全且易于使用的工具,可以自动完成获取和续期 Let’s Encrypt SSL 证书的任务。certbot 软件包包含在 Debian 默认软件仓库中。

使用以下命令更新软件包列表并安装 certbot 软件包:

终端
sudo apt update
sudo apt install certbot

生成强 DH(Diffie-Hellman)参数组

Diffie–Hellman 密钥交换(DH)是一种在不安全的通信信道上安全交换加密密钥的方法。

要生成一组新的 2048 位 DH 参数,请运行:

终端
sudo openssl dhparam -out /etc/ssl/certs/dhparam.pem 2048
提示如果你愿意,可以将位数增加到 4096 位,但在这种情况下,生成过程可能需要超过 30 分钟,具体取决于系统熵。

获取 Let’s Encrypt SSL 证书

为了给我们的域名获取 SSL 证书,我们将使用 Webroot 插件,该插件通过在 ${webroot-path}/.well-known/acme-challenge 目录中创建临时文件来验证所请求的域名。Let’s Encrypt 服务器会对该临时文件发起 HTTP 请求,以验证所请求的域名是否解析到 certbot 运行的服务器。

为了更简单起见,我们将把所有针对 .well-known/acme-challenge 的 HTTP 请求映射到一个单独目录 /var/lib/letsencrypt。

以下命令会创建该目录并使其对 Apache 服务器可写。

终端
sudo mkdir -p /var/lib/letsencrypt/.well-known
sudo chgrp www-data /var/lib/letsencrypt
sudo chmod g+s /var/lib/letsencrypt

为避免重复代码,请创建以下两个配置片段:

/etc/apache2/conf-available/letsencrypt.confapache
Alias /.well-known/acme-challenge/ "/var/lib/letsencrypt/.well-known/acme-challenge/"
<Directory "/var/lib/letsencrypt/">
    AllowOverride None
    Options MultiViews Indexes SymLinksIfOwnerMatch IncludesNoExec
    Require method GET POST OPTIONS
</Directory>
/etc/apache2/conf-available/ssl-params.confapache
SSLCipherSuite EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH
SSLProtocol All -SSLv2 -SSLv3 -TLSv1 -TLSv1.1
SSLHonorCipherOrder On
Header always set Strict-Transport-Security "max-age=63072000; includeSubDomains; preload"
Header always set X-Frame-Options SAMEORIGIN
Header always set X-Content-Type-Options nosniff
# 需要 Apache >= 2.4
SSLCompression off
SSLUseStapling on
SSLStaplingCache "shmcb:logs/stapling-cache(150000)"
# 需要 Apache >= 2.4.11
SSLSessionTickets Off

SSLOpenSSLConfCmd DHParameters "/etc/ssl/certs/dhparam.pem" 

上面的代码片段包含推荐的加密套件,启用 OCSP Stapling、HTTP 严格传输安全(HSTS)以及一些安全相关的 HTTP 头。

在启用配置文件之前,请通过以下命令确保 mod_ssl 和 mod_headers 已启用:

终端
sudo a2enmod ssl
sudo a2enmod headers

启用 HTTP/2 模块,这将使你的网站更快、更健壮:

终端
sudo a2enmod http2

运行以下命令启用 SSL 配置文件:

终端
sudo a2enconf letsencrypt
sudo a2enconf ssl-params

重新加载 Apache 配置以使更改生效:

终端
sudo systemctl reload apache2

使用带有 webroot 插件的 Certbot 工具获取 SSL 证书文件:

终端
sudo certbot certonly --agree-tos --email admin@example.com --webroot -w /var/lib/letsencrypt/ -d example.com -d www.example.com

如果 SSL 证书成功获取,certbot 将打印以下消息:

输出
IMPORTANT NOTES:
 - 恭喜!你的证书和证书链已保存到
   /etc/letsencrypt/live/example.com/fullchain.pem。你的证书将于
   2019-01-17 过期。如果将来需要获取此证书的新版本或调整后的版本,
   只需再次运行 certbot。要以非交互方式续期*所有*证书,
   请运行 "certbot renew"。
 - 如果你丢失了账户凭据,可以通过发送到
   admin@example.com 的电子邮件找回。
 - 你的账户凭据已保存在 Certbot 配置目录
   /etc/letsencrypt 中。你现在应该对此文件夹进行安全备份。
   此配置目录还将包含 Certbot 获取的证书和私钥,
   因此定期备份此文件夹是理想做法。
 - 如果你喜欢 Certbot,请考虑通过以下方式支持我们的工作:

   向 ISRG / Let's Encrypt 捐款:   https://letsencrypt.org/donate
   向 EFF 捐款:                    https://eff.org/donate-le

现在你已经拥有证书文件,请按如下方式编辑你的域名虚拟主机配置:

/etc/apache2/sites-available/example.com.confapache
<VirtualHost *:80> 
  ServerName example.com
  ServerAlias www.example.com

  Redirect permanent / https://example.com/
</VirtualHost>

<VirtualHost *:443>
  ServerName example.com
  ServerAlias www.example.com

  Protocols h2 http/1.1

  <If "%{HTTP_HOST} == 'www.example.com'">
    Redirect permanent / https://example.com/
  </If>

  DocumentRoot /var/www/example.com/public_html
  ErrorLog ${APACHE_LOG_DIR}/example.com-error.log
  CustomLog ${APACHE_LOG_DIR}/example.com-access.log combined

  SSLEngine On
  SSLCertificateFile /etc/letsencrypt/live/example.com/fullchain.pem
  SSLCertificateKeyFile /etc/letsencrypt/live/example.com/privkey.pem

  # 其他 Apache 配置

</VirtualHost>

使用上述配置,我们强制启用 HTTPS,并将 www 版本重定向到非 www 版本。你可以根据自己的需要随意调整配置。

重新加载 Apache 服务以使更改生效:

终端
sudo systemctl reload apache2

使用 https:// 打开你的网站,你会看到一个绿色锁图标。

如果你使用 SSL Labs Server Test 测试你的域名,你将获得 A+ 评级,如下所示:

SSLLABS 测试

自动续期 Let’s Encrypt SSL 证书

Let’s Encrypt 的证书有效期为 90 天。为了在证书过期前自动续期,certbot 软件包会创建一个每天运行两次的 cronjob,并会在任何证书过期前 30 天自动续期。

证书续期后,我们还需要重新加载 Apache 服务。将 --renew-hook "systemctl reload apache2" 追加到 /etc/cron.d/certbot 文件中,使其看起来如下所示:

/etc/cron.d/certbotsh
0 */12 * * * root test -x /usr/bin/certbot -a \! -d /run/systemd/system && perl -e 'sleep int(rand(3600))' && certbot -q renew --renew-hook "systemctl reload apache2"

要测试续期过程,请使用 certbot 的 --dry-run 开关:

终端
sudo certbot renew --dry-run

如果没有错误,则表示续期过程成功。