Browse Source

feat: test of VMess

master
Dnomd343 3 years ago
parent
commit
d9b6d8aa35
  1. 5
      ProxyBuilder/V2ray.py
  2. 5
      ProxyBuilder/Xray.py
  3. 1
      ProxyBuilder/builder.py
  4. 6
      ProxyFilter/V2ray.py
  5. 14
      ProxyFilter/Xray.py
  6. 223
      ProxyTester/V2ray.py
  7. 114
      ProxyTester/VMess.py
  8. 5
      Test.py
  9. 73
      demo.py
  10. 16
      docs/ProxyObject.md

5
ProxyBuilder/V2ray.py

@ -41,9 +41,10 @@ def __secureConfig(secureInfo: dict or None) -> dict: # TLS加密传输配置
if secureInfo is None: if secureInfo is None:
return {} return {}
tlsObject = { tlsObject = {
'allowInsecure': not secureInfo['verify'], 'allowInsecure': not secureInfo['verify']
'alpn': secureInfo['alpn'].split(',')
} }
if secureInfo['alpn'] is not None:
tlsObject['alpn'] = secureInfo['alpn'].split(',')
if secureInfo['sni'] != '': if secureInfo['sni'] != '':
tlsObject['serverName'] = secureInfo['sni'] tlsObject['serverName'] = secureInfo['sni']
return { return {

5
ProxyBuilder/Xray.py

@ -9,9 +9,10 @@ def __secureConfig(secureInfo: dict or None) -> dict: # TLS/XTLS加密传输配
if secureInfo is None: if secureInfo is None:
return {} return {}
secureObject = { secureObject = {
'allowInsecure': not secureInfo['verify'], 'allowInsecure': not secureInfo['verify']
'alpn': secureInfo['alpn'].split(',')
} }
if secureInfo['alpn'] is not None:
secureObject['alpn'] = secureInfo['alpn'].split(',')
if secureInfo['sni'] != '': if secureInfo['sni'] != '':
secureObject['serverName'] = secureInfo['sni'] secureObject['serverName'] = secureInfo['sni']
if secureInfo['type'] == 'tls': if secureInfo['type'] == 'tls':

1
ProxyBuilder/builder.py

@ -119,7 +119,6 @@ def build(proxyInfo: dict, configDir: str,
except: # 配置文件写入失败 except: # 配置文件写入失败
raise Exception('Unable write to file ' + str(configFile)) raise Exception('Unable write to file ' + str(configFile))
process = None
try: # 子进程形式启动 try: # 子进程形式启动
for libcPath in libcPaths: for libcPath in libcPaths:
if os.path.exists(libcPath): # 定位libc.so文件 if os.path.exists(libcPath): # 定位libc.so文件

6
ProxyFilter/V2ray.py

@ -132,8 +132,7 @@ v2rayStreamRules = {
}, },
'secure': { 'secure': {
'optional': False, 'optional': False,
'default': None, 'default': {},
'allowNone': True,
'type': 'secureObject' 'type': 'secureObject'
} }
}, },
@ -218,7 +217,8 @@ v2rayStreamRules = {
}, },
'alpn': { 'alpn': {
'optional': False, 'optional': False,
'default': 'h2,http/1.1', 'default': None,
'allowNone': True,
'type': str, 'type': str,
'format': baseFunc.toStrTidy, 'format': baseFunc.toStrTidy,
'filter': lambda alpn: alpn in ['h2', 'http/1.1', 'h2,http/1.1'], 'filter': lambda alpn: alpn in ['h2', 'http/1.1', 'h2,http/1.1'],

14
ProxyFilter/Xray.py

@ -1,6 +1,8 @@
#!/usr/bin/python #!/usr/bin/python
# -*- coding:utf-8 -*- # -*- coding:utf-8 -*-
import copy
from ProxyFilter import baseFunc from ProxyFilter import baseFunc
from ProxyFilter import V2ray from ProxyFilter import V2ray
@ -10,11 +12,7 @@ xrayFlowList = [
'xtls-splice', 'xtls-splice',
] ]
def testFunc(raw): xrayStreamRules = copy.deepcopy(V2ray.v2rayStreamRules)
print(raw)
return False
xrayStreamRules = V2ray.v2rayStreamRules
xrayStreamRules.pop('secureObject') xrayStreamRules.pop('secureObject')
xrayStreamRules['tcpObject']['secure']['type'] = ['tlsObject', 'xtlsObject'] xrayStreamRules['tcpObject']['secure']['type'] = ['tlsObject', 'xtlsObject']
xrayStreamRules['kcpObject']['secure']['type'] = ['tlsObject', 'xtlsObject'] xrayStreamRules['kcpObject']['secure']['type'] = ['tlsObject', 'xtlsObject']
@ -40,7 +38,8 @@ xrayStreamRules['tlsObject'] = {
}, },
'alpn': { 'alpn': {
'optional': False, 'optional': False,
'default': 'h2,http/1.1', 'default': None,
'allowNone': True,
'type': str, 'type': str,
'format': baseFunc.toStrTidy, 'format': baseFunc.toStrTidy,
'filter': lambda alpn: alpn in ['h2', 'http/1.1', 'h2,http/1.1'], 'filter': lambda alpn: alpn in ['h2', 'http/1.1', 'h2,http/1.1'],
@ -71,7 +70,8 @@ xrayStreamRules['xtlsObject'] = {
}, },
'alpn': { 'alpn': {
'optional': False, 'optional': False,
'default': 'h2,http/1.1', 'default': None,
'allowNone': True,
'type': str, 'type': str,
'format': baseFunc.toStrTidy, 'format': baseFunc.toStrTidy,
'filter': lambda alpn: alpn in ['h2', 'http/1.1', 'h2,http/1.1'], 'filter': lambda alpn: alpn in ['h2', 'http/1.1', 'h2,http/1.1'],

223
ProxyTester/V2ray.py

@ -0,0 +1,223 @@
#!/usr/bin/python
# -*- coding:utf-8 -*-
import copy
import json
httpHeader = {
'version': '1.1',
'status': '200',
'reason': 'OK',
'headers': {
'Content-Type': [
'application/octet-stream',
'video/mpeg'
],
'Transfer-Encoding': [
'chunked'
],
'Connection': [
'keep-alive'
],
'Pragma': 'no-cache'
}
}
kcpSetting = {
"mtu": 1350,
"tti": 20,
"uplinkCapacity": 5,
"downlinkCapacity": 20,
"congestion": False,
"readBufferSize": 1,
"writeBufferSize": 1,
}
udpObfsList = [
'none',
'srtp',
'utp',
'wechat-video',
'dtls',
'wireguard'
]
quicMethodList = [
'none',
'aes-128-gcm',
'chacha20-poly1305',
]
def loadTcpStream(isObfs: bool, host: str, path: str) -> dict:
streamConfig = {
'network': 'tcp',
'tcpSettings': {
'type': 'none'
}
}
if not isObfs: # 不带http混淆
return {
'caption': 'TCP',
'client': {
'type': 'tcp'
},
'server': streamConfig
}
streamConfig['tcpSettings'] = { # http混淆配置
'header': {
'type': 'http',
'response': httpHeader
}
}
return {
'caption': 'TCP with http obfs',
'client': {
'type': 'tcp',
'obfs': {
'host': host,
'path': path
}
},
'server': streamConfig
}
def loadKcpStream(seed: str, obfs: str) -> dict:
kcpSetting['header'] = {
'type': obfs
}
kcpSetting['seed'] = seed
return {
'caption': 'mKCP obfs ' + obfs,
'client': {
'type': 'kcp',
'seed': seed,
'obfs': obfs
},
'server': {
'network': 'kcp',
'kcpSettings': kcpSetting
}
}
def loadWsStream(host: str, path: str, isEd: bool) -> dict:
wsSetting = {
'path': path,
'headers': {
'Host': host
}
}
if not isEd: # 不带Early Data
return {
'caption': 'WebSocket',
'client': {
'type': 'ws',
'host': host,
'path': path
},
'server': {
'network': 'ws',
'wsSettings': wsSetting
}
}
wsSetting['maxEarlyData'] = 2048
wsSetting['earlyDataHeaderName'] = 'Sec-WebSocket-Protocol'
return {
'caption': 'WebSocket Max-Early-Data 2048',
'client': {
'type': 'ws',
'host': host,
'path': path,
'ed': 2048
},
'server': {
'network': 'ws',
'wsSettings': wsSetting
}
}
def loadH2Stream(host: str, path: str) -> dict:
return {
'caption': 'HTTP/2',
'client': {
'type': 'h2',
'host': host,
'path': path
},
'server': {
'network': 'h2',
'httpSettings': {
'host': [host],
'path': path
}
}
}
def loadQuicStream(method: str, passwd: str, obfs: str) -> dict:
return {
'caption': 'QUIC method ' + method + ' obfs ' + obfs,
'client': {
'type': 'quic',
'method': method,
'passwd': passwd,
'obfs': obfs
},
'server': {
'network': 'quic',
'quicSettings': {
"security": method,
"key": passwd,
"header": {
"type": obfs
}
}
}
}
def loadGrpcStream(service: str) -> dict:
return {
'caption': 'gRPC',
'client': {
'type': 'grpc',
'service': service
},
'server': {
'network': 'grpc',
'grpcSettings': {
"serviceName": service
}
}
}
def addSecureConfig(rawStreamInfo: dict, cert: str, key: str, sni: str) -> dict:
streamInfo = copy.deepcopy(rawStreamInfo)
streamInfo['caption'] += ' (tls)'
streamInfo['client']['secure'] = {
'sni': sni
}
streamInfo['server']['security'] = 'tls'
streamInfo['server']['tlsSettings'] = {
'alpn': [
'h2',
'http/1.1'
],
'certificates': [
{
'certificateFile': cert,
'keyFile': key
}
]
}
return streamInfo
def v2rayConfig(inboundConfig: dict) -> str:
return json.dumps({
'log': {
'loglevel': 'warning'
},
'inbounds': [inboundConfig],
'outbounds': [
{
'protocol': 'freedom'
}
]
})

114
ProxyTester/VMess.py

@ -1,8 +1,7 @@
#!/usr/bin/python #!/usr/bin/python
# -*- coding:utf-8 -*- # -*- coding:utf-8 -*-
import copy from ProxyTester import V2ray
import json
config = {} config = {}
@ -14,23 +13,8 @@ vmessMethodList = [
'zero', 'zero',
] ]
def loadServerConfig(inboundObject: dict) -> str: def vmessBasicTest(method: str, alterId: int):
return json.dumps({ inboundConfig = {
'log': {
'loglevel': 'warning'
},
'inbounds': [inboundObject],
'outbounds': [
{
'protocol': 'freedom'
}
]
})
def basicConfig(method: str, alterId: int):
filePath = '/tmp/v2ray.json'
inboundObject = {
'protocol': 'vmess', 'protocol': 'vmess',
'listen': '127.0.0.1', 'listen': '127.0.0.1',
'port': config['port'], 'port': config['port'],
@ -65,20 +49,102 @@ def basicConfig(method: str, alterId: int):
'aid': alterId 'aid': alterId
}, },
'server': { 'server': {
'startCommand': ['v2ray', '-c', filePath], 'startCommand': ['v2ray', '-c', config['file']],
'fileContent': loadServerConfig(inboundObject), 'fileContent': V2ray.v2rayConfig(inboundConfig),
'filePath': filePath, 'filePath': config['file'],
'envVar': envVar 'envVar': envVar
}, },
'aider': None 'aider': None
} }
def loadVmessStream(streamInfo):
proxyInfo = {
'type': 'vmess',
'server': '127.0.0.1',
'port': config['port'],
'id': config['id'],
'stream': streamInfo['client']
}
inboundConfig = {
'protocol': 'vmess',
'listen': '127.0.0.1',
'port': config['port'],
'settings': {
'clients': [
{
'id': config['id']
}
]
},
'streamSettings': streamInfo['server']
}
return {
'caption': 'VMess network ' + streamInfo['caption'],
'proxy': proxyInfo,
'server': {
'startCommand': ['v2ray', '-c', config['file']],
'fileContent': V2ray.v2rayConfig(inboundConfig),
'filePath': config['file'],
'envVar': {}
},
'aider': None
}
def vmessTest(vmessConfig: dict) -> list: def vmessTest(vmessConfig: dict) -> list:
result = [] result = []
for key, value in vmessConfig.items(): # vmessConfig -> config for key, value in vmessConfig.items(): # vmessConfig -> config
config[key] = value config[key] = value
# Basic test
for method in vmessMethodList: # methods and AEAD/MD5+AES test for method in vmessMethodList: # methods and AEAD/MD5+AES test
result.append(basicConfig(method, 0)) result.append(vmessBasicTest(method, 0))
result.append(basicConfig(method, 64)) result.append(vmessBasicTest(method, 64))
# TCP stream
streamInfo = V2ray.loadTcpStream(False, '', '')
result.append(loadVmessStream(streamInfo))
streamInfo = V2ray.addSecureConfig(streamInfo, config['cert'], config['key'], config['host'])
result.append(loadVmessStream(streamInfo))
streamInfo = V2ray.loadTcpStream(True, config['host'], '/')
result.append(loadVmessStream(streamInfo))
streamInfo = V2ray.addSecureConfig(streamInfo, config['cert'], config['key'], config['host'])
result.append(loadVmessStream(streamInfo))
# mKCP stream
for obfs in V2ray.udpObfsList:
streamInfo = V2ray.loadKcpStream(config['passwd'], obfs)
result.append(loadVmessStream(streamInfo))
streamInfo = V2ray.addSecureConfig(streamInfo, config['cert'], config['key'], config['host'])
result.append(loadVmessStream(streamInfo))
# WebSocket stream
streamInfo = V2ray.loadWsStream(config['host'], config['path'], False)
result.append(loadVmessStream(streamInfo))
streamInfo = V2ray.addSecureConfig(streamInfo, config['cert'], config['key'], config['host'])
result.append(loadVmessStream(streamInfo))
streamInfo = V2ray.loadWsStream(config['host'], config['path'], True)
result.append(loadVmessStream(streamInfo))
streamInfo = V2ray.addSecureConfig(streamInfo, config['cert'], config['key'], config['host'])
result.append(loadVmessStream(streamInfo))
# HTTP/2 stream
streamInfo = V2ray.loadH2Stream(config['host'], config['path'])
streamInfo = V2ray.addSecureConfig(streamInfo, config['cert'], config['key'], config['host'])
result.append(loadVmessStream(streamInfo))
# QUIC stream
for method in V2ray.quicMethodList:
for obfs in V2ray.udpObfsList:
streamInfo = V2ray.loadQuicStream(method, config['passwd'], obfs)
streamInfo = V2ray.addSecureConfig(streamInfo, config['cert'], config['key'], config['host'])
result.append(loadVmessStream(streamInfo))
# GRPC stream
streamInfo = V2ray.loadGrpcStream(config['service'])
result.append(loadVmessStream(streamInfo))
streamInfo = V2ray.addSecureConfig(streamInfo, config['cert'], config['key'], config['host'])
result.append(loadVmessStream(streamInfo))
return result return result

5
Test.py

@ -13,6 +13,9 @@ testConfig = {
'port': 12345, 'port': 12345,
'passwd': 'dnomd343', 'passwd': 'dnomd343',
'host': 'dns.343.re', 'host': 'dns.343.re',
'path': '/test',
'service': 'dnomd343',
'file': '/tmp/proxyc-test.json',
'cert': '/etc/ssl/certs/dns.343.re/certificate.crt', 'cert': '/etc/ssl/certs/dns.343.re/certificate.crt',
'key': '/etc/ssl/certs/dns.343.re/private.key', 'key': '/etc/ssl/certs/dns.343.re/private.key',
'id': '1f7aa040-94d8-4b53-ae85-af6946d550bb', 'id': '1f7aa040-94d8-4b53-ae85-af6946d550bb',
@ -63,7 +66,7 @@ def testObject(option: dict) -> None: # test target object
if len(sys.argv) == 1: # no param if len(sys.argv) == 1: # no param
print('Unknown test type') print('Unknown test type')
sys.exit(1) sys.exit(1)
testList = Tester.test(sys.argv[1], testConfig) # get test list testList = Tester.test(sys.argv[1].lower(), testConfig) # get test list
if len(sys.argv) == 2: # test all if len(sys.argv) == 2: # test all
for i in range(0, len(testList)): for i in range(0, len(testList)):

73
demo.py

@ -3,6 +3,7 @@
import copy import copy
import time import time
import Check as Checker
import ProxyFilter as Filter import ProxyFilter as Filter
import ProxyBuilder as Builder import ProxyBuilder as Builder
@ -27,23 +28,73 @@ import ProxyBuilder as Builder
# #
# print(ret[0]) # print(ret[0])
# print(ret[1]) # print(ret[1])
#
# info = {
# 'type': 'vless',
# 'server': '127.0.0.1',
# 'port': '12345',
# 'id': '58c0f2eb-5d47-45d0-8f5f-ebae5c2cfdd9',
# 'stream': {
# 'type': 'tcp',
# 'secure': {
# 'type': 'xtls',
# 'udp443': True
# }
# }
# }
#
# info = copy.deepcopy(Filter.filte(info)[1])
# print(info)
# Builder.build(info, '/tmp/ProxyC')
# time.sleep(5)
# Builder.destroy(info)
# info = {
# 'type': 'vmess',
# 'server': '127.0.0.1',
# 'port': 12345,
# 'id': '1f7aa040-94d8-4b53-ae85-af6946d550bb',
# 'stream': {
# 'type': 'h2',
# # 'host': 'dns.343.re',
# # 'path': '/test',
# # 'secure': {}
# # 'secure': {
# # 'sni': 'dns.343.re'
# # }
# }
# }
#
# ret = Filter.filte(info)
#
# print(ret[0])
# print(ret[1])
info = { info = {
'type': 'vless', 'type': 'vmess',
'server': '127.0.0.1', 'server': '127.0.0.1',
'port': '12345', 'port': '3345',
'id': '58c0f2eb-5d47-45d0-8f5f-ebae5c2cfdd9', 'id': '657b26d0-d25e-5b75-a018-40cb679c83a3',
'stream': { 'stream': {
'type': 'tcp', 'type': 'ws',
'host': None,
'path': '/test',
'ed': 2048,
'secure': { 'secure': {
'type': 'xtls', 'sni': 'dns.343.re',
'udp443': True 'alpn': 'h2,http/1.1'
} }
} }
} }
info = copy.deepcopy(Filter.filte(info)[1]) ret = Filter.filte(info)
print(info)
Builder.build(info, '/tmp/ProxyC') print(ret[0])
time.sleep(5) print(ret[1])
Builder.destroy(info)
data = Checker.proxyTest({
'check': ['http'],
'info': ret[1]
})
print(data)

16
docs/ProxyObject.md

@ -373,7 +373,7 @@
**secure** **secure**
+ 类型:*None* / *secureObject* + 类型:*secureObject*
+ 说明:TLS加密 + 说明:TLS加密
+ 缺省:None + 缺省:None
+ 可选值:不限 + 可选值:不限
@ -488,9 +488,9 @@
**alpn** **alpn**
+ 类型:*str* + 类型:*None* / *str*
+ 说明:TLS握手协商协议 + 说明:TLS握手协商协议
+ 缺省:'h2,http/1.1' + 缺省:None
+ 可选值:`h2`,`http/1.1`,`h2,http/1.1` + 可选值:`h2`,`http/1.1`,`h2,http/1.1`
+ 建议值:'h2,http/1.1' + 建议值:'h2,http/1.1'
@ -687,7 +687,7 @@
**secure** **secure**
+ 类型:*None* / *tlsObject* + 类型:*tlsObject*
+ 说明:TLS加密 + 说明:TLS加密
+ 缺省:None + 缺省:None
+ 可选值:不限 + 可选值:不限
@ -803,9 +803,9 @@
**alpn** **alpn**
+ 类型:*str* + 类型:*None* / *str*
+ 说明:TLS握手协商协议 + 说明:TLS握手协商协议
+ 缺省:'h2,http/1.1' + 缺省:None
+ 可选值:`h2`,`http/1.1`,`h2,http/1.1` + 可选值:`h2`,`http/1.1`,`h2,http/1.1`
+ 建议值:'h2,http/1.1' + 建议值:'h2,http/1.1'
@ -840,9 +840,9 @@
**alpn** **alpn**
+ 类型:*str* + 类型:*None* / *str*
+ 说明:TLS握手协商协议 + 说明:TLS握手协商协议
+ 缺省:'h2,http/1.1' + 缺省:None
+ 可选值:`h2`,`http/1.1`,`h2,http/1.1` + 可选值:`h2`,`http/1.1`,`h2,http/1.1`
+ 建议值:'h2,http/1.1' + 建议值:'h2,http/1.1'

Loading…
Cancel
Save