使用 Certbot 为网站签发永久免费的 HTTPS 证书

我们常常在自己的服务器上搭建 Web 服务,但是大部分都使用的 HTTP 协议。在一些特殊的场景下,例如:微信小程序或是 APP 后台服务开发,则必须使用 HTTPS 协议。众所周知,HTTPS 可以在各个云服务厂商上购买,通过都需要高昂的费用,往往劝退很多初级的个人开发者。

但是如果你使用 Nginx、Apache 等服务器来运行服务,则可以使用 Certbot 来申请免费的 SSL 证书,轻松帮你实现 HTTPS 网站。申请 Let’s Encrypt 证书不但免费,还非常简单,虽然每次只有 90 天的有效期,但可以通过脚本定期更新,配好之后一劳永逸。

Let’s Encrypt 是由互联网安全研究小组(ISRG,一个公益组织)提供的服务,主要赞助商包括电子前哨基金会,Mozilla基金会,Akamai以及思科。

ISRG于2015年4月9日与Linux基金会宣布合作。

Let’s Encrypt 最初是由 Mozilla 的两名员工于2012年发起,2015年12月3日开启公测,2016年4月12日,该项目正式对外使用。

本文将记录 Centos 7.4 + Nginx + Certbot 为 blog.frankfeekr.cn 网站安装安全的 HTTPS 证书,并且实现到期自动续期。

1. 安装 Certbot

1
2
yum install epel-release -y
yum install certbot -y

2. 申请证书

这里证书可以申请单域名或是泛域名证书。这里推荐大家申请泛域名证书申请,例如:*.frankfeekr.cn 域名证书申请后,即可用于该域名下的三级域名。即:blog.frankfeekr.cn / docs.frankfeekr.cn 等等三级域名都可以使用。

  • 安装 python-certbot-nginx 插件

在生成证书的过程需要确保 Nginx 关闭,需要使用 80 端口执行。

在申请证书前需要先安装 certbot 的 Nginx 插件,如果执行 certbot --nginx 出现 The requested nginx plugin does not appear to be installed,则需要先安装插件。

1
yum install python-certbot-nginx -y

(1)单域名证书

执行命令

1
certbot certonly -d blog.frankfeekr.cn --nginx

执行结果

1
2
3
4
5
6
7
8
9
10
11
12
13
IMPORTANT NOTES:
- Congratulations! Your certificate and chain have been saved at:
/etc/letsencrypt/live/blog.frankfeekr.cn/fullchain.pem
Your key file has been saved at:
/etc/letsencrypt/live/blog.frankfeekr.cn/privkey.pem
Your certificate will expire on 2021-06-26. 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

生成的证书会放在:/etc/letsencrypt/live/blog.frankfeekr.cn 目录下,目录证书说明如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
This directory contains your keys and certificates.

`[cert name]/privkey.pem` : the private key for your certificate.
`[cert name]/fullchain.pem`: the certificate file used in most server software.
`[cert name]/chain.pem` : used for OCSP stapling in Nginx >=1.3.7.
`[cert name]/cert.pem` : will break many server configurations, and should not be used
without reading further documentation (see link below).

WARNING: DO NOT MOVE OR RENAME THESE FILES!
Certbot expects these files to remain in this location in order
to function properly!

We recommend not moving these files. For more information, see the Certbot
User Guide at https://certbot.eff.org/docs/using.html#where-are-my-certificates.

(2)泛域名证书(推荐)

上面我们学会了生成单个域名证书,但是这里更推荐大家申请泛域名证书,方便在多个网站服务托管的时候共同使用。

执行命令

1
certbot certonly --preferred-challenges dns --manual -d *.frankfeekr.cn --server https://acme-v02.api.letsencrypt.org/directory

image-20210328171038158

上面的命令执行到这里,会在命令行阻塞,这时候我们需要到域名解析的服务商添加一条 txt 的解析,如下图所示。

image-20210328170744447

添加完解析后稍等几秒钟,即可回车继续,这时候就会校验记录是否有效。

image-20210328171113452

至此:已经完成了泛域名的生成,生成的证书在:/etc/letsencrypt/live 目录下。相比于单域名的证书,泛域名步骤会稍微复杂一些,大家根据自己应用场景申请即可。

3. 安装 Nginx

如果已经安装了 Nginx 请直接跳过这一步

1
2
yum install epel-release -y
yum install nginx -y

4. Nginx 证书配置

/etc/nginx/conf.d 目录下创建 blog.frankfeekr.cn.conf(文件名以 .conf 后缀,推荐使用域名命名方便管理)

1
2
3
4
5
6
7
8
9
10
server {
listen 443 ssl;
server_name blog.frankfeekr.cn;
ssl_certificate /etc/letsencrypt/live/frankfeekr.cn/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/frankfeekr.cn/privkey.pem;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE;
ssl_prefer_server_ciphers on;
root /usr/share/nginx/html;
}

配置完证书后重启服务

1
service nginx restart

5. 自动续期

首先检查 crontab 服务是否运行

1
systemctl status crond

如果没有启动,先 enable 它再 start 它

1
2
systemctl enable crond
systemctl start crond

编辑计划任务

1
crontab -e

输入下面的表达式(每天 00:00:00),让他每天都尝试一次关闭 Nginx->更新->启动 Nginx,到了最后 30 天的时候就会成功。

1
0 0 * * * "service nginx stop ; /bin/certbot renew --renew-by-default; service nginx start"

6. 访问 https 网站

点击访问:https://blog.frankfeekr.cn

image-20210328224333690

证书查看:有效期是 90 天,待快到期则可以通过上述配置的定时任务来更新。

image-20210328173120842

FAQ

  1. 证书重置请求超过次数,一般 3 次,子域名除外。就会出现如下错误,5 天以后才可以再次重置。

    1
    2
    An unexpected error occurred:
    There were too many requests of a given type :: Error creating new order :: too many certificates already issu for exact set of domains: blog.frankfeekr.cn: see https://letsencrypt.org/docs/rate-limits/

    速率限制 - Let’s Encrypt - 免费的SSL/TLS证书

参考链接