免费无限续期 SSL 证书
要实现自动续期,至少需要有一台服务器,虚拟空间不行。
且如果要签泛域名证书的话,证书中包含的域名的 DNS 解析不用全部放在同一个地方,比如几个域名用 cloudflare 管理解析记录,另外几个用 DNSpod,这几个域名签进同一张泛域证书里,也是可以的。
acme.sh
完成 SSL 自动续期的是一个开源脚本 -- acme.sh
某 freessl.cn 里面的一元证书自动化就是用 acme 魔改的,用的还是特别老的 acme,教程也不全,效率很低。
下面就总结一下怎么用 acme
签多域泛域名证书。
使用 acme.sh
安装 acme
可以先安装一下依赖 socat,其实不装也没什么影响
# Centos
yum install socat -y
# Debian/Ubuntu
apt install socat -y
# install acme
curl https://get.acme.sh | sh
Github 无法访问
国内主机可能无法访问 GitHub,需要以下步骤
- 打开 DNS 解析网址 https://tool.lu/dns/index.html ,查询有关与 github.com 域名相关的 IP 地址
- 将查询到的 A 类 IP 地址,写入到 hosts 文件下(Windows 和 Linux 都有该文件,但路径不同)
- 需要添加以下内容到
/etc/hosts
(Linux)vi /etc/hosts
Ins
快捷键进入编辑模式- 输入如下内容(此处仅列举大部分 dns 地址),并
Esc
退出编辑模式 :wq
保存并退出文件
140.82.114.25 alive.github.com
140.82.112.25 live.github.com
185.199.108.154 github.githubassets.com
140.82.112.22 central.github.com
185.199.108.133 desktop.githubusercontent.com
185.199.108.153 assets-cdn.github.com
185.199.108.133 camo.githubusercontent.com
185.199.108.133 github.map.fastly.net
199.232.69.194 github.global.ssl.fastly.net
140.82.112.4 gist.github.com
185.199.108.153 github.io
140.82.114.4 github.com
192.0.66.2 github.blog
140.82.112.6 api.github.com
185.199.108.133 raw.githubusercontent.com
185.199.108.133 user-images.githubusercontent.com
185.199.108.133 favicons.githubusercontent.com
185.199.108.133 avatars5.githubusercontent.com
185.199.108.133 avatars4.githubusercontent.com
185.199.108.133 avatars3.githubusercontent.com
185.199.108.133 avatars2.githubusercontent.com
185.199.108.133 avatars1.githubusercontent.com
185.199.108.133 avatars0.githubusercontent.com
185.199.108.133 avatars.githubusercontent.com
140.82.112.10 codeload.github.com
52.217.223.17 github-cloud.s3.amazonaws.com
52.217.199.41 github-com.s3.amazonaws.com
52.217.93.164 github-production-release-asset-2e65be.s3.amazonaws.com
52.217.174.129 github-production-user-asset-6210df.s3.amazonaws.com
52.217.129.153 github-production-repository-file-5c1aeb.s3.amazonaws.com
185.199.108.153 githubstatus.com
64.71.144.202 github.community
23.100.27.125 github.dev
185.199.108.133 media.githubusercontent.com
这些只能让你能够有访问 github 的能力,即 DNS 能够解析成功,但不代表无障碍访问,可能还会遇到访问失败的问题
设置脚本别名,即终端输入 acme.sh
执行的就是 ~/.acme.sh/acme.sh
alias acme.sh=~/.acme.sh/acme.sh
这是通用的,所有主流的 Linux 都能用,Github 英文页给了支持范围。
acme 可以用命令手动更新
acme.sh --upgrade
也能开启自动更新(推荐)
acme.sh --upgrade --auto-upgrade
使用(单 DNS 运营商)
acme 是自动工作的,你签了证书之后,每 60 天就会帮你续期一次,你只要签好就行了。
- 非泛域名多域名证书如果只是想普通地签多域名证书的话,可以直接用宝塔签,宝塔也是内置的 acme 签的证书。也能自己用 acme(得自己装个新的,找到宝塔内置的 acme 在哪也行)。
acme.sh --issue -d xxx.com -d www.xxx.com --webroot /home/wwwroot/xxx.com
也可以这样
acme.sh --issue -d xxx.com,www.xxx.com --webroot /home/wwwroot/xxx.com
推荐第二种,加域名更方便。但旧版的 acme 可能不支持。
泛域名证书(阿里云)
由于泛域名证书需要验证域名只能用 DNS 验证而不能用文件验证,所以需要配置好相关 DNS API,目前支持近 160 种 DNS API,此处仅列举国内常用的,具体可以看 acme.sh 文档。
CloudFlare
、DNSPod
、GoDaddy
、Aliyun
、Google Cloud
阿里云配置 AccessKey
自己的服务器用 AccessKey 也可以,简单方便,用子账户的话还需要手动授予权限(前提是能分辨那些该分配那些不该分配)。
总的配置文件是 /root/.acme.sh/account.conf
,所有的 api 信息都最终被储存在这里。
然后打开 ssh,申请证书。
acme.sh --issue --dns dns_ali -d xxx.com,*.xxx.com --server https://acme-v02.api.letsencrypt.org/directory
配置正确的话,执行命令后就会自动完成证书签发续期了,生成的证书文件的路径会用绿字输出 ,每六十天会自动续期。
**注意:**新转移到阿里云或新购的域名需要转移后等一天等 DNS 全球生效之后再配置。
更多的域名厂商的 SSL 证书,比如 cloudflare 等生成可以参考 DNS_API
acme 命令其它使用场景
查看证书列表
在创建完证书后,可以使用以下命令查看证书列表。
acme.sh --list
更换服务器
当你要换服务器的时候,你只要在新的服务器装好 acme,然后把整个证书文件夹(在/root/.acme.sh/
内,以第一个域名命名的文件夹,我这里的文件夹就是 xxx.com_cee
)复制过去,就会在新的服务器继续自动续期。
Nginx 配置
安装 Nginx
yum install nginx
# 启动
systemctl start nginx
# 开机自启
systemctl enable nginx
# 停止
systemctl stop nginx
# 重启
nginx -s reload # systemctl restart nginx
Nginx 配置文件
配置 nginx
vi /etc/nginx/nginx.conf
# 或者在 /etc/nginx/conf.d 文件夹下新建 conf 文件
# nginx 识别此路径下的配置文件 /etc/nginx/conf.d/*.conf;
此处给出一个 nginx 配置 http 及多域名的示例,其中 xxx.com
就是代表你的域名
server {
listen 80;
server_name xxx.com www.xxx.com;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name xxx.com www.xxx.com;
# root /usr/share/nginx/html;
ssl_certificate "/root/.acme.sh/xxx.com_ecc/xxx.com.cer";
ssl_certificate_key "/root/.acme.sh/xxx.com_ecc/xxx.com.key";
ssl_session_cache shared:SSL:1m;
ssl_session_timeout 10m;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
location / {
proxy_pass http://localhost:3000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
server {
listen 80;
server_name my.xxx.com www.my.xxx.com;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name my.xxx.com www.my.xxx.com;
# root /usr/share/nginx/html;
ssl_certificate "/root/.acme.sh/xxx.com_ecc/xxx.com.cer";
ssl_certificate_key "/root/.acme.sh/xxx.com_ecc/xxx.com.key";
ssl_session_cache shared:SSL:1m;
ssl_session_timeout 10m;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
location / {
proxy_pass http://localhost:8888;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
需要先在安全组开启 80 443 端口
防火墙相关命令
firewall-cmd --state # 查看防火墙状态
systemctl start firewalld.service # 启动防火墙
systemctl stop firewalld.service # 关闭防火墙
systemctl enable firewalld.service # 设置开机自启动
firewall-cmd --zone=public --add-port=3306/tcp --permanent # 开放防火墙端口 例如 3306
firewall-cmd --remove-port=3306/tcp --permanent # 删除防火墙端口
firewall-cmd --reload # 重新加载配置
firewall-cmd --zone=public --list-ports # 查看开放的防火墙端口
为了安全考虑,简易开启防火墙,并开放 80 443 端口,和安全组对应
上传证书到阿里云
先找到(搜索) 数字证书管理服务
根据之前 acme 生成的证书,最简单的方法:使用 Xftp 将 /root/.acme.sh/xxx.com_cee
文件夹下载下到本地,然后上传到阿里云
- 证书文件 -
jsonq.top.cer
- 证书私钥 -
jsonq.top.key
- 证书链 -
ca.cer
默认情况下,Xftp 中以
.
开头的隐藏文件都不会显示,可以根据上方操作栏的:工具 --> 选项 --> 显示隐藏文件夹(勾选) 即可
更新: 脚本自动签发的证书在过期后自动签发,私钥没有更新,导致私钥重复,所以证书过期后就无法再使用此方式走泛域名证书。最稳妥的方法还是去阿里云再搞个单域名证书(3 个月免费的手动续期和 1 年 68 的手动续期),真是 mmp 了。
很奇怪,由 nginx 直接代理的 ssl 证书不受影响,https 的网站域名正常使用,但是在第三方平台上传 ssl 证书就会出现校验不通过的现象,不知怎么回事。