前言
在折腾运维技术的这条路上,必不可少的就是管理多服务器和多域名,而同时维护这么多有效期仅三个月的免费泛域名证书无疑是一项繁琐的工作.经过一段时间的学习和研究,最终决定使用 GitHub Action 来全自动签发多域名证书,并设置定时触发,自动 Commit Push,甚至可以以附件的形式 Email 给你.服务器端可以通过 crontab 计划任务来执行更新证书的脚本以达到多服务器多域名环境的自动化运维工作.
教程说明
适用场景
本方案适用于多个域名
,不同 dns 服务商
,多域名证书合并
等运维环境需求.
例如:一台服务器上部署了多个不同域名,甚至每个域名都不是同一 DNS 解析服务商,那么acme.sh
程序无法全自动续签和部署每一个域名.此时就可以使用本工作流来实现批量申请,最后在通过编写一个shell
脚本,利用crontab
来定时批量部署证书,重启 nginx 等 Web 服务器.
acme.sh
程序在服务器上安装部署,即可达到自动申请和到期续签的需求.
基本流程
- GitHub Action 每月定时触发一次
- 根据配置文件签发各证书
- 自动打包所有证书
- 可选 Commit 和 Push 到当前仓库
- 可选 附件形式 Email 到指定邮箱
准备工作
域名 API KEY
根据 acme.sh 官方项目文档获取自己域名的 API KEY ,具体请参考本文结尾的链接.其示例参考如下:
export DP_Id="xxxxx"
export DP_Key="xxxxxxxxxxxxxxxxxx"
export CF_Token="xxxxxxxxxxxxxxxxxxx"
export CF_Account_ID="xxxxxxxxxxxxxxxxxxxxxxxxx"
邮件 SMTP 服务器信息 (可选)
如果你的仓库为公开仓库
,为避免证书私钥泄漏,可以配置邮件发送到邮箱.
如果是私有仓库,签发的证书可以自动 Commit 并 Push 到本仓库.
配置流程
配置 Secret
可以在任意已存在的仓库配置工作流,也可以单独新建一个仓库来专门管理域名证书.
在仓库的 Settings 中添加 Secret
DNSAPI
创建 DNSAPI 填写上文获取的 API KEY
MAILUSERNAME
创建 MAILUSERNAME 填写 SMTP 服务器的发件邮箱
MAILPASSWORD
创建 MAILPASSWORD 填写 SMTP 服务器的邮箱密码
更新配置
如果后期需要更新 API 或 SMTP 相关信息可以在此 Update 更新
配置 GitHub Action
在仓库中创建 .github/workflows
目录,在其目录下创建AutoACME.yml
配置文件,参考复制粘贴如下.
name: Auto ACME
on:
schedule:
- cron: "0 2 1 * *"
watch:
types: [started]
env:
ACME: /home/runner/.acme.sh/acme.sh
DNSAPI: ${{ secrets.DNSAPI }}
jobs:
build:
runs-on: ubuntu-latest
if: github.event.repository.owner.id == github.event.sender.id
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Install & Configure ACME.SH
run: |
curl https://get.acme.sh | sh
echo "$DNSAPI" >> /home/runner/.acme.sh/account.conf
- name: Issue & Deploy Certificates
run: |
mkdir -p ./ssl
$ACME --issue --server letsencrypt --dns dns_dp -d ioiox.com -d *.ioiox.com
$ACME --installcert -d ioiox.com --key-file ./ssl/ioiox.com.key --fullchain-file ./ssl/ioiox.com.cer
$ACME --issue --server letsencrypt --dns dns_cf -d ioiox.xyz -d *.ioiox.xyz
$ACME --installcert -d ioiox.xyz --key-file ./ssl/ioiox.xyz.key --fullchain-file ./ssl/ioiox.xyz.cer
zip -r ssl.zip ssl
- name: Commit
run: |
git config --global user.email AutoupdateRobot@email.com
git config --global user.name AutoupdateRobot
git add ./ssl/
git commit -m "Update certificate files" -a
- name: Push
uses: ad-m/github-push-action@master
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
- name: Send mail
uses: dawidd6/action-send-mail@v2
with:
server_address: smtp.qiye.aliyun.com
server_port: 465
username: ${{ secrets.MAILUSERNAME }}
password: ${{ secrets.MAILPASSWORD }}
subject: GitHub Actions Auto ACME
body: Build job of ${{github.repository}} completed successfully!
to: stille@ioiox.com
from: GitHub Actions Auto ACME
attachments: ./ssl.zip
Action 详情
此配置文件中的name
为整个工作流步骤.分别为:
Checkout
标准检出操作,用于 clone 仓库文件方便后续 Commit 和 Push .Install & Configure ACME.SH
安装 acme.sh 并根据创建的 Secret 配置 DNSAPIIssue & Deploy Certificates
申请证书并压缩以便 Email 附件Commit
公共仓库请删除该段Push
公共仓库请删除该段Send mail
根据需求配置邮件通知或发送证书附件.
修改部分参数申请证书
Issue & Deploy Certificates
本文示例申请ioiox.com
和ioiox.xyz
两个域名的泛域名证书:
该两个域名服务商分别为dnspod.cn
和cloudflare
,上文DNSAPI
中同时填写了两个服务商的 API KEY.--issue
为申请证书命令--installcert
为部署证书,用于把申请的证书移动到ssl
目录,方便打包发送邮件.
以上两条命令为一组,根据自身申请域名的多少自行添加.
最后一条zip
命令为压缩邮件附件所用,如果无需可以删除.
根据实际情况修改本段中的域名和 dns 类型.具体的 dns 支持可以参考本文结尾的链接.在此你可以根据示例添加多个域名.
定时触发
工作流已配置每月1
日UTC
时间凌晨2
点,即北京时间10
点自动运行.同时当仓库所有者
点击star
也会触发工作流运行.
测试使用
一切配置完毕即可star
启动运行,检测各步骤是否正常.后续工作流将定时自动运行.
成功运行完成
自动 Commit 并 Push 到仓库
收到含证书附件的邮件
结语
最后在次声明几点
公共仓库
请一定删除Commit
和Push
的步骤,否则会泄漏证书私钥.本工作流主要是方便多域名证书申请管理
,并不适用于自动部署至服务器,请自行选择使用.- 关于证书
申请命令
可以参考官方项目,也欢迎给我留言咨询.
20 条评论
自动的工具真的很方便
我决定把公钥放到 GitHub 仓库,然后生成证书后,通过公钥加密证书后再放到 GitHub 上。
私钥只存在服务器上,不存在 GitHub 仓库。
不是太懂这个,作用是? 解决公有仓库存放证书的安全性么? 求详细指点.
公钥加密的东西,只有私钥才能解密。别人没有私钥的情况下,是没办法从加密后的内容解密出原文。
把私钥存在本地,这样计算 GitHub 仓库内容泄漏,也能保证 ssl 证书的安全。
我大致理解这个意思,只是说用到这个的场景或者自动化流程是?
你是打算存放在公开仓库,通过vps创建的公钥上传至github,然后在aciton内申请证书后进行加密,最后服务器端通过http链接下载证书后私钥解密部署到相关证书目录,这样理解的吗?
只是为了保证证书的安全,增加一个加密的步骤。
任何要的地方,手动解密一下就行了。
支持博主以下
自动签发搞定了 接下来就是如何自动部署了
我个人的方案是将证书在action自动上传到了对象存储,也就是能够http下载的地方
(可能有安全隐患,但是不公开地址别人也不知道我的证书下载链接)
然后写了个脚本,在服务器上的crontab做了个定时任务,自动下载证书到指定位置,并重启nginx.
这一整套流程6.1的时候已经全自动完成了,也邮件提醒了我.感觉还是很方便
服務器定時git clone不就可以了
git clone 私有仓库需要密钥,证书分发不可能在每台服务器上部署github密钥.
可以加个access_secret ,然后通过github page? or clouflare worker部署后端api来访问github私有仓库push的私钥[客户端通过access_secret在url参数里面访问api验证,校验时间戳后下载私钥.]
定时访问api,返回证书上次更新时间戳,比本地新则下载
博主真是高产!