申请免费https证书并自动更新
说明
想给我的域名 sxy91.com 加 https 实现域名由 http 升级为 https,找了一圈发现一个免费的 ssl 证书颁发机构 Let’s Encrypt。
申请好 ssl 证书,绑定好自己的域名,这样就可以通过 https 方式来访问,起到安全的作用。
Let’s Encrypt 证书免费,不过每次申请只有90天的有效期,可以通过 acme脚本自动申请证书并定期自动更新。申请步骤如下:
ACME 客户端
支持 ACME v2 协议的客户端 有很多
这里推荐使用 acme.sh
buypass 证书
nginx -s stop
acme.sh --server https://api.buypass.com/acme/directory --register-account --accountemail me@sxy91.com
acme.sh --server https://api.buypass.com/acme/directory \
--issue -d sxy91.com -d www.sxy91.com \
--days 170 \
--force \
--standalone
基于 acme.sh
1.安装脚本
#创建一个目录存放证书
mkdir -p /etc/nginx/ssl
#安装acme脚本
curl https://get.acme.sh | sh
#测试安装
acme.sh -v
#如果找不到命令就创建alias
alias acme.sh=~/.acme.sh/acme.sh
2.配置nginx
# acme.sh 会查找 -d指定的domain
server {
listen 80;
server_name www.sxy91.com sxy91.com;
}
3.生成证书
nginx -s stop
acme.sh --issue -d sxy91.com -d www.sxy91.com --standalone
#会在 "~/.acme.sh/" 目录下生成证书文件
#会自动创建cronjob,每天 0:00 点自动检测所有的证书
crontab -l
上面的方法是http验证方式,若要使用通配符配置域名,则只能通过dns模式验证。
4.安装证书
acme.sh --installcert -d sxy91.com -d www.sxy91.com \
--key-file /etc/nginx/ssl/sxy91.key \
--fullchain-file /etc/nginx/ssl/sxy91.cer \
--reloadcmd "nginx"
# 会自动把证书文件复制到"/etc/nginx/ssl"目录下 并改名为sxy91,然后重启nginx。
5. 强制使用https访问
配置nginx并强制使用htpps
server {
listen 80;
server_name *.sxy91.com;
rewrite ^ https://sxy91.com$request_uri? permanent;
}
server {
listen 443 ssl;
server_name *.sxy91.com;
ssl_certificate /etc/nginx/ssl/sxy91.cer;
ssl_certificate_key /etc/nginx/ssl/sxy91.key;
ssl_session_timeout 5m;
ssl_session_cache shared:SSL:50m;
ssl_prefer_server_ciphers on;
}
重启nginx
nginx -t
nginx -s reload
6. 自动更新
因增nginx加了rewrite强制http跳转到https,acme.sh的自动更新证书无法通过http验证,所以会失败。可以写成一个脚本或用下面的命令。
yum -y install socat
nginx -s stop
acme.sh --issue -d sxy91.com --standalone -d www.sxy91.com
acme.sh --installcert -d sxy91.com -d www.sxy91.com \
--key-file /etc/nginx/ssl/sxy91.key \
--fullchain-file /etc/nginx/ssl/sxy91.cer \
--reloadcmd "nginx"
生成的四个文件:
- .cer: 由ca机构签发的域名证书。
- .key:域名证书的私钥。nginx的ssl_certificate_key参数所用文件。
- ca.cer: CA证书
- fullchain.cer:链证书,包含域名证书和ca证书。nginx的ssl_certificate参数所用文件。
nginx参数说明:
- –key-file:需要把.key复制到哪里
- –fullchain-file:需要把fullchain.cer复制到哪里
7. 错误信息解决
若调试的时候出现:Create new order error. Le_OrderFinalize not found.
错误,一般是域名没写对,或者解析出错。Let’s Encrypt 在有频次限制,如果每个域名、账号在一个小时内触发了 5 次失败的验证,那么就需要等待 1 小时再试。错误信息如下:
{
"type": "urn:ietf:params:acme:error:rateLimited",
"detail": "Error creating new order :: too many failed authorizations recently: see https://letsencrypt.org/docs/rate-limits/",
"status": 429
}
acme.sh 提示 CURLE_PEER_FAILED_VERIFICATION 错误
Please refer to https://curl.haxx.se/libcurl/c/libcurl-errors.html for error code: 60
Can not init api.
CURLE_PEER_FAILED_VERIFICATION (60)
The remote server's SSL certificate or SSH md5 fingerprint was deemed not OK. This error code has been unified with CURLE_SSL_CACERT since 7.62.0. Its previous value was 51.
先查看 acme.sh -v 版本, acme 从 3.0 版本开始,颁发机构从 letencrypt 换成了 ZeroSSL
升级 acme
acme.sh --upgrade
acme.sh -v
# 注册一次 ZeroSSL 账号
acme.sh --register-account -m 931918906@qq.com --server zerossl
acme.sh --issue -d sxy91.com --dns dns_cf
acme.sh --issue -d sxy91.com
acme.sh --register-account --server zerossl \
--eab-kid xxxx \
--eab-hmac-key xxxx
acme.sh --server zerossl --issue -d sxy91.com --dns dns_cf
传送门:https://app.zerossl.com/signup
[2021年 10月 21日 星期四 09:28:53 EDT] You didn't specify a Cloudflare api key and email yet.
[2021年 10月 21日 星期四 09:28:53 EDT] You can get yours from here https://dash.cloudflare.com/profile.
[2021年 10月 21日 星期四 09:28:53 EDT] Error add txt for domain:_acme-challenge.sxy91.com
[2021年 10月 21日 星期四 09:28:53 EDT] Please add '--debug' or '--log' to check more details.
[2021年 10月 21日 星期四 09:28:53 EDT] See: https://github.com/acmesh-official/acme.sh/wiki/How-to-debug-acme.s
acme.sh letsencrypt 和Cloudflare DNS API
export CF_Key="fdffT_qI3KAH75yNstggmhcoXQ"
export CF_Email="sxy@qq.com"
export Namesilo_Key="05ed62502fdsaff"
acme.sh --issue --dns dns_namesilo -d sxy91.com -d *.sxy91.com
Unable to add the DNS record.
一直错误,通过调试模式发现,acme 读取一次 key 之后会保存在 ~/.acme.sh/account.conf
把 Namesilo_Key 修改成正确的就好了。
在dns模式下,添加dns记录后,acme.sh会使用cloudflare public dns或者google dns来检查记录是否生效。
如果您不想要此检查,请使用–dnssleep 300.
acme.sh --issue --dns dns_namesilo -d sxy91.com -d *.sxy91.com --dnssleep 60
# --standalone
参考