让 Git 提交自动带「Verified」徽章:GitHub SSH 签名免 ssh-agent 实战

📅 2026/7/8 2:03:49 👁️ 阅读次数 📝 编程学习
让 Git 提交自动带「Verified」徽章:GitHub SSH 签名免 ssh-agent 实战

你有没有遇到过这种情况:兴冲冲给 Git 配好 SSH 签名,结果一提交就报错Couldn't get agent socket?,然后被「每次开终端先eval "$(ssh-agent -s)"ssh-add」的繁琐流程劝退?

本文讲一个更简单的方案:把user.signingkey直接指向私钥文件,从此git commit全自动签名,彻底不需要 ssh-agent、不需要 Windows 服务、不需要任何前置命令


为什么要给提交签名

没签名的提交,GitHub 上长这样:

liuweiqing committed 2 minutes ago

签名之后:

liuweiqing committed 2 minutes ago ✓ Verified

那个绿色Verified徽章的意义是:这个提交确实出自你本人,没有被中间人篡改或冒名顶替。在开源协作、团队 CI 校验、供应链安全越来越受重视的今天,签名提交正在从「加分项」变成「默认项」。

GitHub 支持三种签名方式:GPG / SSH / S/MIME。本文聚焦最省事的SSH 签名——前提是你已经有一把 SSH 密钥(大概率你已经在用它git push了)。


背景:SSH 签名的两个阶段

Git 的 SSH 签名机制分两步:

  1. 签名git调用ssh-keygen -Y sign,用你的私钥对提交内容生成签名。
  2. 验证git log --show-signature调用ssh-keygen -Y verify,用allowed_signers文件把邮箱映射到公钥来校验。

问题就出在第 1 步。Git 默认把user.signingkey当作公钥,交给ssh-keygen去签名——但ssh-keygen只能从 ssh-agent 拿私钥,没法直接读私钥文件。于是:

  • 没有 agent → 报错Couldn't get agent socket?
  • 有了 agent 但没ssh-add→ 还是报错

这就是「每次开终端都要折腾 agent」这个坏习惯的来源。


关键技巧:让 signingkey 直接指向私钥文件

绕开 agent 的核心就一句话:

user.signingkey设成私钥文件路径(如~/.ssh/id_rsa),而不是公钥内容。

signingkey是一个文件路径时,ssh-keygen直接读取该文件里的私钥完成签名,完全不需要 agent 中转。这一改,整个繁琐链路就消失了。


完整配置步骤(从 0 到 Verified)

以下示例邮箱为liuweiqing147@gmail.com,请替换成你自己的。

1. 确认已有 SSH 密钥

ls~/.ssh/*.pub# 输出示例:/c/Users/13963/.ssh/id_rsa.pub

如果没有,先生成一把(推荐复用你登录 GitHub 的那把,省事):

# 仅当你还没有密钥时才需要ssh-keygen-trsa-b4096-C"you@example.com"

2. 写入 Git 全局签名配置

# 告诉 git 用 SSH 格式签名gitconfig--globalgpg.formatssh# ★ 关键:signingkey 指向「私钥文件」,不是公钥内容gitconfig--globaluser.signingkey ~/.ssh/id_rsa# 提交和 tag 自动签名(之后不需要再手动加 -S)gitconfig--globalcommit.gpgsigntruegitconfig--globaltag.gpgsigntrue

3. 创建 allowed_signers 文件

这是 SSH 签名必须的映射文件,把邮箱和公钥对应起来(验证阶段要用):

gitconfig--globalgpg.ssh.allowedSignersFile ~/.ssh/allowed_signers# 把你自己的邮箱 + 公钥写进去printf'%s namespaces="git" %s\n'\"liuweiqing147@gmail.com"\"$(cat~/.ssh/id_rsa.pub)">~/.ssh/allowed_signers

文件内容形如:

liuweiqing147@gmail.com namespaces="git" ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQC...

4. 完成 —— 不需要启动任何 agent

到此为止,配置全部完成。没有 ssh-agent、没有 Windows 服务、没有前置命令。


验证签名链路

随便建个临时仓库测一下(不开 agent,纯全局配置):

cd/tmp&&rm-rfgit-check&&mkdirgit-check&&cdgit-checkgitinit-qgitcommit-q--allow-empty-S-m"test signed commit"# 或直接 git commit(已全局开启)gitlog --show-signature-1

看到这行就成功了:

Good "git" signature for liuweiqing147@gmail.com with RSA key SHA256:V6n/4TEs...8A

如果显示Good,说明签名 + 本地验证全链路打通。


还差你最后一步:把公钥加到 GitHub

Git 这边配好了,但 GitHub不知道这把公钥是你的,所以提交推上去仍是Unverified。需要在 GitHub 网页单独登记一次「签名密钥」:

  1. 复制公钥内容:
    cat~/.ssh/id_rsa.pub
  2. 打开 👉 https://github.com/settings/ssh/new
  3. Title随便填(如laptop-signing
  4. Key type 务必选Signing Key(默认是 Authentication Key,选错不会生效!)
  5. 粘贴公钥 →Add SSH key

⚠️ 即使这把id_rsa已经作为「Authentication key」加过,GitHub 也要求再单独加一次到 Signing keys 区。两者是分开管理的。

加完之后,再git push上来的提交就会显示绿色Verified徽章 🔏


常见坑 & FAQ

现象原因解决
Couldn't get agent socket?signingkey是公钥,git 去找 agent 拿私钥signingkey改成私钥文件路径
本地Good但 GitHub 显示Unverified公钥没加到 GitHub 的Signing keys去 settings/ssh/new,Key type 选 Signing Key 重加
No principal matched/ 验证失败allowed_signers里邮箱和提交邮箱不一致确保allowed_signers邮箱 =git config user.email
私钥有密码时仍提示输入正常,签名时要解锁私钥要么输密码,要么换无密码密钥(注意保管)

关于私钥密码:本文示例用的是无密码密钥,所以签名完全无感。如果你的私钥设了密码,每次签名仍需输一次——这是安全与便利的取舍,按需选择。


总结

让 Git 提交自动带Verified徽章,最省事的配置就这几行:

gitconfig--globalgpg.formatsshgitconfig--globaluser.signingkey ~/.ssh/id_rsa# 私钥文件,免 agent 的关键gitconfig--globalcommit.gpgsigntruegitconfig--globaltag.gpgsigntruegitconfig--globalgpg.ssh.allowedSignersFile ~/.ssh/allowed_signers

再加上 GitHub 网页登记一次 Signing Key,就齐活了。告别 ssh-agent,从此git commit即签名。


本文基于 Windows + Git for Windows 2.53 + OpenSSH 实测验证。其他平台(macOS / Linux)步骤完全一致,区别仅在于密钥路径。