def __init__(self): # only support Linux and require 'epoll' model. if hasattr(select, 'epoll'): self._impl = select.epoll() logging.info('Using event model: epoll.') else: exit.error('only support Linux and require \'epoll\' model.') self._fdmap = {} # (f, handler) self._last_time = time.time() self._periodic_callbacks = [] self._stopping = False
def check(): try: opts, args = getopt.getopt(sys.argv[1:], 'hv', ['help', 'version']) for opt, param in opts: if opt in ('-h', '--help'): print(conf.help_msg()) exit.ok() if opt in ('-v', '--version'): print(conf.version()) exit.ok() except getopt.GetoptError: print(' Error: args checked.') print(conf.help_msg()) exit.error()
def run_server(): def child_handler(signum, _): logger.warning('received SIGQUIT, doing graceful shutting down..') list(map(lambda s: s.close(next_tick=True), tcp_servers + udp_servers)) signal.signal(getattr(signal, 'SIGQUIT', signal.SIGTERM), child_handler) def int_handler(signum, _): sys.exit(1) signal.signal(signal.SIGINT, int_handler) try: loop = eventloop.EventLoop() dns_resolver.add_to_loop(loop) list(map(lambda s: s.add_to_loop(loop), tcp_servers + udp_servers)) daemon.set_user(ssr_conf.get('user', None)) loop.run() except Exception as e: exit.error(e)
def check_config(config: Dict, is_local: bool): if is_local and not config.get('password'): exit.error('password not defined.') if not is_local and not config.get('password') \ and not config.get('port_password'): exit.error('password or port_password not defined.') if config.get('local_address') == '0.0.0.0': logger.warning( 'warning: local set to listen on 0.0.0.0, it\'s not safe') if config.get('server') in ['127.0.0.1', 'localhost']: logger.warning( 'warning: server set to listen on %s:%s, are you sure?' % (common.to_str(config['server']), config['server_port'])) if config.get('timeout') < 100: logger.warning('warning: your timeout %d seems too short' % int(config.get('timeout'))) if config.get('timeout') > 600: logger.warning('warning: your timeout %d seems too long' % int(config.get('timeout'))) encrypt.try_cipher(config['password'], config['method'])
def main(): import logging # -- import from shadowsockesr-v import conf import exit import shell import eventloop import tcprelay import udprelay import asyncdns # -- init logging -- conf.logger_init() # show version logging.info(conf.version()) # -- starting ssr -- # get ssr configurations ssr_conf = shell.get_ssr_conf(ssr_conf_path=conf.ssr_conf_path()) if not ssr_conf.get('dns_ipv6', False): asyncdns.IPV6_CONNECTION_SUPPORT = False password = ssr_conf['password'] method = ssr_conf['method'] protocol = ssr_conf['protocol'] protocol_param = ssr_conf['protocol_param'] obfs = ssr_conf['obfs'] obfs_param = ssr_conf['obfs_param'] udp_enable = ssr_conf['udp_enable'] dns_list = ssr_conf['dns'] logging.info(f'Server start with ' f'password [{password}] ' f'method [{method}] ' f'protocol[{protocol}] ' f'protocol_param[{protocol_param}] ' f'obfs [{obfs}] ' f'obfs_param [{obfs_param}]') server = ssr_conf['server'] port = ssr_conf['server_port'] logging.info(f'Starting server at [{server}]:{port}') try: ssr_conf['out_bind'] = '' ssr_conf['out_bindv6'] = '' # create epoll (singleton) loop = eventloop.EventLoop() # dns server (singleton) dns_resolver = asyncdns.DNSResolver(dns_list) dns_resolver.add_to_loop(loop) stat_counter_dict = {} # listen tcp && register socket tcp = tcprelay.TCPRelay(ssr_conf, dns_resolver, stat_counter=stat_counter_dict) tcp.add_to_loop(loop) if udp_enable: # listen udp && register socket udp = udprelay.UDPRelay(ssr_conf, dns_resolver, False, stat_counter=stat_counter_dict) udp.add_to_loop(loop) # run epoll to handle socket loop.run() except Exception as e: exit.error(e)
def check_file_path(file: str): if is_blank(file): exit.error(f'Blank file path. [arg -> {file}]') if not os.path.exists(file): exit.error('Not found file.')
def get_ssr_conf(ssr_conf_path: str) -> Dict: _ssr_conf: Dict = utils.parse_json(ssr_conf_path) if not _ssr_conf: exit.error('Require ssr-config.') # -- check params -- port = _ssr_conf.get('server_port') if port is None: exit.error('Require \'server_port\'.') if type(port) != int or port <= 0: exit.error('Illegal \'server_port\'.') password = _ssr_conf.get('password') if common.is_blank(password): exit.error('Require \'password\'.') method = _ssr_conf.get('method') if common.is_blank(method): exit.error('Require \'method\'.') if not encrypt.is_supported(method): exit.error(f'Not supported method [{method}]') protocol = _ssr_conf.get('protocol') if common.is_blank(protocol): exit.error('Require \'protocol\'.') obfs = _ssr_conf.get('obfs') if common.is_blank(obfs): exit.error('Require \'obfs\'.') # -- default params -- _ssr_conf['server'] = '::' _ssr_conf['password'] = common.to_bytes(_ssr_conf['password']) _ssr_conf['protocol_param'] = _ssr_conf.get('protocol_param', '') _ssr_conf['obfs_param'] = _ssr_conf.get('obfs_param', '') # process default data try: _ssr_conf['forbidden_ip'] = \ common.IPNetwork(_ssr_conf.get('forbidden_ip', '127.0.0.0/8,::1/128')) except Exception as e: exit.error('error configuration \'forbidden_ip\'.') try: _ssr_conf['forbidden_port'] = common.PortRange( _ssr_conf.get('forbidden_port', '')) except Exception as e: exit.error('error configuration \'forbidden_port\'.') try: _ssr_conf['ignore_bind'] = \ common.IPNetwork(_ssr_conf.get('ignore_bind', '127.0.0.0/8,::1/128,10.0.0.0/8,192.168.0.0/16')) except Exception as e: exit.error('error configuration \'ignore_bind\'.') return _ssr_conf
def get_ssr_conf(is_local: bool, ssr_conf_path: str): _ssr_conf: Dict = utils.parse_json(ssr_conf_path) if not _ssr_conf: exit.error('ssr-config not defined.') # process default data if is_local: if _ssr_conf.get('server') is None: exit.error('server addr not defined.') else: _ssr_conf['server'] = common.to_str(_ssr_conf['server']) else: _ssr_conf['server'] = common.to_str(_ssr_conf.get('server', '0.0.0.0')) try: _ssr_conf['forbidden_ip'] = \ common.IPNetwork(_ssr_conf.get('forbidden_ip', '127.0.0.0/8,::1/128')) except Exception as e: exit.error('error configuration \'forbidden_ip\'.') try: _ssr_conf['forbidden_port'] = common.PortRange( _ssr_conf.get('forbidden_port', '')) except Exception as e: exit.error('error configuration \'forbidden_port\'.') try: _ssr_conf['ignore_bind'] = \ common.IPNetwork(_ssr_conf.get('ignore_bind', '127.0.0.0/8,::1/128,10.0.0.0/8,192.168.0.0/16')) except Exception as e: exit.error('error configuration \'ignore_bind\'.') _ssr_conf['server_port'] = int(_ssr_conf.get('server_port', 8388)) _ssr_conf['local_address'] = common.to_str( _ssr_conf.get('local_address', '127.0.0.1')) _ssr_conf['local_port'] = int(_ssr_conf.get('local_port', 1080)) _ssr_conf['password'] = common.to_bytes(_ssr_conf.get('password', b'')) _ssr_conf['method'] = common.to_str(_ssr_conf.get('method', 'aes-128-ctr')) _ssr_conf['protocol'] = common.to_str( _ssr_conf.get('protocol', 'auth_aes128_md5')) _ssr_conf['protocol_param'] = common.to_str( _ssr_conf.get('protocol_param', '')) _ssr_conf['obfs'] = common.to_str( _ssr_conf.get('obfs', 'tls1.2_ticket_auth')) _ssr_conf['obfs_param'] = common.to_str(_ssr_conf.get('obfs_param', '')) _ssr_conf['port_password'] = None _ssr_conf['additional_ports'] = _ssr_conf.get('additional_ports', {}) _ssr_conf['additional_ports_only'] = \ _ssr_conf.get('additional_ports_only') is not None and 'true' == _ssr_conf.get('additional_ports_only') _ssr_conf['timeout'] = int(_ssr_conf.get('timeout', 120)) _ssr_conf['udp_timeout'] = int(_ssr_conf.get('udp_timeout', 60)) _ssr_conf['udp_cache'] = int(_ssr_conf.get('udp_cache', 64)) _ssr_conf['fast_open'] = _ssr_conf.get( 'fast_open') is not None and 'true' == _ssr_conf.get('fast_open') _ssr_conf['workers'] = _ssr_conf.get('workers', 1) _ssr_conf['pid-file'] = _ssr_conf.get('pid-file', '/var/run/shadowsocksr.pid') _ssr_conf['log-file'] = _ssr_conf.get('log-file', '/var/log/shadowsocksr.log') _ssr_conf['verbose'] = _ssr_conf.get( 'verbose') is not None and 'true' == _ssr_conf.get('verbose') _ssr_conf['connect_verbose_info'] = _ssr_conf.get('connect_verbose_info', 0) check_config(_ssr_conf, is_local) return _ssr_conf