Added missing files for future translation
parent
6deb427a5a
commit
24341883df
|
@ -0,0 +1,240 @@
|
|||
---
|
||||
sidebar: auto
|
||||
---
|
||||
|
||||
# 大史记
|
||||
|
||||
## 2021.4.6
|
||||
|
||||
- VuePress Next.
|
||||
- With Dark Mode.
|
||||
|
||||
## 2021.4.4
|
||||
|
||||
- 本文档迎来的新的首页。
|
||||
- 本文档迎来了暗黑模式。
|
||||
- ~~当然,暗黑模式还有各种各样的问题。具体的内容还需要慢慢调整。~~
|
||||
- 另:Telegram 群聊突破了 5000 人!还加入了 Anti-Spam 机器人!
|
||||
- 🎉🎉🎉
|
||||
|
||||
## 2021.4.1 <Badge>[v1.4.2](https://github.com/XTLS/Xray-core/releases/tag/v1.4.2)</Badge>
|
||||
|
||||
- 不是愚人节玩笑,今天更新。
|
||||
- 加入 Browser Dialer,用与改变 TLS 指纹与行为。
|
||||
- 加入 uTLS,用与改变 TLS Client Hello 的指纹。
|
||||
- 顺便修复了一大堆奇妙的问题,具体的内容见更新日志。
|
||||
|
||||
## 2021.3.25
|
||||
|
||||
<!-- prettier-ignore -->
|
||||
没错还在变。 -_-
|
||||
|
||||
## 2021.3.15
|
||||
|
||||
文档网站正在悄悄的进行着某些神秘的变化。。。,🙊🙊🙊
|
||||
|
||||
## 2021.3.14 <Badge>[v1.4.0](https://github.com/XTLS/Xray-core/releases/tag/v1.4.0)</Badge>
|
||||
|
||||
- Happy Pi-Day!
|
||||
- 这次是个大更新:
|
||||
- 为链式代理引入了传输层支持。
|
||||
- 为 Dialer 引入了 Domain Strategy,解决奇妙的 DNS 问题。
|
||||
- 添加了 gRPC 传输方式,与更快一点的 Multi Mode。
|
||||
- 添加了 WebSocket Early-Data 功能,减少了 WebSocket 的延迟。
|
||||
- 添加了 FakeDNS。
|
||||
- 还修复了系列的问题,添加了各类功能,详情请见更新日志。
|
||||
- 还是 VuePress 比较爽啊(
|
||||
|
||||
## 2021.3.3 <Badge>[1.3.1](https://github.com/XTLS/Xray-core/releases/tag/v1.3.1)</Badge>
|
||||
|
||||
- 这个版本使用了 Golang 1.16,正式原生支持 Apple Silicon。
|
||||
- 同时修复了一个会导致 Panic 的 bug。~~Holmium\_认为这是在骗、在偷袭。~~
|
||||
- 修复了几个遗留问题。
|
||||
|
||||
## 2021.2.14 <Badge>[1.3.0](https://github.com/XTLS/Xray-core/releases/tag/v1.3.0)</Badge>
|
||||
|
||||
- Happy 🐮 Year 🎉!
|
||||
- v1.3.0 通过非常巧妙的机制实现了 V 系协议全部 FullCone,同时保证了一定的兼容性。
|
||||
- OHHHHHHHHHHHH!
|
||||
|
||||
## 2021.01.31 <Badge>[1.2.4](https://github.com/XTLS/Xray-core/releases/tag/v1.2.4)</Badge>
|
||||
|
||||
- 解决两个“连接至标准 Socks 服务端时可能出错”的历史遗留问题。
|
||||
- 似乎这个版本没有什么改变,但这只是暴风雨前的宁静。
|
||||
- (没错我就是先知)
|
||||
> 你个傻子,你拿的是 UNO 牌。
|
||||
|
||||
## 2021.01.25
|
||||
|
||||
- 全互联网最好最详细的秘籍入门篇同学们练熟了吗? 🍉 老师开始连载[秘籍第一层](../document/level-1/)咯...
|
||||
- [英文版文档网站](../en)逐渐增加内容 ing, 感谢各位大佬的辛苦付出~!
|
||||
|
||||
## 2021.01.22 <Badge>[1.2.3](https://github.com/XTLS/Xray-core/releases/tag/v1.2.3)</Badge>
|
||||
|
||||
- 对 SS 协议的支持**又**变强了, 支持单端口多用户!
|
||||
- 对 trojan 协议的支持也**又**变强了, trojan 的回落也解锁 SNI 分流的新姿势啦~!
|
||||
- _(VLESS: 嘤嘤嘤)_
|
||||
- UDP 奇奇怪怪的 BUG 被干掉了, 一个字, "稳定".
|
||||
- 嗅探可以排除你不想嗅探的域名, 可以开启一些新玩法.
|
||||
- 向发现问题->开 issue->自行测试->自行分析->自行找到问题->自行解决->然后给上下游提交 PR 的大佬 <img src="https://avatars2.githubusercontent.com/u/8384161?s=32" width="32px" height="32px" alt="a"/> [@Bohan Yang](https://github.com/bohanyang) 致敬!
|
||||
- 其他美味小樱桃, 惯例更新品尝就对啦.
|
||||
|
||||
## 2021.01.19
|
||||
|
||||
- 一些数字
|
||||
- 版本发布了 10 个 tag
|
||||
- 解决掉了 100 个 issue
|
||||
- 复刻了 300 个 fork
|
||||
- 点了 2000 个 star
|
||||
- 群 3000 个 人
|
||||
|
||||
## 2021.01.17
|
||||
|
||||
- 辛苦的翻译工作开始了, 感谢<img src="https://avatars2.githubusercontent.com/u/60207794?s=32" width="32px" height="32px" alt="a"/> [@玖柒 Max](https://github.com/jiuqi9997)和其他所有的翻译大佬们.
|
||||
- [English version](https://xtls.github.io/en/)
|
||||
|
||||
## 2021.01.15 <Badge>[1.2.2](https://github.com/XTLS/Xray-core/releases/tag/v1.2.2)</Badge>
|
||||
|
||||
- 回落分流又解锁了奇怪的新姿势! 回落中可以根据 SNI 分流啦~!
|
||||
- 之前预告的 UUID 修改正式上线.([往下看往下看](#2021.01.12))
|
||||
- 日志现在看起来比上一次顺眼又更顺眼了一丢丢.
|
||||
- 远程 DOH 和其他的 DNS 模式一样学会了走路由分流.
|
||||
- 当然还有其他各种小糖果.(更新品尝就对了)
|
||||
- 啊, 还有, 世界上第一個 M1 上跑起 Xray 的男人是 Anthony TSE
|
||||
|
||||
## 2021.01.12
|
||||
|
||||
- 将要到来的 UUID 修改, 支持自定义字符串和 UUID 之间的映射. 这意味着你将可以这样在配置文件中写 id 来对应用户.
|
||||
- 客户端写 "id": "我爱 🍉 老师 1314",
|
||||
- 服务端写 "id": "5783a3e7-e373-51cd-8642-c83782b807c5" (此 UUID 是 `我爱🍉老师1314` 的 UUID 映射)
|
||||
- 🍉 老师的[小小白白话文](../document/level-0/)大结局, 撒花.
|
||||
|
||||
## 2021.01.10 <Badge>[1.2.1](https://github.com/XTLS/Xray-core/releases/tag/v1.2.1)</Badge>
|
||||
|
||||
- [小小白白话文](../document/level-0/)连载上线啦,🍉 老师呕心沥血之作, 手把手教你从什么都不会到熟练配置 Xray!
|
||||
- (可能是整个互联网上, 最详细最有耐心的教你从 0 开始配置的教程)
|
||||
- [透明代理](../document/level-2/)也增加了更多文章.
|
||||
- 还有很多细节修改, 文档将会越来越规范!
|
||||
- 感谢 [@ricuhkaen](https://github.com/ricuhkaen) , [@BioniCosmos](https://github.com/BioniCosmos), [@kirin](https://github.com/kirin10000)
|
||||
|
||||
* 大量的 UDP 相关修复, 甚至可以在育碧的土豆服务器上玩彩虹六号!
|
||||
* Google Voice 应该也可以正常使用 v2rayNG 拨打了.
|
||||
* 日志现在看起来更顺眼.
|
||||
|
||||
## 2021.01.07
|
||||
|
||||
- 礼貌和尊重本应是社区不需要明说的准则之一。
|
||||
|
||||
## 2021.01.05
|
||||
|
||||
- 文档网站正在悄悄的进行着某些神秘的变化。。。,🙊🙊🙊
|
||||
|
||||
## 2021.01.03
|
||||
|
||||
- 文档仓库第一个 PR。🎉
|
||||
[透明代理(TProxy)配置教程 ](../document/level-2/tproxy.md) ,感谢<img src="https://avatars2.githubusercontent.com/u/41363844?s=32" width="32px" height="32px" alt="a"/> [@BioniCosmos](https://github.com/BioniCosmos)
|
||||
- tg 群突破 2500。
|
||||
|
||||
## 2021.01.01
|
||||
|
||||
【祝大家新年快乐,嗨皮牛耶!】🎆🎇🎆 <Badge>[1.2.0](https://github.com/XTLS/Xray-core/releases/tag/v1.2.0)</Badge>
|
||||
|
||||
🎁 在元旦的最后几分钟,v1.2.0 它来了,带着周五必更的惯例,带着各位贡献大佬的心血以及 @rprxx 的黑眼圈,不负众望的来了!
|
||||
|
||||
- 圣诞礼物[v1.1.5](#20201225)后的元旦礼物 🎁,游戏玩家大福利,全面 FullCone。
|
||||
- (UDP 还会继续增强!)
|
||||
- 如果你已经拆过圣诞礼物,这次还有比圣诞礼物更精美的包装和小糖果哦。(同样不用问,更新品尝就对了)
|
||||
- (不,下面不是广告,是里程碑。)
|
||||
- Xray 是有史以来第一个不受限制的多协议平台:只需 Xray 即可解决问题,无需借力其它实现。
|
||||
- 一人扛起了所有!支持各大主流协议!
|
||||
- 一骑绝尘的性能!
|
||||
- 日趋完善的功能!
|
||||
- 可怕的生命力与社区亲和力!
|
||||
- Xray 将继续保持前行! 因此 [Xray 需要更多的英雄!!](https://github.com/XTLS/Xray-core/discussions/56)!
|
||||
- PS:请品,请细品[release notes](https://github.com/XTLS/Xray-core/releases/tag/v1.2.0)每一句。似乎有一个小秘密小彩蛋 ~~(啊,有人敲门...我一会和你们说)~~
|
||||
|
||||
## 2020.12.29
|
||||
|
||||
透明代理的游戏玩家利好! Xray-core tproxy 入站, socks 出站 UDP FullCone 测试版, [TG 群](https://t.me/projectXray)火热测试中
|
||||
|
||||
## 2020.12.25 <Badge>[1.1.5](https://github.com/XTLS/Xray-core/releases/tag/v1.1.5)</Badge>
|
||||
|
||||
圣诞节快乐!
|
||||
|
||||
- 游戏玩家的圣诞礼物!你可以用 xray 爽快的打游戏啦!因为有了 SS/trojan UDP fullcone
|
||||
- 你可以用你喜欢的格式写配置文件了,比如 yaml,比如 toml...
|
||||
- (VLESS 的 UDP fullcone 和更多增强很快就到!)
|
||||
- 无须再担心证书验证被墙,OCSP stapling 已经上线!
|
||||
- kirin 带来了一大波 脚本更新.[脚本在此](https://github.com/XTLS/Xray-install)
|
||||
- 还有更多美味小樱桃!(不用问,更新品尝就对了)
|
||||
|
||||
## 2020.12.24
|
||||
|
||||
因为某些不可描述的原因,Xray 的文档网站已在发布日前偷跑上线。
|
||||
网址为:[没错你正在看的就是](https://xtls.github.io)
|
||||
|
||||
大家可以查阅各种内容也欢迎纠错/提出建议(可发往文档 github 仓库的 issue 区)
|
||||
|
||||
文档网站需要不断完善和增加内容,以及完善设计。
|
||||
因此更欢迎大家一起为文档建设添砖加瓦。
|
||||
[文档的仓库](https://github.com/XTLS/XTLS.github.io)
|
||||
|
||||
仓库的 readme 中有简略教程说明如何帮助 xray 改进文档网站.
|
||||
欢迎大家查看,纠错,修改,增加心得。
|
||||
|
||||
## 2020.12.23
|
||||
|
||||
Xray-core Shadowsocks UDP FullCone 测试版, [TG 群](https://t.me/projectXray)火热测试中
|
||||
|
||||
## 2020.12.21
|
||||
|
||||
- Project X 群人数 2000+
|
||||
- 群消息(含游戏群) 日均破万
|
||||
|
||||
## 2020.12.18 <Badge>[1.1.4](https://github.com/XTLS/Xray-core/releases/tag/v1.1.4)</Badge>
|
||||
|
||||
- 更低的启动内占用和内存使用优化
|
||||
- 随意定制的 TLS 提高你的 SSL 评级
|
||||
- 支持 XTLS 入站的 Splice 以及支持 trojan 的 XTLS
|
||||
- 还有在您路由器上使用的 Splice 最佳使用模式建议
|
||||
|
||||
## 2020.12.17
|
||||
|
||||
鉴于日益增长群人数和游戏需求, 开启了[TG 游戏群](https://t.me/joinchat/UO4NixbB_XDQJOUjS6mHEQ)
|
||||
|
||||
## 2020.12.15
|
||||
|
||||
[安装脚本 dev 分支](https://github.com/XTLS/Xray-install/tree/dev)开启, 持续更新功能中.
|
||||
|
||||
## 2020.12.11 <Badge>[1.1.3](https://github.com/XTLS/Xray-core/releases/tag/v1.1.3)</Badge>
|
||||
|
||||
- 完整版本的 REDIRECT 透明代理模式.
|
||||
- 软路由 splice 流控模式的优化建议.
|
||||
|
||||
## 2020.12.06 <Badge>[1.1.2](https://github.com/XTLS/Xray-core/releases/tag/v1.1.2)</Badge>
|
||||
|
||||
- 流控增加 splice 模式, Linux 限定, 性能一骑绝尘.
|
||||
- 增强了 API 兼容
|
||||
|
||||
## 2020.12.04
|
||||
|
||||
增加 splice 模式
|
||||
|
||||
## 2020.11.27
|
||||
|
||||
- Project X 的 GitHub 主仓库 Xray-core 已获 500+ stars
|
||||
- 登上了 GitHub Trending
|
||||
- Project X 群人数破千,频道订阅数 500+
|
||||
|
||||
## 2020.11.25 <Badge>[1.0.0](https://github.com/XTLS/Xray-core/releases/tag/v1.0.0)</Badge>
|
||||
|
||||
Xray 的第一个版本.
|
||||
|
||||
- 基于 v2ray-core 修改而来,改动较大
|
||||
- 全面增强, 性能卓越, 完全兼容
|
||||
|
||||
## 2020.11.23
|
||||
|
||||
project X start
|
||||
|
||||
> ~~梦开始的时候~~
|
|
@ -0,0 +1,41 @@
|
|||
# 开发指南
|
||||
|
||||
## 编译文档
|
||||
|
||||
Xray 支持各种平台, 您可以在多种平台上自行进行交叉编译。
|
||||
|
||||
请点击[编译文档](./intro/compile.md)以查看具体编译相关内容。
|
||||
|
||||
## 设计思路
|
||||
|
||||
Xray 内核提供了一个平台,在其之上可以进二次开发。
|
||||
|
||||
这个章节阐述了 Xray 的设计目标和架构。
|
||||
|
||||
请点击[设计思路](./intro/design.md)以了解 Xray 的设计目标和架构。
|
||||
|
||||
## 开发规范
|
||||
|
||||
这个章节阐述了获取代码,进行开发,提交 PR 的流程中需要遵循的准则, 以及相关的编码规范。
|
||||
|
||||
请点击[开发规范](./intro/guide.md)查看 Xray 开发中应遵循的准则。
|
||||
|
||||
## 协议详解
|
||||
|
||||
Xray 用到了很多种协议, 您可以通过各种途径获得协议的详细描述。
|
||||
|
||||
### [VLESS 协议](./protocols/vless.md)
|
||||
|
||||
VLESS 是一个无状态的轻量传输协议,可以作为 Xray 客户端和服务器之间的桥梁。
|
||||
|
||||
### [VMess 协议](./protocols/vmess.md)
|
||||
|
||||
VMess 是一个加密传输协议,可以作为 Xray 客户端和服务器之间的桥梁。
|
||||
|
||||
### [Mux.Cool 协议](./protocols/muxcool.md)
|
||||
|
||||
Mux.Cool 协议是一个多路复用传输协议,用于在一条已建立的数据流中传输多个各自独立的数据流。
|
||||
|
||||
### [mKCP 协议](./protocols/mkcp.md)
|
||||
|
||||
mKCP 是流式传输协议,由 [KCP 协议](https://github.com/skywind3000/kcp)修改而来,可以按顺序传输任意的数据流。
|
|
@ -0,0 +1,81 @@
|
|||
# 编译文档
|
||||
|
||||
## 前序工作
|
||||
|
||||
Xray 使用 [Golang](https://golang.org/) 作为编程语言,你需要先安装最新版本 Golang 才能够编译。
|
||||
|
||||
::: tip TIP
|
||||
安装 Golang: [golang.org/doc/install](https://golang.org/doc/install)
|
||||
:::
|
||||
|
||||
> 如果你不幸使用 Windows, 请 **务必** 使用 Powershell
|
||||
|
||||
## 拉取 Xray 源代码
|
||||
|
||||
```bash
|
||||
git clone https://github.com/XTLS/Xray-core.git
|
||||
cd Xray-core && go mod download
|
||||
```
|
||||
|
||||
> 如果你闲的没事干,可以试试 GitHub 官方工具: `gh repo clone XTLS/Xray-core`
|
||||
|
||||
注意:在无法正常访问 Google 的网络环境,依赖无法被正常拉取,需要先设置 `GOPROXY`:
|
||||
|
||||
```bash
|
||||
go env -w GOPROXY=https://goproxy.io,direct
|
||||
```
|
||||
|
||||
## 构建二进制
|
||||
|
||||
:::warning
|
||||
本小节的命令需要在 Xray 根目录内运行。
|
||||
:::
|
||||
|
||||
### Windows(Powershell):
|
||||
|
||||
```powershell
|
||||
$env:CGO_ENABLED=0
|
||||
go build -o xray.exe -trimpath -ldflags "-s -w -buildid=" ./main
|
||||
```
|
||||
|
||||
### macOS, Linux:
|
||||
|
||||
```bash
|
||||
CGO_ENABLED=0 go build -o xray -trimpath -ldflags "-s -w -buildid=" ./main
|
||||
```
|
||||
|
||||
运行以上命令会在目录下生成 xray 可执行文件。
|
||||
|
||||
::: tip
|
||||
如果需要编译可以进行 debug 的程序,即可以用 dlv 附加到运行的程序进行调试, 请去掉 ldflags 中的 '-w -s' 选项.
|
||||
|
||||
-w 禁止生成 debug 信息。使用该选项后,将无法使用 gdb 进行调试。
|
||||
-s 禁用符号表
|
||||
PS:其实用 vscode 或其他 IDE 调试似乎更方便。
|
||||
:::
|
||||
|
||||
## 交叉编译:
|
||||
|
||||
这里以在 Windows(Powershell) 环境中,编译到 Linux 服务器为例:
|
||||
|
||||
```powershell
|
||||
$env:CGO_ENABLED=0
|
||||
$env:GOOS="linux"
|
||||
$env:GOARCH="amd64"
|
||||
|
||||
go build -o xray -trimpath -ldflags "-s -w -buildid=" ./main
|
||||
```
|
||||
|
||||
上传到服务器后,记得在服务器终端内执行 `chmod +x xray`
|
||||
|
||||
::: tip
|
||||
执行 `go tool dist list` 查看所有支持的系统与架构。
|
||||
:::
|
||||
|
||||
## 可复现构建:
|
||||
|
||||
按照上述步骤,能够编译与 Release 中完全相同的二进制文件。
|
||||
|
||||
::: warning
|
||||
请先确认您使用的 Golang 版本与编译 Release 的一致。
|
||||
:::
|
|
@ -0,0 +1,43 @@
|
|||
# 设计目标
|
||||
|
||||
- Xray 内核提供了一个平台,支持必要的网络代理功能,在其之上可以进二次开发,以提供更好的用户体验;
|
||||
- 以跨平台为首要原则,以减少二次开发的成本;
|
||||
|
||||
## 架构
|
||||
|
||||

|
||||
|
||||
内核分为三层:应用层、代理层和传输层。
|
||||
|
||||
每一层内包含数个模块,模块间互相独立,同类型的模块可无缝替换。
|
||||
|
||||
### 应用层
|
||||
|
||||
应用层包含一些代理层中常用的功能,这些功能被抽象出来,以便在不同的代理模块中复用。
|
||||
|
||||
应用层的模块应为纯软件实现,与硬件或平台相关的技术无关。
|
||||
|
||||
重要模块列表:
|
||||
|
||||
- Dispatcher: 用于把入站代理所接收到的数据,传送给出站代理;
|
||||
- Router: 路由模块,详见 [路由配置](../../config/routing.md);
|
||||
- DNS: 内置的 DNS 服务器模块;
|
||||
- Proxy Manager: 代理管理器;
|
||||
|
||||
### 代理层
|
||||
|
||||
代理层分为两部分:入站代理(Inbound Proxy)和出站代理(Outbound Proxy)。
|
||||
|
||||
两部分相互独立,入站代理不依赖于某个特定的出站代理,反之亦然。
|
||||
|
||||
#### 入站代理
|
||||
|
||||
- 实现 [proxy.Inbound](https://github.com/xtls/Xray-core/blob/main/proxy/proxy.go) 接口;
|
||||
|
||||
#### 出站代理
|
||||
|
||||
- 实现 [proxy.Outbound](https://github.com/xtls/Xray-core/blob/main/proxy/proxy.go) 接口;
|
||||
|
||||
### 传输层
|
||||
|
||||
传输层提供一些网络数据传输相关的工具模块。
|
Binary file not shown.
After Width: | Height: | Size: 66 KiB |
|
@ -0,0 +1,131 @@
|
|||
# 开发规范
|
||||
|
||||
## 基本
|
||||
|
||||
### 版本控制
|
||||
|
||||
Project X 的代码被托管在 github 上:
|
||||
|
||||
- Xray 核心 [Xray-core](https://github.com/XTLS/Xray-core)
|
||||
- 安装脚本 [Xray-install](https://github.com/XTLS/Xray-install)
|
||||
- 配置模板 [Xray-examples](https://github.com/XTLS/Xray-examples)
|
||||
- Xray 文档 [Xray-docs-next](https://github.com/XTLS/Xray-docs-next)
|
||||
|
||||
您可以使用 [Git](https://git-scm.com/) 来获取代码。
|
||||
|
||||
### 分支(Branch)
|
||||
|
||||
- 本项目的主干分支为 main,
|
||||
- 本项目的发布主分支同为 main,
|
||||
- 需要确保 main 在任一时刻都是可编译,且可正常使用的。
|
||||
- 如果需要开发新的功能,请新建分支进行开发,在开发完成并且经过充分测试后,合并回主干分支。
|
||||
- 已经合并入主干且没有必要存在的分支,请删除。
|
||||
|
||||
### 发布(Release)
|
||||
|
||||
<Badge text="WIP" type="warning"/>
|
||||
|
||||
- 建立尝鲜版本和稳定版本两个发布通道
|
||||
- 尝鲜版本,可以为 daily build,主要用于特定情况的测试,尝鲜和获得即时反馈和再改进。
|
||||
- 稳定版本,为定时更新(比如月更),合并稳定的修改并发布。
|
||||
|
||||
### 引用其它项目
|
||||
|
||||
- Golang
|
||||
- 产品代码建议使用 Golang 标准库和 [golang.org/x/](https://pkg.go.dev/search?limit=25&m=package&q=golang.org%2Fx) 下的库;
|
||||
- 如需引用其它项目,请事先创建 issue 讨论;
|
||||
- 其它
|
||||
- 不违反双方的协议,且对项目有帮助的工具,都可以使用。
|
||||
|
||||
## 开发流程
|
||||
|
||||
### 写代码之前
|
||||
|
||||
发现任何问题,或对项目有任何想法,请创建 [issue](https://github.com/XTLS/Xray-core/issues) 讨论以减少重复劳动和消耗在代码上的时间。
|
||||
|
||||
### 修改代码
|
||||
|
||||
- Golang
|
||||
- 请参考 [Effective Go](https://golang.org/doc/effective_go.html);
|
||||
- 每一次 push 之前,请运行:`go generate core/format.go`;
|
||||
- 如果需要修改 protobuf,例如增加新配置项,请运行:`go generate core/proto.go`;
|
||||
- 提交 pull request 之前,建议测试通过:`go test ./...`;
|
||||
- 提交 pull request 之前,建议新增代码有超过 70% 的代码覆盖率(code coverage);
|
||||
- 其它
|
||||
- 请注意代码的可读性。
|
||||
|
||||
### Pull Request
|
||||
|
||||
- 提交 PR 之前,请先运行 `git pull https://github.com/XTLS/Xray-core.git` 以确保 merge 可顺利进行;
|
||||
- 一个 PR 只做一件事,如有对多个 bug 的修复,请对每一个 bug 提交一个 PR;
|
||||
- 由于 Golang 的特殊需求(Package path),Go 项目的 PR 流程和其它项目有所不同,建议流程如下:
|
||||
1. 先 Fork 本项目,创建你自己的 `github.com/<your_name>/Xray-core.git` 仓库;
|
||||
2. 克隆你自己的 Xray 仓库到本地:`git clone https://github.com/<your_name>/Xray-core.git`;
|
||||
3. 基于 `main` 分支创建新的分支,例如 `git branch issue24 main`;
|
||||
4. 在新创建的分支上作修改并提交修改(commit);
|
||||
5. 在推送(push)修改完成的分支到自己的仓库前,先切换到 `main` 分支,运行 `git pull https://github.com/XTLS/Xray-core.git` 拉取最新的远端代码;
|
||||
6. 如果上一步拉取得到了新的远端代码,则切换到之前自己创建的分支,运行 `git rebase main` 执行分支合并操作。如遇到文件冲突,则需要解决冲突;
|
||||
7. 上一步处理完毕后,就可以把自己创建的分支推送到自己的仓库:`git push -u origin your-branch`
|
||||
8. 最后,把自己仓库的新推送的分支往 `XTLS/Xray-core` 的 `main` 分支发 PR 即可;
|
||||
9. 请在 PR 的标题和正文中,完整表述此次 PR 解决的问题 / 新增的功能 / 代码所做的修改的用意等;
|
||||
10. 耐心等待开发者的回应。
|
||||
|
||||
### 对代码的修改
|
||||
|
||||
#### 功能性问题
|
||||
|
||||
请提交至少一个测试用例(Test Case)来验证对现有功能的改动。
|
||||
|
||||
#### 性能相关
|
||||
|
||||
请提交必要的测试数据来证明现有代码的性能缺陷,或是新增代码的性能提升。
|
||||
|
||||
#### 新功能
|
||||
|
||||
- 如果新增功能对已有功能不影响,请提供可以开启/关闭的开关(如 flag),并使新功能保持默认关闭的状态;
|
||||
- 大型新功能(比如增加一个新的协议)开发之前,请先提交一个 issue,讨论完毕之后再进行开发。
|
||||
|
||||
#### 其它
|
||||
|
||||
视具体情况而定。
|
||||
|
||||
## Xray 编码规范
|
||||
|
||||
以下内容适用于 Xray 中的 Golang 代码。
|
||||
|
||||
### 代码结构
|
||||
|
||||
```
|
||||
Xray-core
|
||||
├── app // 应用模块
|
||||
│ ├── router // 路由
|
||||
├── common // 公用代码
|
||||
├── proxy // 通讯协议
|
||||
│ ├── blackhole
|
||||
│ ├── dokodemo-door
|
||||
│ ├── freedom
|
||||
│ ├── socks
|
||||
│ ├── vmess
|
||||
├── transport // 传输模块
|
||||
```
|
||||
|
||||
### 编码规范
|
||||
|
||||
基本与 Golang 官方所推荐做法一致,有一些例外。写在这里以方便大家熟悉 Golang。
|
||||
|
||||
#### 命名
|
||||
|
||||
- 文件和目录名尽量使用单个英文单词,比如 hello.go;
|
||||
- 如果实在没办法,则目录使用连接线/文件名使用下划线连接两个(或多个单词),比如 hello-world/hello_again.go;
|
||||
- 测试代码使用 \_test.go 结尾;
|
||||
- 类型使用 Pascal 命名法,比如 ConnectionHandler;
|
||||
- 对缩写不强制小写,即 HTML 不必写成 Html;
|
||||
- 公开成员变量也使用 Pascal 命名法;
|
||||
- 私有成员变量使用 [小驼峰式命名法](https://zh.wikipedia.org/wiki/%E9%A7%9D%E5%B3%B0%E5%BC%8F%E5%A4%A7%E5%B0%8F%E5%AF%AB) ,如 `privateAttribute` ;
|
||||
- 为了方便重构,方法建议全部使用 Pascal 命名法;
|
||||
- 完全私有的类型放入 `internal` 。
|
||||
|
||||
#### 内容组织
|
||||
|
||||
- 一个文件包含一个主要类型,及其相关的私有函数等;
|
||||
- 测试相关的文件,如 Mock 等工具类,放入 testing 子目录。
|
|
@ -0,0 +1,92 @@
|
|||
# mKCP 协议
|
||||
|
||||
mKCP 是流式传输协议,由 [KCP 协议](https://github.com/skywind3000/kcp) 修改而来,可以按顺序传输任意的数据流。
|
||||
|
||||
## 版本
|
||||
|
||||
mKCP 没有版本号,不保证版本之间兼容性。
|
||||
|
||||
## 依赖
|
||||
|
||||
### 底层协议
|
||||
|
||||
mKCP 是一个基于 UDP 的协议,所有通讯使用 UDP 传输。
|
||||
|
||||
### 函数
|
||||
|
||||
- fnv: [FNV-1a](https://en.wikipedia.org/wiki/Fowler%E2%80%93Noll%E2%80%93Vo_hash_function) 哈希函数
|
||||
- 输入参数为任意长度的字符串;
|
||||
- 输入出一个 32 位无符号整数;
|
||||
|
||||
## 通讯过程
|
||||
|
||||
1. mKCP 将数据流拆成若干个数据包进行发送。一个数据流有一个唯一标识,用以区分不同的数据流。数据流中的每一个数据包都携带了同样的标识。
|
||||
1. mKCP 没有握手过程,当收到一个数据包时,根据其携带的数据流的标识来判断是否为新的通话,或是正在进行中的通话。
|
||||
1. 每一个数据包中包含若干个片段(Segment),片段分为三类:数据(Data)、确认(ACK)、心跳(Ping)。每个片段需要单独处理。
|
||||
|
||||
## 数据格式
|
||||
|
||||
### 数据包
|
||||
|
||||
| 4 字节 | 2 字节 | L 字节 |
|
||||
| ---------- | ---------- | -------- |
|
||||
| 认证信息 A | 数据长度 L | 片段部分 |
|
||||
|
||||
其中:
|
||||
|
||||
- 认证信息 A = fnv(片段部分),big endian;
|
||||
- 片段部分可能包含多个片段;
|
||||
|
||||
### 数据片段
|
||||
|
||||
| 2 字节 | 1 字节 | 1 字节 | 4 字节 | 4 字节 | 4 字节 | 2 字节 | Len 字节 |
|
||||
| --------- | -------- | -------- | --------- | --------- | ---------------- | -------- | -------- |
|
||||
| 标识 Conv | 指令 Cmd | 选项 Opt | 时间戳 Ts | 序列号 Sn | 未确认序列号 Una | 长度 Len | 数据 |
|
||||
|
||||
其中:
|
||||
|
||||
- 标识 Conv: mKCP 数据流的标识
|
||||
- 指令 Cmd: 常量 0x01
|
||||
- 选项 Opt: 可选的值有:
|
||||
- 0x00: 空选项
|
||||
- 0x01: 对方已发出所有数据
|
||||
- 时间戳 Ts: 当前片段从远端发送出来时的时间,big endian
|
||||
- 序列号 Sn: 该数据片段时数据流中的位置,起始片段的序列号为 0,之后每个新片段按顺序加 1
|
||||
- 未确认序列号 Una: 远端主机正在发送的,且尚未收到确认的最小的 Sn
|
||||
|
||||
### 确认片段
|
||||
|
||||
| 2 字节 | 1 字节 | 1 字节 | 4 字节 | 4 字节 | 4 字节 | 2 字节 | Len \* 4 字节 |
|
||||
| --------- | -------- | -------- | -------- | ----------------- | --------- | -------- | -------------- |
|
||||
| 标识 Conv | 指令 Cmd | 选项 Opt | 窗口 Wnd | 下一接收序列号 Sn | 时间戳 Ts | 长度 Len | 已收到的序列号 |
|
||||
|
||||
其中:
|
||||
|
||||
- 标识 Conv: mKCP 数据流的标识
|
||||
- 指令 Cmd: 常量 0x00
|
||||
- 选项 Opt: 同上
|
||||
- 窗口 Wnd: 远端主机可以接收的最大序列号
|
||||
- 下一接收序列号 Sn: 远端主机未收到的数据片段中的最小序列号
|
||||
- 时间戳 Ts: 远端主机最新收到的数据片段的时间戳,可用于计算延迟
|
||||
- 已收到的序列号: 每个 4 字节,表示此序列号的数据已经确认收到
|
||||
|
||||
注释:
|
||||
|
||||
- 远程主机期待收到序列号 [Sn, Wnd) 范围内的数据
|
||||
|
||||
### 心跳片段
|
||||
|
||||
| 2 字节 | 1 字节 | 1 字节 | 4 字节 | 4 字节 | 4 字节 |
|
||||
| --------- | -------- | -------- | ---------------- | ----------------- | -------- |
|
||||
| 标识 Conv | 指令 Cmd | 选项 Opt | 未确认序列号 Una | 下一接收序列号 Sn | 延迟 Rto |
|
||||
|
||||
其中:
|
||||
|
||||
- 标识 Conv: mKCP 数据流的标识
|
||||
- 指令 Cmd: 可选的值有
|
||||
- 0x02: 远端主机强行终止会话
|
||||
- 0x03: 正常心跳
|
||||
- 选项 Opt: 同上
|
||||
- 未确认序列号 Una: 同数据片段的 Una
|
||||
- 下一接收序列号 Sn: 同确认片段的 Sn
|
||||
- 延迟 Rto: 远端主机自己计算出的延迟
|
|
@ -0,0 +1,129 @@
|
|||
# Mux.Cool 协议
|
||||
|
||||
Mux.Cool 协议是一个多路复用传输协议,用于在一条已建立的数据流中传输多个各自独立的数据流。
|
||||
|
||||
## 版本
|
||||
|
||||
当前版本是 1 Beta。
|
||||
|
||||
## 依赖
|
||||
|
||||
### 底层协议
|
||||
|
||||
Mux.Cool 必须运行在一个已建立的可靠数据流之上。
|
||||
|
||||
## 通讯过程
|
||||
|
||||
一个 Mux.Cool 连接中可传输若干个子连接,每个子连接有一个独立的 ID 和状态。传输过程由帧(Frame)组成,每一帧用于传输一个特定的子连接的数据。
|
||||
|
||||
### 客户端行为
|
||||
|
||||
当有连接需求时并且没有现有可用的连接时,客户端向服务器发起一个新连接,以下称为“主连接”。
|
||||
|
||||
1. 一个主连接可用于发送若干个子连接。客户端可自主决定主连接可承载的子连接数量。
|
||||
1. 对于一个新的子连接,客户端必须发送状态`New`以通知服务器建立子连接,然后使用状态`Keep`来传送数据。
|
||||
1. 当子连接结束时,客户端发送`End`状态来通知服务器关闭子连接。
|
||||
1. 客户端可自行决定何时关闭主连接,但必须确定服务器也同时保持连接。
|
||||
1. 客户端可使用 KeepAlive 状态来避免服务器关闭主连接。
|
||||
|
||||
### 服务器端行为
|
||||
|
||||
当服务器端接收到新的子连接时,服务器应当按正常的连接来处理。
|
||||
|
||||
1. 当收到状态`End`时,服务器端可以关闭对目标地址的上行连接。
|
||||
1. 在服务器的响应中,必须使用与请求相同的 ID 来传输子连接的数据。
|
||||
1. 服务器不能使用`New`状态。
|
||||
1. 服务器可使用 KeepAlive 状态来避免客户端关闭主连接。
|
||||
|
||||
## 传输格式
|
||||
|
||||
Mux.Cool 使用对称传输格式,即客户端和服务器发送和接收相同格式的数据。
|
||||
|
||||
### 帧格式
|
||||
|
||||
| 2 字节 | L 字节 | X 字节 |
|
||||
| ------------ | ------ | -------- |
|
||||
| 元数据长度 L | 元数据 | 额外数据 |
|
||||
|
||||
### 元数据
|
||||
|
||||
元数据有若干种类型。所有类型的元数据都包含 ID 和 Opt 两项,其含义为:
|
||||
|
||||
- ID: 子连接的唯一标识
|
||||
- 对于一般 Mux 子连接,ID 由 1 开始累加
|
||||
- 对于 Xray 实现的 [Single XUDP](https://github.com/XTLS/Xray-core/blob/main/common/xudp/xudp.go),ID 始终为 0
|
||||
- Opt:
|
||||
- D(0x01): 有额外数据
|
||||
|
||||
当选项 Opt(D) 开启时,额外数据格式如下:
|
||||
|
||||
| 2 字节 | X-2 字节 |
|
||||
| -------- | -------- |
|
||||
| 长度 X-2 | 数据 |
|
||||
|
||||
### 新建子连接 (New)
|
||||
|
||||
| 2 字节 | 1 字节 | 1 字节 | 1 字节 | 2 字节 | 1 字节 | A 字节 | 8 字节 |
|
||||
| ------ | ------ | -------- | ---------- | ------ | ---------- | ------ | ---------------- |
|
||||
| ID | 0x01 | 选项 Opt | 网络类型 N | 端口 | 地址类型 T | 地址 A | Global ID (XUDP) |
|
||||
|
||||
其中:
|
||||
|
||||
- 网络类型 N:
|
||||
- 0x01:TCP,表示当前子连接的流量应当以 TCP 的方式发送至目标。
|
||||
- 0x02:UDP,表示当前子连接的流量应当以 UDP 的方式发送至目标。
|
||||
- 地址类型 T:
|
||||
- 0x01:IPv4
|
||||
- 0x02:域名
|
||||
- 0x03:IPv6
|
||||
- 地址 A:
|
||||
- 当 T = 0x01 时,A 为 4 字节 IPv4 地址;
|
||||
- 当 T = 0x02 时,A 为 1 字节长度(L) + L 字节域名;
|
||||
- 当 T = 0x03 时,A 为 16 字节 IPv6 地址;
|
||||
- Global ID (XUDP):
|
||||
- 客户端计算出 UDP 来源二元组的全局独特 ID,服务端用以确保当 XUDP 断线重连时,仍使用同一个端口与目标通信。
|
||||
|
||||
在新建子连接时,若 Opt(D) 开启,则这一帧所带的数据需要被发往目标主机。
|
||||
|
||||
### 保持子连接 (Keep)
|
||||
|
||||
TCP
|
||||
|
||||
| 2 字节 | 1 字节 | 1 字节 |
|
||||
| ------ | ------ | -------- |
|
||||
| ID | 0x02 | 选项 Opt |
|
||||
|
||||
UDP
|
||||
|
||||
| 2 字节 | 1 字节 | 1 字节 | 1 字节 | 2 字节 | 1 字节 | A 字节 |
|
||||
| ------ | ------ | -------- | ---------- | ------ | ---------- | ------ |
|
||||
| ID | 0x02 | 选项 Opt | 网络类型 N | 端口 | 地址类型 T | 地址 A |
|
||||
|
||||
在保持子连接时,若 Opt(D) 开启,则这一帧所带的数据需要被发往目标主机。
|
||||
XUDP 在 Opt(D) 之后加 UDP 地址,格式同新建子连接,但没有 Global ID。
|
||||
|
||||
### 关闭子连接 (End)
|
||||
|
||||
| 2 字节 | 1 字节 | 1 字节 |
|
||||
| ------ | ------ | -------- |
|
||||
| ID | 0x03 | 选项 Opt |
|
||||
|
||||
在保持子连接时,若 Opt(D) 开启,则这一帧所带的数据需要被发往目标主机。
|
||||
|
||||
### 保持连接 (KeepAlive)
|
||||
|
||||
| 2 字节 | 1 字节 | 1 字节 |
|
||||
| ------ | ------ | -------- |
|
||||
| ID | 0x04 | 选项 Opt |
|
||||
|
||||
在保持连接时:
|
||||
|
||||
- 若 Opt(D) 开启,则这一帧所带的数据必须被丢弃。
|
||||
- ID 可为随机值。
|
||||
|
||||
## 应用
|
||||
|
||||
Mux.Cool 协议与底层协议无关,理论上可以使用任何可靠的流式连接来传输 Mux.Cool 的协议数据。
|
||||
|
||||
在目标导向的协议如 Shadowsocks 和 VMess 协议中,连接建立时必须包含一个指定的地址。
|
||||
为了保持兼容性,Mux.Cool 协议指定地址为“v1.mux.cool”。即当主连接的目标地址与之匹配时,则进行 Mux.Cool 方式的转发,否则按传统方式进行转发。(注:这是一个程序内的标记,VMess 和 VLESS 并不会在数据包中发送“v1.mux.cool”地址)
|
|
@ -0,0 +1,91 @@
|
|||
# VLESS 协议
|
||||
|
||||
VLESS 是一个无状态的轻量传输协议,可以作为 Xray 客户端和服务器之间的桥梁。
|
||||
|
||||
## Request & Response
|
||||
|
||||
| 1 字节 | 16 字节 | 1 字节 | M 字节 | 1 字节 | 2 字节 | 1 字节 | S 字节 | X 字节 |
|
||||
| -------- | --------- | -------------- | ----------------- | ------ | ------ | -------- | ------ | -------- |
|
||||
| 协议版本 | 等价 UUID | 附加信息长度 M | 附加信息 ProtoBuf | 指令 | 端口 | 地址类型 | 地址 | 请求数据 |
|
||||
|
||||
| 1 字节 | 1 字节 | N 字节 | Y 字节 |
|
||||
| ---------------------- | -------------- | ----------------- | -------- |
|
||||
| 协议版本,与请求的一致 | 附加信息长度 N | 附加信息 ProtoBuf | 响应数据 |
|
||||
|
||||
VLESS 早在第二个测试版 ALPHA 2 时就已经是上述结构了(BETA 是第五个测试版):
|
||||
|
||||
> “响应认证”被替换为“协议版本”并移至最前,使 VLESS 可以升级换代,同时消除了生成伪随机数的开销。混淆相关结构被替换为附加信息(ProtoBuf)并前移,赋予协议本身可扩展性,相关开销也极小([gogo/protobuf](https://github.com/gogo/protobuf)),若无附加信息则无相关开销。
|
||||
|
||||
我一直觉得“响应认证”不是必要的,ALPHA 时为了提升生成随机数的性能,还用 math/rand 替换 crypto/rand,而现在都不需要了。
|
||||
|
||||
“协议版本”不仅能起到“响应认证”的作用,还赋予了 VLESS 无痛升级协议结构的能力,带来无限的可能性。
|
||||
“协议版本”在测试版本中均为 0,正式版本中为 1,以后若有不兼容的协议结构变更则应升级版本。
|
||||
|
||||
VLESS 服务端的设计是 switch version,即同时支持所有 VLESS 版本。若需要升级协议版本(可能到不了这一步),推荐的做法是服务端提前一个月支持,一个月后再改客户端。VMess 请求也有协议版本,但它的认证信息在外面,指令部分则高度耦合且有固定加密,导致里面的协议版本毫无意义,服务端也没有进行判断,响应则没有协议版本。Trojan 的协议结构中没有协议版本。
|
||||
|
||||
接下来是 UUID,我本来觉得 16 字节有点长,曾经考虑过缩短它,但后来看到 Trojan 用了 56 个可打印字符(56 字节),就彻底打消了这个念头。服务端每次都要验证 UUID,所以性能也很重要:VLESS 的 Validator 经历了多次重构/升级,相较于 VMess,它十分简洁且耗资源很少,可以同时支持非常多的用户,性能也十分强悍,验证速度极快(sync.Map)。API 动态增删用户则更高效顺滑。
|
||||
https://github.com/XTLS/Xray-core/issues/158
|
||||
|
||||
引入 ProtoBuf 是一个创举,等下会详细讲解。“指令”到“地址”的结构目前与 VMess 完全相同,同样支持 Mux。
|
||||
|
||||
总体上,ALPHA 2 到 BETA 主要是:结构进化、清理整合、性能提升、更加完善。这些都是一点一滴的,详见 [VLESS Changes](https://github.com/rprx/v2ray-vless/releases)。
|
||||
|
||||
## ProtoBuf
|
||||
|
||||
似乎只有 VLESS 可选内嵌 ProtoBuf,它是一种数据交换格式,信息被紧密编码成二进制,TLV 结构(Tag Length Value)。
|
||||
|
||||
起因是我看到一篇文章称 SS 有一些缺点,如没有设计错误回报机制,客户端没办法根据不同的错误采取进一步的动作。
|
||||
(但我并不认同所有错误都要回报,不然防不了主动探测。下一个测试版中,服务器可以返回一串自定义信息。)
|
||||
于是想到一个可扩展的结构是很重要的,未来它也可以承载如动态端口指令。不止响应,请求也需要类似的结构。
|
||||
本来打算自己设计 TLV,接着发觉 ProtoBuf 就是此结构、现成的轮子,完全适合用来做这件事,各语言支持等也不错。
|
||||
|
||||
目前“附加信息”只有 Scheduler 和 SchedulerV,它们是 MessName 和 MessSeed 的替代者,**当你不需要它们时,“附加信息长度”为 0,也就不会有 ProtoBuf 序列化/反序列化的开销**。其实我更愿意称这个过程为“拼接”,因为 pb 实际原理上也只是这么做而已,相关开销极小。拼接后的 bytes 十分紧凑,和 ALPHA 的方案相差无几,有兴趣的可以分别输出并对比。
|
||||
|
||||
为了指示对附加信息(Addons,也可以理解成插件,以后可以有很多个插件)的不同支持程度,下个测试版会在“附加信息长度”前新增“附加信息版本”。256 - 1 = 255 字节是够用且合理的(65535 就太多了,还可能有人恶意填充),现有的只用了十分之一,以后也不会同时有那么多附加信息,且大多数情况下是完全没有附加信息的。真不够用的话,可以升级 VLESS 版本。
|
||||
|
||||
为了减少逻辑判断等开销,暂定 Addons 不使用多级结构。一个月前出现过“可变协议格式”的想法,pb 是可以做到打乱顺序,但没必要,因为现代加密的设计不会让旁观者看出两次传输的头部相同。
|
||||
|
||||
下面介绍 Schedulers 和 Encryption 的构想,**它们都是可选的**,一个应对流量时序特征问题,一个应对密码学上的问题。
|
||||
|
||||
## ~~Schedulers~~ Flow
|
||||
|
||||
~~中文名暂称:流量调度器~~(2020-09-03 更新:中文名确定为“流控”),指令由 ProtoBuf 承载,控制的是数据部分。
|
||||
|
||||
我之前发现,VMess 原有的 shake “元数据混淆”在 TLS 上完全不会带来有意义的改变,只会降低性能,所以 VLESS 弃用了它。并且,“混淆”这个表述容易被误解成伪装,也弃用了。顺便一提,我一直是不看好伪装的:做不到完全一样,那不就是强特征吗?做得到完全一样,那为什么不直接用伪装目标?我一开始用的是 SSR,后来发现它只是表面伪装骗运营商,就再也没用过了。
|
||||
|
||||
那么,“流量调度器”要解决什么问题?它影响的是宏观流量时序特征,而不是微观特征,后者是加密要解决的事情。流量时序特征可以是协议带来的,比如 Socks5 over TLS 时的 Socks5 握手 ,TLS 上不同的这种特征对于监测者来说就是不同的协议,此时无限 Schedulers 就相当于无限协议(重新分配每次发送的数据量大小等)。流量时序特征也可以是行为带来的,比如访问 Google 首页时加载了多少文件、顺序、每个文件的大小,多套一层加密并不能有效掩盖这些信息。
|
||||
|
||||
Schedulers 没必要像下面的 Encryption 一样整个套在外面,因为头部的一丁点数据相对于后面的数据量来说太微不足道了。
|
||||
|
||||
BETA 2 预计推出两个初级的 Scheduler:Zstd 压缩、数据量动态扩充。进阶操作才是从宏观层面来控制、分配,暂时咕咕。
|
||||
|
||||
## Encryption
|
||||
|
||||
与 VMess 的高度耦合不同,VLESS 的服务端、客户端不久后可以提前约定好加密方式,仅在外面套一层加密。这有点类似于使用 TLS,不影响承载的任何数据,也可以理解成底层就是从 TLS 换成预设约定加密。相对于高度耦合,这种方式更合理且灵活:一种加密方式出了安全性问题,直接扔掉并换用其它的就行了,十分方便。VLESS 服务端还会允许不同的加密方式共存。
|
||||
|
||||
对比 VMess,VLESS 相当于把 security 换成 encryption,把 disableInsecureEncryption 换成 decryption,就解决了所有问题。目前 encryption 和 decryption 只接受 \"none\" 且不能留空(即使以后有连接安全性检查),详见 [VLESS 配置文档](https://github.com/rprx/v2fly-github-io/blob/master/docs/config/protocols/vless.md)。encryption 并不需要往外移一级,一是因为无法复用很多代码,二是因为会影响控制粒度,看未来的应用就明白了。
|
||||
|
||||
加密支持两类形式,一类是加密完全独立,需要额外密码,适合私用,另一类是结合已有的 UUID 来加密,适合公用。
|
||||
(若用第一类加密形式,且密码是以某种形式公开的,比如多人共用,那么中间人攻击就不远了)
|
||||
重新设计的动态端口可能会随加密同时推出,指令由 ProtoBuf 承载,具体实现和 VMess 的动态端口也会有很多不同。
|
||||
|
||||
套现成加密是件很简单的事情,也就多一层 writer & reader。BETA 3 预计支持 SS 的 aes-128-gcm 和 chacha20-ietf-poly1305:
|
||||
客户端的 encryption 可以填 “auto: ss_aes-128-gcm_0_123456, ss_chacha20-ietf-poly1305_0_987654”,auto 会选择最适合当前机器的,0 代表测试版,最后的是密码。服务端的 decryption 也是类似填法,收到请求时会逐一尝试解密。
|
||||
|
||||
并不是所有组合都需逐一尝试:VMess 的加密分为三段,第一段是认证信息,结合了 UUID、alterId、时间因素,第二段是指令部分,以固定算法加密,指令中含有数据部分使用的加密算法,第三段才是重要的数据部分。可以看出,VMess 的加解密方式实际上是多对一(服务端适配),而不仅是结合 UUID。但仅是结合 UUID 来加密也是件相对麻烦的事情,短时间内不会出,鉴于我们现在有 VMessAEAD 可用,也并不着急。若 VLESS 推出了结合 UUID 的加密方式,相当于重构了整个 VMess。
|
||||
|
||||
## UDP issues
|
||||
|
||||
[XUDP:VLESS & VMess & Mux UDP FullCone NAT](https://github.com/XTLS/Xray-core/discussions/252)
|
||||
|
||||
## 客户端开发指引
|
||||
|
||||
1. VLESS 协议本身还会有不兼容升级,但客户端配置文件参数基本上是只增不减的。iOS 客户端的协议实现则需紧跟升级。
|
||||
2. **视觉标准:UI 标识请统一用 VLESS**,而不是 VLess / Vless / vless,配置文件不受影响,代码内则顺其自然。
|
||||
3. `encryption` 应做成输入框而不是选择框,新配置的默认值应为 `none`,若用户置空则应代填 `none`。
|
||||
|
||||
## VLESS 分享链接标准
|
||||
|
||||
感谢 <img src="https://avatars2.githubusercontent.com/u/7822648?s=32" width="32px" height="32px" alt="a"/> [@DuckSoft](https://github.com/DuckSoft) 的提案!
|
||||
|
||||
详情请见 [VMessAEAD / VLESS 分享链接标准提案](https://github.com/XTLS/Xray-core/issues/91)
|
|
@ -0,0 +1,175 @@
|
|||
# VMess 协议
|
||||
|
||||
VMess 是一个加密传输协议,可以作为 Xray 客户端和服务器之间的桥梁。
|
||||
|
||||
## 版本
|
||||
|
||||
当前版本号为 1。
|
||||
|
||||
## 依赖
|
||||
|
||||
### 底层协议
|
||||
|
||||
VMess 是一个基于 TCP 的协议,所有数据使用 TCP 传输。
|
||||
|
||||
### 用户 ID
|
||||
|
||||
ID 等价于 [UUID](https://en.wikipedia.org/wiki/Universally_unique_identifier),是一个 16 字节长的随机数,它的作用相当于一个令牌(Token)。
|
||||
一个 ID 形如:de305d54-75b4-431b-adb2-eb6b9e546014,几乎完全随机,可以使用任何的 UUID 生成器来生成,比如[这个](https://www.uuidgenerator.net/)。
|
||||
|
||||
用户 ID 可在[配置文件](../../config)中指定。
|
||||
|
||||
### 函数
|
||||
|
||||
- MD5: [MD5 函数](https://en.wikipedia.org/wiki/MD5)
|
||||
- 输入参数为任意长度的 byte 数组
|
||||
- 输出为一个 16 byte 的数组
|
||||
- HMAC: [HMAC 函数](https://en.wikipedia.org/wiki/Hash-based_message_authentication_code)
|
||||
- 输入参数为:
|
||||
- H:散列函数
|
||||
- K:密钥,任意长度的 byte 数组
|
||||
- M:消息,任意长度的 byte 数组
|
||||
- Shake: [SHA3-Shake128 函数](https://en.wikipedia.org/wiki/SHA-3)
|
||||
- 输入参数为任意长度的字符串
|
||||
- 输出为任意长度的字符串
|
||||
|
||||
## 通讯过程
|
||||
|
||||
VMess 是一个无状态协议,即客户端和服务器之间不需要握手即可直接传输数据,每一次数据传输对之前和之后的其它数据传输没有影响。
|
||||
|
||||
VMess 的客户端发起一次请求,服务器判断该请求是否来自一个合法的客户端。如验证通过,则转发该请求,并把获得的响应发回给客户端。
|
||||
|
||||
VMess 使用非对称格式,即客户端发出的请求和服务器端的响应使用了不同的格式。
|
||||
|
||||
## 客户端请求
|
||||
|
||||
| 16 字节 | X 字节 | 余下部分 |
|
||||
| -------- | -------- | -------- |
|
||||
| 认证信息 | 指令部分 | 数据部分 |
|
||||
|
||||
### 认证信息
|
||||
|
||||
认证信息是一个 16 字节的哈希(hash)值,它的计算方式如下:
|
||||
|
||||
- H = MD5
|
||||
- K = 用户 ID (16 字节)
|
||||
- M = UTC 时间,精确到秒,取值为当前时间的前后 30 秒随机值(8 字节, Big Endian)
|
||||
- Hash = HMAC(H, K, M)
|
||||
|
||||
### 指令部分
|
||||
|
||||
指令部分经过 AES-128-CFB 加密:
|
||||
|
||||
- Key:MD5(用户 ID + []byte('c48619fe-8f02-49e0-b9e9-edf763e17e21'))
|
||||
- IV:MD5(X + X + X + X),X = []byte(认证信息生成的时间) (8 字节, Big Endian)
|
||||
|
||||
| 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 |
|
||||
|
||||
选项 Opt 细节:(当某一位为 1 时,表示该选项启用)
|
||||
|
||||
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
|
||||
| :-: | :-: | :-: | :-: | :-: | :-: | :-: | :-: |
|
||||
| X | X | X | X | X | M | R | S |
|
||||
|
||||
其中:
|
||||
|
||||
- 版本号 Ver:始终为 1;
|
||||
- 数据加密 IV:随机值;
|
||||
- 数据加密 Key:随机值;
|
||||
- 响应认证 V:随机值;
|
||||
- 选项 Opt:
|
||||
- S (0x01):标准格式的数据流(建议开启);
|
||||
- R (0x02):客户端期待重用 TCP 连接(Xray 2.23+ 弃用);
|
||||
- 只有当 S 开启时,这一项才有效;
|
||||
- M (0x04):开启元数据混淆(建议开启);
|
||||
- 只有当 S 开启时,这一项才有效;
|
||||
- 当其项开启时,客户端和服务器端需要分别构造两个 Shake 实例,分别为 RequestMask = Shake(请求数据 IV), ResponseMask = Shake(响应数据 IV)。
|
||||
- X:保留
|
||||
- 余量 P:在校验值之前加入 P 字节的随机值;
|
||||
- 加密方式:指定数据部分的加密方式,可选的值有:
|
||||
- 0x00:AES-128-CFB;
|
||||
- 0x01:不加密;
|
||||
- 0x02:AES-128-GCM;
|
||||
- 0x03:ChaCha20-Poly1305;
|
||||
- 指令 Cmd:
|
||||
- 0x01:TCP 数据;
|
||||
- 0x02:UDP 数据;
|
||||
- 端口 Port:Big Endian 格式的整型端口号;
|
||||
- 地址类型 T:
|
||||
- 0x01:IPv4
|
||||
- 0x02:域名
|
||||
- 0x03:IPv6
|
||||
- 地址 A:
|
||||
- 当 T = 0x01 时,A 为 4 字节 IPv4 地址;
|
||||
- 当 T = 0x02 时,A 为 1 字节长度(L) + L 字节域名;
|
||||
- 当 T = 0x03 时,A 为 16 字节 IPv6 地址;
|
||||
- 校验 F:指令部分除 F 外所有内容的 FNV1a hash;
|
||||
|
||||
### 数据部分
|
||||
|
||||
当 Opt(S) 开启时,数据部分使用此格式。实际的请求数据被分割为若干个小块,每个小块的格式如下。服务器校验完所有的小块之后,再按基本格式的方式进行转发。
|
||||
|
||||
| 2 字节 | L 字节 |
|
||||
| :----: | :----: |
|
||||
| 长度 L | 数据包 |
|
||||
|
||||
其中:
|
||||
|
||||
- 长度 L:Big Endian 格式的整型,最大值为 2^14;
|
||||
- 当 Opt(M) 开启时,L 的值 = 真实值 xor Mask。Mask = (RequestMask.NextByte() << 8) + RequestMask.NextByte();
|
||||
- 数据包:由指定的加密方式加密过的数据包;
|
||||
|
||||
在传输结束之前,数据包中必须有实际数据,即除了长度和认证数据之外的数据。当传输结束时,客户端必须发送一个空的数据包,即 L = 0(不加密) 或认证数据长度(有加密),来表示传输结束。
|
||||
|
||||
按加密方式不同,数据包的格式如下:
|
||||
|
||||
- 不加密:
|
||||
- L 字节:实际数据;
|
||||
- AES-128-CFB:整个数据部分使用 AES-128-CFB 加密
|
||||
- 4 字节:实际数据的 FNV1a hash;
|
||||
- L - 4 字节:实际数据;
|
||||
- AES-128-GCM:Key 为指令部分的 Key,IV = count (2 字节) + IV (10 字节)。count 从 0 开始递增,每个数据包加 1;IV 为 指令部分 IV 的第 3 至第 12 字节。
|
||||
- L - 16 字节:实际数据;
|
||||
- 16 字节:GCM 认证信息
|
||||
- ChaCha20-Poly1305:Key = MD5(指令部分 Key) + MD5(MD5(指令部分 Key)),IV = count (2 字节) + IV (10 字节)。count 从 0 开始递增,每个数据包加 1;IV 为 指令部分 IV 的第 3 至第 12 字节。
|
||||
- L - 16 字节:实际数据;
|
||||
- 16 字节:Poly1305 认证信息
|
||||
|
||||
## 服务器应答
|
||||
|
||||
应答头部数据使用 AES-128-CFB 加密,IV 为 MD5(数据加密 IV),Key 为 MD5(数据加密 Key)。实际应答数据视加密设置不同而不同。
|
||||
|
||||
| 1 字节 | 1 字节 | 1 字节 | 1 字节 | M 字节 | 余下部分 |
|
||||
| ---------- | -------- | -------- | ---------- | -------- | ------------ |
|
||||
| 响应认证 V | 选项 Opt | 指令 Cmd | 指令长度 M | 指令内容 | 实际应答数据 |
|
||||
|
||||
其中:
|
||||
|
||||
- 响应认证 V:必须和客户端请求中的响应认证 V 一致;
|
||||
- 选项 Opt:
|
||||
- 0x01:服务器端准备重用 TCP 连接(Xray 2.23+ 弃用);
|
||||
- 指令 Cmd:
|
||||
- 0x01:动态端口指令
|
||||
- 实际应答数据:
|
||||
- 如果请求中的 Opt(S) 开启,则使用标准格式,否则使用基本格式。
|
||||
- 格式均和请求数据相同。
|
||||
- 当 Opt(M) 开启时,长度 L 的值 = 真实值 xor Mask。Mask = (ResponseMask.NextByte() << 8) + ResponseMask.NextByte();
|
||||
|
||||
### 动态端口指令
|
||||
|
||||
| 1 字节 | 2 字节 | 16 字节 | 2 字节 | 1 字节 | 1 字节 |
|
||||
| ------ | --------- | ------- | ------- | -------- | ---------- |
|
||||
| 保留 | 端口 Port | 用户 ID | AlterID | 用户等级 | 有效时间 T |
|
||||
|
||||
其中:
|
||||
|
||||
- 端口 Port:Big Endian 格式的整型端口号;
|
||||
- 有效时间 T:分钟数;
|
||||
|
||||
客户端在收到动态端口指令时,服务器已开放新的端口用于通信,这时客户端可以将数据发往新的端口。在 T 分钟之后,这个端口将失效,客户端必须重新使用主端口进行通信。
|
||||
|
||||
## 注释
|
||||
|
||||
- 为确保向前兼容性,所有保留字段的值必须为 0。
|
Loading…
Reference in New Issue