Closed thuhollow2 closed 10 months ago
有没有h2的vmess URI示例
当net为“ws”时,我server_name是直接取ws里的host而不是'sni'的值。这个h2示例里的host有两个,那么server_name怎么写?
上述clash转为v2ray的格式为: {"v": "2", "ps": "vmess-h2", "add": "server", "port": 443, "id": "uuid", "aid": 32, "net": "h2", "scy": "auto", "type": "none", "host": ["http.example.com", "http-alt.example.com"], "path": "/", "tls": "tls"} 此host我写的是否有误。
转为sing-box格式: { "tag": "vmess-h2", "type": "vmess", "server": "server", "server_port": 443, "uuid": "uuid", "security": "auto", "alter_Id": 32, "packet_encoding": "xudp", "tls": { "enabled": true, "insecure": true, "server_name": "" }, "transport": { "type": "http", "host": [ "http.example.com", "http-alt.example.com" ], "path": "/" } } 此singbox格式是否正确
这是我用clash.meta验证过的vmess文件 各参数格式可以在Clash.Meta/Alpha/outbound/vmess.go找到 我改了vmess部分
if share_link['type'] == 'vmess':
vmess_info = {
"v": "2",
"ps": share_link['name'].encode('utf-8', 'surrogatepass').decode('utf-8'),
"add": share_link['server'],
"port": share_link['port'],
"id": share_link['uuid'],
"aid": share_link['alterId'],
"net": share_link.get('network', 'tcp'),
"scy": share_link.get('cipher', 'auto'),
"type": "none",
"tls": '',
"alpn": share_link.get('alpn', [])
}
if share_link.get('skip-cert-verify') == True:
vmess_info['verify_cert'] = True
if share_link.get('tls') and share_link['tls'] != False:
vmess_info['tls'] = 'tls'
vmess_info["sni"] = share_link.get('servername', '')
if vmess_info['net'] == 'ws':
vmess_info["host"] = share_link.get('ws-opts', {}).get('headers', {}).get('Host', '')
vmess_info["path"] = share_link.get('ws-opts', {}).get('path', '/')
elif vmess_info['net'] == 'grpc':
vmess_info["path"] = share_link.get('grpc-opts', {}).get('grpc-service-name', '/')
elif vmess_info['net'] == 'http':
vmess_info["host"] = share_link.get('http-opts', {}).get('headers', {}).get('Host', [])
vmess_info["path"] = share_link.get('http-opts', {}).get('path', '[]')
elif vmess_info['net'] == 'h2':
vmess_info["host"] = share_link.get('h2-opts', {}).get('host', [])
vmess_info["path"] = share_link.get('h2-opts', {}).get('path', '/')
vmess_json = json.dumps(vmess_info).encode('utf-8')
vmess_base64 = base64.b64encode(vmess_json).decode('utf-8')
link = f"vmess://{vmess_base64}"
return link
# TODO
多个h2 host写成json格式就好,就像
{
"server": "a.v2ray.world",
"server_port": 443,
"tag": "🇺🇸US-199.59.243.225-0880",
"transport": {
"path": "/",
"type": "http",
"host": [
"a.v2ray.world",
"a.world"
]
},
"type": "vmess",
"alter_id": 64,
"security": "auto",
"uuid": "05b6b25b-bb5d-4dcd-9710-31e374ffa584"
}
改好了,有些跟你写有出入,好像是以前测试过我写的才能运行,我就不改了
en,vmess的http类型转换到sing-box有一些问题,因为您是先clash转为v2ray再到sing-box,原来clash中的http-opts.method(参见Clash.Meta/Alpha/outbound/vmess.go)在v2ray中没有对应参数,但在sing-box里有(参见SagerNet/sing-box/transport/v2rayhttp/client.go),所以会出现这种情况:
- {name: 🇺🇸US-5.161.177.114-3389, server: 5.161.177.114, port: 3389, type: vmess, uuid: 9c050a86-d612-48f1-ec32-e573df08a1b7, alterId: 0, cipher: auto, tls: false, tfo: false, skip-cert-verify: true, network: http, http-opts: {method: GET, path: [/]}, udp: true}
被转成
{
"tag": "❤️🇺🇸US-5.161.177.114-3389",
"type": "vmess",
"server": "5.161.177.114",
"server_port": 3389,
"uuid": "9c050a86-d612-48f1-ec32-e573df08a1b7",
"security": "auto",
"alter_Id": 0,
"packet_encoding": "xudp",
"transport": {
"type": "http",
"path": "/"
}
}
实际应是:
{
"tag": "❤️🇺🇸US-5.161.177.114-3389",
"type": "vmess",
"server": "5.161.177.114",
"server_port": 3389,
"uuid": "9c050a86-d612-48f1-ec32-e573df08a1b7",
"security": "auto",
"alter_Id": 0,
"packet_encoding": "xudp",
"transport": {
"type": "http",
"method": "GET",
"path": "/"
}
}
method参数虽无大用,但有时导入软件缺失会报错,推荐v2ray转sing-box时默认添加"method": "GET",即在vmess.py的line 81后部分进行添加
修正好了
还有一个不妥之处,在vmess的v2ray转sing-box的配置参数中,alter_Id(1处、2处,暂不知他处是否需要修改)实际应为alter_id(sing-box相关参数参见SagerNet/sing-box/option/vmess.go)
netquery.get('alterId','99')的含义是,是否获取到{“alterId”:“数字”},没有获取到alterId就设置99,99是我乱写的但不影响。好像我遇到过奇葩的vmess格式才这样写的。
alter_Id只要是纯数字就行
不是指v2ray的alterld,是指sing-box的alter_id
这导致转换出来的sing-box节点像:
{
"tag": "❤️🇦🇺AU-158.179.22.148-80",
"type": "vmess",
"server": "mrb2.shabijichang.com",
"server_port": 80,
"uuid": "c458695d-6908-45c3-9512-e0c46418454c",
"security": "auto",
"alter_Id": 0,
"packet_encoding": "xudp",
"transport": {
"type": "ws",
"path": "/",
"headers": {
"Host": "mrb2.shabijichang.com"
}
}
}
alter_Id应该为alter_id
em,就是变量名写错了
用大写的ID好久了,没问题。 那我还是改一下吧
sing-box没检查到alter_id,估计是默认为0处理了
如果为alter为0.那我这个节点不可能通
关于parsers/clash2base64.py的vless部分的修改:
elif share_link['type'] == 'vless':
vless_info = {
"uuid": share_link['uuid'],
"server": share_link['server'],
"port": share_link['port'],
"sni": share_link.get('servername', ''),
"fp": share_link.get('client-fingerprint', ''),
"type": share_link.get('network', 'tcp'),
"flow": share_link.get('flow', ''),
"allowInsecure": '0' if share_link.get('skip-cert-verify', True) == False else '1',
"name": quote(share_link['name'], 'utf-8'),
"alpn": ''
}
if share_link.get('alpn', []) != []:
vless_info['alpn'] = quote(','.join(share_link.get('alpn', [])), 'utf-8')
if vless_info['type'] == 'ws':
vless_info["path"] = quote(share_link['ws-opts'].get('path', '') or share_link['ws-path'], 'utf-8')
vless_info["host"] = share_link['ws-opts'].get('headers', {}).get('Host', '') or share_link.get('ws-headers', {}).get('Host', '') or share_link['ws-opts'].get('headers', {}).get('host', '') or share_link.get('ws-headers', {}).get('host', '')
if share_link.get('tls', '') and share_link['tls'] != False:
vless_info["security"] = 'tls'
else:
vless_info["security"] = 'none'
link = "vless://{uuid}@{server}:{port}?encryption=none&security={security}&sni={sni}&type={type}&host={host}&path={path}&fp={fp}&flow={flow}&alpn={alpn}&allowInsecure={allowInsecure}".format(**vless_info)
elif vless_info['type'] == 'grpc':
if share_link.get('grpc-opts', {}).get('grpc-service-name', '') != '/' :
vless_info["serviceName"] = unquote(share_link.get('grpc-opts', {}).get('grpc-service-name', ''))
if share_link.get('reality-opts', {}):
vless_info["security"] = 'reality'
vless_info["pbk"] = share_link['reality-opts'].get('public-key', '')
vless_info["sid"] = share_link['reality-opts'].get('short-id', '')
link = "vless://{uuid}@{server}:{port}?encryption=none&security={security}&sni={sni}&type={type}&serviceName={serviceName}&fp={fp}&flow={flow}&alpn={alpn}&allowInsecure={allowInsecure}&pbk={pbk}&sid={sid}".format(**vless_info)
elif share_link.get('tls', '') and share_link['tls'] != False:
vless_info["security"] = 'tls'
link = "vless://{uuid}@{server}:{port}?encryption=none&security={security}&sni={sni}&type={type}&serviceName={serviceName}&fp={fp}&flow={flow}&alpn={alpn}&allowInsecure={allowInsecure}".format(**vless_info)
else:
vless_info["security"] = 'none'
link = "vless://{uuid}@{server}:{port}?encryption=none&security={security}&sni={sni}&type={type}&serviceName={serviceName}&fp={fp}&flow={flow}&alpn={alpn}&allowInsecure={allowInsecure}".format(**vless_info)
elif vless_info['type'] == 'h2':
vless_info["path"] = quote(share_link.get('h2-opts', {}).get('path', ''), 'utf-8')
vless_info["host"] = ','.join(share_link.get('h2-opts', {}).get('host', []))
if share_link.get('reality-opts', {}):
vless_info["security"] = 'reality'
vless_info["pbk"] = share_link['reality-opts'].get('public-key', '')
vless_info["sid"] = share_link['reality-opts'].get('short-id', '')
link = "vless://{uuid}@{server}:{port}?encryption=none&security={security}&sni={sni}&type={type}&host={host}&path={path}&fp={fp}&flow={flow}&alpn={alpn}&allowInsecure={allowInsecure}&pbk={pbk}&sid={sid}".format(**vless_info)
elif share_link.get('tls', '') and share_link['tls'] != False:
vless_info["security"] = 'tls'
link = "vless://{uuid}@{server}:{port}?encryption=none&security={security}&sni={sni}&type={type}&host={host}&path={path}&fp={fp}&flow={flow}&alpn={alpn}&allowInsecure={allowInsecure}".format(**vless_info)
else:
vless_info["security"] = 'none'
link = "vless://{uuid}@{server}:{port}?encryption=none&security={security}&sni={sni}&type={type}&host={host}&path={path}&fp={fp}&flow={flow}&alpn={alpn}&allowInsecure={allowInsecure}".format(**vless_info)
elif vless_info['type'] == 'http':
vless_info["path"] = ','.join(share_link.get('http-opts', {}).get('path', []))
vless_info["host"] = share_link.get('http-opts', {}).get('headers', {}).get('Host', [''])[0] or share_link.get('http-opts', {}).get('headers', {}).get('host', [''])[0]
if share_link.get('reality-opts', {}):
vless_info["security"] = 'reality'
vless_info["pbk"] = share_link['reality-opts'].get('public-key', '')
vless_info["sid"] = share_link['reality-opts'].get('short-id', '')
link = "vless://{uuid}@{server}:{port}?encryption=none&security={security}&sni={sni}&type={type}&host={host}&path={path}&fp={fp}&flow={flow}&alpn={alpn}&allowInsecure={allowInsecure}&pbk={pbk}&sid={sid}".format(**vless_info)
elif share_link.get('tls', '') and share_link['tls'] != False:
vless_info["security"] = 'tls'
link = "vless://{uuid}@{server}:{port}?encryption=none&security={security}&sni={sni}&type={type}&host={host}&path={path}&fp={fp}&flow={flow}&alpn={alpn}&allowInsecure={allowInsecure}".format(**vless_info)
else:
vless_info["security"] = 'none'
link = "vless://{uuid}@{server}:{port}?encryption=none&security={security}&sni={sni}&type={type}&host={host}&path={path}&fp={fp}&flow={flow}&alpn={alpn}&allowInsecure={allowInsecure}".format(**vless_info)
elif vless_info['type'] == 'tcp':
if share_link.get('reality-opts', {}):
vless_info["security"] = 'reality'
vless_info["pbk"] = share_link['reality-opts'].get('public-key', '')
vless_info["sid"] = share_link['reality-opts'].get('short-id', '')
link = "vless://{uuid}@{server}:{port}?encryption=none&security={security}&sni={sni}&type={type}&fp={fp}&flow={flow}&alpn={alpn}&allowInsecure={allowInsecure}&pbk={pbk}&sid={sid}".format(**vless_info)
elif share_link.get('tls', '') and share_link['tls'] != False:
vless_info["security"] = 'tls'
link = "vless://{uuid}@{server}:{port}?encryption=none&security={security}&sni={sni}&type={type}&fp={fp}&flow={flow}&alpn={alpn}&allowInsecure={allowInsecure}".format(**vless_info)
else:
vless_info["security"] = 'none'
link = "vless://{uuid}@{server}:{port}?encryption=none&security={security}&sni={sni}&type={type}&fp={fp}&flow={flow}&alpn={alpn}&allowInsecure={allowInsecure}".format(**vless_info)
if share_link.get('smux',{}).get('enabled', '') == True:
vless_info["protocol"] = share_link['smux']['protocol']
vless_info["max_connections"] = share_link['smux'].get('max-connections','')
vless_info["min_streams"] = share_link['smux'].get('min-streams','')
vless_info["max_streams"] = share_link['smux'].get('max-streams','')
vless_info["padding"] = share_link['smux'].get('padding','')
link += "&protocol={protocol}&max-connections={max_connections}&min-streams={min_streams}&max-streams={max_streams}&padding={padding}#{name}".format(**vless_info)
else:
link += f"#{vless_info['name']}"
return link
# TODO
好吧
不好意思,昨天代码有地方我写的不对,vmess_info["path"] = share_link.get('http-opts', {}).get('path', '[]')应改为vmess_info["path"] = share_link.get('http-opts', {}).get('path', []),多打了引号见谅;其他协议我打算都搓一遍,隔段时间再在这统一提交一次issue可好
parsers/clash2base64.py里的vmess_info["sni"] = share_link.get('servername', '')应该是 if share_link.get('tls') and share_link['tls'] != False: 的结果吧,servername应是tls为ture时才有的选项;另外,vmess还能补充h2,http类型吗