Skip to content

提议制定 VMess 分享链接标准 #720

@ghost

Description

1. 为什么提议指定官方标准?

现有的主流 vmess:// 分享链接分为以下几种:

  1. V2RayN 格式
  2. ShadowRocket 格式
  3. Quantumult 格式
  4. 等……

以上分享链接协议仅仅适用于自家软件的导入/导出,普通用户如需要转换则需要第三方组件,在无形之中增加了链接配置被恶意盗用的可能性。

另外,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 类型的值将遵循以下规定:

  • 表示 真 的值: true, True, Yes, On
  • 表示 假 的值:false, False, No, Off, 0
  • 其余值如果出现,将解析为真
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: 更新 TLSServerNametlsServerName
Update: 新增 TCP 在 HTTP 伪装时的 host 字段

Update: 移除了 tlsAllowInsecure

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions