三个月之前,词元发布了一则非常详细的 VLESS、WebSocket、TLS 加上 CDN 的代理搭建指南(搭建自己的代理服务器),给出了词元当时认为最安全的方案。
事实证明,这个方案确实很安全,元旦期间词元用的 Cloudflare Anycast IP 被封了,但词元的服务器 IP 依然坚挺,可以正常访问(改 hosts
可以继续使用 CDN)。而这个安全性,主要就来自于 CDN 的加持,这样可以最大限度地防止 IP 泄露,将自己的流量隐藏在 CDN 边缘服务器的巨量吞吐中,被封也就无从谈起了。
上个月,词元又在 XTLS/Xray-core 的讨论中看到维护者 RPRX 提供了一种他十分自豪的方案:XHTTP。光是从他宣传 XHTTP 的力度(超长“简”介、写进个人主页)上来看,这个协议很牛。
之前词元嫌麻烦,原本的“三驾马车”协议也很够用,而且词元也不能确定这个协议抗封锁的有效性。(词元并不是科学上网领域的专家!)但是最近看到不良林也发布了搭建这种协议节点的视频,说实话有点心动了。借着 L 站上白嫖的节点,词元删掉了原本搭建使用的脚本,来试试这个金光闪闪的新协议!
“……这下又开启了一个崭新的时代……”——RPRX
✨ 这是什么
词元与上一篇文章相反,先来讲讲 XHTTP 的原理。因为,来这儿看先进技术的您估计已经有了能用的代理节点,看这则博客的目的大概是改进一下安全性,肯定要先知道凭什么做出改变嘛。
🫣 永不被封的 meek 协议
故事的开端是一个叫作 meek 的协议。这个协议原本是 TOR 的一种混淆处理方式,在 TOR 的实现中模仿了 Azure 的流量,用以防止封禁。
TOR 浏览器中也提到,这种方法虽然能在“重度”审查地区使用,但是会非常缓慢。
半年之前,Xray 的维护者在内核中实现了 meek 协议。其关键,就在于将 VLESS 节点信息伪装成普通 HTTP 流量,采用标准格式。正常的 HTTP 流量中,服务端在没有客户端的请求的情况下,不能向其主动发送数据包。为了克服这一问题,meek 在发送请求之后,不能从服务端得到数据,而是会再次发送请求,获得服务端已经从客户端请求的地址中获取的数据。
绕晕了?列个表:
- 浏览器:访问
hi.bug-barrel.top
。 - 客户端代理:拦截请求,先用 VLESS 加密,然后包进正常 HTTP 数据包中,发送给服务端代理。
- 过墙(内到外),检测到正常 HTTP 数据包。
- 服务端代理:收到 HTTP 数据包,解包;里面是 VLESS 数据包,解包;哦,原来是
hi.bug-barrel.top
,发送给目标服务器。 - 目标服务器:对服务端代理慢慢发包,正在传输。
- 客户端代理:过一段时间,发包问服务端代理“好没好啊”,包装方式相同。
- 过墙(内到外),检测到正常 HTTP 数据包。
- 服务端代理:还没有收到目标服务器发的包,回复一个空数据包,包装方式相同。
- 重复以上三步,直到服务端代理收到目标服务器的数据包,服务端代理回复有内容的数据包。
就这样,客户端反复发包,服务端反复回复(还得严格按照顺序),直到数据传输完成。
优点是全部都是标准的 HTTP 数据包,以往 GFW 依赖的那些特征通通不存在(VLESS 数据本身加密,加上 HTTPS 加密,不大可能泄露),而且还能用 CDN(标准 HTTP 嘛);缺点就是,慢!这方法本身就浪费时间,发挥一下优势,加个 CDN——更慢。
根据不良林的实测,即使是很好的线路(CN2 GIA),给 meek 这么一搞,速度能上到 200 Kbps 就算好的了。因为其不会被封的特性,当个备用节点传送“千金家书”还是不错的,但是日常使用……还是算了。
🛜 全能的 XHTTP
meek 的思想可以概括为“分包上行,流式下行”,而 XHTTP(原名SplitHTTP)解决的问题就是下行速率的问题。XHTTP 实现了不损失上行效率、流式地过 CDN,然后用不定长的包流式下行,且上下行分流,只要是标准 HTTP 包支持的,上下行都可以分别支持(可以完全不同)。
这确实是一个非常优雅的解决方案,把之前 WebSocket、gRPC、REALITY 等等的优势综合起来,而且特征非常低。具体实现的特别之处,可以看看维护者的夹叙夹议的讨论,这小介绍搞得 😄
讨论里对于 XHTTP 的技术细节介绍得非常详尽,如果您有一些网络基础,就会发现这玩意儿确实挺牛。春节马上就要到了,您做好准备开工了吗?
⚙️ 搭建 XHTTP 代理
本节参考不良林的视频撰写,综合了词元的个人经验,也很建议您去看看原视频,有些东西词元在上一篇文章里已经讲过了,就不仔细介绍。
词元在自己研究的基础上,决定按照视频里的指导,选择这样的协议组合:VLESS、XHTTP、Reality,以及 CDN 保护,上下行流量分裂。
💡 其实原视频建议下行不使用 CDN,因为 gRPC 流式下行用 CDN 会比较慢。但是这里为了安全,词元还是决定全部使用 CDN。
这是快速迭代的科学上网技术中最先进、最安全的方案(尤其是在 XHTTP 的参与下,“最先进”可以确定了 😁)。相应地,由于功能多,配置也很复杂,但是按照维护者的说法,大多数保持默认即可。
🏃♂️ 准备
首先,您需要有一部线路还不错的服务器,有钱就去 BandwagonHost 上 CN2 GIA,没钱就到 RackNerd 买部也还凑合的洛杉矶 MC 机房的 VPS,实在不行服务端上 WARP 去解锁吧。
服务器的基本配置,您可以看词元的往期博客,重点要设置一下 SSH 密钥登录,防止服务器密码暴力破解。
然后,千万别忘了,要断开(如果有的话)您正在使用的那部服务器提供的代理,并另找一个不错的代理,不然 SSH 断联或者 YouTube 视频放不了就老实了。
然后,无论您之前拿什么玩意儿搭的代理,一律移除,为 XHTTP 驾到做好准备 😁 如果您之前采用词元推荐的脚本安装了 caddy
,也建议您使用 dnf
重新安装一次,以保证它能随系统更新。
🔧 安装 3X-UI 面板
3X-UI 面板此前拒绝按照 Xray 的推荐,强制要求用户开启 HTTPS 或使用 SSH 端口转发,因此被维护者从 Xray 推荐面板的名单中移除。但是毕竟 3X-UI 是开源的,只要我们自己开启了这些功能,大概是没啥问题的,而且它作为 X-UI 的后继者,目前还在积极开发,功能和安全性上更完善。
按照 3X-UI 仓库文档的说明,直接在 root 权限下使用一键脚本安装。
⚠️ 对于比较信任的脚本,可以直接执行一键脚本;但是还是建议您先看看脚本的内容,如果有什么奇怪的东西,就别着急拿着
sudo
去跑了。
|
|
稍候一会儿,等待命令自动执行完成,然后我们用 Caddy 进行反向代理,顺便获取一个 SSL 证书,这样连接更加安全。X-UI 面板因为 HTTP 明文连接的原因,很容易被 FOFA 这类的网络空间测绘的搜索引擎查到,因此非常不建议您直接使用 HTTP 连接,也很推荐您安装 fail2ban 这种封禁工具。
|
|
然后添加反向代理:
|
|
注意,重启 Caddy 之前要在域名托管商那边设置这个域名(咱就称为“面板域名”好了)的解析,Cloudflare 用户暂时不要开启小黄云(申请证书的时候需要直接访问)。这样,我们就将面板的端口转发到了 443 端口上,实现了 HTTPS 访问。
可以用 sudo systemctl status caddy
看看证书申请得怎么样了,如果出现 error
字样,像这样:
说明配置有问题,需要修改。尤其注意防火墙需要开放 80 和 443 端口,或者如果您使用 firewalld,那就启用 http
和 https
两个服务。
如果像这样:
则说明申请成功,可以打开小黄云,然后从您的浏览器用 3X-UI 给出的路径访问了!Caddy 的配置惊人地简单,下文不再赘述添加域名的方法了。
输入您看到的用户名和密码,登录进管理界面。由于我们没有采用面板内置的申请 SSL,在查看密码的时候可能会提示没有启用 SSL:
忽略即可,在网页端这个警告已经消失了。首先,我们来修改一下随机生成的用户名和密码。
按您自己的习惯和需要设置即可,也可以在这一页的下面开启 Token 登录,这样更安全。
🧙♂️ VLESS、XHTTP、Reality 入站规则
然后,在“入站列表”中按以下配置建立一个入站规则:
- 启用:那当然,备注:随意。
- 协议:
vless
。 - 监听:留空,监听所有地址。
- 端口:
443
、2053
或者8443
这类广泛受 CDN 支持的 HTTPS 端口。 - 总流量:0(无限,自己限制自己干嘛),到期时间:不填。
- 客户:保持默认。
- 传输:
XHTTP
。 - 主机:留空。
- 路径:随便生成一个 UUID,可以用在线工具。
- 下面直到“安全”都保持默认。
- 安全:Reality。
- Dest 和 SNI 保持默认的
yahoo.com
即可,目前看来不会触发连接重置,尚且可用。 - 其他保持默认。
- 点击“Get New Cert”生成一个密钥。
然后便可添加节点,这样我们的节点就添加完成了。选择菜单可以导出节点链接,这时候可以先导入客户端试试能不能用,不着急连接。
Linux 用户注意:常用的 v2rayA 使用 v2ray 内核,不支持 XHTTP 节点,需要使用 v2rayN,现在后者也有 Linux 版本了。
可以注意到,这个节点的地址就是我们的“面板域名”,端口就是我们设置的、可用于 CDN 的端口,开启了 HTTPS(Caddy 自动申请的),且拥有完全的加密协议。现在,您可以打开它的小黄云了。
这个节点就搭建完毕,接下来设置上行、下行的规则。
⬆️ 上下行分流
在 Cloudflare 面板里,添加两条解析记录,分别称为“上行域名”和“下行域名”,暂时不要开启小黄云。然后前往域名设置中,打开 gRPC 支持:
回到 3X-UI 面板,创建一个新的进站规则:
- 启用、备注就不说了。
- 端口:随便选择一个,大于 1024 就好。
- 传输:
XHTTP
。 - 路径:还是随机生成一个 UUID。
- 安全:无。
- 其他保持默认。
如果您之前拿 X-UI 搭建过 WebSocket 节点,就会发现这玩意儿除了协议是 XHTTP,其他简直和 WebSocket 一模一样。只不过,WebSocket 是使用专门的隧道和帧数据来传输,只有一小部分 CDN 支持(但是包括 Cloudflare),而 XHTTP 就是标准的 HTTP 流量。
然后,我们在 Cloudflare 那边再添加两条解析记录(“上行域名”和“下行域名”),将其解析到服务器,然后在 Caddy 那边,配置如下:
“上行域名”:端口 {
reverse_proxy http://127.0.0.1:你刚刚设置的端口
}
“下行域名”:端口 {
reverse_proxy http://127.0.0.1:还是那个端口
}
这两个端口号可以随意设置,甚至可以不一样,只要保证实际指向的本地端口相同即可。
发现没有?实际上,这两个解析实际上是一模一样的。至于为什么我们不直接使用面板的那个端口,那是因为 Caddy 的自动 HTTPS 证书申请很方便,将这个端口给 Cloudflare,域名就能开启 Full(Strict) 模式,全流程加密。
下面的一步,词元是跟着教程做的,其中的原理词元说实话——也不是很懂,但是没有这个操作是用不了的。大家先跟着做,词元要是悟出原因了再回来告诉大家吧……
到 Cloudflare 面板,来到 Rules 里的 Overview。
点右侧的“Create Rules”,从“Products”里选择“Origin Rules”,添加一条。
随便起个名字,然后关键是添加规则,如图:
一路拉到最下面,填入刚刚你为“上行域名”选择的那个端口号:
然后保存,再为你的“下行域名”也设置一样的规则。
规则很简单,就是把所有 80 端口的请求全部转发到服务器的实际端口(然后再被 Caddy 反代到本地端口),但是为什么这么做?词元暂时不清楚。
💡 后来词元想到的最合理的猜想就是:为了模仿 HTTP 流量,端口必须为常用的网页端口,而且只有访问 80 这样的通用端口的时候才能使用 Cloudflare 的 CDN。
🖥 客户端设置
最后,我们回到客户端。删除刚刚那个“面板域名”的那个节点,我们以后不会直接使用它;然后导入你刚刚创建的第二个节点链接,右键修改配置。
按照图中的说明,有数字的部分无须修改,标文字的部分需要按照您的实际情况修改。这里以 v2rayN 为例,是因为目前似乎只有它提供了比较完整的 XHTTP 支持,Clash 系和使用 v2ray 内核的目前都没有支持。
然后,最重要的一步,我们刚刚设置了一个下行域名,现在我们需要添加相应的配置。
在蹦出来的文本框内,输入以下配置:
|
|
这段配置的本质就是添加一个节点,作为我们正在修改的节点的下行。
好了!然后,测试一下真延迟和速度,如果正常的话,恭喜您,您赶上时代了!
🎆 下课
对抗审核的本质就是使封禁成本尽可能大。从某种意义上来说,我们使用 CDN 作为前置,实际上是对于 CDN 的滥用——CDN 不是用来传送静态资源的吗?但我们用它来作为中间部分,避免过墙地访问自己的服务器。
试想,现在的 GFW 是黑名单模式,也就一律放行,除了已知的需要屏蔽的域名。但是,如果未来的某一天,突然切换至白名单模式(就像伊朗试行过的那样),到时候如果有 Cloudflare 或者谁家的 CDN 在白名单内,又该不该使用呢?
词元为了使用 CDN,是每个月给 Cloudflare 付了使用费(Pro),但是免费的 CDN 也很好,很够用了。希望 Cloudflare 能多给一点机会,希望它晚些进入中国市场,因为这意味着它将不得不遵守政府的要求,很可能会屏蔽、封号代理的 IP。
😮💨 几天之后的幺蛾子:XHTTP 虽好,但是这个 gRPC 断流是什么鬼?连接 10 分钟,断流 5 分钟,尤其是对于词元这种垃圾线路,只要切断连接,原地立刻爆炸。还是“三驾马车”香啊……