使用 GitHub Actions 自动申请 SSL 证书并推送到仓库 在现代 Web 开发中,SSL 证书的管理和自动化是确保网站安全性的重要一环。本文将介绍如何使用 GitHub Actions 自动申请 SSL 证书,并将证书推送到 GitHub 仓库中的指定分支。我们将使用 Let’s Encrypt 和 GTS 作为证书提供者,并通过 Cloudflare 的 DNS API 进行域名验证。确保您具有相应的权限和配置来顺利执行该工作流程。请注意,由于证书会上传到仓库,请将仓库设置为私有 。
前提条件 配置 Secrets :在仓库的 Settings > Secrets and Variables > Actions 中,配置以下 Secrets:
DOMAIN_LIST
:需要申请的域名列表,格式为 <域名>,<DNS服务商>,[ACME服务器],[Profile名称],[证书有效期],[证书剩余时间触发续订]
,每个域名会申请单独的泛域名证书。配置示例:
1 2 3 example.com,cloudflare,,tlsserver example.com,cloudflare,zerossl,,,15 example.com,cloudflare,google,,30,15
DNS_API
:DNS API 配置,一行一个,例如:
1 2 export GANDI_API_KEY="xxx" export CF_DNS_API_TOKEN="xxx"
支持的 DNS 服务商列表请参考:lego DNS Providers
LEGO_ACCOUNT_TAR
:Base64 编码的 lego 配置信息,在本地成功签发后运行 tar cz .lego/accounts | base64 -w0
获取。
本地签发命令示例:
1 2 3 4 CF_DNS_API_TOKEN="***" ./lego --accept-tos \ --email ssl@example.com --dns cloudflare \ --server https://dv.acme-v02.api.pki.goog/directory \ --eab --kid *** --hmac *** --domains example.com run
CERT_EMAIL
:注册 ACME 的电子邮件地址。
编写 GitHub Actions 配置文件 在仓库根目录下创建 .github/workflows/acme.yml
文件,内容如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 name: ssl automation on: workflow_dispatch: schedule: - cron: '0 16 * * *' permissions: contents: write packages: read env: TZ: Asia/Shanghai jobs: ssl-cert-issuer: runs-on: ubuntu-latest steps: - name: 🚚 Checkout Repository uses: actions/checkout@v4 with: ref: main path: .lego - name: 📦 Install latest lego shell: bash run: | RELEASE_INFO=$(curl -s https://api.github.com/repos/go-acme/lego/releases/latest) TAG_NAME=$(echo "$RELEASE_INFO" | jq -r '.tag_name') DOWNLOAD_URL=$(echo "$RELEASE_INFO" | jq -r ".assets[] | select(.name == \"lego_${TAG_NAME}_linux_amd64.tar.gz\") | .browser_download_url") curl -sLO "$DOWNLOAD_URL" tar -xzf lego_* - name: 🔐 Extract lego account shell: bash run: | echo "${{ secrets.LEGO_ACCOUNT_TAR }}" | base64 -d | tar -C . -xz - name: 📄 Issue or Renew Certificates shell: bash run: | ${{ secrets.DNS_API }} DOMAIN_LIST=(${{ secrets.DOMAIN_LIST }}) for DOMAIN_INFO in "${DOMAIN_LIST[@]}" ; do IFS=',' read -r DOMAIN DNS ACME_SERVER PROFILE VALID_DAYS RENEW_BEFORE_DAYS <<< "$DOMAIN_INFO" ACME_SERVER=${ACME_SERVER:-letsencrypt} ACTION="renew --no-random-sleep --ari-disable --days ${RENEW_BEFORE_DAYS:-30}" if [ ! -f "./.lego/certificates/$DOMAIN.crt" ]; then ACTION="run" fi ./lego \ --accept-tos \ --email "${{ secrets.CERT_EMAIL }} " \ --dns "$DNS" \ --server "${!ACME_SERVER}" \ --domains "$DOMAIN" \ --domains "*.$DOMAIN" \ --eab \ $ACTION ${VALID_DAYS:+--not-after=$(date -u -Is -d "+$VALID_DAYS days" )} ${PROFILE:+--profile $PROFILE} done env: letsencrypt: https://acme-v02.api.letsencrypt.org/directory zerossl: https://acme.zerossl.com/v2/DV90 google: https://dv.acme-v02.api.pki.goog/directory - name: ⬆️ Push Certificates to GitHub run: | git config --global user.name "github-actions[bot]" git config --global user.email "41898282+github-actions[bot]@users.noreply.github.com" cd ./.lego git add certificates if git diff --cached --quiet; then echo "✅ No certificate changes detected." else git commit -m "🔒 Update certificates on $(date '+%Y-%m-%d %H:%M:%S')" git push fi
运行工作流程 您可以通过以下两种方式触发工作流程:
手动运行 :在 GitHub 仓库的 Actions 页面,选择 acme ssl automation
工作流程,然后点击 Run workflow
手动触发。
定时运行 :工作流程将根据配置的 cron 表达式,每周六运行一次。
总结 通过上述配置,您可以实现 SSL 证书的自动申请和更新,并将最新的证书文件推送到 GitHub 仓库。这样可以方便地管理和分发 SSL 证书,同时确保证书的及时更新。