Browse Source

update: release Filter module

master
dnomd343 2 years ago
parent
commit
53451eebb5
  1. 12
      Filter/Brook.py
  2. 13
      Filter/Hysteria.py
  3. 8
      Filter/Shadowsocks.py
  4. 13
      Filter/ShadowsocksR.py
  5. 10
      Filter/Trojan.py
  6. 13
      Filter/TrojanGo.py
  7. 19
      Filter/V2ray.py
  8. 10
      Filter/VLESS.py
  9. 10
      Filter/VMess.py
  10. 2
      Filter/Xray.py
  11. 77
      Filter/__init__.py
  12. 61
      demo.py
  13. 4
      docs/ProxyObject/Trojan.md
  14. 4
      docs/ProxyObject/VLESS.md
  15. 2
      docs/ProxyObject/VMess.md

12
Filter/Brook.py

@ -1,8 +1,9 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
from Basis.Filter import rulesFilter
import copy
from Basis.Functions import isHost, isPort
from Basis.Filter import Filter, rulesFilter
from Basis.Functions import toInt, toStr, toStrTidy, toBool
secureObject = rulesFilter({
@ -99,3 +100,12 @@ brookObject = rulesFilter({
'errMsg': 'Invalid Brook stream'
}
})
def brookFilter(proxyInfo: dict) -> dict:
proxyInfo = copy.deepcopy(proxyInfo)
proxyInfo = Filter(proxyInfo, brookObject) # run filter
stream = proxyInfo['stream']
if stream['type'] == 'ws' and stream['host'] == '':
stream['host'] = proxyInfo['server'] # fill host option in WebSocket stream
return proxyInfo

13
Filter/Hysteria.py

@ -1,10 +1,11 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
from Basis.Filter import rulesFilter
import copy
from Basis.Functions import isHost, isPort
from Basis.Filter import Filter, rulesFilter
from Basis.Constant import hysteriaProtocols
from Basis.Functions import toInt, toStr, toStrTidy, toBool
from Basis.Functions import isIpAddr, toInt, toStr, toStrTidy, toBool
hysteriaObject = rulesFilter({
'server': {
@ -84,3 +85,11 @@ hysteriaObject = rulesFilter({
'errMsg': 'Invalid verify option'
}
})
def hysteriaFilter(proxyInfo: dict) -> dict:
proxyInfo = copy.deepcopy(proxyInfo)
proxyInfo = Filter(proxyInfo, hysteriaObject) # run filter
if proxyInfo['sni'] == '' and not isIpAddr(proxyInfo['server']):
proxyInfo['sni'] = proxyInfo['server']
return proxyInfo

8
Filter/Shadowsocks.py

@ -1,10 +1,11 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
from Basis.Filter import rulesFilter
import copy
from Filter.Plugin import pluginObject
from Basis.Constant import ssAllMethods
from Basis.Functions import isHost, isPort
from Basis.Filter import Filter, rulesFilter
from Basis.Functions import toInt, toStr, toStrTidy
ssObject = rulesFilter({
@ -39,3 +40,8 @@ ssObject = rulesFilter({
'errMsg': 'Invalid plugin options'
}
})
def ssFilter(proxyInfo: dict) -> dict:
proxyInfo = copy.deepcopy(proxyInfo)
return Filter(proxyInfo, ssObject) # run filter

13
Filter/ShadowsocksR.py

@ -1,8 +1,9 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
from Basis.Filter import rulesFilter
import copy
from Basis.Functions import isHost, isPort
from Basis.Filter import Filter, rulesFilter
from Basis.Functions import toInt, toStr, toStrTidy
from Basis.Constant import ssrMethods, ssrProtocols, ssrObfuscations
@ -72,3 +73,13 @@ ssrObject = rulesFilter({
'errMsg': 'Invalid ShadowsocksR obfuscation param'
}
})
def ssrFilter(proxyInfo: dict) -> dict:
proxyInfo = copy.deepcopy(proxyInfo)
proxyInfo = Filter(proxyInfo, ssrObject) # run filter
if proxyInfo['protocol'] == 'origin': # origin without param
proxyInfo['protocolParam'] = ''
if proxyInfo['obfs'] == 'plain': # plain without param
proxyInfo['obfsParam'] = ''
return proxyInfo

10
Filter/Trojan.py

@ -1,9 +1,10 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import copy
from Filter import Xray
from Basis.Filter import rulesFilter
from Basis.Functions import isHost, isPort
from Basis.Filter import Filter, rulesFilter
from Basis.Functions import toInt, toStr, toStrTidy
trojanObject = rulesFilter({
@ -41,3 +42,10 @@ trojanObject = rulesFilter({
'errMsg': 'Invalid Trojan stream'
}
})
def trojanFilter(proxyInfo: dict) -> dict:
proxyInfo = copy.deepcopy(proxyInfo)
proxyInfo = Filter(proxyInfo, trojanObject) # run filter
Xray.addSni(proxyInfo) # add SNI option
return proxyInfo

13
Filter/TrojanGo.py

@ -1,11 +1,12 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
from Basis.Filter import rulesFilter
import copy
from Filter.Plugin import pluginObject
from Basis.Constant import trojanGoMethods
from Basis.Functions import isHost, isPort
from Basis.Functions import toInt, toStr, toStrTidy, toBool
from Basis.Filter import Filter, rulesFilter
from Basis.Functions import isIpAddr, toInt, toStr, toStrTidy, toBool
ssObject = rulesFilter({
'method': {
@ -105,3 +106,11 @@ trojanGoObject = rulesFilter({
'errMsg': 'Invalid plugin options'
}
})
def trojanGoFilter(proxyInfo: dict) -> dict:
proxyInfo = copy.deepcopy(proxyInfo)
proxyInfo = Filter(proxyInfo, trojanGoObject) # run filter
if proxyInfo['sni'] == '' and not isIpAddr(proxyInfo['server']):
proxyInfo['sni'] = proxyInfo['server']
return proxyInfo

19
Filter/V2ray.py

@ -3,7 +3,7 @@
from Basis.Filter import rulesFilter
from Basis.Constant import quicMethods, udpObfuscations
from Basis.Functions import toInt, toStr, toStrTidy, toBool
from Basis.Functions import isIpAddr, toInt, toStr, toStrTidy, toBool
tlsObject = rulesFilter({
'sni': {
@ -237,3 +237,20 @@ grpcObject = rulesFilter({
'errMsg': 'Invalid secure options'
}
})
def addSni(proxyInfo: dict) -> None:
stream = proxyInfo['stream']
if stream['secure'] is None or stream['secure']['sni'] != '': # don't need to set SNI
return
if not isIpAddr(proxyInfo['server']):
stream['secure']['sni'] = proxyInfo['server'] # set SNI as server address (domain case)
sniContent = ''
if stream['type'] == 'tcp' and stream['obfs'] is not None: # obfs host in TCP stream
sniContent = stream['obfs']['host'].split(',')[0]
elif stream['type'] == 'ws': # WebSocket host
sniContent = stream['host']
elif stream['type'] == 'h2': # HTTP/2 host
sniContent = stream['host'].split(',')[0]
if sniContent != '':
stream['secure']['sni'] = sniContent # overwrite SNI content

10
Filter/VLESS.py

@ -1,9 +1,10 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import copy
from Filter import Xray
from Basis.Filter import rulesFilter
from Basis.Functions import isHost, isPort
from Basis.Filter import Filter, rulesFilter
from Basis.Functions import toInt, toStrTidy
vlessObject = rulesFilter({
@ -49,3 +50,10 @@ vlessObject = rulesFilter({
'errMsg': 'Invalid VLESS stream'
}
})
def vlessFilter(proxyInfo: dict) -> dict:
proxyInfo = copy.deepcopy(proxyInfo)
proxyInfo = Filter(proxyInfo, vlessObject) # run filter
Xray.addSni(proxyInfo) # add SNI option
return proxyInfo

10
Filter/VMess.py

@ -1,10 +1,11 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import copy
from Filter import V2ray
from Basis.Filter import rulesFilter
from Basis.Constant import vmessMethods
from Basis.Functions import isHost, isPort
from Basis.Filter import Filter, rulesFilter
from Basis.Functions import toInt, toStrTidy
vmessObject = rulesFilter({
@ -59,4 +60,9 @@ vmessObject = rulesFilter({
}
})
# TODO: add SNI / ws host / h2 host
def vmessFilter(proxyInfo: dict) -> dict:
proxyInfo = copy.deepcopy(proxyInfo)
proxyInfo = Filter(proxyInfo, vmessObject) # run filter
V2ray.addSni(proxyInfo) # add SNI option
return proxyInfo

2
Filter/Xray.py

@ -162,3 +162,5 @@ grpcObject = rulesFilter({
**copy.deepcopy(V2ray.grpcObject),
'secure': secureRule_2 # None / tlsObject
})
addSni = V2ray.addSni

77
Filter/__init__.py

@ -1,60 +1,27 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
xxObject = { # a dict that describe multi-field
'field_1': {
'optional': ..., # field force require or not
'default': ..., # default value when field is not exist (optional == True)
'allowNone': ..., # whether the value can be None (override the format and filter process)
'type': ..., # type of field content (in filter process) (any / type / list / dict)
'multiSub': ..., # whether there are multi subObject (type is dict)
'indexKey': ..., # index key of subObject (type is dict and multiSub == True)
'format': ..., # format function (before filter process) (invalid content -> throw error)
'filter': ..., # filter function -> bool (throw error when return False)
'errMsg': ..., # raise message if there is something error
},
'field_2': {
...
},
...
from Filter.Brook import brookFilter
from Filter.VMess import vmessFilter
from Filter.VLESS import vlessFilter
from Filter.Trojan import trojanFilter
from Filter.Shadowsocks import ssFilter
from Filter.ShadowsocksR import ssrFilter
from Filter.TrojanGo import trojanGoFilter
from Filter.Hysteria import hysteriaFilter
filterEntry = {
'ss': ssFilter,
'ssr': ssrFilter,
'vmess': vmessFilter,
'vless': vlessFilter,
'trojan': trojanFilter,
'trojan-go': trojanGoFilter,
'brook': brookFilter,
'hysteria': hysteriaFilter,
}
default value
+ optional: False
+ default: None
+ allowNone: False
+ format: lambda -> return same thing
+ type: force require
+ multiSub: False
+ indexKey: 'type'
+ filter: lambda -> return True
+ errMsg: 'filter error'
pre process
=> field not exist
=> optional == False -> throw errMsg
=> optional == True -> set as default value -> continue
=> field exist
=> filed is None
=> allowNone is False -> throw errMsg
=> allowNone is True -> break
=> field is not None -> continue
format process -> set as field value (maybe throw error -> catch and throw errMsg)
filter process
=> type is `any` -> filter function check (skip type compare)
=> type is `type` -> compare with field type -> filter function check
=> type is `list` -> compare every type in list with field -> filter function check
=> type is `dict`
=> multiSub == False -> recursive check
=> multiSub == True
=> field content is not dict or not include indexKey -> throw error
=> others
=> indexKey's content not in type (dict) -> throw error
=> others -> recursive check
"""
def Filter(proxyType: str, proxyInfo: dict) -> dict:
if proxyType not in filterEntry:
raise RuntimeError('Unknown proxy type')
return filterEntry[proxyType](proxyInfo)

61
demo.py

@ -1,26 +1,7 @@
#!/usr/bin/env python
from pprint import pprint
from Basis.Filter import Filter
from Basis.Filter import filterObject
from Filter.Shadowsocks import ssObject
from Filter.ShadowsocksR import ssrObject
from Filter.VMess import vmessObject
from Filter.VLESS import vlessObject
from Filter.Trojan import trojanObject
from Filter.TrojanGo import trojanGoObject
from Filter.Brook import brookObject
from Filter.Hysteria import hysteriaObject
# pprint(ssObject, sort_dicts = False)
# pprint(ssrObject, sort_dicts = False)
# pprint(vmessObject, sort_dicts = False)
# pprint(vlessObject, sort_dicts = False)
# pprint(trojanObject, sort_dicts = False)
# pprint(trojanGoObject, sort_dicts = False)
# pprint(brookObject, sort_dicts = False)
# pprint(hysteriaObject, sort_dicts = False)
# pprint(filterObject, sort_dicts = False)
from Filter import Filter
ssProxy = {
'server': '1.1.1.1',
@ -38,7 +19,9 @@ ssrProxy = {
'method': 'table',
'passwd': 'dnomd343',
'protocol': 'auth_chain-a',
'obfs': 'http_post'
'protocolParam': '123',
'obfs': 'plain',
'obfsParam': 'ok',
}
vmessProxy = {
@ -51,7 +34,7 @@ vmessProxy = {
'service': 'no-gfw',
'mode': ' multi ',
'secure': {
'sni': ' DNOMD343.top',
'sni': '',
'alpn': 'h2, http/1.1',
'verify': 'False '
}
@ -66,7 +49,7 @@ vlessProxy = {
'stream': {
'type': 'grpc',
'service': 'dnomd343',
'secure': None,
# 'secure': None,
# 'secure': {
# 'type': 'tls',
# 'sni': '23333',
@ -85,16 +68,18 @@ vlessProxy = {
}
trojanProxy = {
'server': '1.1.1.1',
'server': 'www.dnomd343.top',
'port': 12345,
'passwd': b'dnomd343',
'stream': {
'type': 'grpc',
# 'type': 'grpc',
'type': 'h2',
# 'host': '343.re',
'service': 'dnomd343',
# 'secure': None,
'secure': {
'type': 'tls',
'sni': '23333',
'sni': '',
'alpn': 'h2',
'verify': 0
}
@ -110,10 +95,10 @@ trojanProxy = {
}
trojanGoProxy = {
'server': '1.1.1.1',
'server': '343.re',
'port': 12345,
'passwd': 'dnomd343',
'sni': '343.re',
'sni': '',
'alpn': ' h2',
'verify': 'FALSE',
'ws': {
@ -146,24 +131,24 @@ brookProxy = {
}
hysteriaProxy = {
'server': '1.1.1.1',
'server': 'www.343.re',
'port': 12345,
'protocol': 'faketcp',
'obfs': '1234',
'passwd': 'dnomd343',
'up': 100,
'down': 500,
'sni': '343.re',
'sni': '',
'alpn': 'h3',
'verify': 'FALSE',
}
# ret = Filter(ssProxy, ssObject)
# ret = Filter(ssrProxy, ssrObject)
# ret = Filter(vmessProxy, vmessObject)
# ret = Filter(vlessProxy, vlessObject)
# ret = Filter(trojanProxy, trojanObject)
# ret = Filter(trojanGoProxy, trojanGoObject)
# ret = Filter(brookProxy, brookObject)
ret = Filter(hysteriaProxy, hysteriaObject)
# ret = Filter('ss', ssProxy)
# ret = Filter('ssr', ssrProxy)
# ret = Filter('vmess', vmessProxy)
# ret = Filter('vless', vlessProxy)
# ret = Filter('trojan', trojanProxy)
# ret = Filter('trojan-go', trojanGoProxy)
# ret = Filter('brook', brookProxy)
ret = Filter('hysteria', hysteriaProxy)
pprint(ret, sort_dicts = False)

4
docs/ProxyObject/Trojan.md

@ -275,7 +275,7 @@
+ 类型:*str*
+ 说明:TLS握手SNI字段
+ 缺省:`obfsObject.host[0]` / `wsObject.host` / `h2Object.host[0]` / `空`
+ 缺省:`空`
+ 限制:无
### alpn
@ -309,7 +309,7 @@
+ 类型:*str*
+ 说明:TLS握手SNI字段
+ 缺省:`obfsObject.host[0]` / `wsObject.host` / `h2Object.host[0]` / `空`
+ 缺省:`空`
+ 限制:无
### alpn

4
docs/ProxyObject/VLESS.md

@ -283,7 +283,7 @@
+ 类型:*str*
+ 说明:TLS握手SNI字段
+ 缺省:`obfsObject.host[0]` / `wsObject.host` / `h2Object.host[0]` / `空`
+ 缺省:`空`
+ 限制:无
### alpn
@ -317,7 +317,7 @@
+ 类型:*str*
+ 说明:TLS握手SNI字段
+ 缺省:`obfsObject.host[0]` / `wsObject.host` / `h2Object.host[0]` / `空`
+ 缺省:`空`
+ 限制:无
### alpn

2
docs/ProxyObject/VMess.md

@ -290,7 +290,7 @@
+ 类型:*str*
+ 说明:TLS握手SNI字段
+ 缺省:`obfsObject.host[0]` / `wsObject.host` / `h2Object.host[0]` / `空`
+ 缺省:`空`
+ 限制:无
### alpn

Loading…
Cancel
Save