v2fly / v2fly-github-io

V2Fly Website & Documentation

Home Page:https://v2fly.org

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

VMess 分享链接标准 Draft 1

opened this issue · comments

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

  • 表示 假 的值: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: 更新 TLSServerNametlsServerName
Update: 新增 TCP 在 HTTP 伪装时的 host 字段

Update: 移除了 tlsAllowInsecure

Hmm,或许需要更新下了,现在加入了 gRPC 传输层。