Browse Source

feat: Trojan-Go share url decode

master
Dnomd343 2 years ago
parent
commit
460852fcf8
  1. 2
      ProxyDecoder/Trojan.py
  2. 96
      ProxyDecoder/TrojanGo.py
  3. 3
      ProxyDecoder/decoder.py
  4. 52
      demo.py

2
ProxyDecoder/Trojan.py

@ -8,7 +8,7 @@ def __trojanCommonDecode(url: str) -> dict:
""" """
Trojan标准分享链接解码 Trojan标准分享链接解码
FORMAT: trojan://$(UUID)@server:port?{fields}#$(remark) FORMAT: trojan://$(password)@server:port?{fields}#$(remark)
type -> tcp / kcp / ws / http / quic / grpc type -> tcp / kcp / ws / http / quic / grpc

96
ProxyDecoder/TrojanGo.py

@ -0,0 +1,96 @@
#!/usr/bin/python
# -*- coding:utf-8 -*-
import re
from ProxyDecoder import baseFunc
def __trojanGoCommonDecode(url: str) -> dict:
"""
Trojan-Go标准分享链接解码
FORMAT: trojan-go://$(password)@server:port/?{fields}#$(remark)
sni -> TLS SNI
type -> original / ws
host -> WebSocket Host
path -> WebSocket Path
encryption -> urlEncode(ss;aes-256-gcm;ss-password)
plugin -> urlEncode(pluginName;pluginOption) -> officially undefined (refer to SIP002 scheme)
"""
match = re.search(r'^trojan-go://([\S]+?)(#[\S]*)?$', url) # trojan-go://...#REMARK
remark = baseFunc.urlDecode(
match[2][1:] if match[2] is not None else ''
)
match = re.search(
r'^([\S]+)@([a-zA-Z0-9.:\-_\[\]]+)/?([\S]*)$', match[1] # $(password)@server[:port]/?...
)
info = {
'passwd': baseFunc.urlDecode(match[1]),
'remark': remark
}
params = baseFunc.paramSplit(match[3])
match = re.search(
r'^([a-zA-Z0-9.:\-_\[\]]+?)(:([0-9]{1,5}))?$', match[2] # server[:port]
)
info['server'] = baseFunc.formatHost(match[1])
info['port'] = int(match[3]) if match[3] is not None else 443
if 'sni' in params:
info['sni'] = params['sni']
if 'type' in params:
if params['type'] not in ['', 'original', 'ws']:
raise Exception('Unknown Trojan-Go network type')
if params['type'] == 'ws': # WebSocket mode
info['ws'] = {}
if 'host' in params:
info['ws']['host'] = params['host']
if 'path' in params:
info['ws']['path'] = params['path']
if 'encryption' in params and params['encryption'] not in ['', 'none']: # shadowsocks encrypt
match = re.search(
r'^ss;([a-zA-Z0-9\-_]+):([\S]+)$', params['encryption']
)
info['ss'] = {
'method': match[1],
'passwd': match[2]
}
if 'plugin' in params and params['plugin'] not in ['', 'none']: # SIP003 plugin
match = re.search(
r'^([\S]+?)(;([\S]+))?$', params['plugin']
)
info['plugin'] = {
'type': match[1],
'param': match[3] if match[3] is not None else ''
}
return info
def trojanGoDecode(url: str) -> dict or None:
"""
Trojan-Go分享链接解码
链接合法:
return {
'type': 'trojan-go',
...
}
链接不合法:
return None
"""
if url[0:12] != 'trojan-go://':
return None
try:
result = __trojanGoCommonDecode(url) # try Trojan-Go common decode
except:
return None
result['type'] = 'trojan-go'
return result

3
ProxyDecoder/decoder.py

@ -7,6 +7,7 @@ from ProxyDecoder import ShadowsocksR
from ProxyDecoder import VMess from ProxyDecoder import VMess
from ProxyDecoder import VLESS from ProxyDecoder import VLESS
from ProxyDecoder import Trojan from ProxyDecoder import Trojan
from ProxyDecoder import TrojanGo
def decode(url: str) -> dict or None: def decode(url: str) -> dict or None:
""" """
@ -34,6 +35,8 @@ def decode(url: str) -> dict or None:
return VLESS.vlessDecode(url) return VLESS.vlessDecode(url)
elif scheme == 'trojan': elif scheme == 'trojan':
return Trojan.trojanDecode(url) return Trojan.trojanDecode(url)
elif scheme == 'trojan-go':
return TrojanGo.trojanGoDecode(url)
except: except:
pass pass
return None return None

52
demo.py

@ -5,32 +5,32 @@ import ProxyDecoder as Decoder
import ProxyFilter as Filter import ProxyFilter as Filter
import Check as Checker import Check as Checker
info = { # info = {
'type': 'trojan-go', # 'type': 'trojan-go',
'server': '127.0.0.1', # 'server': '127.0.0.1',
'port': 12345, # 'port': 12345,
'passwd': 'dnomd343', # 'passwd': 'dnomd343',
'sni': 'local.343.re', # 'sni': 'local.343.re',
'plugin': { # 'plugin': {
'type': 'simple-tls', # 'type': 'simple-tls',
'param': 'n=local.343.re;no-verify' # 'param': 'n=local.343.re;no-verify'
} # }
} # }
#
# status, ret = Filter.filte(info, isExtra = True)
# print(status)
# print(ret)
#
# data = Checker.proxyTest({
# 'check': ['http'],
# 'info': ret
# })
#
# print(data)
status, ret = Filter.filte(info, isExtra = True) url = 'trojan-go://password1234@google.com/?sni=microsoft.com&type=ws&host=youtube.com&path=%2Fgo&encryption=ss%3Baes-256-gcm%3Afuckgfw&plugin=obfs-local%3Bobfs%3Dhttp%3Bobfs-host%3Dwww.bing.com#server%20name'
print(status) ret = Decoder.decode(url)
print(ret) print(ret)
data = Checker.proxyTest({ ret = Filter.filte(ret)
'check': ['http'], print(ret)
'info': ret
})
print(data)
# status, client = Builder.build(ret, '/tmp/ProxyC')
# print(status)
# print(client)
#
# time.sleep(300)
# Builder.destroy(client)

Loading…
Cancel
Save