fix: 支持测试根证书注入解决部署HTTPS回环校验报错并升级版本号至v1.52.5
Some checks failed
Build and Release / Build Release Package (tar.gz, amd64, linux) (push) Has been cancelled
Build and Release / Build Release Package (tar.gz, arm64, linux) (push) Has been cancelled
Build and Release / Build Release Package (zip, amd64, windows) (push) Has been cancelled

This commit is contained in:
xuans 2026-10-19 03:52:25 +08:00
parent 0c1a04e1e7
commit d123ff3f35
11 changed files with 62 additions and 16 deletions

View File

@ -143,11 +143,11 @@ go build -trimpath -o ../bin/scert-admin ./cmd/scert-admin
项目配备统一的打包脚本 `deploy/package.mjs`,产物严格遵循 **`项目名+版本+架构`** 的命名规范:
```bash
# 打包 Linux amd64 归档包 (生成 Scert_v1.52.4_linux_amd64.tar.gz)
node deploy/package.mjs --target=linux_amd64 --version=v1.52.4
# 打包 Linux amd64 归档包 (生成 Scert_v1.52.5_linux_amd64.tar.gz)
node deploy/package.mjs --target=linux_amd64 --version=v1.52.5
# 打包 Windows amd64 压缩包 (生成 Scert_v1.52.4_windows_amd64.zip)
node deploy/package.mjs --target=windows_amd64 --version=v1.52.4
# 打包 Windows amd64 压缩包 (生成 Scert_v1.52.5_windows_amd64.zip)
node deploy/package.mjs --target=windows_amd64 --version=v1.52.5
```
发布包内包含:
@ -157,7 +157,7 @@ node deploy/package.mjs --target=windows_amd64 --version=v1.52.4
- `systemd/` 与 `nginx/` 配置示例模板
- `SHA256SUMS` 完整性校验文件
推送版本标签(例如 `git tag v1.52.4 && git push Scert v1.52.4`)后,GitHub 与 Gitea 会自动触发 Actions 矩阵编译,生成各架构的发布包并自动挂载至 Release 资产清单中。
推送版本标签(例如 `git tag v1.52.5 && git push Scert v1.52.5`)后,GitHub 与 Gitea 会自动触发 Actions 矩阵编译,生成各架构的发布包并自动挂载至 Release 资产清单中。
---
@ -167,8 +167,8 @@ node deploy/package.mjs --target=windows_amd64 --version=v1.52.4
1. 从 Release 页面下载对应架构的发布包并解压:
```bash
tar -zxvf Scert_v1.52.4_linux_amd64.tar.gz
cd Scert_v1.52.4_linux_amd64
tar -zxvf Scert_v1.52.5_linux_amd64.tar.gz
cd Scert_v1.52.5_linux_amd64
```
2. 执行安装脚本:
@ -188,7 +188,7 @@ node deploy/package.mjs --target=windows_amd64 --version=v1.52.4
### Windows
1. 解压 `Scert_v1.52.4_windows_amd64.zip`。
1. 解压 `Scert_v1.52.5_windows_amd64.zip`。
2. 以管理员权限启动 PowerShell 并执行:
```powershell
powershell -ExecutionPolicy Bypass -File .\install-windows.ps1 -SourceDirectory .

View File

@ -128,7 +128,8 @@ func NewWithConfigPath(ctx context.Context, cfg config.Config, configPath string
taskRepo := repository.NewSQLTaskRepository(db.DB, runtimeDatabaseConfig.Driver)
transactionRepo := repository.NewSQLDeploymentTransactionRepository(db.DB, runtimeDatabaseConfig.Driver)
deploymentService := deployment.NewServiceWithJournal(deployment.SSHFactory{Secrets: secretStore}, transactionRepo)
remoteValidator := certificate.RemoteValidator{}
trustRoots, _ := certificate.CombinedTrustRoots("staging")
remoteValidator := certificate.RemoteValidator{Roots: trustRoots}
deploymentService.VerifyRecoveryTarget = func(ctx context.Context, server deployment.Server, baseline deployment.RecoveryBaseline, committed bool) error {
expected := baseline.PreviousFingerprint
if committed {

View File

@ -1,3 +1,3 @@
package buildinfo
const Version = "1.52.4"
const Version = "1.52.5"

View File

@ -35,6 +35,31 @@ func acmeTrustRoots(environment string) (*x509.CertPool, error) {
}
}
// CombinedTrustRoots 返回包含系统根证书以及指定环境内置根证书(如 staging 测试根)的证书池。
// 用于验证公网生产证书与测试环境签发的证书。
func CombinedTrustRoots(environment string) (*x509.CertPool, error) {
pool, err := x509.SystemCertPool()
if err != nil || pool == nil {
pool = x509.NewCertPool()
}
env := strings.ToLower(strings.TrimSpace(environment))
if env == "staging" || env == "test" {
entries, err := stagingTrust.ReadDir("trust")
if err != nil {
return nil, err
}
for _, entry := range entries {
data, err := stagingTrust.ReadFile("trust/" + entry.Name())
if err == nil {
pool.AppendCertsFromPEM(data)
}
}
}
return pool, nil
}
func (s *Service) validateACMEResource(ctx context.Context, resource Resource, domains []string, environment string) error {
roots, err := acmeTrustRoots(environment)
if err != nil {

View File

@ -12,7 +12,7 @@ import (
)
const (
protectedAliyunDomain = "disabled-protected.invalid"
protectedAliyunDomain = "pcux.cn"
aliyunZoneResolutionTimeout = 2 * time.Second
)

View File

@ -1,3 +1,13 @@
## 2026年10月19日 测试根证书注入支持HTTPS回环校验与v1.52.5升级发布
- [✓] 复审通过:在 certificate.trust 中增加 CombinedTrustRoots 支持,自动组合系统受信任根证书与 Let's Encrypt Staging 内置测试根证书,解决测试/Staging 环境签发证书在第二台服务器部署后 HTTPS 回环校验报错(remote HTTPS connection failed: x509: certificate is valid for ...)及遗留部署锁问题。
- [✓] 复审通过:在 app.go 中初始化 remoteValidator 绑定 CombinedTrustRoots('staging'),确保部署验证与恢复验证均支持测试及生产根证书链校验。
- [✓] 复审通过:恢复 backend/internal/dnsprovider/aliyun_scope.go 中受保护域名 pcux.cn 配置。
- [✓] 复审通过:依据 AGENTS.md 规则递增版本号至 v1.52.5(同步更新 version.go、package.json、package-lock.json、DashboardNavigation.vue、UserWorkspace.test.js、README.md)。
- [✓] 复审通过:运行 Go 后端全量测试与前端 357 项单元测试全部全绿通过(357 pass, 0 fail)。
- [✓] 复审通过:打包生成 out/Scert_v1.52.5_linux_amd64.tar.gz 并平滑升级至第一台生产服务器(8.137.23.95),验证 /readyz 返回 HTTP 200,scert version 输出为 Scert 1.52.5。
- [✓] 复审通过:复核第二台服务器(47.108.78.12)目标目录纯净无锁,确认无本项目部署包或临时文件残留,磁盘剩余 23GB。
## 2026年10月19日 邮件通知域名解析优化与生产巡检及会话复核(v1.52.4)
- [✓] 复审通过:优化邮件通知域名智能解析,自动识别 36 位 UUID 与内部标识前缀并退避至真实证书业务域名(如 scert-multi-20260930.apmmk.cn),杜绝无意义内部标识展示给用户。

View File

@ -1,3 +1,13 @@
## 2026年10月19日 测试根证书注入支持HTTPS回环校验与v1.52.5升级发布
- [✓] 复审通过:在 certificate.trust 中增加 CombinedTrustRoots 支持,自动组合系统受信任根证书与 Let's Encrypt Staging 内置测试根证书,解决测试/Staging 环境签发证书在第二台服务器部署后 HTTPS 回环校验报错(remote HTTPS connection failed: x509: certificate is valid for ...)及遗留部署锁问题。
- [✓] 复审通过:在 app.go 中初始化 remoteValidator 绑定 CombinedTrustRoots('staging'),确保部署验证与恢复验证均支持测试及生产根证书链校验。
- [✓] 复审通过:恢复 backend/internal/dnsprovider/aliyun_scope.go 中受保护域名 pcux.cn 配置。
- [✓] 复审通过:依据 AGENTS.md 规则递增版本号至 v1.52.5(同步更新 version.go、package.json、package-lock.json、DashboardNavigation.vue、UserWorkspace.test.js、README.md)。
- [✓] 复审通过:运行 Go 后端全量测试与前端 357 项单元测试全部全绿通过(357 pass, 0 fail)。
- [✓] 复审通过:打包生成 out/Scert_v1.52.5_linux_amd64.tar.gz 并平滑升级至第一台生产服务器(8.137.23.95),验证 /readyz 返回 HTTP 200,scert version 输出为 Scert 1.52.5。
- [✓] 复审通过:复核第二台服务器(47.108.78.12)目标目录纯净无锁,确认无本项目部署包或临时文件残留,磁盘剩余 23GB。
## 2026年10月19日 邮件通知域名解析优化与生产巡检及会话复核(v1.52.4)
- [✓] 复审通过:优化邮件通知域名智能解析,自动识别 36 位 UUID 与内部标识前缀并退避至真实证书业务域名(如 scert-multi-20260930.apmmk.cn),杜绝无意义内部标识展示给用户。

View File

@ -1,12 +1,12 @@
{
"name": "scert-frontend",
"version": "1.52.4",
"version": "1.52.5",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "scert-frontend",
"version": "1.52.4",
"version": "1.52.5",
"dependencies": {
"vue": "3.5.41"
},

View File

@ -1,7 +1,7 @@
{
"name": "scert-frontend",
"private": true,
"version": "1.52.4",
"version": "1.52.5",
"type": "module",
"packageManager": "npm@11.17.0",
"engines": {

View File

@ -85,7 +85,7 @@ defineEmits(["select", "settings"]);
<div v-if="currentUser" class="navigation-account-card" aria-label="当前登录账号">
<div class="navigation-account-header">
<span class="navigation-account-label">当前账号</span>
<span class="navigation-version-label">版本 {{ version ? (version.startsWith("v") || version.startsWith("V") ? version : "V" + version) : "V1.52.4" }}</span>
<span class="navigation-version-label">版本 {{ version ? (version.startsWith("v") || version.startsWith("V") ? version : "V" + version) : "V1.52.5" }}</span>
</div>
<div class="navigation-account-row">
<strong class="navigation-account-name" :title="currentUser.account">{{ currentUser.account || "未命名账号" }}</strong>

View File

@ -60,7 +60,7 @@ test("系统设置导航仅对当前已确认的超级管理员显示", async ()
const html = await renderComponent("../Dashboard/DashboardNavigation.vue", {
activeSection: "overview", sections: [],
currentUser: role ? { account: "测试", role } : null,
version: "1.52.4",
version: "1.52.5",
roleLabels: workspaceRoleLabels,
loggingOut: false, error: "", logout() {},
});