Add deployment traces for the JPpro proxy node, RackNerd origin hosts, catproxy boundary changes, local speed checks, and Sub2API rate-limit behavior. Keep remote secrets excluded while tracking sanitized nginx, compose, plan, and operational memory documents.
36 KiB
proxy-ng origin 加固方案 — 审阅版
日期:2026-05-26
状态:已执行,2026-05-26 有边界调整
适用范围:proxy.api.lilifamily.com 公开入口、catproxy.lilifamily.com 公开直连主站入口、origin.proxy.api.lilifamily.com 受限回源入口、*.proxy.api.lilifamily.com proxy-ng 节点扩展
2026-05-26 决策变更:
catproxy.lilifamily.com不再做 IP 白名单限制,作为 3c4g 公开直连主站域名和回滚入口;只有origin.proxy.api.lilifamily.com保持来源 IP 白名单和X-Proxy-Ng-Token校验。本文中早期关于catproxy受限访问的草案描述已被此决策覆盖,当前运行事实以ops/remote/us-racknerd-0526-sub2api/为准。
1. 结论
当前 JPpro 入口中转已经可以用于稳定性测试,但还不是生产加固架构。后续不依赖 Cloudflare Load Balancing;公开入口用普通 DNS 记录指向 proxy-ng 节点,防攻击和主站隐藏由 nginx、防火墙、origin 白名单和 token 完成。
当前已执行链路是:
flowchart LR
U[用户] -->|HTTPS| P[公开入口<br/>proxy.api.lilifamily.com]
P -->|HTTPS| J[JPpro nginx<br/>jp.proxy.api.lilifamily.com]
J -->|HTTPS + 节点 Token| O[3c4g origin nginx<br/>origin.proxy.api.lilifamily.com]
O -->|127.0.0.1:8080| S[Sub2API]
C[直连用户] -->|HTTPS| D[3c4g nginx<br/>catproxy.lilifamily.com]
D -->|127.0.0.1:8080| S
推荐生产加固链路是:
flowchart LR
U[用户] -->|HTTPS| D[公开入口<br/>proxy.api.lilifamily.com<br/>普通多 A / 手工切换]
D --> J[JPpro nginx<br/>jp.proxy.api.lilifamily.com]
D --> N[其它 proxy-ng 节点<br/>*.proxy.api.lilifamily.com]
J -->|HTTPS + 节点 Token| O[3c4g origin nginx<br/>origin.proxy.api.lilifamily.com]
N -->|HTTPS + 节点 Token| O
O -->|本机回环| S[Sub2API :8080]
C[普通公网用户] -.->|403 / 拒绝| O
X[未知服务器] -.->|IP 不在白名单| O
前置阶段先做域名迁移和入口角色调整:
- 公开服务入口保留为
proxy.api.lilifamily.com,但它不再指向 3c4g,而是指向 proxy-ng 节点。 - 3c4g 原直连入口从
proxy.api.lilifamily.com改为catproxy.lilifamily.com,作为公开直连主站域名和回滚入口。 - DNS 增加
origin.proxy.api.lilifamily.comA 记录,指向 3c4g,只给 proxy-ng 回源使用。 - 其它 proxy-ng 节点统一使用
<node>.proxy.api.lilifamily.com命名。
第一阶段加固只建议做三件事:
- 在 3c4g 增加独立 origin 入口:
origin.proxy.api.lilifamily.com。 - origin 入口只允许 JPpro IP 访问,并校验
X-Proxy-Ng-Token。 - JPpro 从回源公网主域名改为回源 origin 入口。
proxy.api.lilifamily.com的 A 记录只指向 proxy-ng 节点,不再暴露 3c4g。
这三项完成后,proxy-ng 才从“能用的公网反代”升级成“信任边界清楚的入口中转”。
2. 当前已验证事实
| 项目 | 当前事实 |
|---|---|
| JPpro 服务器 | 个人-JPpro-akile-0504-1c1g |
| JPpro 公网 IP | 151.242.164.72 |
| JPpro 入口域名 | jp.proxy.api.lilifamily.com |
| JPpro 当前职责 | 只运行 nginx proxy-ng,不运行 Sub2API、PostgreSQL、Redis、Caddy 或账号出口代理 |
| JPpro 当前回源 | 测试期可临时回源 https://catproxy.lilifamily.com,加固后必须改为 https://origin.proxy.api.lilifamily.com |
| 3c4g 服务器 | 个人-US-racknerd-0526-3c4g |
| 公开服务入口域名 | proxy.api.lilifamily.com,目标是普通多 A 指向 proxy-ng 节点 |
| 3c4g 公开直连主站域名 | catproxy.lilifamily.com,不做 IP 白名单限制 |
| 3c4g origin 域名 | origin.proxy.api.lilifamily.com,只给 proxy-ng 回源 |
| 3c4g 当前职责 | nginx 反代到本机 Sub2API 127.0.0.1:8080 |
| 当前风险边界 | 直接回源公网主域名,尚未做独立 origin、后端来源 IP 白名单、X-Proxy-Ng-Token 校验 |
2.1 域名命名与 DNS 记录
本方案按以下域名边界规划:
| 域名 | DNS 记录 | 角色 | 说明 |
|---|---|---|---|
proxy.api.lilifamily.com |
多个 A -> proxy-ng 节点 IP | 公开服务入口 | 不用 Cloudflare LB;普通 DNS 多 A 或手工切换 |
catproxy.lilifamily.com |
A -> 216.45.59.243 |
3c4g 公开直连主站入口 | 可直接访问主站,也可作为 proxy-ng 故障时的回滚入口 |
origin.proxy.api.lilifamily.com |
A -> 216.45.59.243 |
3c4g 回源入口 | 只给 proxy-ng 节点访问,必须加 IP 白名单和 token |
jp.proxy.api.lilifamily.com |
A -> 151.242.164.72 |
JPpro proxy-ng 节点 | 当前第一台入口中转节点 |
*.proxy.api.lilifamily.com |
每个节点独立 A/AAAA | 后续 proxy-ng 节点命名空间 | 例如 us.proxy.api.lilifamily.com、sg.proxy.api.lilifamily.com |
约束:
proxy.api.lilifamily.com是用户看到的正式入口,但它只指向 proxy-ng 节点,不直接指向 3c4g。catproxy.lilifamily.com是独立公开直连入口;proxy-ng 回源不使用它,也不应在proxy.api.lilifamily.com链路中把它暴露到Location、Host、页面链接或错误页中。*.proxy.api.lilifamily.com在本文表示节点命名规则,不等于必须使用一条 wildcard A 记录。- 多个节点如果 IP 不同,应为每个节点创建独立 A/AAAA 记录;
proxy.api.lilifamily.com可以配置多个 A 记录,但这是普通 DNS 轮询,不具备健康检查和按网络质量调度能力。 origin.proxy.api.lilifamily.com即使有公网 DNS,也不应作为用户入口;访问控制必须在 nginx 和防火墙层生效。origin默认限制公网访问,证书签发不应依赖长期开放 HTTP-01;优先使用 DNS-01,或在签发/续期窗口临时开放并立即恢复限制。catproxy公开访问,可使用常规 HTTP-01。
当前配置留痕:
| 文件 | 说明 |
|---|---|
ops/remote/jppro-sub2api/README.md |
JPpro proxy-ng 部署记录 |
ops/remote/jppro-sub2api/current/nginx-jp-proxy-sub2api.conf |
JPpro 当前 nginx 配置副本 |
ops/remote/us-racknerd-0526-sub2api/current/nginx-sub2api.conf |
3c4g 当前 nginx 主入口配置副本 |
docs/memorys/2026-05-25-proxy-ng职责边界.md |
proxy-ng 不承担账号出口代理的边界记录 |
proxy-ng/README.md |
多节点 proxy-ng 方案说明 |
proxy-ng/nginx/proxy-node.conf.template |
proxy-ng 节点 nginx 模板 |
proxy-ng/nginx/backend-gateway.conf.template |
后端入口网关模板 |
3. 目标和非目标
目标
- 把用户公开入口和 proxy-ng 回源入口分离。
- 让 3c4g 后端能识别“这是受控 proxy-ng 节点发来的请求”。
- 防止普通公网用户绕过 proxy-ng 直接访问 origin。
- 防止客户端伪造
X-Proxy-Ng-*或X-Forwarded-*头影响日志和安全判断。 - 公开入口
proxy.api.lilifamily.com只解析到 proxy-ng 节点,避免 3c4g 主站直接暴露。 - 保留
catproxy.lilifamily.com作为公开直连主站域名和紧急回滚入口。 - 为后续新增 proxy-ng 节点提供标准流程。
非目标
- 不把 JPpro 改造成账号出口代理。
- 不在 proxy-ng 节点部署 Clash、sing-box、Xray、SOCKS、mixed 等代理服务。
- 不改 Sub2API 业务代码作为第一阶段方案。
- 不在仓库提交真实 token、
.env、API key、数据库密码。 - 不立即强制所有用户流量都走 JPpro。
- 不立即建设复杂的多地域调度系统。
4. 设计项解释和实施方案
4.1 独立 origin 入口
作用
独立 origin 用来区分两类入口:
| 入口 | 面向对象 | 是否公开给用户 |
|---|---|---|
proxy.api.lilifamily.com |
用户公开访问,解析到 proxy-ng 节点 | 是 |
catproxy.lilifamily.com |
运维直连、临时回滚 | 否 |
origin.proxy.api.lilifamily.com |
proxy-ng 节点回源 | 否 |
如果 JPpro 继续回源 https://catproxy.lilifamily.com,那么 catproxy 就会被放进常规服务链路。它能用于短期迁移,但不能作为生产回源目标。生产回源必须使用 origin.proxy.api.lilifamily.com,并通过 IP 白名单和 token 限制访问。
独立 origin 的意义是:回源链路可以单独配置 IP 白名单、token 校验、日志格式和限流策略,不影响用户公开入口。
实施方案
DNS 增加:
proxy.api.lilifamily.com -> 151.242.164.72
proxy.api.lilifamily.com -> <其它 proxy-ng 节点 IP>
catproxy.lilifamily.com -> 216.45.59.243
origin.proxy.api.lilifamily.com -> 216.45.59.243
3c4g 新增 nginx server block:
server {
server_name origin.proxy.api.lilifamily.com;
listen 443 ssl;
ssl_certificate /etc/letsencrypt/live/origin.proxy.api.lilifamily.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/origin.proxy.api.lilifamily.com/privkey.pem;
location / {
proxy_pass http://127.0.0.1:8080;
proxy_http_version 1.1;
proxy_set_header Host proxy.api.lilifamily.com;
proxy_set_header X-Forwarded-Host $http_x_forwarded_host;
proxy_set_header X-Forwarded-Proto https;
proxy_read_timeout 3600s;
proxy_send_timeout 3600s;
proxy_buffering off;
proxy_request_buffering off;
}
}
JPpro 后续改为:
proxy_pass https://origin.proxy.api.lilifamily.com;
proxy_ssl_server_name on;
proxy_ssl_name origin.proxy.api.lilifamily.com;
proxy_set_header Host origin.proxy.api.lilifamily.com;
proxy_set_header X-Forwarded-Host $host;
风险
- 新增域名证书签发失败会导致 origin 不可用。
- 如果直接切 JPpro 回源而未保留回滚,会造成 JPpro 入口不可用。
缓解
- 先用
curl --resolve验证 origin,再切 JPpro。 - JPpro 原配置保留备份;失败时把
proxy_pass改回https://catproxy.lilifamily.com。
4.2 来源 IP 白名单
作用
来源 IP 白名单保证 origin 只接受你控制的 proxy-ng 节点访问。
即使别人知道 origin.proxy.api.lilifamily.com,只要请求来源 IP 不是 JPpro 或后续受控节点,就会被拒绝。
实施方案
3c4g origin nginx 增加:
location / {
allow 151.242.164.72; # JPpro
deny all;
proxy_pass http://127.0.0.1:8080;
}
如果服务器防火墙可控,建议同时在系统防火墙层限制:
允许 151.242.164.72 访问 443 或 origin 专用端口
拒绝其他公网来源访问 origin 入口
后续新增节点时,只追加节点 IP:
allow 151.242.164.72; # JPpro
allow x.x.x.x; # 新 proxy-ng 节点
deny all;
风险
- 节点 IP 写错会导致 proxy-ng 回源 403。
- VPS 如果更换 IP,origin 会继续拒绝旧配置之外的来源。
缓解
- 每个节点目录必须记录公网 IP。
- 新增或迁移节点时,先更新 origin allowlist,再切 DNS 或入口。
4.3 X-Proxy-Ng-Token
作用
IP 白名单证明“请求来自这台服务器 IP”,但不能证明“请求一定来自你配置的 nginx”。
X-Proxy-Ng-Token 是第二道校验:
- 防止同一节点上其他进程误打 origin。
- 防止节点配置被部分滥用。
- 为后续多节点密钥轮换提供边界。
正确边界是:
来源 IP 白名单 + X-Proxy-Ng-Token + HTTPS 回源
Token 不是防火墙替代品。
实施方案
JPpro 注入 token:
proxy_set_header X-Proxy-Ng-Token "REDACTED_SECRET";
proxy_set_header X-Proxy-Ng-Node "jppro-akile-0504-1c1g";
3c4g origin 校验 token:
map $http_x_proxy_ng_token $proxy_ng_token_ok {
default 0;
"REDACTED_SECRET" 1;
}
map $http_x_forwarded_host $sub2api_host {
default $http_x_forwarded_host;
"" "proxy.api.lilifamily.com";
}
server {
server_name origin.proxy.api.lilifamily.com;
location / {
if ($proxy_ng_token_ok = 0) {
return 403;
}
proxy_pass http://127.0.0.1:8080;
proxy_set_header X-Proxy-Ng-Token "";
}
}
真实 token 保存建议:
| 位置 | 规则 |
|---|---|
| 远程服务器 root-only 配置 | 可以保存真实 token,权限建议 600 |
仓库 ops/remote/**/current/ |
只保存脱敏副本 |
仓库 secrets/ |
如需本机私有备份,必须被 .gitignore 排除 |
风险
- 所有节点共用一个 token 时,泄露后需要同步更新所有节点。
- nginx 配置中使用明文 token,远程文件权限要控制好。
缓解
- 第一阶段可以单 token。
- 第二阶段支持双 token:先加新 token,再滚动节点,最后删旧 token。
- 真实 token 不写入 Git。
4.4 覆盖客户端伪造 header
作用
客户端可以自己发送这些 header:
X-Proxy-Ng-Token
X-Proxy-Ng-Node
X-Forwarded-For
X-Real-IP
X-Forwarded-Host
如果 proxy-ng 不覆盖,后端日志和安全判断可能被伪造。
实施方案
JPpro 对安全相关 header 使用 proxy_set_header 覆盖:
proxy_set_header X-Proxy-Ng-Token "REDACTED_SECRET";
proxy_set_header X-Proxy-Ng-Node "jppro-akile-0504-1c1g";
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header X-Forwarded-Host $host;
3c4g origin 校验后清除 token,不继续传给 Sub2API:
proxy_set_header X-Proxy-Ng-Token "";
proxy_set_header X-Proxy-Ng-Node $http_x_proxy_ng_node;
风险
- 如果
X-Forwarded-For处理不当,Sub2API 可能拿不到真实客户端 IP。 - 如果信任任意
X-Forwarded-For,日志和限流可能被客户端伪造。
缓解
- 第一阶段先让 JPpro 覆盖
X-Forwarded-For为$remote_addr,保证不可伪造。 - 后续如接入多级代理,再单独设计可信真实 IP 链路。
4.5 入口策略
作用
入口策略决定用户应该访问哪条链路。
如果同时存在多个入口但没有规则,会出现:
- 有的用户走 JPpro。
- 有的用户绕过 JPpro 直连 3c4g。
- 出问题时无法快速判断是哪条链路坏了。
推荐阶段
| 阶段 | 入口策略 | 目的 |
|---|---|---|
| P0 迁移期 | catproxy.lilifamily.com 可短期直连,jp.proxy.api.lilifamily.com 用于测试中转 |
建立回滚入口 |
| P1 加固期 | JPpro 改走 origin + IP 白名单 + token | 验证安全边界 |
| P2 稳定期 | proxy.api.lilifamily.com 多 A 指向 proxy-ng 节点 |
常规用户不直连 3c4g |
实施方案
当前不依赖 Cloudflare LB。公开入口采用普通 DNS 多 A 或手工切换,接受“坏节点不会自动摘除”的限制。
先保持:
proxy.api.lilifamily.com -> 一个或多个 proxy-ng 节点
jp.proxy.api.lilifamily.com -> JPpro proxy-ng
*.proxy.api.lilifamily.com -> 后续 proxy-ng 节点命名空间
origin.proxy.api.lilifamily.com -> 3c4g origin,仅供 proxy-ng 回源
catproxy.lilifamily.com -> 3c4g 受限直连/管理/回滚入口
稳定期约束:
proxy.api.lilifamily.com 不能解析到 3c4g
proxy-ng 节点不能把 catproxy.lilifamily.com 暴露给用户
catproxy.lilifamily.com 不能作为常规公开业务入口
4.6 监控
作用
proxy-ng 是多段链路。用户报慢或报错时,需要区分:
- JPpro nginx 是否正常。
- JPpro 到 3c4g origin 是否正常。
- 3c4g nginx 是否正常。
- Sub2API 是否正常。
- 证书是否即将过期。
实施方案
最小监控项:
| 检查项 | 期望 |
|---|---|
https://jp.proxy.api.lilifamily.com/health |
200 |
https://proxy.api.lilifamily.com/health |
200,且解析到 proxy-ng 节点 |
https://catproxy.lilifamily.com/health 从管理 IP/Tailscale 访问 |
200 |
https://catproxy.lilifamily.com/health 从普通公网访问 |
403 或 444 |
https://origin.proxy.api.lilifamily.com/health 从非白名单来源访问 |
403 或连接被拒绝 |
https://origin.proxy.api.lilifamily.com/health 从 JPpro 访问 |
200 |
POST /v1/responses 无授权访问 |
401 API_KEY_REQUIRED |
| 证书剩余天数 | 小于 15 天告警 |
| nginx 服务状态 | 非 active 告警 |
可以用 Uptime Kuma,或先用 cron + webhook。
风险
- 只监控
/health不足以发现 API 路由问题。 - 从本机监控 origin 可能因为 IP 白名单而得到 403,这是预期,不是故障。
缓解
- 同时监控
/health和未授权 API 路由。 - origin 监控要从 JPpro 节点执行。
4.7 日志可观测
作用
响应慢时要知道慢在哪里。
关键区分:
| 字段 | 含义 |
|---|---|
request_time |
当前 nginx 从接收请求到响应完成的总耗时 |
upstream_response_time |
当前 nginx 等上游响应的耗时 |
upstream_status |
上游返回状态,例如 200、401、502、504 |
X-Proxy-Ng-Node |
哪个 proxy-ng 节点处理了请求 |
request_id |
一次请求的追踪 ID |
实施方案
JPpro 和 3c4g origin 都建议增加专用 log format:
log_format proxy_ng '$remote_addr "$request" status=$status '
'request_time=$request_time '
'upstream_status=$upstream_status '
'upstream_time=$upstream_response_time '
'node=$sent_http_x_proxy_ng_node '
'request_id=$request_id';
access_log /var/log/nginx/proxy-ng-access.log proxy_ng;
风险
- access log 过大导致磁盘占满。
缓解
- 配置 logrotate。
- 稳定后可只保留错误日志和采样日志。
4.8 无 Cloudflare LB 的防攻击方案
作用
不依赖 Cloudflare LB 后,公网攻击会直接打到 proxy-ng 节点。防攻击目标不是承诺抗大规模 DDoS,而是降低常见扫描、CC、小流量洪泛、慢连接和暴力破解对服务的影响,并保证攻击不会绕过 proxy-ng 打到 3c4g 主站。
API 网关类服务常见风险:
- 大量并发连接。
- 大请求体。
- 慢速上传。
- 登录和验证码接口被刷。
- 流式响应占用长连接。
- 路径扫描,例如
/.env、/.git、/wp-login.php。 - 直接扫描 3c4g IP、
catproxy或origin。
实施方案
第一层:proxy-ng 节点系统防火墙。
入站允许:
- 80/tcp、443/tcp:公网用户访问 proxy-ng
- 22/tcp:只允许管理 IP 或 Tailscale/内网管理入口
入站拒绝:
- 其它所有端口
- 1080、7890、mixed、socks、xray、sing-box 等出口代理端口
第二层:proxy-ng 节点 nginx 基础抗压。
worker_processes auto;
worker_rlimit_nofile 65535;
events {
worker_connections 4096;
multi_accept on;
}
http {
sendfile on;
tcp_nopush on;
reset_timedout_connection on;
keepalive_timeout 20s;
keepalive_requests 100;
client_header_timeout 10s;
client_body_timeout 30s;
send_timeout 30s;
client_max_body_size 100m;
client_body_buffer_size 256k;
large_client_header_buffers 4 16k;
limit_conn_zone $binary_remote_addr zone=conn_per_ip:20m;
limit_req_zone $binary_remote_addr zone=req_per_ip:20m rate=10r/s;
limit_req_zone $binary_remote_addr zone=auth_per_ip:10m rate=10r/m;
}
第三层:proxy-ng 节点 nginx 路由限流。
location ~ /\.(git|svn|hg|env|aws|ssh) {
return 444;
}
location ~* ^/(wp-admin|wp-login\.php|phpmyadmin|cgi-bin|vendor|boaform) {
return 444;
}
location / {
limit_req zone=req_per_ip burst=30 nodelay;
limit_conn conn_per_ip 50;
proxy_pass https://origin.proxy.api.lilifamily.com;
}
location ~ ^/api/v1/auth/(login|login/2fa|register|send-verify-code|forgot-password|reset-password) {
limit_req zone=auth_per_ip burst=3 nodelay;
limit_conn conn_per_ip 10;
proxy_pass https://origin.proxy.api.lilifamily.com;
}
第四层:3c4g origin 防绕过。
3c4g 防火墙:
- 只允许 proxy-ng 节点 IP 访问 origin 入口端口
- 只允许管理 IP 或 Tailscale 访问 SSH
- Sub2API 8080 只监听 127.0.0.1 或 Docker 内网,不直接暴露公网
3c4g nginx:
- origin server 只 allow proxy-ng 节点 IP
- 必须校验 X-Proxy-Ng-Token
- default_server 对未知 Host 返回 444
- catproxy 入口只用于受限直连/回滚,不作为公开业务入口
第五层:fail2ban 和日志轮转。
fail2ban 建议规则:
- nginx-404:短时间大量 404/444 扫描封禁
- nginx-limit-req:短时间大量 429 封禁
- sshd:SSH 暴力破解封禁
logrotate:
- nginx access/error 日志按大小轮转
- 保留 3-7 份
- 防止攻击流量把磁盘写满
第六层:Sub2API 成本保护。
- API Key 配额和余额限制
- 单 key 并发限制
- 单 key 速率限制
- 异常 401/429/5xx 告警
- 高额模型调用成本预警
风险
- 这些措施不能替代专业 DDoS 清洗;大流量打满 VPS 带宽时仍会不可用。
- 太严格会误伤正常 API 客户端。
- 流式响应连接时间长,连接数限制过低会误伤。
- 多 A 普通 DNS 没有健康摘除;坏节点仍可能被解析到。
缓解
- 先在 JPpro 测试入口启用。
- 观察 429 和连接拒绝日志后再调参。
- 对
/v1/responses等长连接路径不要过度收紧。 proxy.api.lilifamily.comTTL 设低,例如 60-300 秒,故障时手工删除坏节点 A 记录。- 保留至少一个受限直连回滚入口,但不公开给普通用户。
4.9 备份和回滚
作用
proxy-ng 节点无业务数据,真正不能丢的是 3c4g 的数据库、Redis、Sub2API 数据目录和运行配置。
入口改造前必须有回滚方案,否则一次 nginx 配置错误可能导致入口不可用。
实施方案
改动前备份:
3c4g:
- /etc/nginx/sites-available/sub2api.conf
- /etc/nginx/sites-enabled/sub2api.conf
- /opt/sub2api/docker-compose.yml
- /opt/sub2api/.env
- PostgreSQL dump
- /opt/sub2api/data
JPpro:
- /etc/nginx/sites-available/jp-proxy-sub2api.conf
- /etc/nginx/conf.d/proxy-ng-map.conf
回滚路径:
| 故障 | 回滚方式 |
|---|---|
| origin 配置失败 | JPpro proxy_pass 改回 https://catproxy.lilifamily.com |
| token 校验误拦截 | 临时关闭 origin token 校验,恢复后重新加固 |
| IP 白名单误拦截 | 修正 allow 节点 IP 或临时回滚到公网主入口 |
| JPpro 故障 | 用户切回 https://catproxy.lilifamily.com |
| 3c4g 服务异常 | 使用 3c4g 备份和 Docker Compose 回滚 |
4.10 多节点扩展
作用
多节点用于提升入口稳定性,但不是简单“节点越多越好”。
不使用 Cloudflare LB 时,多 A 记录会把用户随机分配到节点。某个节点故障后,DNS 仍可能返回坏 IP,表现为部分用户随机失败。
实施方案
新增节点标准流程:
1. 新建 ops/remote/<server>-sub2api/
2. 安装 nginx + certbot
3. 配置 proxy-ng node id
4. 回源 origin.proxy.api.lilifamily.com
5. 3c4g origin allow 新节点 IP
6. 给新节点配置 token
7. 验证 /health、/、/v1/responses
8. 加入 `proxy.api.lilifamily.com` 多 A 记录
DNS 策略:
| 阶段 | 方案 | 风险 |
|---|---|---|
| P0 | 单节点入口 | 简单,但节点故障需手工切换 |
| P1 | proxy.api.lilifamily.com 多 A 记录,TTL 60-300 秒 |
成本低,但坏节点不会自动摘除 |
| P2 | 自建监控 + 手工或脚本更新 DNS | 不依赖 Cloudflare LB,但需要自己处理摘除 |
当前确认不采用 Cloudflare Load Balancing,因此方案不承诺按用户网络质量或节点健康自动调度。节点健康只能通过监控告警后手工移除 DNS 记录,或后续自建 DNS 更新脚本实现。
5. 推荐实施顺序
阶段 0:主站隐藏和入口域名迁移基线
先把公开入口和 3c4g 直连入口拆开,避免 proxy-ng 节点或公开 DNS 暴露主站。
动作:
proxy.api.lilifamily.com从 3c4g 移走,改为 A 到 proxy-ng 节点,例如 JPpro。- DNS 增加或确认
catproxy.lilifamily.com -> 216.45.59.243,但它只作为受限直连、管理和回滚入口。 - 3c4g nginx 为
catproxy.lilifamily.com签发证书,但访问限制为管理 IP、Tailscale 或临时回滚窗口。 - Sub2API 对外公开域名应保持为用户访问入口
proxy.api.lilifamily.com,避免页面、回调或错误信息暴露catproxy.lilifamily.com。 - JPpro 临时回源可用
https://catproxy.lilifamily.com,但只作为切 origin 前的过渡。
目标基线链路:
proxy.api.lilifamily.com -> JPpro/proxy-ng -> catproxy.lilifamily.com(临时) -> 3c4g -> Sub2API
验收:
proxy.api.lilifamily.com/health返回 200,且解析到 proxy-ng 节点 IP。jp.proxy.api.lilifamily.com/health返回 200。jp.proxy.api.lilifamily.com/返回 200。- 普通公网访问
catproxy.lilifamily.com被拒绝,或仅在明确回滚窗口内允许。 - 未授权
POST /v1/responses返回 401。
阶段 1:3c4g 增加 origin
动作:
- DNS 增加
origin.proxy.api.lilifamily.com -> 216.45.59.243。 - 3c4g nginx 新增 origin server block。
- certbot 为 origin 域名签发证书。
- 暂不切 JPpro,先验证 origin 本身。
验收:
- 从 3c4g 本机访问
127.0.0.1:8080/health正常。 - 从 JPpro 访问
https://origin.proxy.api.lilifamily.com/health正常。 - 从非白名单来源访问 origin 被拒绝。
阶段 2:origin 加 IP 白名单和 token
动作:
- 3c4g origin 允许 JPpro IP
151.242.164.72。 - 3c4g origin 配置
X-Proxy-Ng-Token校验。 - JPpro 配置注入 token。
- token 真实值只保存在远程 root-only 配置。
验收:
- JPpro 带 token 访问 origin 返回 200。
- JPpro 不带 token 访问 origin 返回 403。
- 非 JPpro IP 访问 origin 返回 403 或连接拒绝。
- origin 不把
X-Proxy-Ng-Token继续传给 Sub2API。
阶段 3:JPpro 切换 origin 回源
动作:
- 备份 JPpro 当前 nginx 配置。
- JPpro
proxy_pass从https://catproxy.lilifamily.com改为https://origin.proxy.api.lilifamily.com。 nginx -t后 reload。- 公网验证 JPpro 入口。
验收:
https://jp.proxy.api.lilifamily.com/health返回 200。https://jp.proxy.api.lilifamily.com/返回 200。- 未授权
POST /v1/responses返回 401。 - 3c4g origin access log 能看到
X-Proxy-Ng-Node=jppro-akile-0504-1c1g。
阶段 4:完善监控、日志、限流
动作:
- 增加 proxy-ng 专用 access log。
- 配置证书到期检查。
- 配置 JPpro 和 3c4g 健康检查。
- 先在 JPpro 入口启用保守限流、连接数限制和扫描路径拦截。
- 配置 fail2ban 和 logrotate。
- 3c4g 防火墙确认只允许 proxy-ng 节点访问 origin。
验收:
- 能通过日志区分 JPpro 耗时和 3c4g origin 耗时。
- 证书剩余天数低于阈值能告警。
- 429 数量可观测,不误伤正常请求。
- 访问
/.env、/.git/config、/wp-login.php等扫描路径返回 444 或 403。 - 3c4g
8080不对公网开放。
阶段 5:评估是否增加第二个 proxy-ng 节点
动作:
- 选择第二台节点。
- 按同样目录规范留痕。
- 先不进正式 DNS,用
--resolve验证。 - 通过
--resolve proxy.api.lilifamily.com:443:<节点IP>逐个验证。 - 验证通过后加入
proxy.api.lilifamily.com多 A 记录。
验收:
- 第二节点独立验证通过。
- origin allowlist 已补第二节点 IP。
- 节点配置副本已保存到项目
ops/remote/<server>-sub2api/。 proxy.api.lilifamily.com的多 A 记录不包含 3c4g IP。
6. 配置草案
6.1 3c4g origin nginx 草案
map $http_x_proxy_ng_token $proxy_ng_token_ok {
default 0;
"REDACTED_SECRET" 1;
}
map $http_x_forwarded_host $sub2api_host {
default $http_x_forwarded_host;
"" "proxy.api.lilifamily.com";
}
server {
server_name origin.proxy.api.lilifamily.com;
listen 443 ssl;
ssl_certificate /etc/letsencrypt/live/origin.proxy.api.lilifamily.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/origin.proxy.api.lilifamily.com/privkey.pem;
server_tokens off;
underscores_in_headers on;
client_max_body_size 100m;
location / {
allow 151.242.164.72;
deny all;
if ($proxy_ng_token_ok = 0) {
return 403;
}
proxy_pass http://127.0.0.1:8080;
proxy_http_version 1.1;
proxy_set_header Host $sub2api_host;
proxy_set_header X-Real-IP $http_x_real_ip;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto https;
proxy_set_header X-Forwarded-Host $http_x_forwarded_host;
proxy_set_header X-Proxy-Ng-Token "";
proxy_set_header X-Proxy-Ng-Node $http_x_proxy_ng_node;
proxy_redirect https://origin.proxy.api.lilifamily.com/ https://$sub2api_host/;
proxy_redirect https://catproxy.lilifamily.com/ https://$sub2api_host/;
proxy_read_timeout 3600s;
proxy_send_timeout 3600s;
proxy_buffering off;
proxy_request_buffering off;
}
}
待审阅点:X-Real-IP 和 X-Forwarded-For 是否按第一阶段“不可伪造优先”处理,还是按“保留真实客户端 IP 链路”处理。当前草案偏向保留链路,但需要结合 Sub2API 的 trusted_proxies 配置验证。
6.2 JPpro nginx 草案
server {
server_name proxy.api.lilifamily.com jp.proxy.api.lilifamily.com;
server_tokens off;
underscores_in_headers on;
client_max_body_size 100m;
add_header X-Proxy-Ng-Node "jppro-akile-0504-1c1g" always;
location / {
proxy_pass https://origin.proxy.api.lilifamily.com;
proxy_ssl_server_name on;
proxy_ssl_name origin.proxy.api.lilifamily.com;
proxy_http_version 1.1;
proxy_set_header Host origin.proxy.api.lilifamily.com;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Proxy-Ng-Node "jppro-akile-0504-1c1g";
proxy_set_header X-Proxy-Ng-Token "REDACTED_SECRET";
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_read_timeout 3600s;
proxy_send_timeout 3600s;
proxy_buffering off;
proxy_request_buffering off;
}
}
待审阅点:当前 JPpro 配置已有 client_max_body_size 256m,草案写 100m 是为了和 3c4g 主入口一致。是否保留 256m 需要根据实际请求体规模确认。
6.3 3c4g catproxy 受限直连草案
catproxy.lilifamily.com 不作为常规用户入口。它的作用是运维验证和紧急回滚,因此默认应限制来源。
server {
server_name catproxy.lilifamily.com;
listen 443 ssl;
ssl_certificate /etc/letsencrypt/live/catproxy.lilifamily.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/catproxy.lilifamily.com/privkey.pem;
server_tokens off;
underscores_in_headers on;
client_max_body_size 100m;
# 管理 IP、Tailscale 出口或临时回滚窗口内的来源。
allow <ADMIN_OR_TAILSCALE_IP>;
deny all;
location / {
proxy_pass http://127.0.0.1:8080;
proxy_http_version 1.1;
proxy_set_header Host proxy.api.lilifamily.com;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header X-Forwarded-Proto https;
proxy_set_header X-Forwarded-Host proxy.api.lilifamily.com;
proxy_read_timeout 3600s;
proxy_send_timeout 3600s;
proxy_buffering off;
proxy_request_buffering off;
}
}
server {
listen 443 ssl default_server;
server_name _;
return 444;
}
如果管理 IP 不固定,优先使用 Tailscale、SSH 隧道或临时开放窗口,不建议长期把 catproxy.lilifamily.com 暴露给公网。
7. 验收清单
7.1 基础链路
https://proxy.api.lilifamily.com/health返回 200,且 DNS 解析结果只包含 proxy-ng 节点 IP。- 从管理 IP/Tailscale 访问
https://catproxy.lilifamily.com/health返回 200。 https://jp.proxy.api.lilifamily.com/health返回 200。https://jp.proxy.api.lilifamily.com/返回 200。- 未授权
POST https://jp.proxy.api.lilifamily.com/v1/responses返回401 API_KEY_REQUIRED。 - 普通公网访问
https://catproxy.lilifamily.com/返回 403/444,除非处于明确回滚窗口。
7.2 origin 边界
- JPpro 带 token 访问
https://origin.proxy.api.lilifamily.com/health返回 200。 - JPpro 不带 token 访问 origin 返回 403。
- 非 JPpro IP 访问 origin 返回 403 或连接被拒绝。
- origin 日志能看到
X-Proxy-Ng-Node。 - origin 不把
X-Proxy-Ng-Token继续传给 Sub2API。
7.3 回滚验证
- JPpro 配置可一条改回
proxy_pass https://catproxy.lilifamily.com。 - 3c4g 受限入口
catproxy.lilifamily.com对管理 IP/Tailscale 可访问,对普通公网不可访问。 - 远程配置备份路径已记录。
7.4 运维验证
nginx -t通过。systemctl is-active nginx返回active。- 证书到期时间已记录。
- 访问日志可区分
request_time和upstream_response_time。 - 限流启用后没有误伤正常 API 请求。
/.env、/.git/config、/wp-login.php等扫描路径返回 444/403。- fail2ban 对高频 404/429 和 SSH 爆破生效。
- logrotate 已限制 nginx 日志增长。
proxy.api.lilifamily.com的任一 A 记录故障时,有手工摘除流程。
8. 风险和取舍
| 风险 | 严重性 | 原因 | 缓解 |
|---|---|---|---|
| origin 配置错误导致 JPpro 入口不可用 | 高 | JPpro 切到 origin 后依赖新链路 | 先验证 origin,再切 JPpro;保留回滚 |
| IP 白名单误配 | 高 | 节点 IP 写错或 VPS 换 IP | 操作前核对公网 IP;变更留痕 |
| token 泄露 | 中 | nginx 远程配置含明文 token | 权限 600;仓库只保存脱敏副本 |
| 真实客户端 IP 丢失 | 中 | 为防伪造而覆盖 X-Forwarded-For |
明确第一阶段优先级;后续再做可信 IP 链路 |
| 限流误伤正常请求 | 中 | API 客户端并发高、流式请求长 | 先保守配置并观察日志 |
| 大流量 DDoS 打满 proxy-ng 带宽 | 高 | 不使用 Cloudflare LB/清洗时,攻击流量直达 VPS | 接受该边界;多节点分散;必要时换高防/CDN |
catproxy 被公网发现并直接访问 |
高 | 3c4g 直连入口暴露会绕过 proxy-ng | 默认 deny all,仅管理 IP/Tailscale/临时回滚允许 |
| 多 A 记录随机命中坏节点 | 中 | 普通 DNS 无健康检查 | TTL 60-300 秒;监控告警后手工摘除坏 A 记录 |
| 日志占满磁盘 | 低 | access log 增多 | 配置 logrotate 或采样 |
9. 待确认项
- 公开服务入口采用
proxy.api.lilifamily.com,但只解析到 proxy-ng 节点。 catproxy.lilifamily.com作为 3c4g 受限直连、管理和紧急回滚入口。- origin 回源入口采用
origin.proxy.api.lilifamily.com。 - proxy-ng 节点统一使用
<node>.proxy.api.lilifamily.com命名。 - 不依赖 Cloudflare Load Balancing;
proxy.api.lilifamily.com使用普通 A 记录指向 proxy-ng 节点。 catproxy.lilifamily.com的长期访问策略:仅 Tailscale/管理 IP,还是完全不开放公网。- JPpro 到 origin 是否继续使用 443,还是改用 origin 专用端口。
- 第一阶段是否优先保证
X-Forwarded-For不可伪造,接受真实客户端 IP 链路暂时简化。 - token 采用单 token 还是一开始就做双 token 轮换。
- 是否立即启用限流、fail2ban、扫描路径 444,还是先只增强 origin 安全边界。
- 监控使用 Uptime Kuma、cron + webhook,还是暂时手工巡检。
- 下一台 proxy-ng 节点是否已经确定。
10. 下一步
建议先审阅并确认以下决策:
- origin 域名和是否使用 443。
- JPpro 回源切换窗口和回滚策略。
X-Forwarded-For第一阶段处理策略。- token 保存位置和轮换方式。
确认后再输出执行版文档,执行版应包含:
- 远程配置文件路径。
- 备份命令。
- 变更步骤。
- 验证命令。
- 回滚命令。
- 本地
ops/remote/留痕更新清单。