申请 Let'sEncrypt 证书


通过促进 HTTPS 的广泛采用,来创建一个更加安全和尊重隐私的 Web 环境。

为了在您的网站上启用 HTTPS 协议,您需要从证书颁发机构(CA)那里获取证书,而 Let's Encrypt 就是一个 CA 证书的颁发机构。想要从 Let's Encrypt 获取您网站域名的证书,您必须证明您对域名的实际控制权。即如果你通过新网购买的域名,就可以在新网的管理界面看到你自己购买的域名,您可以在您的 Web 主机上运行使用 ACME 协议的软件来获取 Let's Encrypt 证书。

为了找出最适合您获取证书的方法,您需要知道您是否拥有服务器的命令行访问权限,即称为 SSH 访问权限。如果您仅使用控制面板管理您的网站,您很有可能没有命令行访问权限,您可以联系您的托管服务提供商确认。

Let's Encrypt 是一个于 2015 年推出的数字证书认证机构,将通过旨在消除当前手动创建和安装证书的复杂过程的自动化流程,为安全网站提供免费的 SSL/TLS 证书。这是由 互联网安全研究小组 这一个公益组织提供的服务,主要赞助商包括 电子前哨基金会Mozilla 基金会Akamai 以及 Cisco 等公司。

20156 月,Let's Encrypt 得到了一个存储在硬件安全模块中的离线的 RSA 根证书。这个由 IdenTrust 证书签发机构交叉签名的根证书被用于签署两个证书。其中一个就是用于签发请求的证书,另一个则是保存在本地的证书,这个证书用于在上一个证书出问题时作备份证书之用。因为 IdenTrustCA 根证书目前已被预置于主流浏览器中,所以 Let's Encrypt 签发的证书可以从项目开始就被识别并接受,甚至当用户的浏览器中没有信任 ISRG 的根证书时也可以。

申请Let'sEncrypt证书


1. 运作方式

域名认证 + 证书颁发和吊销

Let's EncryptACME 协议的目标是使配置能够自动获取受信任浏览器的证书的 HTTPS 服务器成为可能。这是通过在 Web 服务器上运行证书管理软件(Agent)来达成的。为了理解该技术的工作原理,让我们来看一下使用支持 Let's Encrypt 的证书管理软件来配置 https://example.com/ 的流程。

该认证流程分为两步。首先,管理软件向证书颁发机构证明该服务器拥有域名的控制权。之后,该管理软件就可以向 Let's Encrypt 申请、续期或吊销该域名的证书。

  • [1] 域名认证

Let's Encrypt 通过公钥识别服务器管理员。证书管理软件首次与 Let's Encrypt 交互时,会生成新的密钥对,并向 Let's Encrypt CA 证明服务器控制着一个或多个域名。这类似于创建帐户和向该帐户添加域名的传统证书颁发流程。

为了启动该过程,证书管理软件向 Let's Encrypt CA 询问它需要做什么才能证明它控制 example.com 这个域名。Let's Encrypt CA 将查看所请求的域名并发出一组或多组验证请求,这些验证请求就是管理软件可以用于证明对域名的控制权的不同方式。例如,CA 可能会让证书管理软件(Agent)选择: *example.com 下配置 DNS 记录,或者 *https://example.com/ 的已知 URI 下放置一个 HTTP 资源。

除了验证请求之外,Let's Encrypt CA 还会提供一个 nonce(一次性数字)要求证书管理软件使用私钥对它签名,以证明其对密钥对的控制权。

申请Let'sEncrypt证书

证书管理软件需要完成其中一项提供的验证请求,来证明自己的合法性。假设它能够完成上面的第二个任务:它在 https://example.com 站点的指定路径上创建了一个文件。证书管理软件还使用其私钥对提供的 nonce(一次性数字)进行签名。完成这些步骤后,证书管理软件会通知 CA 它已准备好完成验证。

然后,CA 的工作就是检查验证是否已经完成。CA 会验证 nonce 上的签名,并尝试从 Web 服务器下载该文件,并确保其具有 CA 需要的内容。

申请Let'sEncrypt证书

如果 nonce 上的签名有效,并且验证也成功完成,那么由公钥代表的证书管理软件将被授权对 example.com 进行证书管理。 我们将证书管理软件使用的密钥对称为 example.com授权密钥对

  • [2] 证书颁发和吊销

一旦代理拥有了授权公私钥,那么请求、续期和撤销证书就会变得很简单——只需发送证书管理消息并使用授权私钥对其进行签名。

为了获得该域名的证书,证书管理软件将创建一个 PKCS#10 证书签名请求(CSR),要求 Let's Encrypt CA 为指定的公钥颁发 example.com 的证书。通常,CSR 中包含与 CSR 中的公钥对应的私钥的签名。证书管理软件还使用 example.com 的授权私钥签署整个 CSR,以便 Let's Encrypt CA 知道它已获得授权。

Let's Encrypt CA 收到用户端的请求时,它会验证这两个签名。如果一切都正常的话,CA 将为 CSR 中的公钥颁发 example.com 的证书,并将文件发送回证书管理软件。

申请Let'sEncrypt证书

申请吊销证书的流程类似。证书管理软件使用 example.com 的授权私钥签署一个吊销请求,Let's Encrypt CA 将验证该请求是否已被授权。如果已授权,则将吊销信息发布到正常的吊销通道(即 OCSP)中,以便浏览器等依赖方知道他们不应该接受这个已被吊销的证书。

申请Let'sEncrypt证书


2. 工具选择 - Certbot

推荐使用 Certbot 客户端

Let's Encrypt 使用 ACME 协议来验证您对给定域名的控制权并向您颁发证书。要获得 Let's Encrypt 证书,您需要选择一个要使用的 ACME 客户端软件。我建议大多数人从 Certbot 客户端开始。 它既可以仅为您获取证书,也可以帮助您安装证书。它易于使用,适用于许多操作系统,并且具有出色的文档。

如果 Certbot 不能满足您的需求,或者您只是想尝试其他软件,那么下面有更多的客户端可供选择,这些客户端按照编写所用的语言或是使用环境。


3. 认证方式与速率限制

Let's Encrypt的认证方式有以下三种

申请证书要解决的一个关键问题就是,如何证明域名是你所拥有的?Let's Encrypt 提供了三种模式:HTTPDNSTLS-SNIHTTP 模式和 DNS 模式各有优劣,适用于不同的场景。HTTP 模式不需要操作 DNS 记录,只需要新建一个文件就可以完成验证,带来的限制就是验证过程必须操作服务器;DNS 模式不需要操作服务器,只需添加 DNSTXT 记录就行,缺点是必须登录到域名提供商的页面上修改 DNS 记录。不管是 HTTP 模式还是 DNS 模式,申请证书的操作都是可以在任意电脑上完成,申请完之后再将证书复制到服务器上。HTTP 模式验证过程需要操作服务器,DNS 模式验证过程需要操作 DNS

  • [1] HTTP 模式 - 主机可以开放 80 或 443 端口的选择
    • 常用于匹配单个域名 - 比如 www.escapelife.site
    • 就是 Let's Encrypt 给你一个随机字符串,你需要在 Web 服务器的 /.well-known/acme-challenge/ 服务路径下放置一个以该字符串命名的文件,当 Let's Encrypt 能够访问到这个文件时,证明你是这个域名的所有者。
  • [2] DNS 模式 - 主机无法访问 80 或 443 端口时的选择
    • 常用于匹配多个域名 - 比如 *.escapelife.site
    • 同样是 Let's Encrypt 给你一个随机字符串,你需要以该字符串建立一个 DNSTXT 记录,当 Let's Encrypt 查询域名的 TXT 记录时,发现得到的字符串一致,则证明你是这个域名的所有者。
  • [3] TLS-SNI 模式 - (基本废弃)
    • 没有仔细研究过,似乎通过 SSL 加密传输。http 走的是 80 端口,tls-sni 走的是 443 端口。由于当前的 tls-sni 似乎有漏洞,该模式一度遭禁用,所以不推荐采用此模式,本文也不加以讨论。
  • [4] 购买域名证书
    • 当然,这里我们也可以不使用免费的证书,而是使用自己购买的域名证书。
    • 其配置就更为简单了,只需要下载对应证书存放到指定目录下,配置对应参数即可。
server {
    ssl_certificate            "/etc/ssl/certs/escapelife_site-ssl-bundle.crt";
    ssl_trusted_certificate    "/etc/ssl/certs/escapelife_site-trusted.crt";
    ssl_certificate_key        "/etc/ssl/private/STAR_escapelife_site.key";
    ......
}

Let's Encrypt虽然可以免费申请,但是有如下限制

  • 每个注册域名允许颁发的证书数量限制为每周 30000
  • 重复证书限制为每周 30000
  • 每小时允许 60 次验证失败
  • 每个 IP 地址注册账户数量限制为每个 IP3 小时允许注册 50 个账户
  • 对于 ACME v2,新订单限制为每个帐户每 3 小时 1500

4. 申请证书 - 直接申请 - 默认(HTTP)

就是通过域名解析之后的对应 IP 地址的服务器,来直接申请证书。

在我们自己的博客上线之前,最好能够给我们的网站加上 HTTPS 的,一方面是为了安全,再就是为了显示有逼格。如果我们使用像 Cloudflare 这样的服务提供商,直接在其后台配置即可添加。如果是使用 Nginx 等服务器来运行自己的网站,推荐大家最好使用 Certbot 工具,其可以自动化来配置 SSL 证书和定时更新。如果我们是在域名解析的那个服务器配置 HTTPS 的话,配置证书的过程大约需要 5 分钟左右。

  1. 打开 https://certbot.eff.org 网页
  2. 按照机器人下方的提示,选择对应的 Web 服务软件和对应操作系统版本
  3. 然后,按照页面跳转之后的教程一步步操作,完成基本的配置即可

申请Let'sEncrypt证书

申请Let'sEncrypt证书

申请Let'sEncrypt证书

使用 Certbot 工具,其会自动检查到你的 nginx.conf 下的配置,把你所有的虚拟站点都列出来然后让你选择需要开启 https 的站点。简单的输入列表编号,用空格分隔符分开,然后使用 Certbot 工具就帮你下载证书并更新 nginx.conf 了。我们再次打开 nginx.conf 文件,发现文件中的 server 配置中添加了证书以及做了 301 的永久重定向。

这里建议配置为 HTTP2 协议,HTTP2 具有更快的 HTTPS 传输性能,非常值得开启。同时需要注意的是,Let's Encrypt 的证书有效期为 90 天,过期的话可以再次续签。

listen 443 ssl http2;
ssl_certificate /etc/letsencrypt/live/escapelife.site/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/escapelife.site/privkey.pem;
include /etc/letsencrypt/options-ssl-nginx.conf;

# Redirect non-https traffic to https
if ($scheme != "https") {
    return 301 https://$host$request_uri;
}
  • [1] 整体流程
    • 在新版本中,安装 Certbot 工具已经使用 snapd 方式了
    • https://certbot.eff.org/lets-encrypt/ubuntubionic-nginx
# 1.安装snapd工具
$ sudo sudo apt update
$ sudo apt install snapd
$ sudo snap install core; sudo snap refresh core
$ sudo apt-get remove certbot

# 2.安装Certbot工具
$ sudo snap install --classic certbot
$ sudo ln -s /snap/bin/certbot /usr/bin/certbot

# 3.获取证书
$ sudo certbot --nginx  # 获取证书并自动配置Nginx服务
$ sudo certbot certonly --nginx  # 仅仅获取证书后续需自行配置
$ sudo certbot --nginx -d example.com -d www.example.com  # 指定获取证书的域名

# 3.获取证书
# 如果apt老版本可以不能使用--nginx参数
$ sudo certbot
$ sudo certbot certonly
$ sudo certbot -d example.com -d www.example.com
$ sudo certbot certonly -d example.com -d www.example.com

# 4.测试证书自动更新
$ sudo certbot renew --dry-run

# 5.证书到期前自动更新 - crontab
# 配置位置: /etc/crontab/ or /etc/cron.*/* or systemctl list-timers
0 0 * * *    /usr/bin/certbot renew --force-renewal
0 1 * * *    /usr/sbin/service nginx restart

# 6. 确认配置成功
访问你的网站地址,然后查看是否已经添加上了HTTPS的标识了。
  • [2] certbot (–nginx)
    • 这里主要介绍,具体的获取证书的过程(blog.escapelife.site)。
    • 可能你在配置和执行的过程中会提示不同的信息,但是大致流程都是一致的。
# 1.获取证书并自动配置Nginx服务
# ------------------------------------
[root@localhost ~]# certbot --nginx
Saving debug log to /var/log/letsencrypt/letsencrypt.log
Plugins selected: Authenticator nginx, Installer nginx
Enter email address (used for urgent renewal and security notices) (Enter 'c' to
cancel): [email protected] # 输入邮箱地址
Starting new HTTPS connection (1): acme-v02.api.letsencrypt.org

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
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 # 同意并接受

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
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: y # 是否需要接受邮件通知
Starting new HTTPS connection (1): supporters.eff.org
No names were found in your configuration files. Please enter in your domain
name(s) (comma and/or space separated)  (Enter 'c' to cancel): blog.escapelife.site # 输入域名地址
Obtaining a new certificate
Performing the following challenges:
http-01 challenge for blog.escapelife.site
Waiting for verification...
Cleaning up challenges
Resetting dropped connection: acme-v02.api.letsencrypt.org
Deploying Certificate to VirtualHost /etc/nginx/nginx.conf

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): 2  # 选择重定向模式
Redirecting all traffic on port 80 to ssl in /etc/nginx/nginx.conf

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Congratulations! You have successfully enabled https://blog.escapelife.site

You should test your configuration at:
https://www.ssllabs.com/ssltest/analyze.html?d=blog.escapelife.site
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

IMPORTANT NOTES:
 - Congratulations! Your certificate and chain have been saved at:
   /etc/letsencrypt/live/bohr.escapelife.site/fullchain.pem
   Your key file has been saved at:
   /etc/letsencrypt/live/bohr.escapelife.site/privkey.pem
   Your cert will expire on 2019-07-25. To obtain a new or tweaked
   version of this certificate in the future, simply run certbot again
   with the "certonly" option. To non-interactively renew *all* of
   your certificates, run "certbot renew"
 - Your account credentials have been saved in your Certbot
   configuration directory at /etc/letsencrypt. You should make a
   secure backup of this folder now. This configuration directory will
   also contain certificates and private keys obtained by Certbot so
   making regular backups of this folder is ideal.
 - If you like Certbot, please consider supporting our work by:

   Donating to ISRG / Let's Encrypt:   https://letsencrypt.org/donate
   Donating to EFF:                    https://eff.org/donate-le
  • [3] certbot certonly (–nginx)
# 正式申请操作
$ sudo certbot certonly --nginx -d blog.escapelife.site
Saving debug log to /var/log/letsencrypt/letsencrypt.log

How would you like to authenticate with the ACME CA?
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1: Spin up a temporary webserver (standalone) # 启动一个临时的网络服务器
2: Place files in webroot directory (webroot) # 将文件放在webroot目录中
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Select the appropriate number [1-2] then [enter] (press 'c' to cancel): 2
Plugins selected: Authenticator webroot, Installer None
Cert not yet due for renewal

You have an existing certificate that has exactly the same domains or certificate name you requested and is not close to expiry.
(ref: /etc/letsencrypt/renewal/blog.escapelife.site.conf)

What would you like to do?
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1: Keep the existing certificate for now
2: Renew & replace the cert (limit ~5 per 7 days)
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Select the appropriate number [1-2] then [enter] (press 'c' to cancel): /var/www/html
......

# 应该也可以直接在命令给对应选项
$ sudo certbot certonly -a manual -i nginx -d blog.escapelife.site
$ sudo certbot certonly -a webroot -i nginx -w /var/www/html -d blog.escapelife.site

5. 申请证书 - DNS 认证 - 通配符(DNS)

就是通过 DNS 的方式来认证对该域名的合法性,从而申请证书。

我们在使用 letsencrypt 获取免费的 HTTPS 证书的时候,letsencrypt 需要对域名进行验证。默认情况下它的验证方式是, certbot 工具在 web 目录的根目录下放置一个文件,然后 letsencrypt 的服务器通过域名来访问这个文件,来验证你申请的域名是属于你的。

  • 有时候我们想为内网的某台主机设置 HTTPS 加密,因为内网的主机无法被 letsencrypt 的服务器访问到,所以运行 sudo certbot certonly --nginx 命令生成证书的时候就会出现 Connection refused 的情况。

  • 还有就是,一般情况下国内的网络运营商都会屏蔽掉 80443 这两个端口,所以大部分教程中的方法都会失效。

为了解决上述问题,我们可以更改验证方式,通过校验域名的 TXT 记录来验证你申请的域名是属于你的,从而获取证书。

  • [1] 安装基础工具
# 查看域名提供商是否支持自动续约(API)
# https://eff-certbot.readthedocs.io/en/stable/using.html#dns-plugins
certbot-dns-cloudflare
certbot-dns-cloudxns
certbot-dns-digitalocean

# 不支持的话,就只能手动自己加或者写脚本
# https://eff-certbot.readthedocs.io/en/stable/using.html#manual

# 安装snapd和certbot工具
$ sudo sudo apt update
$ sudo apt install snapd
$ sudo snap install core; sudo snap refresh core
$ sudo apt-get remove certbot
$ sudo ln -s /snap/bin/certbot /usr/bin/certbot

# 确保g工具和插件可信
$ sudo snap set certbot trust-plugin-with-root=ok
# 下载对应插件(DNS-Provider)
# sudo snap install certbot-dns-<PLUGIN>
$ sudo snap install certbot-dns-cloudflare

# 获取域名服务商信息
dns_cloudflare_email = [email protected]
dns_cloudflare_api_key = 0123456789abcdef0123456789abcdef01234
dns_cloudflare_api_token = 0123456789abcdef0123456789abcdef01234567

# 需要设置DNS凭证
# 通过点击文档列表中的DNS插件名称来查找您的DNS提供商的凭证说明
$ certbot certonly \
  --dns-cloudflare \
  --dns-cloudflare-credentials ~/.secrets/certbot/cloudflare.ini \
  --dns-cloudflare-propagation-seconds 60 \
  -d blog.escapelife.site \
  -d *.blog.escapelife.site

# 测试证书自动更新
$ sudo certbot renew --dry-run

# 证书到期前自动更新 - crontab
# 配置位置: /etc/crontab/ or /etc/cron.*/* or systemctl list-timers
0 0 * * *    /usr/bin/certbot renew --force-renewal
0 1 * * *    /usr/sbin/service nginx restart

# 确认配置成功
访问你的网站地址,然后查看是否已经添加上了HTTPS的标识了。
  • [3] 域名提供商不支持该工具
# 命令行的方式获取证书
$ sudo certbot certonly --manual \
    --preferred-challenges=dns \
    --email [email protected] \
    --server https://acme-v02.api.letsencrypt.org/directory \
    -d *.blog.escapelife.site -d blog.escapelife.site

# 上面命令的输出交互式信息
# 进行DNS认证时,在输出KEY的时候需要修改DNS的TXT记录,完成之后点击回车即可
# 解析类型为: TXT
# 主机记录为: _acme-challenge.blog.escapelife.site
# 记录值则为: 74H12USt......2345g6888
Saving debug log to /var/log/letsencrypt/letsencrypt.log
Plugins selected: Authenticator manual, Installer None
Starting new HTTPS connection (1): acme-v02.api.letsencrypt.org
Obtaining a new certificate
Performing the following challenges:
dns-01 challenge for blog.escapelife.site

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
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: y

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Please deploy a DNS TXT record under the name
_acme-challenge.blog.escapelife.site with the following value:

74H12USt......2345g6888

Before continuing, verify the record is deployed.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Press Enter to Continue
Waiting for verification...
Resetting dropped connection: acme-v02.api.letsencrypt.org
Cleaning up challenges

IMPORTANT NOTES:
 - Congratulations! Your certificate and chain have been saved at:
   /etc/letsencrypt/live/blog.escapelife.site/fullchain.pem
   Your key file has been saved at:
   /etc/letsencrypt/live/blog.escapelife.site/privkey.pem
   Your cert will expire on 2020-05-18. To obtain a new or tweaked
   version of this certificate in the future, simply run certbot
   again. To non-interactively renew *all* of your certificates, run
   "certbot renew"
 - If you like Certbot, please consider supporting our work by:

   Donating to ISRG / Let's Encrypt:   https://letsencrypt.org/donate
   Donating to EFF:                    https://eff.org/donate-le
# 执行完成之后会在如下目录下得到对应证书
[root@localhost ~]# ll /etc/letsencrypt/live/
drwxr-xr-x 2 root root  93 Feb 18 23:02 blog.escapelife.site
-rw-r--r-- 1 root root 740 Feb 18 23:02 README

# 证书会被存储到如下配置
[root@localhost ~]# ll /etc/letsencrypt/live/blog.escapelife.site/
lrwxrwxrwx 1 root root  38 Feb 18 23:02 cert.pem -> ../../archive/blog.escapelife.site/cert1.pem
lrwxrwxrwx 1 root root  39 Feb 18 23:02 chain.pem -> ../../archive/blog.escapelife.site/chain1.pem
lrwxrwxrwx 1 root root  43 Feb 18 23:02 fullchain.pem -> ../../archive/blog.escapelife.site/fullchain1.pem
lrwxrwxrwx 1 root root  41 Feb 18 23:02 privkey.pem -> ../../archive/blog.escapelife.site/privkey1.pem
-rw-r--r-- 1 root root 692 Feb 18 23:02 README

# 得到上述信息,则表示证书已经生成了
# 我们现在需要做的就是,等待DNS解析成功,然后配置Nginx配置即可
$ dig -t TXT _acme-challenge.blog.escapelife.site
; <<>> DiG 9.9.4-RedHat-9.9.4-50.el7 <<>> -t TXT _acme-challenge.blog.escapelife.site
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 61108
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 512
;; QUESTION SECTION:
;_acme-challenge.blog.escapelife.site. IN TXT

;; ANSWER SECTION:
_acme-challenge.blog.escapelife.site.  299 IN TXT  "74H12USt......2345g6888"

;; Query time: 98 msec
;; SERVER: 8.8.8.8#53(8.8.8.8)
;; WHEN: Tue Feb 18 23:10:39 CST 2020
;; MSG SIZE  rcvd: 115
# 当然,还可以使用docker申请letsencrypt证书的好处就是不需要在宿主机上安装依赖
# 用docker申请letsencrypt通配符证书
docker run -it --rm \
    --name certbot \
    -v /mnt/letsencrypt:/etc/letsencrypt \
    -v /mnt/bak/letsencrypt:/var/lib/letsencrypt \
    certbot/certbot \
    certonly --manual --agree-tos \
    --server https://acme-v02.api.letsencrypt.org/directory \
    --preferred-challenges dns \
    -d *.blog.escapelife.site -d blog.escapelife.site

# -v: 挂载目录; certbot申请到的或备份的证书会放在这两个目录
# --manual: 交互模式
# --agree-tos: 同意服务协议
# --server: 指定使用acmev2协议的服务器地址; 因为通配符证书的申请需要这个协议
# -–preferred-challenges: 使用dns检验来证明你拥有这个域名
# -d: 指定了需要申请证书的通配符域名,根域名要额外再写一次

6. 配置文件 - nginx.conf

展示配置 HTTPS 的 Nginx 配置文件: nginx.conf

  • 我们这里配置的是单个子域名的形式 - blog.escapelife.site
  • 如果我们需要泛域名解析的话,在配置 certbot 的时候选择 wildcard * 进行配置。
  • 然后,申请、使用、配置证书的时候都是用泛域名的形式,即可。
# Generated by nginxconfig.io
# https://www.digitalocean.com/community/tools/nginx#?0.redirect=false&0.http2=false&0.hsts=false&0.php=false&0.root=false&gzip=false&file_structure=unified

user www-data;
pid /run/nginx.pid;
worker_processes auto;
worker_rlimit_nofile 65535;

events {
  multi_accept on;
  worker_connections 65535;
}

http {
  charset utf-8;
  sendfile on;
  tcp_nopush on;
  tcp_nodelay on;
  server_tokens off;
  log_not_found off;
  types_hash_max_size 2048;
  client_max_body_size 16M;

  # MIME
  include mime.types;
  default_type application/octet-stream;

  # logging
  access_log /var/log/nginx/access.log;
  error_log /var/log/nginx/error.log warn;

  # SSL
  ssl_session_timeout 1d;
  ssl_session_cache shared:SSL:10m;
  ssl_session_tickets off;

  # Diffie-Hellman parameter for DHE ciphersuites
  ssl_dhparam /etc/nginx/dhparam.pem;

  # Mozilla Intermediate configuration
  ssl_protocols TLSv1.2 TLSv1.3;
  ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;

  # OCSP Stapling
  ssl_stapling on;
  ssl_stapling_verify on;
  resolver 1.1.1.1 1.0.0.1 8.8.8.8 8.8.4.4 208.67.222.222 208.67.220.220 valid=60s;
  resolver_timeout 2s;

  # load configs
  include /etc/nginx/conf.d/*.conf;

  # blog.escapelife.site
  server {
    listen 443 ssl;
    listen [::]:443 ssl;

    server_name blog.escapelife.site;

    # SSL
    ssl_certificate /etc/letsencrypt/live/blog.escapelife.site/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/blog.escapelife.site/privkey.pem; # managed by Certbot
    ssl_trusted_certificate /etc/letsencrypt/live/blog.escapelife.site/chain.pem;

    include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot

    # security headers
    add_header X-Frame-Options "SAMEORIGIN" always;
    add_header X-XSS-Protection "1; mode=block" always;
    add_header X-Content-Type-Options "nosniff" always;
    add_header Referrer-Policy "no-referrer-when-downgrade" always;
    add_header Content-Security-Policy "default-src 'self' http: https: data: blob: 'unsafe-inline'" always;

    # . files
    location ~ /\.(?!well-known) {
      deny all;
    }

    # favicon.ico
    location = /favicon.ico {
      log_not_found off;
      access_log off;
    }

    # robots.txt
    location = /robots.txt {
      log_not_found off;
      access_log off;
    }
  }

  # HTTP redirect
  server {
    listen 80;
    listen [::]:80;

    server_name blog.escapelife.site;

    # ACME-challenge
    # 随便丁一个目录就行了,默认在/var/www/letsencrypt下面
    location ^~ /.well-known/acme-challenge/ {
      root /var/www/letsencrypt;
    }

    location / {
      return 301 https://blog.escapelife.site$request_uri;
    }
  }
}

7. 常见问题

记录使用过程中遇到的问题,以及对应的解决方法!

  • [1] 提示缺少 Nginx 的插件依赖
$ sudo certbot --nginx
Saving debug log to /var/log/letsencrypt/letsencrypt.log
The nginx plugin is not working; there may be problems with your existing configuration.
The error was: NoInstallationError("Could not find a usable 'nginx' binary. Ensure nginx exists, the binary is executable, and your PATH is set correctly.")

$ sudo cat /var/log/letsencrypt/letsencrypt.log
2022-07-01 09:45:15,186:DEBUG:certbot._internal.plugins.selection:Requested authenticator nginx and installer nginx
2022-07-01 09:45:15,189:DEBUG:certbot._internal.plugins.disco:No installation (PluginEntryPoint#nginx): Could not find a usable 'nginx' binary. Ensure nginx exists, the binary is executable, and your PATH is set correctly.
Traceback (most recent call last):
  File "/snap/certbot/2133/lib/python3.8/site-packages/certbot/_internal/plugins/disco.py", line 160, in prepare
    self._initialized.prepare()
  File "/snap/certbot/2133/lib/python3.8/site-packages/certbot_nginx/_internal/configurator.py", line 194, in prepare
    raise errors.NoInstallationError(
certbot.errors.NoInstallationError: Could not find a usable 'nginx' binary. Ensure nginx exists, the binary is executable, and your PATH is set correctly.
2022-07-01 09:45:15,192:DEBUG:certbot._internal.plugins.selection:No candidate plugin
# 有部分环境可能没法找到对应包
# 此时可以不带 --nginx 参数,进行尝试(其实效果基本一样的)
$ sudo apt install certbot python3-certbot-nginx

8. 参考文档

授人玫瑰,手有余香!


文章作者: Escape
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 Escape !
  目录