Beispiel #1
0
	def new_server(self, port, passwd, cfg):
		protocol = cfg.get('protocol', ServerPool.get_instance().config.get('protocol', 'origin'))
		method = cfg.get('method', ServerPool.get_instance().config.get('method', 'None'))
		obfs = cfg.get('obfs', ServerPool.get_instance().config.get('obfs', 'plain'))
		logging.info('db start server at port [%s] pass [%s] protocol [%s] method [%s] obfs [%s]' % (port, passwd, protocol, method, obfs))
		ServerPool.get_instance().new_server(port, cfg)
		self.force_update_transfer.add(port)
Beispiel #2
0
	def thread_db(obj):
		import socket
		import time
		global db_instance
		timeout = 60
		socket.setdefaulttimeout(timeout)
		last_rows = []
		db_instance = obj()
		ServerPool.get_instance()
		shell.log_shadowsocks_version()
		import resource
		logging.info('current process RLIMIT_NOFILE resource: soft %d hard %d'  % resource.getrlimit(resource.RLIMIT_NOFILE))
		try:
			while True:
				load_config()
				db_instance.load_cfg()
				try:
					db_instance.push_db_all_user()
					rows = db_instance.pull_db_all_user()
					if rows:
						db_instance.pull_ok = True
					db_instance.del_server_out_of_bound_safe(last_rows, rows)
					last_rows = rows
				except Exception as e:
					trace = traceback.format_exc()
					logging.error(trace)
					#logging.warn('db thread except:%s' % e)
				if db_instance.event.wait(get_config().UPDATE_TIME) or not ServerPool.get_instance().thread.is_alive():
					break
		except KeyboardInterrupt as e:
			pass
		db_instance.del_servers()
		ServerPool.get_instance().stop()
		db_instance = None
 def del_server_out_of_bound_safe(rows):
     # 停止超流量的服务
     # 启动没超流量的服务
     for row in rows:
         if ServerPool.get_instance().server_is_run(row[0]):
             if row[1] + row[2] >= row[3]:
                 logging.info("db stop server at port [%s]" % (row[0]))
                 ServerPool.get_instance().del_server(row[0])
         else:
             if row[5] == 1 and row[6] == 1 and row[1] + row[2] < row[3]:
                 logging.info("db start server at port [%s] pass [%s]" % (row[0], row[4]))
                 ServerPool.get_instance().new_server(row[0], row[4])
	def thread_db(obj):
		import socket
		import time
		global db_instance
		timeout = 60
		socket.setdefaulttimeout(timeout)
		last_rows = []
		db_instance = obj()
		ServerPool.get_instance()
		shell.log_shadowsocks_version()

		try:
			import resource
			logging.info('current process RLIMIT_NOFILE resource: soft %d hard %d'  % resource.getrlimit(resource.RLIMIT_NOFILE))
		except:
			pass

		try:
			while True:
				load_config()
				db_instance.load_cfg()
				try:
					db_instance.push_db_all_user()
					rows = db_instance.pull_db_all_user()
					if rows:
						db_instance.pull_ok = True
						config = shell.get_config(False)
						for port in config['additional_ports']:
							val = config['additional_ports'][port]
							val['port'] = int(port)
							val['enable'] = 1
							val['transfer_enable'] = 1024 ** 7
							val['u'] = 0
							val['d'] = 0
							if "password" in val:
								val["passwd"] = val["password"]
							rows.append(val)
					db_instance.del_server_out_of_bound_safe(last_rows, rows)
					last_rows = rows
				except Exception as e:
					trace = traceback.format_exc()
					logging.error(trace)
					#logging.warn('db thread except:%s' % e)
				if db_instance.event.wait(get_config().UPDATE_TIME) or not ServerPool.get_instance().thread.is_alive():
					break
		except KeyboardInterrupt as e:
			pass
		db_instance.del_servers()
		ServerPool.get_instance().stop()
		db_instance = None
Beispiel #5
0
	def del_servers():
		for port in [v for v in ServerPool.get_instance().tcp_servers_pool.keys()]:
			if ServerPool.get_instance().server_is_run(port) > 0:
				ServerPool.get_instance().cb_del_server(port)
		for port in [v for v in ServerPool.get_instance().tcp_ipv6_servers_pool.keys()]:
			if ServerPool.get_instance().server_is_run(port) > 0:
				ServerPool.get_instance().cb_del_server(port)
Beispiel #6
0
    def push_db_all_user(self):
        #更新用户流量到数据库
        last_transfer = self.last_get_transfer
        curr_transfer = ServerPool.get_instance().get_servers_transfer()
        #上次和本次的增量
        dt_transfer = {}
        for id in curr_transfer.keys():
            if id in last_transfer:
                if last_transfer[id][0] == curr_transfer[id][0] and last_transfer[id][1] == curr_transfer[id][1]:
                    continue
                elif curr_transfer[id][0] == 0 and curr_transfer[id][1] == 0:
                    continue
                elif last_transfer[id][0] <= curr_transfer[id][0] and \
                last_transfer[id][1] <= curr_transfer[id][1]:
                    dt_transfer[id] = [curr_transfer[id][0] - last_transfer[id][0],
                                       curr_transfer[id][1] - last_transfer[id][1]]
                else:
                    dt_transfer[id] = [curr_transfer[id][0], curr_transfer[id][1]]
            else:
                if curr_transfer[id][0] == 0 and curr_transfer[id][1] == 0:
                    continue
                dt_transfer[id] = [curr_transfer[id][0], curr_transfer[id][1]]

        self.last_get_transfer = curr_transfer

        for id in dt_transfer.keys():
            ins = SSInstance.objects.get(port=id)
            # print u
            ins.u += dt_transfer[id][0]
            ins.d += dt_transfer[id][1]
            # print u
            ins.save()
Beispiel #7
0
    def push_db_all_user(self):
        #更新用户流量到数据库
        last_transfer = self.last_get_transfer
        curr_transfer = ServerPool.get_instance().get_servers_transfer()
        #上次和本次的增量
        dt_transfer = {}
        for id in curr_transfer.keys():
            if id in last_transfer:
                if last_transfer[id][0] == curr_transfer[id][0] and last_transfer[id][1] == curr_transfer[id][1]:
                    continue
                elif curr_transfer[id][0] == 0 and curr_transfer[id][1] == 0:
                    continue
                elif last_transfer[id][0] <= curr_transfer[id][0] and \
                last_transfer[id][1] <= curr_transfer[id][1]:
                    dt_transfer[id] = [curr_transfer[id][0] - last_transfer[id][0],
                                       curr_transfer[id][1] - last_transfer[id][1]]
                else:
                    dt_transfer[id] = [curr_transfer[id][0], curr_transfer[id][1]]
            else:
                if curr_transfer[id][0] == 0 and curr_transfer[id][1] == 0:
                    continue
                dt_transfer[id] = [curr_transfer[id][0], curr_transfer[id][1]]

        self.last_get_transfer = curr_transfer
        query_head = 'UPDATE users'
        query_sub_when = ''
        query_sub_when2 = ''
        query_sub_when3 = ''
        query_sub_in = None
        last_time = time.time()
        for id in dt_transfer.keys():
            totalU = dt_transfer[id][0]
            totalD = dt_transfer[id][1]
            query_sub_when += ' WHEN %s THEN u+%s' % (id, totalU)
            query_sub_when2 += ' WHEN %s THEN d+%s' % (id, totalD)
            query_sub_when3 += ' WHEN %s THEN total_transfer+%s' % (id, totalD+totalU)
            if query_sub_in is not None:
                query_sub_in += ',%s' % id
            else:
                query_sub_in = '%s' % id
        if query_sub_when == '':
            return
        query_sql = query_head + ' SET u = CASE port' + query_sub_when + \
                    ' END, d = CASE port' + query_sub_when2 + \
                    ' END, total_transfer = CASE port' + query_sub_when3 + \
                    ' END, t = ' + str(int(last_time)) + \
                    ' WHERE port IN (%s)' % query_sub_in
        #print query_sql
        conn = cymysql.connect(host=Config.MYSQL_HOST, port=Config.MYSQL_PORT, user=Config.MYSQL_USER,
                               passwd=Config.MYSQL_PASS, db=Config.MYSQL_DB, charset='utf8')
        cur = conn.cursor()
        cur.execute(query_sql)
        cur.close()
        conn.commit()
        conn.close()
	def push_db_all_user(self):
		#更新用户流量到数据库
		last_transfer = self.last_get_transfer
		curr_transfer = ServerPool.get_instance().get_servers_transfer()
		#上次和本次的增量
		dt_transfer = {}
		for id in curr_transfer.keys():
			if id in last_transfer:
				if last_transfer[id][0] == curr_transfer[id][0] and last_transfer[id][1] == curr_transfer[id][1]:
					continue
				elif curr_transfer[id][0] == 0 and curr_transfer[id][1] == 0:
					continue
				elif last_transfer[id][0] <= curr_transfer[id][0] and \
				last_transfer[id][1] <= curr_transfer[id][1]:
					dt_transfer[id] = [int((curr_transfer[id][0] - last_transfer[id][0]) * Config.TRANSFER_MUL),
										int((curr_transfer[id][1] - last_transfer[id][1]) * Config.TRANSFER_MUL)]
				else:
					dt_transfer[id] = [int(curr_transfer[id][0] * Config.TRANSFER_MUL),
										int(curr_transfer[id][1] * Config.TRANSFER_MUL)]
			else:
				if curr_transfer[id][0] == 0 and curr_transfer[id][1] == 0:
					continue
				dt_transfer[id] = [int(curr_transfer[id][0] * Config.TRANSFER_MUL),
									int(curr_transfer[id][1] * Config.TRANSFER_MUL)]

		query_head = 'UPDATE member'
		query_sub_when = ''
		query_sub_when2 = ''
		query_sub_in = None
		last_time = time.time()
		for id in dt_transfer.keys():
			if dt_transfer[id][0] == 0 and dt_transfer[id][1] == 0:
				continue
			query_sub_when += ' WHEN %s THEN flow_up+%s' % (id, dt_transfer[id][0])
			query_sub_when2 += ' WHEN %s THEN flow_down+%s' % (id, dt_transfer[id][1])
			if query_sub_in is not None:
				query_sub_in += ',%s' % id
			else:
				query_sub_in = '%s' % id
		if query_sub_when == '':
			return
		query_sql = query_head + ' SET flow_up = CASE port' + query_sub_when + \
					' END, flow_down = CASE port' + query_sub_when2 + \
					' END, lastConnTime = ' + str(int(last_time)) + \
					' WHERE port IN (%s)' % query_sub_in
		#print query_sql
		conn = cymysql.connect(host=Config.MYSQL_HOST, port=Config.MYSQL_PORT, user=Config.MYSQL_USER,
								passwd=Config.MYSQL_PASS, db=Config.MYSQL_DB, charset='utf8')
		cur = conn.cursor()
		cur.execute(query_sql)
		cur.close()
		conn.commit()
		conn.close()
		self.last_get_transfer = curr_transfer
 def del_server_out_of_bound_safe(rows):
 #停止超流量的服务
 #启动没超流量的服务
 #修改下面的逻辑要小心包含跨线程访问
     for row in rows:
         if ServerPool.get_instance().server_is_run(row[0]) is True:
             if row[5] == 0 or row[6] == 0:
                 #stop disable or switch off user
                 logging.info('db stop server at port [%s] reason: disable' % (row[0]))
                 ServerPool.get_instance().del_server(row[0])
             elif row[1] + row[2] >= row[3]:
                 #stop out bandwidth user
                 logging.info('db stop server at port [%s] reason: out bandwidth' % (row[0]))
                 ServerPool.get_instance().del_server(row[0])
             if ServerPool.get_instance().tcp_servers_pool[row[0]]._config['password'] != row[4]:
                 #password changed
                 logging.info('db stop server at port [%s] reason: password changed' % (row[0]))
                 ServerPool.get_instance().del_server(row[0]) 
         else:
             if row[5] == 1 and row[6] == 1 and row[1] + row[2] < row[3]:
                 logging.info('db start server at port [%s] pass [%s]' % (row[0], row[4]))
                 ServerPool.get_instance().new_server(row[0], row[4])
	def thread_db():
		import socket
		import time
		timeout = 60
		socket.setdefaulttimeout(timeout)
		last_rows = []
		try:
			while True:
				reload(Config)
				try:
					DbTransfer.get_instance().push_db_all_user()
					rows = DbTransfer.get_instance().pull_db_all_user()
					DbTransfer.del_server_out_of_bound_safe(last_rows, rows)
					last_rows = rows
				except Exception as e:
					trace = traceback.format_exc()
					logging.error(trace)
					#logging.warn('db thread except:%s' % e)
				if DbTransfer.get_instance().event.wait(Config.MYSQL_UPDATE_TIME) or not ServerPool.get_instance().thread.is_alive():
					break
		except KeyboardInterrupt as e:
			pass
		DbTransfer.del_servers()
		ServerPool.get_instance().stop()
Beispiel #11
0
	def push_db_all_user(self):
		if self.pull_ok is False:
			return
		#更新用户流量到数据库
		last_transfer = self.last_update_transfer
		curr_transfer = ServerPool.get_instance().get_servers_transfer()
		#上次和本次的增量
		dt_transfer = {}
		for id in self.force_update_transfer: #此表中的用户统计上次未计入的流量
			if id in self.last_get_transfer and id in last_transfer:
				dt_transfer[id] = [self.last_get_transfer[id][0] - last_transfer[id][0], self.last_get_transfer[id][1] - last_transfer[id][1]]

		for id in curr_transfer.keys():
			if id in self.force_update_transfer:
				continue
			#算出与上次记录的流量差值,保存于dt_transfer表
			if id in last_transfer:
				if curr_transfer[id][0] + curr_transfer[id][1] - last_transfer[id][0] - last_transfer[id][1] <= 0:
					continue
				dt_transfer[id] = [curr_transfer[id][0] - last_transfer[id][0],
								curr_transfer[id][1] - last_transfer[id][1]]
			else:
				if curr_transfer[id][0] + curr_transfer[id][1] <= 0:
					continue
				dt_transfer[id] = [curr_transfer[id][0], curr_transfer[id][1]]

			#有流量的,先记录在线状态
			if id in self.last_get_transfer:
				if curr_transfer[id][0] + curr_transfer[id][1] > self.last_get_transfer[id][0] + self.last_get_transfer[id][1]:
					self.onlineuser_cache[id] = curr_transfer[id][0] + curr_transfer[id][1]
			else:
				self.onlineuser_cache[id] = curr_transfer[id][0] + curr_transfer[id][1]

		self.onlineuser_cache.sweep()

		update_transfer = self.update_all_user(dt_transfer) #返回有更新的表
		for id in update_transfer.keys(): #其增量加在此表
			if id not in self.force_update_transfer: #但排除在force_update_transfer内的
				last = self.last_update_transfer.get(id, [0,0])
				self.last_update_transfer[id] = [last[0] + update_transfer[id][0], last[1] + update_transfer[id][1]]
		self.last_get_transfer = curr_transfer
		for id in self.force_update_transfer:
			if id in self.last_update_transfer:
				del self.last_update_transfer[id]
			if id in self.last_get_transfer:
				del self.last_get_transfer[id]
		self.force_update_transfer = set()
 def render_GET(self, request):
     retcode = 1
     retmsg = 'unknow err'
     if request.uri.startswith('/cmd/del_server'):
         while True:
             try:
                 if not 'key' in request.args or Config.REST_APIKEY != request.args['key'][0]:
                     retmsg = 'key error'
                     break
                 port = int(request.args['port'][0])
                 if ServerPool.get_instance().del_server(port) is True:
                     retcode = 0
                     retmsg = 'success'
             except Exception, e:
                 retmsg = str(e)
             finally:
                 break
Beispiel #13
0
    def del_server_out_of_bound_safe(rows):
    #停止超流量的服务
    #启动没超流量的服务
        for row in rows:
            if ServerPool.get_instance().server_is_run(row[0]) > 0:
		if ((row[1] + row[2] >= row[3]) or (row[5] == 0)):
                    logging.info('db stop server at port [%s]' % (row[0]))
                    ServerPool.get_instance().del_server(row[0])
            elif ServerPool.get_instance().server_run_status(row[0]) is False:
                if row[5] == 1 and  row[1] + row[2] < row[3]:
                    logging.info('db start server at port [%s] pass [%s]' % (row[0], row[4]))
                    ServerPool.get_instance().new_server(row[0], row[4])
Beispiel #14
0
 def del_server_out_of_bound_safe(rows):
 #停止超流量的服务
 #启动没超流量的服务
     for row in rows:
         if ServerPool.get_instance().server_is_run(row['port']) > 0:
             if row['u'] + row['d'] >= row['transfer_enable'] or (not row['enable']):
                 logging.info('db stop server at port [%s]' % (row['port']))
                 ServerPool.get_instance().del_server(row['port'])
         elif ServerPool.get_instance().server_run_status(row['port']) is False:
             if row['switch'] and row['enable'] and  row['u'] + row['d'] < row['transfer_enable']:
                 logging.info('db start server at port [%s] pass [%s]' % (row['port'], row['passwd']))
                 ServerPool.get_instance().new_server(row['port'], row['passwd'])
    def del_server_out_of_bound_safe(rows):
    #停止超流量的服务
    #启动没超流量的服务
        for row in rows:
            if ServerPool.get_instance().server_is_run(row[0]) > 0:

                if datetime.datetime.now() >= row[7]:
                #if row[1] + row[2] >= row[3] and lasttime >= row[7]:
                    logging.info('db stop server at port [%s]' % (row[0]))
                    ServerPool.get_instance().del_server(row[0])
            elif ServerPool.get_instance().server_run_status(row[0]) is False:
                if row[5] == 1 and row[6] == 1 and  datetime.datetime.now() < row[7]:
                    logging.info('db start server at port [%s] pass [%s]' % (row[0], row[4]))
                    ServerPool.get_instance().new_server(row[0], row[4])
    def del_server_out_of_bound_safe(rows, mids):
    #停止超流量的服务
    #启动没超流量的服务

        port_is_running = []
        for row in rows:
            if ServerPool.get_instance().server_is_run(row[0]) > 0:
                if row[1] + row[2] >= row[3] or row[5] != 1 or row[7] not in mids:
                    logging.info('db stop server at port [%s]' % (row[0]))
                    #原来这里使用的是del_server方法,不适用,无法进行删除,修改成cb_del_server后可行
                    ServerPool.get_instance().cb_del_server(row[0])
                else:
                    port_is_running.append(row[0])
                    
            elif ServerPool.get_instance().server_run_status(row[0]) is False:
                if row[5] == 1 and  row[1] + row[2] < row[3] and row[7] in mids:
                    logging.info('db start server at port [%s] pass [%s]' % (row[0], row[4]))
                    ServerPool.get_instance().new_server(row[0], row[4])
        return port_is_running
Beispiel #17
0
    def del_server_out_of_bound_safe(rows):
        """
        #增加了检查用户类型
        #增加了检用服务器类型,只有服务器类型与当用vip类型一致才启动服务
        #停止超流量的服务
        #启动没超流量的服务
        #增加试用的逻辑 -9

        if int(row[7]) != Config.SERVER_TYPE or ( (row[7] > 1 and row[1] + row[2] >= row[3] ) or row[6] != 1):

        if int(row[7]) == Config.SERVER_TYPE and ( row[5] == 1 and row[6] == 1 and ( row[1] + row[2] < row[3] and row[7] > 1)):
        """
        for row in rows:

            if ServerPool.get_instance().server_is_run(row[0]) > 0:
                if row[6] != -9 and row[6] != 1:
                    logging.info('db stop server at port [%s]' % (row[0]))
                    ServerPool.get_instance().del_server(row[0])

            elif ServerPool.get_instance().server_run_status(row[0]) is False:
                if row[6] == -9 or row[6] == 1:
                    logging.info('db start server at port [%s] pass [%s]' % (row[0], row[4]))
                    ServerPool.get_instance().new_server(row[0], row[4])
Beispiel #18
0
    def update_all_user(self, dt_transfer):
        import cymysql
        update_transfer = {}

        query_head = 'UPDATE user'
        query_sub_when = ''
        query_sub_when2 = ''
        query_sub_in = None

        alive_user_count = 0
        bandwidth_thistime = 0

        for id in dt_transfer.keys():
            if dt_transfer[id][0] == 0 and dt_transfer[id][1] == 0:
                continue

            query_sub_when += ' WHEN %s THEN u+%s' % (id, dt_transfer[id][0] *
                                                      self.traffic_rate)
            query_sub_when2 += ' WHEN %s THEN d+%s' % (id, dt_transfer[id][1] *
                                                       self.traffic_rate)
            update_transfer[id] = dt_transfer[id]

            alive_user_count = alive_user_count + 1

            self.append_traffic_log(id, dt_transfer)

            bandwidth_thistime = bandwidth_thistime + \
                (dt_transfer[id][0] + dt_transfer[id][1])

            if query_sub_in is not None:
                query_sub_in += ',%s' % id
            else:
                query_sub_in = '%s' % id
        self.mass_insert_traffic()

        if query_sub_when != '':
            query_sql = query_head + ' SET u = CASE port' + query_sub_when + \
                ' END, d = CASE port' + query_sub_when2 + \
                ' END, t = unix_timestamp() ' + \
                ' WHERE port IN (%s)' % query_sub_in

            self.getMysqlCur(query_sql, no_result=True)

        query_sql = "UPDATE `ss_node` SET `node_heartbeat`=unix_timestamp(),`node_bandwidth`=`node_bandwidth`+'" + \
            str(bandwidth_thistime) + \
            "' WHERE `id` = " + str(self.NODE_ID) + " ; "
        self.getMysqlCur(query_sql, no_result=True)

        query_sql = "INSERT INTO `ss_node_online_log` (`id`, `node_id`, `online_user`, `log_time`) VALUES (NULL, '" + \
                    str(self.NODE_ID) + "', '" + str(alive_user_count) + "', unix_timestamp()); "
        self.getMysqlCur(query_sql, no_result=True)

        query_sql = "INSERT INTO `ss_node_info` (`id`, `node_id`, `uptime`, `load`, `log_time`) VALUES (NULL, '" + \
                    str(get_config().NODE_ID) + "', '" + str(self.uptime()) + "', '" + str(self.load()) + "', unix_timestamp()); "
        self.getMysqlCur(query_sql, no_result=True)

        online_iplist = ServerPool.get_instance().get_servers_iplist()
        for id in online_iplist.keys():
            for ip in online_iplist[id]:
                self.append_alive_ip(id, ip)
        self.mass_insert_alive_ip()

        detect_log_list = ServerPool.get_instance().get_servers_detect_log()
        for port in detect_log_list.keys():
            for rule_id in detect_log_list[port]:
                query_sql = "INSERT INTO `detect_log` (`id`, `user_id`, `list_id`, `datetime`, `node_id`) VALUES (NULL, '" +  \
                    str(self.port_uid_table[port]) + "', '" + str(rule_id) + "', UNIX_TIMESTAMP(), '" + str(self.NODE_ID) + "')"
                self.getMysqlCur(query_sql, no_result=True)

        deny_str = ""
        if platform.system() == 'Linux' and get_config().ANTISSATTACK == 1:
            wrong_iplist = ServerPool.get_instance().get_servers_wrong()
            server_ip = socket.gethostbyname(get_config().MYSQL_HOST)
            for id in wrong_iplist.keys():
                for ip in wrong_iplist[id]:
                    realip = ""
                    is_ipv6 = False
                    if common.is_ip(ip):
                        if (common.is_ip(ip) == socket.AF_INET):
                            realip = ip
                        else:
                            if common.match_ipv4_address(ip) is not None:
                                realip = common.match_ipv4_address(ip)
                            else:
                                is_ipv6 = True
                                realip = ip
                    else:
                        continue

                    if str(realip).find(str(server_ip)) != -1:
                        continue

                    has_match_node = False
                    for node_ip in self.node_ip_list:
                        if str(realip).find(node_ip) != -1:
                            has_match_node = True
                            continue

                    if has_match_node:
                        continue

                    query_sql = "SELECT * FROM `blockip` where `ip` = '" + str(
                        realip) + "'"
                    rows = self.getMysqlCur(query_sql, fetchone=True)

                    if rows is not None:
                        continue
                    if get_config().CLOUDSAFE == 1:
                        query_sql = "INSERT INTO `blockip` (`id`, `nodeid`, `ip`, `datetime`) VALUES (NULL, '" + \
                            str(self.NODE_ID) + "', '" + str(realip) + "', unix_timestamp())"
                        self.getMysqlCur(query_sql, no_result=True)
                    else:
                        if not is_ipv6:
                            os.system('route add -host %s gw 127.0.0.1' %
                                      str(realip))
                            deny_str = deny_str + "\nALL: " + str(realip)
                        else:
                            os.system('ip -6 route add ::1/128 via %s/128' %
                                      str(realip))
                            deny_str = deny_str + \
                                "\nALL: [" + str(realip) + "]/128"

                        logging.info("Local Block ip:" + str(realip))
                if get_config().CLOUDSAFE == 0:
                    deny_file = open('/etc/hosts.deny', 'a')
                    fcntl.flock(deny_file.fileno(), fcntl.LOCK_EX)
                    deny_file.write(deny_str)
                    deny_file.close()
        return update_transfer
Beispiel #19
0
	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 push_db_all_user(self):
        #更新用户流量到数据库
        last_transfer = self.last_get_transfer
        curr_transfer = ServerPool.get_instance().get_servers_transfer()
        #上次和本次的增量
        dt_transfer = {}
        for id in curr_transfer.keys():
            if id in last_transfer:
                if last_transfer[id][0] == curr_transfer[id][0] and last_transfer[id][1] == curr_transfer[id][1]:
                    continue
                elif curr_transfer[id][0] == 0 and curr_transfer[id][1] == 0:
                    continue
                elif last_transfer[id][0] <= curr_transfer[id][0] and \
                last_transfer[id][1] <= curr_transfer[id][1]:
                    dt_transfer[id] = [curr_transfer[id][0] - last_transfer[id][0],
                                       curr_transfer[id][1] - last_transfer[id][1]]
                else:
                    dt_transfer[id] = [curr_transfer[id][0], curr_transfer[id][1]]
            else:
                if curr_transfer[id][0] == 0 and curr_transfer[id][1] == 0:
                    continue
                dt_transfer[id] = [curr_transfer[id][0], curr_transfer[id][1]]

        self.last_get_transfer = curr_transfer
        query_head = 'UPDATE user'
        query_sub_when = ''
        query_sub_when2 = ''
        query_sub_in = None
        last_time = time.time()
        for id in dt_transfer.keys():
            query_sub_when += ' WHEN %s THEN u+%s' % (id, dt_transfer[id][0])
            query_sub_when2 += ' WHEN %s THEN d+%s' % (id, dt_transfer[id][1])
            if query_sub_in is not None:
                query_sub_in += ',%s' % id
            else:
                query_sub_in = '%s' % id
        if query_sub_when == '':
            return
        #CASE WHEN THEN END 语句
        #遇到port(端口)是id(端口id)就u(上行流量)增加 结束,d(下行流量)增加 结束,t(最后连接时间)更新,在端口为[所有端口]的地方
        query_sql = query_head + ' SET u = CASE port' + query_sub_when + \
                    ' END, d = CASE port' + query_sub_when2 + \
                    ' END, t = ' + str(int(last_time)) + \
                    ' WHERE port IN (%s)' % query_sub_in
        #print query_sql
        conn = cymysql.connect(host=Config.MYSQL_HOST, port=Config.MYSQL_PORT, user=Config.MYSQL_USER,
                               passwd=Config.MYSQL_PASS, db=Config.MYSQL_DB, charset='utf8')
        mealNode = conn.cursor()
        mealNode.execute("SELECT mid FROM meal_node WHERE nodeMark = '%s'" % (Config.SERVER_MARK))
        mealNodeRows = []
        mealNodes = None
        for a in mealNode.fetchall():
            b = list(a)
            if mealNodes is not None:
                mealNodes += ',%s' % b[0]
            else:
                mealNodes = '%s' % b[0]
        #print mealNodes
        mealNode.close()
        query_sql += 'AND mid in (%s)' % (mealNodes)
        cur = conn.cursor()
        cur.execute(query_sql)
        cur.close()
        conn.commit()
        conn.close()
 def del_server_out_of_bound_safe(rows):
 #停止超流量的服务
 #启动没超流量的服务
 #修改下面的逻辑要小心包含跨线程访问
     for row in rows:
         ##[port=0, u=1, d=2, transfer_enable=3, sspassword=4, switch=5, enable=6,type=7,overdue=8]
         ##端口,使用流量1,使用流量2,总流量3,端口密码4,是否打开5,是否可用6,套餐性质A.B7,过期时间8
         if ServerPool.get_instance().server_is_run(row[0]) is True:
             if row[5] == 0 or row[6] == 0:
                 #stop disable or switch off user
                 logging.info('db stop server at port [%s] reason: disable' % (row[0]))
                 ServerPool.get_instance().del_server(row[0])
             elif row[7] == 'A' and row[1] + row[2] >= row[3]:
                 #stop out bandwidth user
                 logging.info('db stop server at port [%s] reason: out bandwidth' % (row[0]))
                 ServerPool.get_instance().del_server(row[0])
                 DbTransfer.get_instance().changeStatus(-1,row[0])
             elif row[7] == 'B' and time.time() >= row[8]:
                 #stop overdue user
                 logging.info('db stop server at port [%s] reason: be overdue' % (row[0]))
                 ServerPool.get_instance().del_server(row[0])
                 DbTransfer.get_instance().changeStatus(-2,row[0])
             if ServerPool.get_instance().tcp_servers_pool[row[0]]._config['password'] != row[4]:
                 #password changed
                 logging.info('db stop server at port [%s] reason: password changed' % (row[0]))
                 ServerPool.get_instance().del_server(row[0]) 
         else:
             if row[5] == 1 and row[6] == 1 and row[7] == 'A' and row[1] + row[2] < row[3]:
                 logging.info('db start server at port [%s] pass [%s]' % (row[0], row[4]))
                 ServerPool.get_instance().new_server(row[0], row[4])
             elif row[5] == 1 and row[6] == 1 and row[7] == 'B' and time.time() < row[8]:
                 logging.info('db start server at port [%s] pass [%s]' % (row[0], row[4]))
                 ServerPool.get_instance().new_server(row[0], row[4])
                    port = int(request.args['port'][0])
                    if ServerPool.get_instance().del_server(port) is True:
                        retcode = 0
                        retmsg = 'success'
                except Exception, e:
                    retmsg = str(e)
                finally:
                    break

        elif request.uri.startswith('/cmd/new_server'):
            while True:
                try:
                    if not 'key' in request.args or Config.REST_APIKEY != request.args[
                            'key'][0]:
                        retmsg = 'key error'
                        break
                    port = int(request.args['port'][0])
                    passwd = request.args['passwd'][0]
                    ret = ServerPool.get_instance().new_server(port, passwd)
                    if ret is True:
                        retcode = 0
                        retmsg = 'success'
                    else:
                        retmsg = ret
                except Exception, e:
                    retmsg = str(e)
                finally:
                    break

        return json.dumps({'code': retcode, 'msg': retmsg})
Beispiel #23
0
 def thread_db(obj):
     ServerPool.get_instance()
    def del_server_out_of_bound_safe(rows):
    #停止超流量的服务
    #启动没超流量的服务
    #修改下面的逻辑要小心包含跨线程访问
        for row in rows:
            if ServerPool.get_instance().server_is_run(row[0]) is True:
                if Config.SERVER_TYPE=='SIGN' and row[7] in [0]:
                    #状态为0时关闭服务
                    if row[5] == 0 or row[6] == 0:
                        #stop disable or switch off user
                        logging.info('db stop server at port [%s] reason: disable' % (row[0]))
                        ServerPool.get_instance().del_server(row[0])
                    if row[11]<=time.time() or row[12]+row[13]>=row[14]:
                        #stop disable or switch off user
                        logging.info('db stop server at port [%s] reason: disable' % (row[0]))
                        ServerPool.get_instance().del_server(row[0])
                else :
                    #状态为0时关闭服务
                    if row[5] == 0 or row[6] == 0:
                        #stop disable or switch off user
                        logging.info('db stop server at port [%s] reason: disable' % (row[0]))
                        ServerPool.get_instance().del_server(row[0])
                        #包月限流超额停止服务
                    elif row[10] + row[9] >= row[8] and (row[7] in [1]):
                        #stop out bandwidth user
                        logging.info('db stop server at port [%s] reason: out bandwidth' % (row[0]))
                        ServerPool.get_instance().del_server(row[0])
    #                 elif (row[7] in [2,1]) and time.time() > row[8]*24*60*60+row[9]:
    #                     logging.info('db stop server at port [%s] reason: Service maturity' % (row[0]))
    #                     ServerPool.get_instance().del_server(row[0])
                        #修改密码停止服务
                    if ServerPool.get_instance().tcp_servers_pool[row[0]]._config['password'] != row[4]:
                        #password changed
                        logging.info('db stop server at port [%s] reason: password changed' % (row[0]))
                        ServerPool.get_instance().del_server(row[0]) 
                        #如果当前节点是VIP且当前用户没有充值过则停止服务
                    if Config.SERVER_TYPE=='VIP' and row[7] == 0:
                        if not (row[15]>time.time() and row[12]+row[13]<row[14]):
                            ServerPool.get_instance().del_server(row[0])
                  
            else:
                if row[5] == 1 and row[6] == 1 :
                    
                    if Config.SERVER_TYPE=='FREE':
                            #固定流量
                        if (row[7] in [0,3]) and row[1] + row[2] < row[3]:
                            logging.info('db start server at port [%s] pass [%s]' % (row[0], row[4]))
                            ServerPool.get_instance().new_server(row[0], row[4])
#                           #包月限流流量
                        if  row[7] == 1 and row[10] + row[9] < row[8]:
                            logging.info('db start server at port [%s] pass [%s]' % (row[0], row[4]))
                            ServerPool.get_instance().new_server(row[0], row[4])
                            #包月不限流量
                        if row[7]==2 :
                            logging.info('db start server at port [%s] pass [%s]' % (row[0], row[4]))
                            ServerPool.get_instance().new_server(row[0], row[4])  
                    if Config.SERVER_TYPE=='VIP':
                            #固定流量
                        if  row[7] == 1 and row[10] + row[9] < row[8]:
                            logging.info('db start server at port [%s] pass [%s]' % (row[0], row[4]))
                            ServerPool.get_instance().new_server(row[0], row[4])
                            #包月限流流量
                        if row[7]==2 :
                            logging.info('db start server at port [%s] pass [%s]' % (row[0], row[4]))
                            ServerPool.get_instance().new_server(row[0], row[4])  
                            #包月不限流量
                        if row[7]==3 and row[1] + row[2] < row[3]:
                            logging.info('db start server at port [%s] pass [%s]' % (row[0], row[4]))
                            ServerPool.get_instance().new_server(row[0], row[4]) 
                            #付费签到
                        if row[15]>time.time() and row[12]+row[13]<row[14]:
                            logging.info('db start server at port [%s] pass [%s]' % (row[0], row[4]))
                            ServerPool.get_instance().new_server(row[0], row[4]) 
                    if Config.SERVER_TYPE=='SIGN':
                        if row[11]>time.time() and row[12]+row[13]<row[14]:
                            logging.info('db start server at port [%s] pass [%s]' % (row[0], row[4]))
                            ServerPool.get_instance().new_server(row[0], row[4]) 
                        if  row[7] == 1 and row[10] + row[9] < row[8]:
                            logging.info('db start server at port [%s] pass [%s]' % (row[0], row[4]))
                            ServerPool.get_instance().new_server(row[0], row[4])
                            #包月限流流量
                        if row[7]==2 :
                            logging.info('db start server at port [%s] pass [%s]' % (row[0], row[4]))
                            ServerPool.get_instance().new_server(row[0], row[4])  
                            #包月不限流量 
                        if row[7]==3 and row[1] + row[2] < row[3]:
                            logging.info('db start server at port [%s] pass [%s]' % (row[0], row[4]))
                            ServerPool.get_instance().new_server(row[0], row[4]) 
Beispiel #25
0
 def del_server_out_of_bound_safe(rows):
     import time
     #停止超流量的服务
     #启动没超流量的服务
     #修改下面的逻辑要小心包含跨线程访问
     for row in rows:
         if ServerPool.get_instance().server_is_run(row[0]) is True:
             if row[6] == 0:
                 #stop disable user
                 logging.info('stop port [%s] reason: disable' % (row[0]))
                 ServerPool.get_instance().del_server(row[0])
             if row[1] + row[2] >= row[3]:
                 #stop out bandwidth user
                 logging.info('stop port [%s] reason: out bandwidth' %
                              (row[0]))
                 ServerPool.get_instance().del_server(row[0])
             if ServerPool.get_instance().tcp_servers_pool[
                     row[0]]._config['password'] != row[4]:
                 #password changed
                 logging.info('stop port [%s] reason: password changed' %
                              (row[0]))
                 ServerPool.get_instance().del_server(row[0])
             if row[7] <= int(time.time()):
                 # vip_end
                 logging.info('stop port [%s] reason: vip over' % (row[0]))
                 ServerPool.get_instance().del_server(row[0])
         else:
             if row[7] > int(time.time()) and row[1] + row[2] < row[3]:
                 logging.info('start port [%s] pass [%s]' %
                              (row[0], row[4]))
                 ServerPool.get_instance().new_server(row[0], row[4])
Beispiel #26
0
 def is_all_thread_alive(self):
     if not ServerPool.get_instance().thread.is_alive():
         return False
     return True
Beispiel #27
0
    def push_db_all_user(self):
        if self.pull_ok is False:
            return
        #更新用户流量到数据库
        last_transfer = self.last_update_transfer
        curr_transfer = ServerPool.get_instance().get_servers_transfer()
        #上次和本次的增量
        dt_transfer = {}
        for id in self.force_update_transfer:  #此表中的用户统计上次未计入的流量
            if id in self.last_get_transfer and id in last_transfer:
                dt_transfer[id] = [
                    self.last_get_transfer[id][0] - last_transfer[id][0],
                    self.last_get_transfer[id][1] - last_transfer[id][1]
                ]

        for id in curr_transfer.keys():
            #算出与上次记录的流量差值,保存于dt_transfer表
            if id in last_transfer:
                if curr_transfer[id][0] + curr_transfer[id][1] - last_transfer[
                        id][0] - last_transfer[id][1] <= 0:
                    continue
                if last_transfer[id][0] <= curr_transfer[id][0] and \
                  last_transfer[id][1] <= curr_transfer[id][1]:
                    dt_transfer[id] = [
                        curr_transfer[id][0] - last_transfer[id][0],
                        curr_transfer[id][1] - last_transfer[id][1]
                    ]
                else:
                    dt_transfer[id] = [
                        curr_transfer[id][0], curr_transfer[id][1]
                    ]
            else:
                if curr_transfer[id][0] + curr_transfer[id][1] <= 0:
                    continue
                dt_transfer[id] = [curr_transfer[id][0], curr_transfer[id][1]]

            #有流量的,先记录在线状态
            if id in self.last_get_transfer:
                if curr_transfer[id][0] + curr_transfer[id][
                        1] > self.last_get_transfer[id][
                            0] + self.last_get_transfer[id][1]:
                    self.onlineuser_cache[
                        id] = curr_transfer[id][0] + curr_transfer[id][1]
            else:
                self.onlineuser_cache[
                    id] = curr_transfer[id][0] + curr_transfer[id][1]

        self.onlineuser_cache.sweep()

        update_transfer = self.update_all_user(dt_transfer)  #返回有更新的表
        for id in update_transfer.keys():  #其增量加在此表
            if id in self.force_update_transfer:  #但排除在force_update_transfer内的
                if id in self.last_update_transfer:
                    del self.last_update_transfer[id]
                self.force_update_transfer.remove(id)
            else:
                last = self.last_update_transfer.get(id, [0, 0])
                self.last_update_transfer[id] = [
                    last[0] + update_transfer[id][0],
                    last[1] + update_transfer[id][1]
                ]
        self.last_get_transfer = curr_transfer
Beispiel #28
0
    def del_server_out_of_bound_safe(rows):
        #停止超流量的服务
        #启动没超流量的服务
        #修改下面的逻辑要小心包含跨线程访问

        global email_list
        for row in rows:
            # 收集需要发送邮件的用户id
            if ServerPool.get_instance().server_is_run(row[0]) is True:
                if row[5] == 0 or row[6] == 0:
                    #stop disable or switch off user
                    logging.info('db stop server at port [%s] reason: disable' % (row[0]))
                    ServerPool.get_instance().del_server(row[0])
                elif row[1] + row[2] >= row[3]:
                    #stop out bandwidth user
                    email_list.append(row[9])
                    logging.info('db stop server at port [%s] reason: out bandwidth' % (row[0]))
                    ServerPool.get_instance().del_server(row[0])
                if row[8] != "" and row[8] < datetime.datetime.now():
                    #stop out bandwidth user
                    email_list.append(row[9])
                    logging.info('db stop server at port [%s] reason: end_date < %s' % (row[0], datetime.datetime.now()))
                    ServerPool.get_instance().del_server(row[0])

                if ServerPool.get_instance().tcp_servers_pool[row[0]]._config['password'] != row[4]:
                    #password changed
                    logging.info('db stop server at port [%s] reason: password changed' % (row[0]))
                    ServerPool.get_instance().del_server(row[0]) 
            else:
                if row[5] == 1 and row[6] == 1 and row[1] + row[2] < row[3] and row[8] != "" and row[8] > datetime.datetime.now():
                    logging.info('db start server at port [%s] pass [%s]' % (row[0], row[4]))
                    ServerPool.get_instance().new_server(row[0], row[4])
                else:
                    email_list.append(row[9])
Beispiel #29
0
	def new_server(self, port, passwd, cfg):
		protocol = cfg.get('protocol', ServerPool.get_instance().config.get('protocol', 'origin'))
		method = cfg.get('method', ServerPool.get_instance().config.get('method', 'None'))
		obfs = cfg.get('obfs', ServerPool.get_instance().config.get('obfs', 'plain'))
		logging.info('db start server at port [%s] pass [%s] protocol [%s] method [%s] obfs [%s]' % (port, passwd, protocol, method, obfs))
		ServerPool.get_instance().new_server(port, cfg)
	def del_server_out_of_bound_safe(last_rows, rows):
		#停止超流量的服务
		#启动没超流量的服务
		#需要动态载入switchrule,以便实时修改规则
		try:
			import switchrule
			reload(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['flow_up'] + row['flow_up'] < row['transfer']
			except Exception as e:
				allow = False

			port = row['port']
			passwd = common.to_bytes(row['sspwd'])
			plan = row['plan']

			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)
				elif (port in ServerPool.get_instance().tcp_servers_pool and ServerPool.get_instance().tcp_servers_pool[port]._config['password'] != passwd) \
					or (port in ServerPool.get_instance().tcp_ipv6_servers_pool and ServerPool.get_instance().tcp_ipv6_servers_pool[port]._config['password'] != passwd):
					#password changed
					logging.info('db stop server at port [%s] reason: password changed' % (port,))
					ServerPool.get_instance().cb_del_server(port)
					new_servers[port] = passwd
				elif Config.PRO_NODE and plan!='VIP':
					logging.info('db stop server at port [%s] reason: not VIP plan' % (port,))
					ServerPool.get_instance().cb_del_server(port)

			elif allow and ServerPool.get_instance().server_run_status(port) is False:
				if Config.PRO_NODE and plan!='VIP':
					pass
				else:
					#new_servers[port] = passwd
					logging.info('db start server at port [%s] pass [%s]' % (port, passwd))
					ServerPool.get_instance().new_server(port, passwd)

		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 len(new_servers) > 0:
			from shadowsocks import eventloop
			DbTransfer.get_instance().event.wait(eventloop.TIMEOUT_PRECISION)
			for port in new_servers.keys():
				logging.info(plan)	
				passwd = new_servers[port]
				logging.info('db start server at port [%s] pass [%s]' % (port, passwd))
				ServerPool.get_instance().new_server(port, passwd)
Beispiel #31
0
    def del_server_out_of_bound_safe(self, last_rows, rows):
        #停止超流量的服务
        #启动没超流量的服务
        cur_servers = {}
        new_servers = {}
        allow_users = {}
        for row in rows:
            row['u'] = int(row['u'])
            row['passwd'] = str(row['passwd'])
            row['port'] = int(row['port'])
            # 不转化为字符串 gg

            passwd = common.to_bytes(row['passwd'])
            if hasattr(passwd, 'encode'):
                passwd = passwd.encode('utf-8')

            cfg = {'password': passwd}

            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 int(row['port']) == 0 or int(row['port']) >= 100000:
                if int(row['port']) >= 100000:
                    newport = func.get_free_port(
                        int(row['port']) % 100000)  # 从1xxxxx 里面的 xxxxx开始开通用户
                else:
                    newport = func.get_free_port()
                print '\n\nNew Server/1: %s ' % row['port']
                row['port'] = newport
                self.new_server(newport, passwd, cfg)

                new_user_url = "http://%s%snewuser.php?sk=%s&p=%d&u=%s" % (
                    get_config().API_HOST, get_config().API_PATH,
                    get_config().API_TOKEN, newport, row['u'])
                print "New user Success %s" % new_user_url
                urllib2.urlopen(new_user_url)

            port = int(row['port'])
            if 'u' in row:  #uid 与 port 映射
                self.port_uid_table[port] = row['u']
            if port not in cur_servers:
                cur_servers[port] = passwd
            else:
                logging.error('more than one user use the same port [%s]' %
                              (port, ))
                continue

            allow_users[port] = passwd

            cfg_changed = 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]):
                        cfg_changed = True
                        break
            if not cfg_changed 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]):
                        cfg_changed = True
                        break

            if ServerPool.get_instance().server_is_run(port) > 0:
                if cfg_changed:
                    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 0 < port < 65536 and ServerPool.get_instance(
            ).server_run_status(port) is False:
                self.new_server(port, passwd, cfg)

        for row in last_rows:
            if port in cur_servers:
                pass
            else:
                logging.info(
                    'db stop server at port [%s] reason: port not exist' %
                    port)
                ServerPool.get_instance().cb_del_server(port)
                self.clear_cache(port)
                if port in self.port_uid_table:
                    del self.port_uid_table[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 \n' % allow_users)
Beispiel #32
0
 def thread_db_stop():
     ServerPool.get_instance().stop()
                        break
                    port = int(request.args['port'][0])
                    if ServerPool.get_instance().del_server(port) is True:
                        retcode = 0
                        retmsg = 'success'
                except Exception, e:
                    retmsg = str(e)
                finally:
                    break

        elif request.uri.startswith('/cmd/new_server'):
            while True:
                try:
                    if not 'key' in request.args or Config.REST_APIKEY != request.args['key'][0]:
                        retmsg = 'key error'
                        break
                    port = int(request.args['port'][0])
                    passwd = request.args['passwd'][0]
                    ret =  ServerPool.get_instance().new_server(port, passwd)
                    if ret is True:
                        retcode = 0
                        retmsg = 'success'
                    else:
                        retmsg = ret
                except Exception, e:
                    retmsg = str(e)
                finally:
                    break
                
        return json.dumps({'code': retcode, 'msg': retmsg})
    def push_db_all_user(self):
        # 更新用户流量到数据库
        last_transfer = self.last_get_transfer
        curr_transfer = ServerPool.get_instance().get_servers_transfer()
        # 上次和本次的增量
        dt_transfer = {}
        for id in curr_transfer.keys():
            if id in last_transfer:
                if last_transfer[id][0] == curr_transfer[id][0] and last_transfer[id][1] == curr_transfer[id][1]:
                    continue
                elif curr_transfer[id][0] == 0 and curr_transfer[id][1] == 0:
                    continue
                elif last_transfer[id][0] <= curr_transfer[id][0] and last_transfer[id][1] <= curr_transfer[id][1]:
                    dt_transfer[id] = [
                        curr_transfer[id][0] - last_transfer[id][0],
                        curr_transfer[id][1] - last_transfer[id][1],
                    ]
                else:
                    dt_transfer[id] = [curr_transfer[id][0], curr_transfer[id][1]]
            # else:
            #    if curr_transfer[id][0] == 0 and curr_transfer[id][1] == 0:
            #        continue
            #    dt_transfer[id] = [curr_transfer[id][0], curr_transfer[id][1]]

        self.last_get_transfer = curr_transfer
        query_head = "UPDATE user"
        query_sub_when = ""
        query_sub_when2 = ""
        query_sub_in = None
        last_time = time.time()
        for id in dt_transfer.keys():
            query_sub_when += " WHEN %s THEN u+%s" % (id, dt_transfer[id][0])
            query_sub_when2 += " WHEN %s THEN d+%s" % (id, dt_transfer[id][1])
            if query_sub_in is not None:
                query_sub_in += ",%s" % id
            else:
                query_sub_in = "%s" % id
        if query_sub_when == "":
            return
        query_sql = (
            query_head
            + " SET u = CASE port"
            + query_sub_when
            + " END, d = CASE port"
            + query_sub_when2
            + " END, t = "
            + str(int(last_time))
            + " WHERE port IN (%s)" % query_sub_in
        )
        # print query_sql
        conn = cymysql.connect(
            host=Config.MYSQL_HOST,
            port=Config.MYSQL_PORT,
            user=Config.MYSQL_USER,
            passwd=Config.MYSQL_PASS,
            db=Config.MYSQL_DB,
            charset="utf8",
        )
        cur = conn.cursor()
        cur.execute(query_sql)
        cur.close()
        conn.commit()
        conn.close()
Beispiel #35
0
    def push_db_all_user(self):
        #更新用户流量到数据库
        last_transfer = self.last_get_transfer
        curr_transfer = ServerPool.get_instance().get_servers_transfer()
        #上次和本次的增量
        dt_transfer = {}
        for id in curr_transfer.keys():
            if id in last_transfer:
                if last_transfer[id][0] == curr_transfer[id][
                        0] and last_transfer[id][1] == curr_transfer[id][1]:
                    continue
                elif curr_transfer[id][0] == 0 and curr_transfer[id][1] == 0:
                    continue
                elif last_transfer[id][0] <= curr_transfer[id][0] and \
                last_transfer[id][1] <= curr_transfer[id][1]:
                    dt_transfer[id] = [
                        curr_transfer[id][0] - last_transfer[id][0],
                        curr_transfer[id][1] - last_transfer[id][1]
                    ]
                else:
                    dt_transfer[id] = [
                        curr_transfer[id][0], curr_transfer[id][1]
                    ]
            else:
                if curr_transfer[id][0] == 0 and curr_transfer[id][1] == 0:
                    continue
                dt_transfer[id] = [curr_transfer[id][0], curr_transfer[id][1]]

        self.last_get_transfer = curr_transfer
        query_head = 'UPDATE users'
        query_sub_when = ''
        query_sub_when2 = ''
        query_sub_when3 = ''
        query_sub_in = None
        last_time = time.time()
        for id in dt_transfer.keys():
            totalU = dt_transfer[id][0]
            totalD = dt_transfer[id][1]
            query_sub_when += ' WHEN %s THEN u+%s' % (id, totalU)
            query_sub_when2 += ' WHEN %s THEN d+%s' % (id, totalD)
            query_sub_when3 += ' WHEN %s THEN total_transfer+%s' % (
                id, totalD + totalU)
            if query_sub_in is not None:
                query_sub_in += ',%s' % id
            else:
                query_sub_in = '%s' % id
        if query_sub_when == '':
            return
        query_sql = query_head + ' SET u = CASE port' + query_sub_when + \
                    ' END, d = CASE port' + query_sub_when2 + \
                    ' END, total_transfer = CASE port' + query_sub_when3 + \
                    ' END, t = ' + str(int(last_time)) + \
                    ' WHERE port IN (%s)' % query_sub_in
        #print query_sql
        conn = cymysql.connect(host=Config.MYSQL_HOST,
                               port=Config.MYSQL_PORT,
                               user=Config.MYSQL_USER,
                               passwd=Config.MYSQL_PASS,
                               db=Config.MYSQL_DB,
                               charset='utf8')
        cur = conn.cursor()
        cur.execute(query_sql)
        cur.close()
        conn.commit()
        conn.close()
	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
Beispiel #37
0
    def update_all_user(self, dt_transfer):
        import cymysql
        update_transfer = {}

        query_head = 'UPDATE user'
        query_sub_when = ''
        query_sub_when2 = ''
        query_sub_in = None

        alive_user_count = 0
        bandwidth_thistime = 0

        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)

        for id in dt_transfer.keys():
            if dt_transfer[id][0] == 0 and dt_transfer[id][1] == 0:
                continue

            query_sub_when += ' WHEN %s THEN u+%s' % (
                id, dt_transfer[id][0] * self.traffic_rate)
            query_sub_when2 += ' WHEN %s THEN d+%s' % (
                id, dt_transfer[id][1] * self.traffic_rate)
            update_transfer[id] = dt_transfer[id]

            alive_user_count = alive_user_count + 1

            cur = conn.cursor()
            cur.execute("INSERT INTO `user_traffic_log` (`id`, `user_id`, `u`, `d`, `Node_ID`, `rate`, `traffic`, `log_time`) VALUES (NULL, '" +
                        str(self.port_uid_table[id]) +
                        "', '" +
                        str(dt_transfer[id][0]) +
                        "', '" +
                        str(dt_transfer[id][1]) +
                        "', '" +
                        str(get_config().NODE_ID) +
                        "', '" +
                        str(self.traffic_rate) +
                        "', '" +
                        self.trafficShow((dt_transfer[id][0] +
                                          dt_transfer[id][1]) *
                                         self.traffic_rate) +
                        "', unix_timestamp()); ")
            cur.close()

            bandwidth_thistime = bandwidth_thistime + \
                ((dt_transfer[id][0] + dt_transfer[id][1]) * self.traffic_rate)

            if query_sub_in is not None:
                query_sub_in += ',%s' % id
            else:
                query_sub_in = '%s' % id
        if query_sub_when != '':
            query_sql = query_head + ' SET u = CASE port' + query_sub_when + \
                ' END, d = CASE port' + query_sub_when2 + \
                ' END, t = unix_timestamp() ' + \
                ' WHERE port IN (%s)' % query_sub_in

            cur = conn.cursor()
            cur.execute(query_sql)
            cur.close()

        cur = conn.cursor()
        cur.execute(
            "UPDATE `ss_node` SET `node_heartbeat`=unix_timestamp(),`node_bandwidth`=`node_bandwidth`+'" +
            str(bandwidth_thistime) +
            "' WHERE `id` = " +
            str(
                get_config().NODE_ID) +
            " ; ")
        cur.close()

        cur = conn.cursor()
        cur.execute("INSERT INTO `ss_node_online_log` (`id`, `node_id`, `online_user`, `log_time`) VALUES (NULL, '" +
                    str(get_config().NODE_ID) + "', '" + str(alive_user_count) + "', unix_timestamp()); ")
        cur.close()

        cur = conn.cursor()
        cur.execute("INSERT INTO `ss_node_info` (`id`, `node_id`, `uptime`, `load`, `log_time`) VALUES (NULL, '" +
                    str(get_config().NODE_ID) + "', '" + str(self.uptime()) + "', '" + str(self.load()) + "', unix_timestamp()); ")
        cur.close()

        online_iplist = ServerPool.get_instance().get_servers_iplist()
        for id in online_iplist.keys():
            for ip in online_iplist[id]:
                cur = conn.cursor()
                cur.execute("INSERT INTO `alive_ip` (`id`, `nodeid`,`userid`, `ip`, `datetime`) VALUES (NULL, '" + str(
                    get_config().NODE_ID) + "','" + str(self.port_uid_table[id]) + "', '" + str(ip) + "', unix_timestamp())")
                cur.close()

        detect_log_list = ServerPool.get_instance().get_servers_detect_log()
        for port in detect_log_list.keys():
            for rule_id in detect_log_list[port]:
                cur = conn.cursor()
                cur.execute("INSERT INTO `detect_log` (`id`, `user_id`, `list_id`, `datetime`, `node_id`) VALUES (NULL, '" + str(
                    self.port_uid_table[port]) + "', '" + str(rule_id) + "', UNIX_TIMESTAMP(), '" + str(get_config().NODE_ID) + "')")
                cur.close()

        deny_str = ""
        if platform.system() == 'Linux' and get_config().ANTISSATTACK == 1:
            wrong_iplist = ServerPool.get_instance().get_servers_wrong()
            server_ip = socket.gethostbyname(get_config().MYSQL_HOST)
            for id in wrong_iplist.keys():
                for ip in wrong_iplist[id]:
                    realip = ""
                    is_ipv6 = False
                    if common.is_ip(ip):
                        if(common.is_ip(ip) == socket.AF_INET):
                            realip = ip
                        else:
                            if common.match_ipv4_address(ip) is not None:
                                realip = common.match_ipv4_address(ip)
                            else:
                                is_ipv6 = True
                                realip = ip
                    else:
                        continue

                    if str(realip).find(str(server_ip)) != -1:
                        continue

                    has_match_node = False
                    for node_ip in self.node_ip_list:
                        if str(realip).find(node_ip) != -1:
                            has_match_node = True
                            continue

                    if has_match_node:
                        continue

                    cur = conn.cursor()
                    cur.execute(
                        "SELECT * FROM `blockip` where `ip` = '" +
                        str(realip) +
                        "'")
                    rows = cur.fetchone()
                    cur.close()

                    if rows is not None:
                        continue
                    if get_config().CLOUDSAFE == 1:
                        cur = conn.cursor()
                        cur.execute(
                            "INSERT INTO `blockip` (`id`, `nodeid`, `ip`, `datetime`) VALUES (NULL, '" +
                            str(
                                get_config().NODE_ID) +
                            "', '" +
                            str(realip) +
                            "', unix_timestamp())")
                        cur.close()
                    else:
                        if not is_ipv6:
                            os.system('route add -host %s gw 127.0.0.1' %
                                      str(realip))
                            deny_str = deny_str + "\nALL: " + str(realip)
                        else:
                            os.system(
                                'ip -6 route add ::1/128 via %s/128' %
                                str(realip))
                            deny_str = deny_str + \
                                "\nALL: [" + str(realip) + "]/128"

                        logging.info("Local Block ip:" + str(realip))
                if get_config().CLOUDSAFE == 0:
                    deny_file = open('/etc/hosts.deny', 'a')
                    fcntl.flock(deny_file.fileno(), fcntl.LOCK_EX)
                    deny_file.write(deny_str + "\n")
                    deny_file.close()
        conn.close()
        return update_transfer
    def push_db_all_user(self):
        #更新用户流量到数据库
        last_transfer = self.last_get_transfer
        curr_transfer = ServerPool.get_instance().get_servers_transfer()
        #上次和本次的增量
        dt_transfer = {}
        for id in curr_transfer.keys():
            if id in last_transfer:
                if last_transfer[id][0] == curr_transfer[id][0] and last_transfer[id][1] == curr_transfer[id][1]:
                    continue
                elif curr_transfer[id][0] == 0 and curr_transfer[id][1] == 0:
                    continue
                elif last_transfer[id][0] <= curr_transfer[id][0] and \
                last_transfer[id][1] <= curr_transfer[id][1]:
                    dt_transfer[id] = [curr_transfer[id][0] - last_transfer[id][0],
                                       curr_transfer[id][1] - last_transfer[id][1]]
                else:
                    dt_transfer[id] = [curr_transfer[id][0], curr_transfer[id][1]]
            else:
                if curr_transfer[id][0] == 0 and curr_transfer[id][1] == 0:
                    continue
                dt_transfer[id] = [curr_transfer[id][0], curr_transfer[id][1]]

        self.last_get_transfer = curr_transfer
        query_head = 'UPDATE user'
        query_sub_when = ''
        query_sub_when2 = ''
        query_sub_when3 = ''
        query_sub_when4 = ''
        query_sub_when5 = ''
        query_sub_when6 = ''
        query_sub_in = None
        last_time = time.time()
        for id in dt_transfer.keys():
            query_sub_when += ' WHEN %s THEN u+%s' % (id, dt_transfer[id][0])
            query_sub_when2 += ' WHEN %s THEN d+%s' % (id, dt_transfer[id][1])
            query_sub_when3 += ' WHEN %s THEN month_u+%s' % (id, dt_transfer[id][0])
            query_sub_when4 += ' WHEN %s THEN month_d+%s' % (id, dt_transfer[id][1])
            query_sub_when5 += ' WHEN %s THEN sign_u+%s' % (id, dt_transfer[id][0])
            query_sub_when6 += ' WHEN %s THEN sign_d+%s' % (id, dt_transfer[id][1])
            if query_sub_in is not None:
                query_sub_in += ',%s' % id
            else:
                query_sub_in = '%s' % id
        if query_sub_when == '' and query_sub_when3 == '' and query_sub_when5== '':
            return
        query_sql = query_head + ' SET u = CASE port' + query_sub_when + \
                    ' END, d = CASE port' + query_sub_when2 + \
                    ' END, t = ' + str(int(last_time)) + \
                    ',last_login_server_id = ' +str(int(Config.SERVER_ID)) + \
                    ' WHERE service_type in (0,3) and port IN (%s)' % query_sub_in
        query_sql2 = query_head + ' SET month_u = CASE port' + query_sub_when3 + \
                    ' END, month_d = CASE port' + query_sub_when4 + \
                    ' END, t = ' + str(int(last_time)) + \
                    ',last_login_server_id = ' +str(int(Config.SERVER_ID)) + \
                    ' WHERE service_type in (1,2) and port IN (%s)' % query_sub_in       
        query_sql3 = query_head + ' SET sign_u = CASE port' + query_sub_when5 + \
                    ' END, sign_d = CASE port' + query_sub_when6 + \
                    ' END, t = ' + str(int(last_time)) + \
                    ',last_login_server_id = ' +str(int(Config.SERVER_ID)) + \
                    ' WHERE service_type = 0 and port IN (%s)' % query_sub_in          
        #print query_sql
        conn = cymysql.connect(host=Config.MYSQL_HOST, port=Config.MYSQL_PORT, user=Config.MYSQL_USER,
                               passwd=Config.MYSQL_PASS, db=Config.MYSQL_DB, charset='utf8')
        cur = conn.cursor()
        cur.execute(query_sql)
        cur.execute(query_sql2)
        if Config.SERVER_TYPE=='SIGN' :
            cur.execute(query_sql3)
        cur.close()
        conn.commit()
        conn.close()
Beispiel #39
0
    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'] != 0:
                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

        self.mu_port_list = []

        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()
                self.mu_port_list.append(port)

            cfg['detect_hex_list'] = self.detect_hex_list.copy()
            cfg['detect_text_list'] = self.detect_text_list.copy()

            cfg['ip_md5_salt'] = get_config().IP_MD5_SALT

            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':
                            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 self.detect_text_ischanged or self.detect_hex_ischanged:
                    cfgchange = True

                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':
                                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 del_server_out_of_bound_safe(rows):
     #停止超流量的服务
     #启动没超流量的服务
     #修改下面的逻辑要小心包含跨线程访问
     for row in rows:
         ##[port=0, u=1, d=2, transfer_enable=3, sspassword=4, switch=5, enable=6,type=7,overdue=8]
         ##端口,使用流量1,使用流量2,总流量3,端口密码4,是否打开5,是否可用6,套餐性质A.B7,过期时间8
         if ServerPool.get_instance().server_is_run(row[0]) is True:
             if row[5] == 0 or row[6] == 0:
                 #stop disable or switch off user
                 logging.info(
                     'db stop server at port [%s] reason: disable' %
                     (row[0]))
                 ServerPool.get_instance().del_server(row[0])
             elif row[7] == 'A' and row[1] + row[2] >= row[3]:
                 #stop out bandwidth user
                 logging.info(
                     'db stop server at port [%s] reason: out bandwidth' %
                     (row[0]))
                 ServerPool.get_instance().del_server(row[0])
                 DbTransfer.get_instance().changeStatus(-1, row[0])
             elif row[7] == 'B' and time.time() >= row[8]:
                 #stop overdue user
                 logging.info(
                     'db stop server at port [%s] reason: be overdue' %
                     (row[0]))
                 ServerPool.get_instance().del_server(row[0])
                 DbTransfer.get_instance().changeStatus(-2, row[0])
             if ServerPool.get_instance().tcp_servers_pool[
                     row[0]]._config['password'] != row[4]:
                 #password changed
                 logging.info(
                     'db stop server at port [%s] reason: password changed'
                     % (row[0]))
                 ServerPool.get_instance().del_server(row[0])
         else:
             if row[5] == 1 and row[6] == 1 and row[
                     7] == 'A' and row[1] + row[2] < row[3]:
                 logging.info('db start server at port [%s] pass [%s]' %
                              (row[0], row[4]))
                 ServerPool.get_instance().new_server(row[0], row[4])
             elif row[5] == 1 and row[6] == 1 and row[
                     7] == 'B' and time.time() < row[8]:
                 logging.info('db start server at port [%s] pass [%s]' %
                              (row[0], row[4]))
                 ServerPool.get_instance().new_server(row[0], row[4])
Beispiel #41
0
    def del_server(self, port, reason):
        logging.info(
            'db stop server at port [%s] reason: %s!' % (port, reason))
        ServerPool.get_instance().cb_del_server(port)
        if port in self.last_update_transfer:
            del self.last_update_transfer[port]

        for mu_user_port in self.mu_port_list:
            if mu_user_port in ServerPool.get_instance().tcp_servers_pool:
                ServerPool.get_instance().tcp_servers_pool[
                    mu_user_port].reset_single_multi_user_traffic(self.port_uid_table[port])
            if mu_user_port in ServerPool.get_instance().tcp_ipv6_servers_pool:
                ServerPool.get_instance().tcp_ipv6_servers_pool[
                    mu_user_port].reset_single_multi_user_traffic(self.port_uid_table[port])
            if mu_user_port in ServerPool.get_instance().udp_servers_pool:
                ServerPool.get_instance().udp_servers_pool[
                    mu_user_port].reset_single_multi_user_traffic(self.port_uid_table[port])
            if mu_user_port in ServerPool.get_instance().udp_ipv6_servers_pool:
                ServerPool.get_instance().udp_ipv6_servers_pool[
                    mu_user_port].reset_single_multi_user_traffic(self.port_uid_table[port])
Beispiel #42
0
	def del_server_out_of_bound_safe(self, last_rows, rows):
		cur_servers = {} #记录每次读取配置的所有有效端口服务,port=>passwd
		new_servers = {} #记录每次读取配置后需要新启动的端口,port=>(passwd,cfg)
		config = shell.get_config(False)
		for row in rows:
			#超流判断
			allow = row['u'] + row['d'] < row['quota']
			port = row['port']
			#转换密码编码为utf-8编码
			passwd = common.to_bytes(row['passwd'])
			if hasattr(passwd, 'encode'):
				passwd = passwd.encode('utf-8')
			cfg = {'password': passwd}
			#把端口参数存入cfg
			read_config_keys = ['method', 'obfs', 'obfs_param', 'protocol', 'protocol_param', '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
			#转换端口参数值为utf-8编码
			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('端口冲突: [%s]' %(port))
				continue
			#如果当前端口允许运行
			if allow:
				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
			#停止需要重启的端口服务,并把端口参数放入new_servers
			if ServerPool.get_instance().server_is_run(port) > 0:
				if cfgchange:
					self.force_update_transfer[port] = ServerPool.get_instance().get_server_transfer(port)
					ServerPool.get_instance().cb_del_server(port)
					new_servers[port] = (passwd, cfg)
			#新增的端口服务放入new_server
			elif 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'] not in cur_servers:
				self.force_update_transfer[row['port']] = ServerPool.get_instance().get_server_transfer(row['port'])
				ServerPool.get_instance().cb_del_server(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)
Beispiel #43
0
    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
Beispiel #44
0
	def del_servers():
		for port in [v for v in ServerPool.get_instance().tcp_servers_pool.keys()]:
			if ServerPool.get_instance().server_is_run(port) > 0:
				ServerPool.get_instance().cb_del_server(port)
    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"] = 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)
Beispiel #46
0
	def del_server_out_of_bound_safe(last_rows, rows):
		#停止超流量的服务
		#启动没超流量的服务
		#需要动态载入switchrule,以便实时修改规则
		try:
			import switchrule
			reload(switchrule)
		except Exception as e:
			logging.error('load switchrule.py fail')
		cur_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 = row['passwd']
			cur_servers[port] = passwd

			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)
				elif (port in ServerPool.get_instance().tcp_servers_pool and ServerPool.get_instance().tcp_servers_pool[port]._config['password'] != passwd) \
					or (port in ServerPool.get_instance().tcp_ipv6_servers_pool and ServerPool.get_instance().tcp_ipv6_servers_pool[port]._config['password'] != passwd):
					#password changed
					logging.info('db stop server at port [%s] reason: password changed' % (port,))
					ServerPool.get_instance().cb_del_server(port)
					ServerPool.get_instance().new_server(port, passwd)

			elif allow and ServerPool.get_instance().server_run_status(port) is False:
				logging.info('db start server at port [%s] pass [%s]' % (port, passwd))
				ServerPool.get_instance().new_server(port, passwd)

		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'])
Beispiel #47
0
	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)
				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)
						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'])
				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)
Beispiel #48
0
		try:
			import switchrule
		except Exception, e:
			logging.error('load switchrule.py fail')
		cur_servers = {}
		for row in rows:
			try:
				allow = switchrule.isTurnOn(row) and row['enable'] == 1 and row['u'] + row['d'] < row['transfer_enable']
			except Exception, e:
				allow = False

			port = row['port']
			passwd = row['passwd']
			cur_servers[port] = passwd

			if ServerPool.get_instance().server_is_run(port) > 0:
				if not allow:
					logging.info('db stop server at port [%s]' % (port,))
					ServerPool.get_instance().del_server(port)
				elif (port in ServerPool.get_instance().tcp_servers_pool and ServerPool.get_instance().tcp_servers_pool[port]._config['password'] != passwd) \
					or (port in ServerPool.get_instance().tcp_ipv6_servers_pool and ServerPool.get_instance().tcp_ipv6_servers_pool[port]._config['password'] != passwd):
					#password changed
					logging.info('db stop server at port [%s] reason: password changed' % (port,))
					ServerPool.get_instance().del_server(port)

			elif allow and ServerPool.get_instance().server_run_status(port) is False:
				logging.info('db start server at port [%s] pass [%s]' % (port, passwd))
				ServerPool.get_instance().new_server(port, passwd)

		for row in last_rows:
			if row['port'] in cur_servers:
Beispiel #49
0
    def update_all_user(self, dt_transfer):
        global webapi

        update_transfer = {}

        alive_user_count = 0
        bandwidth_thistime = 0

        data = []
        for id in dt_transfer.keys():
            if dt_transfer[id][0] == 0 and dt_transfer[id][1] == 0:
                continue
            data.append({
                'u': dt_transfer[id][0],
                'd': dt_transfer[id][1],
                'user_id': self.port_uid_table[id]
            })
            update_transfer[id] = dt_transfer[id]
        webapi.postApi('users/traffic', {'node_id': get_config().NODE_ID},
                       {'data': data})

        webapi.postApi('nodes/%d/info' % (get_config().NODE_ID),
                       {'node_id': get_config().NODE_ID}, {
                           'uptime': str(self.uptime()),
                           'load': str(self.load())
                       })

        online_iplist = ServerPool.get_instance().get_servers_iplist()
        data = []
        for port in online_iplist.keys():
            for ip in online_iplist[port]:
                data.append({'ip': ip, 'user_id': self.port_uid_table[port]})
        webapi.postApi('users/aliveip', {'node_id': get_config().NODE_ID},
                       {'data': data})

        detect_log_list = ServerPool.get_instance().get_servers_detect_log()
        data = []
        for port in detect_log_list.keys():
            for rule_id in detect_log_list[port]:
                data.append({
                    'list_id': rule_id,
                    'user_id': self.port_uid_table[port]
                })
        webapi.postApi('users/detectlog', {'node_id': get_config().NODE_ID},
                       {'data': data})

        deny_str = ""
        data = []
        if platform.system() == 'Linux' and get_config().ANTISSATTACK == 1:
            wrong_iplist = ServerPool.get_instance().get_servers_wrong()
            server_ip = socket.gethostbyname(get_config().MYSQL_HOST)
            for id in wrong_iplist.keys():
                for ip in wrong_iplist[id]:
                    realip = ""
                    is_ipv6 = False
                    if common.is_ip(ip):
                        if (common.is_ip(ip) == socket.AF_INET):
                            realip = ip
                        else:
                            if common.match_ipv4_address(ip) is not None:
                                realip = common.match_ipv4_address(ip)
                            else:
                                is_ipv6 = True
                                realip = ip
                    else:
                        continue

                    if str(realip).find(str(server_ip)) != -1:
                        continue

                    has_match_node = False
                    for node_ip in self.node_ip_list:
                        if str(realip).find(node_ip) != -1:
                            has_match_node = True
                            continue

                    if has_match_node:
                        continue

                    if get_config().CLOUDSAFE == 1:
                        data.append({'ip': realip})
                    else:
                        if not is_ipv6:
                            os.system('route add -host %s gw 127.0.0.1' %
                                      str(realip))
                            deny_str = deny_str + "\nALL: " + str(realip)
                        else:
                            os.system('ip -6 route add ::1/128 via %s/128' %
                                      str(realip))
                            deny_str = deny_str + \
                                "\nALL: [" + str(realip) + "]/128"

                        logging.info("Local Block ip:" + str(realip))
                if get_config().CLOUDSAFE == 0:
                    deny_file = open('/etc/hosts.deny', 'a')
                    fcntl.flock(deny_file.fileno(), fcntl.LOCK_EX)
                    deny_file.write(deny_str)
                    deny_file.close()
            webapi.postApi('func/block_ip', {'node_id': get_config().NODE_ID},
                           {'data': data})
        return update_transfer