Total Pageviews

Sunday 24 April 2022

v2ray_simple和v2simple

项目大大简化了 转发机制,能提高运行速度。本项目转发流量时,关键代码直接放在main.go里!非常直白易懂

只有项目名称是v2ray_simple,其它所有场合 全使用 verysimple 这个名称,可简称 "vs"。本作过于极简,极简得连logo也没有.

规定,编译出的文件名必须以 verysimple 开头.

verysimple 研发了一些新技术,使用自研架构,可以加速,目前基本上是全网最快,且有用户报告内存占用 比v2ray/xray 小1/3。

vs的一些亮点是 全协议readv加速,lazy技术,vless v1,hysteria 阻控,更广泛等utls支持,交互模式等。

支持的功能有:

socks5/http/dokodemo/tproxy(透明代理)/trojan/simplesocks/vless/vless_v1,

ws(以及earlydata)/grpc/quic(以及hy阻控)/smux,

dns(udp/tls)/route(geoip/geosite)/fallback(path/sni/alpn),

tcp/udp/unix domain socket, uTls, lazy, http伪装头, cli(交互模式)/apiServer

为了不吓跑小白,目前 本 README 把安装、使用方式 放在了前面,如果你要直接阅读本作的技术介绍部分,点击跳转 -> 创新点

安装方式:

下载安装

如果是 linux服务器,可以参考我的一篇指导文章 install.md

电脑客户端的话直接自己到release下载就行。

客户端的 geoip和 geosite

注意如果要geoip分流,而且要自己的mmdb文件的话(高玩情况),还要下载mmdb;

默认第一次运行是会自动下载mmdb文件的,所以不用太担心。

不过geosite的话,也是需要下载的,可以通过交互模式进行下载,或者通过如下命令下载

#在verysimple可执行文件所在目录
git clone github.com/v2fly/domain-list-community
mv domain-list-community geosite

通过git下载的好处是, 自己想要更新时,直接 git pull 即可;

通过 交互模式进行下载的好处是, 如果你配置了配置文件, 并且有一个可用的节点, 则交互模式优先通过你的节点来下载geosite.

这样可以避免github被墙的情况。

编译安装

git clone https://github.com/hahahrfool/v2ray_simple
cd v2ray_simple && go build

详细优化的编译参数请参考Makefile文件

如果你是直接下载的可执行文件,则不需要 go build

运行方式

本作支持多种运行模式,方便不同需求的同学使用

  1. 命令行模式
  2. 极简模式
  3. 标准模式
  4. 兼容模式
  5. 交互模式

运行前的准备

若为客户端,运行 ./verysimple -i 进入交互模式,选择下载geosite文件

第一次运行时会自动下载geoip文件。

可选拷贝示例文件

#如果使用极简模式,则复制vs.json文件
cp examples/vs.client.json client.json
cp examples/vs.server.json server.json

#如果使用 标准toml格式,则复制toml文件,我们提供了多种配置示例,你只需复制一种想要的即可
cp examples/vlesss.client.toml client.toml
cp examples/vlesss.server.toml server.toml

如果你不拷贝示例文件,也可以通过 交互模式 来生成自定义的配置。

极简模式

#客户端, 极简模式
verysimple -c client.json

#服务端, 极简模式
verysimple -c server.json

关于 vlesss 的配置,查看 server.example.json和 client.example.json就知道了,很简单的。

目前极简模式配置文件最短情况一共就4行,其中两行还是花括号,这要是还要我解释我就踢你的屁股。

极简模式使用json格式,内部使用链接url的方式,所以非常节省空间;

极简模式 不支持 复杂分流,dns 等高级特性。极简模式只支持通过 mycountry进行 geoip分流 这一种分流情况。

极简模式暂不支持 ws/grpc 特性.

极简模式继承自v2simple,理念是字越少越好。推荐没有极简需求的同学直接使用标准模式。

verysimple 继承 v2simple的一个优点,就是服务端的配置也可以用url做到。谁规定url只能用于分享客户端配置了?一条url肯定比json更容易配置,不容易出错。

另外,极简模式所使用的 url并不是正规的 各个协议所规定的 分享链接格式,而是我们自己的格式,所以链接看起来会略有区别。

以后可以考虑 推出一个 选项,选择 到底是 使用协议所规定的格式, 还是 使用我们verysimple自己的通用链接格式。

命令行模式

如果学会了极简模式里的url配置后,还可以用如下命令来运行,无需配置文件

#客户端
verysimple -L=socks5://127.0.0.1:10800 -D=vlesss://你的uuid@你的服务器ip:443?insecure=true

#服务端
verysimple -L=vlesss://你的uuid@你的服务器ip:443?cert=cert.pem&key=cert.key&version=0&fallback=:80

不细心的人要注意了,vlesss,要三个s,不然的话你就是裸奔状态,加了第三个s才表示套tls

命令行模式 实际上就是把命令行的内容转化成极简模式的配置 然后再处理

命令行模式 不支持dns、分流、复杂回落 等特性。只能在url中配置 默认回落。

标准模式

#客户端,标准模式
verysimple -c client.toml
#服务端,标准模式
verysimple -c server.toml

标准模式使用toml格式,类似windows的ini,对新手友好,不容易写错。推荐直接使用标准模式。

本作的 examples文件夹中的 vlesss.client.toml, vlesss.server.toml , multi.client.toml 等文件中 提供了大量解释性的注释, 对新手很友好, 一定要读一下,才可以熟练掌握配置格式。

兼容模式

未来会推出兼容v2ray的json配置文件的模式。

交互模式

已经推出了交互模式, 可以在命令行交互着生成一个你想要的配置,这样也就不需要各种一键脚本了

交互模式有很多好玩的功能,可以试试。

运行 verysimple -i 即可进入交互模式

目前支持如下功能:

  1. 生成随机ssl证书
  2. 交互生成配置,超级强大
  3. 热删除配置
  4. 热加载新配置文件
  5. 调节日志等级
  6. 调节hy手动挡
  7. 生成一个随机的uuid供你参考
  8. 下载geosite原文件
  9. 打印当前版本所支持的所有协议
  10. 查询当前状态

交互生成配置后还可以输出到文件、加载到当前运行环境、生成分享链接。

其他说明

如果你不是放在path里的,则要 ./verysimple, 前面要加一个点和一个斜杠。windows没这个要求。

注意,如果你是自己直接 go build 编译的,则可执行文件与项目名称一致,为 v2ray_simple;

如果用的下载的官方编译版本,则可执行文件叫做 verysimple. 可以通过文件名称判断是自己编译的还是下载的。

官方发布版统一叫做verysimple是为了与 v2ray区别开。

关于证书

自己生成证书!而且最好是用 自己真实拥有的域名,使用acme.sh等脚本申请免费证书,特别是建站等情况。

而且用了真证书后,别忘了把配置文件中的 insecure=true 给删掉.

使用自签名证书是会被中间人攻击的,再次特地提醒。如果被中间人攻击,就能直接获取你的uuid,然后你的服务器 攻击者就也能用了。

要想申请真实证书,仅有ip是不够的,要拥有一个域名。本项目提供的自签名证书仅供快速测试使用,切勿用于实际场合。

shell 命令 生成自签名证书

注意运行第二行命令时会要求你输入一些信息。确保至少有一行不是空白即可,比如打个1

openssl ecparam -genkey -name prime256v1 -out cert.key
openssl req -new -x509 -days 7305 -key cert.key -out cert.pem

此命令会生成ecc证书,这个证书比rsa证书 速度更快, 有利于网速加速(加速tls握手)。

交互模式 生成证书

本作的交互模式也有自动生成随机自签名证书功能

在你的服务端下载好程序后,运行 verysimple -i 开启交互模式,然后按向下箭头 找到对应选项,按回车 来自动生成tls证书。

创新点

本作有不少创新点,如下

协议

实现了vless协议(v0,v1)和vlesss(即vless+tcp+tls),

在本项目里 制定 并实现了 vless v1标准 (还在继续研发新功能),添加了非mux的fullcone;

lazy技术

本项目 发明了独特的非魔改tls包的 双向splice,本作称之为 tls lazy encrypt, 简称lazy

架构

使用了简单的架构,单单因为架构简单 就可以 提升不少性能。

本作使用了分层架构,网络层,tls层,高级层,代理层等层级互不影响。

所有传输方式均可使用utls来伪装指纹; 所有方式均可以选用 tcp、udp、unix domain socket 等 网络层,不再拘泥于原协议的网络层设计。

兼容性与速度

v0协议是直接兼容现有v2ray/xray的,比如可以客户端用任何现有支持vless的客户端,服务端使用verysimple

经过实际测速,就算不使用lazy encrypt等任何附加技术,verysimple作为服务端还是要比 v2ray做服务端要快。作客户端时也是成立的。最新1.10的测速似乎不lazy时即可比xray的 xtls快。( 最新测速 )

命令行

本作的命令行界面还在开发一种 “交互模式”,欢迎下载体验,使用 -i 参数打开。也欢迎提交PR 来丰富 交互模式的功能。

创新之外的已实现的有用特性

支持trojan协议 以及smux, 而且经过测速,比trojan-go快。(速度差距和本作的vless与v2ray的vless的差距基本一致,所以就不放出测速文件了,参考vless即可)

不过 lazy特性是不支持trojan的。这种不稳定不安全的特性还是专用在一个协议上比较好。

在没有mmdb文件时,自动下载mmdb

使用readv 进行加速

其它监听协议还支持 socks5, http, dokodemo

多种配置文件格式,包括自有的 toml标准格式

默认回落,以及按 path/sni/alpn 回落

按 geoip,geosite,ip,cidr,domain,inTag,network 分流,以及 按国别 顶级域名分流,用到了 mmdb和 v2fly的社区维护版域名列表

支持utls伪装tls指纹,本作的 utls 还可以在 用 webscoket和grpc 时使用

支持websocket, 使用性能最高的 gobwas/ws 包,支持 early data 这种 0-rtt方式,应该是与现有xray/v2ray兼容的

支持grpc,与 xray/v2ray兼容

支持 quic以及hysteria 阻控,与xray/v2ray兼容(详情见wiki),还新开发了“手动挡”模式

api服务器;tproxy 透明代理; http伪装头

技术详情

关于vless v1

这里的v1是 verysimple 自己制定的,总是要摸着石头过河嘛。标准的讨论详见 vless_v1

总之,强制tls,简单修订了一下协议格式,然后重点完善了fullcone。

verysimple 实现了 一种独创的 非mux型“分离信道”方法的 udp over tcp 的fullcone

v1还有很多其他新设计,比如用于 连接池和 dns等,详见 vless_v1

vless v1协议还处在开发阶段,我随时可能新增、修改定义。

因为本作率先提出了 vless v1的开发,所以本作的版本号 也直接从 v1.0.0开始

关于udp

本项目 完整支持 udp

最新的代码已经完整支持vless v0

后来我还自己实现了vless v1,自然也是支持udp的,也支持fullcone。v1还处于测试、研发阶段.

另外上面说的是承载数据支持udp;我们协议的底层传输方式也是全面支持udp的。也就是说可以用udp传输vless数据,然后vless里面还可以传输 udp的承载数据。

底层用udp传输的话,可以理解为 比 v2ray的mkcp传输方式 更低级的模式,直接用udp传输, 不加任何控制。所以可能丢包,导致速度较差 且不稳定。

tls lazy encrypt (splice)

注意,因为技术实现不同,该功能不兼容xtls。, 因为为了能够在tls包外进行过滤,我们需要做很多工作,所以技术实现与xtls是不一样的。

lazy功能是对标xtls的,但是不兼容xtls,你用lazy的话,两端必须全用verysimple

在最新代码里,实现了 双向 tls lazy encrypt, 即另一种 xtls的 splice的实现,底层也是会调用splice,本包为了加以区分,就把这种方式叫做 tls lazy encrypt。

tls lazy encrypt 特性 运行时可以用 -lazy 参数打开(服务端客户端都要打开),然后可以用 -pdd 参数 打印 tls 探测输出

在系统 不支持splice和sendfile 系统调用时,lazy特性等价于 xtls 的 direct 流控.

因为是双向的,而xtls的splice是单向,所以 理论上 tls lazy encrypt 比xtls 还快,应该是正好快一倍?不懂。反正我是读写都是用的splice。

而且这种技术不通过魔改tls包实现,而是在tls的外部实现,不会有我讲的xtls的233漏洞,而且以后可以与utls配合 进行模拟指纹。

关于 splice,还可以参考我的文章 https://github.com/hahahrfool/xray_splice-

该特性不完全稳定,可能会导致一些网页访问有时出现异常,有时出现bad mac alert;刷新页面可以解决

不是速度慢,是因为 目前的tls过滤方式有点问题, 对close_alert等情况没处理好。而且使用不同的浏览器,现象也会不同

在我的最新代码里,采用了独特的技术,已经规避了大部分不稳定性。总之比较适合看视频,毕竟双向splice,不是白给的!

经过我后来的思考,发现似乎xtls的splice之所以是单向的,就是因为它在Write时需要过滤掉一些 alert的情况,否则容易被探测;

不过根据 a report by gfwrev, 对拷直连 还是会有很多问题,很难解决

所以既然问题无法解决,不如直接应用双向splice,也不用过滤任何alert问题。破罐子破摔。

总之这种splice东西只适用于玩一玩,xtls以及所有类似的 对拷直连的 技术都是不可靠的。我只是放这里练一下手。大家玩一玩就行。

我只是在内网自己试试玩一玩,从来不会真正用于安全性要求高的用途。

关于splice的一个现有“降速”问题也要看看,(linux 的 forward配置问题),我们这里也是会存在的 XTLS/Xray-core#59

总结 tls lazy encrypt 技术优点

解决了xtls以下痛点

  1. 233 漏洞
  2. 只有单向splice
  3. 无法与fullcone配合
  4. 无法与utls配合

原因:

  1. 我不使用循环进行tls过滤,而且不魔改tls包
  2. 我直接开启了双向splice;xtls只能优化客户端性能,我们两端都会优化;一般而言大部分服务器都是linux的,所以这样就大大提升了所有连接的性能.
  3. 因为我的vless v1的fullcone是非mux的,分离信道,所以说是可以应用splice的(以后会添加支持,可能需要加一些代码,有待考察)
  4. 因为我不魔改tls包,所以说可以套任何tls包的,比如utls,目前已经添加了utls。所以你可以享受伪装的同时享受splice

而且alert根本不需要过滤,因为反正xtls本身过滤了还是有两个issue存在,是吧。

而且后面可以考虑,如果底层是使用的tls1.2,那么我们上层也可以用 tls1.2来握手。这个是可以做到的,因为底层的判断在客户端握手刚发生时就可以做到,而此时我们先判断,然后再发起对 服务端的连接,即可。

也有一种可能是,客户端的申请是带tls1.3的,但是目标服务器却返回的是tls1.2,这也是有可能的,比如目标服务器比较老,或者特意关闭了tls1.3功能;此时我们可以考虑研发新技术来绕过,也要放到vless v1技术栈里。参见 #2

在不使用新协议时,lazy只能通过不lazy tls1.2的方式来解决此问题, 即裸奔转发 tls1.3、加密转发 tls1.2.

关于内嵌geoip 文件

默认的Makefile或者直接 go build 是不开启内嵌功能的,需要加载外部mmdb文件,就是说你要自己去下载mmdb文件,

不过,最新的版本会自动检测,如果你没有mmdb文件,会自动给你从cdn下载下来,所以已经很方便了,不需要自己动手.

可以从 https://github.com/P3TERX/GeoLite.mmdb 项目,https://github.com/Loyalsoldier/geoip 项目, 或者类似项目 进行下载

加载的外部文件 必须使用原始 mmdb格式。

若要内嵌编译,要用 tar -czf GeoLite2-Country.mmdb.tgz GeoLite2-Country.mmdb 来打包一下,将生成的tgz文件放到 netLayer文件夹中,然后再编译 ,用 go build -tags embed_geoip 编译

内嵌编译 所使用的 文件名 必须是 GeoLite2-Country.mmdb.tgz

因为为了减小文件体积,所以才内嵌的gzip格式,而不是内嵌原始mmdb

开发标准以及理念

文档尽量多,代码尽量少. 同时本作不追求极致模块化, 可以进行适当耦合. 一切以速度、浅显易懂 优先

KISS, Keep it Simple and Stupid.

文档

文档、注释尽量详细,且尽量完全使用中文,尽量符合golang的各种推荐标准。

根据golang的标准,注释就是文档本身(godoc的原理),所以一定要多写注释。不要以为解释重复了就不要写,因为要生成godoc文档,在 pkg.go.dev 上 给用户看的时候它们首先看到的是注释内容,而不是代码内容

本项目所生成的文档在 https://pkg.go.dev/github.com/hahahrfool/v2ray_simple

再次重复,文档越多越好,尽量降低开发者入门的门槛。

我有时也会时常在 discussion里发一些研究、讨论的文章,大家也要踊跃发言 https://github.com/hahahrfool/v2ray_simple/discussions

代码

代码的理念就是极简!这也是本项目名字由来!

根据 奥卡姆剃刀原理,不要搞一大堆复杂机制,最简单的能实现的代码就是最好的代码。

想要为本作贡献的同学,要学习本作的这些理念,并能够贯彻你的代码。

不够极简或者解释不够清晰的代码我们将会进行淘汰或修正。

有贡献想法的同学,阅读 CONTRIBUTING 或者issue中的【开发者贡献指南】.

开发者入门指导

首先学会使用verysimple,熟读本 README.md 和 examples/ 下的配置文件

之后读 version.go 文件里的 注释,对本作结构有一个认识。然后读 proxy/doc.go 理解 VSI模型。

之后 学习 proxy.ProxyCommon 接口.

之后就可以在go doc中选择自己感兴趣的地方阅读了。

本项目所使用的开源协议

MIT协议,即你用的时候也要附带一个MIT文件,然后作者不承担任何责任、义务、后果。

历史

启发自我fork的v2simple,不过原作者的架构还是有点欠缺,我就直接完全重构了,完全使用我自己的代码。

这样也杜绝了 原作者跑路 导致的 一些不懂法律的人对于开源许可的 质疑。

实际上是毫无问题的,关键是他们太谨慎。无所谓,现在我完全自己写,没话说了吧—;

我fork也是尊重原作者,既然你们这么谨慎,正好推动了我的重构计划,推动了历史发展.

额外说明 以及 开发计划

目前正在计划的有

  1. 完善并实现 vless v1协议
  2. 什么时候搞一个 verysimple_c 项目,用c语言照着写一遍; 也就是说,就算本verysimple没有任何技术创新,单单架构简单也是有技术优势的,可以作为参考 实现更底层的 c语言实现。
  3. verysimple_c 写好后,就可以尝试将 naiveproxy 嵌入 verysimple_c 了
  4. 完善 tls lazy encrypt技术
  5. 链接池技术,可以重用与服务端的连接 来发起新请求
  6. 握手延迟窗口技术,可用于分流一部分流量使用mux发送,达到精准降低延迟的目的;然后零星的链接依然使用单独信道。

其它开发计划请参考 #3

验证方式

对于功能的golang test,请使用 go test ./... -count=1 命令。如果要详细的打印出test的过程,可以添加 -v 参数

测速

测试环境:ubuntu虚拟机, 使用开源测试工具 https://github.com/librespeed/speedtest-go

编译后运行,会监听8989。注意要先按speedtest-go的要求,把web/asset文件夹 和一个toml配置文件 放到 可执行文件的文件夹中,我们直接在项目文件夹里编译的,所以直接移动到项目文件夹根部即可

然后内网搭建nginx 前置,加自签名证书,配置添加反代: proxy_pass http://127.0.0.1:8989; 然后 speedtest-go 后置。

然后verysimple本地同时开启 客户端和 服务端,然后浏览器 firefox配置 使用 socks5代理,连到我们的verysimple客户端

注意访问测速网页时要访问https的,否则测的 splice的速度实际上还是普通的tls速度,并没有真正splice。

访问 https://自己ip/example-singleServer-full.html 注意这个自己ip不能为 127.0.0.1,因为本地回环是永远不过代理的,要配置成自己的局域网ip。

关于readv与测速

如果你是按上面指导内网进行测速的话,实际上readv有可能会造成减速效果,具体可参考 #14

如果发现减速,则要关闭readv

结果

左侧下载,右侧上传,单位Mbps。我的虚拟机性能太差,所以就算内网连接速度也很低。

不过这样正好可以测出不同代理协议之间的差距。

verysimple 版本 v1.0.3

//直连
156,221
163,189
165,226
162,200


//verysimple, vless v0 + tls
145,219
152,189
140,222
149,203

//verysimple, vless v0 + tls + tls lazy encrypt (splice):

161,191,
176,177
178,258
159,157

详细测速还可以参考另外几个文件,docs/speed_macos.md 和 docs/speed_ubuntu.md。

总之目前可以看到,verysimple是绝对的王者。虽然有时还不够稳定,但是我会进一步优化这个问题的。

交流

群肯定是有的。只在此山中,云深不知处。实际上每一个群都有可能是verysimple群,每一个成员都有可能是verysimple的作者。

如果你实在找不到群,你不妨自己建一个,然后自称verysimple项目作者。

建议所有的人都认真阅读README以及其它所有有文字的文件和页面;

有能力的人要阅读整个verysimple项目的所有代码;

希望每一个人都能站出来,自豪地说,“我就是原作者”,并且能够滔滔不绝地讲解自己对verysimple的架构的理解。

如果你能fork,并青出于蓝,那么我甘拜下风。

也希望本项目能够普及到世界上所有需要学习相关技术的国家,希望所有的想要学习代码的人都能够先学习中文。

如果本作作者突然停更,这里允许任何人以 verysimple 作者的名义fork并 接盘。你只要声称自己是原作者,忘记了github和自己邮箱的密码,只好重开,这不就ok了。

关键不在于谁是作者,一个作者倒下,千万个作者会站起来。

我们的思想 生生不息,追求自由的人们啊,一起奋斗吧!

免责声明与鸣谢

MIT协议!作者不负任何责任。

我们只会帮助研究理论的朋友。

同时,我们对于v2ray/xray等项目也是没有任何责任的。

引用的外部包

github.com/oschwald/maxminddb-golang v1.8.0
github.com/yl2chen/cidranger v1.0.2
github.com/BurntSushi/toml v1.0.0
github.com/gobwas/ws v1.1.0
gonum.org/v1/gonum v0.11.0
google.golang.org/grpc v1.45.0
github.com/miekg/dns v1.1.47
github.com/lucas-clemente/quic-go
github.com/tobyxdd/quic-go
go.uber.org/zap
github.com/manifoldco/promptui
github.com/xtaci/smux v1.5.16

可能不全,详见 go.mod 文件

为了支持hysteria 的阻塞控制,从 https://github.com/HyNetwork/hysteria 的 pkg/congestion里拷贝了 brutal.go 和 pacer.go 到我们的 quic文件夹中.

from  https://github.com/hahahrfool/v2ray_simple

------

A simple implementation of V2Ray.

V2Simple

该项目实现了一个简单版本的V2Ray。如果你对V2Ray等代理软件的运行机制很好奇,又没有时间研究其庞杂的实现,不妨关注此项目,核心代码不过100行,其余代码则是几个主要协议的具体实现。

目前实现了 VMess协议 的客户端和服务端以及一个简洁的路由,只需简单配置即可无缝对接如下配置的V2Ray客户端或者服务端:

以下V2Ray的功能暂不支持

  • VMess协议的AEAD认证以及动态端口
  • 多入口多出口路由
  • Mux/mKCP/WebSocket/H2等协议
  • 流量统计以及用户管理
  • DNS服务

接下来继续完成的功能点:

  • 支持 UDP over TCP
  • 支持 VLess


编译和使用

编译

要求 Go >= 1.14:

git clone https://github.com/jarvisgally/v2simple
cd v2simple && go build -o bin

客户端模式

客户端模式在本地启动一个socks5代理,对流量进行加密和伪装,随后转发到Q外的服务器上:

# 先将项目中的client.example.json复制到bin目录中,修改里面远程服务器的域名,并重命名为client.json
bin/v2simple -f client.json

服务端模式

服务器模式监听一个可以远程连接的接口,将流量还原为原始流量随后直接访问目标网站:

# 先将项目中的server.example.json复制到bin目录中,修改里面域名证书和私钥地址,并重命名为server.json
bin/v2simple -f server.json

配置文件

客户端模式client.example.json

{
  "local": "socks5://127.0.0.1:1081",
  "route": "whitelist",
  "remote": "vmesss://a684455c-b14f-11ea-bf0d-42010aaa0003@<fix-me>:443?alterID=4"
}

服务端模式server.example.json

{
  "local": "vmesss://a684455c-b14f-11ea-bf0d-42010aaa0003@0.0.0.0:443?alterID=4&cert=<fix-me>&key=<fix-me>&fallback=:80",
  "remote": "direct://"
}

其中local项标识本地服务的协议,remote项标识远端服务的协议,目前支持的协议:

  • socks5:仅服务端,用于监听本地的socks5代理请求
  • direct:直连
  • vmess:支持客户端和服务端
vmess://uuid[:alterId]@host:port?[&security=none|aes-128-gcm|chacha20-poly1305]
 - security:在服务端模式下是无需设置的,服务端会根据客户端的请求自动匹配
  • vmesss:使用tls的vmess,同样支持客户端和服务端,服务端还需要额外指定域名的证书和私钥地址
vmesss://uuid[:alterId]@host:port?[&security=none|aes-128-gcm|chacha20-poly1305][&fallback=:80]
 - security:在服务端模式下是无需设置的,服务端会根据客户端的请求自动匹配
 - fallback: 即使用http直接访问443端口会转跳到此地址

注:纯vmess的协议是是基于TCP的,不推荐裸奔;在例子中我们均使用了vmesss,即伪装成常规的https流量;这需要预先注册一个域名并申请TLS证书,具体做法可以参考这里 。

route项表示路由模式,目前支持如下模式:

  • whitelist:白名单模式,如果匹配,则直接访问,否则通过代理访问
  • blacklist:黑名单模式,如果匹配,则通过代理访问,否则直接访问
  • 空白:不做匹配,全部流量通过代理访问

目前项目中仅包含whitelist,每一行是一个域名、IP或者CIDR,来自V2Ray的geosite:cngeoip:cngeoip:private

VMess协议

VMess协议 是V2Ray的原创协议,主要解决了两个问题:

  • 用户的鉴权
  • 数据的加密

本质上是对流量增加了一层编解码的逻辑,在Q看来是未知协议的TCP连接,此乃最大特征,至少在敏感时期就可以轻易被Q阻断,因此一般建议配合TLS或者WS来使用。

此处简述 VMess协议 中的「标准格式」的数据传输方式,即指令部分的Opt为0x01时的处理方式:

  1. 客户端将原始的请求加密为 认证信息 + 指令部分 + 数据部分
    1. 认证信息为16字节,使用用户id和时间戳生成,服务端通过此认证信息匹配用户,并且判断是否存在来自Q的 重放攻击
    2. 指令部分比较复杂,主要包含:
      1. 响应认证 - 服务端使用此认证作为头部将加密后的响应数据返回
      2. 原始请求的协议和目标地址 - 服务端以此访问目标地址
      3. 数据部分的对称加密算法和相关密码 - 服务端以此解密请求数据,并以同样的参数加密响应数据
      4. 将整个指令部分加密
    3. 数据部分包含:
      1. 实际的请求数据被分割为若干个小块,每个小块由2个字节的长度和数据包组成
      2. 每个数据包都会使用指令部分的相关参数进行加密
  2. 服务端接受到请求
    1. 校验请求的认证信息
      1. 检测用户是否存在
      2. 处理重放攻击等
    2. 如果认证通过,解密指令部分可获得:
      1. 响应认证
      2. 原始请求的协议和目标地址
      3. 数据部分的解密方法
    3. 解密数据部分,并以此访问目标网站
    4. 对目标网站的响应数据进行加密,生成加密后的响应数据包,主要包括:
      1. 响应认证
      2. 使用与请求同样的方法加密后的响应数据
  3. 客户端接收到加密后响应数据
    1. 校验响应认证
    2. 使用与请求一样的数据解密响应数据,并返回给浏览器

上述1.i的认证信息生成方式如下,为16字节的hash值:

H = MD5
K = 用户ID
M = UTC时间,精确到秒,取值为当前时间的前后30秒随机值
Hash = HMAC(H, K, M)

服务端会运行一个协程,不断的对已经注册的用户id生成前后120秒内的所有hash值,以此校验认证信息是合法的,这也是V2Ray要求客户端和服务器的时间不能有太大误差的原因。

上述1.ii的指令部分格式如下:

1 字节16 字节16 字节1 字节1 字节4 位4 位1 字节1 字节2 字节1 字节N 字节P 字节4 字节
版本号 Ver数据加密 IV数据加密 Key响应认证 V选项 Opt余量 P加密方式 Sec保留指令 Cmd端口 Port地址类型 T地址 A随机值校验 F

上述1.iii的数据部分被分割成小块,每一个块的数据格式如下,其中数据包由指定的加密算法加密:

2 字节L 字节
长度 L数据包


参考

该项目参考了如下资源:

  • 你也能写个 Shadowsocks ,当前项目参考了里面关于SOCKS5协议的实现;如果标题党一下,本文或许也可改为「你也能撸一个 V2Ray」吧
  • Clash ,VMess的客户端部分
  • V2Ray

from  https://github.com/jarvisgally/v2simple


No comments:

Post a Comment