sun
|
cdc9a7c94b
|
ci: 添加 GitHub Actions Docker 发布 workflow
为 Gitea→GitHub 镜像 + GitHub 镜像仓库场景准备 Docker 镜像
自动构建和发布流程。
触发条件:
- push tag v* (release 时打 tag 自动触发)
- workflow_dispatch (手动触发,可在 GitHub UI 测试)
构建:
- 多平台:linux/amd64 + linux/arm64
- 通过 QEMU + Buildx 跨架构构建
- 推送到 ghcr.io/<github-user>/volcano-engine-tts-ui
- 双标签:语义版本 + 短 commit hash
- OCI labels 包含 version 和 revision
与之前 version 包配合:
workflow 用 git describe --tags --always --dirty 算 VERSION
(commit hash 类似),通过 --build-arg 传给 Dockerfile,
Dockerfile 用 -ldflags 注入到 version.Version / version.Commit
两个变量。最终 /health 端点返回构建时注入的真实版本信息。
前置条件(用户需自行完成):
1. GitHub 建镜像仓库
2. Gitea 配置 Push Mirror 到 GitHub(开启 Sync Tags)
3. 仓库设为 Public(否则 GHCR 镜像默认 private)
|
2026-08-27 10:43:19 +08:00 |
|
sun
|
c00c46e7a1
|
chore: 注入构建时版本信息到 /health 端点
现状:controller/tts.go:232 硬编码 Version: "2.0.0 (v3 API)",
不会随代码变化而更新,/health 无法反映实际跑的代码。
修复:四文件改动,实现构建时 ldflags 注入。
1. 新建 version/version.go,声明两个包级变量:
Version (默认 "dev")
Commit (默认 "dev")
2. dto/health.go:HealthResponse 加 Commit 字段(JSON 输出多一字段)
3. controller/tts.go:HealthResponse 用 version.Version / version.Commit
替代硬编码字面量
4. Dockerfile:加 ARG VERSION=dev ARG COMMIT=dev,
go build 时通过 -ldflags 注入到 version 包的两个变量
效果:
- 本地 go build (不传 ldflags) → version=dev commit=dev
- 开发 build (git describe) → version=v0.2.0-5-g4abcd5 commit=g4abcd5
- release build (打 tag 后) → version=v0.2.1 commit=<对应 hash>
测试环境(develop 分支,无 tag)显示距离上次 release 几个 commit +
具体 hash;生产环境(main + tag)显示干净 semver。
|
2026-08-27 10:18:34 +08:00 |
|
sun
|
3b3aa3b708
|
chore: 清理 DEBT-2 死代码(7 文件,约 30 行)
VUL-003 修复期间意外发现项目遗留一批死代码,本次一并清掉:
- middleware/ratelimit_middleware.go(37 行,物理删除)
文件内 RateLimit / ConcurrencyLimit 函数从 977e9cc 创建后
从未被引用,370a217 commit 用 ratelimit_instrumented.go
(带 metrics 埋点 + 路径过滤)取代了它。占用包体,清。
- middleware/auth.go:InitAPIKeys(6 行)
注释说"已在 setting.InitAuthConfig 中完成",无 op。
- middleware/cors.go:InitCORSConfig(6 行)
同上,setting.InitCORSConfig 已做实际工作。
- dto/tts.go:ByteDanceTTSConfig 类型(7 行)
完整的配置走 setting.TTSOptions + adapter/volcano.Options,
此类型从未被任何代码实例化。
- setting/config.go: var _ = dto.ByteDanceTTSConfig{} 占位(3 行)
配合上方类型删除,移除 dto import。
- controller/tts.go:resolveClientFormat
合并 if reqFmt == "" 与 default 分支(都返回
setting.TTSOptions.Format),2 行简化。
- common/constants.go: MaxResponseTimes / MaxErrors
定义后从未被任何文件引用。
- middleware/ratelimit_instrumented.go 顶部注释
移除对"原 ratelimit_middleware.go"的悬空引用,
改为描述本文件相对路由使用实现的两个增强点。
影响:
- 包体减少约 30 行
- 降低新人接手时的代码理解成本
- 零功能变更,24 个现有测试用例全过
|
2026-08-27 00:57:49 +08:00 |
|
sun
|
695b3ecf25
|
docs: README 修正 speed 与 sample_rate 描述 (VUL-008 / VUL-009)
VUL-008 (信息): speed 超范围静默截断无提示
修复:「API 使用说明」speed 描述从"0.25 ~ 4.0"改为
"客户端接受范围 0.25 ~ 4.0;火山实际生效范围 0.5 ~ 2.0
(speech_rate [-50, 100]),超出范围会被静默截断,客户端无感反馈"。
选 TODO 方案 1(诚实修正文档),不改代码。
VUL-009 (信息): WAV 采样率依赖配置而非上游实际值
修复:BYTEDANCE_TTS_SAMPLE_RATE 描述加风险提示
"此值直接写入 WAV 头,需与上游实际 PCM 采样率一致,
否则音频变速变调"。
上游 v3 协议不返回 sample_rate 字段,代码侧无法自动取真实值,
仅文档强化。
|
2026-08-26 16:16:56 +08:00 |
|
sun
|
7343d5aa5c
|
VUL-006 (低): 监控端点 (/metrics /health /dashboard) 无鉴权
判定:不引入新鉴权机制(会破坏 Prometheus 抓取),文档引导。
修复:「观测 / Metrics」section 末尾新增「公网部署:监控端点
无鉴权」段,含三端点风险表 + nginx 反代 basic auth 配置示例。
VUL-007 (低): 未设置 OPENAI_TTS_API_KEY 时鉴权完全关闭
判定:不改代码(无 API Key 即不鉴权是 README 明示的设计),
文档强化。
修复:三处加强:
1. 环境变量表 OPENAI_TTS_API_KEY 行加 🔴 公网必设 标记
2. 「API 使用说明」section 顶部 callout 警示
3. 「部署」section 末尾新增「公网部署安全清单」段,统一
覆盖鉴权关闭与监控端点保护,形成完整安全姿态
|
2026-08-26 16:06:17 +08:00 |
|
sun
|
171503d775
|
fix: VUL-002 修复 transport 错误埋点缺失
VUL-002 (低): transport 层错误不进入 UpstreamErrors 指标
原代码用 if errCode != 0 判断是否记录错误,但合成链路中
多种错误场景的 errCode 本身是 0(火山 v3 业务码非 0 时才
会传入),导致这些场景在 /metrics 上完全不可见:
- transport_error: client.PostStream 失败(DNS / 连接 / TLS)
- request_error : buildRequest 序列化失败
- wrap_error : WAV 头拼装失败
- stream_error (code=0): 读流错误
修复:把判断改为 if status != "ok",status 是上游调用全链
路的权威错误指示器,任何非 ok 状态都计为错误。
codeLabel(0) → "transport" 已有定义,修复后该分类真正生效,
火山接口不可达等网络故障首次在监控上可见。
向后兼容:已统计的 http_XXX 错误(status="http_xxx" != "ok")
行为不变,新增 transport / request / wrap / stream 错误进入指标。
|
2026-08-26 15:35:24 +08:00 |
|
sun
|
91b0c8acee
|
fix: VUL-005 修复日志注入(RequestURI 与上游错误体转义)
VUL-005 (低): 攻击者可在 HTTP 请求 URL 或上游错误响应中
注入 \n / \r 字符,伪造日志行干扰排障。无代码执行风险。
修复位置:
- middleware/logger.go: 访问日志中的 r.RequestURI 是未经
解析的原始请求行,客户端可控。转义 \n / \r 为字面字符
- adapter/volcano/synthesis.go: 上游非 200 响应体 (rawBody)
可能是攻击者控制的恶意内容,转义后再嵌入错误消息
|
2026-08-26 11:52:28 +08:00 |
|
sun
|
a238e5c2a4
|
chore: 忽略本地 TODO.md,避免误提交
TODO.md 是本地待办清单,通过任务看板追踪更合适,不入 git 仓库。
|
2026-08-26 00:37:15 +08:00 |
|
sun
|
272565f736
|
fix: VUL-003 完整修复,启发式/精确双模式 XFF 解析
VUL-003 (中): X-Forwarded-For 信任链可被伪造 IP 绕过限流
本服务定位为公网入口,即使单人使用,公网暴露意味着攻击面
与公开服务等同,不能"够用就行"。
采用渐进式披露设计,平衡易用性与功能性:
1. 启发式模式(默认, 不设环境变量 或 TRUSTED_PROXY_HOPS=0)
- 从 XFF 链尾扫描,跳过私有 IP,返回第一个公网 IP
- 适合 90% 部署(单跳/多跳/直出),无需了解精确跳数
- 限制:多跳 CDN 场景下,限流粒度为"按 CDN 边缘 IP"
- 直出部署:整个 XFF 分支不会执行
2. 精确模式(TRUSTED_PROXY_HOPS=N, N>0)
- 从 XFF 链尾倒数第 N+1 个位置取值
- 精准到真实 client,需按实际反代跳数正确配置
- N=1:单跳反代;N=2:CDN+反代;以此类推
3. 两种模式都从链尾扫描
- XFF 首值是客户端可控的,信任首值等于信任攻击者
- 链尾由受控的反代添加,天然免疫伪造绕过
4. 默认值从 1 改为 0(行为变化)
- 旧默认:精确模式 N=1,取 XFF 末值
- 新默认:启发式模式,跳过链尾私有 IP
- 对单跳场景行为相同
- 对多跳/链尾含私有 IP 场景新版更准确(返回真实公网 IP)
5. 配套
- middleware/ratelimit_test.go:24 个表驱动测试用例,
覆盖直出/单跳/多跳/伪造/畸形/精确 N 边界,全部通过
- setting/config.go:LogStartupSummary 显示当前 XFF 模式
- .env.example:重写说明,标注默认行为 + 何时需配
- README.md:新增"反代拓扑与 X-Forwarded-For 解析"章节
(何时需要/两种模式/行为对比/为什么从链尾/启动日志验证)
6. 已知边界:TRUSTED_PROXY_HOPS=00 等被 Atoi 解析为 0 的
输入归入启发式模式,日志不会出现"精确模式 0 跳"矛盾输出。
|
2026-08-26 00:36:22 +08:00 |
|
sun
|
ed3d7c6b61
|
本次代码审查(全 12 个包,约 2400 行)的交付物:
- 9 项漏洞(高 1 / 中 2 / 低 4 / 信息 2)
- 已核查无风险项 8 条
- 工程债务记录(零测试、死代码、云盘占用)
- 安全加固建议(Docker 密钥传递、TLS、依赖固定)
供后续按优先级处理备查。
"
|
2026-08-25 23:10:34 +08:00 |
|
sun
|
72d0d6a3a9
|
VUL-001 (中): aac/flac 响应 Content-Type 与真实数据不一致
controller.tts.go:contentTypeFor 对 aac/flac 返回 audio/aac/flac,
但 adapter/volcano/synthesis.go 在上游降级时仅修改 opts.Format,
finalFormat 仍保留 clientFormat,导致响应头与字节流不符。
修复:finalFormat 改为反映真实输出格式(非 wav 时取 opts.Format),
客户端按 AAC/FLAC 解码 MP3 流的失败场景消除。
VUL-004 (高): .env 凭据泄露
README 引导用户 cp .env.example .env 填密钥,但 .gitignore
未忽略 .env,任何 git add . 都会把含 BYTEDANCE_TTS_API_KEY
的文件提交进 git 历史,不可逆。
修复:
- .gitignore 新增 Secrets section,拦截 .env 与 .env.* 变体,
保留 .env.example 作为模板追踪
- .dockerignore 升级为同名规则模式,覆盖未来 .env.local /
.env.production 等变体,保证 git 与 docker 两通道一致
详见 VULNERABILITY_REPORT.md
"
|
2026-08-25 23:09:47 +08:00 |
|
sun
|
78c72004bf
|
chore: 删除 ratelimit_middleware.go.tmp 临时文件
与 ratelimit_middleware.go 内容完全重复(SHA256 一致,1116 字节),
且无任何代码引用 .tmp 路径,属于误提交的开发期残留文件。
|
2026-08-23 13:15:15 +08:00 |
|