VPNGate 家宽出口实战:Oracle VPS + fanout + VLESS/REALITY 全链路

Noesis 2026-10-05 14:52 1

VPNGate 家宽出口实战:Oracle VPS + fanout + VLESS/REALITY 全链路



TL;DR:用 Oracle VPS 做"接线总机",fanout 拨 VPNGate 志愿者家庭宽带做真实出口,VLESS+REALITY 入站,订阅经 nginx + Cloudflare Worker 下发到 karing。零成本,真居民 ISP 出口。

适用:想低成本获得居民 ISP 出口 IP 的个人学习;不适用:需要稳定固定 IP、高纯净度、商用的场景(看完前言再决定)。

测试环境:2026-10,Oracle 圣何塞 ARM(Ubuntu),fanout(byJoey/fanout,main 分支,部署前请固定 commit 并通读 install.sh),xray-core,karing。

本文所有 IP、域名、token、端口均为示例占位符,请替换成自己的;发布后建议更换示例中的 SNI 与端口。





零、前置声明:合理使用(先看完这节)


VPNGate 是筑波大学运营的志愿者网络,节点来自全球志愿者共享的家庭宽带。这意味着:



  1. 志愿者在为你的流量背锅——他们的家庭 IP 会出现在你访问的服务的日志里;

  2. 把 VPNGate 出口做成订阅分发给他人,可能违反其使用条款,也放大了对志愿者的连带风险。本教程默认仅自用;

  3. 请合理使用、不要跑大流量、不要做违规的事。部署与使用后果自负。


能接受,再往下看。




一、架构与取舍


局限先行



  1. 节点寿命按小时计,随时会死,必须有自动重拨;

  2. IP 是共享的——同一出口可能几十个人在用,商业 IP 情报库普遍把 VPNGate 段标记为 VPN/proxy。别指望它帮你过严格的账号/支付风控,“真住宅"不等于"高纯净”;

  3. 节点质量参差,有的国家常年没节点(截至 2026-10:美国符合家宽过滤的极少,新加坡经常挂零)。


架构


数据面(你的流量真正走的路):


你(karing)→ VPS:1000x(VLESS+REALITY 入站)
→ netns 内 SOCKS5 → VPNGate 志愿者家庭宽带 → 目标网站

订阅面(只负责下发配置,不走流量):


karing → Cloudflare Worker(sub.example.com)
→ VPS:10006(nginx TLS,只代理订阅 endpoint)→ fanout 面板 127.0.0.1:8899

上线前必做 3 件事(别等"以后再加固")



  1. 面板进程只绑 127.0.0.1,防火墙不放行面板端口;

  2. 想清楚 fail-open 兜底(见第七节),别等出事;

  3. 搭一个最简健康检查(第七节给逻辑),15 分钟跑一次。




二、准备工作



  1. Oracle Cloud 账号:Always Free ARM 实例,Ubuntu。注意 Oracle 有两层防火墙:VCN 的 Security List/NSG(云控制台管)+ 实例内部的 iptables(机器里管),端口必须两层同时放行,排障时一层一层看;

  2. 一个域名,NS 接入 Cloudflare,例如 proxy.example.com 做回源、sub.example.com 绑 Worker;

  3. Cloudflare 账号(Worker 用)。



灰云/橙云是关键:Cloudflare 只代理 443 等少数端口(10006 不在其中),所以 proxy.example.com 必须设为 DNS only(灰云),直接解析到 VPS IP。设成橙云的话,Worker 回源和 VLESS 直连都会失败。sub.example.com 绑 Worker 自定义域名,走 CF 网络没问题。





三、部署 fanout + 立即加固


# 先看一眼脚本再跑,main 分支换成固定 commit 更稳
bash <(curl -fsSL https://raw.githubusercontent.com/byJoey/fanout/main/install.sh)
systemctl enable --now fanout

装完面板默认监听 0.0.0.0:8899 且是 HTTP。先加固再用,别等第八节:



  1. 进面板改掉默认密码(面板路径是安装时生成的一串随机字符,形如 /<secret-path>,后面所有地址都要带它);

  2. 把面板绑到本机:settings.json 里 listen_addr 改为 127.0.0.1,systemctl restart fanout;

  3. 以后进面板走 SSH 隧道,不走公网:


ssh -L 8899:127.0.0.1:8899 [email protected]
# 本地浏览器打开 http://127.0.0.1:8899/<secret-path>


  1. iptables 只放行业务端口。OCI 的 Ubuntu 镜像 INPUT 链尾有 REJECT:如果链尾已有 REJECT/DROP,允许规则必须插到它前面(iptables -I),否则等于没加。加完 netfilter-persistent save。操作前先开第二个 SSH 会话,防止把自己锁死;IPv6(ip6tables)别漏。




四、新建出口:拨 VPNGate 节点


面板"新建出口"→ 选国家 → fanout 从 VPNGate 列表挑节点拨号。务必打开"只用家宽节点"过滤,否则可能拨到机房节点。



  • 优先日本、韩国:节点多、延迟低、存活相对久;

  • 每个国家 1~2 条就够,多了是维护负担;

  • 美国/新加坡:截至 2026-10 前者极少通过家宽过滤(fanout 会直接拒绝"没有可用的空闲节点"),后者经常挂零,看到没有就换日韩,别硬来。


出口体检(每条新出口都做)



  1. 面板看当前出口 IP → 查 ASN,确认是居民 ISP(So-net、LG DACOM 之类);

  2. 交叉验证 hosting 标记:ipinfo.io/<ip> 看 hosting 字段(whois 只能看到 ISP 名,分不出住宅还是商业专线);

  3. 测速:志愿者家宽上行经常只有几 Mbps,心里有数;

  4. 实测你的目标场景(流媒体解锁等),别信"理论上能过"。




五、VLESS 入站与 REALITY


5.1 端口规划(示例)


fanout 建入站会随机分配高位端口(如示例里的 48650),改成安全组放行范围内的。示例规划 10001~10005(你的环境按自己的安全组定):






































端口 绑定出口 说明
10001 (不绑定) VPS 直连
10002 日本-1 住宅出口
10003 韩国-1 住宅出口
10004 日本-2 住宅出口
10005 韩国-2 住宅出口

改端口走面板 API。密码别写进命令行(会进 shell history 和 ps),用环境变量或交互输入:


read -s PANEL_PW
curl -s -b cookies.txt -c cookies.txt -d "password=$PANEL_PW" \
http://127.0.0.1:8899/<secret-path>/login > /dev/null
curl -s -b cookies.txt \
"http://127.0.0.1:8899/<secret-path>/api/panel/inbound/update?id=<入站ID>&port=10002"
chmod 600 cookies.txt # 用完删掉

改完确认 xray 路由绑定还在(in-10002-tcp → fanout-vpn<id>)。


5.2 REALITY 参数(概念先分清)



  • dest:服务端伪装/回落目标站;

  • serverNames(服务端)/serverName(客户端 SNI):握手时发送的域名;

  • fingerprint:客户端 TLS 指纹(如 chrome),和 SNI 是两回事;

  • privateKey/publicKey:REALITY 密钥对(面板建入站时自动生成);

  • shortId:客户端与服务端匹配用的短 ID,别手改。


REALITY 不用你为每个入站申请证书,借大厂域名的 TLS 握手做伪装。flow 留空即可(xtls-rprx-vision 按需开,它是客户端属性,改动不涉及换 UUID)。


5.3 SNI 选择与分散(建议级别)


同一 IP 上的 5 个端口本来就能被聚类,"分散 SNI"只是降低关联特征的经验做法,不是协议要求。建议:



  • 每个入站用不同的大厂域名做 SNI(示例:tesla / apple / amazon / bing / cloudflare——示例而已,别照抄);

  • 选站标准:支持 TLS1.3、看着像正常网站、最好与 VPS 地域别差太远;

  • fanout 自带的 dest 检查通过 ≠ 客户端能连,必须做端到端验证。


实测坑(截至 2026-10):www.microsoft.com 做 SNI,服务端检查能过,但从圣何塞发起 REALITY 握手连续失败,换 www.bing.com 一次通过。SNI 定下来之前先验证:


openssl s_client -connect www.bing.com:443 -tls1_3 -alpn h2 </dev/null | head -5

5.4 端到端验证(两步)



  1. VPS 上起 xray 客户端,走入站的 vless 链接做 SOCKS 出口,curl -x socks5h://127.0.0.1:11801 https://api.ipify.org,返回 IP 与面板显示的出口一致;

  2. 本地用 karing 实连一次——VPS 上通不代表你的网络路径通。




六、订阅链:证书 → nginx → Worker


6.1 先签证书


Let’s Encrypt 的 HTTP-01 验证走的是 80 端口,和 443 无关。所以:443 没放行不影响申请,只要 80 通;80 也不通才需要 DNS-01。


# 80 已放行时最简单(示例拓扑里 80 是开的,顺便做 301 跳转)
certbot certonly --nginx -d proxy.example.com
# 续期由 systemd timer 自动处理;定期验证:
certbot renew --dry-run

注意顺序:先有证书,再写 nginx 的 ssl 配置(否则 nginx -t 直接失败)。签完把子域名记下来——证书会进 CT 公开日志,子域名是藏不住的。


6.2 nginx:只暴露订阅 endpoint


server {
listen 10006 ssl;
server_name proxy.example.com;

ssl_certificate /etc/letsencrypt/live/proxy.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/proxy.example.com/privkey.pem;

access_log off; # 订阅 URL 带 token,会被明文记进日志——关掉是降低泄露面,不是根治
server_tokens off;

# CF 回源 IP 白名单:只是挡掉直连扫描的噪音,不是认证!
# 任何人的 CF 站点/Worker 出口都在这些段里。完整列表:
# curl -s https://www.cloudflare.com/ips-v4 https://www.cloudflare.com/ips-v6
# 拼成 allow 行(v4+v6 都要),最后 deny all
allow 173.245.48.0/20;
# ...(全部填上,别学示例只写两段就上线,会把正常回源 403 掉)
deny all;

location = /<secret-path>/sub {
proxy_pass http://127.0.0.1:8899;
}
location / {
return 404;
}
}


  • location = 精确匹配是重点:写成 location / 全代理等于把面板登录页挂公网;

  • 端口用 10006 是因为示例里 OCI 安全组没放 443;你的厂商放行了 443 就直接用 443;

  • 想要真认证:上 Authenticated Origin Pulls(mTLS),或 Worker 加自定义头 + nginx 校验。


6.3 Cloudflare Worker:订阅中转


// 建议用 Module Worker(export default)+ wrangler;
// 我们当时用 API 单文件上传时 module 格式被拒(10021),
// 才用的 service-worker(addEventListener)格式——那是上传方式问题,不是"必须"
const UPSTREAM = 'https://proxy.example.com:10006'; // 别硬编码 IP:Worker subrequest 不支持直接对 IP 发起(我们实测报 1003),一律用域名

export default {
async fetch(req, env) {
const url = new URL(req.url);
// 只放行订阅路径,别做成开放转发器
if (url.pathname !== '/<secret-path>/sub') {
return new Response('Not Found', { status: 404 });
}
let resp;
try {
resp = await fetch(UPSTREAM + url.pathname + url.search,
{ headers: { 'User-Agent': 'Mozilla/5.0' } });
if (!resp.ok) throw new Error('upstream ' + resp.status);
} catch (e) {
return new Response('Bad Gateway', { status: 502 });
}
let body = await resp.text();
try {
// 最小实现:假设订阅是标准 base64;base64url/分行等情况需另行处理
let decoded = atob(body.trim());
decoded = decoded.split('198.51.100.10').join('proxy.example.com');
body = btoa(decoded);
} catch (e) {
return new Response('Bad Gateway', { status: 502 });
}
return new Response(body, {
status: 200,
headers: {
'Content-Type': 'text/plain; charset=utf-8',
'Cache-Control': 'no-store', // 带 token 的订阅别被缓存
},
});
}
};

说明:这是最小实现——透传时丢了上游的 subscription-userinfo 等头(karing 会用),生产用建议补上;Worker 只是转发层,不做 token 鉴权,别误会。


最终订阅地址:https://sub.example.com/<secret-path>/sub?token=<SUB_TOKEN>。


6.4 验证订阅


curl -s -A "Mozilla/5.0" \
"https://sub.example.com/<secret-path>/sub?token=<SUB_TOKEN>" \
| base64 -d | grep -o "sni=[^&#]*" | sort | uniq -c
# 期望 5 个不同 sni 各 1 次;另检查 UUID 不重复

curl 带 -A:CF 会拦默认 UA(Python urllib 不带 UA 拿过 403,虚惊一场)。




七、fail-open:最隐蔽的风险


实测:隧道死掉后,xray 里对应入站的路由规则会消失,流量 fallback 到默认出站(direct = VPS 本机出口)。客户端毫无感知,等于静默切成了机房 IP。


我们的做法(15 分钟跑一次):



  • 对每条入站做 REALITY 握手,验证出口 IP 不是 VPS 本机 IP(最好连 ASN 一起对,连续多次确认);

  • 连续 2 次失败 → 调面板 API 自动禁用该入站(连不上,好过静默走直连);

  • 之后每轮恢复探测:重开 → 握手验证 → 通了保持开启并告警,没通重新禁用;

  • 手动禁用的永不自动碰;同一故障只告警一次。


更彻底的结构性兜底:在 xray 路由末尾给住宅入站加一条 → blackhole 的 catch-all(10001 直连显式走 direct),路由丢了就断流不断泄。但要先确认 fanout 重写配置时不会覆盖这条——没验证过,列出来供参考。




八、日常维护(每月看一眼)



  • 健康检查有没有持续 ALERT 的隧道;

  • certbot renew --dry-run 确认续期链路;

  • CF 官方 IP 段变更 → 同步 nginx 白名单;

  • 备份:fanout 配置目录(面板密码、sub_token、入站配置)+ nginx 站点配置,打包加密异地存,口令单独保管;备份完最好做一次恢复演练;

  • 准备一个备用订阅域名,万一主域名被封可迁移。




九、避坑速查表
















































症状 原因 解法
新端口本地通、公网不通 iptables 链尾 REJECT 吃了规则 / 安全组没放 iptables -I 插前面 + netfilter-persistent save;检查云控制台安全组
面板绿勾但客户端连不上 fanout 的 dest 检查只是服务端视角 xray 客户端端到端握手验证(5.4)
karing 订阅 502 裸 IP+非标端口被拦截;或刷新请求走了代理自身 走 Worker 订阅链;订阅域名加直连规则;偶发时可临时关 VPN 排查
某天突然变成机房 IP 隧道死了,fail-open 第七节健康检查 + 自动禁用
能连但网页转圈 链路 UDP/QUIC 不通 karing 里禁用 QUIC/HTTP3
大页面/下载卡死 嵌套隧道 MTU 问题 调小 mssfix / tun-mtu
换了 SNI 还是握手失败 目标站回包策略问题 换 SNI(microsoft→bing 实测案例),用 s_client 先验证站点



十、备选与进阶



  • 嫌 nginx+证书麻烦:可以试试 cloudflared tunnel 或"VPS 定时把订阅推到 Workers KV",整套回源都不用开了;

  • 要更强伪装再看 Hysteria2 等,但先把这套跑稳。




初稿 v2。实测 4 条住宅隧道(日本×2、韩国×2)+ 1 条直连。教程里的"血泪"都是真踩出来的,欢迎指正。

最新回复 (1)
  • Trent 10-05 19:17
    1楼

    github有类似的项目,AimiliVPN

* 帖子来源Linux.do
返回