Files
token_thief/docs/compose/reports/2026-07-10-clickhouse-migration-security-fixes.md
T

33 lines
2.9 KiB
Markdown
Raw 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.
# TokenThief 可靠性与安全修复验证报告
## 结果
本次修订覆盖队列并发关闭和单一总 shutdown deadline、响应完整性、请求体 fail-closed、ClickHouse 部分/模糊提交、64 MiB 默认队列字节预算、严格正值配置、响应体总/idle timeout、SSE 协议边界、WebSocket 101 与 shutdown、DSN/TLS、schema 校验、Compose 安全默认、固定 502、可信代理、batch 清理和 server 启动统一清理。
Compose 使用固定 ClickHouse 镜像 `clickhouse/clickhouse-server:26.3`,默认不发布 ClickHouse 端口,并在配置展开阶段拒绝空的 `UPSTREAM_URL``CLICKHOUSE_URL``CLICKHOUSE_PASSWORD``.env.example` 不提供密码或 DSN 默认值。
## 关键取舍
- 日志仍是内存中、非阻塞、best-effort。队列满、字节预算不足或数据库不可用时允许丢弃并计数。
- ClickHouse `PrepareBatch` 的确定失败保留整批;逐项 `Append` 的确定失败只保留失败项,成功项照常发送。`Send` 错误无法从单机客户端确认服务端是否已提交,因此不自动重试该批并计入 `ambiguous_send`,优先避免静默重复。跨进程 exactly-once 需要持久化 outbox 和服务端幂等协议,未在本次引入。
- WebSocket 仅记录 101 握手元数据并关闭受管连接,不解析帧或承诺跨进程迁移。
- schema 会自动创建缺失表,并校验现有表的列类型、MergeTree 引擎、分区键和排序键;不兼容时拒绝标记健康,不执行有数据风险的自动重建。
- Compose 不默认发布 ClickHouse 端口,强制显式密码和独立 DSN,以同时保留原始服务端密码和 URL 编码凭据。
## 行为边界
- 仅当请求体完整可重放且 `ReverseProxy` 正常结束时提交 HTTP 日志;读取失败的请求不转发,响应中断不提交不完整日志。
- SSE 仅由 `Content-Type: text/event-stream` 判定;看到 `[DONE]` 不会提前提交,仍等待上游正常结束。普通响应使用总 timeout,SSE 使用可重置 idle timeout。
- WebSocket 仅记录成功 `101` 的握手元数据,不采集帧;进程关闭会关闭当前进程管理的升级连接,但不提供跨进程连接迁移或协调。
- `502` 对客户端使用固定错误文本,内部连接错误只进入服务端日志。转发客户端 IP 仅在 TCP 对端属于 `TRUSTED_PROXIES` 时生效。
## 验证
- `gofmt -w .`:通过。
- `go test ./...`:通过。
- `go vet ./...`:通过。
- 新增 `tests/deployment` 契约测试,覆盖必填部署参数、固定 ClickHouse 镜像、不发布数据库端口和示例凭据留空。
- `docker compose config`:未执行,当前环境没有可用 Docker daemon/CLICompose 安全约束由 Go 契约测试覆盖。
- `go test -race`:不属于验收命令,未执行。
- 未连接真实 ClickHouse 做断链模糊提交和旧 schema 集成测试;相关阶段语义通过 fake batch 与纯 schema 校验单测覆盖。