#!/usr/bin/python # -*- coding:utf-8 -*- import json ssrMethodList = [ # ShadowsocksR加密方式 'aes-128-cfb', 'aes-192-cfb', 'aes-256-cfb', 'aes-128-cfb1', 'aes-192-cfb1', 'aes-256-cfb1', 'aes-128-cfb8', 'aes-192-cfb8', 'aes-256-cfb8', 'aes-128-ctr', 'aes-192-ctr', 'aes-256-ctr', 'aes-128-gcm', 'aes-192-gcm', 'aes-256-gcm', 'aes-128-ofb', 'aes-192-ofb', 'aes-256-ofb', 'camellia-128-cfb', 'camellia-192-cfb', 'camellia-256-cfb', 'none', 'table', 'rc4', 'rc4-md5', 'rc4-md5-6', 'bf-cfb', 'cast5-cfb', 'des-cfb', 'idea-cfb', 'seed-cfb', 'rc2-cfb', 'salsa20', 'xsalsa20', 'chacha20', 'xchacha20', 'chacha20-ietf', ] ssrProtocolList = [ # ShadowsocksR协议列表 'origin', 'verify_sha1', 'verify_simple', 'verify_deflate', 'auth_simple', 'auth_sha1', 'auth_sha1_v2', 'auth_sha1_v4', 'auth_aes128', 'auth_aes128_md5', 'auth_aes128_sha1', 'auth_chain_a', 'auth_chain_b', 'auth_chain_c', 'auth_chain_d', 'auth_chain_e', 'auth_chain_f', ] ssrObfsList = [ # ShadowsocksR混淆方式 'plain', 'http_post', 'http_simple', 'tls_simple', 'tls1.2_ticket_auth', 'tls1.2_ticket_fastauth', 'random_head', ] def __ssrFormatCheck(proxyInfo: dict) -> bool: # ShadowsocksR参数检查 if 'server' not in proxyInfo or not isinstance(proxyInfo['server'], str): # server -> str return False if 'port' not in proxyInfo or not isinstance(proxyInfo['port'], int): # port -> int return False if 'method' not in proxyInfo or not isinstance(proxyInfo['method'], str): # method -> str return False if 'passwd' not in proxyInfo or not isinstance(proxyInfo['passwd'], str): # passwd -> str return False if 'protocol' not in proxyInfo or not isinstance(proxyInfo['protocol'], str): # protocol -> str return False if 'protocolParam' not in proxyInfo or not isinstance(proxyInfo['protocolParam'], str): # protocolParam -> str return False if 'obfs' not in proxyInfo or not isinstance(proxyInfo['obfs'], str): # obfs -> str return False if 'obfsParam' not in proxyInfo or not isinstance(proxyInfo['obfsParam'], str): # obfsParam -> str return False return True def load(proxyInfo: dict, socksPort: int, configFile: str) -> tuple[list or None, str or None, dict or None]: """ ShadowsocksR配置载入 proxyInfo: 节点信息 socksPort: 本地通讯端口 configFile: 配置文件路径 节点有误: return None, None, None 载入成功: return startCommand, fileContent, envVar """ if not __ssrFormatCheck(proxyInfo): # 参数有误 return None, None, None if not proxyInfo['method'] in ssrMethodList: # 匹配不到加密方法 return None, None, None if not proxyInfo['protocol'] in ssrProtocolList: # 匹配不到协议 return None, None, None if not proxyInfo['obfs'] in ssrObfsList: # 匹配不到混淆方式 return None, None, None config = { 'server': proxyInfo['server'], 'server_port': proxyInfo['port'], 'local_address': '127.0.0.1', 'local_port': socksPort, 'password': proxyInfo['passwd'], 'method': proxyInfo['method'], 'protocol': proxyInfo['protocol'], 'protocol_param': proxyInfo['protocolParam'], 'obfs': proxyInfo['obfs'], 'obfs_param': proxyInfo['obfsParam'] } return ['ssr-local', '-c', configFile], json.dumps(config), {}