GPG 签名部署并验证 GitHub Pages

举报
timerring 发表于 2025/01/28 13:30:48 2025/01/28
【摘要】 This article is also posted on my blog, feel free refer to it for the latest revisions: Deploy Github Pages With GPG SigningI have been busy migrating my blog this week. Coincidentally, I learned t...

这周在迁移博客时,了解到 GitHub 存在提交伪造风险,出于安全考虑给仓库添加了 GPG 签名。下面是使用 GPG 签名部署并验证 GitHub Pages 的相关内容。

如何使用 GPG 签名部署并验证 GitHub Pages

主流部署方式有两种:

  1. 直接将所有源文件推送到 GitHub,通过官方 Action 完成构建部署。
  2. 将博客源文件与构建产物分离,源文件存放在私有仓库,通过 Workflow 自动构建并推送到公开的静态资源仓库。

为确保更高安全性,选择第二种方式,利用 GitHub Pages 的 Workflow 结合 actions-gh-pages 行动部署 Hugo。但该行动作者明确表示不打算添加 GPG 签名功能,因此需要手动解决签名问题。

导入 GPG 密钥

首先在 GitHub 上找到一个导入 GPG 密钥的 Workflow 行动,参考文档后配置如下:

- name: 导入 GPG 密钥 # 将 GPG 密钥导入到 GitHub Action 环境  
  uses: crazy-max/ghaction-import-gpg@v6 # 行动仓库  
  with: # 使用子密钥进行提交签名(若用主密钥,可参考行动文档)  
      gpg_private_key: ${{ secrets.GPG_PRIVATE_KEY }} # GPG 子私钥(加密存储的 Secret)  
      passphrase: ${{ secrets.PASSPHRASE }} # 子密钥的密码短语  
      git_user_signingkey: true # 配置 Git 使用签名密钥  
      git_commit_gpgsign: true # 强制提交时使用 GPG 签名  
      fingerprint: ${{ secrets.FINGERPRINT }} # 所用子公钥的指纹(不带空格)  

注意:若仅使用 GPG 主私钥,无需指定 fingerprint;但为安全起见,生成专门用于签名的子密钥时,必须填写子公钥的指纹(不带空格),否则会报错。

别忘了在仓库的「 Secrets」中配置对应的密钥和密码变量。

自定义部署行动

由于官方行动不支持 GPG 签名,需克隆项目并修改代码。核心是在提交命令中添加 -S 选项以启用 GPG 签名。在提交记录中找到提交逻辑,添加 -S 参数。

需注意:官方行动不保留分支代码,每次发布后会删除修改,因此必须自行发布自定义版本。在项目根目录运行 ./release.sh 生成新版本,之后即可在 Workflow 中引用。部署配置如下:

- name: 部署到 Web  
  uses: timerring/actions-gh-pages@v5.0.0 # 基于官方行动修改的自定义版本(可直接使用)  
  with:  
      personal_token: ${{ secrets.PERSONAL_TOKEN }} # GitHub Action 的个人令牌  
      external_repository: your_username/your_repository # 目标仓库(格式:用户名/仓库名)  
      publish_branch: main # 部署目标分支  
      publish_dir: ./public # 构建产物目录(Hugo 默认输出路径)  
      user_name: ${{ secrets.USER_NAME }} # 提交者姓名(需与 GPG 密钥 UID 一致)  
      user_email: ${{ secrets.USER_EMAIL }} # 提交者邮箱(必须是 GitHub 验证过的邮箱)  
      commit_message: ${{ github.event.head_commit.message }} # 继承原始提交信息  

关键细节

  • 邮箱必须为 GitHub 验证过的地址:若使用默认值,会导致邮箱与 GPG 密钥中的 UID 不匹配,最终签名显示 unverified。即使在密钥中添加该 UID,未经验证的邮箱仍无法通过 GitHub 校验。

部署完成后,向源仓库推送代码,Workflow 会自动构建并推送到目标仓库,所有提交均会附带 GPG 签名并显示 verified

附录:完整 Workflow 示例

如需复用 Hugo 部署方案,可直接使用自定义行动,并按以下 YAML 配置 Workflow(注意替换 secrets 和仓库名):

name: 博客部署  

on:  
  push:  
    branches:  
      - main  # 监听主分支推送  
  workflow_dispatch:  # 支持手动触发  

jobs:  
  build:  
    runs-on: ubuntu-latest  
    steps:  
      - name: 拉取代码  
        uses: actions/checkout@v3  
        with:  
          submodules: true  # 包含子模块(如主题)  
          fetch-depth: 0     # 获取完整提交历史  
          ref: main          # 拉取主分支代码  

      - name: 安装 Hugo  
        uses: peaceiris/actions-hugo@v2  
        with:  
          hugo-version: "0.108.0"  # 指定 Hugo 版本  
          extended: true           # 启用扩展版本(支持 SCSS 等)  

      - name: 构建网站  
        run: hugo --minify         # 生成压缩后的静态文件  

      - name: 导入 GPG 密钥  
        uses: crazy-max/ghaction-import-gpg@v6  
        with:  
          gpg_private_key: ${{ secrets.GPG_PRIVATE_KEY }}  
          passphrase: ${{ secrets.PASSPHRASE }}  
          git_user_signingkey: true  
          git_commit_gpgsign: true  
          fingerprint: ${{ secrets.FINGERPRINT }}  

      - name: 部署到 GitHub Pages  
        uses: timerring/actions-gh-pages@v5.0.0  
        with:  
          personal_token: ${{ secrets.PERSONAL_TOKEN }}  
          external_repository: timerring/blog  # 目标仓库:你的用户名/仓库名  
          publish_branch: main                 # 部署到主分支  
          publish_dir: ./public                # 构建产物目录  
          user_name: "GitHub Action"           # 提交者姓名(任意,但需与 GPG 密钥 UID 兼容)  
          user_email: ${{ secrets.USER_EMAIL }} # 必须为 GitHub 验证邮箱  
          commit_message: "[skip ci] ${{ github.event.head_commit.message }}"  

通过以上配置,即可在 GitHub Pages 部署流程中实现 GPG 签名验证,确保代码提交的真实性和完整性。

【版权声明】本文为华为云社区用户原创内容,未经允许不得转载,如需转载请自行联系原作者进行授权。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。