Browse Source

update: add vmess url decode

dev
dnomd343 2 years ago
parent
commit
26a6cbc9fc
  1. 86
      Decoder/VMess.py
  2. 2
      Decoder/__init__.py
  3. 1
      ProxyDecoder/VMess.py
  4. 4
      test.py

86
Decoder/VMess.py

@ -1,11 +1,14 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# VMess / VLESS: https://github.com/XTLS/Xray-core/discussions/716
# V2rayN: https://github.com/2dust/v2rayN/wiki/%E5%88%86%E4%BA%AB%E9%93%BE%E6%8E%A5%E6%A0%BC%E5%BC%8F%E8%AF%B4%E6%98%8E(ver-2)
import json import json
from Utils.Logger import logger from Utils.Logger import logger
from Utils.Exception import decodeException from Utils.Exception import decodeException
from Utils.Common import b64Decode, checkScheme from Utils.Common import b64Decode, checkScheme
from Utils.Common import hostFormat, splitEdParam from Utils.Common import hostFormat, splitTag, splitEdParam, splitParam
def v2rayN(url: str) -> dict: def v2rayN(url: str) -> dict:
""" """
@ -72,3 +75,84 @@ def v2rayN(url: str) -> dict:
config['info']['stream'] = stream config['info']['stream'] = stream
logger.debug('V2rayN url release -> %s', config) logger.debug('V2rayN url release -> %s', config)
return config return config
def vmess(url: str) -> dict:
"""
FORMAT: vmess://UUID@server:port?fields#remark
type -> tcp / kcp / ws / http / quic / grpc
encryption -> auto / aes-128-gcm / chacha20-poly1305
security -> none / tls
path -> WebSocket / HTTP/2 / http obfs
host -> WebSocket / HTTP/2 / http obfs
headerType -> mKCP / QUIC UDP obfs -> none / srtp / utp / wechat-video / dtls / wireguard
-> TCP (http obfs) -> http
seed -> mKCP seed
quicSecurity -> QUIC method
key -> QUIC key
serviceName -> gRPC Service Name
mode -> gRPC transport mode -> gun / multi / guna
sni -> TLS SNI
alpn -> TLS ALPN
"""
config = {
'type': 'vmess',
'info': {}
}
info = config['info']
logger.debug('VMess url decode -> %s' % url)
url, config['name'] = splitTag(checkScheme(url, 'vmess', 'VMess'))
params = ''
if '?' in url:
url, params = url.replace('/?', '?').split('?') # `.../?...` or `...?...`
params = splitParam(params)
config['info']['id'], url = url.rsplit('@', 1)
config['info']['server'], config['info']['port'] = url.rsplit(':', 1)
# split params
if 'encryption' in params:
info['method'] = params['encryption']
stream = {
'type': params['type'] if 'type' in params else 'tcp' # stream type (default = tcp)
}
stream['type'] = 'h2' if stream['type'] == 'http' else stream['type'] # http -> h2
if stream['type'] == 'tcp':
if 'headerType' in params and params['headerType'] == 'http':
stream['obfs'] = {
'host': params['host'] if 'host' in params else '',
'path': params['path'] if 'path' in params else '/',
}
elif stream['type'] == 'kcp':
stream['obfs'] = params['headerType'] if 'headerType' in params else 'none'
stream['seed'] = params['seed'] if 'seed' in params else None
elif stream['type'] == 'ws':
stream['host'] = params['host'] if 'host' in params else ''
if 'path' in params:
try:
stream['path'], stream['ed'] = splitEdParam(params['path'])
except:
stream['path'] = params['path']
elif stream['type'] == 'h2':
stream['host'] = params['host'] if 'host' in params else ''
stream['path'] = params['path'] if 'path' in params else '/'
elif stream['type'] == 'quic':
stream['obfs'] = params['headerType'] if 'headerType' in params else 'none'
stream['method'] = params['quicSecurity'] if 'quicSecurity' in params else 'none'
stream['passwd'] = params['key'] if 'key' in params else ''
elif stream['type'] == 'grpc':
stream['service'] = params['serviceName']
stream['mode'] = 'multi' if 'mode' in params and params['mode'] == 'multi' else 'gun'
else:
logger.error('VMess url with unknown network type -> %s' % stream['type'])
raise decodeException('Unknown vmess network type')
if 'security' in params and params['security'] == 'tls': # enable TLS
stream['secure'] = {
'sni': params['sni'] if 'sni' in params else '', # sni option
'alpn': params['alpn'] if 'alpn' in params and params['alpn'] != '' else None # alpn option
}
config['info']['stream'] = stream
return config

2
Decoder/__init__.py

@ -1,6 +1,6 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from Decoder.VMess import v2rayN
from Decoder.ShadowsocksR import ssr from Decoder.ShadowsocksR import ssr
from Decoder.VMess import vmess, v2rayN
from Decoder.Shadowsocks import ss, sip002 from Decoder.Shadowsocks import ss, sip002

1
ProxyDecoder/VMess.py

@ -153,6 +153,7 @@ def __vmessCommonDecode(url: str) -> dict:
'remark': remark 'remark': remark
} }
params = baseFunc.paramSplit(match[4]) params = baseFunc.paramSplit(match[4])
if 'encryption' in params: if 'encryption' in params:
info['method'] = params['encryption'] info['method'] = params['encryption']
stream = { stream = {

4
test.py

@ -11,7 +11,7 @@ from Filter import Filter
# ret = Decoder.ss('ss://aes-128-ctr:pa@ss#word@8.210.148.24:34326#ok%2Bfuck') # ret = Decoder.ss('ss://aes-128-ctr:pa@ss#word@8.210.148.24:34326#ok%2Bfuck')
# ret = Decoder.ss('ss://aes-128-ctr:pa@ss#word@fc00::1:34326#ok%2Bfuck') # ret = Decoder.ss('ss://aes-128-ctr:pa@ss#word@fc00::1:34326#ok%2Bfuck')
# ret = Decoder.ss('ss://aes-128-ctr:pa@ss#word@[fc00::1]:34326#ok%2Bfuck') # ret = Decoder.ss('ss://aes-128-ctr:pa@ss#word@[fc00::1]:34326#ok%2Bfuck')
ret = Decoder.ss('ss://YmYtY2ZiOnRlc3QvIUAjOkAxOTIuMTY4LjEwMC4xOjg4ODg#example-server') # ret = Decoder.ss('ss://YmYtY2ZiOnRlc3QvIUAjOkAxOTIuMTY4LjEwMC4xOjg4ODg#example-server')
# ret = Decoder.sip002('ss://YWVzLTEyOC1nY206dGVzdA@192.168.100.1:8888#Example1') # ret = Decoder.sip002('ss://YWVzLTEyOC1nY206dGVzdA@192.168.100.1:8888#Example1')
# ret = Decoder.sip002('ss://2022-blake3-aes-256-gcm:YctPZ6U7xPPcU%2Bgp3u%2B0tx%2FtRizJN9K8y%2BuKlW2qjlI%3D@192.168.100.1:8888/?plugin=v2ray-plugin%3Bserver#Example3') # ret = Decoder.sip002('ss://2022-blake3-aes-256-gcm:YctPZ6U7xPPcU%2Bgp3u%2B0tx%2FtRizJN9K8y%2BuKlW2qjlI%3D@192.168.100.1:8888/?plugin=v2ray-plugin%3Bserver#Example3')
@ -22,6 +22,8 @@ ret = Decoder.ss('ss://YmYtY2ZiOnRlc3QvIUAjOkAxOTIuMTY4LjEwMC4xOjg4ODg#example-s
# ret = Decoder.v2rayN('vmess://eyJhZGQiOiJmbnlkdXpheW92dnNxaTMyZ2kucTc1NDMudG9wIiwicHMiOiJ2MXzpppnmuK8wM3zljp_nlJ984piF4piF4piFICgyKSIsInNjeSI6ImF1dG8iLCJ0eXBlIjoiaHR0cCIsInNuaSI6IiIsInBhdGgiOiIvIiwicG9ydCI6MzgzMzcsInYiOjIsImhvc3QiOiJ4aGY0eHE3ZDVjYjRnc3kzeW1teWR3b2kuc2luYS5jbiIsInRscyI6IiIsImlkIjoiOTAxY2UyNTUtOTM2OS1kMWUyLTk1ODQtZGE1YTdqZjA1NDdrIiwibmV0IjoidGNwIiwiYWlkIjowfQ') # ret = Decoder.v2rayN('vmess://eyJhZGQiOiJmbnlkdXpheW92dnNxaTMyZ2kucTc1NDMudG9wIiwicHMiOiJ2MXzpppnmuK8wM3zljp_nlJ984piF4piF4piFICgyKSIsInNjeSI6ImF1dG8iLCJ0eXBlIjoiaHR0cCIsInNuaSI6IiIsInBhdGgiOiIvIiwicG9ydCI6MzgzMzcsInYiOjIsImhvc3QiOiJ4aGY0eHE3ZDVjYjRnc3kzeW1teWR3b2kuc2luYS5jbiIsInRscyI6IiIsImlkIjoiOTAxY2UyNTUtOTM2OS1kMWUyLTk1ODQtZGE1YTdqZjA1NDdrIiwibmV0IjoidGNwIiwiYWlkIjowfQ')
# ret = Decoder.v2rayN('vmess://ew0KICAidiI6ICIyIiwNCiAgInBzIjogIummmea4rzLnur8iLA0KICAiYWRkIjogIjExOS4yOC44OC4yMzAiLA0KICAicG9ydCI6ICI0NDMiLA0KICAiaWQiOiAiODRhOGU2ZDItMWFkMy00NjEyLTgzNjItYTdjMjNlOWU5MzEyIiwNCiAgImFpZCI6ICIwIiwNCiAgInNjeSI6ICJhdXRvIiwNCiAgIm5ldCI6ICJ3cyIsDQogICJ0eXBlIjogIm5vbmUiLA0KICAiaG9zdCI6ICJ0ZXN0LnNjdXRyb2JvdC5jb20iLA0KICAicGF0aCI6ICIvdm1lc3M/ZGVtbz10cnVlJmVkPTIwNDgmdGVzdD1vayIsDQogICJ0bHMiOiAidGxzIiwNCiAgInNuaSI6ICJoay5zY3V0cm9ib3QuY29tIiwNCiAgImFscG4iOiAiIg0KfQ==') # ret = Decoder.v2rayN('vmess://ew0KICAidiI6ICIyIiwNCiAgInBzIjogIummmea4rzLnur8iLA0KICAiYWRkIjogIjExOS4yOC44OC4yMzAiLA0KICAicG9ydCI6ICI0NDMiLA0KICAiaWQiOiAiODRhOGU2ZDItMWFkMy00NjEyLTgzNjItYTdjMjNlOWU5MzEyIiwNCiAgImFpZCI6ICIwIiwNCiAgInNjeSI6ICJhdXRvIiwNCiAgIm5ldCI6ICJ3cyIsDQogICJ0eXBlIjogIm5vbmUiLA0KICAiaG9zdCI6ICJ0ZXN0LnNjdXRyb2JvdC5jb20iLA0KICAicGF0aCI6ICIvdm1lc3M/ZGVtbz10cnVlJmVkPTIwNDgmdGVzdD1vayIsDQogICJ0bHMiOiAidGxzIiwNCiAgInNuaSI6ICJoay5zY3V0cm9ib3QuY29tIiwNCiAgImFscG4iOiAiIg0KfQ==')
ret = Decoder.vmess('vmess://901ce214-9369-d1e2-9584-da5a7ff0547d@pqxsiziyovtsqljrhq.q7543.top:38337/?type=tcp&encryption=auto&headerType=http&host=xhf4xq7d5cb4gsyjpmmydwoi.sina.cn&path=%2F#v1%7C%E9%A6%99%E6%B8%AF01%7CMPTCP%7C%E2%98%85%E2%98%85%E2%98%85%20%282%29')
# ret['info']['server'] = '[%s]' % ret['info']['server'] # ret['info']['server'] = '[%s]' % ret['info']['server']
ret['info'] = Filter(ret['type'], ret['info']) ret['info'] = Filter(ret['type'], ret['info'])

Loading…
Cancel
Save