VMess 分享链接标准 Draft 1
opened this issue · comments
Deleted user commented
1. 为什么提议指定官方标准?
现有的主流 vmess://
分享链接分为以下几种:
- V2RayN 格式
- ShadowRocket 格式
- Quantumult 格式
- 等……
以上分享链接协议仅仅适用于自家软件的导入/导出,普通用户如需要转换则需要第三方组件,在无形之中增加了链接配置被恶意盗用的可能性。
另外,V2Ray 现已然成为一个平台化程序,我认为有必要设计一个 VMess 协议的标准分享链接格式,这对于个人用户在设备间分享 / 机场进行标准化适配 / 新客户端编写都具有更多的便利性
2. 标准格式提议
新的 vmess://
标准应当避免使用 Json 存储,同时应当避免大量使用 Base64:
-
Json 是数据交换格式,但不应用在 URL 中,URL 标准有 Query 项目可以存储协议相关设置
-
Base64 的输出会导致配置项不便于观察,在此基础上,Base64 并不能防止数据篡改或因为传输原因损坏:
echo "SGVsbG8K" | base64 -d #---> Hello echo "SGRsbG8K" | base64 -d #---> Hdllo
3. 链接格式标准
下列标准使用类 Python 语法的伪代码编写
在标准中,bool
类型的值将遵循以下规定:
- 表示 假 的值:
false, False, No, Off, 0, "" (空字符串,如 useSomething=)
- 大小写不敏感
- 其余值如果出现,将解析为真
PROTOCOL_OPTION_OBJECT = struct { 名称, 值类型, 默认值 }
# PROTOCOL_OPTIONS = [ PROTOCOL_OPTION_OBJECT ]
PROTOCOL_OPTIONS = []
# QUIC 和 KCP 所需的混淆类型
QUIC_KCP_HEADERS_TYPES = enum { "none", "srtp", "utp", "wechat-video", "dtls", "wireguard" }
# QUIC 所需的 Security 类型
QUIC_SECURITY_TYPES = enum { "none", "aes-128-gcm", "chacha20-poly1305" }
# TCP 所需的 Type
TCP_TYPES = enum { "none", "http" }
switch streamSettings.protocol:
case TCP:
PROTOCOL = "tcp"
PROTOCOL_OPTIONS += { "type", TCP_TYPES, "none" }
PROTOCOL_OPTIONS += { "host", string, "" }
case HTTP:
PROTOCOL = "http"
PROTOCOL_OPTIONS += { "path", string, "/" }
# 每个 Host 项使用 "|" 分割
PROTOCOL_OPTIONS += { "host", string, "" }
case WS:
PROTOCOL = "ws"
PROTOCOL_OPTIONS += { "path", string, "/" }
PROTOCOL_OPTIONS += { "host", string, "" }
case KCP:
PROTOCOL = "kcp"
PROTOCOL_OPTIONS += { "type", QUIC_KCP_HEADERS_TYPES, "none" }
PROTOCOL_OPTIONS += { "seed", string, "" }
case QUIC:
PROTOCOL = "quic"
PROTOCOL_OPTIONS += { "security", QUIC_SECURITY_TYPES, "none" }
PROTOCOL_OPTIONS += { "key", string, "" }
PROTOCOL_OPTIONS += { "type", QUIC_KCP_HEADERS_TYPES, "none" }
TLS_OPTIONS = []
if hasTLS:
# TLS 配置
# e.g.
# ws+tls
# ws
# quic+tls
# tcp
URL_USERNAME_PART = PROTOCOL + "+tls"
# AllowInsecure 选项扬了
TLS_OPTIONS += { "tlsServerName", string, "" }
else:
URL_USERNAME_PART = PROTOCOL
# UUID: 带 "-" 分割的 UUID
# alterId: int
# host: string
# port: int
# e.g. "kcp+tls:aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee-64@server.com:1234"
URL_PART_A = f"{URL_USERNAME_PART}:{UUID}-{alterId}@{HOST}:{PORT}"
# 协议相关设置项,值使用 encodeURIComponent 编码
URL_PART_B = [for OPT in PROTOCOL_OPTIONS, f"{OPT.名称}={encodeURIComponent(OPT.值)}"].join("&")
# TLS 相关设置项,值使用 encodeURIComponent 编码
URL_PART_C = [for OPT in TLS_OPTIONS, f"{OPT.名称}={encodeURIComponent(OPT.值)}"].join("&")
# ALIAS: string
URL_PART_D = encodeURIComponent(ALIAS)
FULL_VMESS_URL = "vmess://" + URL_PART_A + "/?" + URL_PART_B + URL_PART_C + "#" + URL_PART_D
链接格式解析样例
vmess://ws+tls:7db04e8f-7cfc-46e0-9e18-d329c22ec353-64@myServer.com:12345/?path=%2FmyServerAddressPath%2F%E4%B8%AD%E6%96%87%E8%B7%AF%E5%BE%84%2F&host=www.myServer.com&tlsAllowInsecure=true&tlsServerName=%E4%BC%AA%E8%A3%85%E5%9F%9F%E5%90%8D.com#%E4%B8%AA%E6%80%A7%E5%8C%96%E9%93%BE%E6%8E%A5%E5%A4%87%E6%B3%A8
传输协议: WS + TLS
UUID/AlterID: 7db04e8f-7cfc-46e0-9e18-d329c22ec353 / 64
服务器地址/端口: myServer.com:12345
协议设置: path=/myServerAddressPath/中文路径/
host=www.myServer.com
TLS 设置:SNI: 伪装域名.com
连接名:"个性化链接备注"
vmess://kcp:ba1b8f8f-efe6-427f-99b2-50491f0adf86-10@baidu.com:443/?type=srtp#AirportConnection1
传输协议: KCP
UUID/AlterID: ba1b8f8f-efe6-427f-99b2-50491f0adf86/10
服务器地址/端口: baidu.com:443
协议设置: type=srtp
连接名: AirportConnection1
vmess://unknown:2e09f64c-c967-4ce3-9498-fdcd8e39e04e-10@google.com:4433/?query=Value1#Connection2
"unknown" 不是 V2Ray 已知传输协议,因此 vmess 链接非法
vmess://tcp:2e09f64c-c967-4ce3-9498-fdcd8e39e04e-10@google.com:4433/?query=Value1#Connection2
传输协议: TCP
UUID/AlterID: 2e09f64c-c967-4ce3-9498-fdcd8e39e04e/10
服务器地址/端口: google.com:4433
协议设置: TCP type 由于未在链接中出现,所以使用默认值 none
链接中 "query" 项忽略
连接名: Connection2
Update: V2Ray-core 新增了 KCP Seed,因此更新
Update: 更新 TLSServerName
为 tlsServerName
Update: 新增 TCP 在 HTTP 伪装时的 host 字段
Update: 移除了 tlsAllowInsecure
项
秋野かえで commented
Hmm,或许需要更新下了,现在加入了 gRPC 传输层。