前言
“如果能把 SSL 证书附加在域名上,那该多酷啊!” —— 凯丽
Certbot 是 Let's Encrypt 的官方工具。
本文主要介绍如何使用 Let's Encrypt 的 Certbot 工具免费生成、修改、更新和撤销 SSL 证书。
简略介绍一点证书的配置。
本文没有提及泛域名证书的生成。
要求网站已经正确配置了服务器、DNS 等,已经能够正常访问。
本文操作环境为 Ubuntu。
安装
可部分参照。
在官网首页,选择服务器和操作系统后,会给出相应的安装以及生成证书的命令。这里只看安装的部分:
sudo apt-get updatesudo apt-get install software-properties-commonsudo add-apt-repository ppa:certbot/certbotsudo apt-get updatesudo apt-get install certbot复制代码
查看是否安装成功:
certbot --version复制代码
或
letsencrypt --version复制代码
输出的都是 certbot 的版本号:
certbot 0.25.0复制代码
生成证书
重要:在开始之前,先看一下本文末尾关于的说明。
在前一节里,官网给出安装命令后,也给出了生成证书的命令,比如:
为 Nginx 服务器生成:
sudo certbot --nginx复制代码
为 Apache 服务器生成:
sudo certbot --apache复制代码
在生成证书后,可以选择让 certbot 自动修改对应服务器软件的配置文件,包括将 80
端口的请求重定向至 443
,启用相应模块,激活配置文件等。
但是!为了更深入地了解 Let's Encrypt,也为了能够更灵活地操作证书,我们不采用这种快捷方式。而是仅仅生成证书,并手动配置。
方法有 standalone
和 webroot
两种。
standalone 与 webroot 的区别
无论哪种方式,certbot 都需要验证域名,但是实现的方式不同,这也是两者有区别的根本原因。
standalone
方法生成和更新证书的时候,certbot ,因此导致需要暂时停止服务器。这种方式不需要给出网站根目录webroot
方法没有上述问题。不过webroot
方法配置略微复杂,并且需要给出网站根目录
webroot
方式之所以不需要 80
或 443
端口,是因为它的实现方式是,在网站根目录中生成一个临时子目录 .well-known/acme-challenge
,然后从 certbot 的服务器向这个路径发送请求,如果请求成功,那么验证通过。
简单介绍了几个 webroot 模式可能会遇到的问题。
standalone 模式
基本命令为:
sudo letsencrypt certonly --standalone复制代码
需要使用 80
或 443
端口,可以通过 --preferred-challenges
指定要使用的端口,只要其中一个端口空闲就可以。
但是说实话,难道存在其中一个端口是空闲的情况吗
使用 80
端口:
--preferred-challenges http复制代码
使用 443
端口:
--preferred-challenges tls-sni复制代码
使用 -d
指定要生成证书的域名。可以添加多个域名,使用逗号分隔,或者使用多个 -d
。两种方法效果相同。
多个域名时,同一个主域名下的多个子域名是可以的,没有试过多个不同的主域名是什么效果。
执行生成命令:
sudo letsencrypt certonly --standalone -d example.com,www.example.com复制代码
第一次使用时,会询问邮箱、是否同意服务条款、是否接受推送内容。
推荐如实填写邮箱,因为证书即将过期时会通过邮件通知。 推送内容不接受就好了。证书即将过期的通知邮件:
感觉这个通知不太准,很多次收到邮件,但是登录查看了一下并没有。
也(很)可能是因为当时没用
--staging
导致生成了很多证书...
2019年4月26日更新:
妈的今天面试演示项目的时候证书过期。。 回来一看有过邮件通知,但是没在意。。这是一个狼来了的故事
如果看到以下信息说明证书生成成功:
Obtaining a new certificatePerforming the following challenges:http-01 challenge for example.comWaiting for verification...Cleaning up challengesIMPORTANT NOTES: - Congratulations! Your certificate and chain have been saved at: /etc/letsencrypt/live/example.com/fullchain.pem Your key file has been saved at: /etc/letsencrypt/live/example.com/privkey.pem Your cert will expire on 2018-09-25. 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复制代码
可以使用 certbot certificates
命令查看当前证书的信息:
Found the following certs: Certificate Name: example.com Domains: example.com, www.example.com Expiry Date: 2018-09-26 00:42:47+00:00 (VALID: 89 days) Certificate Path: /etc/letsencrypt/live/example.com/fullchain.pem Private Key Path: /etc/letsencrypt/live/example.com/privkey.pem复制代码
可以看到,生成了1个证书,-d
后面的第一个域名为证书名和所在目录的目录名,该证书包含了两个域名 example.com
和 www.example.com
。
共生成了四个文件:
- cert.pem
- chain.pem
- fullchain.pem
- privkey.pem
/etc/letsencrypt/archive/example.com
目录保存原件。
/etc/letsencrypt/live/example.com
目录保存文件的软链接,可以理解为快捷方式。
live/
中的文件貌似不只是原件的软链接那么简单,但是没有仔细研究。
privkey.pem 为私钥,务必妥善保管。
webroot 模式
这种方式需要给出网站根目录作为参数。从这名字 webroot
应该也能看出来。
基本命令:
certbot certonly --webroot -w /path/to/webroot -d www.example.com -d example.com复制代码
其中,-w
是网站的根目录,-d
是要生成证书的域名。
-d
列出的域名的根路径必须全部与 -w
的值相同。 如果要为根路径不同的多个域名生成证书,那么只需要在后面再添加 -w
及其对应的 -d
即可:
certbot certonly --webroot -w /path/to/webroot1 -d www.example.com -d example.com -w /path/to/webroot2 -d other.example.net -d another.other.example.net复制代码
其他内容不再赘述,参考前面 standalone
部分。
泛域名证书
从 0.22.0
版本开始,Let's Encrypt 。
TODO
配置服务器
以 Apache 和 Nginx 为例。这里只介绍一下最基本的配置。
首先,这里是官方文档给出的。
Apache 配置
# apache < 2.4.8SSLCertificateKeyFile privkey.pemSSLCertificateFile cert.pemSSLCertificateChainFile chain.pem复制代码
# apache >= 2.4.8SSLCertificateKeyFile privkey.pemSSLCertificateFile fullchain.pem复制代码
官方文档是这么写的,但是现在最新版本才2.4.3,哪来的2.4.8?
启用 SSL 模块:
a2enmod ssl复制代码
修改配置文件:
ServerName example.com SSLCertificateKeyFile privkey.pem # apache < 2.4.8 SSLCertificateFile cert.pem SSLCertificateChainFile chain.pem # apache >= 2.4.8 SSLCertificateFile fullchain.pem ... 复制代码
重启 Apache:
service apache2 restart复制代码
Nginx 配置
ssl_certificate_key privkey.pem;ssl_certificate fullchain.pem;复制代码
修改配置文件:
server { listen 443 ssl; server_name example.com; ssl_certificate fullchain.pem; ssl_certificate_key privkey.pem; ...}复制代码
重启服务器:
service nginx restart复制代码
更进一步的配置:
修改证书
上面使用 standalone
方法已经生成了域名 example.com
和 www.example.com
的证书,证书名为 example.com
。
a.example.com
生成证书,那么可以生成一张新的证书,也可以选择添加到现有的证书 example.com
里。 提供了简单的示例:
certbot --expand -d existing.com -d example.com -d newdomain.com复制代码
虽然示例使用了 --expand
选项,但是后面推荐使用的是 --cert-name
,因为 --expand
只能用来添加域名,而 --cert-name
更灵活,既可以添加也可以删除。
官方文档没有提供 --cert-name
的示例,下面介绍一下。
命令的大致结构是:
certbot certonly --cert-name certname -d a.domain.com,b.domain.com复制代码
--cert-name
选项的参数是现有证书的证书名,-d
选项的参数是证书包含的域名。
注意,多个域名用逗号分隔,并且中间不能有空格。
即,不能是:
-d a.domain.com, b.domain.com
,而应该是-d a.domain.com,b.domain.com
。
添加域名
现在开始为证书名为 example.com
、包含 example.com
和 www.example.com
两个域名的证书添加一个新的域名 a.example.com
。
certbot certonly --cert-name example.com -d example.com,www.example.com,a.example.com复制代码
会出现提示:
Saving debug log to /var/log/letsencrypt/letsencrypt.logHow would you like to authenticate with the ACME CA?-------------------------------------------------------------------------------1: Spin up a temporary webserver (standalone)2: Place files in webroot directory (webroot)-------------------------------------------------------------------------------Select the appropriate number [1-2] then [enter] (press 'c' to cancel):复制代码
选择 1
。或者在命令中添加 --standalone
选项,可以跳过这一步。
Plugins selected: Authenticator standalone, Installer None-------------------------------------------------------------------------------You are updating certificate example.com to include new domain(s):+ a.example.comYou are also removing previously included domain(s):(None)Did you intend to make this change?-------------------------------------------------------------------------------(U)pdate cert/(C)ancel:复制代码
选择 u
,执行更新即可。
删除域名
现在证书中包含了三个域名,如果要从中删除域名www.example.com
,执行的命令为:
certbot certonly --cert-name example.com -d example.com,a.example.com复制代码
想要删除的域名,不在 -d
后列出来即可。
其他
可以发现,上面在修改由 standalone
方式生成的证书时,仍然可以选择 standalone
和 webroot
。
但是没有试过,感兴趣的同学可以试一下。
更新证书
从证书信息中可以看到,证书有效期为90天。在证书到期前需要进行更新。
可以手动进行更新:
certbot renew复制代码
根据 ,该命令只会更新30天内即将过期的证书。对其他的证书没有影响。
证书更新可以使用 crontab 等设置计划任务实现自动更新,比如每天执行一次 renew
命令。
但是注意,由 standalone
方法生成的证书,更新时也需要使用 80
或 443
端口,因此可能需要(不如说一定需要)在执行 renew
前先关闭服务器,结束后再重新开启。
撤销证书
使用 revoke
选项:
sudo certbot revoke --cert-path /etc/letsencrypt/live/CERTNAME/cert.pem复制代码
前面说过,archive
目录保存了证书原件,live
目录保存了证书的软链接。
live
,不能是 archive
,否则会报错。 撤销成功后,会询问是否删除证书文件和证书所在目录:
-------------------------------------------------------------------------------Would you like to delete the cert(s) you just revoked?-------------------------------------------------------------------------------(Y)es (recommended)/(N)o:复制代码
推荐选择 Yes
自动删除。如果选择 No
,之后需要执行 certbot delete
来删除文件。
根据 ,无论自动还是手动,最后都需要把相关文件删掉。
如果没有删除,那么 archive
和 live
两个目录及其中的文件就仍然存在。执行 certbot certificates
仍然能显示该证书的信息,不过后面会注明已经失效 INVALID
。但是,在执行证书更新的时候,已经撤销的证书还会被更新。
其他
频率限制
Let's Encrypt 为证书申请的频率做了限制,每个主域名每周不超过20次。
如果达到这个 rate limits,不能够再继续生成了,会报错。所以如果只是为了学习和测试,最好使用 Let's Encrypt 提供的 Staging Environment(模拟环境),没有频率限制。
只要在执行命令时加上--staging
选项就可以了。 等会用了再玩真的。
关于 HTTPS
百度 LAVAS 项目中关于 HTTPS 的介绍:,写得挺好的。
打个广告
我的其他文章: