2026-08-26 06:41:07 +08:00
|
|
|
|
# 压测、告警与生产安全门禁
|
|
|
|
|
|
|
|
|
|
|
|
## 1. 生产配置启动门禁
|
|
|
|
|
|
|
|
|
|
|
|
当`APP_ENV=prod`时,进程在连接外部依赖前执行配置校验,任一条件不满足即拒绝启动:
|
|
|
|
|
|
|
|
|
|
|
|
- OIDC签发方和JWKS地址必须使用HTTPS;
|
|
|
|
|
|
- PostgreSQL连接不能使用`sslmode=disable`;
|
|
|
|
|
|
- Redis必须配置非占位密码;
|
|
|
|
|
|
- API设备凭据必须按设备从受控Secrets/KMS CSI目录解析,生产禁止单一静态开发密钥;
|
|
|
|
|
|
- RTC应用必须使用正式AppID/AppKey和火山正式Token格式;
|
|
|
|
|
|
- Worker必须使用火山RTC HTTPS签名VoiceChat接口以及非占位AK/SK,禁止本地模拟供应商;
|
|
|
|
|
|
- 分页游标和分享签名密钥必须至少32字符、不得使用本地/示例值且彼此不同;
|
|
|
|
|
|
- 对象存储必须启用TLS,内外端点不能指向本机,访问凭据不得使用本地/示例值;
|
|
|
|
|
|
- Callback签名密钥不得使用本地/示例值。
|
|
|
|
|
|
|
|
|
|
|
|
生产密钥不得写入Git、镜像、Compose文件或普通配置文件。部署平台应通过Secret Manager/KMS、短期工作负载身份或只读内存挂载注入,并建立轮换、吊销、双密钥过渡和访问审计。当前仓库只提供启动门禁,不宣称已经接入任何特定云厂商的密钥托管。
|
|
|
|
|
|
|
|
|
|
|
|
所有后端长期敏感配置均支持`NAME_FILE`约定,包括数据库连接串、Redis密码、RTC AppKey、火山AK/SK/临时Token、方舟API Key、对象存储凭据、设备本地开发密钥以及游标、分享、供应商回调和告警签名密钥。文件必须使用容器内绝对路径并小于等于64KiB;同一密钥的`NAME`与`NAME_FILE`同时配置时服务拒绝启动。该能力用于直接消费Docker/Kubernetes Secret或KMS CSI挂载文件,不等同于已经完成某个云厂商的身份授权与轮换验收。
|
|
|
|
|
|
|
|
|
|
|
|
本地开发已通过目录解析器测试验证不同设备密钥隔离、越界引用拒绝、短密钥拒绝,以及原子替换文件后无需重启即可读取新密钥。`scripts/verify-local-secret-rotation.ps1`保留用于验证旧的进程级环境注入路径;两者都不能替代真实KMS/HSM、量产设备注入、双密钥过渡和吊销审计。
|
|
|
|
|
|
|
|
|
|
|
|
## 2. 压测入口
|
|
|
|
|
|
|
|
|
|
|
|
`test/load/api-readiness.js`提供固定到达率压测。`acceptance`配置为50 RPS持续30分钟,门禁为失败率低于0.1%、p95低于500毫秒、p99低于1秒;`smoke`配置用于提交前短测。该数值是研发压测门禁,不是未经真实环境验证的产品SLA。
|
|
|
|
|
|
|
|
|
|
|
|
```powershell
|
|
|
|
|
|
docker run --rm -v "${PWD}/test/load:/scripts:ro" grafana/k6 run `
|
|
|
|
|
|
-e BASE_URL=http://host.docker.internal:58080 `
|
|
|
|
|
|
-e PROFILE=acceptance /scripts/api-readiness.js
|
|
|
|
|
|
|
|
|
|
|
|
# 500次/秒供应商回调,持续10分钟,并对账30万唯一事件
|
|
|
|
|
|
pwsh -NoProfile -File .\scripts\load-provider-callbacks.ps1 `
|
|
|
|
|
|
-Profile acceptance -ConversationPool 100
|
|
|
|
|
|
|
|
|
|
|
|
# 1000活跃通话、500条SSE、10000媒体分片、100并发隐私删除
|
|
|
|
|
|
pwsh -NoProfile -File .\scripts\load-conversation-state.ps1
|
|
|
|
|
|
pwsh -NoProfile -File .\scripts\load-sse-connections.ps1 -Connections 500
|
|
|
|
|
|
pwsh -NoProfile -File .\scripts\load-media-manifest.ps1
|
|
|
|
|
|
pwsh -NoProfile -File .\scripts\load-privacy-delete.ps1
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
如需叠加真实OIDC授权读取,将短期测试令牌通过进程环境传入`ACCESS_TOKEN`。禁止把令牌写进脚本或提交仓库。负载脚本必须使用隔离租户和合成数据;带夹具的包装脚本会在结束后执行数据库对账和精确清理。压测应在与生产容量相近的测试环境执行;本地结果只能形成研发回归基线,不能替代生产容量结论。完整本地结果、夹具边界和失败修正记录见[性能、恢复、安全与兼容性专项验证报告](performance-recovery-security-compatibility.md)。
|
|
|
|
|
|
|
|
|
|
|
|
## 3. Prometheus告警
|
|
|
|
|
|
|
|
|
|
|
|
`deploy/prometheus/rules/platform-alerts.yml`定义以下基础规则:
|
|
|
|
|
|
|
|
|
|
|
|
| 告警 | 条件 | 建议动作 |
|
|
|
|
|
|
|---|---|---|
|
|
|
|
|
|
| `PlatformServiceDown` | 连续2分钟无法抓取服务 | 检查部署、健康依赖和网络 |
|
|
|
|
|
|
| `PlatformHighHTTP5xxRate` | 5分钟窗口5xx高于5%,持续5分钟 | 按服务、路由和trace定位错误 |
|
|
|
|
|
|
| `PlatformHighP95Latency` | 路由p95高于1.5秒,持续10分钟 | 检查数据库、Redis、对象存储和下游供应商 |
|
|
|
|
|
|
| `OutboxDeadLetterPresent` | 存在死信 | 核对错误码,修复后人工重放 |
|
|
|
|
|
|
| `OutboxPendingBacklog` | pending超过100且持续10分钟 | 检查Worker容量及下游可用性 |
|
|
|
|
|
|
| `PrivacyDeletionPartialFailure` | 隐私请求存在`PARTIAL_FAILED` | 立即对账六子系统并保留处置证据 |
|
|
|
|
|
|
| `FirmwareAssignmentFailure` | 存在失败设备 | 暂停批次,分析设备结果,必要时回滚 |
|
|
|
|
|
|
| `FirmwareRolloutStalled` | 运行批次15分钟无更新 | 检查命令投递、设备在线和下载权限 |
|
|
|
|
|
|
|
|
|
|
|
|
业务告警扫描器还会从`provider_dependency_state`生成`PROVIDER_UNAVAILABLE`事件。连续临时失败达到部署阈值后只暂停新启动,不阻断停止与回收;历史网页和普通查询不依赖供应商在线状态。恢复演练必须证明外呼调用数在熔断窗口内不再因新启动增加、停止任务仍有尝试、告警出现,并在供应商恢复后最终收敛。
|
|
|
|
|
|
|
|
|
|
|
|
本地Compose已挂载规则目录,并自动配置Grafana业务、技术、安全三类仪表盘;Prometheus采集API、Callbacks和Worker三类目标。正式环境还需对接告警接收器、值班分组、抑制规则和升级策略,并基于真实容量重新校准阈值。
|
|
|
|
|
|
|
|
|
|
|
|
业务扫描器还生成供应商通知积压和证书到期信号。证书通过`ops_resource_reference`登记为受控引用,只保存引用、核验时间和到期时间,不保存私钥或证书正文;30天内到期为高等级,7天内提升为严重等级。
|
|
|
|
|
|
|
|
|
|
|
|
## 4. 恢复与安全专项入口
|
|
|
|
|
|
|
|
|
|
|
|
```powershell
|
|
|
|
|
|
# 真实pg_dump/pg_restore到隔离数据库并核对迁移、表、外键和关键计数
|
|
|
|
|
|
pwsh -NoProfile -File .\scripts\verify-postgres-restore.ps1
|
|
|
|
|
|
|
|
|
|
|
|
# API/Callbacks/Worker重启、停机Outbox恢复和Redis热状态重建
|
|
|
|
|
|
pwsh -NoProfile -File .\scripts\verify-runtime-recovery.ps1
|
|
|
|
|
|
|
|
|
|
|
|
# 本地长期设备签名密钥轮换,不重建镜像
|
|
|
|
|
|
pwsh -NoProfile -File .\scripts\verify-local-secret-rotation.ps1
|
|
|
|
|
|
|
|
|
|
|
|
# 认证、授权、输入、签名、防重放、安全响应头和日志正文过滤
|
|
|
|
|
|
pwsh -NoProfile -File .\scripts\security-http-smoke.ps1
|
|
|
|
|
|
|
|
|
|
|
|
# 后端依赖可达漏洞、前端依赖、仓库密钥和最终镜像
|
|
|
|
|
|
docker run --rm -v "${PWD}:/src" -w /src golang:1.26.6-alpine `
|
|
|
|
|
|
sh -c "go run golang.org/x/vuln/cmd/govulncheck@v1.1.4 ./..."
|
|
|
|
|
|
npm --prefix web audit --audit-level=high
|
|
|
|
|
|
docker run --rm -v "${PWD}:/src" zricethezav/gitleaks:v8.30.1 `
|
|
|
|
|
|
detect --source=/src --config=/src/.gitleaks.toml --no-banner
|
2026-09-06 17:04:11 +08:00
|
|
|
|
docker run --rm -v "${PWD}:/src" `
|
|
|
|
|
|
-v data-terminal-trivy-cache:/root/.cache/trivy aquasec/trivy:0.74.0 `
|
|
|
|
|
|
config --ignorefile /src/.trivyignore.yaml --exit-code 1 `
|
|
|
|
|
|
--severity HIGH,CRITICAL /src
|
2026-08-26 06:41:07 +08:00
|
|
|
|
docker run --rm -v /var/run/docker.sock:/var/run/docker.sock `
|
|
|
|
|
|
-v data-terminal-trivy-cache:/root/.cache/trivy aquasec/trivy:0.74.0 `
|
|
|
|
|
|
image --scanners vuln --ignore-unfixed --severity HIGH,CRITICAL `
|
|
|
|
|
|
data-terminal-cloud-api:latest
|
|
|
|
|
|
docker run --rm -v /var/run/docker.sock:/var/run/docker.sock `
|
|
|
|
|
|
-v data-terminal-trivy-cache:/root/.cache/trivy aquasec/trivy:0.74.0 `
|
|
|
|
|
|
image --scanners vuln --ignore-unfixed --severity HIGH,CRITICAL `
|
|
|
|
|
|
data-terminal-cloud-web:latest
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
Web最终镜像使用非特权UID 101和8080监听;构建基线为Nginx 1.30.4 unprivileged Alpine并在镜像构建时应用当前系统安全更新。配置扫描必须确认Dockerfile不存在root运行高危项,镜像扫描必须同时覆盖API和Web最终运行层。
|
|
|
|
|
|
|
|
|
|
|
|
CI进一步使用镜像摘要固定Gitleaks、Trivy和Syft,并输出CycloneDX SBOM。浏览器矩阵由`node test/e2e/browser-matrix.mjs`执行,Safari必须在macOS真浏览器补测。宿主Go版本可能落后于镜像构建器,因此最终`govulncheck`证据必须在与生产构建一致的Go版本中生成。
|
|
|
|
|
|
|
|
|
|
|
|
## 5. 上线前证据
|
|
|
|
|
|
|
|
|
|
|
|
生产候选版本至少应保存:构建提交号、SBOM和镜像摘要,单元/集成/迁移/接口契约结果,依赖与镜像漏洞报告,密钥扫描报告,压测报告,故障恢复演练,固件暂停/回滚演练,隐私删除六子系统对账,以及真实供应商和真机连续通话记录。缺少外部账号、硬件或生产基础设施时,应明确标为“待外部验证”,不能用本地模拟结果替代。
|