Browse Source

feat: filter of ShadowsocksR

master
dnomd343 2 years ago
parent
commit
e1816b53cb
  1. 28
      Basis/Functions.py
  2. 2
      Filter/Shadowsocks.py
  3. 74
      Filter/ShadowsocksR.py
  4. 18
      demo.py

28
Basis/Functions.py

@ -1,6 +1,7 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
import re
import time import time
import uuid import uuid
import psutil import psutil
@ -10,9 +11,28 @@ from IPy import IP
from Basis.Logger import logging from Basis.Logger import logging
def isHost(raw) -> bool: def isIpAddr(ipAddr: str) -> bool:
# TODO: isHost function try:
return True if '/' in ipAddr: # filter CIDR
return False
if '.' not in ipAddr and ':' not in ipAddr: # not IPv4 or IPv6
return False
IP(ipAddr) # try to convert to IP address
return True # valid IP address
except:
return False
def isDomain(domain: str) -> bool:
try:
domainRegex = r'^(?=^.{3,255}$)[a-zA-Z0-9_][a-zA-Z0-9_-]{0,62}(\.[a-zA-Z0-9_][a-zA-Z0-9_-]{0,62})+$'
return re.search(domainRegex, domain) is not None # regex matching
except: # unexpected error
return False
def isHost(host: str) -> bool:
return isIpAddr(host) or isDomain(host) # IPv4 / IPv6 / Domain
def isPort(port: int) -> bool: def isPort(port: int) -> bool:
@ -22,7 +42,7 @@ def isPort(port: int) -> bool:
def md5Sum(data: str, encode: str = 'utf-8') -> str: def md5Sum(data: str, encode: str = 'utf-8') -> str:
return hashlib.md5(data.encode(encoding = encode)).hexdigest() return hashlib.md5(data.encode(encoding = encode)).hexdigest() # MD5 hash
def hostFormat(host: str, v6Bracket: bool = False) -> str: def hostFormat(host: str, v6Bracket: bool = False) -> str:

2
Filter/Shadowsocks.py

@ -10,7 +10,7 @@ from Basis.Functions import isHost, isPort
ssObject = rulesFilter({ ssObject = rulesFilter({
'server': { 'server': {
'type': str, 'type': str,
'format': toStr, 'format': lambda s: toStr(s).strip().lower(),
'filter': isHost, 'filter': isHost,
'errMsg': 'Invalid server address' 'errMsg': 'Invalid server address'
}, },

74
Filter/ShadowsocksR.py

@ -0,0 +1,74 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
from Basis.Filter import rulesFilter
from Basis.Functions import toInt, toStr
from Basis.Functions import isHost, isPort
from Basis.Constant import ssrMethods, ssrProtocols, ssrObfuscations
def ssrProtocolFormat(protocol: str) -> str:
protocol = toStr(protocol).strip().lower().replace('-', '_')
return 'origin' if protocol == '' else protocol # '' -> origin
def ssrObfsFormat(obfs: str) -> str:
obfs = toStr(obfs).strip().lower().replace('-', '_')
return 'plain' if obfs == '' else obfs # '' -> plain
ssrObject = rulesFilter({
'server': {
'type': str,
'format': lambda s: toStr(s).strip().lower(),
'filter': isHost,
'errMsg': 'Invalid server address'
},
'port': {
'type': int,
'format': toInt,
'filter': isPort,
'errMsg': 'Invalid port number'
},
'method': {
'type': str,
'format': lambda s: toStr(s).strip().lower().replace('_', '-'),
'filter': lambda s: s in ssrMethods,
'errMsg': 'Unknown ShadowsocksR method'
},
'passwd': {
'type': str,
'format': toStr,
'errMsg': 'Invalid password content'
},
'protocol': {
'optional': True,
'default': 'origin',
'type': str,
'format': ssrProtocolFormat,
'filter': lambda s: s in ssrProtocols,
'errMsg': 'Unknown ShadowsocksR protocol'
},
'protocolParam': {
'optional': True,
'default': '',
'type': str,
'format': toStr,
'errMsg': 'Invalid ShadowsocksR protocol param'
},
'obfs': {
'optional': True,
'default': 'plain',
'type': str,
'format': ssrObfsFormat,
'filter': lambda s: s in ssrObfuscations,
'errMsg': 'Unknown ShadowsocksR obfuscation'
},
'obfsParam': {
'optional': True,
'default': '',
'type': str,
'format': toStr,
'errMsg': 'Invalid ShadowsocksR obfuscation param'
}
})

18
demo.py

@ -4,8 +4,10 @@ from pprint import pprint
from Basis.Filter import Filter from Basis.Filter import Filter
from Basis.Filter import filterObject from Basis.Filter import filterObject
from Filter.Shadowsocks import ssObject from Filter.Shadowsocks import ssObject
from Filter.ShadowsocksR import ssrObject
# pprint(ssObject, sort_dicts = False) # pprint(ssObject, sort_dicts = False)
# pprint(ssrObject, sort_dicts = False)
# pprint(filterObject, sort_dicts = False) # pprint(filterObject, sort_dicts = False)
ssProxy = { ssProxy = {
@ -14,9 +16,19 @@ ssProxy = {
'method': 'none', 'method': 'none',
'passwd': 'dnomd343', 'passwd': 'dnomd343',
'plugin': { 'plugin': {
'type': 'obfs', 'type': 'obfs'
} }
} }
ret = Filter(ssProxy, ssObject)
ssrProxy = {
'server': '1.1.1.1',
'port': 12345,
'method': 'table',
'passwd': 'dnomd343',
'protocol': 'auth_chain-a',
'obfs': 'http_post'
}
# ret = Filter(ssProxy, ssObject)
ret = Filter(ssrProxy, ssrObject)
pprint(ret, sort_dicts = False) pprint(ret, sort_dicts = False)

Loading…
Cancel
Save