def _dnat_rules(zone, action, form): error = None fields = SimpleNamespace(**form) if (action == 'remove'): try: # NOTE: validation needs to know the zone so it can ensure the position is valid validate.del_nat_rule(fields) except ValidationError as ve: error = ve else: with IPTableManager() as iptables: iptables.delete_nat(fields) elif (action == 'add'): try: validate.add_dnat_rule(fields) if (fields.protocol in ['tcp', 'udp']): validate.network_port(fields.dst_port) validate.network_port(fields.host_port) validate.ip_address(fields.host_ip) except ValidationError as ve: error = ve else: with IPTableManager() as iptables: iptables.add_nat(fields) configure.add_open_wan_protocol(fields) else: return INVALID_FORM, zone return error, zone
def _snat_rules(zone, action, form): error = None print(333333, form) fields = SimpleNamespace(**form) # TODO: make this code for snat (currently using dnat code as template) if (action == 'remove'): try: # NOTE: validation needs to know the zone so it can ensure the position is valid validate.del_nat_rule(fields) except ValidationError as ve: error = ve else: with IPTableManager() as iptables: iptables.delete_nat(fields) elif (action == 'add'): try: validate.add_snat_rule(fields) validate.ip_address( ip_iter=[fields.orig_src_ip, fields.new_src_ip]) except ValidationError as ve: error = ve else: with IPTableManager() as iptables: iptables.add_nat(fields) else: return INVALID_FORM, zone return error, zone
def _ddos_inspect(self, packet): ddos = self.ddos_tracker[packet.protocol] with ddos.lock: if not self._ddos_detected(ddos.tracker, packet): return if (self._IPS.ids_mode): Log.log(packet, IPS.LOGGED, engine=IPS.DDOS) elif (self._IPS.ddos_prevention): IPTableManager.proxy_add_rule(packet.conn.tracked_ip, table='mangle', chain='IPS') Log.log(packet, IPS.FILTERED, engine=IPS.DDOS)
def _firewall_rules(zone, action, form): error = None # moving form data into a simple namespace. this will allow us to validate and mutate it easier # that its current state of immutable dict. print(form) fields = SimpleNamespace(**form) if (action == 'remove'): try: # NOTE: validation needs to know the zone so it can ensure the position is valid validate.del_firewall_rule(fields) except ValidationError as ve: error = ve else: with IPTableManager() as iptables: iptables.delete_rule(fields) elif (action =='add'): if not all([x in form for x in valid_standard_rule_fields]): return INVALID_FORM, zone fields.action = 'ACCEPT' if 'accept' in form else 'DROP' try: validate.add_firewall_rule(fields) if (fields.dst_port): validate.network_port(fields.dst_port) if (fields.src_ip): validate.ip_address(fields.src_ip) validate.cidr(fields.src_netmask) validate.ip_address(fields.dst_ip) validate.cidr(fields.dst_netmask) except ValidationError as ve: error = ve else: if (not fields.src_ip): fields.src_ip, fields.src_netmask = '0', '0' with IPTableManager() as iptables: iptables.add_rule(fields) elif ('change_interface' not in form): return INVALID_FORM, zone return error, zone
def _ddos_inspect(self): ddos = self.ddos_tracker.get(self._packet.protocol) with ddos['lock']: if not self._ddos_detected(ddos['tracker']): return # this is to supress log entries for ddos hosts that are being detected by the engine, but not blocked # this behavior would only happen in informational logging mode without block enabled. if self._recently_detected(self._packet.conn.tracked_ip): return if (self._IPS.ddos_prevention): IPTableManager.proxy_add_rule(self._packet.conn.tracked_ip, table='mangle', chain='IPS') # TODO: add entry for ids mode Log.log(self._packet, engine=IPS.DDOS)
def _clear_ip_tables(self): # quick check to see if any firewall rules exist if not self.IPS.firewall_rules: return firewall_rules = self.IPS.firewall_rules block_length = self.IPS.block_length now = fast_time() with IPTableManager() as iptables: for tracked_ip, insert_time in list(firewall_rules.items()): if (now - insert_time > block_length) and firewall_rules.pop( tracked_ip, None): iptables.proxy_del_rule(tracked_ip, table='mangle', chain='IPS')
def _clear_ip_tables(self): ips_to_remove = [] if (self.IPS.active_ddos or not self.IPS.ddos_prevention): return ONE_MIN now = time.time() for tracked_ip, rule_info in self.IPS.fw_rules.items(): time_added = rule_info['timestamp'] if (now - time_added < self.IPS.block_length): continue ips_to_remove.append(tracked_ip) if (not ips_to_remove): return FIVE_MIN with IPTableManager() as iptables: for tracked_ip in ips_to_remove: if not self.IPS.fw_rules.pop(tracked_ip, None): continue iptables.proxy_del_rule(tracked_ip, table='mangle', chain='IPS') return FIVE_MIN
def _clear_ip_tables(self): IPS = self.IPS if (not IPS.fw_rules): return ONE_MIN now, ips_to_remove = fast_time(), [] for tracked_ip, insert_time in IPS.fw_rules.items(): if (now - insert_time > IPS.block_length): ips_to_remove.append(tracked_ip) if (not ips_to_remove): return FIVE_MIN with IPTableManager() as iptables: for tracked_ip in ips_to_remove: # NOTE: if the system is configured in IDS mode when the rule was created, an active rule would not have # be inserted into the system. this will still run, but effectively do nothing. maybe we can figure out # a way to identify the type of rule in the data set. remember that there could be some thread safety # concerns when dealing with this issue so make sure solution is well thought out. if IPS.fw_rules.pop(tracked_ip, None): iptables.proxy_del_rule(tracked_ip, table='mangle', chain='IPS') return FIVE_MIN
def _manage_ip_tables(self): IPTableManager.purge_proxy_rules(table='mangle', chain='IPS')
def _manage_ip_tables(self): IPTableManager.clear_dns_over_https() IPTableManager.update_dns_over_https()
def configure_ipv6_iptables(self): IPTables.block_ipv6()
def apply_network_forwarding(self): IPTables.network_forwarding()
def update_page(form): if ('fw_remove' in form): fw_rule = form.get('fw_remove', None) chain = 'FIREWALL' if (not fw_rule): return INVALID_FORM try: validate.del_firewall_rule(fw_rule, chain) except ValidationError as ve: return ve else: with IPTableManager() as iptables: iptables.delete_rule(fw_rule, chain='FIREWALL') elif ('fw_add' in form): pos = form.get('position', None) dst_ip = form.get('dst_ip', None) dst_netmask = form.get('dst_netmask', None) src_ip = form.get('src_ip', None) src_netmask = form.get('src_netmask', None) protocol = form.get('protocol', None) dst_port = form.get('dst_port', False) if (dst_port == ''): dst_port = None if (src_ip == ''): src_ip = '0' src_netmask = '0' if ('accept' in form): action = 'ACCEPT' else: action = 'DROP' iptable_rule = { 'pos': pos, 'src_ip': src_ip, 'src_netmask': src_netmask, 'dst_ip': dst_ip, 'dst_netmask': dst_netmask, 'dst_port': dst_port, 'protocol': protocol, 'action': action } # TODO: make this less compiticated? if (pos and dst_ip and dst_netmask and src_ip and src_netmask and protocol and dst_port is not False): try: validate.add_firewall_rule(iptable_rule) if (dst_port != None): validate.network_port(dst_port) if (src_ip != '0'): validate.ip_address(src_ip) validate.cidr(src_netmask) validate.cidr(dst_netmask) validate.ip_address(dst_ip) with IPTableManager() as iptables: iptables.add_rule(iptable_rule) except ValidationError as ve: return ve else: return INVALID_FORM elif ('nat_remove' in form): nat_rule = form.get('nat_remove', None) if (not nat_rule): return INVALID_FORM try: validate.del_firewall_rule(nat_rule, chain='NAT') except ValidationError as ve: return ve else: configure.del_open_wan_protocol(nat_rule) with IPTableManager() as iptables: iptables.delete_nat(nat_rule) elif ('nat_add' in form): host_ip = form.get('host_ip', None) protocol = form.get('protocol', None) if (protocol in ['tcp', 'udp']): dst_port = form.get('dst_port') host_port = form.get('host_port') elif (protocol in ['icmp']): dst_port = None host_port = None open_protocols = load_configuration('ips.json') icmp_allow = open_protocols['ips']['open_protocols']['icmp'] if (icmp_allow): return 'Only one ICMP rule can be active at a time. Remove existing rule before adding another.' else: return INVALID_FORM try: if (protocol in ['tcp', 'udp']): validate.network_port(dst_port) validate.network_port(host_port) validate.ip_address(host_ip) except ValidationError as ve: return ve else: with IPTableManager() as iptables: iptables.add_nat(protocol, dst_port, host_ip, host_port) configure.add_open_wan_protocol(protocol, dst_port, host_port) else: return INVALID_FORM