示例#1
0
    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
示例#2
0
    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
示例#3
0
    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
示例#4
0
    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)
示例#5
0
    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
示例#6
0
    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
示例#7
0
    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
        }
示例#8
0
    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)
示例#9
0
    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)
示例#10
0
    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
示例#11
0
    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
示例#12
0
    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
示例#13
0
    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)
示例#14
0
    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)
示例#15
0
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()