Let's Encrypt于2018年3月14日在社区宣布支持通配符证书(Wildcard certificates)。

通配符证书可以使同一域名下的所有子域名使用同一个证书,对于拥有大量域名的用户来说,大大减少了证书申请和维护工作。下面简要介绍Let's Encrypt通配符证书的申请方法。

证书申请

Let's Encrypt使用ACME协议验证域名所有权并分配证书,为申请证书首先需要选取实现ACME协议的客户端。

Let's Encrypt证书申请时,需要验证域名的所有权,官方支持三种验证方式:

  • http-01: 在域名对应的 Web 服务器下放置一个 HTTP well-known URL 资源文件。
  • tls-sni-01: 在域名对应的 Web 服务器下放置一个 HTTPS well-known URL 资源文件。
  • dns-01: 给域名添加一个 DNS TXT 记录。

申请Let's Encrypt通配符证书需要注意的事情如下:

  • 必须使用dns-01验证方法。
  • 必须使用支持ACME v2版本的客户端。
  • 需要指定server路径: https://acme-v02.api.letsencrypt.org/directory
  • *.example.com不包含example.com,需分别申请。
  • *.example.com和www.example.com 不可同时申请,因为前者已包含后者。

官方给出了支持ACME v2的客户端列表,本文选取官方推荐的客户端Certbot,并使用Docker环境申请证书。

假设证书在本地的存放位置为letsencrypt文件夹,日志存放位置为log文件夹,执行如下命令申请证书:

$ docker run -it --rm \
  -v path/to/letsencrypt/:/etc/letsencrypt/  \
  -v path/to/log/:/var/log/letsencrypt/ \
  certbot/certbot:v0.26.1 \
    certonly \
   --email your@email.com \
   --agree-tos \
   --manual \
   --preferred-challenges dns-01 \
   --server https://acme-v02.api.letsencrypt.org/directory \
   -d *.yourdomain.com \
   -d yourdomain.com

替换其中的邮件和域名,运行后根据提示为域名添加DNS TXT记录,以验证域名所有权。生成的证书存放在本地letsencrypt文件夹中。

证书使用

申请的证书保存在letsencrypt/live/youdomain.com文件夹下,其中四个文件的说明如下:

  • privkey.pem : 证书私钥。
  • fullchain.pem: 大多数服务器使用的证书文件。
  • chain.pem : 用于OCSP stapling(Nginx >=1.3.7)。
  • cert.pem : 在进一步阅读相关文档前不要使用。

以Nginx服务器为例,在其配置文件中添加如下配置:

ssl on;
ssl_certificate path/to/letsencrypt/live/yourdomain.com/fullchain.pem;
ssl_certificate_key path/to/letsencrypt/live/yourdomain.com/privkey.pem;

证书更新

证书的有效期为90天,在到期前需要手动进行更新,Certbot中可使用renew对申请的证书进行更新,可执行命令如下:

$ docker run -it --rm \
  -v path/to/letsencrypt/:/etc/letsencrypt/  \
  -v path/to/log/:/var/log/letsencrypt/ \
  certbot/certbot:v0.26.1 \
    renew

当证书有效期小于30天时,该命令会对证书进行更新。为防止手动更新的麻烦,可创建脚本文件certbotrenew.sh如下:

#!/bin/bash
$ docker run -it --rm \
  -v path/to/letsencrypt/:/etc/letsencrypt/  \
  -v path/to/log/:/var/log/letsencrypt/ \
  certbot/certbot:v0.26.1 \
    renew

若使用的服务器为Nginx,在证书更新完成后,服务器不会自动加载证书,需要重启服务器。可创建crontab计划任务,定期执行脚本检查证书,若证书更新后(通过文件修改时间判断)自动重启服务器。脚本文件(checkservice.sh)如下:

#!/bin/bash
timestamp=`date`
echo $timestamp "====renew certbot====" >> path/to/renew.log
path/to/certbotrenew.sh
modifytime=`stat -c %Y path/to/letsencrypt/live/datarepo.cn/fullchain.pem`
nowtime=`date +%s`
if [ $[ $nowtime-$modifytime ] -lt 1800 ]; then
  echo $timestamp "====restart nginx====" >> path/to/renew.log
  path/to/restartnginx.sh
else
  echo $timestamp "====no need to restart====" >> path/to/renew.log

其中restartnginx.sh为重启Nginx服务器的命令。

创建crontab计划任务,每周五0点0分执行checkservice.sh。

0 0 * * 5 path/to/checkservice.sh