结论:封禁不看环境/TLS,只看请求形状
拦截方式:把 opencode 的 provider baseURL 改到本地反向代理(provider.opencode.options.baseURL),跑 opencode run -m opencode/mimo-v2.5-free,抓下真实请求;然后把代理留在链路上,逐个字段做 A/B 回放(相同传输、只变请求内容)。同一份抓包用 Python 原样回放 → 200,说明不是 TLS/JA3、HTTP/2、IP、key 或 session 来源问题。
必须同时满足 4 条(缺任一 → 403 FreeTierError):
# |
位置 |
要求 |
反例证据 |
|---|
1 |
Header User-Agent |
含 opencode/<semver>,≥ 1.18.0 |
1.17.99 → 426 UpgradeRequired;curl/8.5.0、python-urllib 默认 UA → 403 |
2 |
Header x-opencode-session |
ses_ + 12 位小写 hex + 14 位 [0-9A-Za-z](恰好 30 字符) |
长度 15/13、含 -、大写 hex、无前缀 → 403 |
3 |
Body |
"stream": true |
stream:false → 403(恒失败) |
4 |
Body |
tools 含函数名正好 bash 和 read |
去掉任一个 → 403;随机 11 个工具名 → 403;[bash,read] 空壳定义 → 200 |
不需要:x-opencode-client / -project / -request、Authorization(免费模型不带 key 也 200)、cookie、HTTP/2、特定 IP。
风险
- 这是反滥用闸门,维护者明确表示免费档不打算给非 OpenCode 的 harness 用,规则可能随时变(公开镜像里
ipRateLimiter.ts 的 header 校验当前是注释掉的,线上实现与之不同)。
- 免费档另有 Redis 按 IP 的每日配额(超限返回
FreeUsageLimitError)。
- 只验证了
/zen/v1/chat/completions;/zen/v1/messages 返回 500。免费模型按账号授权,ling-3.0-flash-free/hy3-free/kimi-k2.5-free/glm-5-free 在本 key 下 401 ModelError,mimo-v2.5-free、nemotron-3.5-lightning-free 可用。