Files
ykxmz/docs/EzHub-SSH诊断报告.md
xmz7891 94252ca156 加 EzHub SSH 诊断报告(给服务端运维看)
结论:EzHub 的 22 端口上是**系统 OpenSSH 9.6**,不是 Forgejo 内置的
SSH 服务。Forgejo 把公钥存在自己数据库里,不会写进
git 用户的 authorized_keys,而 sshd 也没配 AuthorizedKeysCommand
去问 Forgejo —— 所以网页上加了公钥也不生效。

判定依据(客户端就能测出来):
  1. ssh -vv 显示 remote software version = OpenSSH_9.6p1 Ubuntu
     (内置 SSH 会带自己的标识,且只支持 publickey,不提供 password)
  2. 服务端声明 Authentications that can continue: publickey,password
     —— password 是系统 sshd 的默认行为
  3. 只有 22 端口开,2222/2022 都不通(内置 SSH 默认在 2222)
  4. 网页注册的密钥指纹和客户端完全一致,客户端也确实送出了公钥,
     但仍被拒

报告里给了两种修法(开启内置 SSH / 给 sshd 配 AuthorizedKeysCommand)、
先手动验证命令能不能跑通的办法、以及 /var/log/auth.log 该看什么。
也说明了这不紧急:HTTPS + 令牌目前完全可用。
2026-10-07 12:56:47 +08:00

217 lines
5.7 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.
# EzHub SSH 无法认证 —— 诊断报告
> 给 EzHub 运维看的。客户端的证据都在这,含完整复现步骤。
---
## 结论先说
**EzHub 的 SSH 是系统 OpenSSH 在处理,但它的 `git` 用户 `authorized_keys`
里没有网页上注册的公钥。**
Forgejo/Gitea 把公钥存在**自己的数据库**里,不会自动写进
`~git/.ssh/authorized_keys`。要么开启内置 SSH 服务,
要么给 sshd 配 `AuthorizedKeysCommand` 去问 Forgejo。现在两个都没做,
所以公钥加了也没用。
---
## 客户端证据
### 1. 密钥是对的
```
EzHub 网页上注册的:
id=1 title=ykxmz
key=ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIMFMh2Zqwm+8KFhU3DhzhOO5Sx7cIzybYqUsrbt1c3ly ykxmz-ezhub
fingerprint=SHA256:Acmu49YQcjw3m5WefOXSBzYNY2WPHLL2vvhnlYRAttA
创建于=2026-10-07T04:22:13Z
客户端本机的:
key=ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIMFMh2Zqwm+8KFhU3DhzhOO5Sx7cIzybYqUsrbt1c3ly ykxmz-ezhub
fingerprint=SHA256:Acmu49YQcjw3m5WefOXSBzYNY2WPHLL2vvhnlYRAttA
```
**指纹完全一致**,公钥内容逐字符相同。(通过
`GET /api/v1/user/keys` 读的,不是截图对比。)
### 2. 客户端确实把钥匙送出去了
`ssh -vv` 的输出:
```
debug1: Offering public key: /c/Users/shu/.ssh/id_ed25519_ezhub
ED25519 SHA256:Acmu49YQcjw3m5WefOXSBzYNY2WPHLL2vvhnlYRAttA explicit
```
### 3. 服务端拒绝了
```
debug1: Authentications that can continue: publickey,password
debug1: Authentications that can continue: publickey,password
Permission denied, please try again.
git@git.261826.xyz: Permission denied (publickey,password).
```
### 4. 服务端是系统 OpenSSH,不是 Forgejo 内置的
```
debug1: Remote protocol version 2.0,
remote software version OpenSSH_9.6p1 Ubuntu-3ubuntu13.19
```
**这条是判定的关键。** Forgejo/Gitea 内置的 SSH 服务
(`START_SSH_SERVER = true`)banner 会带自己的标识,
而且**只支持 publickey**,不会提供 `password` 这个选项。
现在服务端说 `publickey,password` —— 这是 Ubuntu 系统 sshd 的默认行为,
说明 22 端口上是系统 OpenSSH 在接,跟 Forgejo 无关。
### 5. 只用 22 端口
```
22 : 开
2222 : 不通
2022 : 不通
22022 : 不通
```
说明 Forgejo 没开内置 SSH(内置的默认在 2222)。
---
## 复现步骤
```bash
ssh -vv -T git@git.261826.xyz
# 观察三行:
# Remote protocol version ... OpenSSH_9.6p1 Ubuntu <- 系统 sshd
# Offering public key: ... SHA256:Acmu49YQ... <- 钥匙送出去了
# Authentications that can continue: publickey,password <- 被拒
# 最后 Permission denied
```
用 `git` 也一样:
```bash
GIT_SSH_COMMAND='ssh -v' git ls-remote ssh://git@git.261826.xyz/xmz/ykxmz.git
# fatal: Could not read from remote repository.
```
---
## 服务端怎么修(任选一种)
### 方案 A:开启内置 SSH 服务(推荐,最省事)
编辑 Forgejo 的 `app.ini`(通常在 `/etc/forgejo/app.ini`
或 `/var/lib/forgejo/custom/conf/app.ini`):
```ini
[server]
START_SSH_SERVER = true
SSH_PORT = 2222
SSH_LISTEN_HOST = 0.0.0.0
```
然后:
```bash
systemctl restart forgejo
# 放行防火墙
ufw allow 2222/tcp # 或 firewall-cmd / 安全组放行
# 确认在监听
ss -lntp | grep 2222
```
**注意**:开启后克隆地址会变成
`ssh://git@git.261826.xyz:2222/xmz/ykxmz.git`(**带端口**)。
如果希望用户不带端口,要么把内置服务直接放在 22 上
(那就得让系统 sshd 让位),要么用方案 B。
### 方案 B:继续用系统 OpenSSH,让它去问 Forgejo
在 `/etc/ssh/sshd_config` 里加:
```apache
AuthorizedKeysCommand /usr/bin/forgejo keys -e git -u %u -t %t -k %k
AuthorizedKeysCommandUser git
```
**路径按实际改**。先确认二进制在哪:
```bash
which forgejo gitea
# 常见位置:
# /usr/bin/forgejo
# /usr/local/bin/forgejo
# /usr/local/bin/gitea
```
也可以先手动试一下命令能不能跑通(把 `<你的公钥>` 换成实际内容):
```bash
sudo -u git /usr/bin/forgejo keys -e git -u git -t ssh-ed25519 -k '<你的公钥>'
# 能返回一行 command="..." 开头的 authorized_keys 格式,就说明对了
```
如果报 `command not found` 或权限错,就是路径或用户不对。
然后:
```bash
sshd -t # 先验证配置语法
systemctl reload ssh # 或 systemctl reload sshd
```
**注意 `AuthorizedKeysCommandUser` 必须是 Forgejo 能读数据库的那个用户**
(一般就是运行 Forgejo 的用户,常是 `git`)。配错会静默失败,
日志在 `/var/log/auth.log`。
---
## 排查时可以先看这几处
```bash
# 1. Forgejo 当前的 SSH 相关配置
grep -A8 '^\[server\]' /etc/forgejo/app.ini
# 2. sshd 有没有配 AuthorizedKeysCommand
grep -i -A2 authorizedkeys /etc/ssh/sshd_config
# 3. git 用户的 authorized_keys 到底有没有内容
sudo ls -la ~git/.ssh/
sudo cat ~git/.ssh/authorized_keys
# 如果这个文件不存在或是空的 —— 就是本文说的问题
# 4. Forgejo 有没有在内置 SSH 上监听
ss -lntp | grep -E ':(22|2222)'
# 5. 认证失败的具体原因(最有用)
sudo tail -50 /var/log/auth.log | grep -i ssh
```
`/var/log/auth.log` 里会明确写是
`Failed publickey for git` 还是 `invalid user`,
一看就清楚。
---
## 附:客户端用的公钥
```
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIMFMh2Zqwm+8KFhU3DhzhOO5Sx7cIzybYqUsrbt1c3ly ykxmz-ezhub
```
指纹 `SHA256:Acmu49YQcjw3m5WefOXSBzYNY2WPHLL2vvhnlYRAttA`。
**不用再让客户端换密钥或重加** —— 网页上那条已经是对的。
---
## 补充:目前用 HTTPS + 令牌可以正常工作
修 SSH 之前,客户端改用 HTTPS + 访问令牌推代码是通的
(`write:repository` 权限),内容完全一样,不影响使用。
所以这个问题**不紧急**,方便的时候再修。