使用Certbot获取免费泛域名(通配符)证书
Certbot是Let's Encrypt提供的一个获取证书的程序, 支持自动获取证书(不用注册用户), 自动续期证书(免费证书只有3个月有效期, 但可以无限续期)
安装cerbot
sudo apt-get update
sudo apt-get install software-properties-common
sudo add-apt-repository ppa:certbot / certbot
sudo apt-get update
sudo apt-get install python-certbot-nginx
使用
入门版, 获取单个域名
生产环境使用nginx作为web服务器, 但我没有使用certbot提供的nginx插件一键安装证书, 第一是我怕搞坏了生产环境, 第二是好像certbot的nginx插件局限性很大, 并不能支持换个地方安装的nginx.
所以目前我需求就是获取nginx上使用的.pem
和.key
两个文件.
challenge
Let's Encrypt需要验证网站的所有权才能颁发证书, 官方称之为challenge(挑战).
有三种方式可以实现验证: (官方文档在此)
- 在网站上的指定位置发布指定文件(HTTP-01)
- 在网站上提供指定的临时证书(TLS-SNI-01)
- 在域名系统中发布指定的DNS记录(DNS-01)
在这里选用HTTP-01任务.
(后记: 推荐使用DNS认证方式和DNS插件自动模式, 本文后部分有讲. 手动是真的麻烦...)
HTTP-01
- 确保域名存在并且已经指向您请求证书的服务器的公共IP地址。
- 确保端口80处于打开状态,可从Internet公开访问,并且不会被路由器或防火墙阻止。
- 当使用Webroot插件或手动插件时,请确保webroot目录存在并且您正确指定它。如果您为example.com设置了webroot目录,/var/www/example.com 那么放置的文件/var/www/example.com/.well-known/acme-challenge/testfile应该出现在您的网站上http://example.com/.well-known/acme-challenge/testfile(此处重定向到HTTPS是可以的,并且不应该阻止工作中的挑战)。
- 在一些Web服务器配置中,所有页面都是由某种框架动态生成的,通常使用数据库后端。在这种情况下,Web服务器可能无法从中直接为文件提供特定的目录。在这种情况下使用Webroot插件需要首先更改Web服务器配置。
- 确保您的网络服务器正确地将挑战文件所在的目录(例如/.well-known/acme-challenge)提供给网站上预期的位置,而无需添加页眉或页脚。
- 使用独立插件时,请确保其他程序尚未侦听服务器上的端口80。
- 使用Webroot插件时,确保有一个Web服务器在端口80上侦听。
说实话我看着也头大, 这么长篇大论. 所以实践出真知吧, 过一遍上面的说明就开始敲命令吧.
假如我的域名为: bysir.store
sudo certbot certonly --standalone --email 'zbysir@qq.com' -d 'bysir.store'
standalone 就是独立插件, 它需要绑定80端口, 所以先关掉机器上的80端口吧, 或者换一台主机安装.
不出意外的话, 会死在Waiting for verification...
,
Saving debug log to /var/log/letsencrypt/letsencrypt.log
Plugins selected: Authenticator standalone, Installer None
Starting new HTTPS connection (1): acme-v01.api.letsencrypt.org
Obtaining a new certificate
Performing the following challenges:
http-01 challenge for bysir.store
Waiting for verification...
Cleaning up challenges
Failed authorization procedure. bysir.store (http-01): urn:acme:error:unauthorized :: The client lacks sufficient authorization :: The key authorization file from the server did not match this challenge [r9NH9hle6_7L9avkG-ID6A1BI4h4IgFVn6nx3VQZRpI.IL3bE2eqHDs1k0Lmxm63CXpLvzmosMuUDIywEIBTPnG] != []
IMPORTANT NOTES:
- The following errors were reported by the server:
Domain: bysir.store
Type: unauthorized
Detail: The key authorization file from the server did not match
this challenge
[r9NH9hle6_7L9avkG-ID6A1BI4h4IgFVn6nx3VQZRpI.IL3bE2eqHDs1k0Lmxm63CXpLvzmosMuUDIywEIBTPnG]
!= []
To fix these errors, please make sure that your domain name was
entered correctly and the DNS A/AAAA record(s) for that domain
contain(s) the right IP address.
可以看到他会请求http://bysir.store/.well-known/acme-challenge/r9NH9hle6_7L9avkG-ID6A1BI4h4IgFVn6nx3VQZRpI
以认证网站.
错误就是没认证通过, 期望得到的字符串是r9NH9hle6_7L9avkG-ID6A1BI4h4IgFVn6nx3VQZRpI.IL3bE2eqHDs1k0Lmxm63CXpLvzmosMuUDIywEIBTPnG
但是你返回空串``
笨办法是在nginx配置中添加如下代码
location ~ "^/\.well-known/acme-challenge/(.*)$" {
default_type text/plain;
return 200 "$1.IL3bE2eqHDs1k0Lmxm63CXpLvzmosMuUDIywEIBTPnG";
}
访问一下路径http://bysir.store/.well-known/acme-challenge/r9NH9hle6_7L9avkG-ID6A1BI4h4IgFVn6nx3VQZRpI
检查下是否按预期返回了.
重新执行certbot生成证书.
$ sudo certbot certonly --standalone -d 'bysir.store'
Saving debug log to /var/log/letsencrypt/letsencrypt.log
Plugins selected: Authenticator standalone, Installer None
Starting new HTTPS connection (1): acme-v01.api.letsencrypt.org
Obtaining a new certificate
Performing the following challenges:
http-01 challenge for bysir.store
Waiting for verification...
Cleaning up challenges
IMPORTANT NOTES:
- Congratulations! Your certificate and chain have been saved at:
/etc/letsencrypt/live/bysir.store/fullchain.pem
Your key file has been saved at:
/etc/letsencrypt/live/bysir.store/privkey.pem
Your cert will expire on 2018-09-11. 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
可以看到验证通过并成功生成了证书, 其中 privkey.pem就是nginx要的key, fullchain.pem就是nginx要的pem.
完成.
(ps: 使用DNS认证方式会简单很多, 推荐使用)
泛域名证书
免费泛域名证书真的良心...
手动模式
只需要:
certbot certonly --preferred-challenges dns --manual -d *.bysir.cn --server https://acme-v02.api.letsencrypt.org/directory
讲解下参数:
- --preferred-challenges dns: 认证方式选择DNS, 泛域名支持DNS
- --manual: 手动模式, 这里为了简单就使用手动认证了, 下面会说自动模式的使用.
- -d *.bysir.cn: 就是要申请的泛域名了
- --server https://acme-v02.api.letsencrypt.org/directory: 泛域名证书是新功能, 如果要使用就得加上这个参数
敲下回车:
-------------------------------------------------------------------------------
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
再敲下y
-------------------------------------------------------------------------------
Please deploy a DNS TXT record under the name
_acme-challenge.bysir.cn with the following value:
cuAVEgl69tzimaIm2ncIEIVeMLYnzw05JohSdXuAOAA
Before continuing, verify the record is deployed.
-------------------------------------------------------------------------------
Press Enter to Continue
注意这一步需要手动配置TXT记录, 在域名解析服务商添加一个泛解析就可以了, 设置好了再敲下回车.
最后就会将生成好的证书保存到本地.
自动模式
吸取到上面手动模式无比麻烦的教训, 咱们这次一定要使用自动模式.
查询官方文档, 使用一个合适的插件, dns-plugin
![](https://img.haomeiwen.com/i3447621/c62519909bb82304.png)
这里我使用的dns服务商的xns, 所以我选择了certbot-dns-cloudxns.
按照插件文档编写配置文件:
cloudxns.ini
# CloudXNS API credentials used by Certbot
dns_cloudxns_api_key = 1234567890abcdef1234567890abcdef
dns_cloudxns_secret_key = 1122334455667788
敲下命令:
certbot certonly --preferred-challenges dns --dns-cloudxns --dns-cloudxns-credentials ./cloudxns.ini -d *.bysir.cn --server https://acme-v02.api.letsencrypt.org/directory
运行之 报错:
certbot: error: unrecognized arguments: --dns-cloudxns-credentials ./cloudxns.ini
仔细看上面的文档, 其实这些插件是没被发行的, 通过我之前的安装方式是不能使用这些插件的, 但可以使用docker运行方式来使用这些插件:
进入https://hub.docker.com/u/certbot/, 找到需要的镜像
![](https://img.haomeiwen.com/i3447621/12cd691dc5ab8f0d.png)
然后使用以下命令行来运行certbot:
sudo docker run -it --rm --name certbot \
-v "/etc/letsencrypt:/etc/letsencrypt" \
-v "/var/lib/letsencrypt:/var/lib/letsencrypt" \
-v "/workspace/certbot/cloudxns.ini:/cloudxns.ini" \
certbot/dns-cloudxns certonly --preferred-challenges dns --dns-cloudxns --dns-cloudxns-credentials /cloudxns.ini -d *.bysir.cn --server https://acme-v02.api.letsencrypt.org/directory
现在就可以自动完成申请证书了, 简单到感人. 申请下来的证书同样会放在/etc/letsencrypt/live
下.
至此完成, 感谢letsencrypt.
后续可能会更新自动更新证书方案, 敬请期待.