使用 Docker 快速搭建 Telegram 專用代理 MTProxy-Go

來源:https://www.jkg.tw/p3526/

之前有一篇使用一鍵快速腳本搭建 Telegram 專用代理 MTProxy-Go,不過好像原作者被抓去喝茶還是什麼鬼的 🥸

反正那個腳本已經年久失修,不太能正常使用了,有些上游路徑已經改過,於是另外找了 Docker 版本

Docker 版本跟之前腳本相比起來搭建出錯機率小很多,因為別人都包好了,日後更新起來也很容易

另外可能還會有人問 Telegram 不就直接可以正常使用嗎?為什麼還要翻牆代理?

在台灣確實可以正常使用,但是台灣連去 Telegram 新加坡機房的速度時好時壞,有時候圖片或者影片會跑好久

為了要有更好的使用體驗,如果能自己搭一個海外 VPS 會改善非常多,像是 GCP 的台灣或者 AWS 的日本都能有不錯的連線穩定度


安裝 Docker Community 穩定版

雖然這安裝 Docker 的部分已經講過很多次,不過還是再寫一遍

如果你已經有 Docker 執行環境就可以跳過



一樣先 SSH 連到伺服器上,安裝 Docker 跟需要的軟體,以下適用於 Debian 與 Ubuntu
# 先完整更新一下系統 $ sudo apt update && sudo apt full-upgrade -y # 安裝一下等下會需要用到的軟體 $ sudo apt install curl -y




更新好以後,使用 Docker 官方的一鍵安裝腳本
$ curl -fsSL https://get.docker.com/ | sh


接著稍等片刻,他會自動安裝到最新穩定版的 Docker

安裝完畢後,設定一下權限
# 將你帳號加入 docker 群組 $ sudo usermod -aG docker $USER # 退出重連一次 $ exit




以上就完成執行 Docker 基本環境安裝


MTProxy-Go 無廢話直接跑起來 Docker 版

MTProxy-Go 相關的在 Docker Hub 上面有很多,後來看到以下這個版本沒太多廢話

直接兩條指令就可以跑起來,舒舒服服,所以就直接用它啦!

https://hub.docker.com/r/p3terx/mtg


$ docker run --rm p3terx/mtg generate-secret tls -c shopee.tw


上面這條指令可以幫你快速產生註冊一組 Secret Key 並開啟 TLS 混淆,讓你假裝好像在連 shopee.tw

當然你也可以改成其他網站,像是如果你要在中國使用,就不要填 facebook.com or google.com 之類的

輸出的 Key 請拷貝起來,下面馬上就會用到


$ docker run -d \ --name mtg \ --restart unless-stopped \ --dns 1.1.1.2 \ -p <PORT>:3128 \ p3terx/mtg \ run <SECRET>


上面這行指令要自己改的只有 PORT 與 SECRET 兩個參數需要改掉

PORT 就填自己要開的伺服器連接埠,SECRET 就是從上面指令產生的 Secret Key 拷貝過來即可

實際指令大概會長下面這樣:
$ docker run -d \ --name mtg \ --restart unless-stopped \ --dns 1.1.1.2 \ -p 9958:3128 \ p3terx/mtg \ run ee78442ab5f0965ae521b60b691e46b932351f75796562652e146f2d


以上一行指令一按下去就會直接跑一個 MTProxy-Go 的代理伺服器起來了,非常的方便!



接著記得開個防火牆連接埠
# Port 請改成你自己實際使用的 $ sudo iptables -I INPUT -p tcp --dport 9958 -j ACCEPT # 裝個 iptables-persistent 保存規則 $ sudo apt install iptables-persistent -y



給 Telegram 連線的連結

而要丟給 Telegram 連線的連結可以套用以下規則https://t.me/proxy?server=<YOUR_IP>&port=<PORT>&secret=<SECRET>


YOUR_IP 請改為你的伺服器外網公共 IP

PORT 跟 SECRET 就如上個步驟你設定的那樣填,你實際多少就填多少

實際完成後大概會是長下面這樣:
https://t.me/proxy?server=101.101.101.101&port=9958&secret=ee78442ab5f0965ae521b60b691e46b932351f75796562652e146f2d




完成後的連結直接丟到 Telegram 裡面,按一下即可新增連線

日後要更新也很簡單,建議可以另外新建一個 WatchTower 全自動無人值守升級



以上搭一個私人 Telegram 專用代理 MTProxy-Go 就是這麼簡單 🖖

如何测试VPN安全与否


原文链接:

https://zh.vpnmentor.com/blog/%e5%a6%82%e4%bd%95%e6%b8%ac%e8%a9%a6vpn%e7%9a%84%e5%ae%89%e5%85%a8%e6%80%a7/

一般人使用VPN服务的主要目便是对数据安全的考量。但是您如何确定您的VPN能确实保护您?,即使您正连接到至VPN,在安装VPN时,有几个步骤可能会出错并因此泄漏您的数据和暴露您的IP地址。

在本文中,我们将帮助您搞懂数种可用于测试VPN连接以防止各种泄漏的工具。本文所提到的所有测试工具都能让您知道您的VPN是否真的在保护您。

DNS泄露测试


DNS说穿了就是网域名称系统(Domain Name System)。借由将网域名称转换为相应的IP地址,它能使访问网站更为容易。举例来说,vpnmentor.com被分配的IP地址是104.25.7.109。

在一般情况下,将网域名称转换为相应IP地址的工作乃由互联网服务供应商(ISP)提供。然而,在您使用VPN时,您的真实IP地址将被隐藏,从而阻止其他人追踪您的位置。

有时,VPN通道会泄露转换的请求,您的互联网服务供应商的IP地址和所在位置也会因此暴光。而您若想要进行DNS泄漏测试,只需连接至位于您所在国家以外的VPN服务器。接下来,您可以使用像dnsleaktest.com这类的工具。如果其中的IP地址、位置和其他详细资讯与ISP的IP地址、位置等细节吻合,就表示您的DNS被泄漏了。

请注意,DNS泄漏不会导致您的IP地址曝光。其泄漏的是您的互联网服务供应商的IP地址和位置,而这些资讯可以轻易被用来追踪您的IP地址。

要防止DNS泄漏,请使用本身拥有加密DNS系统的VPN。

IP地址泄漏测试


多数VPN都声称能保护您的IP地址,但事实却非如此。根据一项针对Android VPN应用程序的研究发现,有84%的VPN泄露其用户的真实IP地址。

要测试您的VPN服务是否泄露您的IP地址,只需使用我们的IP泄露测试工具

必须注意的是,VPN连接处于活动状态以及处于重新连接阶段时,是最有必要进行IP地址泄漏测试的时刻。 多数VPN会在连接断开后的重新连接时间内泄漏您的IP地址。

为防VPN失去连接,VPN通常有一个完全阻止所有互联网流量的杀死键

以下为在重新连接阶段进行VPN的IP地址泄漏测试的步骤:

  1. 断开互联网,并同时保持VPN的连接及运转
  2. 一旦失去连接,便重新连接并执行连续性的IP测试。此步骤可以通过打开IP测试网页的多个标签页来完成,之后再尽快更新每个标签页。
  3. 一旦VPN重新连接后,便请停止刷新并检查测试结果。
  4. 如果您的真实IP地址出现在几个标签页中,便表示您有重新连接泄漏的情形。

欲防止IP地址泄漏,您必须确保使用一个安全的VPN。如果您有IPv6泄漏的情形,您可以手动卸除您的装置上的IPv6连接。此外请注意,如果您的VPN支持IPv6,您也会自动获得针对IPv4的防护。

WebRTC泄漏测试


WebRTC是个主要可在像Firefox、Chrome和Opera等网络浏览器中看到的API定义,其可允许P2P文件共享以及Web浏览器中的语音和视频聊天,并无需任何外部附加元件或扩充程序。市面上有各种可用于Internet Explorer和其他浏览器以支持WebRTC的附加元件。

当您的IP地址经由WebRTC API泄露时,便会发生WebRTC泄漏。您可以借由访问网站Perfect Privacy WebRTC Test来测试您的VPN WebRTC泄漏。

您可以在您正在使用的浏览器中停止使用WebRTC以防止其泄漏。

VPN速度测试

除了隐私和安全性外,速度也是VPN服务中最重要的面向之一。影响VPN速度的因素很多。以下是其中的几个因素。

  1. 受到您的互联网服务供应商的限制


无论您的VPN有多快速,其速度永远不会超过您的互联网服务供应商所提供的速度。您的互联网服务供应商控制您的互联网的整体速度。

  1. 加密的層級


隨著加密級別的增加,VPN的速度會相對下降。 L2PT協議比PPTP協議更安全,但速度明顯更低。如果您在互联网上執行的多數工作項目不需要高級別的加密,則我們更建議您使用較低級別的加密。

  1. 用户与VPN服务器之间的物理距离


这是影响VPN速度最常见的因素。如果您在印度使用位于美国的VPN服务器,则您便需要忍受较慢的网络速度。选择位于您所在地附近的VPN服务器将能解决这个问题。

  1. VPN服务器上的使用人数


许多受欢迎的VPN服务供应商的服务器超载,因而导致速度缓慢。在购买VPN之前,请确保其提供一个服务器状态的页面以显示即时的频宽资讯。

  1. 防火墙设定


您的防火墙设置不能影响VPN流量或CPU性能,因为其可能因此大为减低速度。

  1. 装置的处理能力


每当您的计算机或移动装置上的VPN处于启用状态时,您的装置便会不断在后台运作以加密和解密一封又一封的资讯。 此过程耗用相当大的处理能力。 而更快的互联网速度,也需要更强大的处理能力。

因此,即使您的VPN速度很快,而且您也有高标准的互联网连接,您的CPU仍可能会抑制速度的表现。

若想测试您的VPN速度,可参考Speedof.me的网站。



翻墙需要避免的几种行为



原文链接:https://matters.news/@codisk518/%E7%BF%BB%E5%A2%99%E9%9C%80%E8%A6%81%E9%81%BF%E5%85%8D%E7%9A%84%E5%87%A0%E7%A7%8D%E8%A1%8C%E4%B8%BA-bafyreiguf43kzcm3px2e2vsbyfc73j76xcwwhxraob2loijarjrtetpcha

首先需要大致的科普一下,为什么中國的互联网用户无法正常接入国际互联网。这是因为中國大陸组建了名为“长城”的网络防火墙系统,该系统是由微软、思科及中国国内多个顶尖科研机构共同开发。该系统截止目前还是使用“黑名单”机制,庆幸没有使用“白名单”机制。两套机制的区别在于:黑名单机制是指将特定的网站或IP设置为不可访问,例如现在全球有100个网站,长城系统将其中的10个设置为不可访问,那么剩余的90个是可以访问的,此时如果有人新建了1个网站,只要没有被纳入长城防火墙系统的监管之内,那么这第91个网站就可以被访问。白名单机制则是刚好相反,例如全球有100个网站,长城系统将其中10个纳入为可访问的,那么剩余的90个则是不可访问的,同时如果有人新建了一个网站,但是这个网站是还没有被纳入长城系统的,那么这个网站也是无法访问的,这就是两种机制的最大的区别。


  另外如果你将一个网站或App的服务器放在中国境内例如阿里云、腾讯云等,那么在网站开通上线之前就必须到“中国工业和信息化部政务服务平台”进行备案,就是将你这个网站地址提交到ZF进行审核,审核通过了,这个网站/App才可以上线,不然就无法上线。这就是中国目前国内外网站、App等网络服务大致的现状。就我个人观察虽然同为访问限制,但是中國大陸比朝鲜要好一点,因为朝鲜是使用白名单机制,中国则是采用严控的黑名单机制。至于他们为什么要限制,就不在本文讨论范围之内了。

翻墙需要避免的三种行为

  凡事有可为,有可不为!出于人身安全考虑,作为一名翻墙者请尽量避免以下三种行为。因为这涉及到中國大陸的法律、自身安全等因素。

一不要:不要自己租用服务器搭建VPN或SSL,顶级的网络安全专家忽略此条;(政治法律因素,你不想被抓或被罚吧,那条中國大陸法律叫:擅自建立、使用非法定信道进行国际联网)。

二不要:不要使用中國大陸开发的VPN或翻墙软件;

(安全因素,你不希望将自己电脑或手机上的账号密码泄露给那些翻墙软件服务商吧,阿里巴巴、百度、腾讯等超级服务商都在窃取用户隐私,更别说游走在中国法律灰色地带的不正规的翻墙软件服务商了)。还要注意中国钓鱼执法式的VPN服务提供商。同时也要警惕Apple Store商城和Google Play商城中的免费VPN,有很多是钓鱼类的。—请永远记住,天下没有免费的午餐!

三不要:翻墙后不要将国内不允许的内容转发至国内,特别是转发至微信、微博、抖音、快手、QQ等社交平台;

(政治法律因素,这个一定要当心,自己看看就行,不要传播,不然后果严重)

  也许你会疑惑,国外人他们既然没有互联网内容的限制,为什么他们也在用VPN,这不是多此一举吗?这里我需要解释一下,如我之前所说的。VPN的初始用途是用于隐私安全领域,而中国的用户只不过是通过这个工具进行绕开长城防火墙的限制,也就是中国VPN用户说的“翻墙”。下图能简单的说明VPN的工作原理,希望能够帮助你理解。

从这张简易原理图中,我们可以大致了解,VPN其实就是一个服务器,你的电脑、手机或其它设备先登录到VPN的服务器,再通过服务器访问国际互联网,反向传输数据也是同一个道理。看到这张图,你会不会产生一个疑问?那就是这个VPN服务器是否安全,因为使用了VPN之后,你所有的传输数据都将经过这台VPN服务器,包括你的账号、密码、银行账号、手机指纹、面部识别码等。如果这个VPN服务器不安全,那么你的账号密码又怎么会安全呢。事实确实如此!当你使用了不安全的VPN服务器,那么相当于将所有的电脑、手机、账号密码等全部都公布了出去,这是一件多么可怕的事情,想想就吓人啊。这就是我不建议使用任何一款免费翻墙软件的理由。



Xray教程

原文链接:https://tlanyan.me/xray-tutorial/

本以为 V2ray的VLESS协议介绍和使用教程 是V2ray系列教程 的最后一篇,万万没想到Xray横空出世,并且项目发展高歌猛进,风光无限。鉴于此,有必要为学不动的网友科普一下Xray项目。

本Xray教程重点介绍Xray项目由来、和V2ray的关系,至于服务端部署和客户端使用,目前基本与V2ray一致,因此仅做简要介绍。

Xray介绍

一个Debian包维护者发现XTLS库的LICENSE不是BSD许可,提了一个issue希望作者 @rprx 能修改方便打包,详见 https://github.com/XTLS/Go/issues/9。由这个issue引发了广泛讨论,rprx认为目前许可不是问题,也有不少人认为协议是立场的体现,各执一词。

最终V2ray(V2fly社区)维护者经过投票确认XTLS不符合V2ray的MIT协议,并在V2ray-core 4.33.0版本移除了XTLS。rprx和其拥护者行动起来,很快就创建了Project X项目Xray子项目(Xray取名来自XTLS和V2ray的结合),并发布了Xray-core的多个版本。这便是Xray的大致由来。

XTLS和Xray离不开作者 @rprx 的辛勤付出,因此也简要介绍一下@rprx :

1. @rprx 是VLESS协议的设计者,在介绍VLESS协议时写下了 性能至上、可扩展性空前,目标是全场景终极协议 的宏壮愿景;

2. @rprx 是 XTLS 的作者,在 XTLS库 中写下了 “THE FUTURE” 的霸气描述。将内外两条TLS连接结合,rprx可能不是第一个有这想法的人,但却是第一个将其实现、并成熟应用到实际中的作者。从使用表现上看,XTLS无愧于rprx对其的评价:划时代的革命性概念与技术:XTLS,以及社区给出的“黑科技”称谓;

3. @rprx 是Project X和Xray项目的创始人。由于LICENSE理念之争,rprx创建了对标Project V和V2ray-core的Project X和Xray-core项目,广受欢迎。

Xray-Core自上个月创立以来,短短一个月已经发布了七个版本,足见维护者的诚意。Xray-Core目前发布的各个版本主要介绍如下:

1. Xray-core 1.0.0版本:项目创建,提供完整的VLESS和XTLS支持,功能上是V2ray-core的超集。主要变动是将v2ray和v2ctl可执行文件合并为xray,性能全面增强;

2. Xray-core 1.1.0和1.1.1版本:测试过渡版本,未提供详细发行说明;

3. Xray-core 1.1.2版本:引入了Linux Kernel Splice技术,适用于安卓、路由器等Linux环境。Splice技术减少了数据拷贝次数和内存占用,拥有更强的性能。需要说明的是,只适用于类Linux环境的客户端出栈,服务端入栈仍然是direct;

4. Xray-core 1.1.3版本:重构了透明代理的 REDIRECT 模式,使之同时支持 IPv4 和 IPv6,解决了V2ray和trojan遗留的问题;

5. Xray-core 1.1.4版本:优化内存占用,TLS更多选项配置,使服务端伪装站的TLS设置在SSL Labs能达到A+评分;

6. Xray-core 1.1.5版本:测试过渡版本,支持YAML配置文件、OCSP Stapling等功能,官方安装脚本大更新;

7. Xray-core 1.2.0版本:SS、trojan协议完美支持Fullcone,向游戏使用迈出了重要一步。

更多Xray-core新特性请参考官方说明:https://xtls.github.io/about/new/,或者官方库发行说明:https://github.com/XTLS/Xray-core/releases


Xray和V2ray的区别

返回目录

在说明Xray和V2ray区别之前,先说一下三个相近但不同的概念:

  • V2ray:Project V 是用于构建基础通信网络的工具合集,其核心工具称为V2Ray。V2ray主要负责网络协议和功能的实现,既可以单独运行,也可以和其它工具配合。V2ray官网是:https://v2ray.com/,Github项目主页是:https://github.com/v2ray,TG讨论组是:@projectv2ray
  • V2fly:出现一些科学上网作者被喝茶事件后,V2ray原开发者长期不上线,其他维护者没有完整权限,导致V2ray项目维护困难。因此社区在2019年组建了V2fly组织,继续维护V2ray,也是目前V2ray发展的主力。V2fly官网是:https://www.v2fly.org,Github项目主页是:https://github.com/v2fly,TG通知频道:@v2fly,TG交流群为:@v2fly_chat
  • Xray:因许可理念之争,VLESS和XTLS的作者单独创建了Xray项目,目前是V2ray的超集,后续可能有不同的发展路线。Xray文档官网(测试中):https://xtls.github.io/, Github项目主页:https://github.com/XTLS,TG交流群:@projectXray

从上面可以看到,先有V2ray(Project V),然后是V2fly,最后才出来Xray(Project X)。其中V2fly是V2ray的社区,可以认为两者是同一个组织。

详细一点说,Xray和V2ray区别如下:

  1. Xray是V2ray的一个分支(Fork)。Xray项目基于V2ray而来,其支持并且兼容V2ray的配置;
  2. Xray是V2ray的超集。虽然最新版V2ray删除了XTLS,但仍保留VLESS协议。Xray提供完整的VLESS和XTLS支持,目前是V2ray的超集,但后续Xray可能会有会有自己的发展方向;
  3. 如果使用XTLS,强烈推荐使用Xray,或者安装V2ray-Core 4.29.0 ~ 4.32.1版本;不使用XTLS的情况下,使用V2ray和Xray均可。

一个小提示是,Xray项目创建以来,V2ray没再发布新版本,反而Xray热火朝天,不断出新版和新功能。此外Xray的TG群也非常热闹,每天至少七八K的消息。如果你喜欢尝试新东西和折腾,Xray适合你,否则V2ray也挺好用。

如今Xray和V2ray分家,后续有没有可能Xray再合并回V2ray呢?这个问题没有答案,也许会合并回去结束分裂,也可能就此分道扬镳。io.js从Node.js分出后来又合并回去,C++源自C但完全是一门新语言独立发展,因此一切皆有可能。

Xray安装和使用教程

和其他自行部署的技术相同,使用Xray分为安装服务端和配置客户端两部分,接下来分别做介绍。


安装Xray

1. 准备一台境外的VPS,购买可参考 一些VPS商家整理;

2. SSH连接到境外服务器,windows请参考:Bitvise连接Linux服务器教程,mac系统请参考:Mac电脑连接Linux教程

3. 自行部署Xray服务端需要你有基本linux技巧,能使用vim/nano等编辑器。官方提供了大多数Linux系统的一键脚本,可以直接使用:

bash <(curl -L https://github.com/XTLS/Xray-install/raw/main/install-release.sh) install
新手推荐使用 Xray一键脚本

官方脚本安装的文件符合FHS规范,可执行文件xray在 /usr/local/bin 目录下,配置文件位于 /usr/local/etc/xray目录内。

4. 官方脚本安装的配置文件内容为空,可参考 Xray-examples 中提供的模板编辑配置文件。例如使用VLESS+TCP+XTLS的配置文件为:

{
    "log": {
        "loglevel": "info"
    },
    "inbounds": [
        {
            "port": 443, # 可以换成其他端口
            "protocol": "vless",
            "settings": {
                "clients": [
                    {
                        "id": "", // 填写UUID,可以使用xray uuid生成
                        "flow": "xtls-rprx-direct",
                        "level": 0
                    }
                ],
                "decryption": "none",
                "fallbacks": [
                    {
                        "dest": 80 // 回落配置,可以直接转到其他网站,例如"www.baidu.com:80"
                    }
                ]
            },
            "streamSettings": {
                "network": "tcp",
                "security": "xtls",
                "xtlsSettings": {
                    "alpn": [
                        "http/1.1"
                    ],
                    "certificates": [
                        {
                            "certificateFile": "/path/to/fullchain.crt", // 换成你的证书,绝对路径
                            "keyFile": "/path/to/private.key" // 换成你的私钥,绝对路径
                        }
                    ]
                }
            }
        }
    ],
    "outbounds": [
        {
            "protocol": "freedom"
        }
    ]
}

XTLS需要证书,因此需要一个域名并申请证书。域名不需要备案,国内和国外买的都可以。域名购买可参考:Namesilo域名注册和使用教程 或从 适合国人的域名注册商推荐 选购。域名申请证书可参考从Let’s Encrypt获取免费证书 或 从阿里云获取免费SSL证书


fallback选项以及ALPN等设置请参考:VLESS协议的fallback参数介绍

5. 配置完毕后,可通过 systemctl start xray 运行 xray,systemctl stop xray 停止xray,systemctl restart xray 重启,journalctl -xe --no-pager -u xray 查看运行日志。

最后,记得放行防火墙。如果是阿里云、腾讯云、AWS/GCP等大厂的服务器,还需要到网页后台的安全组放行端口。


配置Xray客户端

服务端配置好后,接下来是配置客户端。目前有如下客户端支持Xray:

Xray Windows客户端

  • V2rayN:3.28版本起支持xray,只需要下载Xray-core,将解压的文件放到V2rayN-Core文件夹下即可。需要注意的是V2rayN 4.0版本移除了PAC,改用路由规则,会给习惯了PAC的用户带来困扰。习惯Qv2ray的网友应该乐于接受这个改变;
  • winXray:winXray是Windows系统上简洁稳定的Xray/V2RayShadowsocksTrojan 通用客户端,可自动检测并连接访问速度最快的 代理服务器。该项目原作者删库后出现了一些同名库,安全性未知,因此本站托管的依然是旧版;
  • Qv2ray:Qv2ray是一个基于Qt框架开发的v2ray客户端,可通过插件支持SS、SSR、VMESS、VLESS、trojan等多种协议。

Xray安卓客户端

  • V2rayNG:V2rayNG可以说是最跟随Xray步伐的V2ray客户端了,Xray发布新版本后会在第一时间更新,推荐使用。

Xray Mac客户端

  • Qv2ray:Qv2ray是一个基于Qt框架开发的跨平台v2ray客户端,因此支持MacOS系统。实际上,自V2rayU作者删库不更新后,Qv2ray算得上Mac系统上支持VLESS协议的独苗,但可能会出现设置系统代理无效的bug。

Xray苹果客户端:

  • Shadowrocket/小火箭:小火箭目前是ios系统上更新最频繁的V2ray客户端,价格也不贵,支持多种协议,推荐使用。

以上客户端均可以在 V2ray客户端 下载,请参考其中的配置教程配置,本文不再赘述。

总结

不管V2ray和Xray今后发展如何,本人都真心感谢为这两个项目付出时间和贡献的开发人员,他们为自由获取互联网信息作出了重要贡献。

本文到此结束,欢迎批评指正!



进阶必读:代理协议 UDP 全方位透彻解析

原文链接:https://v2xtls.org/%e8%bf%9b%e9%98%b6%e5%bf%85%e8%af%bb%ef%bc%9a%e4%bb%a3%e7%90%86%e5%8d%8f%e8%ae%ae-udp-%e5%85%a8%e6%96%b9%e4%bd%8d%e9%80%8f%e5%bd%bb%e8%a7%a3%e6%9e%90/

绝大多数人对代理协议中的 UDP 部分完全没概念,目前很多经验丰富的使用者甚至是开发者一遇到 UDP 就变成小白,导致大多数关于 UDP 的问题悬而不决。鉴于 UDP 正扮演着越来越重要的角色,却没有一篇文章讲代理协议中的 UDP,我干脆写了这篇文章。

这篇文章的目的就是扭转现状,让大家完全参透 UDP,以便更游刃有余地使用 Xray-core 或其它代理类软件。 —— RPRX

简单理解 IP Packet、TCP Connection、五元组、端口、User Datagram Protocol

这些是必须掌握的基本概念,实际上非常简单。

IP Packet:一个个符合 IP 协议的数据包,允许丢包,允许乱序(即接收时的顺序不同于发送时的顺序),属于非可靠传输。

它不是最底层的形式,这里无需深究,重点是知道它的特性。IP 数据包无法直接提供可靠传输,这对应用来说当然是很不方便的,于是就有了面向连接的 TCP 协议,它基于 IP 数据包,但实现了一套连接和可靠传输机制,大多数其它协议直接放 TCP 上面即可。

确定一个 TCP 连接的是“五元组”:

  1. TCP 协议本身的标识
  2. 自己的 IP 地址
  3. 自己使用的一个端口(Port)
  4. 对方的 IP 地址
  5. 对方使用的一个端口

TCP 连接建立后,双方便可从自己的端口向对方的端口发送应用数据,这是全双工的,即双方都可以一边发送数据、一边接收数据。

“端口”这个概念各位都不陌生,它常和 IP 一起出现,但实际上它不属于 IP 协议(没想到吧.jpg),它属于更上层的 TCP、UDP 协议。TCP、UDP 是分别实现了“端口”这一标识方式,所以这两个协议的“端口”不会互相影响。 ping 用到的协议是 ICMP,它也是基于 IP 数据包,与 TCP、UDP 是类似的,但 ICMP 就没有“端口”这个概念。顺便提一句,常见的代理协议只能代理 TCP 或加个 UDP,不能代理 ICMP,所以就无法 ping,有此需求请用传统的 VPN。

接下来终于轮到我们的主角登场了:UDP(User Datagram Protocol)

虽然 UDP 和 TCP 一样是基于 IP 数据包的,但它异常简单,直接完全继承了 IP 数据包的特性:

  1. 允许丢包
  2. 允许乱序
  3. Apparently,属于非可靠传输

你可以这样简单理解:UDP 协议就只是在 IP 协议的基础上加了一个端口机制和校验而已。

对于 UDP 而言,TCP 的“连接”机制也是不存在的,即你申请到一个本地 UDP 端口后,不需要握手/建立连接即可直接向任意 IP 的任意 UDP 端口发送应用数据。 不需要关心对方有没有收到数据,对方也不会告诉你有没有收到数据。(需要指出:存在一种 connected UDP 的中间状态,这只是在发送数据前确定一下目标地址,并没有真正去握手)

UDP 的这些特性催生了三种应用方式:

  1. 注重效率,比如 DNS 查询(不需要先握手)
  2. 注重实时,比如直播、语音等(允许丢包,不需要等重传)
  3. 两者皆有 + P2P,比如一些联机游戏、语音等。注意这就是充分利用了上面加粗的那种 UDP 特性,也是本文的重点。

当然还有另一种对 UDP 的应用方式:基于 UDP 造新的通用可靠传输协议,比如 KCP、QUIC。为什么这些新协议不直接基于 IP 协议而要基于 UDP 协议?因为前者往往需要各级运营商进行设备、系统改造来支持,这显然不太现实,所以 UDP 成了更合适的选择。

那么 FullCone、Symmetric 又是什么?

这两个指的都是 NAT 行为,NAT 的全称为 Network Address Translation,就是你家路由器、各级运营商做的事情:地址转换。NAT 的广泛存在是因为 IPv4 地址不足,另一方面它还可以保护局域网中的设备。

对于 TCP 而言,NAT 行为是什么并不重要,因为 TCP 是双向的流,本机每发起一个 TCP 连接往往会使用一个新的临时端口,从而对应一个新的五元组。

但对于 UDP,NAT 行为可太重要了,因为 UDP 是方向不定的包,使用同一个本地 UDP 端口向不同的目标二元组发包十分常见。

二元组:IP 和 Port,任一不同即视为不同的二元组

那么这种情况下 UDP 数据包到达路由器后,路由器要怎样转发它呢?这就取决于路由器的 NAT 行为了。

其实 NAT 行为多种多样,这里先举例介绍最具代表性的情况。首先有以下情景:

  1. 本地来源二元组 A 向远端目标二元组 M 发若干个包
  2. 本地来源二元组 A 又向远端目标二元组 N 发若干个包

如果由于目标二元组不同,路由器把 A->M、A->N 分别映射成了自己的 A1->M、A2->N(一般为分别使用两个不同的端口发包),且严格限制回包来源,就属于 Symmetric。不难发现,这时候实际上变成了类似 TCP “连接”的通信模式,也是大多数运营商的做法。

而若路由器只看来源二元组 A,始终映射成自己的 A1 向 M、N 发包,就属于 Cone NAT;更进一步,如果 A1 收到了回包,路由器不管来源,直接把这个包发回给 A,就属于 FullCone,也是代理类软件能实现的最佳 NAT 等级、P2P 游戏必备神器(GTA NAT 开放)

上面是简单举例,现实中运营商大概率不会主动分配给你一个公网 IP,也就是说还需要经过层层 NAT,最终得到 Symmetric 很正常。所以为什么你用了代理协议,比如 Xray-core 的 Shadowsocks、Trojan 就可以获得 FullCone?

很简单,因为此时用到的是你的 VPS 的公网 IP,和你本地的 NAT 环境没有任何关系。

这就是为什么要特殊设置 VPS 的防火墙:它默认会过滤返回的包的来源,导致你只能得到某种 Restricted Cone 而不是 FullCone。

对于简单的 UDP 需求比如 DNS 查询,Symmetric 也不是不能用。但对于复杂的 UDP 需求,比如各类 P2P 场景,实现 FullCone 就非常重要了,因为应用程序需要对外使用一个固定的端口,通过这个端口不受限制地往任何目标发包、从任何目标收包(至少别测错了当前的 NAT 类型,后文会说明)。如果你主要是为了打游戏,可以让 UDP 走 SS 协议,因为它拥有原生 UDP 的特性。

这里提一下,Xray-core 正计划着推出更适合打游戏的协议。

Xray-core 和一些代理协议中的 UDP 细节讲解

前面都是铺垫,终于到主菜了。

Xray-core 同时支持 FullCone 和 Symmetric 两种模式,且对协议的支持也非常全面,是很理想的例子。

完美支持 FullCone 的有:

  • Shadowsocks 入站、出站
  • Trojan 入站、出站
  • Socks 入站、出站
  • Dokodemo-door TPROXY 入站(透明代理)
  • Freedom 出站,支持域名解析

仅支持 Symmetric 的有:

  • VMess,因为协议结构不支持,后面会说原因
  • 当前的 Mux,同样是协议结构不支持
  • VLESS(FullCone 在路上了)

众所周知 v2ray 对 UDP 的支持一言难尽,所以 Xray-core 是重构了相关架构和各个出入站的代码,外加反复测试和对很多细节问题的定位、修复,才实现了全面 FullCone 化(除非协议不支持,这种情况会为它准备没问题的 Symmetric,Clash 的 VMess 存在问题)

Xray-core 的 release note 都很有营养,再摘抄一段:

  1. Socks5、Shadowsocks 都是原生 UDP,它们的 UDP 不走底层传输方式
  2. VLESS、Trojan、VMess、Mux 都是 UDP over TCP,且走底层传输方式
  3. HTTP 出入站不支持代理 UDP,Socks 版本 5 之前也不支持 UDP
  4. 这里的 FullCone 指的是 UDP 的 NAT 行为,配置时尤其注意防火墙
  5. 链式代理若要实现 FullCone,一般来说所有环节都要支持 FullCone
  6. Docker 若要实现 FullCone,相关容器的网络模式需要是 Host

补充:Socks、SS 是原生 UDP,套 TLS/WSS 后它们的 UDP 并没有被特殊处理,除非开了 Mux。SS 的 SIP003 插件也不管 UDP。

UDP over TCP 简称 UoT,特别注意,即使你用 mKCP、QUIC 作为底层传输方式,UoT 的也并不会表现出原生 UDP 的那些特性。

v2ray-core 存在的问题

这里主要是解惑,让 UDP 不再玄学。

  1. v2ray-core 架构上只支持 Symmetric 路由,所以你用 v2ray-core 的任何协议都只能 Symmetric
  2. v2ray-core 各出入站对 UDP 的处理和 TCP 是类似的逻辑,不可能实现 UDP 特有的 FullCone
  3. v2ray-core 的 Freedom 出站收返回的包时却没有按 Symmetric 过滤来源,这是玄学的根本原因
  4. v2ray-core 中各处维持 UDP 映射关系的不活动超时时间都很短,所以很容易出现断流等情况

对于第 3 点,简单来说是这样:

  1. 正常的 Symmetric NAT,A 对 M 发过包,只能收到从 M 返回的包,其它的会被过滤掉
  2. 如果中间插一个 v2ray,即使 A 没对 N 发过包,A 也能收到 N 发过来的包
  3. 重点是此时 N 的地址被丢掉了,A 会以为这个包是 M 发给它的,绝无仅有的迷惑行为

这种行为是预期之外的,再加上一些不标准的测试服务器,就会导致能给 v2ray、VMess 测出 FullCone,实际上却完全不起作用。

去年七月底我在某个开发者群内说过这个问题(不标准的测试服务器比如 Google 的那些,以及 v2ray UDP 的迷惑行为),随后 NatTypeTester 的更新只保留了五个标准的测试服务器,并特意验证了返回的包的源地址,测 v2ray 会显示 UnsupportedServer。

此外,Google 的一些应用会先自己测一下当前网络的 NAT 类型,若测出了假的 FullCone,就会导致奇奇怪怪的问题。

NAT 行为进一步探究

相信你已经发现了,NAT 行为并不只有 FullCone、Symmetric 这两种(但这是最极端的两种),实际上 NAT 行为由“发包时映射”和“收包时过滤”这两个行为来共同确定,FullCone 就是两者都最开放,Symmetric 就是两者都最严格,引用一张图:

Fig5 STUN


可以看到,RFC 3489 定义了四种经典的 NAT 行为,v2ray 实际上不属于其中的任何一种,但它最接近 RFC 5780 的 Address and Port-Dependent Mapping 加 Endpoint-Independent Filtering,即图中的 NAT Type 7,只是可能会把返回的包的来源搞错。

Xray-core 的代理协议如何实现 FullCone

这是本文的核心内容,其实原理很简单:把你本地的一个 UDP 端口映射为 VPS 的一个 UDP 端口,并使它们具有相同的效果。

拿一个最简单的场景举例:Socks 入站 + Freedom 出站

  1. Socks 入站收到二元组 A 发来的 Socks UDP 包,其中包含原始载荷与其原始目标 M,路由到 Freedom
  2. Freedom 出站使用一个随机端口将原始载荷发到其原始目标 M,这里认为 Freedom 使用了二元组 A1
  3. 映射关系已经建立,一段时间内 Socks 入站又收到了 A 发来的代理包,Freedom 还会用 A1 发到目标
  4. 同样地,如果 Freedom 的 A1 收到了 N 发回的包,Socks 就会把原始载荷同 N 这个信息一起发回给 A

当然,FullCone 还需要调用方按常理使用 Socks 代理协议,诸如各种 tun2socks 实现一般是没问题的。

下面插一个 Shadowsocks 出入站进来:

  1. 路由到 Shadowsocks 出站,它也是使用一个随机端口,将加密后的“载荷与目标”发到服务端的 SS 入站
  2. 服务端 SS 入站收到了客户端 SS 出站发来的 Shadowsocks UDP 包,解密,剩下的流程和上面没有区别

Trojan 协议的 UDP 也是类似的原理,不同之处是每个来源二元组都会对应一条 TCP 连接,在 TCP 上传输 UDP 的“载荷与目标”。

那么为什么同样是 UoT 的 VMess 却无法实现 FullCone?

根本原因是 VMess 的 UoT 协议结构只能在最开始时传一个“目标”,后面的多个数据包只能传“载荷”而不能带“目标”,服务端会把后续的数据包都发往最开始的“目标”。服务端向客户端返回数据包是同理的,协议结构只有“载荷”,客户端会认为返回的数据包都来自于最开始的“目标”,这和 v2ray 设计上的问题倒是一脉相承的,自带的 Mux 当然也是这样。(VLESS 也没有幸免,不过在改了)

所以对于 VMess、Mux、VLESS,Xray-core 目前是按 Symmetric 来路由的。否则如果是 FullCone 模式,后面的包都会被发到第一个包的目标地址,这就是 Clash 的 VMess 存在的问题,但并不好解决。此外,存在此问题时 VMess 又会被测出 FullCone,假的。

透明代理 TPROXY UDP 的原理

为了让游戏机用上 Xray-core 实现 FullCone,通常需要一个 Linux 设备来透明代理,一个树莓派就可以搞定。

为什么透明代理 UDP 只能 TRPOXY 而不推荐 REDIRECT?

  1. REDIRECT 会修改 UDP 包的目标二元组,并且此时 Linux 没有提供一个配套的机制让代理软件获知 UDP 包的原目标地址
  2. TRPOXY 则完全相反:它不会修改 UDP 包,Linux 还提供了简单的配套机制让代理软件获知 UDP 包的原目标地址

等需要往回发包时,代理软件会先在本地伪造出“返回的 UDP 包的来源二元组”的 socket,用这个 socket 把包发回去(这个原理就是可能会遇到 too many open files 的原因)。相比于其它软件,Xray-core 对这里有专门的优化,更优雅且有更好的性能。

若你在用 Windows 测透明代理的 NAT,一定注意要把当前网络设为 专用网络,这是很多人踩过的大坑,我也踩过。

提一下 QUIC:启用了 Xray-core 的 XTLS 时,通往 UDP 443 端口的流量默认会被拦截(拦截 QUIC),这样应用就不会使用 QUIC 而会使用 TLS,XTLS 才会真正生效。实际上,QUIC 本身也不适合被代理,因为 QUIC 自带了 TCP 的功能,UoT 就相当于两层 TCP 了。