def __check_format(self, subnet, prefix): prefix = int(prefix) if prefix < 1: return False if utils.is_ipv4_address(subnet) and prefix > 32: return False if utils.is_ipv6_address(subnet) and prefix > 128: return False if not utils.is_ipv6_address(subnet) and not utils.is_ipv4_address( subnet): return False return True
def get_server_ip(self, host): """获取服务器IP :param host: :return: """ if utils.is_ipv4_address(host): return host if utils.is_ipv6_address(host): return host enable_ipv6 = bool(int(self.__configs["connection"]["enable_ipv6"])) resolver = dns.resolver.Resolver() resolver.nameservers = [self.__configs["public"]["remote_dns"]] try: if enable_ipv6: rs = resolver.query(host, "AAAA") else: rs = resolver.query(host, "A") except dns.resolver.NoAnswer: return None except dns.resolver.Timeout: return None except dns.resolver.NoNameservers: return None for anwser in rs: ipaddr = anwser.__str__() break if self.__mode == _MODE_GW: self.__set_tunnel_ip(ipaddr) return ipaddr
def check(self, o): keys = ( "port", "protocol", "is_ipv6", "address", ) if not isinstance(o, dict): return False for k in keys: if k not in o: return False port = o["port"] protocol = o["protocol"] is_ipv6 = o["is_ipv6"] address = o["address"] if not cfg_check.is_port(port): return False if protocol not in ( "tcp", "udp", ): return False if is_ipv6 and not utils.is_ipv6_address(address): return False if not is_ipv6 and not utils.is_ipv4_address(address): return False return True
def handle_from_dnsserver(self, dns_msg): if len(dns_msg) < 6: return dns_id = (dns_msg[0] << 8) | dns_msg[1] # 检查是否在映射当中 if dns_id not in self.__dns_map: return my_dns_id, address, flags = self.__dns_map[dns_id] self.__empty_ids.append(dns_id) if self.__query_timer.exists(dns_id): self.__query_timer.drop(dns_id) del self.__dns_map[dns_id] dns_msg = b"".join([struct.pack("!H", my_dns_id), dns_msg[2:]]) try: msg = dns.message.from_wire(dns_msg) except: return for rrset in msg.answer: for cname in rrset: ip = cname.__str__() if utils.is_ipv4_address(ip) or utils.is_ipv6_address(ip): if 1 == flags: self.dispatcher.match_host_rule_add(ip) '''''' '''''' self.sendto(dns_msg, address) self.add_evt_write(self.fileno)
def get_server_ip(self, host): """获取服务器IP :param host: :return: """ if utils.is_ipv4_address(host): return host if utils.is_ipv6_address(host): return host enable_ipv6 = bool(int(self.__configs["connection"]["enable_ipv6"])) resolver = dns.resolver.Resolver() resolver.nameservers = [self.__configs["public"]["remote_dns"]] try: if enable_ipv6: rs = resolver.query(host, "AAAA") else: rs = resolver.query(host, "A") except dns.resolver.NoAnswer: return None except dns.resolver.Timeout: return None except dns.resolver.NoNameservers: return None for anwser in rs: ipaddr = anwser.__str__() break if self.__mode == _MODE_GW: self.__set_tunnel_ip(ipaddr) return ipaddr
def get_server_ip(self, host): """获取服务器IP :param host: :return: """ self.__server_ip = host if utils.is_ipv4_address(host): return host if utils.is_ipv6_address(host): return host enable_ipv6 = bool(int(self.__configs["connection"]["enable_ipv6"])) resolver = dns.resolver.Resolver() try: if enable_ipv6: rs = resolver.query(host, "AAAA") else: rs = resolver.query(host, "A") except dns.resolver.NoAnswer: return None except dns.resolver.Timeout: return None except dns.resolver.NoNameservers: return None except: return None ipaddr = None for anwser in rs: ipaddr = anwser.__str__() break self.__server_ip = ipaddr return ipaddr
def parse_relay_config(self, name, py_obj): """解析中继配置 :param name: :param py_obj: :return: """ o = py_obj[name] listen_ip = o.get("listen_ip") if not utils.is_ipv6_address(listen_ip) and not utils.is_ipv4_address( listen_ip): return None if utils.is_ipv4_address(listen_ip): is_ipv6 = False else: is_ipv6 = True try: port = int(o.get("port", 8800)) except ValueError: return None if port < 1 or port > 65535: return None try: conn_timeout = int(o.get("conn_timeout", 120)) except ValueError: return None if conn_timeout < 1: return None redir_host = o.get("redirect_host", "") try: redir_port = int(o.get("redirect_port", 0)) except ValueError: return None if redir_port < 1 or redir_port > 65535: return None return { "is_ipv6": is_ipv6, "listen_ip": listen_ip, "port": port, "conn_timeout": conn_timeout, "redirect_host": redir_host, "redirect_port": redir_port }
def create_dns_service(self): config = cfg.ini_parse_from_file(self.__cfg_path) c = config.get("dns_listen", {}) try: enable_ipv6 = bool(int(c.get("enable_ipv6", 0))) except ValueError: sys.stderr.write("wrong dns config A") sys.stderr.flush() return listen_ip = c.get("listen_ip", "0.0.0.0") listen_ipv6 = c.get("listen_ipv6", "::") ns_no_proxy_v4 = c.get("nameserver_no_proxy_v4", "223.5.5.5") ns_with_proxy_v4 = c.get("nameserver_with_proxy_v4", "8.8.8.8") ns_no_proxy_v6 = c.get("nameserver_no_proxy_v6", "2001:4860:4860::8888") ns_with_proxy_v6 = c.get("nameserver_with_proxy_v6", "2001:4860:4860::8844") if not utils.is_ipv4_address(listen_ip) or not utils.is_ipv4_address( ns_no_proxy_v4) or not utils.is_ipv4_address(ns_with_proxy_v4): sys.stderr.write("wrong dns config B") sys.stderr.flush() return if not utils.is_ipv6_address(listen_ipv6) or not utils.is_ipv6_address( ns_no_proxy_v6) or not utils.is_ipv6_address(ns_with_proxy_v6): sys.stderr.write("wrong dns config C") sys.stderr.flush() return self.__dnsserver_fd = self.create_handler(-1, socks2https_dns.dns_proxy, ( listen_ip, 53, ), ns_no_proxy_v4, ns_with_proxy_v4) if enable_ipv6: self.__dnsserver_fd6 = self.create_handler( -1, socks2https_dns.dns_proxy, ( listen_ipv6, 53, ), ns_no_proxy_v6, ns_with_proxy_v6)
def __handle_msg_from_response(self, message): try: msg = dns.message.from_wire(message) except: return dns_id = (message[0] << 8) | message[1] if not self.dns_id_map_exists(dns_id): return saddr, daddr, dport, n_dns_id, flags, is_ipv6 = self.get_dns_id_map(dns_id) self.del_dns_id_map(dns_id) L = list(message) L[0:2] = ( (n_dns_id & 0xff00) >> 8, n_dns_id & 0xff, ) message = bytes(L) for rrset in msg.answer: for cname in rrset: ip = cname.__str__() if utils.is_ipv4_address(ip): self.__set_route(ip, flags, is_ipv6=False) if utils.is_ipv6_address(ip): self.__set_route(ip, flags, is_ipv6=True) '''''' '''''' if not self.__server_side: if self.__is_ipv6: mtu = 1280 else: mtu = 1500 packets = ippkts.build_udp_packets(saddr, daddr, 53, dport, message, mtu=mtu, is_ipv6=self.__is_ipv6) for packet in packets: self.dispatcher.send_msg_to_tun(packet) self.del_dns_id_map(dns_id) self.__timer.drop(dns_id) return if self.__is_ipv6 != is_ipv6 and self.__server_side: if self.__is_ipv6: is_ipv6 = False else: is_ipv6 = True self.dispatcher.send_msg_to_other_dnsservice_for_dns_response(message, is_ipv6=is_ipv6) if self.__is_ipv6: sts_daddr = socket.inet_ntop(socket.AF_INET6, daddr) else: sts_daddr = socket.inet_ntop(socket.AF_INET, daddr) self.del_dns_id_map(dns_id) self.__timer.drop(dns_id) self.sendto(message, (sts_daddr, dport)) self.add_evt_write(self.fileno)
def __check_rule(self, rule: dict): """检查每一条规则 :param rule: :return: """ keys = ( "is_ipv6", "dest_addr", "rewrite_dest_addr", "dest_port", "rewrite_dest_port", ) for k in keys: if k not in rule: return False is_ipv6 = rule["is_ipv6"] dest_addr = rule["dest_addr"] rewrite_dest = rule["rewrite_dest_addr"] dest_port = rule["dest_port"] rewrite_dest_port = rule["rewrite_dest_port"] protocol = rule["protocol"] if protocol not in ( "tcp", "udp", "udplite", "sctp", ): return False if is_ipv6 and (not utils.is_ipv6_address(dest_addr) or not utils.is_ipv6_address(rewrite_dest)): return False if not is_ipv6 and (not utils.is_ipv4_address(dest_addr) or not utils.is_ipv4_address(rewrite_dest)): return False if not cfg_check.is_port(dest_port): return False if not cfg_check.is_port(rewrite_dest_port): return False return True
def __get_atyp(self, host): """根据host获取socks5 atyp值 :param host: :return: """ if utils.is_ipv4_address(host): return 1 if utils.is_ipv6_address(host): return 4 return 3
def get_server_ip(self, host): """获取服务器IP :param host: :return: """ self.__server_ip = host if utils.is_ipv4_address(host): return host if utils.is_ipv6_address(host): return host enable_ipv6 = bool(int(self.__configs["connection"]["enable_ipv6"])) resolver = dns.resolver.Resolver() resolver.nameservers = [self.__configs["public"]["remote_dns"]] try: if enable_ipv6: rs = resolver.query(host, "AAAA") else: rs = resolver.query(host, "A") except dns.resolver.NoAnswer: return None except dns.resolver.Timeout: return None except dns.resolver.NoNameservers: return None except: return None ipaddr = None for anwser in rs: ipaddr = anwser.__str__() break if self.__mode == _MODE_GW: self.__set_tunnel_ip(ipaddr) self.__server_ip = ipaddr if not ipaddr: return ipaddr # 检查路由是否冲突 rs = self.__get_conflict_from_static_route(ipaddr, is_ipv6=enable_ipv6) # 路由冲突那么先删除路由 if rs: self.__del_route(rs[0], prefix=rs[1], is_ipv6=rs[2], is_dynamic=False) logging.print_error("conflict route with tunnel ip,it is %s/%s" % (rs[0], rs[1],)) if ipaddr in self.__routes: self.__del_route(ipaddr, is_dynamic=True, is_ipv6=enable_ipv6) return ipaddr
def __set_static_ip_rules(self, rules): nameserver = self.__configs["public"]["remote_dns"] ns_is_ipv6 = utils.is_ipv6_address(nameserver) # 查看新的规则 kv_pairs_new = {} for subnet, prefix in rules: if not utils.is_ipv6_address(subnet) and not utils.is_ipv4_address(subnet): logging.print_error("wrong pre ip rule %s/%s" % (subnet, prefix,)) continue is_ipv6 = utils.is_ipv6_address(subnet) # 找到和nameserver冲突的路由那么跳过 t = utils.calc_subnet(nameserver, prefix, is_ipv6=ns_is_ipv6) if t == subnet: logging.print_error( "conflict preload ip rules %s/%s with nameserver %s" % (subnet, prefix, nameserver,) ) continue name = "%s/%s" % (subnet, prefix,) kv_pairs_new[name] = (subnet, prefix, is_ipv6,) # 需要删除的列表 need_dels = [] # 需要增加的路由 need_adds = [] for name in kv_pairs_new: # 新的规则旧的没有那么就需要添加 if name not in self.__static_routes: need_adds.append(kv_pairs_new[name]) for name in self.__static_routes: # 旧的规则新的没有,那么就是需要删除 if name not in kv_pairs_new: need_dels.append(self.__static_routes[name]) # 删除需要删除的路由 for subnet, prefix, is_ipv6 in need_dels: self.__del_route(subnet, prefix=prefix, is_ipv6=is_ipv6, is_dynamic=False) # 增加需要增加的路由 for subnet, prefix, is_ipv6 in need_adds: self.set_route(subnet, prefix=prefix, is_ipv6=is_ipv6, is_dynamic=False)
def send_conn_request(self): self.__packet_id = self.dispatcher.alloc_packet_id(self.fileno) _, address = self.dispatcher.get_relay_service(self.__cfg_name) is_ipv6 = False is_ipv4 = False if utils.is_ipv6_address(address[0]): is_ipv6 = True if utils.is_ipv4_address(address[0]): is_ipv4 = True if is_ipv4: _t = socks2https.ADDR_TYPE_IP elif is_ipv6: _t = socks2https.ADDR_TYPE_IPv6 else: _t = socks2https.ADDR_TYPE_DOMAIN self.dispatcher.send_conn_frame(socks2https.FRAME_TYPE_TCP_CONN, self.__packet_id, address[0], address[1], _t)
def main(): help_doc = """ --bind=address,port --redirect=host,port -p tcp | udp [-6] [--nofork] """ try: opts, args = getopt.getopt(sys.argv[1:], "6p:", ["nofork", "bind=", "redirect=", "help"]) except getopt.GetoptError: print(help_doc) return bind = None redirect = None force_ipv6 = False bind_s = None redirect_s = None fork = True is_ipv6 = False protocol = None for k, v in opts: if k == "-6": force_ipv6 = True if k == "--bind": bind_s = v if k == "--redirect": redirect_s = v if k == "--help": print(help_doc) return if k == "--nofork": fork = False if k == "-p": protocol = v if not bind_s: print("please set bind address") return if not redirect_s: print("please set redirect address") return if not protocol: print("not set protocol") return if protocol not in ( "tcp", "udp", ): print("unsupport protocol %s" % protocol) return seq = bind_s.split(",") if len(seq) != 2: print("wrong bind address format") return try: bind = ( seq[0], int(seq[1]), ) except ValueError: print("wrong bind address format") return if bind[1] > 0xffff - 1 or bind[1] < 1: print("wrong bind port number") return if not utils.is_ipv6_address(bind[0]) and (not utils.is_ipv4_address( bind[0])): print("please set bind address") return if utils.is_ipv6_address(bind[0]): is_ipv6 = True seq = redirect_s.split(",") if len(seq) != 2: print("wrong redirect address format") return try: redirect = ( seq[0], int(seq[1]), ) except ValueError: print("wrong redirect address format") return if fork: pid = os.fork() if pid != 0: sys.exit(0) os.umask(0) os.setsid() pid = os.fork() if pid != 0: sys.exit(0) is_udp = False if protocol == "udp": is_udp = True instance = service() try: instance.ioloop(bind, redirect, is_udp=is_udp, force_ipv6=force_ipv6) except KeyboardInterrupt: instance.release()