vless 简述
啥是 vless
vless 就是应用层的传输协议,与 HTTP、FTP、SMTP 类似,但是他是代理协议并非通用通信协议。
要注意的是,虽然 vless 是代理协议 但是 vless 数据帧里没有代理服务器的地址。代理服务器地址在 IP 头中
vless 长什么样
VLESS 数据帧
┌─────────────────────────────────────────────────┐
│ 协议头 │
│ ┌──────────┬──────┬──────┬──────┬──────┐ │
│ │ 版本(1B) │UUID │附加信息│指令(1B)│端口(2B)│ │
│ │ 0x00 │16B │长度+数据│ │ │ │
│ └──────────┴──────┴──────┴──────┴──────┘ │
│ ┌──────────────────────────────┐ │
│ │ 地址类型(1B) │ │
│ │ 0x01 = IPv4 (4B) │ │
│ │ 0x02 = 域名 (1B长度+域名) │ │
│ │ 0x03 = IPv6 (16B) │ │
│ └──────────────────────────────┘ │
├─────────────────────────────────────────────────┤
│ 载荷 │
│ ┌──────────────────────────────────────────┐ │
│ │ 你真正要发的数据 │ │
│ │ (HTTP请求、随便什么都行) │ │
│ └──────────────────────────────────────────┘ │
└─────────────────────────────────────────────────┘
指令就几个值:
0x01 = TCP(建立连接) 0x02 = UDP(包转发) 0x03 = Mux(多路复用)
一个完整的请求大概长这样(访问 google.com:443):
00 版本
00 附加信息长度=0
01 指令=TCP
01BB 端口=443
02 0A 676F6F676C652E636F6D 域名类型 + 长度 10 + “google.com”
────────────────────────────── ↓ 下面是载荷
474554202F20485454502F312E310D0A “GET / HTTP/1.1…”
┌─────────────────────────────────────────────────────┐
│ 以太网帧头(MAC地址) │
├─────────────────────────────────────────────────────┤
│ IP头 │
│ 源:你的IP 192.168.1.5 │
│ 目标:代理服务器 1.2.3.4 │
├─────────────────────────────────────────────────────┤
│ TCP头 │
│ 目标端口:443 │
├─────────────────────────────────────────────────────┤
│ TLS 加密 │
│ ┌─────────────────────────────────────────────────┐ │
│ │ VLESS 协议头 │ │
│ │ UUID + 指令=TCP │ │
│ │ 目标地址:ph.com:443 ← 协议头里的 │ │
│ │ 目标端口:443 │ │
│ │ ┌─────────────────────────────────────────────┐ │ │
│ │ │ 载荷:GET / HTTP/1.1... ← 真实请求 │ │ │
│ │ └─────────────────────────────────────────────┘ │ │
│ └─────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────┘
系统代理模式和 TUN 虚拟网卡模式
从上面可以看出来 vless 只是提供了一种标识头,本身没有功能和加密。 而代理服务器则是在 IP 头中。 这里的 IP 代理服务器的地址替换(IP 的填充是由 OS 来做的)和 VLESS 协议包装是由客户端来做, mihomo 通过拦截请求改写发送。
正常上网:
浏览器 → "我要访问bilibili.com"
→ DNS查到IP
→ OS打包,IP头填bilibili的IP
→ 直接连bilibili
代理模式:(TUN模式)
浏览器 → "我要访问ph.com"
→ 走代理客户端(系统代理/PAC/TUN等)
→ 代理客户端说"这个走代理"
→ OS打包,IP头填代理服务器IP
→ 连代理服务器 //代理服务器的地址在客户端的配置文件中规定
→ VLESS头里写ph.com
系统代理: 浏览器 → 代理客户端 (127.0.0.1:1080) → OS → 真网卡 → 代理服务器
TUN 模式: 浏览器 → OS → 虚拟网卡 (代理客户端) → 重新打包 → 真网卡 → 代理服务器
既然这样的话 代理服务器是如何识别我们是被准许的人呢?
Vless 结构
出站和入站
vless 有两部分,分别是出站和入站。
我的电脑 代理服务器
┌──────────┐ ┌──────────┐
│ 出站配置 │ ──────────→ │ 入站配置 │
│ outbound │ │ inbound │
└──────────┘ └──────────┘
- 出站(客户端):
- 代理服务器地址在哪
- 用什么协议(VLESS)
- 我的 UUID 是什么
- 负责打包请求发和发送
- 入站(代理服务器):
- 允许哪些 UUID 连进来
- 解密设置
- 不认识的流量 fallback 到哪
- 负责拆包、转发
出站
{
"protocol": "vless",
"settings": {
"address": "example.com", // 代理服务器地址
"port": 443, // 代理服务器端口
"id": "5783a3e7-...", // 你的 UUID(身份证)
"encryption": "none", // 加密设置
"flow": "xtls-rprx-vision" // 流控模式
}
}
address — 代理服务器在哪。IP、域名、IPv6 都行。
port — 代理服务器监听的端口。
id — 你的身份标识。可以是 UUID,也可以是自定义字符串,Xray 会自动映射成 UUID v5。
encryption — VLESS 的加密设置。注意这个不是 TLS 那层加密,是 VLESS 协议自己额外加的一层加密。格式是一串用 . 连接的配置: mlkem768x25519plus.native.600s.100-111-1111.75-0-111.50-0-3333.认证参数 │ │ │ │ │ 握手方式 加密方式 会话票据有效期 padding 配置 认证参数 (后量子算法) native=原始数据 垃圾数据填充,混淆流量长度特征 xorpub=混淆公钥 random=全随机数
flow — XTLS 的流控模式:
- 空:普通 TLS 代理,不管原始数据是否已经 TLS 加密了都在加密一次
- xtls-rprx-vision:智能识别,如果载荷本身已经是 TLS 1.3 加密的数据,直接原样转发,不做多余的解密再加密。Linux 下还会用 Splice,让内核直接转发 TCP,数据都不经过 Xray 的内存,CPU 开销几乎为零
入站
入站(Inbound)— 代理服务器的配置
代理服务器上的 Xray 用的。告诉服务器"怎么接进来"。
{
"protocol": "vless",
"settings": {
"clients": [ // 允许连进来的用户列表
{
"id": "5783a3e7-...", // 用户 UUID
"flow": "xtls-rprx-vision",
"email": "love@xray.com"
}
],
"decryption": "none", // 解密设置
"fallbacks": [ // 回落配置
{ "dest": 80 }
]
}
}
clients — 数组,白名单。只有 UUID 在列表里的用户才能连进来。可以配多个用户,每个用户可以有不同的 flow 和 level。
decryption — 对应客户端的 encryption。客户端加密了,服务端就得配对应的解密。两边要一致。
fallbacks — 伪装用。如果连进来的流量不是合法的 VLESS 请求,可以这个流量转发到一个正常网站:
有人探测你的服务器: 发了个普通 HTTP 请求过来 → 不是合法 VLESS 流量 → fallback 到 80 端口(你服务器上跑的正常网站) → 探测的人看到一个普通网站,觉得这服务器没问题
而你在访问时服务器监测到该访问属于白名单内的用户便发送请求至代理服务器。