GPG 签名部署并验证 GitHub Pages
这周在迁移博客时,了解到 GitHub 存在提交伪造风险,出于安全考虑给仓库添加了 GPG 签名。下面是使用 GPG 签名部署并验证 GitHub Pages 的相关内容。
如何使用 GPG 签名部署并验证 GitHub Pages
主流部署方式有两种:
- 直接将所有源文件推送到 GitHub,通过官方 Action 完成构建部署。
- 将博客源文件与构建产物分离,源文件存放在私有仓库,通过 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 签名验证,确保代码提交的真实性和完整性。
- 点赞
- 收藏
- 关注作者
评论(0)