def modify_multi_user_table(self, new_table): self.multi_user_table = new_table.copy() self.multi_user_host_table = {} self._protocol.obfs.server_info.users = self.multi_user_table for id in self.multi_user_table: self.multi_user_host_table[common.get_mu_host( id, self.multi_user_table[id]['md5'])] = id if self.multi_user_table[id]['forbidden_ip'] is not None: self.multi_user_table[id]['_forbidden_iplist'] = IPNetwork( str(self.multi_user_table[id]['forbidden_ip'])) else: self.multi_user_table[id][ '_forbidden_iplist'] = IPNetwork(str("")) if self.multi_user_table[id]['disconnect_ip'] is not None: self.multi_user_table[id]['_disconnect_ipset'] = IPNetwork( str(self.multi_user_table[id]['disconnect_ip'])) else: self.multi_user_table[id]['_disconnect_ipset'] = None if self.multi_user_table[id]['forbidden_port'] is not None: self.multi_user_table[id]['_forbidden_portset'] = PortRange( str(self.multi_user_table[id]['forbidden_port'])) else: self.multi_user_table[id][ '_forbidden_portset'] = PortRange(str(""))
def get_config(is_local): global verbose config = {} config_path = None logging.basicConfig(level=logging.INFO, format='%(levelname)-s: %(message)s') if is_local: # 客户端模式 shortopts = 'hd:s:b:p:k:l:m:O:o:G:g:c:t:vq' longopts = ['help', 'fast-open', 'pid-file=', 'log-file=', 'user='******'version'] else: # 服务器模式 shortopts = 'hd:s:p:k:m:O:o:G:g:c:t:vq' longopts = ['help', 'fast-open', 'pid-file=', 'log-file=', 'workers=', 'forbidden-ip=', 'user='******'manager-address=', 'version'] try: optlist, args = getopt.getopt(sys.argv[1:], shortopts, longopts) # 返回筛选后的命令行的(选项,值)序列 for key, value in optlist: if key == '-c': config_path = value elif key in ('-h', '--help'): print_help(is_local) sys.exit(0) elif key == '--version': print_shadowsocks() sys.exit(0) else: continue if config_path is None: config_path = find_config() if config_path: logging.debug('loading config from %s' % config_path) print(config_path) with open(config_path, 'rb') as f: try: config = parse_json_in_str(remove_comment(f.read().decode('utf8'))) except ValueError as e: logging.error('found an error in config.json: %s', str(e)) sys.exit(1) v_count = 0 for key, value in optlist: if key == '-p': config['server_port'] = int(value) elif key == '-k': config['password'] = to_bytes(value) elif key == '-l': config['local_port'] = int(value) elif key == '-s': config['server'] = to_str(value) elif key == '-m': config['method'] = to_str(value) elif key == '-O': config['protocol'] = to_str(value) elif key == '-o': config['obfs'] = to_str(value) elif key == '-G': config['protocol_param'] = to_str(value) elif key == '-g': config['obfs_param'] = to_str(value) elif key == '-b': config['local_address'] = to_str(value) elif key == '-v': v_count += 1 # '-vv' turns on more verbose mode config['verbose'] = v_count elif key == '-t': config['timeout'] = int(value) elif key == '--fast-open': config['fast_open'] = True elif key == '--workers': config['workers'] = int(value) elif key == '--manager-address': config['manager_address'] = value elif key == '--user': config['user'] = to_str(value) elif key == '--forbidden-ip': config['forbidden_ip'] = to_str(value) elif key == '-d': config['daemon'] = to_str(value) elif key == '--pid-file': config['pid-file'] = to_str(value) elif key == '--log-file': config['log-file'] = to_str(value) elif key == '-q': v_count -= 1 config['verbose'] = v_count else: continue except getopt.GetoptError as e: print(e, file=sys.stderr) print_help(is_local) sys.exit(2) if not config: logging.error('config not specified') print_help(is_local) sys.exit(2) config['password'] = to_bytes(config.get('password', b'')) config['method'] = to_str(config.get('method', 'aes-256-cfb')) config['protocol'] = to_str(config.get('protocol', 'origin')) config['protocol_param'] = to_str(config.get('protocol_param', '')) config['obfs'] = to_str(config.get('obfs', 'plain')) config['obfs_param'] = to_str(config.get('obfs_param', '')) config['port_password'] = config.get('port_password', None) config['additional_ports'] = config.get('additional_ports', {}) config['additional_ports_only'] = config.get('additional_ports_only', False) config['timeout'] = int(config.get('timeout', 300)) config['udp_timeout'] = int(config.get('udp_timeout', 120)) config['udp_cache'] = int(config.get('udp_cache', 64)) config['fast_open'] = config.get('fast_open', False) config['workers'] = config.get('workers', 1) config['pid-file'] = config.get('pid-file', '/var/run/shadowsocksr.pid') # 进程标识符文件 config['log-file'] = config.get('log-file', '/var/log/shadowsocksr.log') # 日志 config['verbose'] = config.get('verbose', False) config['connect_verbose_info'] = config.get('connect_verbose_info', 0) config['local_address'] = to_str(config.get('local_address', '127.0.0.1')) config['local_port'] = config.get('local_port', 1080) if is_local: if config.get('server', None) is None: logging.error('server addr not specified') print_local_help() sys.exit(2) else: config['server'] = to_str(config['server']) else: config['server'] = to_str(config.get('server', '0.0.0.0')) try: config['forbidden_ip'] = \ IPNetwork(config.get('forbidden_ip', '127.0.0.0/8,::1/128')) except Exception as e: logging.error(e) sys.exit(2) try: config['forbidden_port'] = PortRange(config.get('forbidden_port', '')) except Exception as e: logging.error(e) sys.exit(2) try: config['ignore_bind'] = \ IPNetwork(config.get('ignore_bind', '127.0.0.0/8,::1/128,10.0.0.0/8,192.168.0.0/16')) except Exception as e: logging.error(e) sys.exit(2) config['server_port'] = config.get('server_port', 8388) logging.getLogger('').handlers = [] logging.addLevelName(VERBOSE_LEVEL, 'VERBOSE') if config['verbose'] >= 2: level = VERBOSE_LEVEL elif config['verbose'] == 1: level = logging.DEBUG elif config['verbose'] == -1: level = logging.WARN elif config['verbose'] <= -2: level = logging.ERROR else: level = logging.INFO verbose = config['verbose'] logging.basicConfig(level=level, format='%(asctime)s %(levelname)-8s %(filename)s:%(lineno)s %(message)s', datefmt='%Y-%m-%d %H:%M:%S') check_config(config, is_local) return config
def get_config(is_local): global verbose logging.basicConfig(level=logging.INFO, format='%(levelname)-s: %(message)s') if is_local: shortopts = 'hd:s:b:p:k:l:m:c:t:vq' longopts = [ 'help', 'fast-open', 'pid-file=', 'log-file=', 'user='******'version' ] else: shortopts = 'hd:s:p:k:m:c:t:vq' longopts = [ 'help', 'fast-open', 'pid-file=', 'log-file=', 'workers=', 'forbidden-ip=', 'user='******'version' ] try: config_path = find_config() optlist, args = getopt.getopt(sys.argv[1:], shortopts, longopts) for key, value in optlist: if key == '-c': config_path = value if config_path: logging.info('loading config from %s' % config_path) with open(config_path, 'rb') as f: try: config = json.loads(f.read().decode('utf8'), object_hook=_decode_dict) except ValueError as e: logging.error('found an error in config.json: %s', e.message) sys.exit(1) else: config = {} v_count = 0 for key, value in optlist: if key == '-p': config['server_port'] = int(value) elif key == '-k': config['password'] = to_bytes(value) elif key == '-l': config['local_port'] = int(value) elif key == '-s': config['server'] = to_str(value) elif key == '-m': config['method'] = to_str(value) elif key == '-b': config['local_address'] = to_str(value) elif key == '-v': v_count += 1 # '-vv' turns on more verbose mode config['verbose'] = v_count elif key == '-t': config['timeout'] = int(value) elif key == '--fast-open': config['fast_open'] = True elif key == '--workers': config['workers'] = int(value) elif key == '--user': config['user'] = to_str(value) elif key == '--forbidden-ip': config['forbidden_ip'] = to_str(value).split(',') elif key in ('-h', '--help'): if is_local: print_local_help() else: print_server_help() sys.exit(0) elif key == '--version': print_shadowsocks() sys.exit(0) elif key == '-d': config['daemon'] = to_str(value) elif key == '--pid-file': config['pid-file'] = to_str(value) elif key == '--log-file': config['log-file'] = to_str(value) elif key == '-q': v_count -= 1 config['verbose'] = v_count except getopt.GetoptError as e: print(e, file=sys.stderr) print_help(is_local) sys.exit(2) if not config: logging.error('config not specified') print_help(is_local) sys.exit(2) config['password'] = to_bytes(config.get('password', b'')) config['method'] = to_str(config.get('method', 'aes-256-cfb')) config['port_password'] = config.get('port_password', None) config['timeout'] = int(config.get('timeout', 300)) config['fast_open'] = config.get('fast_open', False) config['workers'] = config.get('workers', 1) config['pid-file'] = config.get('pid-file', '/var/run/shadowsocks.pid') config['log-file'] = config.get('log-file', '/var/log/shadowsocks.log') config['verbose'] = config.get('verbose', False) config['local_address'] = to_str(config.get('local_address', '127.0.0.1')) config['local_port'] = config.get('local_port', 1080) if is_local: if config.get('server', None) is None: logging.error('server addr not specified') print_local_help() sys.exit(2) else: config['server'] = to_str(config['server']) else: config['server'] = to_str(config.get('server', '0.0.0.0')) try: config['forbidden_ip'] = \ IPNetwork(config.get('forbidden_ip', '127.0.0.0/8,::1/128')) except Exception as e: logging.error(e) sys.exit(2) config['server_port'] = config.get('server_port', 8388) logging.getLogger('').handlers = [] logging.addLevelName(VERBOSE_LEVEL, 'VERBOSE') if config['verbose'] >= 2: level = VERBOSE_LEVEL elif config['verbose'] == 1: level = logging.DEBUG elif config['verbose'] == -1: level = logging.WARN elif config['verbose'] <= -2: level = logging.ERROR else: level = logging.INFO verbose = config['verbose'] logging.basicConfig(level=level, format='%(asctime)s %(levelname)-8s %(message)s', datefmt='%Y-%m-%d %H:%M:%S') check_config(config, is_local) return config
def check_config(config, is_local): if config.get('daemon', None) == 'stop': # no need to specify configuration for daemon stop return if is_local: if config.get('server', None) is None: logging.error('server addr not specified') print_local_help() sys.exit(2) else: config['server'] = to_str(config['server']) if config.get('tunnel_remote', None) is None: logging.error('tunnel_remote addr not specified') print_local_help() sys.exit(2) else: config['tunnel_remote'] = to_str(config['tunnel_remote']) else: config['server'] = to_str(config.get('server', '0.0.0.0')) try: config['forbidden_ip'] = \ IPNetwork(config.get('forbidden_ip', '127.0.0.0/8,::1/128')) except Exception as e: logging.error(e) sys.exit(2) if is_local and not config.get('password', None): logging.error('password not specified') print_help(is_local) sys.exit(2) if not is_local and not config.get('password', None) \ and not config.get('port_password', None) \ and not config.get('manager_address', None): logging.error('password or port_password not specified') print_help(is_local) sys.exit(2) if 'local_port' in config: config['local_port'] = int(config['local_port']) if not config.get('server_port', None) and not config.get( 'manager_address', None): config['server_port'] = int(8388) if 'tunnel_remote_port' in config: config['tunnel_remote_port'] = int(config['tunnel_remote_port']) if 'tunnel_port' in config: config['tunnel_port'] = int(config['tunnel_port']) if config.get('local_address', '') in [b'0.0.0.0']: logging.warn('warning: local set to listen on 0.0.0.0, it\'s not safe') if config.get('server', '') in ['127.0.0.1', 'localhost']: logging.warn('warning: server set to listen on %s:%s, are you sure?' % (to_str(config['server']), config['server_port'])) if (config.get('method', '') or '').lower() == 'table': logging.warn('warning: table is not safe; please use a safer cipher, ' 'like AES-256-CFB') if (config.get('method', '') or '').lower() == 'rc4': logging.warn('warning: RC4 is not safe; please use a safer cipher, ' 'like AES-256-CFB') if config.get('timeout', 300) < 100: logging.warn('warning: your timeout %d seems too short' % int(config.get('timeout'))) if config.get('timeout', 300) > 600: logging.warn('warning: your timeout %d seems too long' % int(config.get('timeout'))) if config.get('password') in [b'mypassword']: logging.error('DON\'T USE DEFAULT PASSWORD! Please change it in your ' 'config.json!') sys.exit(1) if config.get('user', None) is not None: if os.name != 'posix': logging.error('user can be used only on Unix') sys.exit(1) if config.get('dns_server', None) is not None: if type(config['dns_server']) != list: config['dns_server'] = to_str(config['dns_server']) else: config['dns_server'] = [to_str(ds) for ds in config['dns_server']] logging.info('Specified DNS server: %s' % config['dns_server']) config['crypto_path'] = { 'openssl': config['libopenssl'], 'mbedtls': config['libmbedtls'], 'sodium': config['libsodium'] } cryptor.try_cipher(config['password'], config['method'], config['crypto_path'])
def get_config(is_local): """ 获得配置(额外指令) :param is_local: 是否客户端操作(否则使用服务器端那一套指令) :return: None """ global verbose logging.basicConfig(level=logging.INFO, format='%(levelname)-s: %(message)s') # 客户端使用if成立的指令,否则使用else的 if is_local: shortopts = 'hd:s:b:p:k:l:m:c:t:vq' longopts = [ 'help', 'fast-open', 'pid-file=', 'log-file=', 'user='******'version' ] else: shortopts = 'hd:s:p:k:m:c:t:vq' longopts = [ 'help', 'fast-open', 'pid-file=', 'log-file=', 'workers=', 'forbidden-ip=', 'user='******'manager-address=', 'version' ] try: config_path = find_config() optlist, args = getopt.getopt(sys.argv[1:], shortopts, longopts) for key, value in optlist: if key == '-c': config_path = value if config_path: logging.info('loading config from %s' % config_path) with open(config_path, 'rb') as f: try: config = parse_json_in_str(f.read().decode('utf8')) except ValueError as e: logging.error('found an error in config.json: %s', e.message) sys.exit(1) else: config = {} v_count = 0 for key, value in optlist: #服务器端口 if key == '-p': config['server_port'] = int(value) #密码 elif key == '-k': config['password'] = to_bytes(value) #客户端端口号 elif key == '-l': config['local_port'] = int(value) #服务器的地址,服务器端默认0.0.0.0 elif key == '-s': config['server'] = to_str(value) #加密模式,默认AES-256 elif key == '-m': config['method'] = to_str(value) #客户端独有,客户端绑定地址 elif key == '-b': config['local_address'] = to_str(value) #verbose模式 elif key == '-v': v_count += 1 # '-vv' turns on more verbose mode config['verbose'] = v_count #设置timeout,默认300 elif key == '-t': config['timeout'] = int(value) #tcp快速打开,需要python3.7以上 elif key == '--fast-open': config['fast_open'] = True #同时允许接入的客户端数? elif key == '--workers': config['workers'] = int(value) #服务器管理员UDP地址 elif key == '--manager-address': config['manager_address'] = value #打印用户列表 elif key == '--user': config['user'] = to_str(value) #服务器端,打印被禁止的ip列表 elif key == '--forbidden-ip': config['forbidden_ip'] = to_str(value).split(',') #打印帮助 elif key in ('-h', '--help'): if is_local: print_local_help() else: print_server_help() sys.exit(0) #打印版本号 elif key == '--version': print_shadowsocks() sys.exit(0) #开启/停止/重启daemon模式 elif key == '-d': config['daemon'] = to_str(value) #daemon模式,pid文件 elif key == '--pid-file': config['pid-file'] = to_str(value) #daemon模式,log文件 elif key == '--log-file': config['log-file'] = to_str(value) #安静模式 elif key == '-q': v_count -= 1 config['verbose'] = v_count except getopt.GetoptError as e: print(e, file=sys.stderr) print_help(is_local) sys.exit(2) if not config: logging.error('config not specified') print_help(is_local) sys.exit(2) config['password'] = to_bytes(config.get('password', b'')) config['method'] = to_str(config.get('method', 'aes-256-cfb')) config['port_password'] = config.get('port_password', None) config['timeout'] = int(config.get('timeout', 300)) config['fast_open'] = config.get('fast_open', False) config['workers'] = config.get('workers', 1) config['pid-file'] = config.get('pid-file', '/var/run/shadowsocks.pid') config['log-file'] = config.get('log-file', '/var/log/shadowsocks.log') config['verbose'] = config.get('verbose', False) config['local_address'] = to_str(config.get('local_address', '127.0.0.1')) config['local_port'] = config.get('local_port', 1080) if is_local: #服务器未指定,打印客户端帮助 if config.get('server', None) is None: logging.error('server addr not specified') print_local_help() sys.exit(2) else: config['server'] = to_str(config['server']) else: config['server'] = to_str(config.get('server', '0.0.0.0')) try: config['forbidden_ip'] = \ IPNetwork(config.get('forbidden_ip', '127.0.0.0/8,::1/128')) except Exception as e: logging.error(e) sys.exit(2) config['server_port'] = config.get('server_port', 8388) logging.getLogger('').handlers = [] logging.addLevelName(VERBOSE_LEVEL, 'VERBOSE') if config['verbose'] >= 2: level = VERBOSE_LEVEL elif config['verbose'] == 1: level = logging.DEBUG elif config['verbose'] == -1: level = logging.WARN elif config['verbose'] <= -2: level = logging.ERROR else: level = logging.INFO verbose = config['verbose'] logging.basicConfig(level=level, format='%(asctime)s %(levelname)-8s %(message)s', datefmt='%Y-%m-%d %H:%M:%S') check_config(config, is_local) return config
def __init__( self, config, dns_resolver, is_local, stat_callback=None, stat_counter=None): self._config = config if config.get('connect_verbose_info', 0) > 0: common.connect_log = logging.info if config.get('connect_hex_data', 0) > 0: self._connect_hex_data = True else: self._connect_hex_data = False if is_local: self._listen_addr = config['local_address'] self._listen_port = config['local_port'] self._remote_addr = config['server'] self._remote_port = config['server_port'] else: self._listen_addr = config['server'] self._listen_port = config['server_port'] self._remote_addr = None self._remote_port = None self._dns_resolver = dns_resolver self._password = common.to_bytes(config['password']) self._method = config['method'] self._timeout = config['timeout'] self._is_local = is_local self._udp_cache_size = config['udp_cache'] self._cache = lru_cache.LRUCache( timeout=config['udp_timeout'], close_callback=self._close_client_pair) self._cache_dns_client = lru_cache.LRUCache( timeout=10, close_callback=self._close_client_pair) self._client_fd_to_server_addr = {} #self._dns_cache = lru_cache.LRUCache(timeout=1800) self._eventloop = None self._closed = False self.server_transfer_ul = 0 self.server_transfer_dl = 0 self.connected_iplist = [] self.wrong_iplist = {} self.detect_log_list = [] self.is_cleaning_connected_iplist = False self.is_cleaning_wrong_iplist = False self.is_cleaning_detect_log = False self.is_cleaning_mu_detect_log_list = False self.is_cleaning_mu_connected_iplist = False if 'users_table' in self._config: self.multi_user_table = self._config['users_table'] self.mu_server_transfer_ul = {} self.mu_server_transfer_dl = {} self.mu_connected_iplist = {} self.mu_detect_log_list = {} self.is_pushing_detect_hex_list = False self.is_pushing_detect_text_list = False self.detect_hex_list = self._config['detect_hex_list'].copy() self.detect_text_list = self._config['detect_text_list'].copy() self.protocol_data = obfs.obfs(config['protocol']).init_data() self._protocol = obfs.obfs(config['protocol']) server_info = obfs.server_info(self.protocol_data) server_info.host = self._listen_addr server_info.port = self._listen_port if 'users_table' in self._config: server_info.users = self.multi_user_table else: server_info.users = {} server_info.is_multi_user = config["is_multi_user"] server_info.protocol_param = config['protocol_param'] server_info.obfs_param = '' server_info.iv = b'' server_info.recv_iv = b'' server_info.key_str = common.to_bytes(config['password']) try: server_info.key = encrypt.encrypt_key(self._password, self._method) except Exception: logging.error("UDP: method not support") server_info.key = b'' server_info.head_len = 30 server_info.tcp_mss = 1452 server_info.buffer_size = BUF_SIZE server_info.overhead = 0 self._protocol.set_server_info(server_info) self._sockets = set() self._fd_to_handlers = {} self._reqid_to_hd = {} self._data_to_write_to_server_socket = [] self._timeouts = [] # a list for all the handlers # we trim the timeouts once a while self._timeout_offset = 0 # last checked position for timeout self._handler_to_timeouts = {} # key: handler value: index in timeouts self._bind = config.get('out_bind', '') self._bindv6 = config.get('out_bindv6', '') self._ignore_bind_list = config.get('ignore_bind', []) if 'forbidden_ip' in config: self._forbidden_iplist = IPNetwork(config['forbidden_ip']) else: self._forbidden_iplist = None if 'forbidden_port' in config: self._forbidden_portset = PortRange(config['forbidden_port']) else: self._forbidden_portset = None if 'disconnect_ip' in config: self._disconnect_ipset = IPNetwork(config['disconnect_ip']) else: self._disconnect_ipset = None self._relay_rules = self._config['relay_rules'].copy() self._is_pushing_relay_rules = False addrs = socket.getaddrinfo(self._listen_addr, self._listen_port, 0, socket.SOCK_DGRAM, socket.SOL_UDP) if len(addrs) == 0: raise Exception("can't get addrinfo for %s:%d" % (self._listen_addr, self._listen_port)) af, socktype, proto, canonname, sa = addrs[0] server_socket = socket.socket(af, socktype, proto) server_socket.bind((self._listen_addr, self._listen_port)) server_socket.setblocking(False) server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_SNDBUF, 1024 * 1024) server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_RCVBUF, 1024 * 1024) self._server_socket = server_socket self._stat_callback = stat_callback
def get_config(is_local): global verbose if is_local: shortopts = 'hd:s:b:p:k:l:m:c:t:vq' longopts = ['help', 'fast-open', 'pid-file=', 'log-file=', 'user='******'version'] else: shortopts = 'hd:s:p:k:m:c:t:vq' longopts = ['help', 'fast-open', 'pid-file=', 'log-file=', 'workers=', 'forbidden-ip=', 'user='******'manager-address=', 'version'] try: config_path = find_config() optlist, args = getopt.getopt(sys.argv[1:], shortopts, longopts) for key, value in optlist: if key == '-c': config_path = value if config_path: logging.info('loading config from %s' % config_path) with open(config_path, 'rb') as f: try: #config = json.loads(f.read()) config = json.loads(f.read().decode('utf8'),object_hook=_decode_dict) except ValueError as e: logging.error('found an error in config.json: [%s] .. Please make sure path like: [C:\\ss\\ss.log] on win platform' % str(e)) sys.exit(1) else: config = {} v_count = 0 for key, value in optlist: if key == '-p': config['server_port'] = int(value) elif key == '-k': config['password'] = to_bytes(value) elif key == '-l': config['local_port'] = int(value) elif key == '-s': config['server'] = to_str(value) elif key == '-m': config['method'] = to_str(value) elif key == '-b': config['local_address'] = to_str(value) elif key == '-v': v_count += 1 # '-vv' turns on more verbose mode config['verbose'] = v_count elif key == '-t': config['timeout'] = int(value) elif key == '--fast-open': config['fast_open'] = True elif key == '--workers': config['workers'] = int(value) elif key == '--user': config['user'] = to_str(value) elif key == '--forbidden-ip': config['forbidden_ip'] = to_str(value).split(',') elif key in ('-h', '--help'): if is_local: print_local_help() else: print_server_help() sys.exit(0) elif key == '--version': print_shadowsocks() sys.exit(0) elif key == '--manager-address': config['manager_address'] = value elif key == '-d': config['daemon'] = to_str(value) elif key == '--pid-file': config['pid-file'] = to_str(value) elif key == '--log-file': config['log-file'] = to_str(value) elif key == '-q': v_count -= 1 config['verbose'] = v_count except getopt.GetoptError as e: print(e, file=sys.stderr) print_help(is_local) sys.exit(2) if not config: logging.error('config not specified') print_help(is_local) sys.exit(2) config['password'] = to_bytes(config.get('password', b'')) config['server_port'] = to_bytes(config.get('server_port', b'')) config['method'] = to_str(config.get('method', 'aes-256-cfb')) config['port_password'] = config.get('port_password', None) config['timeout'] = int(config.get('timeout', 300)) config['fast_open'] = config.get('fast_open', False) config['workers'] = config.get('workers', 1) if "ss_no_change" in str(os.getcwd()): ak = "ss_no_change" log_ak = "ss_no_change" elif "ss_hub" in str(os.getcwd()): ak = "ss_hub" log_ak = "ss_hub" else: ak = "ss" log_ak = "ss" config['pid-file'] = config.get('pid-file', "/var/run/shadowsocks_%s.pid" % ak) config['log-file'] = config.get('log-file', "/var/log/shadowsocks_%s.log" % log_ak) config['verbose'] = config.get('verbose', False) config['local_address'] = to_str(config.get('local_address', '127.0.0.1')) config['local_port'] = config.get('local_port', 1080) config['log'] = config.get('log',{'log_enable':'','log_path':''}) config['forbid'] = config.get('forbid',{'site':[''],'port':['']}) if is_local: if config.get('server', None) is None: logging.error('server addr not specified') print_local_help() sys.exit(2) else: if type(config["server"]) == list and config['server']: config["server"] = to_str(random.choice(config["server"])).strip() elif type(config['server']) is list and len(config['server']) == 0: logging.error("You must write your VPS ips in config['server']") sys.exit(2) elif type(config['server']) is str and len(config['server']) == 0: logging.error("You must write your VPS ips in config['server']") sys.exit(2) else: config['server'] = to_str(config['server']) else: config['server'] = to_str(config.get('server', '0.0.0.0')) try: config['forbidden_ip'] = IPNetwork(config.get('forbidden_ip', '127.0.0.0/8,::1/128'),config) except Exception as e: logging.error(e) sys.exit(2) logging.getLogger('').handlers = [] if config['verbose'] >= 2: level = logging.NOTSET elif config['verbose'] == 1: level = logging.DEBUG elif config['verbose'] == -1: level = logging.WARN elif config['verbose'] <= -2: level = logging.ERROR else: level = logging.INFO verbose = config['verbose'] logging.basicConfig(level=level, format='%(asctime)s %(levelname)-8s %(message)s', datefmt='%Y-%m-%d %H:%M:%S') check_config(config, is_local) return config
def get_config(is_local): """ :param is_local: 布尔值,是否本地 :return: """ global verbose # logging.basicConfig() 打印日志 logging.basicConfig(level=logging.INFO, format='%(levelname)-s: %(message)s') # 设定段格式命令和长格式命令-和--(-h和--help的区别) if is_local: shortopts = 'hd:s:b:p:k:l:m:c:t:vq' longopts = ['help', 'fast-open', 'pid-file=', 'log-file=', 'user='******'version'] else: shortopts = 'hd:s:p:k:m:c:t:vq' longopts = ['help', 'fast-open', 'pid-file=', 'log-file=', 'workers=', 'forbidden-ip=', 'user='******'manager-address=', 'version'] try: config_path = find_config() # getopt 处理命令行参数的,对命令行进行截取 optlist, args = getopt.getopt(sys.argv[1:], shortopts, longopts) for key, value in optlist: # 如果命令是-c,则配置文件路径按照给定的value设定 if key == '-c': config_path = value if config_path: # 如果日志文件存在,日志打印从路径载入配置文件,如果配置文件不存在,在配置文件为空 logging.info('loading config from %s' % config_path) with open(config_path, 'rb') as f: try: config = parse_json_in_str(f.read().decode('utf8')) except ValueError as e: logging.error('found an error in config.json: %s', e.message) sys.exit(1) else: config = {} v_count = 0 for key, value in optlist: # 检查配置参数,然后为ss配置赋值 if key == '-p': config['server_port'] = int(value) elif key == '-k': config['password'] = to_bytes(value) elif key == '-l': config['local_port'] = int(value) elif key == '-s': config['server'] = to_str(value) elif key == '-m': config['method'] = to_str(value) elif key == '-b': config['local_address'] = to_str(value) elif key == '-v': v_count += 1 # '-vv' turns on more verbose mode config['verbose'] = v_count elif key == '-t': config['timeout'] = int(value) elif key == '--fast-open': config['fast_open'] = True elif key == '--workers': config['workers'] = int(value) elif key == '--manager-address': config['manager_address'] = value elif key == '--user': config['user'] = to_str(value) elif key == '--forbidden-ip': config['forbidden_ip'] = to_str(value).split(',') elif key in ('-h', '--help'): if is_local: print_local_help() else: print_server_help() sys.exit(0) elif key == '--version': print_shadowsocks() sys.exit(0) elif key == '-d': config['daemon'] = to_str(value) elif key == '--pid-file': config['pid-file'] = to_str(value) elif key == '--log-file': config['log-file'] = to_str(value) elif key == '-q': v_count -= 1 config['verbose'] = v_count except getopt.GetoptError as e: print(e, file=sys.stderr) print_help(is_local) sys.exit(2) if not config: logging.error('config not specified') print_help(is_local) sys.exit(2) # 重新赋值,如果不存在的时候设置默认值 config['password'] = to_bytes(config.get('password', b'')) config['method'] = to_str(config.get('method', 'aes-256-cfb')) config['port_password'] = config.get('port_password', None) config['timeout'] = int(config.get('timeout', 300)) config['fast_open'] = config.get('fast_open', False) config['workers'] = config.get('workers', 1) config['pid-file'] = config.get('pid-file', '/var/run/shadowsocks.pid') config['log-file'] = config.get('log-file', '/var/log/shadowsocks.log') config['verbose'] = config.get('verbose', False) config['local_address'] = to_str(config.get('local_address', '127.0.0.1')) config['local_port'] = config.get('local_port', 1080) if is_local: if config.get('server', None) is None: # 如果server地址没有被指定 logging.error('server addr not specified') print_local_help() sys.exit(2) else: config['server'] = to_str(config['server']) else: config['server'] = to_str(config.get('server', '0.0.0.0')) try: config['forbidden_ip'] = \ IPNetwork(config.get('forbidden_ip', '127.0.0.0/8,::1/128')) except Exception as e: logging.error(e) sys.exit(2) config['server_port'] = config.get('server_port', 8388) # 日志对象,logging模块中最基础的对象,用logging.getLogger(name)方法进行初始化 # name可以不填。通常logger的名字我们对应模块名,如聊天模块、数据库模块、验证模块等。 # 要进行日志输出必须有一个handler才行 logging.getLogger('').handlers = [] logging.addLevelName(VERBOSE_LEVEL, 'VERBOSE') if config['verbose'] >= 2: level = VERBOSE_LEVEL elif config['verbose'] == 1: level = logging.DEBUG elif config['verbose'] == -1: level = logging.WARN elif config['verbose'] <= -2: level = logging.ERROR else: level = logging.INFO verbose = config['verbose'] logging.basicConfig(level=level, format='%(asctime)s %(levelname)-8s %(message)s', datefmt='%Y-%m-%d %H:%M:%S') check_config(config, is_local) return config
def get_config(is_local): global verbose logging.basicConfig(level=logging.INFO, format='%(levelname)-s: %(message)s') if is_local: shortopts = 'hd:s:b:p:k:l:m:c:t:vq' longopts = [ 'help', 'fast-open', 'pid-file=', 'log-file=', 'user='******'version' ] else: shortopts = 'hd:s:p:k:m:c:t:vq' longopts = [ 'help', 'fast-open', 'pid-file=', 'log-file=', 'workers=', 'forbidden-ip=', 'user='******'manager-address=', 'version' ] try: config_path = find_config() optlist, args = getopt.getopt(sys.argv[1:], shortopts, longopts) for key, value in optlist: if key == '-c': config_path = value if config_path: logging.info('loading config from %s' % config_path) with open(config_path, 'rb') as f: try: config = parse_json_in_str(f.read().decode('utf8')) except ValueError as e: logging.error('found an error in config.json: %s', e.message) sys.exit(1) else: config = {} v_count = 0 for key, value in optlist: if key == '-p': config['server_port'] = int(value) # 服务器端口 elif key == '-k': config['password'] = to_bytes(value) # 帐号密码 elif key == '-l': config['local_port'] = int(value) # 本地端口号 elif key == '-s': config['server'] = to_str(value) # 境外VPS的IP elif key == '-m': config['method'] = to_str(value) # 加密模式 elif key == '-b': config['local_address'] = to_str(value) # 本地IP地址 elif key == '-v': v_count += 1 # '-vv' turns on more verbose mode config['verbose'] = v_count elif key == '-t': config['timeout'] = int(value) # 超时时间 elif key == '--fast-open': config['fast_open'] = True elif key == '--workers': config['workers'] = int(value) # 开启线程数 elif key == '--manager-address': config['manager_address'] = value elif key == '--user': config['user'] = to_str(value) # 用户角色 elif key == '--forbidden-ip': config['forbidden_ip'] = to_str(value).split(',') elif key in ('-h', '--help'): # 输出帮助信息文档 if is_local: print_local_help() else: print_server_help() sys.exit(0) elif key == '--version': # 输出版本信息 print_shadowsocks() sys.exit(0) elif key == '-d': config['daemon'] = to_str(value) # 开启守护进程 elif key == '--pid-file': config['pid-file'] = to_str(value) elif key == '--log-file': config['log-file'] = to_str(value) #log文件路径 elif key == '-q': v_count -= 1 config['verbose'] = v_count except getopt.GetoptError as e: print(e, file=sys.stderr) print_help(is_local) sys.exit(2) # config 为None 时, 返回错误信息 if not config: logging.error('config not specified') print_help(is_local) sys.exit(2) config['password'] = to_bytes(config.get('password', b'')) config['method'] = to_str(config.get('method', 'aes-256-cfb')) # 加密模式,默认为aes-256-cfb config['port_password'] = config.get('port_password', None) # 多用户配置 config['timeout'] = int(config.get('timeout', 300)) # 超时时间,默认为300秒 config['fast_open'] = config.get('fast_open', False) config['workers'] = config.get('workers', 1) # 线程数,默认开启一个线程 config['pid-file'] = config.get('pid-file', '/var/run/shadowsocks.pid') # pid文件保存路径 config['log-file'] = config.get('log-file', '/var/log/shadowsocks.log') # log文件保存路径 config['verbose'] = config.get('verbose', False) # 默认不开启冗余模式 config['local_address'] = to_str(config.get('local_address', '127.0.0.1')) # 本地代理地址 config['local_port'] = config.get('local_port', 1080) # 本地代理端口,程序与系统通信端口 # 如果时客户端配置,需要指明 境外VPS的IP地址 if is_local: if config.get('server', None) is None: logging.error('server addr not specified') print_local_help() sys.exit(2) else: config['server'] = to_str(config['server']) else: config['server'] = to_str(config.get('server', '0.0.0.0')) try: config['forbidden_ip'] = \ IPNetwork(config.get('forbidden_ip', '127.0.0.0/8,::1/128')) except Exception as e: logging.error(e) sys.exit(2) config['server_port'] = config.get('server_port', 8388) # 设置服务器端口,如果没有就采用默认值:8388 logging.getLogger('').handlers = [] logging.addLevelName(VERBOSE_LEVEL, 'VERBOSE') if config['verbose'] >= 2: level = VERBOSE_LEVEL elif config['verbose'] == 1: level = logging.DEBUG elif config['verbose'] == -1: level = logging.WARN elif config['verbose'] <= -2: level = logging.ERROR else: level = logging.INFO verbose = config['verbose'] logging.basicConfig(level=level, format='%(asctime)s %(levelname)-8s %(message)s', datefmt='%Y-%m-%d %H:%M:%S') check_config(config, is_local) # 检查配置信息是否有效,有效就返回配置信息,无效就报错 return config