Files
2026-08-20 23:42:02 +08:00

174 lines
6.3 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# GiteaSSH / 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 "<scripts>/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 "<scripts>/test-ssh.ps1" -RemoteUrl "<SSH仓库URL>"
```
## 二、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 "<scripts>/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
```
## 四、TokenHTTPS 推送)
与密钥验证令牌不同:这是 **访问令牌**(设置 → 应用)。
- 用户名: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 "<scripts>/verify-gitea-keys.ps1" `
-GpgToken "<gpg>" -SshToken "<ssh>" -KeyId "<key_id>"
```
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` 等)