def initChain(): # Is called before threads start, no locking print("Initializing mailcow netfilter chain") # IPv4 if not iptc.Chain(iptc.Table(iptc.Table.FILTER), "MAILCOW") in iptc.Table(iptc.Table.FILTER).chains: iptc.Table(iptc.Table.FILTER).create_chain("MAILCOW") for c in ['FORWARD', 'INPUT']: chain = iptc.Chain(iptc.Table(iptc.Table.FILTER), c) rule = iptc.Rule() rule.src = '0.0.0.0/0' rule.dst = '0.0.0.0/0' target = iptc.Target(rule, "MAILCOW") rule.target = target if rule not in chain.rules: chain.insert_rule(rule) # IPv6 if not iptc.Chain(iptc.Table6(iptc.Table6.FILTER), "MAILCOW") in iptc.Table6(iptc.Table6.FILTER).chains: iptc.Table6(iptc.Table6.FILTER).create_chain("MAILCOW") for c in ['FORWARD', 'INPUT']: chain = iptc.Chain(iptc.Table6(iptc.Table6.FILTER), c) rule = iptc.Rule6() rule.src = '::/0' rule.dst = '::/0' target = iptc.Target(rule, "MAILCOW") rule.target = target if rule not in chain.rules: chain.insert_rule(rule)
def set_chain_policy(self, policy_state): """ set input/output chain policy """ accept_policy = iptc.Policy('ACCEPT') drop_policy = iptc.Policy('DROP') #v4 policy input_chain = iptc.Chain(iptc.Table(iptc.Table.FILTER), 'INPUT') output_chain = iptc.Chain(iptc.Table(iptc.Table.FILTER), 'OUTPUT') if policy_state.lower() == JSON_RULE_NETWORK_ACCEPT \ or policy_state.lower() == JSON_RULE_ALLOW: input_chain.set_policy(accept_policy) output_chain.set_policy(accept_policy) else: input_chain.set_policy(drop_policy) output_chain.set_policy(drop_policy) #v6 policy input_chain6 = iptc.Chain(iptc.Table6(iptc.Table6.FILTER), 'INPUT') output_chain6 = iptc.Chain(iptc.Table6(iptc.Table6.FILTER), 'OUTPUT') if policy_state.lower() == JSON_RULE_NETWORK_ACCEPT \ or policy_state.lower() == JSON_RULE_ALLOW: input_chain6.set_policy(accept_policy) output_chain6.set_policy(accept_policy) else: input_chain6.set_policy(drop_policy) output_chain6.set_policy(drop_policy)
def insert_rule(self, rule, direction, ip, protocol): """ insert rule """ #domain to ip resolved_list = [] it = self.ip_type(ip) if it == 'domain': resolved_list = self.dns_resolver(ip) else: resolved_list.append(ip) self.logger.debug('resolved_list={}'.format(resolved_list)) #chains input_chain = output_chain = None if it == 'v6': input_chain = iptc.Chain(iptc.Table6(iptc.Table6.FILTER), 'INPUT') output_chain = iptc.Chain(iptc.Table6(iptc.Table6.FILTER), 'OUTPUT') else: input_chain = iptc.Chain(iptc.Table(iptc.Table.FILTER), 'INPUT') output_chain = iptc.Chain(iptc.Table(iptc.Table.FILTER), 'OUTPUT') for resolved in resolved_list: if direction == JSON_RULE_NETWORK_INBOUND: rule.src = resolved self._insert_rule_with_log(input_chain, rule) elif direction == JSON_RULE_NETWORK_OUTBOUND: rule.dst = resolved self._insert_rule_with_log(output_chain, rule) else: rule.src = resolved self._insert_rule_with_log(input_chain, rule) rule.dst = resolved self._insert_rule_with_log(output_chain, rule)
def unblock(ip=None): if ip == None: iptc.Chain(iptc.Table(iptc.Table.FILTER), INPUT).flush() iptc.Chain(iptc.Table(iptc.Table.FILTER), OUTPUT).flush() iptc.Chain(iptc.Table(iptc.Table.FILTER), FORWARD).flush() iptc.Chain(iptc.Table6(iptc.Table6.FILTER), INPUT).flush() iptc.Chain(iptc.Table6(iptc.Table6.FILTER), OUTPUT).flush() iptc.Chain(iptc.Table6(iptc.Table6.FILTER), FORWARD).flush() else: try: src = ipaddress.ip_address(ip) if src.version == IPv4: table = iptc.Table(iptc.Table.FILTER) elif src.version == IPv6: table = iptc.Table6(iptc.Table6.FILTER) for chain in table.chains: for rule in chain.rules: if ipaddress.ip_address( rule.src.split('/')[0]) == src.explode: __logger.debug("Un-Block IP %s", rule.src) chain.delete_rule(rule) except ValueError: __logger.error('Invalid source ip address to block') __logger.warning("Block IP %s", newRule.src)
def initChain(): # Is called before threads start, no locking print "Initializing mailcow netfilter chain" # IPv4 if not iptc.Chain(iptc.Table(iptc.Table.FILTER), "MAILCOW") in iptc.Table(iptc.Table.FILTER).chains: iptc.Table(iptc.Table.FILTER).create_chain("MAILCOW") for c in ['FORWARD', 'INPUT']: chain = iptc.Chain(iptc.Table(iptc.Table.FILTER), c) rule = iptc.Rule() rule.src = '0.0.0.0/0' rule.dst = '0.0.0.0/0' target = iptc.Target(rule, "MAILCOW") rule.target = target if rule not in chain.rules: chain.insert_rule(rule) # IPv6 if not iptc.Chain(iptc.Table6(iptc.Table6.FILTER), "MAILCOW") in iptc.Table6(iptc.Table6.FILTER).chains: iptc.Table6(iptc.Table6.FILTER).create_chain("MAILCOW") for c in ['FORWARD', 'INPUT']: chain = iptc.Chain(iptc.Table6(iptc.Table6.FILTER), c) rule = iptc.Rule6() rule.src = '::/0' rule.dst = '::/0' target = iptc.Target(rule, "MAILCOW") rule.target = target if rule not in chain.rules: chain.insert_rule(rule) # Apply blacklist BLACKLIST = r.hgetall('F2B_BLACKLIST') if BLACKLIST: for bl_key in BLACKLIST: if type(ipaddress.ip_network(bl_key.decode('ascii'), strict=False)) is ipaddress.IPv4Network: chain = iptc.Chain(iptc.Table(iptc.Table.FILTER), 'MAILCOW') rule = iptc.Rule() rule.src = bl_key target = iptc.Target(rule, "REJECT") rule.target = target if rule not in chain.rules: log['time'] = int(round(time.time())) log['priority'] = 'crit' log['message'] = 'Blacklisting host/network %s' % bl_key r.lpush('NETFILTER_LOG', json.dumps(log, ensure_ascii=False)) print log['message'] chain.insert_rule(rule) r.hset('F2B_PERM_BANS', '%s' % bl_key, int(round(time.time()))) else: chain = iptc.Chain(iptc.Table6(iptc.Table6.FILTER), 'MAILCOW') rule = iptc.Rule6() rule.src = bl_key target = iptc.Target(rule, "REJECT") rule.target = target if rule not in chain.rules: log['time'] = int(round(time.time())) log['priority'] = 'crit' log['message'] = 'Blacklisting host/network %s' % bl_key r.lpush('NETFILTER_LOG', json.dumps(log, ensure_ascii=False)) print log['message'] chain.insert_rule(rule) r.hset('F2B_PERM_BANS', '%s' % bl_key, int(round(time.time())))
def clear_rules(self): if self.cleared: return self._lock.acquire() try: if settings.vpn.lib_iptables and LIB_IPTABLES: tables = { 'nat': iptc.Table(iptc.Table.NAT), 'nat6': iptc.Table6(iptc.Table.NAT), 'filter': iptc.Table(iptc.Table.FILTER), 'filter6': iptc.Table6(iptc.Table.FILTER), } else: tables = None # TODO # tables['nat'].autocommit = False # tables['nat6'].autocommit = False # tables['filter'].autocommit = False # tables['filter6'].autocommit = False self.cleared = True for rule in self._accept + self._other: self._remove_iptables_rule(rule, tables=tables) if self.ipv6: for rule in self._accept6 + self._other6: self._remove_iptables_rule(rule, ipv6=True, tables=tables) if self.restrict_routes: for rule in self._drop: self._remove_iptables_rule(rule, tables=tables) if self.ipv6: for rule in self._drop6: self._remove_iptables_rule(rule, ipv6=True, tables=tables) self._accept = None self._accept6 = None self._other = None self._other6 = None self._drop = None self._drop6 = None # tables['nat'].commit() # tables['nat6'].commit() # tables['filter'].commit() # tables['filter6'].commit() finally: self._lock.release()
def initChain(): print "Initializing mailcow netfilter chain" # IPv4 if not iptc.Chain(iptc.Table(iptc.Table.FILTER), "MAILCOW") in iptc.Table( iptc.Table.FILTER).chains: iptc.Table(iptc.Table.FILTER).create_chain("MAILCOW") for c in ['FORWARD', 'INPUT']: chain = iptc.Chain(iptc.Table(iptc.Table.FILTER), c) rule = iptc.Rule() rule.src = '0.0.0.0/0' rule.dst = '0.0.0.0/0' target = iptc.Target(rule, "MAILCOW") rule.target = target if rule not in chain.rules: chain.insert_rule(rule) # IPv6 if not iptc.Chain(iptc.Table6(iptc.Table6.FILTER), "MAILCOW") in iptc.Table6(iptc.Table6.FILTER).chains: iptc.Table6(iptc.Table6.FILTER).create_chain("MAILCOW") for c in ['FORWARD', 'INPUT']: chain = iptc.Chain(iptc.Table6(iptc.Table6.FILTER), c) rule = iptc.Rule6() rule.src = '::/0' rule.dst = '::/0' target = iptc.Target(rule, "MAILCOW") rule.target = target if rule not in chain.rules: chain.insert_rule(rule) # Apply blacklist BLACKLIST = r.hgetall('F2B_BLACKLIST') if BLACKLIST: for bl_key in BLACKLIST: if type(ipaddress.ip_network( bl_key.decode('ascii'), strict=False)) is ipaddress.IPv4Network: chain = iptc.Chain(iptc.Table(iptc.Table.FILTER), 'MAILCOW') rule = iptc.Rule() rule.src = bl_key target = iptc.Target(rule, "REJECT") rule.target = target if rule not in chain.rules: chain.insert_rule(rule) else: chain = iptc.Chain(iptc.Table6(iptc.Table6.FILTER), 'MAILCOW') rule = iptc.Rule6() rule.src = bl_key target = iptc.Target(rule, "REJECT") rule.target = target if rule not in chain.rules: chain.insert_rule(rule)
def unban(net): log['time'] = int(round(time.time())) log['priority'] = 'info' r.lpush('NETFILTER_LOG', json.dumps(log, ensure_ascii=False)) if not net in bans: log['message'] = '%s is not banned, skipping unban and deleting from queue (if any)' % net r.lpush('NETFILTER_LOG', json.dumps(log, ensure_ascii=False)) print '%s is not banned, skipping unban and deleting from queue (if any)' % net r.hdel('F2B_QUEUE_UNBAN', '%s' % net) return log['message'] = 'Unbanning %s' % net r.lpush('NETFILTER_LOG', json.dumps(log, ensure_ascii=False)) print 'Unbanning %s' % net if type(ipaddress.ip_network( net.decode('ascii'))) is ipaddress.IPv4Network: chain = iptc.Chain(iptc.Table(iptc.Table.FILTER), 'MAILCOW') rule = iptc.Rule() rule.src = net target = iptc.Target(rule, "REJECT") rule.target = target if rule in chain.rules: chain.delete_rule(rule) else: chain = iptc.Chain(iptc.Table6(iptc.Table6.FILTER), 'MAILCOW') rule = iptc.Rule6() rule.src = net target = iptc.Target(rule, "REJECT") rule.target = target if rule in chain.rules: chain.delete_rule(rule) r.hdel('F2B_ACTIVE_BANS', '%s' % net) r.hdel('F2B_QUEUE_UNBAN', '%s' % net) if net in bans: del bans[net]
def permBan(net, unban=False): global lock if type(ipaddress.ip_network(net, strict=False)) is ipaddress.IPv4Network: with lock: chain = iptc.Chain(iptc.Table(iptc.Table.FILTER), 'MAILCOW') rule = iptc.Rule() rule.src = net target = iptc.Target(rule, "REJECT") rule.target = target if rule not in chain.rules and not unban: logCrit('Add host/network %s to blacklist' % net) chain.insert_rule(rule) r.hset('F2B_PERM_BANS', '%s' % net, int(round(time.time()))) elif rule in chain.rules and unban: logCrit('Remove host/network %s from blacklist' % net) chain.delete_rule(rule) r.hdel('F2B_PERM_BANS', '%s' % net) else: with lock: chain = iptc.Chain(iptc.Table6(iptc.Table6.FILTER), 'MAILCOW') rule = iptc.Rule6() rule.src = net target = iptc.Target(rule, "REJECT") rule.target = target if rule not in chain.rules and not unban: logCrit('Add host/network %s to blacklist' % net) chain.insert_rule(rule) r.hset('F2B_PERM_BANS', '%s' % net, int(round(time.time()))) elif rule in chain.rules and unban: logCrit('Remove host/network %s from blacklist' % net) chain.delete_rule(rule) r.hdel('F2B_PERM_BANS', '%s' % net)
def flush_chain(self): """ flush input/output chain """ #v4 flush input_chain = iptc.Chain(iptc.Table(iptc.Table.FILTER), 'INPUT') output_chain = iptc.Chain(iptc.Table(iptc.Table.FILTER), 'OUTPUT') input_chain.flush() output_chain.flush() #v6 flush input_chain6 = iptc.Chain(iptc.Table6(iptc.Table6.FILTER), 'INPUT') output_chain6 = iptc.Chain(iptc.Table6(iptc.Table6.FILTER), 'OUTPUT') input_chain6.flush() output_chain6.flush()
def _iptc_gettable(table, ipv6=False): """ Return an updated view of an iptc_table """ iptc_table = iptc.Table6(table) if ipv6 else iptc.Table(table) if MODE_BATCH is False: iptc_table.commit() iptc_table.refresh() return iptc_table
def clear(): global lock log['time'] = int(round(time.time())) log['priority'] = 'info' log['message'] = 'Clearing all bans' r.lpush('NETFILTER_LOG', json.dumps(log, ensure_ascii=False)) print 'Clearing all bans' for net in bans.copy(): unban(net) with lock: filter4_table = iptc.Table(iptc.Table.FILTER) filter6_table = iptc.Table6(iptc.Table6.FILTER) for filter_table in [filter4_table, filter6_table]: filter_table.autocommit = False forward_chain = iptc.Chain(filter_table, "FORWARD") input_chain = iptc.Chain(filter_table, "INPUT") mailcow_chain = iptc.Chain(filter_table, "MAILCOW") if mailcow_chain in filter_table.chains: for rule in mailcow_chain.rules: mailcow_chain.delete_rule(rule) for rule in forward_chain.rules: if rule.target.name == 'MAILCOW': forward_chain.delete_rule(rule) for rule in input_chain.rules: if rule.target.name == 'MAILCOW': input_chain.delete_rule(rule) filter_table.delete_chain("MAILCOW") filter_table.commit() filter_table.refresh() filter_table.autocommit = True r.delete('F2B_ACTIVE_BANS') r.delete('F2B_PERM_BANS') pubsub.unsubscribe()
def snat6(snat_target): global lock global quit_now def get_snat6_rule(): rule = iptc.Rule6() rule.src = os.getenv('IPV6_NETWORK', 'fd4d:6169:6c63:6f77::/64') rule.dst = '!' + rule.src target = rule.create_target("SNAT") target.to_source = snat_target return rule while not quit_now: time.sleep(10) with lock: try: table = iptc.Table6('nat') table.refresh() chain = iptc.Chain(table, 'POSTROUTING') table.autocommit = False if get_snat6_rule() not in chain.rules: logInfo('Added POSTROUTING rule for source network %s to SNAT target %s' % (get_snat6_rule().src, snat_target)) chain.insert_rule(get_snat6_rule()) table.commit() else: for position, item in enumerate(chain.rules): if item == get_snat6_rule(): if position != 0: chain.delete_rule(get_snat6_rule()) table.commit() table.autocommit = True except: print('Error running SNAT6, retrying...')
def mailcowChainOrder(): global lock global quit_now global exit_code while not quit_now: time.sleep(10) with lock: filter4_table = iptc.Table(iptc.Table.FILTER) filter6_table = iptc.Table6(iptc.Table6.FILTER) filter4_table.refresh() filter6_table.refresh() for f in [filter4_table, filter6_table]: forward_chain = iptc.Chain(f, 'FORWARD') input_chain = iptc.Chain(f, 'INPUT') for chain in [forward_chain, input_chain]: target_found = False for position, item in enumerate(chain.rules): if item.target.name == 'MAILCOW': target_found = True if position > 2: logCrit('Error in %s chain order: MAILCOW on position %d, restarting container' % (chain.name, position)) quit_now = True exit_code = 2 if not target_found: logCrit('Error in %s chain: MAILCOW target not found, restarting container' % (chain.name)) quit_now = True exit_code = 2
def update_iptables(table, chain, rules): """ Delete all rules marked by WOTT_COMMENT. Then insert new rules from the supplied list. :param table: table name :param chain: chain name :param rules: a list of rules in iptc.easy format :return: None """ tbl4 = iptc.Table(table) tbl6 = iptc.Table6(table) for t in (tbl4, tbl6): t.autocommit = False ch = iptc.Chain(t, chain) for r in ch.rules: for m in r.matches: if m.comment == WOTT_COMMENT: ch.delete_rule(r) break for r, ipv6 in rules: iptc_helper.add_rule(table, chain, r, ipv6=ipv6) for t in (tbl4, tbl6): t.commit() t.refresh() t.autocommit = True
def unban(net): global lock if not net in bans: logInfo('%s is not banned, skipping unban and deleting from queue (if any)' % net) r.hdel('F2B_QUEUE_UNBAN', '%s' % net) return logInfo('Unbanning %s' % net) if type(ipaddress.ip_network(net)) is ipaddress.IPv4Network: with lock: chain = iptc.Chain(iptc.Table(iptc.Table.FILTER), 'MAILCOW') rule = iptc.Rule() rule.src = net target = iptc.Target(rule, "REJECT") rule.target = target if rule in chain.rules: chain.delete_rule(rule) else: with lock: chain = iptc.Chain(iptc.Table6(iptc.Table6.FILTER), 'MAILCOW') rule = iptc.Rule6() rule.src = net target = iptc.Target(rule, "REJECT") rule.target = target if rule in chain.rules: chain.delete_rule(rule) r.hdel('F2B_ACTIVE_BANS', '%s' % net) r.hdel('F2B_QUEUE_UNBAN', '%s' % net) if net in bans: del bans[net]
def openemailChainOrder(): global lock global quit_now while not quit_now: time.sleep(10) with lock: filter4_table = iptc.Table(iptc.Table.FILTER) filter6_table = iptc.Table6(iptc.Table6.FILTER) filter4_table.refresh() filter6_table.refresh() for f in [filter4_table, filter6_table]: forward_chain = iptc.Chain(f, 'FORWARD') input_chain = iptc.Chain(f, 'INPUT') for chain in [forward_chain, input_chain]: target_found = False for position, item in enumerate(chain.rules): if item.target.name == 'OPENEMAIL': target_found = True if position != 0: logCrit( 'Error in %s chain order, restarting container' % (chain.name)) quit_now = True if not target_found: logCrit( 'Error in %s chain: OPENEMAIL target not found, restarting container' % (chain.name)) quit_now = True
def test_rule_iterate_raw(self): if is_table6_available(iptc.Table6.RAW): for r in ( rule for chain in iptc.Table6(iptc.Table6.RAW).chains.values() for rule in chain.rules if rule): pass
def clear(): global lock logInfo('Clearing all bans') for net in bans.copy(): unban(net) with lock: filter4_table = iptc.Table(iptc.Table.FILTER) filter6_table = iptc.Table6(iptc.Table6.FILTER) for filter_table in [filter4_table, filter6_table]: filter_table.autocommit = False forward_chain = iptc.Chain(filter_table, "FORWARD") input_chain = iptc.Chain(filter_table, "INPUT") mailcow_chain = iptc.Chain(filter_table, "MAILCOW") if mailcow_chain in filter_table.chains: for rule in mailcow_chain.rules: mailcow_chain.delete_rule(rule) for rule in forward_chain.rules: if rule.target.name == 'MAILCOW': forward_chain.delete_rule(rule) for rule in input_chain.rules: if rule.target.name == 'MAILCOW': input_chain.delete_rule(rule) filter_table.delete_chain("MAILCOW") filter_table.commit() filter_table.refresh() filter_table.autocommit = True r.delete('F2B_ACTIVE_BANS') r.delete('F2B_PERM_BANS') pubsub.unsubscribe()
def __init__(self, conf: dict) -> None: log.debug('IPTables plugin initialising with config: %s', conf) self._table4 = iptc.Table( self._tables[conf['table'] if 'table' in conf else 'filter']) self._table6 = iptc.Table6( self._tables[conf['table'] if 'table' in conf else 'filter']) log.debug('iptables._table4 == %s', self._table4) log.debug('iptables._table6 == %s', self._table6) chain = conf['chain'] if 'chain' in conf else 'INPUT' self._chain4 = iptc.Chain(self._table4, chain) self._chain6 = iptc.Chain(self._table6, chain) log.debug('iptables._chain4 == %s', chain) log.debug('iptables._chain6 == %s', chain) if 'target' in conf: self._target = self._targets[conf['target']] else: self._target = None log.debug('iptables._target == %s', self._target) if 'ports' in conf['match']: self._ports = conf['match']['ports'] else: self._ports = None log.debug('iptables._ports == %s', self._ports) if 'protocol' in conf['match']: self._proto = conf['match']['protocol'] else: self._proto = None log.debug('iptables._proto == %s', self._proto) if 'sources' in conf['match']: self._sources = [ip_network(ip) for ip in conf['match']['sources']] else: self._sources = None log.debug('iptables._sources == %s', self._sources) if 'destinations' in conf['match']: self._dests = [ip_network(ip) for ip in conf['match']['sources']] else: self._dests = None log.debug('iptables._dests == %s', self._dests) self._rule4 = iptc.Rule() self._rule6 = iptc.Rule6() self._uuids: List[str] = [] try: self.rule_builder() except ValueError as e: log.error( 'An error was encountered while initialising the IPTables plugin' ) log.debug(e) raise e
def mailcowChainOrder(): global lock global quit_now while not quit_now: time.sleep(10) with lock: filter4_table = iptc.Table(iptc.Table.FILTER) filter6_table = iptc.Table6(iptc.Table6.FILTER) filter4_table.refresh() filter6_table.refresh() for f in [filter4_table, filter6_table]: forward_chain = iptc.Chain(f, 'FORWARD') input_chain = iptc.Chain(f, 'INPUT') for chain in [forward_chain, input_chain]: target_found = False for position, item in enumerate(chain.rules): if item.target.name == 'MAILCOW': target_found = True if position != 0: log['time'] = int(round(time.time())) log['priority'] = 'crit' log['message'] = 'Error in ' + chain.name + ' chain order, restarting container' r.lpush('NETFILTER_LOG', json.dumps(log, ensure_ascii=False)) print log['message'] quit_now = True if not target_found: log['time'] = int(round(time.time())) log['priority'] = 'crit' log['message'] = 'Error in ' + chain.name + ' chain: MAILCOW target not found, restarting container' r.lpush('NETFILTER_LOG', json.dumps(log, ensure_ascii=False)) print log['message'] quit_now = True
def _insert_iptables_rule(self, rule, ipv6=False, tables=None): if not isinstance(rule, tuple): return self._insert_iptables_rule_cmd(rule, ipv6) _global_lock.acquire() try: for i in xrange(3): if ipv6: if rule[0] == 'POSTROUTING': if tables: table = tables['nat6'] else: table = iptc.Table6(iptc.Table.NAT) else: if tables: table = tables['filter6'] else: table = iptc.Table6(iptc.Table.FILTER) else: if rule[0] == 'POSTROUTING': if tables: table = tables['nat'] else: table = iptc.Table(iptc.Table.NAT) else: if tables: table = tables['filter'] else: table = iptc.Table(iptc.Table.FILTER) chain = iptc.Chain(table, rule[0]) try: chain.insert_rule(rule[1]) break except: if i == 2: raise logger.error( 'Failed to insert iptables rule, retrying...', 'instance', rule=rule, ) time.sleep(0.5) finally: _global_lock.release()
def get_table(type, name): """ Gets a table. This is a simple helper method that returns either an IP v4 or an IP v6 table according to type. """ if type == IPV4: table = iptc.Table(name) else: table = iptc.Table6(name) return table
def getIPTablesChainForVersion(ipVersion, chain): if ipVersion == IP_VERSION.V4 and iptc.is_table_available( iptc.Table.FILTER): chain = iptc.Chain(iptc.Table(iptc.Table.FILTER), chain) elif ipVersion == IP_VERSION.V6 and iptc.is_table_available( iptc.Table6.FILTER): chain = iptc.Chain(iptc.Table6(iptc.Table6.FILTER), chain) else: LOG.error("Could not find chain \'%s\' for IPv%s IPTables", chain, ipVersion) return chain
def show(ip=None): if ip is IPv4: table = iptc.Table(iptc.Table.FILTER) __logger.debug("Print IPv4 firewall rules") __printrule(table) elif ip is IPv6: table = iptc.Table6(iptc.Table6.FILTER) __logger.debug("Print IPv6 firewall rules") __printrule(table) else: show(IPv4) show(IPv6)
def _exists_iptables_rule(self, rule, ipv6=False, tables=None): # TODO return False if not isinstance(rule, tuple): return self._exists_iptables_rule_cmd(rule, ipv6) _global_lock.acquire() try: if ipv6: if rule[0] == 'POSTROUTING': if tables: table = tables['nat6'] else: table = iptc.Table6(iptc.Table.NAT) else: if tables: table = tables['filter6'] else: table = iptc.Table6(iptc.Table.FILTER) else: if rule[0] == 'POSTROUTING': if tables: table = tables['nat'] else: table = iptc.Table(iptc.Table.NAT) else: if tables: table = tables['filter'] else: table = iptc.Table(iptc.Table.FILTER) chain = iptc.Chain(table, rule[0]) for rule2 in chain.rules: if rule[1] == rule2: return True return False finally: _global_lock.release()
def collect(self): # Metrics iptables_rules = GaugeMetricFamily( 'iptables_rules', 'Number of rules', labels=['ip_version', 'table', 'chain'], ) iptables_packets = CounterMetricFamily( 'iptables_packets', 'Number of matched packets', labels=['ip_version', 'table', 'chain', 'rule'], ) iptables_bytes = CounterMetricFamily( 'iptables_bytes', 'Number of matched bytes', labels=['ip_version', 'table', 'chain', 'rule'], ) for ip_version in self.ip_versions: labels = dict(ip_version=ip_version) for table_name in self.tables: if ip_version == '4': table = iptc.Table(TABLES[table_name]) else: table = iptc.Table6(TABLES[table_name]) table.refresh() labels['table'] = table_name for chain in table.chains: labels['chain'] = chain.name.lower() rule_count = 0 for rule in chain.rules: rule_count += 1 exporter_name = get_exporter_name(rule) if exporter_name: labels['rule'] = exporter_name counter_labels = [ labels['ip_version'], labels['table'], labels['chain'], labels['rule'] ] packets, bytes = rule.get_counters() iptables_packets.add_metric( counter_labels, packets) iptables_bytes.add_metric(counter_labels, bytes) rules_labels = [ labels['ip_version'], labels['table'], labels['chain'] ] iptables_rules.add_metric(rules_labels, rule_count) yield iptables_rules yield iptables_packets yield iptables_bytes
def update_iptables(policy): policies = [p.split() for p in policy] for chain in ['INPUT', 'OUTPUT', 'FORWARD']: rules = [ accept_localhost(iptc.Rule6()), accept_related_established(iptc.Rule6()) ] rules += [ create_rule(iptc.Rule(), p[1], p[2], p[3], p[4]) if len(p) > 2 else create_rule(iptc.Rule(), p[1], None, None, None) for p in policies if p[0] == chain ] write_chain(iptc.Table(iptc.Table.FILTER), chain, rules) write_chain(iptc.Table6(iptc.Table6.FILTER), chain, [create_rule(iptc.Rule6(), 'DROP', None, None, None)])
def _remove_iptables_rule(self, rule, ipv6=False, tables=None): if not isinstance(rule, tuple): return self._remove_iptables_rule_cmd(rule, ipv6) _global_lock.acquire() try: if ipv6: if rule[0] == 'POSTROUTING': if tables: table = tables['nat6'] else: table = iptc.Table6(iptc.Table.NAT) else: if tables: table = tables['filter6'] else: table = iptc.Table6(iptc.Table.FILTER) else: if rule[0] == 'POSTROUTING': if tables: table = tables['nat'] else: table = iptc.Table(iptc.Table.NAT) else: if tables: table = tables['filter'] else: table = iptc.Table(iptc.Table.FILTER) chain = iptc.Chain(table, rule[0]) try: chain.delete_rule(rule[1]) except: pass return True finally: _global_lock.release()
def dropIPv6(ip6): try: v = IP(ip6).version() except: return if ip6 not in v6iplist and v == 6: try: chain = iptc.Chain(iptc.Table6(iptc.Table6.FILTER), "INPUT") rule = iptc.Rule6() rule.in_interface = "eth+" rule.src = ip6 rule.target = iptc.Target(rule, "DROP") chain.insert_rule(rule) v6iplist.append(ip6) except Exception as e: print("OpenDXL.dropIPv6.Exception(%s): %s" % (ip6, str(e)))