Ejemplo n.º 1
0
 def _parse_resolv(self):
     self.logger = logging.getLogger(__name__)
     if get_config().debug:
         self.logger.setLevel(logging.DEBUG)
     fh = logging.FileHandler('log.txt',
                              mode='a',
                              encoding=None,
                              delay=False)
     formater = logging.Formatter(
         '%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s'
     )
     fh.setFormatter(formater)
     self.logger.addHandler(fh)
     self._servers = []
     try:
         with open('dns.conf', 'rb') as f:
             content = f.readlines()
             for line in content:
                 line = line.strip()
                 if line:
                     parts = line.split(b' ', 1)
                     if len(parts) >= 2:
                         server = parts[0]
                         port = int(parts[1])
                     else:
                         server = parts[0]
                         port = 53
                     if common.is_ip(server) == socket.AF_INET:
                         if type(server) != str:
                             server = server.decode('utf8')
                         self._servers.append((server, port))
     except IOError:
         pass
     if not self._servers:
         try:
             with open('/etc/resolv.conf', 'rb') as f:
                 content = f.readlines()
                 for line in content:
                     line = line.strip()
                     if line:
                         if line.startswith(b'nameserver'):
                             parts = line.split()
                             if len(parts) >= 2:
                                 server = parts[1]
                                 if common.is_ip(server) == socket.AF_INET:
                                     if type(server) != str:
                                         server = server.decode('utf8')
                                     self._servers.append((server, 53))
         except IOError:
             pass
     if not self._servers:
         self._servers = [('8.8.4.4', 53), ('8.8.8.8', 53)]
     self.logger.info('dns server: %s' % (self._servers, ))
Ejemplo n.º 2
0
	def resolve(self, hostname, callback):
		if type(hostname) != bytes:
			hostname = hostname.encode('utf8')
		if not hostname:
			callback(None, Exception('empty hostname'))
		elif common.is_ip(hostname):
			callback((hostname, hostname), None)
		elif hostname in self._hosts:
			logging.debug('hit hosts: %s', hostname)
			ip = self._hosts[hostname]
			callback((hostname, ip), None)
		elif hostname in self._cache:
			logging.debug('hit cache: %s', hostname)
			ip = self._cache[hostname]
			callback((hostname, ip), None)
		else:
			if not is_valid_hostname(hostname):
				callback(None, Exception('invalid hostname: %s' % hostname))
				return
			arr = self._hostname_to_cb.get(hostname, None)
			if not arr:
				self._hostname_status[hostname] = STATUS_IPV4
				self._send_req(hostname, QTYPE_A)
				self._hostname_to_cb[hostname] = [callback]
				self._cb_to_hostname[callback] = hostname
			else:
				arr.append(callback)
				# TODO send again only if waited too long
				self._send_req(hostname, QTYPE_A)
Ejemplo n.º 3
0
    def _parse_resolv(self):
        """
        该方法主要是解析/etc/resolv.conf文件,得到dns服务器的ip地址,如果没有配置,则默认使用google的dns服务器。

        :return: None。
        """
        self._servers = []
        try:
            with open('/etc/resolv.conf', 'rb') as f:
                content = f.readlines()
                for line in content:
                    line = line.strip()
                    if line:
                        if line.startswith(b'nameserver'):
                            parts = line.split()
                            if len(parts) >= 2:
                                server = parts[1]
                                if common.is_ip(server) == socket.AF_INET:
                                    if type(server) != str:
                                        server = server.decode('utf8')
                                    self._servers.append(server)
        except IOError:
            pass
        if not self._servers:
            self._servers = ['8.8.4.4', '8.8.8.8']
Ejemplo n.º 4
0
 def resolve(self, hostname, callback):
     if type(hostname) != bytes:
         hostname = hostname.encode('utf8')
     if not hostname:
         callback(None, Exception('empty hostname'))
     elif common.is_ip(hostname):
         callback((hostname, hostname), None)
     elif hostname in self._hosts:
         logging.debug('hit hosts: %s', hostname)
         ip = self._hosts[hostname]
         callback((hostname, ip), None)
     elif hostname in self._cache:
         logging.debug('hit cache: %s', hostname)
         ip = self._cache[hostname]
         callback((hostname, ip), None)
     else:
         if not is_valid_hostname(hostname):
             callback(None, Exception('invalid hostname: %s' % hostname))
             return
         arr = self._hostname_to_cb.get(hostname, None)
         if not arr:
             self._hostname_status[hostname] = STATUS_IPV4
             self._send_req(hostname, QTYPE_A)
             self._hostname_to_cb[hostname] = [callback]
             self._cb_to_hostname[callback] = hostname
         else:
             arr.append(callback)
             # TODO send again only if waited too long
             self._send_req(hostname, QTYPE_A)
Ejemplo n.º 5
0
    def _parse_resolv(self):
        self._servers = []
        try:
            with open('/etc/resolv.conf', 'rb') as f:
                content = f.readlines()
                for line in content:
                    # strip() returns a copy of the string with leading whitespace removed.
                    line = line.strip()
                    if not (line and line.startswith(b'nameserver')):
                        continue

                    parts = line.split()
                    if len(parts) < 2:
                        continue

                    server = parts[1]
                    if common.is_ip(server) == socket.AF_INET:
                        if type(server) != str:
                            server = server.decode('utf8')
                        self._servers.append(server)
        except IOError:
            pass
        if not self._servers:
            # 系统没有指定dns,就用谷歌的
            self._servers = ['8.8.4.4', '8.8.8.8']
Ejemplo n.º 6
0
    def _handle_server(self):
        server = self._server_socket
        data, r_addr = server.recvfrom(BUF_SIZE)
        ogn_data = data
        if not data:
            logging.debug('UDP handle_server: data is empty')
        if self._stat_callback:
            self._stat_callback(self._listen_port, len(data))
        uid = None
        if self._is_local:
            frag = common.ord(data[2])
            if frag != 0:
                logging.warn('drop a message since frag is not 0')
                return
            else:
                data = data[3:]
        else:
            ref_iv = [0]
            data = encrypt.encrypt_all_iv(self._protocol.obfs.server_info.key, self._method, 0, data, ref_iv)
            # decrypt data
            if not data:
                logging.debug('UDP handle_server: data is empty after decrypt')
                return
            self._protocol.obfs.server_info.recv_iv = ref_iv[0]
            data, uid = self._protocol.server_udp_post_decrypt(data)

        #logging.info("UDP data %s" % (binascii.hexlify(data),))
        if not self._is_local:
            data = pre_parse_header(data)
            if data is None:
                return

        try:
            header_result = parse_header(data)
        except:
            self._handel_protocol_error(r_addr, ogn_data)
            return

        if header_result is None:
            self._handel_protocol_error(r_addr, ogn_data)
            return
        connecttype, addrtype, dest_addr, dest_port, header_length = header_result

        if self._is_local:
            addrtype = 3
            server_addr, server_port = self._get_a_server()
        else:
            server_addr, server_port = dest_addr, dest_port

        if (addrtype & 7) == 3:
            af = common.is_ip(server_addr)
            if af == False:
                handler = common.UDPAsyncDNSHandler((data, r_addr, uid, header_length))
                handler.resolve(self._dns_resolver, (server_addr, server_port), self._handle_server_dns_resolved)
            else:
                self._handle_server_dns_resolved("", (server_addr, server_port), server_addr, (data, r_addr, uid, header_length))
        else:
            self._handle_server_dns_resolved("", (server_addr, server_port), server_addr, (data, r_addr, uid, header_length))
Ejemplo n.º 7
0
    def _handle_server(self):
        server = self._server_socket
        data, r_addr = server.recvfrom(BUF_SIZE)
        ogn_data = data
        if not data:
            logging.debug('UDP handle_server: data is empty')
        if self._stat_callback:
            self._stat_callback(self._listen_port, len(data))
        uid = None
        if self._is_local:
            frag = common.ord(data[2])
            if frag != 0:
                logging.warn('drop a message since frag is not 0')
                return
            else:
                data = data[3:]
        else:
            ref_iv = [0]
            data = encrypt.encrypt_all_iv(self._protocol.obfs.server_info.key, self._method, 0, data, ref_iv)
            # decrypt data
            if not data:
                logging.debug('UDP handle_server: data is empty after decrypt')
                return
            self._protocol.obfs.server_info.recv_iv = ref_iv[0]
            data, uid = self._protocol.server_udp_post_decrypt(data)

        #logging.info("UDP data %s" % (binascii.hexlify(data),))
        if not self._is_local:
            data = pre_parse_header(data)
            if data is None:
                return

        try:
            header_result = parse_header(data)
        except:
            self._handel_protocol_error(r_addr, ogn_data)
            return

        if header_result is None:
            self._handel_protocol_error(r_addr, ogn_data)
            return
        connecttype, addrtype, dest_addr, dest_port, header_length = header_result

        if self._is_local:
            addrtype = 3
            server_addr, server_port = self._get_a_server()
        else:
            server_addr, server_port = dest_addr, dest_port

        if (addrtype & 7) == 3:
            af = common.is_ip(server_addr)
            if af == False:
                handler = common.UDPAsyncDNSHandler((data, r_addr, uid, header_length))
                handler.resolve(self._dns_resolver, (server_addr, server_port), self._handle_server_dns_resolved)
            else:
                self._handle_server_dns_resolved("", (server_addr, server_port), server_addr, (data, r_addr, uid, header_length))
        else:
            self._handle_server_dns_resolved("", (server_addr, server_port), server_addr, (data, r_addr, uid, header_length))
Ejemplo n.º 8
0
 def _parse_resolv(self):
     """
     干什么?打开dns.conf文件吗?
     :return: None
     """
     self._servers = []
     try:
         with open('dns.conf', 'rb') as f:
             content = f.readlines()
             for line in content:
                 line = line.strip()
                 if line:
                     parts = line.split(b' ', 1)
                     if len(parts) >= 2:
                         server = parts[0]
                         port = int(parts[1])
                     else:
                         server = parts[0]
                         port = 53
                     if common.is_ip(server) == socket.AF_INET:
                         if type(server) != str:
                             server = server.decode('utf8')
                         self._servers.append((server, port))
     except IOError:
         pass
     if not self._servers:
         try:
             with open('/etc/resolv.conf', 'rb') as f:
                 content = f.readlines()
                 for line in content:
                     line = line.strip()
                     if line:
                         if line.startswith(b'nameserver'):
                             parts = line.split()
                             if len(parts) >= 2:
                                 server = parts[1]
                                 if common.is_ip(server) == socket.AF_INET:
                                     if type(server) != str:
                                         server = server.decode('utf8')
                                     self._servers.append((server, 53))
         except IOError:
             pass
     if not self._servers:
         self._servers = [('8.8.4.4', 53), ('8.8.8.8', 53)]
     logging.info('dns server: %s' % (self._servers,))
Ejemplo n.º 9
0
 def _parse_resolv(self):
     self._servers = []
     try:
         with open('dns.conf', 'rb') as f:
             content = f.readlines()
             for line in content:
                 line = line.strip()
                 if line:
                     parts = line.split(b' ', 1)
                     if len(parts) >= 2:
                         server = parts[0]
                         port = int(parts[1])
                     else:
                         server = parts[0]
                         port = 53
                     if common.is_ip(server) == socket.AF_INET:
                         if type(server) != str:
                             server = server.decode('utf8')
                         self._servers.append((server, port))
     except IOError:
         pass
     if not self._servers:
         try:
             with open('/etc/resolv.conf', 'rb') as f:
                 content = f.readlines()
                 for line in content:
                     line = line.strip()
                     if line:
                         if line.startswith(b'nameserver'):
                             parts = line.split()
                             if len(parts) >= 2:
                                 server = parts[1]
                                 if common.is_ip(server) == socket.AF_INET:
                                     if type(server) != str:
                                         server = server.decode('utf8')
                                     self._servers.append((server, 53))
         except IOError:
             pass
     if not self._servers:
         self._servers = [('8.8.4.4', 53), ('8.8.8.8', 53)]
     logging.info('dns server: %s' % (self._servers,))
Ejemplo n.º 10
0
 def resolve(self, hostname, callback):
     if type(hostname) != bytes:
         hostname = hostname.encode('utf8')
     if not hostname:
         callback(None, Exception('empty hostname'))
     elif common.is_ip(hostname):
         callback((hostname, hostname), None)
     elif hostname in self._hosts:
         logging.debug('hit hosts: %s', hostname)
         ip = self._hosts[hostname]
         callback((hostname, ip), None)
     elif hostname in self._cache:
         logging.debug('hit cache: %s ==>> %s', hostname,
                       self._cache[hostname])
         ip = self._cache[hostname]
         callback((hostname, ip), None)
     elif any(hostname.endswith(t) for t in self._black_hostname_list):
         callback(
             None,
             Exception('hostname <%s> is block by the black hostname list' %
                       hostname))
         return
     else:
         if not is_valid_hostname(hostname):
             callback(None, Exception('invalid hostname: %s' % hostname))
             return
         if False:
             addrs = socket.getaddrinfo(hostname, 0, 0, socket.SOCK_DGRAM,
                                        socket.SOL_UDP)
             if addrs:
                 af, socktype, proto, canonname, sa = addrs[0]
                 logging.debug('DNS resolve %s %s' % (hostname, sa[0]))
                 self._cache[hostname] = sa[0]
                 callback((hostname, sa[0]), None)
                 return
         arr = self._hostname_to_cb.get(hostname, None)
         if not arr:
             if IPV6_CONNECTION_SUPPORT:
                 self._hostname_status[hostname] = STATUS_IPV6
                 self._send_req(hostname, QTYPE_AAAA)
             else:
                 self._hostname_status[hostname] = STATUS_IPV4
                 self._send_req(hostname, QTYPE_A)
             self._hostname_to_cb[hostname] = [callback]
             self._cb_to_hostname[callback] = hostname
         else:
             arr.append(callback)
             # TODO send again only if waited too long
             if IPV6_CONNECTION_SUPPORT:
                 self._send_req(hostname, QTYPE_AAAA)
             else:
                 self._send_req(hostname, QTYPE_A)
Ejemplo n.º 11
0
 def resolve(self, hostname, callback):
     """
     域名解析函数
     :param hostname:    待解析的hostname
     :param callback:    解析完成之后执行的回调函数,参数为(result, error)
                         result: (hostname, ip)
                         error: exception
     :return:
     """
     # 不是以字符串形式则转化成字符串
     if type(hostname) != bytes:
         hostname = hostname.encode('utf8')
     # 若hostname为空,抛出异常
     if not hostname:
         callback(None, Exception('empty hostname'))
     # 若hostname为ip,直接使用
     elif common.is_ip(hostname):
         callback((hostname, hostname), None)
     # 若hostname在host文件中,直接调用回调函数
     elif hostname in self._hosts:
         logging.debug('hit hosts: %s', hostname)
         ip = self._hosts[hostname]
         callback((hostname, ip), None)
     # 若hostname在缓存中,直接调用回调函数
     elif hostname in self._cache:
         logging.debug('hit cache: %s', hostname)
         ip = self._cache[hostname]
         callback((hostname, ip), None)
     # 都不满足,需要解析
     else:
         # 域名不合法
         if not is_valid_hostname(hostname):
             callback(None, Exception('invalid hostname: %s' % hostname))
             return
         # 获得解析该hostname对应的回调函数列表
         arr = self._hostname_to_cb.get(hostname, None)
         if not arr:
             # 发出请求报文,同时记录该域名的一些相关信息
             self._hostname_status[hostname] = STATUS_IPV4
             self._send_req(hostname, QTYPE_A)
             # 同时在_hostname_to_cb注册一个{hostname:[callback]}的一对
             # 要hostname因为这个socket可以发出去很多不同hostname的解析请求
             self._hostname_to_cb[hostname] = [callback]
             self._cb_to_hostname[callback] = hostname
         else:
             arr.append(callback)
             # TODO send again only if waited too long
             self._send_req(hostname, QTYPE_A)
Ejemplo n.º 12
0
 def resolve(self, hostname, callback):
     if type(hostname) != bytes:
         hostname = hostname.encode('utf8')
     if not hostname:
         callback(None, Exception('empty hostname'))
     elif common.is_ip(hostname):
         callback((hostname, hostname), None)
     elif hostname in self._hosts:
         logging.debug('hit hosts: %s', hostname)
         ip = self._hosts[hostname]
         callback((hostname, ip), None)
     elif hostname in self._cache:
         logging.debug('hit cache: %s ==>> %s', hostname, self._cache[hostname])
         ip = self._cache[hostname]
         callback((hostname, ip), None)
     elif any(hostname.endswith(t) for t in self._black_hostname_list):
         callback(None, Exception('hostname <%s> is block by the black hostname list' % hostname))
         return
     else:
         if not is_valid_hostname(hostname):
             callback(None, Exception('invalid hostname: %s' % hostname))
             return
         if False:
             addrs = socket.getaddrinfo(hostname, 0, 0,
                                        socket.SOCK_DGRAM, socket.SOL_UDP)
             if addrs:
                 af, socktype, proto, canonname, sa = addrs[0]
                 logging.debug('DNS resolve %s %s' % (hostname, sa[0]))
                 self._cache[hostname] = sa[0]
                 callback((hostname, sa[0]), None)
                 return
         arr = self._hostname_to_cb.get(hostname, None)
         if not arr:
             if IPV6_CONNECTION_SUPPORT:
                 self._hostname_status[hostname] = STATUS_IPV6
                 self._send_req(hostname, QTYPE_AAAA)
             else:
                 self._hostname_status[hostname] = STATUS_IPV4
                 self._send_req(hostname, QTYPE_A)
             self._hostname_to_cb[hostname] = [callback]
             self._cb_to_hostname[callback] = hostname
         else:
             arr.append(callback)
             # TODO send again only if waited too long
             if IPV6_CONNECTION_SUPPORT:
                 self._send_req(hostname, QTYPE_AAAA)
             else:
                 self._send_req(hostname, QTYPE_A)
Ejemplo n.º 13
0
    def resolve(self, hostname, callback):
        if type(hostname) != bytes:
            hostname = hostname.encode('utf8')

        # if hostname is None
        if not hostname:
            callback(None, Exception('empty hostname'))

        # or hostname is already a ip
        elif common.is_ip(hostname):
            callback((hostname, hostname), None)

        # or hostname is in hosts file
        elif hostname in self._hosts:
            logging.debug('hit hosts: %s', hostname)
            ip = self._hosts[hostname]
            callback((hostname, ip), None)

        # or hostname is in cache
        elif hostname in self._cache:
            logging.debug('hit cache: %s', hostname)
            ip = self._cache[hostname]
            callback((hostname, ip), None)

        # otherwise, resolve hostname
        else:
            # if hostname is invalid
            if not is_valid_hostname(hostname):
                callback(None, Exception('invalid hostname: %s' % hostname))
                return

            # arr is a list of callbacks
            arr = self._hostname_to_cb.get(hostname, None)

            # if hostname is not linked with any callbacks
            # set default status, send request and link hostname with callback
            if not arr:
                self._hostname_status[hostname] = STATUS_IPV4
                self._send_req(hostname, QTYPE_A)
                self._hostname_to_cb[hostname] = [callback]
                self._cb_to_hostname[callback] = hostname
            # or just end request
            else:
                arr.append(callback)  # meaningless
                # TODO send again only if waited too long
                self._send_req(hostname, QTYPE_A)
Ejemplo n.º 14
0
 def _parse_hosts(self):
     etc_path = "/etc/hosts"
     if "WINDIR" in os.environ:
         etc_path = os.environ["WINDIR"] + "/system32/drivers/etc/hosts"
     try:
         with open(etc_path, "rb") as f:
             for line in f.readlines():
                 line = line.strip()
                 parts = line.split()
                 if len(parts) >= 2:
                     ip = parts[0]
                     if common.is_ip(ip):
                         for i in range(1, len(parts)):
                             hostname = parts[i]
                             if hostname:
                                 self._hosts[hostname] = ip
     except IOError:
         self._hosts["localhost"] = "127.0.0.1"
Ejemplo n.º 15
0
 def _parse_hosts(self):
     etc_path = '/etc/hosts'
     if 'WINDIR' in os.environ:
         etc_path = os.environ['WINDIR'] + '/system32/drivers/etc/hosts'
     try:
         with open(etc_path, 'rb') as f:
             for line in f.readlines():
                 line = line.strip()
                 parts = line.split()
                 if len(parts) >= 2:
                     ip = parts[0]
                     if common.is_ip(ip):
                         for i in range(1, len(parts)):
                             hostname = parts[i]
                             if hostname:
                                 self._hosts[hostname] = ip
     except IOError:
         self._hosts['localhost'] = '127.0.0.1'
Ejemplo n.º 16
0
	def _parse_hosts(self):
		etc_path = '/etc/hosts'
		if 'WINDIR' in os.environ:
			etc_path = os.environ['WINDIR'] + '/system32/drivers/etc/hosts'
		try:
			with open(etc_path, 'rb') as f:
				for line in f.readlines():
					line = line.strip()
					parts = line.split()
					if len(parts) >= 2:
						ip = parts[0]
						if common.is_ip(ip):
							for i in range(1, len(parts)):
								hostname = parts[i]
								if hostname:
									self._hosts[hostname] = ip
		except IOError:
			self._hosts['localhost'] = '127.0.0.1'
Ejemplo n.º 17
0
	def _parse_domains(self):
		etc_path = '/etc/domains'
		try:
			with open(etc_path, 'rb') as f:
				for line in f.readlines():
					line = line.strip()
					if b"#" in line:
						line = line[:line.find(b'#')]
					parts = line.split()
					if len(parts) >= 2:
						ip = parts[0]
						if common.is_ip(ip):
							for i in range(1, len(parts)):
								hostname = parts[i]
								if hostname:
									self._domains[hostname] = ip
		except IOError:
			self._domains['localhost'] = '127.0.0.1'
Ejemplo n.º 18
0
 def _parse_resolv(self):
     self._servers = []
     try:
         with open('/etc/resolv.conf', 'rb') as f:
             content = f.readlines()
             for line in content:
                 line = line.strip()
                 if line:
                     if line.startswith(b'nameserver'):
                         parts = line.split()
                         if len(parts) >= 2:
                             server = parts[1]
                             if common.is_ip(server) == socket.AF_INET:
                                 if type(server) != str:
                                     server = server.decode('utf8')
                                 self._servers.append(server)
     except IOError:
         pass
     if not self._servers:
         self._servers = ['8.8.4.4', '8.8.8.8']
Ejemplo n.º 19
0
	def _parse_resolv(self):
		self._servers = []
		try:
			with open('/etc/resolv.conf', 'rb') as f:
				content = f.readlines()
				for line in content:
					line = line.strip()
					if line:
						if line.startswith(b'nameserver'):
							parts = line.split()
							if len(parts) >= 2:
								server = parts[1]
								if common.is_ip(server) == socket.AF_INET:
									if type(server) != str:
										server = server.decode('utf8')
									self._servers.append(server)
		except IOError:
			pass
		if not self._servers:
			self._servers = ['8.8.4.4', '8.8.8.8']
Ejemplo n.º 20
0
 def _parse_resolv(self):
     self._servers = []
     try:
         with open("/etc/resolv.conf", "rb") as f:
             content = f.readlines()
             for line in content:
                 line = line.strip()
                 if line:
                     if line.startswith(b"nameserver"):
                         parts = line.split()
                         if len(parts) >= 2:
                             server = parts[1]
                             if common.is_ip(server) == socket.AF_INET:
                                 if type(server) != str:
                                     server = server.decode("utf8")
                                 self._servers.append(server)
     except IOError:
         pass
     if not self._servers:
         self._servers = ["8.8.4.4", "8.8.8.8"]
Ejemplo n.º 21
0
    def resolve(self, hostname, callback):
        """
        解析域名并执行相应的回调函数。

        :param hostname: 一个域名字符串。

        :param callback: 该域名对应的回调函数。回调函数格式为callback((hostname, ip), error=None)。

        :return: None。
        """
        if type(hostname) != bytes:  # string转bytes
            hostname = hostname.encode('utf8')
        if not hostname:  # 域名为空
            callback(None, Exception('empty hostname'))
        elif common.is_ip(hostname):  # 若本身已经是ip地址了
            callback((hostname, hostname), None)
        elif hostname in self._hosts:  # 若系统的hosts文件里面已经存在了映射
            logging.debug('hit hosts: %s', hostname)
            ip = self._hosts[hostname]
            callback((hostname, ip), None)
        elif hostname in self._cache:  # 若缓存里面存有域名解析的结果
            logging.debug('hit cache: %s', hostname)
            ip = self._cache[hostname]
            callback((hostname, ip), None)
        else:
            if not is_valid_hostname(hostname):  # 若域名格式不合法。
                callback(None, Exception('invalid hostname: %s' % hostname))
                return
            arr = self._hostname_to_cb.get(hostname, None)
            if not arr:
                self._hostname_status[hostname] = STATUS_IPV4
                self._send_req(hostname, QTYPE_A)
                self._hostname_to_cb[hostname] = [callback]
                self._cb_to_hostname[callback] = hostname
            else:
                arr.append(callback)
                # TODO send again only if waited too long
                self._send_req(hostname, QTYPE_A)
Ejemplo n.º 22
0
 def resolve(self, hostname, callback):    # 在tcprelay模块中,callback函数指向tcp类的_handle_dns_resolved()
     # hostname是否是字节码
     if type(hostname) != bytes:
         hostname = hostname.encode('utf8')
     if not hostname:
         callback(None, Exception('empty hostname'))
     elif common.is_ip(hostname):
         # 先看是不是一个ip,是就不用解析了,直接调用callback
         callback((hostname, hostname), None)
     elif hostname in self._hosts:
         # 看是不是在host文件里面,是就直接callback
         logging.debug('hit hosts: %s', hostname)
         ip = self._hosts[hostname]
         callback((hostname, ip), None)
     elif hostname in self._cache:
         # 看是不是在cache里面,是就直接callback
         logging.debug('hit cache: %s', hostname)
         ip = self._cache[hostname]
         callback((hostname, ip), None)
     # 以上条件都不满足,开始进行解析dns
     else:
         if not is_valid_hostname(hostname):
             callback(None, Exception('invalid hostname: %s' % hostname))
             return
         arr = self._hostname_to_cb.get(hostname, None)
         # 在host_to_callback中检查是否有记录
         if not arr:
             self._hostname_status[hostname] = STATUS_FIRST
             self._send_req(hostname, self._QTYPES[0])
             # 同时在_hostname_to_cb注册一个{hostname:callback}的一对
             # 要hostname因为这个socket可以发出去很多不同hostname的解析请求
             self._hostname_to_cb[hostname] = [callback]
             self._cb_to_hostname[callback] = hostname
         else:
             arr.append(callback)
             # TODO send again only if waited too long
             self._send_req(hostname, self._QTYPES[0])
Ejemplo n.º 23
0
    def _handle_server(self):
        server = self._server_socket
        data, r_addr = server.recvfrom(BUF_SIZE)
        ogn_data = data
        if not data:
            logging.debug('UDP handle_server: data is empty')
        if self._stat_callback:
            self._stat_callback(self._listen_port, len(data))
        uid = None
        if self._is_local:
            frag = common.ord(data[2])
            if frag != 0:
                logging.warn('drop a message since frag is not 0')
                return
            else:
                data = data[3:]
        else:
            try:
                data, key, ref_iv = encrypt.decrypt_all(self._password,
                                                    self._method,
                                                    data)
            except Exception:
                logging.debug('UDP handle_server: decrypt data failed')
                return

            # decrypt data
            if not data:
                logging.debug('UDP handle_server: data is empty after decrypt')
                return
            ref_iv = [0]
            self._protocol.obfs.server_info.recv_iv = ref_iv[0]
            data, uid = self._protocol.server_udp_post_decrypt(data)

            if self._config['is_multi_user'] != 0 and data:
                if uid:
                    if uid not in self.mu_server_transfer_ul:
                        self.mu_server_transfer_ul[uid] = 0
                    if uid not in self.mu_server_transfer_dl:
                        self.mu_server_transfer_dl[uid] = 0
                    if uid not in self.mu_connected_iplist:
                        self.mu_connected_iplist[uid] = []
                    if uid not in self.mu_detect_log_list:
                        self.mu_detect_log_list[uid] = []

                    if common.getRealIp(r_addr[0]) not in self.mu_connected_iplist[uid]:
                        self.mu_connected_iplist[uid].append(common.getRealIp(r_addr[0]))

                else:
                    raise Exception(
                        'This port is multi user in single port only,so The connection has been rejected, when connect from %s:%d via port %d' %
                        (r_addr[0], r_addr[1], self._listen_port))

        is_relay = False

        #logging.info("UDP data %s" % (binascii.hexlify(data),))
        if not self._is_local:

            if not self._is_relay(r_addr, ogn_data, uid):
                data = pre_parse_header(data)

                data = self._pre_parse_udp_header(data)
                if data is None:
                    return

                if isinstance(data, tuple):
                    return
                    # return self._handle_tcp_over_udp(data, r_addr)
            else:
                if self._config["is_multi_user"] == 0:
                    data, is_relay = self._handel_normal_relay(r_addr, ogn_data)
                else:
                    data, is_relay = self._handel_mu_relay(r_addr, ogn_data, uid)

        try:
            header_result = parse_header(data)
        except:
            self._handel_protocol_error(r_addr, ogn_data)
            return

        if header_result is None:
            self._handel_protocol_error(r_addr, ogn_data)
            return
        connecttype, addrtype, dest_addr, dest_port, header_length = header_result

        if self._is_local:
            addrtype = 3
            server_addr, server_port = self._get_a_server()
        else:
            server_addr, server_port = dest_addr, dest_port

        if (addrtype & 7) == 3:
            af = common.is_ip(server_addr)
            if af == False:
                handler = common.UDPAsyncDNSHandler((data, r_addr, uid, header_length, is_relay))
                handler.resolve(self._dns_resolver, (server_addr, server_port), self._handle_server_dns_resolved)
            else:
                self._handle_server_dns_resolved("", (server_addr, server_port), server_addr, (data, r_addr, uid, header_length, is_relay))
        else:
            self._handle_server_dns_resolved("", (server_addr, server_port), server_addr, (data, r_addr, uid, header_length, is_relay))
Ejemplo n.º 24
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
Ejemplo n.º 25
0
def auto_block_thread():
	if configloader.get_config().CLOUDSAFE == 0 or platform.system() != 'Linux':
		return

	start_line = file_len("/etc/hosts.deny")



	while True:
		time.sleep(60)
		try:
			server_ip = socket.gethostbyname(configloader.get_config().MYSQL_HOST)

			if configloader.get_config().MYSQL_SSL_ENABLE == 1:
				conn = cymysql.connect(host=configloader.get_config().MYSQL_HOST, port=configloader.get_config().MYSQL_PORT, user=configloader.get_config().MYSQL_USER,
											passwd=configloader.get_config().MYSQL_PASS, db=configloader.get_config().MYSQL_DB, charset='utf8',ssl={'ca':configloader.get_config().MYSQL_SSL_CA,'cert':configloader.get_config().MYSQL_SSL_CERT,'key':configloader.get_config().MYSQL_SSL_KEY})
			else:
				conn = cymysql.connect(host=configloader.get_config().MYSQL_HOST, port=configloader.get_config().MYSQL_PORT, user=configloader.get_config().MYSQL_USER,
											passwd=configloader.get_config().MYSQL_PASS, db=configloader.get_config().MYSQL_DB, charset='utf8')
			conn.autocommit(True)


			deny_file = open('/etc/hosts.deny')
			fcntl.flock(deny_file.fileno(),fcntl.LOCK_EX)
			deny_lines = deny_file.readlines()
			deny_file.close()

			logging.info("Read hosts.deny from line " + str(start_line))
			real_deny_list = deny_lines[start_line:]

			denyed_ip_list = []
			for line in real_deny_list:
				if get_ip(line) and line.find('#') != 0:
					ip = get_ip(line)

					if ip == server_ip:
						i = 0

						for line in deny_lines:
							if line.find(ip) != -1:
								del deny_lines[i]
							i = i + 1

						deny_file = file("/etc/hosts.deny", "w+")
						fcntl.flock(deny_file.fileno(),fcntl.LOCK_EX)
						for line in deny_lines:
							deny_file.write(line)
						deny_file.write("\n")
						deny_file.close()

						continue

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

					if rows != None:
						continue

					cur = conn.cursor()
					cur.execute("INSERT INTO `blockip` (`id`, `nodeid`, `ip`, `datetime`) VALUES (NULL, '" + str(configloader.get_config().NODE_ID) + "', '" + str(ip) + "', unix_timestamp())")
					cur.close()

					logging.info("Block ip:" + str(ip))

					denyed_ip_list.append(ip)

			cur = conn.cursor()
			cur.execute("SELECT * FROM `blockip` where `datetime`>unix_timestamp()-60")
			rows = cur.fetchall()
			cur.close()

			deny_str = "";
			deny_str_at = "";

			for row in rows:
				node = row[1]
				ip = get_ip(row[2])

				if ip != None:

					if str(node) == str(configloader.get_config().NODE_ID):
						if configloader.get_config().ANTISSATTACK == 1 and configloader.get_config().CLOUDSAFE == 1 and ip not in denyed_ip_list:
							if common.is_ip(ip) != False:
								if common.is_ip(ip) == socket.AF_INET:
									os.system('route add -host %s gw 127.0.0.1' % str(ip))
									deny_str = deny_str + "\nALL: " + str(ip)
								else:
									os.system('ip -6 route add ::1/128 via %s/128' % str(ip))
									deny_str = deny_str + "\nALL: [" + str(ip) +"]/128"

							logging.info("Remote Block ip:" + str(ip))
					else:
						if common.is_ip(ip) != False:
							if common.is_ip(ip) == socket.AF_INET:
								os.system('route add -host %s gw 127.0.0.1' % str(ip))
								deny_str = deny_str + "\nALL: " + str(ip)
							else:
								os.system('ip -6 route add ::1/128 via %s/128' % str(ip))
								deny_str = deny_str + "\nALL: [" + str(ip) +"]/128"
						logging.info("Remote Block ip:" + str(ip))


			deny_file=open('/etc/hosts.deny','a')
			fcntl.flock(deny_file.fileno(),fcntl.LOCK_EX)
			deny_file.write(deny_str + "\n")
			deny_file.close()

			if configloader.get_config().ANTISSATTACK == 1 and configloader.get_config().CLOUDSAFE == 1:
				deny_file=open('/etc/hosts.deny','a')
				fcntl.flock(deny_file.fileno(),fcntl.LOCK_EX)
				deny_file.write(deny_str_at + "\n")
				deny_file.close()




			cur = conn.cursor()
			cur.execute("SELECT * FROM `unblockip` where `datetime`>unix_timestamp()-60")
			rows = cur.fetchall()
			cur.close()

			conn.close()

			deny_file = open('/etc/hosts.deny')
			fcntl.flock(deny_file.fileno(),fcntl.LOCK_EX)
			deny_lines = deny_file.readlines()
			deny_file.close()

			i = 0

			for line in deny_lines:
				for row in rows:
					ip = str(row[1])
					if line.find(ip) != -1:
						del deny_lines[i]
						if common.is_ip(ip) != False:
							if common.is_ip(ip) == socket.AF_INET:
								os.system('route del -host %s gw 127.0.0.1' % str(ip))
							else:
								os.system('ip -6 route del ::1/128 via %s/128' % str(ip))
						logging.info("Unblock ip:" + str(ip))
				i = i + 1

			deny_file = file("/etc/hosts.deny", "w+")
			fcntl.flock(deny_file.fileno(),fcntl.LOCK_EX)
			for line in deny_lines:
				deny_file.write(line)
			deny_file.write("\n")
			deny_file.close()

		except BaseException:
			logging.error("Auto block thread error")

		start_line = file_len("/etc/hosts.deny")
Ejemplo n.º 26
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) != False:
						if(common.is_ip(ip) == socket.AF_INET):
							realip = ip
						else:
							if common.match_ipv4_address(ip) != None:
								realip = common.match_ipv4_address(ip)
							else:
								is_ipv6 = True
								realip = ip
					else:
						continue

					if str(realip) == str(server_ip):
						continue

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


					if rows != 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 is_ipv6 == False:
							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 auto_block_thread(self):
        global webapi
        server_ip = socket.gethostbyname(configloader.get_config().MYSQL_HOST)

        if configloader.get_config().API_INTERFACE == "modwebapi":
            # 读取节点IP
            # SELECT * FROM `ss_node`  where `node_ip` != ''
            node_ip_list = []
            data = webapi.getApi("nodes")
            for node in data:
                temp_list = node["node_ip"].split(",")
                node_ip_list.append(temp_list[0])
        else:
            import cymysql

            if configloader.get_config().MYSQL_SSL_ENABLE == 1:
                conn = cymysql.connect(
                    host=configloader.get_config().MYSQL_HOST,
                    port=configloader.get_config().MYSQL_PORT,
                    user=configloader.get_config().MYSQL_USER,
                    passwd=configloader.get_config().MYSQL_PASS,
                    db=configloader.get_config().MYSQL_DB,
                    charset="utf8",
                    ssl={
                        "ca": configloader.get_config().MYSQL_SSL_CA,
                        "cert": configloader.get_config().MYSQL_SSL_CERT,
                        "key": configloader.get_config().MYSQL_SSL_KEY,
                    },
                )
            else:
                conn = cymysql.connect(
                    host=configloader.get_config().MYSQL_HOST,
                    port=configloader.get_config().MYSQL_PORT,
                    user=configloader.get_config().MYSQL_USER,
                    passwd=configloader.get_config().MYSQL_PASS,
                    db=configloader.get_config().MYSQL_DB,
                    charset="utf8",
                )
            conn.autocommit(True)

            # 读取节点IP
            # SELECT * FROM `ss_node`  where `node_ip` != ''
            node_ip_list = []
            cur = conn.cursor()
            cur.execute(
                "SELECT `node_ip` FROM `ss_node`  where `node_ip` != ''")
            for r in cur.fetchall():
                temp_list = str(r[0]).split(",")
                node_ip_list.append(temp_list[0])
            cur.close()

        deny_file = open("/etc/hosts.deny")
        fcntl.flock(deny_file.fileno(), fcntl.LOCK_EX)
        deny_lines = deny_file.readlines()
        deny_file.close()

        logging.info("Read hosts.deny from line " + str(self.start_line))
        real_deny_list = deny_lines[self.start_line:]

        denyed_ip_list = []
        data = []
        for line in real_deny_list:
            if self.get_ip(line) and line.find("#") != 0:
                ip = self.get_ip(line)

                if str(ip).find(str(server_ip)) != -1:
                    i = 0

                    for line in deny_lines:
                        if line.find(ip) != -1:
                            del deny_lines[i]
                        i = i + 1

                    deny_file = open("/etc/hosts.deny", "w+")
                    fcntl.flock(deny_file.fileno(), fcntl.LOCK_EX)
                    for line in deny_lines:
                        deny_file.write(line)
                    deny_file.close()

                    continue

                has_match_node = False
                for node_ip in node_ip_list:
                    if str(ip).find(node_ip) != -1:
                        i = 0

                        for line in deny_lines:
                            if line.find(ip) != -1:
                                del deny_lines[i]
                            i = i + 1

                        deny_file = open("/etc/hosts.deny", "w+")
                        fcntl.flock(deny_file.fileno(), fcntl.LOCK_EX)
                        for line in deny_lines:
                            deny_file.write(line)
                        deny_file.close()

                        has_match_node = True
                        continue

                if has_match_node:
                    continue

                if configloader.get_config().API_INTERFACE == "modwebapi":
                    data.append({"ip": ip})
                    logging.info("Block ip:" + str(ip))
                else:
                    cur = conn.cursor()
                    cur.execute("SELECT * FROM `blockip` where `ip` = '" +
                                str(ip) + "'")
                    rows = cur.fetchone()
                    cur.close()

                    if rows is not None:
                        continue

                    cur = conn.cursor()
                    cur.execute(
                        "INSERT INTO `blockip` (`id`, `nodeid`, `ip`, `datetime`) VALUES (NULL, '"
                        + str(configloader.get_config().NODE_ID) + "', '" +
                        str(ip) + "', unix_timestamp())")
                    cur.close()

                    logging.info("Block ip:" + str(ip))

                    denyed_ip_list.append(ip)

        if configloader.get_config().API_INTERFACE == "modwebapi":
            webapi.postApi(
                "func/block_ip",
                {"node_id": configloader.get_config().NODE_ID},
                {"data": data},
            )

        if configloader.get_config().API_INTERFACE == "modwebapi":
            rows = webapi.getApi("func/block_ip")
        else:
            cur = conn.cursor()
            cur.execute(
                "SELECT * FROM `blockip` where `datetime`>unix_timestamp()-60")
            rows = cur.fetchall()
            cur.close()

        deny_str = ""
        deny_str_at = ""

        for row in rows:
            if configloader.get_config().API_INTERFACE == "modwebapi":
                node = row["nodeid"]
                ip = self.get_ip(row["ip"])
            else:
                node = row[1]
                ip = self.get_ip(row[2])

            if ip is not None:

                if str(node) == str(configloader.get_config().NODE_ID):
                    if (configloader.get_config().ANTISSATTACK == 1
                            and configloader.get_config().CLOUDSAFE == 1
                            and ip not in denyed_ip_list):
                        if common.is_ip(ip):
                            if common.is_ip(ip) == socket.AF_INET:
                                os.system("route add -host %s gw 127.0.0.1" %
                                          str(ip))
                                deny_str = deny_str + "\nALL: " + str(ip)
                            else:
                                os.system(
                                    "ip -6 route add ::1/128 via %s/128" %
                                    str(ip))
                                deny_str = (deny_str + "\nALL: [" + str(ip) +
                                            "]/128")

                        logging.info("Remote Block ip:" + str(ip))
                else:
                    if common.is_ip(ip):
                        if common.is_ip(ip) == socket.AF_INET:
                            os.system("route add -host %s gw 127.0.0.1" %
                                      str(ip))
                            deny_str = deny_str + "\nALL: " + str(ip)
                        else:
                            os.system("ip -6 route add ::1/128 via %s/128" %
                                      str(ip))
                            deny_str = (deny_str + "\nALL: [" + str(ip) +
                                        "]/128")
                    logging.info("Remote Block ip:" + str(ip))

        deny_file = open("/etc/hosts.deny", "a")
        fcntl.flock(deny_file.fileno(), fcntl.LOCK_EX)
        deny_file.write(deny_str)
        deny_file.close()

        if (configloader.get_config().ANTISSATTACK == 1
                and configloader.get_config().CLOUDSAFE == 1):
            deny_file = open("/etc/hosts.deny", "a")
            fcntl.flock(deny_file.fileno(), fcntl.LOCK_EX)
            deny_file.write(deny_str_at)
            deny_file.close()

        if configloader.get_config().API_INTERFACE == "modwebapi":
            rows = webapi.getApi("func/unblock_ip")
        else:
            cur = conn.cursor()
            cur.execute(
                "SELECT * FROM `unblockip` where `datetime`>unix_timestamp()-60"
            )
            rows = cur.fetchall()
            cur.close()
            conn.close()

        deny_file = open("/etc/hosts.deny")
        fcntl.flock(deny_file.fileno(), fcntl.LOCK_EX)
        deny_lines = deny_file.readlines()
        deny_file.close()

        i = 0

        for line in deny_lines:
            for row in rows:
                if configloader.get_config().API_INTERFACE == "modwebapi":
                    ip = str(row["ip"])
                else:
                    ip = str(row[1])
                if line.find(ip) != -1:
                    del deny_lines[i]
                    if common.is_ip(ip):
                        if common.is_ip(ip) == socket.AF_INET:
                            os.system("route del -host %s gw 127.0.0.1" %
                                      str(ip))
                        else:
                            os.system("ip -6 route del ::1/128 via %s/128" %
                                      str(ip))
                    logging.info("Unblock ip:" + str(ip))
            i = i + 1

        deny_file = open("/etc/hosts.deny", "w+")
        fcntl.flock(deny_file.fileno(), fcntl.LOCK_EX)
        for line in deny_lines:
            deny_file.write(line)
        deny_file.close()

        self.start_line = self.file_len("/etc/hosts.deny")
Ejemplo n.º 28
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
Ejemplo n.º 29
0
    def update_all_user(self, dt_transfer):
        update_transfer = {}

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

        alive_user_count = 0
        bandwidth_thistime = 0

        for offset_port in dt_transfer.keys():
            port = self.get_real_port(offset_port)
            if dt_transfer[offset_port][0] == 0 and dt_transfer[offset_port][1] == 0:
                continue

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

            alive_user_count = alive_user_count + 1

            self.append_traffic_log(offset_port, dt_transfer)

            bandwidth_thistime = bandwidth_thistime + (dt_transfer[offset_port][0] + dt_transfer[offset_port][1])

            if query_sub_in is not None:
                query_sub_in += ",%s" % port
            else:
                query_sub_in = "%s" % port
        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.get_mysql_cur(query_sql, fetch_type=FETCH_NONE)

        query_sql = (
            "UPDATE `ss_node` SET `node_heartbeat`=unix_timestamp(),`node_bandwidth`=`node_bandwidth`+'"
            + str(bandwidth_thistime)
            + "' WHERE `id` = "
            + str(self.api_config.NODE_ID)
            + " ; "
        )
        self.get_mysql_cur(query_sql, fetch_type=FETCH_NONE)

        query_sql = (
            "INSERT INTO `ss_node_online_log` (`id`, `node_id`, `online_user`, `log_time`) VALUES (NULL, '"
            + str(self.api_config.NODE_ID)
            + "', '"
            + str(alive_user_count)
            + "', unix_timestamp()); "
        )
        self.get_mysql_cur(query_sql, fetch_type=FETCH_NONE)

        query_sql = (
            "INSERT INTO `ss_node_info` (`id`, `node_id`, `uptime`, `load`, `log_time`) VALUES (NULL, '"
            + str(self.api_config.NODE_ID)
            + "', '"
            + str(self.uptime())
            + "', '"
            + str(self.load())
            + "', unix_timestamp()); "
        )
        self.get_mysql_cur(query_sql, fetch_type=FETCH_NONE)

        online_iplist = sp_instance().get_servers_iplist()
        for port in online_iplist.keys():
            for ip in online_iplist[port]:
                self.append_alive_ip(port, ip)
        self.mass_insert_alive_ip()

        detect_log_list = sp_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.api_config.NODE_ID)
                    + "')"
                )
                self.get_mysql_cur(query_sql, fetch_type=FETCH_NONE)

        deny_str = ""
        if platform.system() == "Linux" and self.api_config.ANTISSATTACK == 1:
            wrong_iplist = sp_instance().get_servers_wrong()
            server_ip = socket.gethostbyname(self.api_config.MYSQL_HOST)
            for id in wrong_iplist.keys():
                for ip in wrong_iplist[id]:
                    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.get_mysql_cur(query_sql, fetch_type=FETCH_ONE)

                    if rows is not None:
                        continue
                    if self.api_config.CLOUDSAFE == 1:
                        query_sql = (
                            "INSERT INTO `blockip` (`id`, `nodeid`, `ip`, `datetime`) VALUES (NULL, '"
                            + str(self.api_config.NODE_ID)
                            + "', '"
                            + str(realip)
                            + "', unix_timestamp())"
                        )
                        self.get_mysql_cur(query_sql, fetch_type=FETCH_NONE)
                    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: %s", str(realip))
                if self.api_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
Ejemplo n.º 30
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("traffic", {"node_id": get_config().NODE_ID},
                       {"data": data})

        webapi.postApi("uptimeinfo", {"node_id": get_config().NODE_ID},
                       {"node_id": get_config().NODE_ID})

        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("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(
            "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(
                "block_ip",
                {"node_id": get_config().NODE_ID},
                {"data": data},
            )
        return update_transfer
Ejemplo n.º 31
0
    def auto_block_thread(self):
        from db_transfer import MySqlWrapper
        global webapi
        server_ip = socket.gethostbyname(configloader.get_config().MYSQL_HOST)

        if configloader.get_config().API_INTERFACE == "modwebapi":
            # 读取节点IP
            # SELECT * FROM `ss_node`  where `node_ip` != ''
            node_ip_list = []
            data = webapi.getApi("nodes")
            for node in data:
                temp_list = node["node_ip"].split(",")
                node_ip_list.append(temp_list[0])
        else:
            mysqlObj = MySqlWrapper()
            node_ip_list = mysqlObj.get_all_node_ip()

        deny_file = open(hosts_deny_file_path())
        fcntl.flock(deny_file.fileno(), fcntl.LOCK_EX)
        deny_lines = deny_file.readlines()
        deny_file.close()

        logging.info("Read hosts.deny from line " + str(self.start_line))
        real_deny_list = deny_lines[self.start_line:]

        denyed_ip_list = []
        data = []
        for line in real_deny_list:
            if self.get_ip(line) and line.find("#") != 0:
                ip = self.get_ip(line)

                if str(ip).find(str(server_ip)) != -1:
                    i = 0

                    for line in deny_lines:
                        if line.find(ip) != -1:
                            del deny_lines[i]
                        i = i + 1

                    deny_file = open(hosts_deny_file_path(), "w+")
                    fcntl.flock(deny_file.fileno(), fcntl.LOCK_EX)
                    for line in deny_lines:
                        deny_file.write(line)
                    deny_file.close()

                    continue

                has_match_node = False
                for node_ip in node_ip_list:
                    if str(ip).find(node_ip) != -1:
                        i = 0

                        for line in deny_lines:
                            if line.find(ip) != -1:
                                del deny_lines[i]
                            i = i + 1

                        deny_file = open(hosts_deny_file_path(), "w+")
                        fcntl.flock(deny_file.fileno(), fcntl.LOCK_EX)
                        for line in deny_lines:
                            deny_file.write(line)
                        deny_file.close()

                        has_match_node = True
                        continue

                if has_match_node:
                    continue

                if configloader.get_config().API_INTERFACE == "modwebapi":
                    data.append({"ip": ip})
                    logging.info("Block ip:" + str(ip))
                else:
                    if mysqlObj.is_ip_in_blockip(ip):
                        continue

                    mysqlObj.write_ip_to_blockip(ip)

                    logging.info("Block ip:" + str(ip))

                    denyed_ip_list.append(ip)

        if configloader.get_config().API_INTERFACE == "modwebapi":
            webapi.postApi(
                "func/block_ip",
                {"node_id": configloader.get_config().NODE_ID},
                {"data": data},
            )

        if configloader.get_config().API_INTERFACE == "modwebapi":
            rows = webapi.getApi("func/block_ip")
        else:
            rows = mysqlObj.get_all_blockip()

        deny_str = ""
        deny_str_at = ""

        for row in rows:
            if configloader.get_config().API_INTERFACE == "modwebapi":
                node = row["nodeid"]
                ip = self.get_ip(row["ip"])
            else:
                node = row[1]
                ip = self.get_ip(row[2])

            if ip is not None:

                if str(node) == str(configloader.get_config().NODE_ID):
                    if (configloader.get_config().ANTISSATTACK == 1
                            and configloader.get_config().CLOUDSAFE == 1
                            and ip not in denyed_ip_list):
                        if common.is_ip(ip):
                            if common.is_ip(ip) == socket.AF_INET:
                                os.system("route add -host %s gw 127.0.0.1" %
                                          str(ip))
                                deny_str = deny_str + "\nALL: " + str(ip)
                            else:
                                os.system(
                                    "ip -6 route add ::1/128 via %s/128" %
                                    str(ip))
                                deny_str = (deny_str + "\nALL: [" + str(ip) +
                                            "]/128")

                        logging.info("Remote Block ip:" + str(ip))
                else:
                    if common.is_ip(ip):
                        if common.is_ip(ip) == socket.AF_INET:
                            os.system("route add -host %s gw 127.0.0.1" %
                                      str(ip))
                            deny_str = deny_str + "\nALL: " + str(ip)
                        else:
                            os.system("ip -6 route add ::1/128 via %s/128" %
                                      str(ip))
                            deny_str = (deny_str + "\nALL: [" + str(ip) +
                                        "]/128")
                    logging.info("Remote Block ip:" + str(ip))

        deny_file = open(hosts_deny_file_path(), "a")
        fcntl.flock(deny_file.fileno(), fcntl.LOCK_EX)
        deny_file.write(deny_str)
        deny_file.close()

        if (configloader.get_config().ANTISSATTACK == 1
                and configloader.get_config().CLOUDSAFE == 1):
            deny_file = open(hosts_deny_file_path(), "a")
            fcntl.flock(deny_file.fileno(), fcntl.LOCK_EX)
            deny_file.write(deny_str_at)
            deny_file.close()

        if configloader.get_config().API_INTERFACE == "modwebapi":
            rows = webapi.getApi("func/unblock_ip")
        else:
            rows = mysqlObj.get_all_unblockip()

        del mysqlObj

        deny_file = open(hosts_deny_file_path())
        fcntl.flock(deny_file.fileno(), fcntl.LOCK_EX)
        deny_lines = deny_file.readlines()
        deny_file.close()

        i = 0

        for line in deny_lines:
            for row in rows:
                if configloader.get_config().API_INTERFACE == "modwebapi":
                    ip = str(row["ip"])
                else:
                    ip = str(row[1])
                if line.find(ip) != -1:
                    del deny_lines[i]
                    if common.is_ip(ip):
                        if common.is_ip(ip) == socket.AF_INET:
                            os.system("route del -host %s gw 127.0.0.1" %
                                      str(ip))
                        else:
                            os.system("ip -6 route del ::1/128 via %s/128" %
                                      str(ip))
                    logging.info("Unblock ip:" + str(ip))
            i = i + 1

        deny_file = open(hosts_deny_file_path(), "w+")
        fcntl.flock(deny_file.fileno(), fcntl.LOCK_EX)
        for line in deny_lines:
            deny_file.write(line)
        deny_file.close()

        self.start_line = self.file_len(hosts_deny_file_path())