← 返回文章列表

从零自建代理节点:一场 3X-UI 面板与 xray 的深夜斗争

📅 2026年9月10日 · 📝 7622 字 · ⏱️ 20 分钟 · #网络#服务器#代理


从零自建代理节点: 3X-UI 面板与 xray

面板不能裸奔,订阅不能明文,节点还得真的能用——换个带家庭或者机房ip的服务器或许真的能做大做强(算了,不敢😅)。

这是一篇把“自建代理节点教程”和“踩坑记录”合在一起的实录:前半部分讲怎么搭,后半部分讲为什么明明每一项看起来都对,Clash 还是一脸冷漠地超时。


0. 事情是怎么开始的

我已经订阅了一个机场,但手里还有一台新加坡的 VPS ,闲着也是闲着,于是就产生了一个非常典型的想法:

“既然我都有 VPS 了,为什么不自己搭一个节点?”

这句话听起来很合理,甚至有一点工程师的浪漫。然后我就从晚上 7 点半折腾到了 11 点,亲眼见证了面板、xray、证书、Cloudflare、防火墙轮流出来给我上课。

我的要求其实不算过分:

3X-UI 面板不能暴露到公网,毕竟管理后台只能对我开放;

订阅链接要走 HTTPS,不能把配置明文晃在公网;

自建节点要能和原来的机场订阅共存,想切换时就切换。

最终架构大概是这样:

[我的电脑 Clash]
        │
        │ ① 订阅链接 https://域名/sub/xxx
        │    (Cloudflare + nginx,HTTPS)
        ▼
[Cloudflare] ──→ [VPS nginx :443] ──→ [3X-UI 订阅服务 :2096]
                                      (只监听 localhost)
        │
        │ ② 节点直连 VPS_IP:8443
        │    (UDP,Hysteria2)
        ▼
                [VPS xray :8443]

这里有一个很重要的分工:订阅链接走域名,节点流量直连 IP。订阅适合走 Cloudflare 的 HTTPS 反代,但 Hysteria2 使用 QUIC/UDP,不能指望 Cloudflare 替你转发代理流量。

一、代理节点到底在干什么

先用一句不太严谨但足够好懂的话解释:代理节点就是一台帮你转发网络请求的海外中间服务器。

你的设备 ──(加密 + 伪装连接)──> 海外 VPS ──(正常访问)──> 目标网站
        <───────────────────────────────────────────────────────

关键点有三个:

  1. 你的设备和 VPS 之间是一条加密隧道,流量会被加密,并尽量伪装成正常的 HTTPS 或 QUIC 流量;
  2. VPS 和目标网站之间,是海外服务器自己的正常网络连接;
  3. 所以本质上就是:借 VPS 的海外网络身份访问目标服务。

这和之前用 frp 做内网穿透有点像,都是“找一台中间服务器转发”。区别是 frp 更像老实的搬运工,而代理协议还要负责加密和伪装,属于“搬运之前先换件衣服”。

二、协议怎么选:先别急着全都装

协议抗干扰能力速度延迟敏感场景特点
Hysteria2✅ 优秀基于 QUIC/UDP,抗丢包
VLESS + Reality很强良好伪装成访问真实网站
Trojan一般老方案,需要证书
Shadowsocks一般经典方案,特征相对明显

我的选择是:

想要延迟低一点、看视频或者折腾游戏:Hysteria2
想要稳定一点、长期使用:VLESS + Reality
两个也可以同时开在不同端口,Clash 里一起导入,哪个状态好就用哪个。

本文主要记录 Hysteria2 的部署过程,因为它在高延迟、存在丢包的线路上体感通常更好。但“更好”不等于“瞬移”——如果服务器在新加坡,国内访问它的物理距离不会因为换了协议就消失。

三、用 3X-UI 部署节点

如果手搓所有 xray 配置,我大概会在 YAML、JSON 和人生之间迷路。所以这次用了 3X-UI:安装面板,然后在网页里添加入站、生成订阅。

3.1 安装面板

SSH 登录 VPS 后执行:

bash <(curl -Ls https://raw.githubusercontent.com/mhsanaei/3x-ui/master/install.sh)

安装完成后会显示面板地址、账号和密码。先把这些信息记好,不要安装结束后只顾着开心,然后回头问“刚才密码是什么来着”。

3.2 开放需要开放的端口

在云厂商安全组里放行真正需要的端口,例如:

面板端口(后面会尽量限制访问来源);

订阅服务反代使用的 HTTPS 端口,例如 443;

Hysteria2 节点端口,例如 UDP 8443。

不要因为“反正是自己的 VPS”就把所有端口都打开。防火墙不是摆设,它是服务器门口那个虽然有点烦、但确实应该存在的保安。

3.3 添加入站

进入 3X-UI 的入站列表 → 添加入站

VLESS + Reality:

  • 协议:vless
  • 传输:tcp,开启 Reality
  • SNI:填一个真实网站域名,例如 www.microsoft.com
  • 公钥 / 私钥:让面板自动生成
  • shortId:留空或随机生成

Hysteria2:

  • 协议:hysteria2
  • 端口:例如 4438443
  • 密码:设置一个自己保存好的密码
  • TLS 证书:必须配置,后面会讲我怎么被它教育的

保存之后,节点理论上就生效了。注意这里的“理论上”非常重要,因为接下来还有六个坑排队等着。

四、订阅导入 Clash

方式 A:订阅导入(推荐)

在 3X-UI 面板里找到对应入站的订阅设置,生成 Clash 格式订阅链接,然后:

  • Clash Verge Rev / Clash Meta:订阅 → 新建 → 粘贴链接 → 导入 → 选择节点 → 打开系统代理;
  • Clash for Windows:Profiles → 粘贴链接 → Download。

如果订阅链接经过了 nginx 和 Cloudflare,确认它访问的是正确的订阅路径,而不是博客首页。博客首页很好看,但它显然不能当代理配置文件吃。

方式 B:手动写配置

不想使用面板订阅,也可以直接在 Clash 配置的 proxies: 下面添加节点。

Hysteria2 示例:

proxies:
  - name: "新加坡-hy2"
    type: hysteria2
    server: 你的VPS_IP
    port: 443
    password: 你的密码
    sni: bing.com
    skip-cert-verify: true

VLESS Reality 示例:

proxies:
  - name: "新加坡-reality"
    type: vless
    server: 你的VPS_IP
    port: 443
    uuid: 你的uuid
    network: tcp
    tls: true
    flow: xtls-rprx-vision
    servername: www.microsoft.com
    reality-opts:
      public-key: 你的公钥
      short-id: 你的shortId
    client-fingerprint: chrome

这里再次强调:如果节点使用自签证书,客户端配置里通常需要 skip-cert-verify: true。当然,生产环境更推荐使用正确配置的证书,而不是把“跳过验证”当成万能创可贴。

五、六个坑:每一个都像在说“明明是你配置错了”

坑 1:面板和 xray 是同一个服务

我一开始以为:面板只是管理工具,停掉它之后,xray 应该还能继续工作。

现实是:3X-UI 的 x-ui.service 同时负责 Web 面板和 xray 核心。面板停了,xray 也跟着停。它们不是“老板”和“员工”,更像是“一个进程里的两个工位”。

所以:

systemctl status x-ui

如果显示 inactive,不要只觉得“面板没了而已”,你的节点大概率也已经一起下班了。

坑 2:SSH 隧道把节点地址变成了 localhost

为了不把面板暴露到公网,我通过 SSH 隧道访问它:

ssh -L 0721:127.0.0.1:0721 root@你的VPS_IP

结果在隧道里生成订阅时,3X-UI 根据访问请求的 Host 自动推断节点地址,最后导出的节点变成了:

server: localhost

然后我的电脑 Clash 很认真地连接了自己的电脑,当然什么也没连接上。这个错误的可爱之处在于:配置文件看起来完整,节点也成功导入,但它压根没有去 VPS。

解决办法:在面板里显式配置节点的公网地址,填 VPS 的 IP,不要让它从 SSH 隧道的 Host 自动猜。

坑 3:节点填域名,Cloudflare 负责把它送走

我又想当然地把节点地址填成了自己的域名。这个域名套在 Cloudflare 后面,开着橙云代理。

问题是 Cloudflare 主要代理 HTTP / HTTPS / WebSocket 等流量,不能替你代理 Hysteria2 的 QUIC / UDP 节点流量。于是节点数据包走到 Cloudflare 门口,Cloudflare 看了一眼,大概说了句“这个我不认识”,然后超时。

正确分工:
订阅链接:走域名,走 HTTPS,走 Cloudflare + nginx。
节点连接:直连 VPS 的 IP,不要让 Hysteria2 绕去 Cloudflare。

坑 4:Hysteria2 没证书,xray 直接崩溃

Hysteria2 底层使用 QUIC,而 QUIC 需要 TLS。没配证书时,xray 日志给出了这样的报错:

failed to build inbound config with tag in-8443-udp
> failed to parse certificate
> both file and bytes are empty.

翻译一下就是:你让我开门,但你连门锁都没装。

更麻烦的是,这不是只影响 Hysteria2 这一条入站。xray 核心因为配置解析失败直接崩溃,其他节点也一起没了。最后我用 openssl 生成了自签证书:

openssl req -x509 -newkey rsa:2048 -keyout /etc/x-ui/certs/hy2.key \
  -out /etc/x-ui/certs/hy2.crt -days 3650 -nodes -subj "/CN=hy2"

证书填进面板后,xray 才终于愿意重新上班。

坑 5:自签证书被 Clash 拒绝

证书有了,xray 也起来了,端口也放行了,但 Clash 还是超时。

最后发现,自签证书不在系统信任的 CA 列表里,Mihomo 内核默认会校验证书,于是把它拒之门外。

自签证书节点需要在客户端配置里加入:

skip-cert-verify: true

加上之后,节点立刻通了。这个坑尤其隐蔽:服务端、端口、防火墙看起来全都正常,但客户端就是不愿意握手。遇到“所有东西都对但还是超时”,证书校验值得排在排查清单前面。

小提醒:skip-cert-verify 适合自签证书的测试或明确场景,不应该成为“证书随便搞”的借口。长期使用还是应该配置正确的证书和域名。

坑 6:订阅路径返回了博客首页

nginx 反代配置好之后,直连 VPS 测试订阅是通的,但通过域名访问 https://域名/sub/xxx,Clash 拿到的却是我的博客首页。

一开始我还以为是订阅内容突然开始追求文学性了。后来排查发现,Cloudflare 的 SSL 模式或缓存规则把请求处理歪了。

需要检查:

  1. Cloudflare SSL/TLS 模式使用“完全(Full)”,不要使用容易导致反代异常的灵活模式;
  2. 订阅路径配置绕过缓存,订阅内容不能被缓存成旧版本;
  3. nginx 的反代路径确实指向本机的 3X-UI 订阅服务端口,例如 0721
  4. 域名、路径和面板生成的订阅地址保持一致。

六、面板怎么藏:三板斧

这次折腾下来,我觉得面板加固至少要做三件事:

  1. 非标准端口:不要把管理入口直接放在最显眼的位置;
  2. 秘密路径:修改 Web base path,让默认扫描少一点收获;
  3. 强密码 + 防火墙:面板端口尽量只允许自己的来源访问,或者直接封死公网入口。

如果想彻底不暴露面板,可以把面板端口防火墙封死,只通过 SSH 隧道访问:

ssh -L 0721:127.0.0.1:0721 root@你的VPS_IP

这样管理面板只能从 SSH 进去,公网扫描器看到的就不是一个敞开的登录框,而是一扇根本不存在的门。

七、延迟高的真相:协议不是魔法

节点终于能用了,但速度和延迟又开始提醒我:服务器在新加坡这件事,并没有因为配置成功而改变。

影响延迟的因素,按重要程度大致是:

1. 物理距离

新加坡到国内的基础 RTT 大约在 70~150ms,光速和路由绕行共同决定。这个是物理规律,不是把配置文件再改三遍就能消失的。

2. 国际出口拥堵

晚高峰(尤其 20:00~23:00)国际线路拥堵,抖动、丢包和速度下降一起出现。白天“还行”,晚上“怎么又不行了”,通常不是 VPS 突然产生了情绪,而是线路真的在堵。

3. 防火墙干扰

防火墙更常见的影响是丢包、限速和阻断特定协议,不会凭空把基础物理延迟变成两倍。但它会和晚高峰叠加,让卡顿更加明显。

所以结论是:延迟高主要是“距离 + 线路拥堵”,防火墙更多是推波助澜。不要指望换一个协议之后,位于新加坡的服务器突然搬到家门口。

比较有效的优化顺序

  1. 换近机房:香港通常最快但更贵,日本、台湾、韩国也可以考虑;
  2. 选优质线路:电信看 CN2 GIA,移动看 CMI,联通看 CUII / 9929;
  3. 换 Hysteria2:QUIC/UDP 在高延迟和丢包环境下体感可能明显好于 TCP;
  4. 使用中转 / 跳板:改善拥堵路由,但解决不了源服务器距离远的问题;
  5. 避开晚高峰:大流量操作尽量放到白天或深夜。

一句话总结:换近机房和优质线路是治本,换 Hysteria2 是锦上添花,中转跳板主要治标。

八、我的排查顺序

以后再遇到节点超时,我决定不再凭感觉乱改配置,而是按照下面的顺序排查:

  1. 先看 xray 有没有启动,Hysteria2 是 UDP,可以用 ss -ulnp 检查;
  2. 再看 VPS 系统防火墙和云厂商安全组有没有放行对应端口;
  3. 然后查证书,尤其是自签证书对应的 skip-cert-verify
  4. 确认节点地址是 VPS IP,而不是被 Cloudflare 代理的域名;
  5. 最后再考虑 Cloudflare、线路和其他网络层问题。

九、命令速查

# 生成自签证书(Hysteria2 用)
openssl req -x509 -newkey rsa:2048 -keyout /etc/x-ui/certs/hy2.key \
  -out /etc/x-ui/certs/hy2.crt -days 3650 -nodes -subj "/CN=hy2"

# 看 xray 有没有监听(Hysteria2 是 UDP)
ss -ulnp | grep 8443

# 重启面板 + xray(同一个服务)
systemctl restart x-ui

# SSH 隧道访问被封的面板
ssh -L 0721:127.0.0.1:0721 root@你的VPS_IP

# Clash 节点配置里,自签证书要加这一行
skip-cert-verify: true

十、最后

从“面板暴露了怎么办”到“节点终于能上网”,中间踩了证书、Cloudflare、防火墙、端口和地址推断等一串坑。最深的感受是:代理节点这条链路上,每一环都能单独把你卡死,而且报错往往还不太会直接告诉你真正的问题。

比如:

节点连不上,可能是证书;
证书没问题,可能是 Cloudflare;
Cloudflare 没问题,可能是 localhost;
localhost 改好了,可能是 xray 根本没启动;
xray 启动了,可能是晚高峰线路堵了。

所以这次最大的收获不是“我成功搭了一个节点”,而是终于知道该怎么拆解问题:先看服务,再看端口,再看证书,再看地址,最后再去怀疑线路。一步一步排查,比对着超时提示陷入哲学思考有效得多。

当然,这类工具请只用于合法用途,例如跨境办公、访问学术资源和远程开发,并遵守当地法律法规。技术可以折腾,边界还是要记得看。

总之,节点现在能用了,面板也没有裸奔,订阅和机场也能和平共处。至于延迟嘛——它还在新加坡,暂时没有搬家的打算。

最后啊最后,就是因为这个B服务器是广播ip,导致基本上有风控的网站都去不了(也没有想到)😅,所以 x-ui 最后就关掉了,不过还是纪念一下(╹ڡ╹ )

——鱼小鳄Sugary

2026年9月10日深夜

💬 评论 (0)

加载中...