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