def pull_db_users(self, conn): try: switchrule = importloader.load('switchrule') keys = switchrule.getKeys(self.key_list) except Exception as e: keys = self.key_list cur = conn.cursor() node_info_keys = ['traffic_rate'] cur.execute("SELECT " + ','.join(node_info_keys) +" FROM ss_node where `id`='" + str(self.cfg["node_id"]) + "'") nodeinfo = cur.fetchone() if nodeinfo == None: rows = [] cur.close() conn.commit() return rows cur.close() node_info_dict = {} for column in range(len(nodeinfo)): node_info_dict[node_info_keys[column]] = nodeinfo[column] self.cfg['transfer_mul'] = float(node_info_dict['traffic_rate']) cur = conn.cursor() cur.execute("SELECT " + ','.join(keys) + " FROM user") rows = [] for r in cur.fetchall(): d = {} for column in range(len(keys)): d[keys[column]] = r[column] rows.append(d) cur.close() return rows
def pull_db_users(self, conn): keys = copy.copy(self.key_list) try: switchrule = importloader.load('switchrule') keymap = switchrule.getRowMap() for key in keymap: if keymap[key] in keys: keys.remove(keymap[key]) keys.append(key) keys = switchrule.getKeys(keys) except Exception as e: logging.error('load switchrule.py fail') cur = conn.cursor() if self.update_node_state: node_info_keys = ['traffic_rate'] try: cur.execute("SELECT " + ','.join(node_info_keys) + " FROM node where `id`='" + str(self.cfg["node_id"]) + "'") nodeinfo = cur.fetchone() except Exception as e: logging.error(e) nodeinfo = None if nodeinfo == None: rows = [] cur.close() conn.commit() logging.warn( 'None result when select node info from ss_node in db, maybe you set the incorrect node id' ) return rows cur.close() node_info_dict = {} for column in range(len(nodeinfo)): node_info_dict[node_info_keys[column]] = nodeinfo[column] self.cfg['transfer_mul'] = float(node_info_dict['traffic_rate']) cur = conn.cursor() try: rows = [] cur.execute("SELECT " + ','.join(keys) + " FROM user WHERE port > 0") for r in cur.fetchall(): d = {} for column in range(len(keys)): d[keys[column]] = r[column] rows.append(d) except Exception as e: logging.error(e) cur.close() return rows
def pull_db_users(self, conn): '''拉取所有符合要求的用户''' try: switchrule = importloader.load('switchrule') keys = switchrule.getKeys(self.key_list) except Exception as e: keys = self.key_list # 节点信息的获取 cur = conn.cursor() # 增加节点等级字段 node_info_keys = ['traffic_rate', 'level'] try: sql = "SELECT " + \ ','.join(node_info_keys) + " FROM ss_node where `id`='" + \ str(self.cfg["node_id"]) + "'" cur.execute(sql) nodeinfo = cur.fetchone() except Exception as e: logging.error(e) nodeinfo = None if nodeinfo == None: rows = [] cur.close() conn.commit() logging.warn( '没有查询到满足要求的user,请检查自己的node_id!') return rows cur.close() # 流量比例设置 node_info_dict = {} for column in range(len(nodeinfo)): node_info_dict[node_info_keys[column]] = nodeinfo[column] self.cfg['transfer_mul'] = float(node_info_dict['traffic_rate']) cur = conn.cursor() try: rows = [] # 增加用户等级判断 # 只适用于django-sspanel sql = "SELECT " + \ ','.join(keys) + " FROM user WHERE `level` >=" + \ str(node_info_dict['level']) cur.execute(sql) for r in cur.fetchall(): d = {} for column in range(len(keys)): d[keys[column]] = r[column] rows.append(d) except Exception as e: logging.error(e) cur.close() return rows
def pull_db_users(self, conn): try: switchrule = importloader.load('switchrule') keys = switchrule.getKeys(self.key_list) except Exception as e: keys = self.key_list cur = conn.cursor() if self.update_node_state: node_info_keys = ['traffic_rate'] try: cur.execute("SELECT " + ','.join(node_info_keys) + " FROM ss_node where `id`='" + str(self.cfg["node_id"]) + "'") nodeinfo = cur.fetchone() except Exception as e: logging.error(e) nodeinfo = None if nodeinfo == None: rows = [] cur.close() conn.commit() logging.warn( 'None result when select node info from ss_node in db, maybe you set the incorrect node id' ) return rows cur.close() node_info_dict = {} for column in range(len(nodeinfo)): node_info_dict[node_info_keys[column]] = nodeinfo[column] self.cfg['transfer_mul'] = float(node_info_dict['traffic_rate']) cur = conn.cursor() try: rows = [] cur.execute("SELECT " + ','.join(keys) + " FROM ssr_user where enable = 1 and serverId=" + str(self.cfg["node_id"])) for r in cur.fetchall(): d = {} for column in range(len(keys)): d[keys[column]] = r[column] rows.append(d) except Exception as e: logging.error(e) cur.close() return rows
def pull_db_users(self, conn): #拉取所有符合要求的用户 try: switchrule = importloader.load('switchrule') keys = switchrule.getKeys(self.key_list) except Exception as e: keys = self.key_list # 节点信息的获取 # cur = conn.cursor() # node_info_keys = ['traffic_rate'] # try: # cur.execute("SELECT " + ','.join(node_info_keys) +" FROM ss_node where `id`='" + str(self.cfg["node_id"]) + "'") # nodeinfo = cur.fetchone() # except Exception as e: # logging.error(e) # nodeinfo = None # if nodeinfo == None: # rows = [] # cur.close() # conn.commit() # logging.warn('None result when select node info from ss_node in db, maybe you set the incorrect node id') # return rows # cur.close() # 流量比例设置 # node_info_dict = {} # for column in range(len(nodeinfo)): # node_info_dict[node_info_keys[column]] = nodeinfo[column] # self.cfg['transfer_mul'] = float(node_info_dict['traffic_rate']) cur = conn.cursor() try: rows = [] if isinstance(self.cfg["node_class"],int): cur.execute("SELECT " + ','.join(keys) + " FROM user WHERE user_class >= " + str(self.cfg["node_class"])) else: cur.execute("SELECT " + ','.join(keys) + " FROM user WHERE user_class = '" + self.cfg["node_class"] +"'") for r in cur.fetchall(): d = {} for column in range(len(keys)): d[keys[column]] = r[column] rows.append(d) except Exception as e: logging.error(e) cur.close() return rows
def pull_db_users(self, conn): try: switchrule = importloader.load('switchrule') keys = switchrule.getKeys(self.key_list) except Exception as e: keys = self.key_list cur = conn.cursor() cur.execute("SELECT " + ','.join(keys) + " FROM user") rows = [] for r in cur.fetchall(): d = {} for column in range(len(keys)): d[keys[column]] = r[column] rows.append(d) cur.close() return rows
def pull_db_users(self, conn): try: switchrule = importloader.load('switchrule') keys = switchrule.getKeys(self.key_list) except Exception as e: keys = self.key_list cur = conn.cursor() cur.execute("SELECT " + ','.join(keys) + " FROM user") rows = [] for r in cur.fetchall(): d = {} for column in range(len(keys)): d[keys[column]] = r[column] rows.append(d) cur.close() return rows
def pull_db_users(self, conn): try: switchrule = importloader.load('switchrule') keys = switchrule.getKeys(self.key_list) except Exception as e: keys = self.key_list cur = conn.cursor() if self.update_node_state: node_info_keys = ['traffic_rate'] try: cur.execute("SELECT " + ','.join(node_info_keys) +" FROM ss_node where `id`='" + str(self.cfg["node_id"]) + "'") nodeinfo = cur.fetchone() except Exception as e: logging.error(e) nodeinfo = None if nodeinfo == None: rows = [] cur.close() conn.commit() logging.warn('None result when select node info from ss_node in db, maybe you set the incorrect node id') return rows cur.close() node_info_dict = {} for column in range(len(nodeinfo)): node_info_dict[node_info_keys[column]] = nodeinfo[column] self.cfg['transfer_mul'] = float(node_info_dict['traffic_rate']) cur = conn.cursor() try: rows = [] cur.execute("SELECT " + ','.join(keys) + " FROM user") for r in cur.fetchall(): d = {} for column in range(len(keys)): d[keys[column]] = r[column] rows.append(d) except Exception as e: logging.error(e) cur.close() return rows
def pull_db_users(self, conn): keys = copy.copy(self.key_list) try: switchrule = importloader.load('switchrule') keymap = switchrule.getRowMap() for key in keymap: if keymap[key] in keys: keys.remove(keymap[key]) keys.append(key) keys = switchrule.getKeys(keys) except Exception as e: logging.error('load switchrule.py fail') cur = conn.cursor() # 这里获取节点的sort 等级 if self.update_node_state: try: cur.execute("SELECT " + 'level' + " FROM ss_node where `id`='" + str(self.cfg["node_id"]) + "'") nodeinfo = cur.fetchone() except Exception as e: logging.error(e) nodeinfo = None node_level = float(nodeinfo[0]) cur.close() cur = conn.cursor() try: rows = [] cur.execute( "SELECT " + ','.join(keys) + " FROM user where port != 0 and status = 1 and level >= " + str(node_level)) #这里获取等级大于node_level的节点 for r in cur.fetchall(): d = {} for column in range(len(keys)): d[keys[column]] = r[column] rows.append(d) except Exception as e: logging.error(e) cur.close() return rows
def pull_db_users(self, conn): try: switchrule = importloader.load('switchrule') keys = switchrule.getKeys(self.key_list) except Exception as e: keys = self.key_list # 注释理由同上 # cur = conn.cursor() # node_info_keys = ['traffic_rate'] # cur.execute("SELECT " + ','.join(node_info_keys) +" FROM ss_node where `id`='" + str(self.cfg["node_id"]) + "'") # nodeinfo = cur.fetchone() # if nodeinfo == None: # rows = [] # cur.close() # conn.commit() # logging.warn('None result when select node info from ss_node in db, maybe you set the incorrect node id') # return rows # cur.close() # node_info_dict = {} # for column in range(len(nodeinfo)): # node_info_dict[node_info_keys[column]] = nodeinfo[column] # self.cfg['transfer_mul'] = float(node_info_dict['traffic_rate']) cur = conn.cursor() cur.execute("SELECT " + ','.join(keys) + " FROM user") rows = [] for r in cur.fetchall(): d = {} for column in range(len(keys)): d[keys[column]] = r[column] rows.append(d) cur.close() return rows
def pull_db_users(self, conn): keys = copy.copy(self.key_list) try: switchrule = importloader.load('switchrule') keymap = switchrule.getRowMap() for key in keymap: if keymap[key] in keys: keys.remove(keymap[key]) keys.append(key) keys = switchrule.getKeys(keys) except Exception as e: logging.error('load switchrule.py fail') cur = conn.cursor() cur.execute("SELECT " + ','.join(keys) + " FROM user") rows = [] for r in cur.fetchall(): d = {} for column in range(len(keys)): d[keys[column]] = r[column] rows.append(d) cur.close() return rows
def del_server_out_of_bound_safe(self, last_rows, rows): #停止超流量的服务 #启动没超流量的服务 #需要动态载入switchrule,以便实时修改规则 try: switchrule = importloader.load('switchrule') except Exception as e: logging.error('load switchrule.py fail') cur_servers = {} new_servers = {} md5_users = {} for row in rows: if row['is_multi_user'] == 1: continue md5_users[row['id']] = row.copy() del md5_users[row['id']]['u'] del md5_users[row['id']]['d'] if md5_users[row['id']]['disconnect_ip'] == None: md5_users[row['id']]['disconnect_ip'] = '' if md5_users[row['id']]['forbidden_ip'] == None: md5_users[row['id']]['forbidden_ip'] = '' if md5_users[row['id']]['forbidden_port'] == None: md5_users[row['id']]['forbidden_port'] = '' md5_users[row['id']]['md5'] = common.get_md5(str(row['id']) + row['passwd'] + row['method'] + row['obfs'] + row['protocol']) for row in rows: port = row['port'] passwd = common.to_bytes(row['passwd']) cfg = {'password': passwd} self.port_uid_table[row['port']] = row['id'] self.uid_port_table[row['id']] = row['port'] read_config_keys = ['method', 'obfs','obfs_param' , 'protocol', 'protocol_param' ,'forbidden_ip', 'forbidden_port' , 'node_speedlimit','forbidden_ip','forbidden_port','disconnect_ip','is_multi_user'] for name in read_config_keys: if name in row and row[name]: cfg[name] = row[name] merge_config_keys = ['password'] + read_config_keys for name in cfg.keys(): if hasattr(cfg[name], 'encode'): cfg[name] = cfg[name].encode('utf-8') if 'node_speedlimit' in cfg: if float(self.node_speedlimit) > 0.0 or float(cfg['node_speedlimit']) > 0.0 : cfg['node_speedlimit'] = max(float(self.node_speedlimit),float(cfg['node_speedlimit'])) else: cfg['node_speedlimit'] = max(float(self.node_speedlimit),float(0.00)) if 'disconnect_ip' not in cfg: cfg['disconnect_ip'] = '' if 'forbidden_ip' not in cfg: cfg['forbidden_ip'] = '' if 'forbidden_port' not in cfg: cfg['forbidden_port'] = '' if 'protocol_param' not in cfg: cfg['protocol_param'] = '' if 'obfs_param' not in cfg: cfg['obfs_param'] = '' if 'is_multi_user' not in cfg: cfg['is_multi_user'] = 0 if port not in cur_servers: cur_servers[port] = passwd else: logging.error('more than one user use the same port [%s]' % (port,)) continue if get_config().MULTI_THREAD == 0: cfg['node_speedlimit'] = 0.00 cfg['detect_text_list'] = self.detect_text_list.copy() cfg['detect_hex_list'] = self.detect_hex_list.copy() if cfg['is_multi_user'] == 1: cfg['users_table'] = md5_users.copy() if ServerPool.get_instance().server_is_run(port) > 0: cfgchange = False if self.detect_text_ischanged == True or self.detect_hex_ischanged == True: cfgchange = True if row['is_multi_user'] == 1: if port in ServerPool.get_instance().tcp_servers_pool: ServerPool.get_instance().tcp_servers_pool[port].modify_multi_user_table(md5_users) if port in ServerPool.get_instance().tcp_ipv6_servers_pool: ServerPool.get_instance().tcp_ipv6_servers_pool[port].modify_multi_user_table(md5_users) if port in ServerPool.get_instance().udp_servers_pool: ServerPool.get_instance().udp_servers_pool[port].modify_multi_user_table(md5_users) if port in ServerPool.get_instance().udp_ipv6_servers_pool: ServerPool.get_instance().udp_ipv6_servers_pool[port].modify_multi_user_table(md5_users) if port in ServerPool.get_instance().tcp_servers_pool: relay = ServerPool.get_instance().tcp_servers_pool[port] for name in merge_config_keys: if name in cfg and not self.cmp(cfg[name], relay._config[name]): cfgchange = True break; if not cfgchange and port in ServerPool.get_instance().tcp_ipv6_servers_pool: relay = ServerPool.get_instance().tcp_ipv6_servers_pool[port] for name in merge_config_keys: if name in cfg and not self.cmp(cfg[name], relay._config[name]): cfgchange = True break; #config changed if cfgchange: logging.info('db stop server at port [%s] reason: config changed!' % (port)) ServerPool.get_instance().cb_del_server(port) if port in self.last_update_transfer: del self.last_update_transfer[port] new_servers[port] = (passwd, cfg) elif ServerPool.get_instance().server_run_status(port) is False: #new_servers[port] = passwd protocol = cfg.get('protocol', ServerPool.get_instance().config.get('protocol', 'origin')) obfs = cfg.get('obfs', ServerPool.get_instance().config.get('obfs', 'plain')) logging.info('db start server at port [%s] pass [%s] protocol [%s] obfs [%s]' % (port, passwd, protocol, obfs)) ServerPool.get_instance().new_server(port, cfg) ServerPool.get_instance().push_uid_port_table(self.uid_port_table) for row in last_rows: if row['port'] in cur_servers: pass else: logging.info('db stop server at port [%s] reason: port not exist' % (row['port'])) ServerPool.get_instance().cb_del_server(row['port']) if row['port'] in self.last_update_transfer: del self.last_update_transfer[row['port']] del self.port_uid_table[row['port']] if len(new_servers) > 0: from shadowsocks import eventloop self.event.wait(eventloop.TIMEOUT_PRECISION + eventloop.TIMEOUT_PRECISION / 2) for port in new_servers.keys(): passwd, cfg = new_servers[port] protocol = cfg.get('protocol', ServerPool.get_instance().config.get('protocol', 'origin')) obfs = cfg.get('obfs', ServerPool.get_instance().config.get('obfs', 'plain')) logging.info('db start server at port [%s] pass [%s] protocol [%s] obfs [%s]' % (port, passwd, protocol, obfs)) self.port_uid_table[row['port']] = row['id'] ServerPool.get_instance().new_server(port, cfg)
def pull_db_all_user(self): import cymysql #数据库所有用户信息 try: switchrule = importloader.load('switchrule') keys = switchrule.getKeys() except Exception as e: keys = ['id' , 'port', 'u', 'd', 'transfer_enable', 'passwd', 'enable' ,'method','protocol','protocol_param','obfs','obfs_param','node_speedlimit','forbidden_ip','forbidden_port','disconnect_ip','is_multi_user'] if get_config().MYSQL_SSL_ENABLE == 1: conn = cymysql.connect(host=get_config().MYSQL_HOST, port=get_config().MYSQL_PORT, user=get_config().MYSQL_USER, passwd=get_config().MYSQL_PASS, db=get_config().MYSQL_DB, charset='utf8',ssl={'ca':get_config().MYSQL_SSL_CA,'cert':get_config().MYSQL_SSL_CERT,'key':get_config().MYSQL_SSL_KEY}) else: conn = cymysql.connect(host=get_config().MYSQL_HOST, port=get_config().MYSQL_PORT, user=get_config().MYSQL_USER, passwd=get_config().MYSQL_PASS, db=get_config().MYSQL_DB, charset='utf8') conn.autocommit(True) cur = conn.cursor() cur.execute("SELECT `node_group`,`node_class`,`node_speedlimit`,`traffic_rate` FROM ss_node where `id`='" + str(get_config().NODE_ID) + "' AND (`node_bandwidth`<`node_bandwidth_limit` OR `node_bandwidth_limit`=0)") nodeinfo = cur.fetchone() if nodeinfo == None : rows = [] cur.close() conn.commit() conn.close() return rows cur.close() self.node_speedlimit = float(nodeinfo[2]) self.traffic_rate = float(nodeinfo[3]) if nodeinfo[0] == 0 : node_group_sql = "" else: node_group_sql = "AND `node_group`=" + str(nodeinfo[0]) cur = conn.cursor() cur.execute("SELECT " + ','.join(keys) + " FROM user WHERE `class`>="+ str(nodeinfo[1]) +" "+node_group_sql+" AND`enable`=1 AND `expire_in`>now() AND `transfer_enable`>`u`+`d`") rows = [] for r in cur.fetchall(): d = {} for column in range(len(keys)): d[keys[column]] = r[column] rows.append(d) cur.close() #读取审计规则,数据包匹配部分 keys_detect = ['id','regex'] cur = conn.cursor() cur.execute("SELECT " + ','.join(keys_detect) + " FROM detect_list where `type` = 1") exist_id_list = [] for r in cur.fetchall(): id = long(r[0]) exist_id_list.append(id) if r[0] not in self.detect_text_list: d = {} d['id'] = id d['regex'] = r[1] self.detect_text_list[id] = d self.detect_text_ischanged = True else: if r[1] != self.detect_text_list[r[0]]['regex']: del self.detect_text_list[id] d = {} d['id'] = r[0] d['regex'] = r[1] self.detect_text_list[id] = d self.detect_text_ischanged = True deleted_id_list = [] for id in self.detect_text_list: if id not in exist_id_list: deleted_id_list.append(id) self.detect_text_ischanged = True for id in deleted_id_list: del self.detect_text_list[id] cur = conn.cursor() cur.execute("SELECT " + ','.join(keys_detect) + " FROM detect_list where `type` = 2") exist_id_list = [] for r in cur.fetchall(): id = long(r[0]) exist_id_list.append(id) if r[0] not in self.detect_hex_list: d = {} d['id'] = id d['regex'] = r[1] self.detect_hex_list[id] = d self.detect_hex_ischanged = True else: if r[1] != self.detect_hex_list[r[0]]['regex']: del self.detect_hex_list[id] d = {} d['id'] = r[0] d['regex'] = r[1] self.detect_hex_list[id] = d self.detect_hex_ischanged = True deleted_id_list = [] for id in self.detect_hex_list: if id not in exist_id_list: deleted_id_list.append(id) self.detect_hex_ischanged = True for id in deleted_id_list: del self.detect_hex_list[id] cur.close() conn.close() return rows
def del_server_out_of_bound_safe(self, last_rows, rows): # 停止超流量的服务 # 启动没超流量的服务 # 需要动态载入switchrule,以便实时修改规则 try: switchrule = importloader.load('switchrule') except Exception as e: logging.error('load switchrule.py fail') cur_servers = {} new_servers = {} md5_users = {} self.mu_port_list = [] for row in rows: if row['is_multi_user'] != 0: self.mu_port_list.append(int(row['port'])) continue md5_users[row['id']] = row.copy() del md5_users[row['id']]['u'] del md5_users[row['id']]['d'] if md5_users[row['id']]['disconnect_ip'] is None: md5_users[row['id']]['disconnect_ip'] = '' if md5_users[row['id']]['forbidden_ip'] is None: md5_users[row['id']]['forbidden_ip'] = '' if md5_users[row['id']]['forbidden_port'] is None: md5_users[row['id']]['forbidden_port'] = '' md5_users[row['id']]['md5'] = common.get_md5( str(row['id']) + row['passwd'] + row['method'] + row['obfs'] + row['protocol']) for row in rows: self.port_uid_table[row['port']] = row['id'] self.uid_port_table[row['id']] = row['port'] if self.mu_only == 1 or self.mu_only == 2: i = 0 while i < len(rows): if rows[i]['is_multi_user'] == 0: rows.pop(i) i -= 1 else: pass i += 1 if self.mu_only == -1: i = 0 while i < len(rows): if rows[i]['is_multi_user'] != 0: rows.pop(i) i -= 1 else: pass i += 1 for row in rows: port = row['port'] user_id = row['id'] passwd = common.to_bytes(row['passwd']) cfg = {'password': passwd} read_config_keys = [ 'method', 'obfs', 'obfs_param', 'protocol', 'protocol_param', 'forbidden_ip', 'forbidden_port', 'node_speedlimit', 'disconnect_ip', 'is_multi_user' ] for name in read_config_keys: if name in row and row[name]: cfg[name] = row[name] merge_config_keys = ['password'] + read_config_keys for name in cfg.keys(): if hasattr(cfg[name], 'encode'): try: cfg[name] = cfg[name].encode('utf-8') except Exception as e: logging.warning('encode cfg key "%s" fail, val "%s"' % (name, cfg[name])) if 'node_speedlimit' in cfg: if float(self.node_speedlimit) > 0.0 or float( cfg['node_speedlimit']) > 0.0: cfg['node_speedlimit'] = max(float(self.node_speedlimit), float(cfg['node_speedlimit'])) else: cfg['node_speedlimit'] = max(float(self.node_speedlimit), float(0.00)) if 'disconnect_ip' not in cfg: cfg['disconnect_ip'] = '' if 'forbidden_ip' not in cfg: cfg['forbidden_ip'] = '' if 'forbidden_port' not in cfg: cfg['forbidden_port'] = '' if 'protocol_param' not in cfg: cfg['protocol_param'] = '' if 'obfs_param' not in cfg: cfg['obfs_param'] = '' if 'is_multi_user' not in cfg: cfg['is_multi_user'] = 0 if port not in cur_servers: cur_servers[port] = passwd else: logging.error('more than one user use the same port [%s]' % (port, )) continue if cfg['is_multi_user'] != 0: cfg['users_table'] = md5_users.copy() cfg['detect_hex_list'] = self.detect_hex_list.copy() cfg['detect_text_list'] = self.detect_text_list.copy() if self.is_relay and row['is_multi_user'] != 2: temp_relay_rules = {} for id in self.relay_rule_list: if ((self.relay_rule_list[id]['user_id'] == user_id or self.relay_rule_list[id]['user_id'] == 0) or row['is_multi_user'] != 0) and ( self.relay_rule_list[id]['port'] == 0 or self.relay_rule_list[id]['port'] == port): has_higher_priority = False for priority_id in self.relay_rule_list: if ( (self.relay_rule_list[priority_id]['priority'] > self.relay_rule_list[id]['priority'] and self.relay_rule_list[id]['id'] != self.relay_rule_list[priority_id]['id']) or (self.relay_rule_list[priority_id]['priority'] == self.relay_rule_list[id]['priority'] and self.relay_rule_list[id]['id'] > self.relay_rule_list[priority_id]['id']) ) and (self.relay_rule_list[priority_id]['user_id'] == user_id or self.relay_rule_list[priority_id]['user_id'] == 0) and (self.relay_rule_list[priority_id] ['port'] == port or self.relay_rule_list[priority_id] ['port'] == 0): has_higher_priority = True continue if has_higher_priority: continue if self.relay_rule_list[id][ 'dist_ip'] == '0.0.0.0' and row[ 'is_multi_user'] == 0: continue temp_relay_rules[id] = self.relay_rule_list[id] cfg['relay_rules'] = temp_relay_rules.copy() else: temp_relay_rules = {} cfg['relay_rules'] = temp_relay_rules.copy() if ServerPool.get_instance().server_is_run(port) > 0: cfgchange = False if port in ServerPool.get_instance().tcp_servers_pool: ServerPool.get_instance( ).tcp_servers_pool[port].modify_detect_text_list( self.detect_text_list) ServerPool.get_instance( ).tcp_servers_pool[port].modify_detect_hex_list( self.detect_hex_list) if port in ServerPool.get_instance().tcp_ipv6_servers_pool: ServerPool.get_instance( ).tcp_ipv6_servers_pool[port].modify_detect_text_list( self.detect_text_list) ServerPool.get_instance( ).tcp_ipv6_servers_pool[port].modify_detect_hex_list( self.detect_hex_list) if port in ServerPool.get_instance().udp_servers_pool: ServerPool.get_instance( ).udp_servers_pool[port].modify_detect_text_list( self.detect_text_list) ServerPool.get_instance( ).udp_servers_pool[port].modify_detect_hex_list( self.detect_hex_list) if port in ServerPool.get_instance().udp_ipv6_servers_pool: ServerPool.get_instance( ).udp_ipv6_servers_pool[port].modify_detect_text_list( self.detect_text_list) ServerPool.get_instance( ).udp_ipv6_servers_pool[port].modify_detect_hex_list( self.detect_hex_list) if row['is_multi_user'] != 0: if port in ServerPool.get_instance().tcp_servers_pool: ServerPool.get_instance().tcp_servers_pool[ port].modify_multi_user_table(md5_users) if port in ServerPool.get_instance().tcp_ipv6_servers_pool: ServerPool.get_instance().tcp_ipv6_servers_pool[ port].modify_multi_user_table(md5_users) if port in ServerPool.get_instance().udp_servers_pool: ServerPool.get_instance().udp_servers_pool[ port].modify_multi_user_table(md5_users) if port in ServerPool.get_instance().udp_ipv6_servers_pool: ServerPool.get_instance().udp_ipv6_servers_pool[ port].modify_multi_user_table(md5_users) if self.is_relay and row['is_multi_user'] != 2: temp_relay_rules = {} for id in self.relay_rule_list: if ((self.relay_rule_list[id]['user_id'] == user_id or self.relay_rule_list[id]['user_id'] == 0) or row['is_multi_user'] != 0) and ( self.relay_rule_list[id]['port'] == 0 or self.relay_rule_list[id]['port'] == port): has_higher_priority = False for priority_id in self.relay_rule_list: if ((self.relay_rule_list[priority_id] ['priority'] > self.relay_rule_list[id]['priority'] and self.relay_rule_list[id]['id'] != self.relay_rule_list[priority_id]['id']) or (self.relay_rule_list[priority_id] ['priority'] == self.relay_rule_list[id]['priority'] and self.relay_rule_list[id]['id'] > self. relay_rule_list[priority_id]['id'])) and ( self.relay_rule_list[priority_id] ['user_id'] == user_id or self.relay_rule_list[priority_id] ['user_id'] == 0) and ( self.relay_rule_list[priority_id] ['port'] == port or self.relay_rule_list[priority_id] ['port'] == 0): has_higher_priority = True continue if has_higher_priority: continue if self.relay_rule_list[id][ 'dist_ip'] == '0.0.0.0' and row[ 'is_multi_user'] == 0: continue temp_relay_rules[id] = self.relay_rule_list[id] if port in ServerPool.get_instance().tcp_servers_pool: ServerPool.get_instance().tcp_servers_pool[ port].push_relay_rules(temp_relay_rules) if port in ServerPool.get_instance().tcp_ipv6_servers_pool: ServerPool.get_instance().tcp_ipv6_servers_pool[ port].push_relay_rules(temp_relay_rules) if port in ServerPool.get_instance().udp_servers_pool: ServerPool.get_instance().udp_servers_pool[ port].push_relay_rules(temp_relay_rules) if port in ServerPool.get_instance().udp_ipv6_servers_pool: ServerPool.get_instance().udp_ipv6_servers_pool[ port].push_relay_rules(temp_relay_rules) else: temp_relay_rules = {} if port in ServerPool.get_instance().tcp_servers_pool: ServerPool.get_instance().tcp_servers_pool[ port].push_relay_rules(temp_relay_rules) if port in ServerPool.get_instance().tcp_ipv6_servers_pool: ServerPool.get_instance().tcp_ipv6_servers_pool[ port].push_relay_rules(temp_relay_rules) if port in ServerPool.get_instance().udp_servers_pool: ServerPool.get_instance().udp_servers_pool[ port].push_relay_rules(temp_relay_rules) if port in ServerPool.get_instance().udp_ipv6_servers_pool: ServerPool.get_instance().udp_ipv6_servers_pool[ port].push_relay_rules(temp_relay_rules) if port in ServerPool.get_instance().tcp_servers_pool: relay = ServerPool.get_instance().tcp_servers_pool[port] for name in merge_config_keys: if name in cfg and not self.cmp( cfg[name], relay._config[name]): cfgchange = True break if not cfgchange and port in ServerPool.get_instance( ).tcp_ipv6_servers_pool: relay = ServerPool.get_instance( ).tcp_ipv6_servers_pool[port] for name in merge_config_keys: if name in cfg and not self.cmp( cfg[name], relay._config[name]): cfgchange = True break # config changed if cfgchange: self.del_server(port, "config changed") new_servers[port] = (passwd, cfg) elif ServerPool.get_instance().server_run_status(port) is False: # new_servers[port] = passwd self.new_server(port, passwd, cfg) for row in last_rows: if row['port'] in cur_servers: pass else: self.del_server(row['port'], "port not exist") if len(new_servers) > 0: from shadowsocks import eventloop self.event.wait(eventloop.TIMEOUT_PRECISION + eventloop.TIMEOUT_PRECISION / 2) for port in new_servers.keys(): passwd, cfg = new_servers[port] self.new_server(port, passwd, cfg) ServerPool.get_instance().push_uid_port_table(self.uid_port_table)
def pull_db_all_user(self): import cymysql # 数据库所有用户信息 try: switchrule = importloader.load('switchrule') keys = switchrule.getKeys() except Exception as e: keys = [ 'id', 'port', 'u', 'd', 'transfer_enable', 'passwd', 'enable', 'method', 'protocol', 'protocol_param', 'obfs', 'obfs_param', 'node_speedlimit', 'forbidden_ip', 'forbidden_port', 'disconnect_ip', 'is_multi_user'] if get_config().MYSQL_SSL_ENABLE == 1: conn = cymysql.connect( host=get_config().MYSQL_HOST, port=get_config().MYSQL_PORT, user=get_config().MYSQL_USER, passwd=get_config().MYSQL_PASS, db=get_config().MYSQL_DB, charset='utf8', ssl={ 'ca': get_config().MYSQL_SSL_CA, 'cert': get_config().MYSQL_SSL_CERT, 'key': get_config().MYSQL_SSL_KEY}) else: conn = cymysql.connect( host=get_config().MYSQL_HOST, port=get_config().MYSQL_PORT, user=get_config().MYSQL_USER, passwd=get_config().MYSQL_PASS, db=get_config().MYSQL_DB, charset='utf8') conn.autocommit(True) cur = conn.cursor() cur.execute( "SELECT `node_group`,`node_class`,`node_speedlimit`,`traffic_rate`,`mu_only`,`sort` ,name FROM ss_node where `id`='" + str(get_config().NODE_ID) + "' AND (`node_bandwidth`<`node_bandwidth_limit` OR `node_bandwidth_limit`=0)") nodeinfo = cur.fetchone() if nodeinfo is None: rows = [] cur.close() conn.commit() conn.close() return rows cur.close() self.node_speedlimit = float(nodeinfo[2]) self.traffic_rate = float(nodeinfo[3]) self.mu_only = int(nodeinfo[4]) if nodeinfo[5] == 10: self.is_relay = True else: self.is_relay = False if nodeinfo[0] == 0: node_group_sql = "" else: node_group_sql = "AND `node_group`=" + str(nodeinfo[0]) cur = conn.cursor() cur.execute("SELECT " + ','.join(keys) + " FROM user WHERE ((`class`>=" + str(nodeinfo[1]) + " " + node_group_sql + ") OR `is_admin`=1) AND`enable`=1 AND `expire_in`>now() AND `transfer_enable`>`u`+`d`") rows = [] for r in cur.fetchall(): d = {} for column in range(len(keys)): d[keys[column]] = r[column] rows.append(d) cur.close() # 读取节点IP # SELECT * FROM `ss_node` where `node_ip` != '' self.node_ip_list = [] cur = conn.cursor() cur.execute("SELECT `node_ip` FROM `ss_node` where `node_ip` != ''") for r in cur.fetchall(): temp_list = str(r[0]).split(',') self.node_ip_list.append(temp_list[0]) cur.close() # 读取审计规则,数据包匹配部分 keys_detect = ['id', 'regex'] cur = conn.cursor() cur.execute("SELECT " + ','.join(keys_detect) + " FROM detect_list where `type` = 1") exist_id_list = [] for r in cur.fetchall(): id = int(r[0]) exist_id_list.append(id) if id not in self.detect_text_list: d = {} d['id'] = id d['regex'] = str(r[1]) self.detect_text_list[id] = d self.detect_text_ischanged = True else: if r[1] != self.detect_text_list[id]['regex']: del self.detect_text_list[id] d = {} d['id'] = id d['regex'] = str(r[1]) self.detect_text_list[id] = d self.detect_text_ischanged = True deleted_id_list = [] for id in self.detect_text_list: if id not in exist_id_list: deleted_id_list.append(id) self.detect_text_ischanged = True for id in deleted_id_list: del self.detect_text_list[id] cur.close() cur = conn.cursor() cur.execute("SELECT " + ','.join(keys_detect) + " FROM detect_list where `type` = 2") exist_id_list = [] for r in cur.fetchall(): id = int(r[0]) exist_id_list.append(id) if r[0] not in self.detect_hex_list: d = {} d['id'] = id d['regex'] = str(r[1]) self.detect_hex_list[id] = d self.detect_hex_ischanged = True else: if r[1] != self.detect_hex_list[r[0]]['regex']: del self.detect_hex_list[id] d = {} d['id'] = int(r[0]) d['regex'] = str(r[1]) self.detect_hex_list[id] = d self.detect_hex_ischanged = True deleted_id_list = [] for id in self.detect_hex_list: if id not in exist_id_list: deleted_id_list.append(id) self.detect_hex_ischanged = True for id in deleted_id_list: del self.detect_hex_list[id] cur.close() # 读取中转规则,如果是中转节点的话 if self.is_relay: self.relay_rule_list = {} keys_detect = ['id', 'user_id', 'dist_ip', 'port', 'priority'] cur = conn.cursor() cur.execute("SELECT " + ','.join(keys_detect) + " FROM relay where `source_node_id` = 0 or `source_node_id` = " + str(get_config().NODE_ID)) for r in cur.fetchall(): d = {} d['id'] = int(r[0]) d['user_id'] = int(r[1]) d['dist_ip'] = str(r[2]) d['port'] = int(r[3]) d['priority'] = int(r[4]) self.relay_rule_list[d['id']] = d cur.close() conn.close() name = nodeinfo[6] names = name.split('#') portAdd = 0L if len(names) > 1: portAdd += long(names[1]) for row in rows: if (row['is_multi_user'] == 1L): row['port'] += portAdd return rows
def del_server_out_of_bound_safe(self, last_rows, rows): # 停止超流量的服务 # 启动没超流量的服务 # 需要动态载入switchrule,以便实时修改规则 try: switchrule = importloader.load("switchrule") except Exception as e: logging.error("load switchrule.py fail") cur_servers = {} new_servers = {} md5_users = {} self.mu_port_list = [] for row in rows: if row["is_multi_user"] != 0: self.mu_port_list.append(int(row["port"])) continue md5_users[row["id"]] = row.copy() del md5_users[row["id"]]["u"] del md5_users[row["id"]]["d"] if md5_users[row["id"]]["disconnect_ip"] is None: md5_users[row["id"]]["disconnect_ip"] = "" if md5_users[row["id"]]["forbidden_ip"] is None: md5_users[row["id"]]["forbidden_ip"] = "" if md5_users[row["id"]]["forbidden_port"] is None: md5_users[row["id"]]["forbidden_port"] = "" md5_users[row["id"]]["md5"] = common.get_md5( str(row["id"]) + row["passwd"] + row["method"] + row["obfs"] + row["protocol"]) for row in rows: self.port_uid_table[row["port"]] = row["id"] self.uid_port_table[row["id"]] = row["port"] if self.mu_only == 1: i = 0 while i < len(rows): if rows[i]["is_multi_user"] == 0: rows.pop(i) i -= 1 else: pass i += 1 if self.mu_only == -1: i = 0 while i < len(rows): if rows[i]["is_multi_user"] != 0: rows.pop(i) i -= 1 else: pass i += 1 for row in rows: port = row["port"] user_id = row["id"] passwd = common.to_bytes(row["passwd"]) cfg = {"password": passwd} read_config_keys = [ "method", "obfs", "obfs_param", "protocol", "protocol_param", "forbidden_ip", "forbidden_port", "node_speedlimit", "disconnect_ip", "is_multi_user", ] for name in read_config_keys: if name in row and row[name]: cfg[name] = row[name] merge_config_keys = ["password"] + read_config_keys for name in cfg.keys(): if hasattr(cfg[name], "encode"): try: cfg[name] = cfg[name].encode("utf-8") except Exception as e: logging.warning('encode cfg key "%s" fail, val "%s"' % (name, cfg[name])) if "node_speedlimit" in cfg: if float(self.node_speedlimit) > 0.0 or float( cfg["node_speedlimit"]) > 0.0: cfg["node_speedlimit"] = min( float(self.node_speedlimit), float(cfg["node_speedlimit"]), ) else: cfg["node_speedlimit"] = max(float(self.node_speedlimit), float(0.00)) if "disconnect_ip" not in cfg: cfg["disconnect_ip"] = "" if "forbidden_ip" not in cfg: cfg["forbidden_ip"] = "" if "forbidden_port" not in cfg: cfg["forbidden_port"] = "" if "protocol_param" not in cfg: cfg["protocol_param"] = "" if "obfs_param" not in cfg: cfg["obfs_param"] = "" if "is_multi_user" not in cfg: cfg["is_multi_user"] = 0 if port not in cur_servers: cur_servers[port] = passwd else: logging.error("more than one user use the same port [%s]" % (port, )) continue if cfg["is_multi_user"] != 0: cfg["users_table"] = md5_users.copy() cfg["detect_hex_list"] = self.detect_hex_list.copy() cfg["detect_text_list"] = self.detect_text_list.copy() if self.is_relay and row["is_multi_user"] != 2: temp_relay_rules = {} for id in self.relay_rule_list: if ((self.relay_rule_list[id]["user_id"] == user_id or self.relay_rule_list[id]["user_id"] == 0) or row["is_multi_user"] != 0) and ( self.relay_rule_list[id]["port"] == 0 or self.relay_rule_list[id]["port"] == port): has_higher_priority = False for priority_id in self.relay_rule_list: if (((self.relay_rule_list[priority_id]["priority"] > self.relay_rule_list[id]["priority"] and self.relay_rule_list[id]["id"] != self.relay_rule_list[priority_id]["id"]) or (self.relay_rule_list[priority_id]["priority"] == self.relay_rule_list[id]["priority"] and self.relay_rule_list[id]["id"] > self.relay_rule_list[priority_id]["id"])) and (self.relay_rule_list[priority_id]["user_id"] == user_id or self.relay_rule_list[priority_id]["user_id"] == 0) and (self.relay_rule_list[priority_id]["port"] == port or self.relay_rule_list[priority_id]["port"] == 0)): has_higher_priority = True continue if has_higher_priority: continue if self.relay_rule_list[id][ "dist_ip"] == "0.0.0.0" and row[ "is_multi_user"] == 0: continue temp_relay_rules[id] = self.relay_rule_list[id] cfg["relay_rules"] = temp_relay_rules.copy() else: temp_relay_rules = {} cfg["relay_rules"] = temp_relay_rules.copy() if ServerPool.get_instance().server_is_run(port) > 0: cfgchange = False if port in ServerPool.get_instance().tcp_servers_pool: ServerPool.get_instance( ).tcp_servers_pool[port].modify_detect_text_list( self.detect_text_list) ServerPool.get_instance( ).tcp_servers_pool[port].modify_detect_hex_list( self.detect_hex_list) if port in ServerPool.get_instance().tcp_ipv6_servers_pool: ServerPool.get_instance( ).tcp_ipv6_servers_pool[port].modify_detect_text_list( self.detect_text_list) ServerPool.get_instance( ).tcp_ipv6_servers_pool[port].modify_detect_hex_list( self.detect_hex_list) if port in ServerPool.get_instance().udp_servers_pool: ServerPool.get_instance( ).udp_servers_pool[port].modify_detect_text_list( self.detect_text_list) ServerPool.get_instance( ).udp_servers_pool[port].modify_detect_hex_list( self.detect_hex_list) if port in ServerPool.get_instance().udp_ipv6_servers_pool: ServerPool.get_instance( ).udp_ipv6_servers_pool[port].modify_detect_text_list( self.detect_text_list) ServerPool.get_instance( ).udp_ipv6_servers_pool[port].modify_detect_hex_list( self.detect_hex_list) if row["is_multi_user"] != 0: if port in ServerPool.get_instance().tcp_servers_pool: ServerPool.get_instance().tcp_servers_pool[ port].modify_multi_user_table(md5_users) if port in ServerPool.get_instance().tcp_ipv6_servers_pool: ServerPool.get_instance().tcp_ipv6_servers_pool[ port].modify_multi_user_table(md5_users) if port in ServerPool.get_instance().udp_servers_pool: ServerPool.get_instance().udp_servers_pool[ port].modify_multi_user_table(md5_users) if port in ServerPool.get_instance().udp_ipv6_servers_pool: ServerPool.get_instance().udp_ipv6_servers_pool[ port].modify_multi_user_table(md5_users) if self.is_relay and row["is_multi_user"] != 2: temp_relay_rules = {} for id in self.relay_rule_list: if ((self.relay_rule_list[id]["user_id"] == user_id or self.relay_rule_list[id]["user_id"] == 0) or row["is_multi_user"] != 0) and ( self.relay_rule_list[id]["port"] == 0 or self.relay_rule_list[id]["port"] == port): has_higher_priority = False for priority_id in self.relay_rule_list: if (((self.relay_rule_list[priority_id] ["priority"] > self.relay_rule_list[id]["priority"] and self.relay_rule_list[id]["id"] != self.relay_rule_list[priority_id]["id"]) or (self.relay_rule_list[priority_id] ["priority"] == self.relay_rule_list[id]["priority"] and self.relay_rule_list[id]["id"] > self.relay_rule_list[priority_id]["id"])) and (self.relay_rule_list[priority_id] ["user_id"] == user_id or self.relay_rule_list[priority_id] ["user_id"] == 0) and (self.relay_rule_list[priority_id]["port"] == port or self.relay_rule_list[priority_id]["port"] == 0)): has_higher_priority = True continue if has_higher_priority: continue if self.relay_rule_list[id][ "dist_ip"] == "0.0.0.0" and row[ "is_multi_user"] == 0: continue temp_relay_rules[id] = self.relay_rule_list[id] if port in ServerPool.get_instance().tcp_servers_pool: ServerPool.get_instance().tcp_servers_pool[ port].push_relay_rules(temp_relay_rules) if port in ServerPool.get_instance().tcp_ipv6_servers_pool: ServerPool.get_instance().tcp_ipv6_servers_pool[ port].push_relay_rules(temp_relay_rules) if port in ServerPool.get_instance().udp_servers_pool: ServerPool.get_instance().udp_servers_pool[ port].push_relay_rules(temp_relay_rules) if port in ServerPool.get_instance().udp_ipv6_servers_pool: ServerPool.get_instance().udp_ipv6_servers_pool[ port].push_relay_rules(temp_relay_rules) else: temp_relay_rules = {} if port in ServerPool.get_instance().tcp_servers_pool: ServerPool.get_instance().tcp_servers_pool[ port].push_relay_rules(temp_relay_rules) if port in ServerPool.get_instance().tcp_ipv6_servers_pool: ServerPool.get_instance().tcp_ipv6_servers_pool[ port].push_relay_rules(temp_relay_rules) if port in ServerPool.get_instance().udp_servers_pool: ServerPool.get_instance().udp_servers_pool[ port].push_relay_rules(temp_relay_rules) if port in ServerPool.get_instance().udp_ipv6_servers_pool: ServerPool.get_instance().udp_ipv6_servers_pool[ port].push_relay_rules(temp_relay_rules) if port in ServerPool.get_instance().tcp_servers_pool: relay = ServerPool.get_instance().tcp_servers_pool[port] for name in merge_config_keys: if name in cfg and not self.cmp( cfg[name], relay._config[name]): cfgchange = True break if not cfgchange and port in ServerPool.get_instance( ).tcp_ipv6_servers_pool: relay = ServerPool.get_instance( ).tcp_ipv6_servers_pool[port] for name in merge_config_keys: if name in cfg and not self.cmp( cfg[name], relay._config[name]): cfgchange = True break # config changed if cfgchange: self.del_server(port, "config changed") new_servers[port] = (passwd, cfg) elif ServerPool.get_instance().server_run_status(port) is False: # new_servers[port] = passwd self.new_server(port, passwd, cfg) for row in last_rows: if row["port"] in cur_servers: pass else: self.del_server(row["port"], "port not exist") if len(new_servers) > 0: from shadowsocks import eventloop self.event.wait(eventloop.TIMEOUT_PRECISION + eventloop.TIMEOUT_PRECISION / 2) for port in new_servers.keys(): passwd, cfg = new_servers[port] self.new_server(port, passwd, cfg) ServerPool.get_instance().push_uid_port_table(self.uid_port_table)
def pull_db_all_user(self): import cymysql # 数据库所有用户信息 try: switchrule = importloader.load("switchrule") keys = switchrule.getKeys() except Exception as e: keys = [ "id", "port", "u", "d", "transfer_enable", "passwd", "enable", "method", "protocol", "protocol_param", "obfs", "obfs_param", "node_speedlimit", "forbidden_ip", "forbidden_port", "disconnect_ip", "is_multi_user", ] if self.api_config.MYSQL_SSL_ENABLE == 1: conn = cymysql.connect( host=self.api_config.MYSQL_HOST, port=self.api_config.MYSQL_PORT, user=self.api_config.MYSQL_USER, passwd=self.api_config.MYSQL_PASS, db=self.api_config.MYSQL_DB, charset="utf8", ssl={ "ca": self.api_config.MYSQL_SSL_CA, "cert": self.api_config.MYSQL_SSL_CERT, "key": self.api_config.MYSQL_SSL_KEY, }, ) else: conn = cymysql.connect( host=self.api_config.MYSQL_HOST, port=self.api_config.MYSQL_PORT, user=self.api_config.MYSQL_USER, passwd=self.api_config.MYSQL_PASS, db=self.api_config.MYSQL_DB, charset="utf8", ) conn.autocommit(True) cur = conn.cursor() cur.execute( "SELECT `node_group`,`node_class`,`node_speedlimit`,`traffic_rate`,`mu_only`,`sort`,`name` FROM ss_node where `id`='" + str(self.api_config.NODE_ID) + "' AND (`node_bandwidth`<`node_bandwidth_limit` OR `node_bandwidth_limit`=0)" ) nodeinfo = cur.fetchone() if nodeinfo is None: rows = [] cur.close() conn.commit() conn.close() return rows cur.close() self.node_speedlimit = float(nodeinfo[2]) self.traffic_rate = float(nodeinfo[3]) self.mu_only = int(nodeinfo[4]) if nodeinfo[5] == 10: self.is_relay = True else: self.is_relay = False try: self.port_offset = int(nodeinfo[6].split("#")[1]) except IndexError: self.port_offset = 0 logging.debug( "node_info >> group=%d class=%d speedlimit=%f traffic_rate=%f mu_only=%d sort=%d name=%s port_offset=%d", nodeinfo[0], nodeinfo[1], nodeinfo[2], nodeinfo[3], nodeinfo[4], nodeinfo[5], nodeinfo[6], self.port_offset) if nodeinfo[0] == 0: node_group_sql = "" else: node_group_sql = "AND `node_group`=" + str(nodeinfo[0]) cur = conn.cursor() cur.execute( "SELECT " + ",".join(keys) + " FROM user WHERE ((`class`>=" + str(nodeinfo[1]) + " " + node_group_sql + ") OR `is_admin`=1) AND`enable`=1 AND `expire_in`>now() AND `transfer_enable`>`u`+`d`" ) rows = [] for r in cur.fetchall(): d = {} for column in range(len(keys)): d[keys[column]] = r[column] d["port"] = self.get_port_by_offset(d["port"]) rows.append(d) cur.close() # 读取节点IP # SELECT * FROM `ss_node` where `node_ip` != '' self.node_ip_list = [] cur = conn.cursor() cur.execute("SELECT `node_ip` FROM `ss_node` where `node_ip` != ''") for r in cur.fetchall(): temp_list = str(r[0]).split(",") self.node_ip_list.append(temp_list[0]) cur.close() # 读取审计规则,数据包匹配部分 keys_detect = ["id", "regex"] cur = conn.cursor() cur.execute("SELECT " + ",".join(keys_detect) + " FROM detect_list where `type` = 1") exist_id_list = [] for r in cur.fetchall(): id = int(r[0]) exist_id_list.append(id) if id not in self.detect_text_list: d = {"id": id, "regex": str(r[1])} self.detect_text_list[id] = d self.detect_text_ischanged = True else: if r[1] != self.detect_text_list[id]["regex"]: del self.detect_text_list[id] d = {"id": id, "regex": str(r[1])} self.detect_text_list[id] = d self.detect_text_ischanged = True deleted_id_list = [] for id in self.detect_text_list: if id not in exist_id_list: deleted_id_list.append(id) self.detect_text_ischanged = True for id in deleted_id_list: del self.detect_text_list[id] cur.close() cur = conn.cursor() cur.execute("SELECT " + ",".join(keys_detect) + " FROM detect_list where `type` = 2") exist_id_list = [] for r in cur.fetchall(): id = int(r[0]) exist_id_list.append(id) if r[0] not in self.detect_hex_list: d = {"id": id, "regex": str(r[1])} self.detect_hex_list[id] = d self.detect_hex_ischanged = True else: if r[1] != self.detect_hex_list[r[0]]["regex"]: del self.detect_hex_list[id] d = {"id": int(r[0]), "regex": str(r[1])} self.detect_hex_list[id] = d self.detect_hex_ischanged = True deleted_id_list = [] for id in self.detect_hex_list: if id not in exist_id_list: deleted_id_list.append(id) self.detect_hex_ischanged = True for id in deleted_id_list: del self.detect_hex_list[id] cur.close() # 读取中转规则,如果是中转节点的话 if self.is_relay: self.relay_rule_list = {} keys_detect = ["id", "user_id", "dist_ip", "port", "priority"] cur = conn.cursor() cur.execute( "SELECT " + ",".join(keys_detect) + " FROM relay where `source_node_id` = 0 or `source_node_id` = " + str(self.api_config.NODE_ID) ) for r in cur.fetchall(): d = { "id": int(r[0]), "user_id": int(r[1]), "dist_ip": str(r[2]), "port": int(r[3]), "priority": int(r[4]), } self.relay_rule_list[d["id"]] = d cur.close() conn.close() return rows
def del_server_out_of_bound_safe(self, last_rows, rows): #停止超流量的服务 #启动没超流量的服务 try: switchrule = importloader.load('switchrule') except Exception as e: logging.error('load switchrule.py fail') cur_servers = {} new_servers = {} for row in rows: try: allow = switchrule.isTurnOn(row) and row['enable'] == 1 and row['u'] + row['d'] < row['transfer_enable'] except Exception as e: allow = False port = row['port'] passwd = common.to_bytes(row['passwd']) cfg = {'password': passwd} if 'id' in row: self.port_uid_table[row['port']] = row['id'] read_config_keys = ['method', 'obfs', 'obfs_param', 'protocol', 'protocol_param', 'forbidden_ip', 'forbidden_port'] for name in read_config_keys: if name in row and row[name]: cfg[name] = row[name] merge_config_keys = ['password'] + read_config_keys for name in cfg.keys(): if hasattr(cfg[name], 'encode'): cfg[name] = cfg[name].encode('utf-8') if port not in cur_servers: cur_servers[port] = passwd else: logging.error('more than one user use the same port [%s]' % (port,)) continue if ServerPool.get_instance().server_is_run(port) > 0: if not allow: logging.info('db stop server at port [%s]' % (port,)) ServerPool.get_instance().cb_del_server(port) self.force_update_transfer.add(port) else: cfgchange = False if port in ServerPool.get_instance().tcp_servers_pool: relay = ServerPool.get_instance().tcp_servers_pool[port] for name in merge_config_keys: if name in cfg and not self.cmp(cfg[name], relay._config[name]): cfgchange = True break; if not cfgchange and port in ServerPool.get_instance().tcp_ipv6_servers_pool: relay = ServerPool.get_instance().tcp_ipv6_servers_pool[port] for name in merge_config_keys: if name in cfg and not self.cmp(cfg[name], relay._config[name]): cfgchange = True break; #config changed if cfgchange: logging.info('db stop server at port [%s] reason: config changed: %s' % (port, cfg)) ServerPool.get_instance().cb_del_server(port) self.force_update_transfer.add(port) new_servers[port] = (passwd, cfg) elif allow and ServerPool.get_instance().server_run_status(port) is False: self.new_server(port, passwd, cfg) for row in last_rows: if row['port'] in cur_servers: pass else: logging.info('db stop server at port [%s] reason: port not exist' % (row['port'])) ServerPool.get_instance().cb_del_server(row['port']) self.clear_cache(row['port']) if row['port'] in self.port_uid_table: del self.port_uid_table[row['port']] if len(new_servers) > 0: from shadowsocks import eventloop self.event.wait(eventloop.TIMEOUT_PRECISION + eventloop.TIMEOUT_PRECISION / 2) for port in new_servers.keys(): passwd, cfg = new_servers[port] self.new_server(port, passwd, cfg)
def del_server_out_of_bound_safe(self, last_rows, rows): #停止超流量的服务 #启动没超流量的服务 try: switchrule = importloader.load('switchrule') except Exception as e: logging.error('load switchrule.py fail') cur_servers = {} new_servers = {} for row in rows: try: allow = switchrule.isTurnOn( row) and row['enable'] == 1 and row['u'] + row['d'] < row[ 'transfer_enable'] except Exception as e: allow = False port = row['port'] passwd = common.to_bytes(row['passwd']) cfg = {'password': passwd} if 'id' in row: self.port_uid_table[row['port']] = row['id'] read_config_keys = [ 'method', 'obfs', 'obfs_param', 'protocol', 'protocol_param', 'forbidden_ip', 'forbidden_port' ] for name in read_config_keys: if name in row and row[name]: cfg[name] = row[name] merge_config_keys = ['password'] + read_config_keys for name in cfg.keys(): if hasattr(cfg[name], 'encode'): cfg[name] = cfg[name].encode('utf-8') if port not in cur_servers: cur_servers[port] = passwd else: logging.error('more than one user use the same port [%s]' % (port, )) continue if ServerPool.get_instance().server_is_run(port) > 0: if not allow: logging.info('db stop server at port [%s]' % (port, )) ServerPool.get_instance().cb_del_server(port) self.force_update_transfer.add(port) else: cfgchange = False if port in ServerPool.get_instance().tcp_servers_pool: relay = ServerPool.get_instance( ).tcp_servers_pool[port] for name in merge_config_keys: if name in cfg and not self.cmp( cfg[name], relay._config[name]): cfgchange = True break if not cfgchange and port in ServerPool.get_instance( ).tcp_ipv6_servers_pool: relay = ServerPool.get_instance( ).tcp_ipv6_servers_pool[port] for name in merge_config_keys: if name in cfg and not self.cmp( cfg[name], relay._config[name]): cfgchange = True break #config changed if cfgchange: logging.info( 'db stop server at port [%s] reason: config changed: %s' % (port, cfg)) ServerPool.get_instance().cb_del_server(port) self.force_update_transfer.add(port) new_servers[port] = (passwd, cfg) elif allow and ServerPool.get_instance().server_run_status( port) is False: self.new_server(port, passwd, cfg) for row in last_rows: if row['port'] in cur_servers: pass else: logging.info( 'db stop server at port [%s] reason: port not exist' % (row['port'])) ServerPool.get_instance().cb_del_server(row['port']) self.clear_cache(row['port']) if row['port'] in self.port_uid_table: del self.port_uid_table[row['port']] if len(new_servers) > 0: from shadowsocks import eventloop self.event.wait(eventloop.TIMEOUT_PRECISION + eventloop.TIMEOUT_PRECISION / 2) for port in new_servers.keys(): passwd, cfg = new_servers[port] self.new_server(port, passwd, cfg)
def pull_db_all_user(self): import cymysql # 数据库所有用户信息 try: switchrule = importloader.load('switchrule') keys = switchrule.getKeys() except Exception as e: keys = [ 'accountId id', 'port', 'u', 'd', 'transfer_enable', 'passwd', 'enable', 'method', 'protocol', 'protocol_param', 'obfs', 'obfs_param', 'node_speedlimit', 'forbidden_ip', 'forbidden_port', 'disconnect_ip', 'is_multi_user' ] if get_config().MYSQL_SSL_ENABLE == 1: conn = cymysql.connect(host=get_config().MYSQL_HOST, port=get_config().MYSQL_PORT, user=get_config().MYSQL_USER, passwd=get_config().MYSQL_PASS, db=get_config().MYSQL_DB, charset='utf8', ssl={ 'ca': get_config().MYSQL_SSL_CA, 'cert': get_config().MYSQL_SSL_CERT, 'key': get_config().MYSQL_SSL_KEY }) else: conn = cymysql.connect(host=get_config().MYSQL_HOST, port=get_config().MYSQL_PORT, user=get_config().MYSQL_USER, passwd=get_config().MYSQL_PASS, db=get_config().MYSQL_DB, charset='utf8') conn.autocommit(True) # b 读取节点信息 cur = conn.cursor() cur.execute( "SELECT `node_speedlimit`,`singleMode` FROM server where `id`=" + str(get_config().NODE_ID) + " AND (`node_bandwidth`<`node_bandwidth_limit` OR `node_bandwidth_limit`=0)" ) # b 原代码 # cur.execute("SELECT `node_group`,`node_class`,`node_speedlimit`,`traffic_rate`,`mu_only`,`sort` FROM ss_node where `id`='" + # str(get_config().NODE_ID) + "' AND (`node_bandwidth`<`node_bandwidth_limit` OR `node_bandwidth_limit`=0)") nodeinfo = cur.fetchone() if nodeinfo is None: rows = [] cur.close() conn.commit() conn.close() return rows cur.close() # b 节点限速 self.node_speedlimit = float(nodeinfo[0]) # b mu_only -1/只启用普通端口 0/单端口多用户与普通端口并存 1/只启用单端口多用户 if nodeinfo[1] == "ssr1port": self.mu_only = 1 else: self.mu_only = 0 # self.node_speedlimit = float(nodeinfo[2]) self.traffic_rate = 1 # self.mu_only = int(nodeinfo[4]) # if nodeinfo[5] == 10: # self.is_relay = True # else: # self.is_relay = False self.is_relay = False # if nodeinfo[0] == 0: # node_group_sql = "" # else: # node_group_sql = "AND `node_group`=" + str(nodeinfo[0]) cur = conn.cursor() cur.execute("SELECT " + ','.join(keys) + " FROM ssr_user where enable = 1 and serverId=" + str(get_config().NODE_ID)) # b 下面是原代码 # cur.execute("SELECT " + # ','.join(keys) + # " FROM user WHERE ((`class`>=" + # str(nodeinfo[1]) + # " " + # node_group_sql + # ") OR `is_admin`=1) AND`enable`=1 AND `expire_in`>now() AND `transfer_enable`>`u`+`d`") rows = [] for r in cur.fetchall(): d = {} for column in range(len(keys)): key_temp = keys[column].split(' ') d[key_temp[len(key_temp) - 1]] = r[column] # for column in range(len(keys)): # d[keys[column]] = r[column] rows.append(d) cur.close() # 读取节点IP # SELECT * FROM `ss_node` where `node_ip` != '' self.node_ip_list = [] cur = conn.cursor() # cur.execute("SELECT `node_ip` FROM `ss_node` where `node_ip` != ''") cur.execute( "SELECT `host` FROM `server` where `type` = 'Shadowsocks'") for r in cur.fetchall(): temp_list = str(r[0]).split(':') self.node_ip_list.append(temp_list[0]) cur.close() # 读取审计规则,数据包匹配部分 type 1/数据包明文匹配 2/数据包 hex 匹配 keys_detect = ['id', 'regex'] cur = conn.cursor() cur.execute("SELECT " + ','.join(keys_detect) + " FROM detect_list where `type` = 1") exist_id_list = [] for r in cur.fetchall(): id = int(r[0]) exist_id_list.append(id) if id not in self.detect_text_list: d = {} d['id'] = id d['regex'] = str(r[1]) self.detect_text_list[id] = d self.detect_text_ischanged = True else: if r[1] != self.detect_text_list[id]['regex']: del self.detect_text_list[id] d = {} d['id'] = id d['regex'] = str(r[1]) self.detect_text_list[id] = d self.detect_text_ischanged = True deleted_id_list = [] for id in self.detect_text_list: if id not in exist_id_list: deleted_id_list.append(id) self.detect_text_ischanged = True for id in deleted_id_list: del self.detect_text_list[id] cur.close() cur = conn.cursor() cur.execute("SELECT " + ','.join(keys_detect) + " FROM detect_list where `type` = 2") exist_id_list = [] for r in cur.fetchall(): id = int(r[0]) exist_id_list.append(id) if r[0] not in self.detect_hex_list: d = {} d['id'] = id d['regex'] = str(r[1]) self.detect_hex_list[id] = d self.detect_hex_ischanged = True else: if r[1] != self.detect_hex_list[r[0]]['regex']: del self.detect_hex_list[id] d = {} d['id'] = int(r[0]) d['regex'] = str(r[1]) self.detect_hex_list[id] = d self.detect_hex_ischanged = True deleted_id_list = [] for id in self.detect_hex_list: if id not in exist_id_list: deleted_id_list.append(id) self.detect_hex_ischanged = True for id in deleted_id_list: del self.detect_hex_list[id] cur.close() # 读取中转规则,如果是中转节点的话 # if self.is_relay: # self.relay_rule_list = {} # keys_detect = ['id', 'user_id', 'dist_ip', 'port', 'priority'] # cur = conn.cursor() # cur.execute("SELECT " + # ','.join(keys_detect) + # " FROM relay where `source_node_id` = 0 or `source_node_id` = " + # str(get_config().NODE_ID)) # for r in cur.fetchall(): # d = {} # d['id'] = int(r[0]) # d['user_id'] = int(r[1]) # d['dist_ip'] = str(r[2]) # d['port'] = int(r[3]) # d['priority'] = int(r[4]) # self.relay_rule_list[d['id']] = d # cur.close() conn.close() return rows
def del_server_out_of_bound_safe(self, last_rows, rows): #停止超流量的服务 #启动没超流量的服务 keymap = {} try: switchrule = importloader.load('switchrule') keymap = switchrule.getRowMap() except Exception as e: logging.error('load switchrule.py fail') cur_servers = {} new_servers = {} allow_users = {} mu_servers = {} config = shell.get_config(False) for row in rows: try: allow = switchrule.isTurnOn(row) and row['enable'] == 1 and row['u'] + row['d'] < row['transfer_enable'] except Exception as e: allow = False port = row['port'] passwd = common.to_bytes(row['passwd']) if hasattr(passwd, 'encode'): passwd = passwd.encode('utf-8') cfg = {'password': passwd} if 'id' in row: self.port_uid_table[row['port']] = row['id'] read_config_keys = ['method', 'obfs', 'obfs_param', 'protocol', 'protocol_param', 'forbidden_ip', 'forbidden_port', 'speed_limit_per_con', 'speed_limit_per_user'] for name in read_config_keys: if name in row and row[name]: if name in keymap: cfg[keymap[name]] = row[name] else: cfg[name] = row[name] merge_config_keys = ['password'] + read_config_keys for name in cfg.keys(): if hasattr(cfg[name], 'encode'): try: cfg[name] = cfg[name].encode('utf-8') except Exception as e: logging.warning('encode cfg key "%s" fail, val "%s"' % (name, cfg[name])) if port not in cur_servers: cur_servers[port] = passwd else: logging.error('more than one user use the same port [%s]' % (port,)) continue if 'protocol' in cfg and 'protocol_param' in cfg and common.to_str(cfg['protocol']) in obfs.mu_protocol(): if '#' in common.to_str(cfg['protocol_param']): mu_servers[port] = passwd allow = True if allow: if port not in mu_servers: allow_users[port] = cfg cfgchange = False if port in ServerPool.get_instance().tcp_servers_pool: relay = ServerPool.get_instance().tcp_servers_pool[port] for name in merge_config_keys: if name in cfg and not self.cmp(cfg[name], relay._config[name]): cfgchange = True break if not cfgchange and port in ServerPool.get_instance().tcp_ipv6_servers_pool: relay = ServerPool.get_instance().tcp_ipv6_servers_pool[port] for name in merge_config_keys: if (name in cfg) and ((name not in relay._config) or not self.cmp(cfg[name], relay._config[name])): cfgchange = True break if port in mu_servers: if ServerPool.get_instance().server_is_run(port) > 0: if cfgchange: logging.info('db stop server at port [%s] reason: config changed: %s' % (port, cfg)) ServerPool.get_instance().cb_del_server(port) self.force_update_transfer.add(port) new_servers[port] = (passwd, cfg) else: self.new_server(port, passwd, cfg) else: if ServerPool.get_instance().server_is_run(port) > 0: if config['additional_ports_only'] or not allow: logging.info('db stop server at port [%s]' % (port,)) ServerPool.get_instance().cb_del_server(port) self.force_update_transfer.add(port) else: if cfgchange: logging.info('db stop server at port [%s] reason: config changed: %s' % (port, cfg)) ServerPool.get_instance().cb_del_server(port) self.force_update_transfer.add(port) new_servers[port] = (passwd, cfg) elif not config['additional_ports_only'] and allow and port > 0 and port < 65536 and ServerPool.get_instance().server_run_status(port) is False: self.new_server(port, passwd, cfg) for row in last_rows: if row['port'] in cur_servers: pass else: logging.info('db stop server at port [%s] reason: port not exist' % (row['port'])) ServerPool.get_instance().cb_del_server(row['port']) self.clear_cache(row['port']) if row['port'] in self.port_uid_table: del self.port_uid_table[row['port']] if len(new_servers) > 0: from shadowsocks import eventloop self.event.wait(eventloop.TIMEOUT_PRECISION + eventloop.TIMEOUT_PRECISION / 2) for port in new_servers.keys(): passwd, cfg = new_servers[port] self.new_server(port, passwd, cfg) logging.debug('db allow users %s \nmu_servers %s' % (allow_users, mu_servers)) for port in mu_servers: ServerPool.get_instance().update_mu_users(port, allow_users) self.mu_ports = mu_servers
def del_server_out_of_bound_safe(self, last_rows, rows): #停止超流量的服务 #启动没超流量的服务 try: switchrule = importloader.load('switchrule') except Exception as e: logging.error('load switchrule.py fail') cur_servers = {} new_servers = {} allow_users = {} mu_servers = {} config = shell.get_config(False) for row in rows: try: allow = switchrule.isTurnOn(row) and row['enable'] == 1 and row['u'] + row['d'] < row['transfer_enable'] except Exception as e: allow = False port = row['port'] passwd = common.to_bytes(row['passwd']) if hasattr(passwd, 'encode'): passwd = passwd.encode('utf-8') cfg = {'password': passwd} if 'id' in row: self.port_uid_table[row['port']] = row['id'] read_config_keys = ['method', 'obfs', 'obfs_param', 'protocol', 'protocol_param', 'forbidden_ip', 'forbidden_port', 'speed_limit_per_con', 'speed_limit_per_user'] for name in read_config_keys: if name in row and row[name]: cfg[name] = row[name] merge_config_keys = ['password'] + read_config_keys for name in cfg.keys(): if hasattr(cfg[name], 'encode'): try: cfg[name] = cfg[name].encode('utf-8') except Exception as e: logging.warning('encode cfg key "%s" fail, val "%s"' % (name, cfg[name])) if port not in cur_servers: cur_servers[port] = passwd else: logging.error('more than one user use the same port [%s]' % (port,)) continue if 'protocol' in cfg and 'protocol_param' in cfg and common.to_str(cfg['protocol']) in obfs.mu_protocol(): if '#' in common.to_str(cfg['protocol_param']): mu_servers[port] = passwd allow = True if allow: if port not in mu_servers: allow_users[port] = cfg cfgchange = False if port in ServerPool.get_instance().tcp_servers_pool: relay = ServerPool.get_instance().tcp_servers_pool[port] for name in merge_config_keys: if name in cfg and not self.cmp(cfg[name], relay._config[name]): cfgchange = True break if not cfgchange and port in ServerPool.get_instance().tcp_ipv6_servers_pool: relay = ServerPool.get_instance().tcp_ipv6_servers_pool[port] for name in merge_config_keys: if (name in cfg) and ((name not in relay._config) or not self.cmp(cfg[name], relay._config[name])): cfgchange = True break if port in mu_servers: if ServerPool.get_instance().server_is_run(port) > 0: if cfgchange: logging.info('db stop server at port [%s] reason: config changed: %s' % (port, cfg)) ServerPool.get_instance().cb_del_server(port) self.force_update_transfer.add(port) new_servers[port] = (passwd, cfg) else: self.new_server(port, passwd, cfg) else: if ServerPool.get_instance().server_is_run(port) > 0: if config['additional_ports_only'] or not allow: logging.info('db stop server at port [%s]' % (port,)) ServerPool.get_instance().cb_del_server(port) self.force_update_transfer.add(port) else: if cfgchange: logging.info('db stop server at port [%s] reason: config changed: %s' % (port, cfg)) ServerPool.get_instance().cb_del_server(port) self.force_update_transfer.add(port) new_servers[port] = (passwd, cfg) elif not config['additional_ports_only'] and allow and port > 0 and port < 65536 and ServerPool.get_instance().server_run_status(port) is False: self.new_server(port, passwd, cfg) for row in last_rows: if row['port'] in cur_servers: pass else: logging.info('db stop server at port [%s] reason: port not exist' % (row['port'])) ServerPool.get_instance().cb_del_server(row['port']) self.clear_cache(row['port']) if row['port'] in self.port_uid_table: del self.port_uid_table[row['port']] if len(new_servers) > 0: from shadowsocks import eventloop self.event.wait(eventloop.TIMEOUT_PRECISION + eventloop.TIMEOUT_PRECISION / 2) for port in new_servers.keys(): passwd, cfg = new_servers[port] self.new_server(port, passwd, cfg) logging.debug('db allow users %s \nmu_servers %s' % (allow_users, mu_servers)) for port in mu_servers: ServerPool.get_instance().update_mu_users(port, allow_users) self.mu_ports = mu_servers