利用acme.sh申请SSL证书并自动更新
背景
有时候买了国外的域名,但是可能不提供直接申请免费的SSL证书,这个时候需要我们去购买付费的证书或者找到一些免费的服务机构,比如Let's Encrypt
,于是我就找有没有比较快捷地申请证书的方式,答案就是acme。
什么是ACME
Automated Certificate Management Environment,即自动证书管理环境,是一种协议来着(RFC8555),可以自动颁发和续订证书,当然也可以实现我们的需求申请证书,这只是一个最基本的功能。
ACME实现
既然ACME是一个标准,那么定然会有众多实现,比如Let’s Encrypt官网描述的certbot,以及本文重点描述的acme.sh,感兴趣也可以看看其他客户端
acme.sh
acme.sh是一个bash环境下运行的脚本,实现了ACME协议。
安装
# 安装
curl https://get.acme.sh | sh -s email=my@example.com
# 查看帮助
acme.sh -h
安装程序做了3步骤
- 复制acme.sh到~/.acme.sh/下,所有的证书都会被放在这里
- 创建别名acme.sh=~/.acme.sh/acme.sh
- 创建定时任务,每天检查是否有证书过期并续订
申请证书
# 通过这个命令申请证书,-d域名,-w nginx下的目录(主要用于校验,所以需要先配置好解析和nginx)
acme.sh --issue -d xxx.com -w /usr/share/nginx/html/fanli
申请完毕可以在~/.acme.sh/
下看到
证书申请好后我们还需要配置让nginx使用
# -d 域名
# 在nginx配置下新建文件夹ssl,将证书放在这里面
# reloadcmd写好nginx的重启命令
# 配置好以后,acme.sh会将前面创建好的证书放在我们指定的目录下
# 并且通过最开始的定时检测证书是否过期(一般是60天)
# 如果过期会自动续订并更新证书文件到现在指定的目录,且会执行reloadcmd重启nginx
acme.sh --install-cert -d xxx.com \
--key-file /etc/nginx/conf.d/ssl/xxx.com.key.pem \
--fullchain-file /etc/nginx/conf.d/ssl/xxx.com.cert.pem \
--reloadcmd "systemctl restart nginx"
配置nginx
# nginx.conf
server {
listen 443 ssl;
server_name xxx.com;
ssl_certificate /etc/nginx/conf.d/ssl/xxx.com.cert.pem;
ssl_certificate_key /etc/nginx/conf.d/ssl/xxx.com.key.pem;
location / {
root /usr/share/nginx/html/xxx;
}
}
保存修改后重启
然后访问域名正常应该可以看到https
可能遇到的问题
verify错误
这个问题是acme在校验网站的所有权时校验失败
- 可能原因是你的域名解析没有解析到你的nginx所在地址
- nginx需要配置好目录,这个目录要和申请证书时的-w对应上
扩展
查看证书类型
# 查看证书内容,
# -in指定证书位置(是key,不是cert)
# -text 输出证书所有信息
# -noout 不输出证书本身
openssl x509 -in xxx.key.pem -text -noout
# 查看公钥算法和签名算法
openssl x509 -in xxx.key.pem -text -noout | awk '/Public Key|Signature Algorithm/'
![](https://i-blog.csdnimg.cn/blog_migrate/a425a576d383df0f2c7b357f20365ae9.png)
sslscan查看网站支持的加密算法和版本
使用sslscan查看网站目前支持的加密套件和TLS版本
![](https://i-blog.csdnimg.cn/blog_migrate/f916632c299c0f9b4c64dc5f6aee1bb3.png)
# 安装sslscan
# centos如果提示没有zlib.h需要安装这个(可以先不安装)
yum install -y zlib zlib-devel
# clone
git clone https://github.com/rbsec/sslscan
cd sslscan/
make static
# 查看是否安装成功
./sslscan
# 使用,就可以出现上面的图片类似的结果
./sslscan xxx.com
从上图可以看到目前网站支持TLS1.0和1.1,这是不安全的,等保过不了
包括下面的支持的加密套件,如果是弱加密套件也有问题
配置nginx TLS版本
server {
listen 443 ssl;
server_name xxx.com;
ssl_certificate /etc/nginx/conf.d/ssl/xxx.com.cert.pem;
ssl_certificate_key /etc/nginx/conf.d/ssl/xxx.com.key.pem;
# TLS版本
ssl_protocols TLSv1.2 TLSv1.3;
# 加密套件
ssl_ciphers HIGH:!aNULL:!MD5;
location / {
root /usr/share/nginx/html/fanli;
}
}
更改完nginx配置重启
再次使用sslscan查看,就可以看到只支持TLS1.2和1.3了
![](https://i-blog.csdnimg.cn/blog_migrate/d3bf4a38549545e3fe0ee18c80fd5ffc.png)
泛域名
泛域名就是通配符域名,比如*.xxx.com
,这样的域名可以匹配任意子域名
这样子我们就可以申请一个泛域名证书,然后所有的子域名都可以使用这个证书了
泛域名需要使用dns模式
可以使用厂商一键模式,也可以使用手动
# 颁发泛域名证书
acme.sh --issue -d '*.xxx.com' --dns --yes-I-know-dns-manual-mode-enough-go-ahead-please
# 按提示在DNS解析上增加TXT_VALUE等值,等待生效
# 使用dig查看是否生效
dig -t txt _acme-challenge.xxx.com @8.8.8.8
# renew,重新颁发
acme.sh --renew -d *.xxx.com \
--yes-I-know-dns-manual-mode-enough-go-ahead-please
# 重新install即可
acme.sh --install-cert -d *.xxx.com \
--key-file /etc/nginx/conf.d/ssl/common.xxx.com.key.pem \
--fullchain-file /etc/nginx/conf.d/ssl/common.xxx.com.cert.pem \
--reloadcmd "systemctl restart nginx"
![](https://i-blog.csdnimg.cn/blog_migrate/e34370901b842336be1fa515ed9c18e4.png)
![](https://i-blog.csdnimg.cn/blog_migrate/18181fdd1b5b8dd38f733845b56f73a3.png)
总结
acme申请证书还是挺方便的,对于企业来说,可能云厂商通常只提供20个,如果不想付费可以采用
对于个人来说,这更是简单了,虽然有60天的限制,但是基于自动更新的话也不用操心,而且可以申请泛域名,很方便。