使用lego签发Let's Encrypt的证书
五年前Let‘s Encrypt还不支持泛域名证书,我这个懒人为了省事,一下子买了五年的wildcard证书。截止到2020年7月22日,Let’s Encrypt已经有近六千四百万活跃的域名,有一亿三千六百万个证书,每天签发近一百五十万次。最重要的是证书全部是免费的,经过这几年的发展,Let‘s encrypt已经是目前互联网最重要的组织之一。而且周边和教程都已经非常成熟了,客户端就有几十种。我的网站要求就两点,一是能支持签发和续签widlcard证书,第二就是要使用简单,最终综合比较了一下选择了Lego。
Lego是Go语言写的,使用之前要先安装GoLang。
一、安装GoLang
从官网下载go语言相应版本的客户端,解压安装即可,需要注意以下两点:
- Linux系统下不要安装多个版本的GO
- 需要正确设置GOROOT和环境变量。
不然编译lego会有很多错误,例如go的解压后的目录在/usr/local/go,设置如下:
export GOROOT=/usr/local/go
export PATH=$PATH:$GOROOT/bin/
将这两条设置放到profile或者bash_profile中即可,和JDK设置类似,这里不需要多说。
二、编译Lego
编译就比较简单了,两条命令即可:
git clone https://github.com/go-acme/lego
cd lego && make build
等待执行完,编译好的文件在dist目录下,复制到PATH里就可以直接用了。
三、签发和续签证书
使用超级简单,签发和续签一条命令即可。泛域名证书只能通过dns验证,需要域名NS的api key,具体支持的ns厂商可以通过:
lego dnshelp
查看需要设置的参数:
lego dnshelp -c dnspod
签发需要先设置api,dnspod完整的API Token是由 ID,Token 组合而成,用英文的逗号分割:
export DNSPOD_API_KEY="ID_xxxx,Token_xxxxxx"
export DNSPOD_HTTP_TIMEOUT="300"
签发:
lego --email="will@nixops.me" --domains="nixops.me" --domains="*.nixops.me" --accept-tos --path=/tmp/lego/ --dns="dnspod" --dns.resolvers="8.8.8.8" run
--run-hook: 签发成功后执行的命令或脚本
续签:
lego --email="will@nixops.me" --domains="nixops.me" --domains="*.nixops.me" --accept-tos --path=/tmp/lego --dns="dnspod" renew --reuse-key
--reuse-key: 不重新生成私钥
--renew-hook: 续签成功后执行的命令或脚本,如替换证书,reload服务
--days: 可以指定提前续期的天数
四、自动签发和续签脚本
#!/bin/bash
lego_bin=/root/lego/lego
save_path=/usr/local/keys/
account_email="will@nixops.me"
export DNSPOD_API_KEY="ID_xxxx,Token_xxxxxx"
export DNSPOD_HTTP_TIMEOUT="300"
case $1 in
run)
$lego_bin --email="$account_email" --domains="*.$2" --domains="$2" --accept-tos --path=$save_path --dns="dnspod" --dns.resolvers="1.1.1.1" run --run-hook="`readlink -f $0` reload" >>/var/log/letencrypt.log
;;
renew)
for domain in `$lego_bin --path=$save_path list -n` ; do
$lego_bin --email="$account_email" --domains="*.$domain" --domains="$domain" --accept-tos --path=$save_path --dns="dnspod" renew --reuse-key --renew-hook="`readlink -f $0` reload" >>/var/log/letencrypt.log
done
;;
reload)
cp -f $save_path/certificates/*.crt /usr/local/openresty/nginx/conf/vhosts/keys/
cp -f $save_path/certificates/*.key /usr/local/openresty/nginx/conf/vhosts/keys/
rm -rf /usr/local/openresty/nginx/conf/vhosts/keys/*.issuer.crt
/usr/local/openresty/bin/openresty -s reload
;;
*)
echo "黙认签发泛域名证书,只写根域名即可"
echo "证书保存在 $save_path"
echo "用法: 1. 签发证书 $0 run nixops.me"
echo "用法: 2. 续签证书 $0 renew "
echo "用法: 3. 复制证书,reload服务 $0 reload"
;;
esac
将以上脚本加入crontab中,每天执行一次renew:
crontab -e
15 3 * * * /usr/local/bin/ssl.sh renew nixops.me >>/dev/null 2>&1
最后不得不说,DNSPOD、namesilo的ns太渣了,默认解析TTL太长导致dns验证的签发和续签都太慢,失败太常见了,成功才是偶然。付费的ns一般都比较稳定,例如aws的router53能在2分钟内签发完成,免费ns测试cloudflare不错,其它的没有测试过。