
CLIProxyAPI 反代下 trusted-proxies 留空时,五个人共用一个 127.0.0.1 计数器,谁连续输错 5 次管理密钥,全站面板与本机采集就一起封 30 分钟——源码三处定位、三种处置与代价,以及为什么升级解决不了。
https://127.0.0.1:8317,管理面板与本机采集也走这个域名,CPA 的 trusted-proxies 留空1。127.0.0.1。谁连续输错 5 次管理密钥,这个共享地址就被封 30 分钟,所有人的面板与本机统计采集一起收 403,同一时间模型接口照常返回 200。handler.go 与 dev 分支逐字节相同,升级改不了这里的任何一步2。https://cpa.example.com),管理面没有直连 CPA 的 8317。server 段的 trusted-proxies 是空列表——默认就是空。/v0/management/* 或 /v8/management/*,它的密钥可能没配好。grep -n "trusted-proxies" config.yaml[2026-11-04 03:40:42] [info ] 200 | 79ms | 127.0.0.1 | GET "/v0/management/usage-queue?count=100"
[2026-11-04 03:40:42] [warn ] 401 | 0s | 127.0.0.1 | GET "/v0/management/config"
[2026-11-04 03:40:42] [warn ] 401 | 0s | 127.0.0.1 | GET "/v0/management/config"
[2026-11-04 03:40:42] [warn ] 401 | 77ms | 127.0.0.1 | GET "/v0/management/config"
[2026-11-04 03:40:43] [warn ] 401 | 79ms | 127.0.0.1 | GET "/v0/management/config"
[2026-11-04 03:40:43] [warn ] 401 | 80ms | 127.0.0.1 | GET "/v0/management/config"
[2026-11-04 03:40:43] [warn ] 403 | 0s | 127.0.0.1 | GET "/v0/management/config"
[2026-11-04 03:40:43] [warn ] 403 | 0s | 127.0.0.1 | GET "/v0/management/config"
[2026-11-04 03:40:44] [warn ] 403 | 0s | 127.0.0.1 | GET "/v0/management/usage-queue?count=100"
...
[2026-11-04 04:10:14] [warn ] 403 | 0s | 127.0.0.1 | GET "/v0/management/usage-queue?count=100"
[2026-11-04 04:10:44] [info ] 200 | 77ms | 127.0.0.1 | GET "/v0/management/usage-queue?count=100"
[2026-11-04 04:10:44] [info ] 200 | 93ms | 127.0.0.1 | GET "/v0/management/auth-files"clientIP := c.ClientIP() 取地址,再用两个字符串字面量判定「本机」:127.0.0.1 与 ::1。
internal/api/handlers/management/handler.go 第 321–354 行:第 331 行取 c.ClientIP(),第 332 行的「本机」判定只有 127.0.0.1 与 ::1 两个字面量,第 348 行把这个地址交去认证。2X-Forwarded-For。trusted-proxies 为空,ClientIP() 退回 TCP 对端;Caddy 与 CPA 同机,对端恒为 127.0.0.1。failedAttempts["127.0.0.1"] 这一格计数上。一个人输错,所有人一起付账。
maxFailures = 5 与 banDuration = 30 * time.Minute;第 385–396 行的封禁检查在 !localClient && !allowRemote 判断与密钥校验之前;第 398–400 行才是远程访问开关。5fail() 再返回 401,错密钥也走 fail();只有验证通过才 reset() 清零。计数是连续的,中间任何一次成功都会重新从零开始。secret-key 留空时整组管理路由返回 404,所以能看到 401/403 的人一定配了密钥。计数存在进程内存的 map 里,重启进程即清空。server.trusted-proxies 之后,ClientIP() 拿到的就是真实来源,localClient 随之变成 false。!localClient && !allowRemote 成立就返回 403 remote management disabled。也就是说,只改 trusted-proxies、不动 allow-remote,会立刻把所有人挡在门外,比原来的共享封禁更彻底。
config.example.yaml 第 52–58 行:空列表是默认值,注释写明「does not trust forwarded headers」,改完这个设置要重启服务。4
allow-remote 默认 false;secret-key 留空会让 /v0/management 与 /v8/management 整组返回 404。6MANAGEMENT_PASSWORD 启动。代码在读到非空的这个变量时会把 allowRemote 直接置真,绕过配置里的 allow-remote。cpaBaseUrl 从 https://cpa.example.com 改成 https://cpa.example.com:8317 之后,连接验证与转发读取都返回 200,采集恢复 running、deadLetters 为 01。代价是最小,覆盖面也最小:只隔离了这一个客户端,别人经同一 Caddy 进来照样撞同一个计数器。X-Forwarded-For,CPA 侧写 server.trusted-proxies: ["127.0.0.1"],同时打开 management.allow-remote(或用 MANAGEMENT_PASSWORD 启动),改完重启。此后计数挂在真实来源上,一个人输错只封他自己。代价是管理面从此按远程访问走,密钥必须有效,反向代理本身的安全性也要担起来。Allowing a correct key to immediately clear an active IP ban would weaken the purpose of the ban. … after the configured failure threshold is exceeded, all management key attempts from that IP should remain blocked for the ban duration, regardless of whether a later attempt contains the correct key. This is the
| 仓库 | 当前版本 | 发行时间(北京) | 主干头(北京) |
|---|---|---|---|
| router-for-me/CLIProxyAPI | v8.0.53 | 11-03 20:279 | main 11-03 20:24,dev 11-04 11:18 |
| Wei-Shaw/sub2api | v0.2.19 | 10-28 18:1610 | main 11-02 11:17 |
| icebear0828/codex-proxy | v2.1.23 | 11-03 19:3511 | main 11-03 19:26,dev 11-03 19:35 |
| james-6-23/codex2api | v3.1.3 | 11-04 10:2212 | main 11-04 10:08 |
8663608;自动评审在最新提交上仍有未解决意见13。github.com
github.com
github.com
github.com
github.com
github.com
github.com
github.com
github.com
github.com
github.com
github.com
github.com
github.com
status.openai.com
status.claude.com
status.cloud.google.com
codex-reset.com
This story was produced automatically by a channel. One sentence is all it takes for Neodrop to keep producing for you.