Co-authored-by: 旅行呀~ <travelxiao@qq.com>
6.3 KiB
Gitea:SSH / GPG 配置与验证
依据官方文档与 Gitea UI 源码整理(用户侧)。管理员侧签名见文末链接。
- 官方:GPG/SSH Commit Signatures
- 密钥页:
https://<你的Gitea>/user/settings/keys - 信任模型(管理员):
[repository.signing] DEFAULT_TRUST_MODEL(collaborator/committer/collaboratorcommitter)
网页图标含义(官方)
| 图标 | 含义 |
|---|---|
| 灰色开锁 | 数据库中找不到可用于校验的密钥(中文常见:「找不到此签名对应的密钥」) |
| 红色开锁 | 声称已签名,但密钥有问题 / 不可信 |
| 已验证锁 | 签名可被 Gitea 用库中已验证密钥校验,且符合仓库信任模型 |
只「添加」公钥不够。 SSH 用于提交签名识别、以及 GPG 显示已验证,通常都要求在设置页完成 验证(证明持有对应私钥)。见 go-gitea/gitea#20597。
远程 URL
https://git.example.com/owner/repo.git
https://git.example.com:3000/owner/repo.git
git@git.example.com:owner/repo.git
ssh://git@git.example.com:2222/owner/repo.git
HTTPS 非默认端口会写入 GCM host=name:port。详见 Skill 脚本 Parse-GitRemoteUrl。
一、SSH 密钥(推送 + 可选 SSH 签名)
1. 本机生成 / 复用
Skill:ensure-ssh.ps1(默认 ~/.ssh/id_ed25519)。
2. 添加到 Gitea
- 设置 → SSH / GPG 密钥 → 增加密钥
- 粘贴公钥(
.pub一整行) - 保存
3. 验证 SSH 密钥(必须,否则 SSH 签名提交会「找不到密钥」)
- 在该密钥旁点 验证
- 复制页面令牌(每次不同,勿写入仓库)
- 官方 UI 给出的命令形态(见
keys_ssh.tmpl):
echo -n 'TOKEN' | ssh-keygen -Y sign -n gitea -f /path/to/id_ed25519
Windows 推荐用 Skill 脚本(避免 PowerShell/echo 编码问题):
powershell -NoProfile -ExecutionPolicy Bypass -File "<scripts>/verify-ssh-challenge.ps1" `
-Token "TOKEN_FROM_PAGE" `
-KeyPath "$env:USERPROFILE\.ssh\id_ed25519"
- 将输出的
-----BEGIN SSH SIGNATURE-----… 整段贴回页面 → 验证 - 成功后应出现「已验证」标记
也可用公钥路径(agent 持有私钥时):-KeyPath 指向 .pub 亦可(OpenSSH 会经 agent 签名)。
4. 测试推送认证(与「签名验证」不同)
powershell -NoProfile -ExecutionPolicy Bypass -File "<scripts>/test-ssh.ps1" -RemoteUrl "<SSH仓库URL>"
二、GPG 密钥(本 Skill 默认的提交签名方式)
1. 本机生成 / 复用
Skill:ensure-gpg.ps1。导出公钥:
& "$env:ProgramFiles\Git\usr\bin\gpg.exe" --armor --export KEY_ID
2. 添加到 Gitea
- 设置 → SSH / GPG 密钥 → GPG 区 增加密钥
- 粘贴 ASCII 公钥(
BEGIN PGP PUBLIC KEY BLOCK) - 保存;确认 匹配身份 含 Gitea 账号已验证邮箱(如
travelxiao@qq.com)
3. 验证 GPG 密钥(必须)
官方 UI 命令形态(见 keys_gpg.tmpl):
echo "TOKEN" | gpg -a --default-key KEY_ID --detach-sig
注意:这里是 带换行 的 echo "TOKEN"(与 SSH 的 echo -n 不同)。
powershell -NoProfile -ExecutionPolicy Bypass -File "<scripts>/verify-gpg-challenge.ps1" `
-Token "TOKEN_FROM_PAGE" `
-KeyId "5996DA789B43D451"
将 -----BEGIN PGP SIGNATURE----- … 贴回 → 验证。
4. 本地 Git 使用同一把 GPG 钥签名
git config user.signingkey KEY_ID # 仓库 local;或按需 --global
git config commit.gpgsign true
# 使用 GPG 时不要设置 gpg.format=ssh
git config --unset gpg.format # 若曾设为 ssh
Skill 的 prepare-commit.ps1 / Init 流程会设置 local user.signingkey 与 commit.gpgsign。
三、排错:「找不到此签名对应的密钥」
按官方说明,灰色开锁 = Gitea 库中没有可用来校验该签名的密钥。常见原因:
- 公钥已添加但 未验证 → 先完成上一节验证
- 本地
user.signingkey/gpg.format与网页上的密钥不是同一把- GPG:
gpg.format未设或为 openpgp,signingkey= 网页 Key ID - SSH 签名:
gpg.format=ssh,且对应 SSH 密钥已在 Gitea 验证
- GPG:
- 提交作者邮箱不在 Gitea 账号邮箱列表 / 与 GPG uid 不一致 → 在 Gitea 添加并验证该邮箱
- 仓库 信任模型(
DEFAULT_TRUST_MODEL)导致虽能识别密钥但不显示为可信(管理员配置;默认常为collaborator) - 验证成功后请 硬刷新(Ctrl+F5);旧提交可能仍显示开锁,新提交才变绿
检查本机:
git config --get user.signingkey
git config --get gpg.format
git config --get user.email
git log -1 --show-signature
四、Token(HTTPS 推送)
与密钥验证令牌不同:这是 访问令牌(设置 → 应用)。
- 用户名:Gitea 登录名(档案
gitUsername) - 密码:访问令牌
- 本机:
store-token.ps1(DPAPI),禁止发到对话
五、Agent 流程(密钥验证 — 主动询问)
HTTPS 访问令牌仍禁止进对话。Gitea 页面上的 验证挑战令牌(一次性)允许 Agent 主动索取。
ensure-ssh.ps1/ensure-gpg.ps1→ 用户把公钥加到 Gitea- Agent 主动询问:
- GPG 验证页令牌
- SSH 验证页令牌(与 GPG 不同)
- 收到后执行:
powershell -NoProfile -ExecutionPolicy Bypass -File "<scripts>/verify-gitea-keys.ps1" `
-GpgToken "<gpg>" -SshToken "<ssh>" -KeyId "<key_id>"
- 把生成的签名块发给用户,指导贴回 Gitea → 验证
- 用户确认「已验证」后,本地
commit.gpgsign+user.signingkey test-ssh.ps1测推送通道
缺令牌时脚本输出 need_token / waiting_for_tokens,Agent 继续追问,不要跳过。
六、管理员参考(非本机 Skill 必做)
服务器可用 [repository.signing] 让 Gitea 自己签 merge 等提交;见官方文档。用户侧密钥验证不依赖该项,但信任模型会影响「已验证」展示。
官方文档: