10分钟搞定支持通配符的永久有效免费HTTPS证书
本文由 小茗同学 发表于 2024-04-07 浏览(218)
最后修改 2024-04-07 标签:ssl https 免费

前言

之前一直用的是腾讯云免费SSL证书,但是只有1年有效期,而且不支持通配符证书(Wildcard Certificates,类似*.haoji.me),所以使用上非常不方便,甚至最近证书过期几个月了都懒得去更换。最近实在是被逼的没办法了,研究一下永久有效证书。

基本原理

市面上的免费证书一般都只有3个月有效期,一般都是通过一些自动重新申请的脚本来实现“永久”有效。其中最出名的应该是Let's Encrypt

踩坑之旅

简单记录一下这中间走的一大堆弯路,顺便简单科普一些基本信息,不感兴趣的可以直奔下个主题。

Let’s Encrypt官方客户端

我是按照Let's Encrypt官网 教程来的,获取证书需要一个ACME客户端,然后官方推荐一个后来被发现非常坑爹、非常走弯路的Certbot,由于一系列原因把我坑的不要不要的。

简而言之就是一个简单的bash命令就能搞定的事情,官方却让我们安装一堆的不必要的软件。

大概流程是:

  • 添加EPEL扩展
  • 通过yum安装snapd
  • 通过snap安装certbot
  • 通过certbot安装证书

这其中还要根据不同的操作系统版本有不同的安装方式,我在安装的时候由于比较特殊的原因一直不成功,坑了我几个小时最后放弃。

GetSSL

官网下面另外推荐了几十个非官方ACME客户端,然后我试了第一个基于Bash的GetSSL,中间也是碰到了很多奇奇怪怪的问题,最后还是放弃,这里省略中间过程。直到最后才发现非常良心的acme.sh客户端,也就是本文主要介绍的方式。

通过acme.sh配置永久有效ssl证书

第一步:安装

curl https://get.acme.sh | sh

这一步会把acme.sh安装到~/.acme.sh/目录,并自动配置一个名叫acme.shalias

第二步:获取DNS解析密钥

acme.sh支持阿里云、腾讯云、godaddy等数十种解析商的自动集成,这里以阿里云为例,其它的参考官方介绍

访问https://ram.console.aliyun.com/users,如果还没有创建过用户这里创建一个。

新建完后一定要记得添加“云解析”相关的权限,否则后面步骤会失败。

然后页面放那里备用,因为生成的id和secret后台是不保存的。

第三步:注册厂商账号

acme.sh支持好几个ssl厂商,Let's Encrypt只是其中一个,需要注意的是之前默认推荐的是Let's Encrypt,但是现在已经改成了ZeroSSL,原因未知,不过个人感觉后者简单多了,一行命令行就注册完毕。

acme.sh  --register-account  -m xxx@youremail.com --server zerossl

如果提示找不到acme.sh可以运行一下source ~/.bashrc

第四步:生成证书

export Ali_Key="<key>"
export Ali_Secret="<secret>"
acme.sh  --issue -d haoji.me  -d *.haoji.me  --dns dns_ali

不出意外的话就会看到一堆success信息,证书自动生成好了:

同时会自动创建cronjob, 每天00:00自动检测所有证书, 如果快过期了需要更新(貌似是60天), 则会自动更新证书。

第五步:使用证书

注意千万不要直接让nginx使用~/.acme.sh/目录下的证书,因为这个文件是会变化的,正确方式是:

acme.sh --install-cert -d haoji.me -d *.haoji.me \
--key-file	   /your-nginx/cert/haoji.me.key.pem  \
--fullchain-file /your-nginx/cert/haoji.me.cert.pem \
--reloadcmd	 "service nginx force-reload"

证书更新后会自动调用reloadcmd

然后确保你的nginx中引用的是上述证书文件。有个小疑问,之前的证书是.key.cert格式的,上述示例给出的是.pem后缀,是否是强制要求这个没测试过。

由于之前可能是写在每个server{}下面的,现在支持通配符了,建议直接将证书配置在http{}下面,这样一劳永逸:

http {
	ssl_certificate cert/haoji.me.cert.pem;
	ssl_certificate_key cert/haoji.me.key.pem;
	# 省略其它配置
	server {
		listen 443 ssl;
		server_name blog.haoji.me
	}
	server {
		listen 443 ssl;
		server_name file.haoji.me
	}
}

最终效果:

参考