Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

VMess 分享链接标准 Draft 1 #26

Closed
ghost opened this issue Aug 16, 2020 · 1 comment
Closed

VMess 分享链接标准 Draft 1 #26

ghost opened this issue Aug 16, 2020 · 1 comment

Comments

@ghost
Copy link

ghost commented Aug 16, 2020

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

@AkinoKaede
Copy link
Contributor

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant