2cddf06b6c
Co-authored-by: 旅行呀~ <travelxiao@qq.com>
174 lines
6.3 KiB
Markdown
174 lines
6.3 KiB
Markdown
# 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 "<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
|
||
```
|
||
|
||
## 四、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 "<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` 等)
|