def check_layers(self, packet): """ Hand over packets to the layer controller or trackers :param packet: ipv4 / ipv6 packet (scapy), packet can be modified in this method :return: forward (should it be forwarded to the network stack) """ forward = True #check every controller or translator for (id, controller) in sorted(self._controller.items()): if isinstance(controller, ILayerController): # check if layer for controller exists layer_types = controller.layers() for layer in layer_types: if packet.haslayer(layer): InternalLogger.get().debug("Forwarding to controller" + str(type(controller))) #original packet, translators can modify forward_controller = controller.process_packet(packet) forward = forward and forward_controller break # Dont send to controller twice elif isinstance(controller, IConnectionTracker): #Copy Packet, dont allow to change it #Track in new thead (no realtime changes required) packet_copy = copy.deepcopy(packet) InternalLogger.get().debug("Forwarding to tracker" + str(type(controller))) self._executor.submit(self.forward_to_tracker, controller, packet_copy, self._io) return forward
def check_buffer(self, packet): """ Check if a mapping for the connection exisits in the connection tacker buffer :param packet: :return: """ tracked_ip = None if packet.haslayer(TCP): tcp = packet[TCP] port = 0 if self._io == IO.INPUT: port = tcp.dport else: port = tcp.sport # check if this connection is allowed to continue based on connection tracking result = self._nas_tracker.check_buffer(packet, self._io) if result is not None: (ip, enforced) = result if self._dyn_port_priority.allow_continue(port) or enforced: tracked_ip = ip else: InternalLogger.get().debug( "DynPort Priority doesnt allow the connection to continue (dest rPort = " + str(port) + ") and it has not been enforced") return tracked_ip
def clean_buffer(self): """ """ # Cleanup while len(self._connection_buffer) > self._max_buffer: # remove first element(s) InternalLogger.get().debug("Removing element from buffer") with self._lock.gen_wlock(): self._connection_buffer.popitem(last=True)
def add_hf_mapping(self, hf_mapping): """ called by REST endpoint add high frequency mapping from other gateway to internal mapping :param hf_mapping: high frequency mapping """ InternalLogger.get().debug("Adding addresses") InternalLogger.get().debug(hf_mapping) self._hf_mapping_other.update(hf_mapping) # Recalculate total mapping (merge) and send self.send_new_mapping()
def virtual_port_to_rport(self, v_port, client_ip, client_key): """ :param v_port: Int, Virtual Port :param client_ip: String, Client IP Address :param client_key: String, Client PreShared Key :return: Real Port, Int """ t = self.get_T() h = self.get_hash(t, client_key, client_ip) r_port = h ^ v_port InternalLogger.get().debug("RPAH rPort =" + str(r_port)) return r_port
def real_port_to_vport(self, r_port, client_ip, client_key): """ :param r_port: Int, Real Port :param client_ip: String, Client IP Address :param client_key: String, Client PreShared Key :return: Virtual Port, Int """ t = self.get_T() h = self.get_hash(t, client_key, client_ip) v_port = h ^ r_port InternalLogger.get().debug("RPAH vPort =" + str(v_port)) return v_port
def run(self): """ Run this class in new thread and start packet receiver """ InternalLogger.get().debug("Starting IP-Controller, queue_num=" + str(self._queue_num)) try: q = self.conn.bind(self._queue_num) q.set_mode(fnfqueue.MAX_PAYLOAD, fnfqueue.COPY_PACKET) except PermissionError: InternalLogger.get().error("Access denied; Do I have root rights or the needed capabilities?") sys.exit(-1) while True: try: for packet in self.conn: self.receive(packet) except fnfqueue.BufferOverflowException: InternalLogger.get().error("Buffer Error") ''' In case packets arrive too fast at the kernel side, the socket buffer overflows and a BufferOverflowException is raised. ''' self.conn.reset() # try to solve Overflow pass except Exception as e: InternalLogger.get().critical("Error: " + str(e), exc_info=True)
def revoke_hf_mapping(self, hf_mapping): """ called by REST endpoint revoke parts of the high frequency mapping from other gateways :param hf_mapping: revoked high frequency mapping """ InternalLogger.get().debug("Revoking addresses") InternalLogger.get().debug(hf_mapping) #delete revoked mappings for v_ip, r_ip in hf_mapping.items(): if self._hf_mapping_other.get(v_ip) is not None: del self._hf_mapping_other[v_ip] # Recalculate total mapping (merge) and send self.send_new_mapping()
def send_new_mapping(self): """ Merge external (other gateways) and internal mappings send new mapping to the receivers = translators (trackers/controllers) internally send new mapping to other gatways (defined in nas/receiver) if necessary """ total_mapping = {} #Internal mapping if self._hf_mapping is not None: total_mapping.update(self._hf_mapping) #external mapping if self._hf_mapping_other is not None: total_mapping.update(self._hf_mapping_other) #send new mapping to translators for translator in self._translators: #POSSIBLE: total_mapping just for DNS translator.set_mapping(total_mapping) InternalLogger.get().debug("Total Mapping") InternalLogger.get().debug(total_mapping) #send new mapping to other gateways self._executor.submit(self.send_all_rest)
def add_connection(self, sourceIP, sourcePort, dest_vIP, dest_rPort, dest_rIP, enforce): """ Add connection information for connection which should be generated in other components :param sourcePort: Source Port :param sourceIP: Source IP-Address :param dest_rPort: Destination virtual Port :param dest_vIP: Destination virtual IP-Address :param dest_rIP: Destination real IP-Address :param enforce: Tell other modules that this connection should be kept alive (even if other security measures prohibit it) """ with self._lock.gen_wlock(): packet_data = (sourceIP, sourcePort, dest_vIP, dest_rPort) InternalLogger.get().debug( "Added external connection to tracker: " + str(packet_data) + ": " + dest_rIP) self._connection_buffer[packet_data] = (False, dest_rIP, enforce) # (TCP Ident) : (Fin tracked, mapped dst) self._connection_buffer.move_to_end( packet_data, last=False) # move to the beginning
def get_hash(self, t, key, client_ip): """ :param t: t = T = Time Interval Value :param key: PSK :param client_ip: IP of the Client :return: Hash """ #Search in Buffer first InternalLogger.get().debug("Searching for hash in buffer") hash_int = self._hash_buffer.get((t, key, client_ip)) if hash_int is not None: InternalLogger.get().debug("Found hash in buffer") self._hash_buffer.move_to_end((t, key, client_ip), last=False) return hash_int # Generate InternalLogger.get().debug("Trying to generate hash") h = hashlib.blake2b(digest_size=2) # optimized for 64 bit h.update(bytes(t)) h.update(key.encode()) h.update(client_ip.encode()) hash_result = h.digest() hash_int = int.from_bytes(hash_result, byteorder='big', signed=False) # Save to buffer self._hash_buffer[(t, key, client_ip)] = hash_int self._hash_buffer.move_to_end((t, key, client_ip), last=False) # move to the beginning # Cleanup while (len(self._hash_buffer) > self._max_buffer): #remove first element(s) self._hash_buffer.popitem(last=True) return hash_int
def block_hf_shuffling(self): """ Check if HF Shuffling should be blocked :returns Boolean """ if self._continue_all: #Dont need to block return False active_ports = self._nas_connection_tracker.get_active_ports() block_value = 0 for port in active_ports: priority = self._priority_list.get(str(port)) if priority is None: InternalLogger.get().debug("No Priority found for port " + str(port)) else: priority_block_value = self._priority_definition.get(priority) if priority_block_value is None: InternalLogger.get().error( "No Priority definition found for " + str(priority)) else: if priority_block_value > block_value: block_value = priority_block_value InternalLogger.get().debug("Highest Priority Block Value: " + str(block_value)) block = self._shuffling_blocked_count < block_value if block: InternalLogger.get().debug("DynPort Blocking (count = " + str(self._shuffling_blocked_count) + ")") self._shuffling_blocked_count = self._shuffling_blocked_count + 1 else: InternalLogger.get().debug("DynPort NOT Blocking (count = " + str(self._shuffling_blocked_count) + ")") self._shuffling_blocked_count = 0 return block
def process_packet(self, packet): """ :param packet: IPv4 / IPv6 packet :return: forward? """ InternalLogger.get().debug("DNS Controller processing packet...") # .show() = all layer informations #Check if it has the DNSRR Layer if packet.haslayer(DNSRR): #Extract Data #resource IP rdata = packet[DNSRR].rdata #resource Name (Domain) rrname = packet[DNSRR].rrname dns_type = packet[DNSRR].type if self._mapping is not None: new_ip = self._mapping.get(rdata) if new_ip is not None: #vIP found in Mapping InternalLogger.get().debug( "DNS Response IP Replaced for " + str(rrname) + "; new = " + str(new_ip) + "; old = " + str(rdata)) #create new response and add it to the existing packet dns_response = DNSRR(rrname=rrname, rdata=new_ip, type=dns_type, ttl=self._ttl) packet[DNS].an = dns_response #change answer count packet[DNS].ancount = 1 else: InternalLogger.get().error("DNS Mapping is None") else: InternalLogger.get().error("No DNSRR Layer (Translator)") return True
def send_all_rest(self): """ Send the High Frequency mapping (total) to Receivers (REST endpoint of other gateways) if necessary """ try: for url in self._receiver: #Send mapping to url of receiver InternalLogger.get().debug("Sending Mapping to: " + url) #Create structure json_structure = {} #add new mapping json_structure["hf_added"] = self._hf_mapping #revoke old mapping json_structure["hf_revoked"] = self._hf_mapping_old json_mapping = json.dumps(json_structure) headers = {"Content-Type": "application/json"} #Send via HTTP r = requests.put(url, data=json_mapping, headers=headers) InternalLogger.get().debug("Status: " + str(r.status_code)) except Exception as e: InternalLogger.get().error("Error: " + str(e), exc_info=True)
def process_packet(self, packet): """ Forward the packet to the translator if necessary :param packet: IPv4/IPv6 Packet with TCP or UDP Payload :return: forward? """ #check if source or dst ip is in ph_subnet_server list is_not_in_sever_subnet = False for subnet in self._ph_subnet_server: netw = IPNetwork(subnet) if not (packet.dst in netw or packet.src in netw): is_not_in_sever_subnet = True if is_not_in_sever_subnet: InternalLogger.get().debug( "PH: Forwarding the incoming packet, not a connection to a MTD Host" ) #check if source or dst ip is in whitelist (for incoming and leaving packets) is_whitelist = False for whitelist_address in self._whitelist: netw = IPNetwork(whitelist_address) if packet.dst in netw or packet.src in netw: is_whitelist = True break if is_whitelist: InternalLogger.get().debug( "PH: Forwarding the incoming packet, no MTD Host and in whitelist" ) #check if destination is this host (local address) elif packet.dst in self._network_helper.local_addresses(): InternalLogger.get().debug( "PH: Accepting the incoming packet, destination = local address" ) else: #translate ports return self._translate(packet) return True
def _translate(self, packet): """ Translate ports :param packet: IPv4/IPv6 Packet with TCP or UDP Payload :return: forward? """ InternalLogger.get().debug("Trying to translate port...") #check if packet has TCP or UDP payload and extract it tcp_or_udp = None if packet.haslayer(TCP): tcp_or_udp = packet[TCP] if packet.haslayer(UDP): tcp_or_udp = packet[UDP] if tcp_or_udp is None: InternalLogger.get().error("ERROR: No TCP or UDP Layer found") return True #Internal Error? Forward Anyways new_port = None #Translate incoming packets if self._io == IO.INPUT: if self._client: #Gateway is part of the client network ip = packet.dst key = self._keymap.get(ip) if key is None: # No key, drop packet InternalLogger.get().debug("No key for " + ip) return False old_port = tcp_or_udp.sport new_port = self._ph_function.virtual_port_to_rport( old_port, ip, key) tcp_or_udp.sport = new_port else: # Gateway is part of the host network ip = packet.src key = self._keymap.get(ip) if key is None: # No key, drop packet InternalLogger.get().debug("No key for " + ip) return False old_port = tcp_or_udp.dport new_port = self._ph_function.virtual_port_to_rport( old_port, ip, key) tcp_or_udp.dport = new_port else: #Translate leaving packets if self._client: # Gateway is part of the client network ip = packet.src key = self._keymap.get(ip) if key is None: # No key, drop packet InternalLogger.get().debug("No key for " + ip) return False old_port = tcp_or_udp.dport new_port = self._ph_function.real_port_to_vport( old_port, ip, key) tcp_or_udp.dport = new_port else: # Gateway is part of the host network ip = packet.dst key = self._keymap.get(ip) if key is None: InternalLogger.get().debug("No key for " + ip) #No key, drop packet return False old_port = tcp_or_udp.sport new_port = self._ph_function.real_port_to_vport( old_port, ip, key) tcp_or_udp.sport = new_port if new_port is None: InternalLogger.get().error("Error no rPort found") return InternalLogger.get().debug("Old Port = " + str(old_port)) InternalLogger.get().debug("New Port = " + str(new_port)) return True
def put(self): """ HTTP Put Request """ try: InternalLogger.get().debug("Received mapping") #Check for json errors data = request.json if data is None: InternalLogger.get().debug("Error: No JSON Data") return if type(data) is not dict: InternalLogger.get().debug("Error: No Dictionary") return #Receive LF Data lf = data.get("lf") if lf is not None: InternalLogger.get().debug("-> lf mapping received") for controller in self._subnet_controller: controller.set_lf_mapping(lf) #Received new HF Data hf_added = data.get("hf_added") if hf_added is not None: InternalLogger.get().debug("-> hf_added mapping received") for controller in self._subnet_controller: controller.add_hf_mapping(hf_added) #Receive revoked HF Data hf_revoked = data.get("hf_revoked") if hf_revoked is not None: InternalLogger.get().debug("-> hf_revoked mapping received") for controller in self._subnet_controller: controller.revoke_hf_mapping(hf_revoked) lf_subnet = data.get("virtual_subnets") if lf_subnet is not None: for controller in self._subnet_controller: controller.set_hf_subnet(lf_subnet) except Exception as e: InternalLogger.get().debug("Error: " + str(e)) InternalLogger.get().debug(traceback.format_exc())
def check_buffer(self, packet, io): """ Search in NAS Track Buffer :param packet: IPv4 / IPv6 Packet :param io: Input/Output :return: (rIP or None if no rIP has been found, enforced) """ InternalLogger.get().debug("Searching for connection in buffer") if packet.haslayer(TCP): tcp = packet[TCP] if len(self._connection_buffer) > 0: #Check for incoming packets if io == IO.INPUT: ##WARNING: Use PH function to translate PORTS packet_data = (packet.src, tcp.sport, packet.dst, tcp.dport) InternalLogger.get().debug("Searching in Buffer for: " + str(packet_data)) with self._lock.gen_rlock(): result = self._connection_buffer.get(packet_data) if result is not None: (fin, ip, enforced) = result InternalLogger.get().debug("Found mapping in buffer") with self._lock.gen_wlock(): self._connection_buffer.move_to_end(packet_data, last=False) return (ip, enforced) else: InternalLogger.get().debug("Connection not found") else: #Check for leaving packet InternalLogger.get().debug("Searching in Buffer for: " + str(packet.src)) result_dst = None result_packet_data = None with self._lock.gen_rlock(): #check connections in order #old connections with similar tuple will not be used because of the order for packet_data, ( fin, r_ip, enforced) in self._connection_buffer.items(): (src, sport, dst, dport) = packet_data if src == packet.dst and dport == tcp.sport and sport == tcp.dport and r_ip == packet.src: InternalLogger.get().debug( "Found mapping in buffer (reverse)") result_packet_data = packet_data result_dst = (dst, enforced) break if result_packet_data is not None: with self._lock.gen_wlock(): #Check again if it has been deleted (protect against race conditions) if self._connection_buffer.get( packet_data) is not None: self._connection_buffer.move_to_end( result_packet_data, last=False) if result_dst is None: InternalLogger.get().debug( "Connection not found (reverse)") return result_dst return None
def recalculate_mapping(self): """ Recualculate mapping (rIP addresses) """ InternalLogger.get().info("--HF Controller recalculating mapping") new_mapping = {} if self._lf_mapping is not None: # Calculate new vIP for every rIP (ip) and the given subnet for ip, subnet in self._lf_mapping.items(): InternalLogger.get().debug("-Checking " + ip + ", subnet " + subnet) #create network of the subnet network = IPNetwork(subnet) #get network size total_count = network.size #select random vIP rand = secrets.randbelow(total_count) InternalLogger.get().debug( str(total_count) + " addresses possible") v_ip = str(network[rand]) InternalLogger.get().debug("New IP: " + str(v_ip)) #Set mapping new_mapping[v_ip] = ip else: InternalLogger.get().debug("Error: No LF Mapping") InternalLogger.get().debug("--HF Controller finished") InternalLogger.get().debug(new_mapping) #save old mapping and set new mapping self._hf_mapping_old = self._hf_mapping self._hf_mapping = new_mapping #send new mapping to other gatways (defined in nas/receiver) if necessary self.send_new_mapping()
def run(self): """ Run HFController in new thread Recalculate mappings (rIP addresses) regulary in a time interval (hopping period) """ try: while True: InternalLogger.get().debug("HF Controller starting") InternalLogger.get().debug( "--------------------------------------------------------------" ) if self._dynamic_port_priority.block_hf_shuffling(): InternalLogger.get().debug( "HF Recalculate Process blocked by DynPortPriority") else: self.recalculate_mapping() InternalLogger.get().debug("HF Controller stopping") InternalLogger.get().debug( "--------------------------------------------------------------" ) time.sleep(self._hopping_period) except KeyboardInterrupt as e: InternalLogger.get().debug(e) except Exception as e: InternalLogger.get().error("Error: " + str(e), exc_info=True)
def track_connection(self, packet, io): """ :param packet: IPv4 / IPv6 Packet :param io: Input/Output """ InternalLogger.get().debug("Trying to track connection") ''' called before (incoming) and after (outgoing) ph translations tracks connections with virtual ip addresses and real ports ''' if packet.haslayer(TCP): tcp = packet[TCP] packet_data = None if io == IO.INPUT: packet_data = (packet.src, tcp.sport, packet.dst, tcp.dport) else: packet_data = (packet.dst, tcp.dport, packet.src, tcp.sport) InternalLogger.get().debug("Tracking packet: " + str(packet_data)) if tcp.flags.S: #SYN has been received, Check if it a new connection result = None with self._lock.gen_rlock(): result = self._connection_buffer.get(packet_data) if result is None: InternalLogger.get().debug( "SYN received for the first time, trying to add mapping" ) new_ip = self._mapping.get(packet.dst) if new_ip is not None: with self._lock.gen_wlock(): self._connection_buffer[packet_data] = (False, new_ip, False) # (TCP Ident) : (Fin tracked, mapped dst) self._connection_buffer.move_to_end( packet_data, last=False) # move to the beginning self.clean_buffer() else: InternalLogger.get().debug( "No new rIP for connection in tracker") elif tcp.flags.F: #CFIN has been received, connection will close and receive one more ACK result = None with self._lock.gen_rlock(): result = self._connection_buffer.get(packet_data) if result is not None: (fin, ip, enforced) = result InternalLogger.get().debug( "FIN received for the first time, FIN = True") with self._lock.gen_wlock(): self._connection_buffer[packet_data] = (True, ip, enforced) elif tcp.flags.A: #Check if last ACK (after FIN) has been received result = None with self._lock.gen_rlock(): result = self._connection_buffer.get(packet_data) if result is not None: (fin, ip, enforced) = result if fin: InternalLogger.get().debug( "ACK received (Last Ack), deleting mapping") with self._lock.gen_wlock(): self._connection_buffer.pop(packet_data)
def process_packet(self, packet): """ :param packet: IPv4 /Ipv6 Packet :return: Forward? """ #manipulate incoming packet if self._io == IO.INPUT: if self._mapping is not None: new_ip = self._mapping.get(packet.dst) #vIP found in Mapping if new_ip is not None: packet.dst = new_ip InternalLogger.get().debug("DST changed to " + new_ip + "(from mapping)") else: #no vIP found in mapping is_whitelist = False #search in whitelist for whitelist_address in self._whitelist: if packet.dst in IPNetwork(whitelist_address): is_whitelist = True break if is_whitelist: InternalLogger.get().debug( "IP-NAS: Forwarding the incoming packet, " "whitelist") return True #search in local addresses (should it be forwarded to this host internally?) elif packet.dst in self._network_helper.local_addresses(): InternalLogger.get().debug( "IP-NAS: Accepting the incoming packet, destination = local address" ) return True #search for vIP in Connection Tracker InternalLogger.get().debug( "No mapping, searching tracker buffer") new_ip_tracked = None if self._track: new_ip_tracked = self.check_buffer(packet) else: InternalLogger.get().debug( "WARNING: Tried to reach MT Area, DROPPED") if new_ip_tracked is not None: #vIP found packet.dst = new_ip_tracked else: #Send to honeypot? if self._honeypot and packet.haslayer(TCP): vsubnet = False #check if destination is part of the virtual subnet if self._virtual_subnets is not None: for subnet in self._virtual_subnets: if packet.dst in IPNetwork(subnet): vsubnet = True break else: InternalLogger.get().error( "No virtual subnets") if vsubnet: #dst is in vSubnet, set honeypot new_ip_honeypot = None if IPAddress(packet.dst).version == 4: new_ip_honeypot = self._honey_v4 else: new_ip_honeypot = self._honey_v6 if new_ip_honeypot is not None: #add to connection tracking: tcp = packet[TCP] self._nas_tracker.add_connection( packet.src, tcp.sport, packet.dst, tcp.dport, new_ip_honeypot, True) packet.dst = new_ip_honeypot InternalLogger.get().debug( "WARNING: Tried to reach MT Area, forwarded to HONEYPOT (" + new_ip_honeypot + ")") return True else: InternalLogger.get().error( "No HoneyPot Address") return False else: InternalLogger.get().debug( "WARNING: Tried to reach MT Area, DROPPED (Not in Virtual Subnet, Honeypot not used)" ) else: #vIP not found InternalLogger.get().debug( "WARNING: Tried to reach MT Area, DROPPED") return False else: InternalLogger.get().critical("ERROR: No mapping") # manipulate leaving packet else: #look for existing mapping in TRACKER first (to ignore mapping for internal rIP if the connection is still being tracked) new_ip_tracked = None if self._track: new_ip_tracked = self.check_buffer(packet) if new_ip_tracked is not None: packet.src = new_ip_tracked InternalLogger.get().debug("SRC changed to " + new_ip_tracked + " (from buffer)") #not in tracking, search in mapping else: new_ip = self._mapping.get(packet.src) if new_ip is not None: packet.src = new_ip InternalLogger.get().debug("SRC changed to " + new_ip + "(from mapping)") else: InternalLogger.get().debug( "Forwarding the leaving packet, SRC != MTD Host") return True
def handle_packet(self, pkt): """ Forward packets to layer controllers and trackers :param pkt: Raw Packet """ try: InternalLogger.get().debug("---Detected packet (" + str(pkt) + "),\t queue_num=" + str(self._queue_num)) data = pkt.payload # Detect v4/v6 and load as IP object ip_packet = None try: ip_packet = IPv6(data) ip_version = 6 except Exception as e: InternalLogger.get().debug("Exception in IPv6 Packet, trying IPv4") if ip_packet is None or ip_packet.version == 4: ip_packet = IP(data) ip_version = 4 # Output data InternalLogger.get().debug("--Source: " + ip_packet.src + "\tDest: " + ip_packet.dst + "\tIPv" + str(ip_version)) if self._debug_direct_forward: #Directly forward InternalLogger.get().debug("DEBUG: Forwarding") pkt.mangle() else: InternalLogger.get().debug("Checking layers") forward = self.check_layers(ip_packet) #check if the packet should be forwarded to the network stack (Attention: internal ip routes are responsible to forward it) if forward: InternalLogger.get().debug("Recalculating checksums and length") self.recalculate_checksums(ip_packet, ip_version) InternalLogger.get().debug("Sending packet") #Redirect packet to network stack pkt.payload = raw(ip_packet) pkt.mangle() else: InternalLogger.get().debug("Dropped") #Dont forward to localhost or another host, drop pkt.drop() except Exception as e: InternalLogger.get().critical("Error: " + str(e), exc_info=True)
def main(): """ COMPOSITION ROOT of the MTG / MTPG Load Configuration, start and configure PH/NAS components """ conf_data = None with open('conf.json') as json_file: conf_data = json.load(json_file) whitelist = conf_data["whitelist"] enable_file_logging = conf_data["file_logging"] enable_debug_output = conf_data["debug_output"] InternalLogger.init(enable_file_logging, enable_debug_output) InternalLogger.get().info("Starting...") debug_forward = conf_data["debug_forward"] conf_data_nas = conf_data["nas"] conf_data_ph = conf_data["ph"] enable_nas = conf_data_nas["activate"] enable_ph = conf_data_ph["activate"] layer_controller_out = {} layer_controller_in = {} ip_translators = None dynamic_port_priority = None # Enable Network Address Shuffling if enable_nas: conf_data_nas = conf_data["nas"] InternalLogger.get().info("Starting NAS") dns_ttl = conf_data_nas["dns_ttl"] # Set Controllers dns = DnsTranslator(None, dns_ttl) conf_data_nas_tracking_honeypot = conf_data_nas["honeypot"] honeypot = conf_data_nas_tracking_honeypot["activate"] tracker = None conf_data_nas_tracking = conf_data_nas["tracking"] enable_nas_track = conf_data_nas_tracking["activate"] if enable_nas_track: #Enable Tracking tracker = NasConnectionTracker() layer_controller_out[70] = tracker layer_controller_in[30] = tracker #Enable Dynamic Port Priority conf_data_nas_tracking_priority = conf_data_nas_tracking[ "dynamic_port_priority"] continue_list = conf_data_nas_tracking_priority["continue"] priority_list = conf_data_nas_tracking_priority["priority"] priority_def_list = conf_data_nas_tracking_priority["priority_def"] continue_all = conf_data_nas_tracking["continue_all"] dynamic_port_priority = DynamicPortPriority( continue_list, priority_list, priority_def_list, continue_all, tracker) ip_out = IPTranslatorNAS(None, whitelist, IO.OUTPUT, enable_nas_track, tracker, dynamic_port_priority) ip_in = IPTranslatorNAS(None, whitelist, IO.INPUT, enable_nas_track, tracker, dynamic_port_priority) honeypot_v4_address = None honeypot_v6_address = None if honeypot: honeypot_v4_address = conf_data_nas_tracking_honeypot["v4_address"] honeypot_v6_address = conf_data_nas_tracking_honeypot["v6_address"] if honeypot_v6_address is None or honeypot_v4_address is None: InternalLogger.error("Honeypot address not set") return ip_in.set_honeypot(honeypot_v4_address, honeypot_v6_address) ip_out.set_honeypot(honeypot_v4_address, honeypot_v6_address) layer_controller_out[51] = dns layer_controller_out[50] = ip_out layer_controller_in[50] = ip_in ip_translators = [dns, ip_out, ip_in] # Enable PortHopping if enable_ph: InternalLogger.get().info("Starting PH") # Set Controllers enable_ph_client = conf_data_ph["client"] max_buffer = conf_data_ph["max_buffer"] hopping_period = conf_data_ph["hopping_period"] ph_function = RpahFunction(hopping_period, max_buffer) keymap = conf_data_ph["keymap"] subnets_server = conf_data_ph["ph_subnets_server"] #tracker needs to use ph function to preserve tracking # ph_function = TestPhFunction() ph_out = PortTranslatorPh(ph_function, IO.OUTPUT, whitelist, enable_ph_client, keymap, subnets_server) layer_controller_out[100] = ph_out ph_in = PortTranslatorPh(ph_function, IO.INPUT, whitelist, enable_ph_client, keymap, subnets_server) layer_controller_in[10] = ph_in if not (enable_nas or enable_ph): InternalLogger.get().warning("WARNING: PH and NAS not activated") incoming_data = IpController(1, layer_controller_in, debug_forward, IO.INPUT) incoming_data.start() leaving_data = IpController(2, layer_controller_out, debug_forward, IO.OUTPUT) leaving_data.start() if enable_nas: # Start HF Controller if ip_translators is None: InternalLogger.get().debug("WARNING: No Translators") hf_receiver = conf_data_nas["receiver"] hopping_period = conf_data_nas["hopping_period"] controller = HfController(ip_translators, hf_receiver, hopping_period, dynamic_port_priority) controller.set_lf_mapping(None) controller.start() subnetmapping_receiver = [controller] rest_local = conf_data_nas["rest_iface"] InternalLogger.get().info("Starting rest at: " + rest_local) # Start Rest API api = Api(app) api.add_resource(LfMappingApi, '/v1.0/nas_mapping', endpoint='nas_mapping', resource_class_kwargs={ 'subnet_controller': subnetmapping_receiver }) Thread.start(run_flask(rest_local))