Ejemplo n.º 1
0
def __start_service(mode, debug):
    if not debug:
        pid = os.fork()
        if pid != 0: sys.exit(0)

        os.setsid()
        os.umask(0)
        pid = os.fork()

        if pid != 0: sys.exit(0)
        proc.write_pid(PID_FILE)

    config_path = "%s/fdslight_etc/fn_client.ini" % BASE_DIR

    configs = configfile.ini_parse_from_file(config_path)

    cls = _fdslight_client()

    if debug:
        cls.ioloop(mode, debug, configs)
        return
    try:
        cls.ioloop(mode, debug, configs)
    except:
        logging.print_error()
Ejemplo n.º 2
0
def __start_service(debug):
    if not debug and os.path.isfile(PID_FILE):
        print("the fdsl_pm_client process exists")
        return

    if not debug:
        pid = os.fork()
        if pid != 0: sys.exit(0)

        os.setsid()
        os.umask(0)
        pid = os.fork()

        if pid != 0: sys.exit(0)
        proc.write_pid(PID_FILE)

    config_path = "%s/fdslight_etc/fn_pm_client.ini" % BASE_DIR

    configs = configfile.ini_parse_from_file(config_path)

    cls = _fdslight_pm_client()

    if debug:
        cls.ioloop(debug, configs)
        return
    try:
        cls.ioloop(debug, configs)
    except:
        logging.print_error()

    os.remove(PID_FILE)
Ejemplo n.º 3
0
    def __handle_ipv4data_from_tunnel(self, session_id):
        self.__mbuf.offset = 9
        protocol = self.__mbuf.get_part(1)

        hdrlen = self.__get_ip4_hdrlen()
        if hdrlen + 8 < 28: return False

        # 检查IP数据报长度是否合法
        self.__mbuf.offset = 2
        payload_length = utils.bytes2number(self.__mbuf.get_part(2))
        if payload_length != self.__mbuf.payload_size: return False

        if protocol not in self.__support_ip4_protocols: return False

        # 对没有启用NAT内核模块UDP和UDPLite进行特殊处理,以支持内网穿透
        if (protocol == 17
                or protocol == 136) and not self.__enable_nat_module:
            is_udplite = False
            if protocol == 136: is_udplite = True
            self.__handle_ipv4_dgram_from_tunnel(session_id,
                                                 is_udplite=is_udplite)
            return True
        self.__mbuf.offset = 0

        rs = self.__nat4.get_ippkt2sLan_from_cLan(session_id, self.__mbuf)
        if not rs:
            logging.print_error(
                "cannot modify source address from client packet for ipv4")
            return
        self.__mbuf.offset = 0
        self.get_handler(self.__tundev_fileno).handle_msg_from_tunnel(
            self.__mbuf.get_data())
        return True
Ejemplo n.º 4
0
    def handle_data(self):
        rdata = self.reader.read()
        self.__time = time.time()

        if self.__is_msg_tunnel:
            fd, _ = self.dispatcher.session_get(self.__session_id)
            if not fd:
                sys.stderr.write("session id not exists\r\n")
                self.delete_handler(self.fileno)
                return
            self.send_message_to_handler(self.fileno, fd, rdata)
            return

        self.__parser.input(rdata)

        while 1:
            try:
                self.__parser.parse()
            except intranet_pass.ProtoErr:
                if self.dispatcher.debug:
                    logging.print_error()
                self.delete_handler(self.fileno)
                return

            rs = self.__parser.get_result()
            if not rs: break
            _type, o = rs

            if _type == intranet_pass.TYPE_PING:
                self.handle_ping()
                continue
            if _type == intranet_pass.TYPE_PONG:
                self.handle_pong()
                continue
            ''''''
Ejemplo n.º 5
0
def __start_service(debug, enable_nat_module):
    if not debug and os.path.isfile(PID_FILE):
        print("the fdsl_server process exists")
        return

    if not debug:
        pid = os.fork()
        if pid != 0: sys.exit(0)

        os.setsid()
        os.umask(0)
        pid = os.fork()

        if pid != 0: sys.exit(0)
        proc.write_pid(PID_FILE)

    configs = configfile.ini_parse_from_file("%s/fdslight_etc/fn_server.ini" %
                                             BASE_DIR)
    cls = _fdslight_server()

    if debug:
        cls.ioloop(debug, configs, enable_nat_module=enable_nat_module)
        return
    try:
        cls.ioloop(debug, configs, enable_nat_module=enable_nat_module)
    except:
        logging.print_error()

    os.remove(PID_FILE)
Ejemplo n.º 6
0
def start(debug, wol_key, wol_port, wol_bind_ip):
    if not debug:
        if os.path.exists(PID_PATH):
            sys.stderr.write("the process exists\r\n")
            sys.exit(-1)
        pid = os.fork()
        if pid != 0: sys.exit(0)

        os.setsid()
        os.umask(0)

        pid = os.fork()
        if pid != 0: sys.exit(0)

        sys.stderr = open(ERR_FILE, "a")
        sys.stdout = open(LOG_FILE, "a")

        proc.write_pid(PID_PATH)
    cls = service()
    try:
        cls.ioloop(wol_key, wol_bind_ip=wol_bind_ip, debug=debug, wol_port=wol_port)
    except KeyboardInterrupt:
        cls.release()
    except:
        cls.release()
        logging.print_error()

    if os.path.isfile(PID_PATH): os.remove(PID_PATH)
    sys.exit(0)
Ejemplo n.º 7
0
def start(debug):
    if not debug:
        pid = os.fork()
        if pid != 0: sys.exit(0)

        os.setsid()
        os.umask(0)

        pid = os.fork()
        if pid != 0: sys.exit(0)

        proc.write_pid(PID_PATH)
        sys.stderr = open(ERR_FILE, "a")
        sys.stdout = open(LOG_FILE, "a")

    cls = service()
    try:
        cls.ioloop(debug=debug)
    except KeyboardInterrupt:
        cls.release()
        if not debug: os.remove(PID_PATH)
        if os.path.exists(SOCK_FILE): os.remove(SOCK_FILE)
        sys.exit(0)
    except:
        cls.release()
        if not debug: os.remove(PID_PATH)
        if os.path.exists(SOCK_FILE): os.remove(SOCK_FILE)
        logging.print_error()
        sys.exit(-1)
Ejemplo n.º 8
0
def __start_service(mode, debug):
    if not debug:
        pid = os.fork()
        if pid != 0: sys.exit(0)

        os.setsid()
        os.umask(0)
        pid = os.fork()

        if pid != 0: sys.exit(0)
        proc.write_pid(PID_FILE)

    config_path = "%s/fdslight_etc/fn_client.ini" % BASE_DIR

    configs = configfile.ini_parse_from_file(config_path)

    cls = _fdslight_client()

    if debug:
        cls.ioloop(mode, debug, configs)
        return
    try:
        cls.ioloop(mode, debug, configs)
    except:
        logging.print_error()
Ejemplo n.º 9
0
 def do_ssl_handshake(self):
     try:
         self.socket.do_handshake()
         self.__ssl_handshake_ok = True
         logging.print_general("TLS_handshake_ok", self.__server_address)
         self.add_evt_read(self.fileno)
         self.send_handshake()
     except ssl.SSLWantReadError:
         self.add_evt_read(self.fileno)
     except ssl.SSLWantWriteError:
         self.add_evt_write(self.fileno)
     except:
         logging.print_error()
         self.delete_handler(self.fileno)
Ejemplo n.º 10
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
Ejemplo n.º 11
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)
Ejemplo n.º 12
0
    def do_ssl_handshake(self):
        try:
            self.socket.do_handshake()
            self.__ssl_handshake_ok = True

            # 如果开启SNI那么匹配证书
            if self.__enable_https_sni:
                cert = self.socket.getpeercert()
                ssl.match_hostname(cert, self.__https_sni_host)

            logging.print_general("TLS_handshake_ok", self.__server_address)
            self.add_evt_read(self.fileno)
            self.send_handshake()
        except ssl.SSLWantReadError:
            self.add_evt_read(self.fileno)
        except ssl.SSLWantWriteError:
            self.add_evt_write(self.fileno)
        except:
            logging.print_error()
            self.delete_handler(self.fileno)
Ejemplo n.º 13
0
    def __handle_ipv6data_from_tunnel(self, session_id):
        # 如果NAT66没开启那么丢弃IPV6数据包
        if not self.__enable_nat6: return False

        if self.__mbuf.payload_size < 48: return False

        # 检查IPV6数据包长度是否合法
        self.__mbuf.offset = 4
        payload_length = utils.bytes2number(self.__mbuf.get_part(2))
        if payload_length + 40 != self.__mbuf.payload_size: return False

        self.__mbuf.offset = 6
        nexthdr = self.__mbuf.get_part(1)

        if nexthdr not in self.__support_ip6_protocols: return False

        self.__mbuf.offset = 40
        nexthdr = self.__mbuf.get_part(1)

        if nexthdr in (
                17,
                136,
        ) and self.__ip6_udp_cone_nat:
            is_udplite = False
            if nexthdr == 136: is_udplite = True
            self.__handle_ipv6_dgram_from_tunnel(session_id,
                                                 is_udplite=is_udplite)
            return True

        b = self.__nat6.get_ippkt2sLan_from_cLan(session_id, self.__mbuf)
        if not b:
            logging.print_error(
                "cannot modify source address from client packet for ipv6")
            return False

        self.__mbuf.offset = 24
        self.__mbuf.offset = 0
        self.get_handler(self.__tundev_fileno).handle_msg_from_tunnel(
            self.__mbuf.get_data())

        return True
Ejemplo n.º 14
0
    def __load_port_map_rules(self):
        fpath = "%s/fdslight_etc/fn_pm_client_rules.json" % BASE_DIR

        with open(fpath, "r") as f:
            s = f.read()
        f.close()

        try:
            rules = json.loads(s)
        except json.JSONDecodeError:
            logging.print_error("wrong port map client rules")
            return

        if not isinstance(rules, list):
            logging.print_error(
                "wrong port map client rules,it must be list type")
            return

        for info in rules:
            if not self.__check_rule(info):
                logging.print_error("wrong port map rule about %s" % info)
                break

            is_ipv6 = info["is_ipv6"]
            if is_ipv6:
                cls = self.__port_mapv6
            else:
                cls = self.__port_mapv4
Ejemplo n.º 15
0
    def tcp_readable(self):
        if not self.__http_handshake_ok:
            self.handle_handshake_response()
            return

        self.__parser.input(self.reader.read())
        self.__time = time.time()

        while 1:
            try:
                self.__parser.parse()
            except socks2https.FrameError:
                logging.print_error()
                self.delete_handler(self.fileno)
                break
            rs = self.__parser.get_result()
            if not rs: break
            frame_type, info = rs

            if frame_type == socks2https.FRAME_TYPE_PING:
                self.send_pong()
                continue
            if frame_type == socks2https.FRAME_TYPE_PONG:
                self.handle_pong()
                continue
            if frame_type == socks2https.FRAME_TYPE_CONN_STATE:
                self.handle_conn_state(info)
                continue
            if frame_type == socks2https.FRAME_TYPE_TCP_DATA:
                self.handle_tcp_data(info)
                continue
            if frame_type == socks2https.FRAME_TYPE_UDP_DATA:
                self.handle_udp_udplite_data(info)
                continue
            if frame_type == socks2https.FRAME_TYPE_UDPLITE_DATA:
                self.handle_udp_udplite_data(info)
                continue
            ''''''
        return
Ejemplo n.º 16
0
def __start_service(debug):
    if not debug:
        pid = os.fork()
        if pid != 0: sys.exit(0)

        os.setsid()
        os.umask(0)
        pid = os.fork()

        if pid != 0: sys.exit(0)
        proc.write_pid(PID_FILE)

    configs = configfile.ini_parse_from_file("fdslight_etc/fn_server.ini")
    cls = _fdslight_server()

    if debug:
        cls.ioloop(debug, configs)
        return
    try:
        cls.ioloop(debug, configs)
    except:
        logging.print_error()
Ejemplo n.º 17
0
    def __set_rules(self, signum, frame):
        fpaths = [
            "%s/fdslight_etc/host_rules.txt" % BASE_DIR,
            "%s/fdslight_etc/ip_rules.txt" % BASE_DIR,
            "%s/fdslight_etc/pre_load_ip_rules.txt" % BASE_DIR
        ]

        for fpath in fpaths:
            if not os.path.isfile(fpath):
                sys.stderr.write("cannot found %s\r\n" % fpath)
                return
        try:
            rules = file_parser.parse_host_file(fpaths[0])
            self.get_handler(self.__dns_fileno).set_host_rules(rules)

            rules = file_parser.parse_ip_subnet_file(fpaths[1])
            self.get_handler(self.__dns_fileno).set_ip_rules(rules)

            rules = file_parser.parse_ip_subnet_file(fpaths[2])
            self.__set_static_ip_rules(rules)

        except file_parser.FilefmtErr:
            logging.print_error()
Ejemplo n.º 18
0
    def myinit(self):
        path = "%s/../../fdslight_etc/fn_pm_server_rules.json" % os.path.dirname(
            __file__)

        with open(path, "r") as f:
            s = f.read()
        f.close()

        s = json.loads(s)

        if not isinstance(s, dict):
            logging.print_error("wrong port map rule file")
            return

        for k in s:
            o = s[k]
            if not self.check(o):
                logging.print_error("wrong port map rule:%s" % str(o))
                break
            self.set_map_info(k,
                              o["address"],
                              o["protocol"],
                              o["port"],
                              is_ipv6=o["is_ipv6"])
Ejemplo n.º 19
0
    def send_query_request(self, dns_msg, address):
        """发送查询请求
        :return:
        """
        if len(dns_msg) < 8: return
        if self.__dns_client < 0:
            self.__dns_client = self.create_handler(self.fileno,
                                                    dns_client,
                                                    self.__dnsserver,
                                                    is_ipv6=self.__is_ipv6)

        # 检查查询以及匹配查询请求
        dns_id = (dns_msg[0] << 8) | dns_msg[1]

        new_dns_id = self.get_dns_id()
        if new_dns_id < 1:
            logging.print_error("not enough dns id,dns server is busy")
            return

        dns_msg = b"".join([struct.pack("!H", new_dns_id), dns_msg[2:]])

        try:
            msg = dns.message.from_wire(dns_msg)
        except:
            # 发生异常那么回收DNS ID
            self.__empty_ids.append(new_dns_id)
            return

        self.__query_timer.set_timeout(new_dns_id, 10)
        self.__dns_map[new_dns_id] = [dns_id, address, -1]

        questions = msg.question
        if len(questions) != 1 or msg.opcode() != 0:
            self.sendto(dns_msg, (
                self.__dnsserver,
                53,
            ))
            self.add_evt_write(self.fileno)
            return

        q = questions[0]
        host = b".".join(q.name[0:-1]).decode("iso-8859-1")
        pos = host.find(".")

        if self.dispatcher.debug: print(host)

        if pos > 0 and self.dispatcher.debug: print(host)
        is_match, flags = self.dispatcher.match_domain(host)

        # 丢弃DNS请求
        if is_match and flags == 2:
            self.__query_timer.drop(new_dns_id)
            self.__empty_ids.append(new_dns_id)
            del self.__dns_map[new_dns_id]
            return

        if not is_match:
            self.send_message_to_handler(self.fileno, self.__dns_client,
                                         dns_msg)
            return

        self.__dns_map[new_dns_id][2] = flags
        self.send_conn_frame(dns_msg)
Ejemplo n.º 20
0
 def set_ip_rules(self, rules):
     self.__ip_match.clear()
     for subnet, prefix in rules:
         rs = self.__ip_match.add_rule(subnet, prefix)
         if not rs: logging.print_error("wrong ip format %s/%s on ip_rules" % (subnet, prefix,))