diff --git a/backend/internal/sshkey/service.go b/backend/internal/sshkey/service.go index f1b9d8a..18e5783 100644 --- a/backend/internal/sshkey/service.go +++ b/backend/internal/sshkey/service.go @@ -146,11 +146,7 @@ func (s *Service) AuthorizedPublicKey(ctx context.Context, reference string) (st if err != nil { return "", err } - publicKey, err := ssh.NewPublicKey(signer.PublicKey()) - if err != nil { - return "", fmt.Errorf("编码 SSH 公钥失败:%w", err) - } - return strings.TrimSpace(string(ssh.MarshalAuthorizedKey(publicKey))), nil + return strings.TrimSpace(string(ssh.MarshalAuthorizedKey(signer.PublicKey()))), nil } func (s *Service) List(ctx context.Context) ([]Metadata, error) { if s == nil || s.store == nil { diff --git a/backend/internal/sshkey/service_test.go b/backend/internal/sshkey/service_test.go index 7719c93..8e6a091 100644 --- a/backend/internal/sshkey/service_test.go +++ b/backend/internal/sshkey/service_test.go @@ -35,6 +35,14 @@ func TestServiceCreatesListsValidatesAndDeletesSSHKey(t *testing.T) { if err != nil || validated.Fingerprint != created.Fingerprint { t.Fatalf("SSH 私钥引用校验失败:metadata=%+v err=%v", validated, err) } + authorized, err := service.AuthorizedPublicKey(t.Context(), created.Reference) + if err != nil { + t.Fatalf("读取 SSH 公钥失败:%v", err) + } + publicKey, _, _, _, err := ssh.ParseAuthorizedKey([]byte(authorized)) + if err != nil || ssh.FingerprintSHA256(publicKey) != created.Fingerprint { + t.Fatalf("SSH 公钥指纹不匹配:fingerprint=%s err=%v", ssh.FingerprintSHA256(publicKey), err) + } if err := service.Delete(t.Context(), created.ID); err != nil { t.Fatalf("删除 SSH 私钥失败:%v", err) } diff --git a/doc/Scert整改任务执行清单.md b/doc/Scert整改任务执行清单.md index 4975f63..92e18b4 100644 --- a/doc/Scert整改任务执行清单.md +++ b/doc/Scert整改任务执行清单.md @@ -1166,3 +1166,14 @@ P0-05 从 `[!]` 调整为 `[~]`,并未标记完成;P0-04 剩余门禁和全 - [ ] 未开始:证书文件推送、Nginx 配置校验/重载、失败回滚、真实多服务器部署和最终生产门禁。 - [!] 第二台真实服务器仍不可用,不以虚构数据替代多服务器生产验收。 - [!] 总体验收不得升级:仍为 **P0-03 完成,待复审**,没有新增 `[✓]`。 + +## 本轮实机阻塞修复进度(2026-09-30,Ed25519 公钥编码) + +总体验收继续保持 **P0-03:完成,待复审**。实机日志已确认前一轮 502 的真实根因,本轮完成代码修复和专项回归,尚未重新部署复测。 + +- [x] 已定位:`AuthorizedPublicKey` 将 `ssh.Signer.PublicKey()` 错误再次传给 `ssh.NewPublicKey`,导致 `ssh: unsupported key type ssh.ed25519PublicKey`。 +- [x] 已完成,等待复审:改为直接使用 `ssh.MarshalAuthorizedKey(signer.PublicKey())` 输出授权公钥。 +- [x] 已完成:新增 Ed25519 私钥授权公钥读取及指纹一致性测试;`go test ./internal/sshkey ./internal/deployment ./internal/httpapi` 通过。 +- [~] 进行中:重新执行全量检查、构建 Linux amd64 候选包、部署并通过现有服务器记录复测。 +- [ ] 未开始:证书推送、Nginx 配置校验/重载、失败回滚、真实多服务器部署和最终生产门禁。 +- [!] 总体验收不得升级:仍为 **P0-03 完成,待复审**,没有新增 `[✓]`。 diff --git a/doc/Scert整改合并优化清单.md b/doc/Scert整改合并优化清单.md index 263948d..b86d118 100644 --- a/doc/Scert整改合并优化清单.md +++ b/doc/Scert整改合并优化清单.md @@ -1814,3 +1814,14 @@ P0-11 生产验收门禁 - [ ] 未开始:证书文件推送、Nginx 配置校验/重载、失败回滚、真实多服务器部署和最终生产门禁。 - [!] 第二台真实服务器仍不可用,不以虚构数据替代多服务器生产验收。 - [!] 总体验收不得升级:仍为 **P0-03 完成,待复审**,没有新增 `[✓]`。 + +## 本轮实机阻塞修复进度(2026-09-30,Ed25519 公钥编码) + +总体验收继续保持 **P0-03:完成,待复审**。实机日志已确认前一轮 502 的真实根因,本轮完成代码修复和专项回归,尚未重新部署复测。 + +- [x] 已定位:`AuthorizedPublicKey` 将 `ssh.Signer.PublicKey()` 错误再次传给 `ssh.NewPublicKey`,导致 `ssh: unsupported key type ssh.ed25519PublicKey`。 +- [x] 已完成,等待复审:改为直接使用 `ssh.MarshalAuthorizedKey(signer.PublicKey())` 输出授权公钥。 +- [x] 已完成:新增 Ed25519 私钥授权公钥读取及指纹一致性测试;`go test ./internal/sshkey ./internal/deployment ./internal/httpapi` 通过。 +- [~] 进行中:重新执行全量检查、构建 Linux amd64 候选包、部署并通过现有服务器记录复测。 +- [ ] 未开始:证书推送、Nginx 配置校验/重载、失败回滚、真实多服务器部署和最终生产门禁。 +- [!] 总体验收不得升级:仍为 **P0-03 完成,待复审**,没有新增 `[✓]`。