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()
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)
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
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 ''''''
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)
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)
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)
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()
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)
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 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)
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
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
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
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()
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()
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"])
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)
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,))