def run(self): ruleset = set(Iptables.read_simple_rules()) while True: modify, rule, directives = self.cmd_queue.get() try: rule_exists = rule in ruleset log.debug('{} rule_exists: {}'.format(rule, rule_exists)) # check for duplicates, apply rule if modify == 'I': if rule_exists: log.warn("Trying to insert existing rule: {}. Command ignored.".format(rule)) else: Iptables.exe_rule(modify, rule) # schedule expiry timeout if present. Only for Insert rules and only if the rule didn't exist before (so it was added now) self.schedule_expiry(rule, directives) ruleset.add(rule) elif modify == 'D': if rule_exists: #TODO delete rules in the loop to delete actual iptables duplicates. It's to satisfy idempotency and plays well with common sense Iptables.exe_rule(modify, rule) ruleset.discard(rule) else: log.warn("Trying to delete not existing rule: {}. Command ignored.".format(rule)) elif modify == 'L': #TODO rereading the iptables? pass finally: self.cmd_queue.task_done()
def run(self): ruleset = set(Iptables.read_simple_rules()) while True: modify, rule, directives = self.cmd_queue.get() try: rule_exists = rule in ruleset log.debug('{} rule_exists: {}'.format(rule, rule_exists)) # check for duplicates, apply rule if modify == 'I': if rule_exists: log.warn( "Trying to insert existing rule: {}. Command ignored." .format(rule)) else: Iptables.exe_rule(modify, rule) # schedule expiry timeout if present. Only for Insert rules and only if the rule didn't exist before (so it was added now) self.schedule_expiry(rule, directives) ruleset.add(rule) elif modify == 'D': if rule_exists: #TODO delete rules in the loop to delete actual iptables duplicates. It's to satisfy idempotency and plays well with common sense Iptables.exe_rule(modify, rule) ruleset.discard(rule) else: log.warn( "Trying to delete not existing rule: {}. Command ignored." .format(rule)) elif modify == 'L': #TODO rereading the iptables? pass finally: self.cmd_queue.task_done()
def rfw_init_rules(rfwconf): """Clean and insert the rfw init rules. The rules block all INPUT/OUTPUT traffic on rfw ssl port except for whitelisted IPs. Here are the rules that should be created assuming that that the only whitelisted IP is 127.0.0.1: Rule(chain='INPUT', num='1', pkts='0', bytes='0', target='ACCEPT', prot='tcp', opt='--', inp='*', out='*', source='127.0.0.1', destination='0.0.0.0/0', extra='tcp dpt:7393') Rule(chain='INPUT', num='4', pkts='0', bytes='0', target='DROP', prot='tcp', opt='--', inp='*', out='*', source='0.0.0.0/0', destination='0.0.0.0/0', extra='tcp dpt:7393') Rule(chain='OUTPUT', num='1', pkts='0', bytes='0', target='ACCEPT', prot='tcp', opt='--', inp='*', out='*', source='0.0.0.0/0', destination='127.0.0.1', extra='tcp spt:7393') Rule(chain='OUTPUT', num='4', pkts='0', bytes='0', target='DROP', prot='tcp', opt='--', inp='*', out='*', source='0.0.0.0/0', destination='0.0.0.0/0', extra='tcp spt:7393') """ if rfwconf.is_outward_server(): rfw_port = rfwconf.outward_server_port() else: rfw_port = rfwconf.local_server_port() ipt = Iptables.load() ### log.info('Delete existing init rules') # find 'drop all packets to and from rfw port' drop_input = ipt.find({'target': ['DROP'], 'chain': ['INPUT'], 'prot': ['tcp'], 'extra': ['tcp dpt:' + rfw_port]}) log.info(drop_input) log.info('Existing drop input to rfw port {} rules:\n{}'.format(rfw_port, '\n'.join(map(str, drop_input)))) for r in drop_input: Iptables.exe_rule('D', r) drop_output = ipt.find({'target': ['DROP'], 'chain': ['OUTPUT'], 'prot': ['tcp'], 'extra': ['tcp spt:' + rfw_port]}) log.info('Existing drop output to rfw port {} rules:\n{}'.format(rfw_port, '\n'.join(map(str, drop_output)))) for r in drop_output: Iptables.exe_rule('D', r) ### log.info('Insert DROP rfw port init rules') Iptables.exe(['-I', 'INPUT', '-p', 'tcp', '--dport', rfw_port, '-j', 'DROP']) Iptables.exe(['-I', 'OUTPUT', '-p', 'tcp', '--sport', rfw_port, '-j', 'DROP']) ### log.info('Insert ACCEPT whitelist IP rfw port init rules') for ip in rfwconf.whitelist(): try: Iptables.exe(['-D', 'INPUT', '-p', 'tcp', '--dport', rfw_port, '-s', ip, '-j', 'ACCEPT']) Iptables.exe(['-D', 'OUTPUT', '-p', 'tcp', '--sport', rfw_port, '-d', ip, '-j', 'ACCEPT']) except subprocess.CalledProcessError, e: pass # ignore Iptables.exe(['-I', 'INPUT', '-p', 'tcp', '--dport', rfw_port, '-s', ip, '-j', 'ACCEPT']) Iptables.exe(['-I', 'OUTPUT', '-p', 'tcp', '--sport', rfw_port, '-d', ip, '-j', 'ACCEPT'])
def rfw_init_rules(rfwconf): """Clean and insert the rfw init rules. The rules block all INPUT/OUTPUT traffic on rfw ssl port except for whitelisted IPs. Here are the rules that should be created assuming that that the only whitelisted IP is 127.0.0.1: Rule(chain='INPUT', num='1', pkts='0', bytes='0', target='ACCEPT', prot='tcp', opt='--', inp='*', out='*', source='127.0.0.1', destination='0.0.0.0/0', extra='tcp dpt:7393') Rule(chain='INPUT', num='4', pkts='0', bytes='0', target='DROP', prot='tcp', opt='--', inp='*', out='*', source='0.0.0.0/0', destination='0.0.0.0/0', extra='tcp dpt:7393') Rule(chain='OUTPUT', num='1', pkts='0', bytes='0', target='ACCEPT', prot='tcp', opt='--', inp='*', out='*', source='0.0.0.0/0', destination='127.0.0.1', extra='tcp spt:7393') Rule(chain='OUTPUT', num='4', pkts='0', bytes='0', target='DROP', prot='tcp', opt='--', inp='*', out='*', source='0.0.0.0/0', destination='0.0.0.0/0', extra='tcp spt:7393') """ rfw_port = rfwconf.outward_server_port() ipt = Iptables.load() ### log.info('Delete existing init rules') # find 'drop all packets to and from rfw port' drop_input = ipt.find({ 'target': ['DROP'], 'chain': ['INPUT'], 'prot': ['tcp'], 'extra': ['tcp dpt:' + rfw_port] }) log.info(drop_input) log.info('Existing drop input to rfw port {} rules:\n{}'.format( rfw_port, '\n'.join(map(str, drop_input)))) for r in drop_input: Iptables.exe_rule('D', r) drop_output = ipt.find({ 'target': ['DROP'], 'chain': ['OUTPUT'], 'prot': ['tcp'], 'extra': ['tcp spt:' + rfw_port] }) log.info('Existing drop output to rfw port {} rules:\n{}'.format( rfw_port, '\n'.join(map(str, drop_output)))) for r in drop_output: Iptables.exe_rule('D', r) ### log.info('Insert DROP rfw port init rules') Iptables.exe( ['-I', 'INPUT', '-p', 'tcp', '--dport', rfw_port, '-j', 'DROP']) Iptables.exe( ['-I', 'OUTPUT', '-p', 'tcp', '--sport', rfw_port, '-j', 'DROP']) ### log.info('Insert ACCEPT whitelist IP rfw port init rules') for ip in rfwconf.whitelist(): try: Iptables.exe([ '-D', 'INPUT', '-p', 'tcp', '--dport', rfw_port, '-s', ip, '-j', 'ACCEPT' ]) Iptables.exe([ '-D', 'OUTPUT', '-p', 'tcp', '--sport', rfw_port, '-d', ip, '-j', 'ACCEPT' ]) except subprocess.CalledProcessError, e: pass # ignore Iptables.exe([ '-I', 'INPUT', '-p', 'tcp', '--dport', rfw_port, '-s', ip, '-j', 'ACCEPT' ]) Iptables.exe([ '-I', 'OUTPUT', '-p', 'tcp', '--sport', rfw_port, '-d', ip, '-j', 'ACCEPT' ])
def run(self): Iptables.read_chains() ruleset = set(Iptables.read_simple_rules(matching_num=False)) while True: modify, rule, directives = self.cmd_queue.get() try: # Modify the rule to nullify parameters which need not to be included in the search if rule.target != 'CREATE': rule_exists = rule in ruleset else: if ':' in rule.chain: new_chain = rule.chain.split(':')[1] rule_exists = new_chain in iptables.RULE_CHAINS else: rule_exists = rule.chain in iptables.RULE_CHAINS log.debug('{} rule_exists: {}'.format(rule, rule_exists)) # check for duplicates, apply rule if modify == 'I': if rule_exists: log.warn("Trying to insert existing rule: {}. Command ignored.".format(rule)) else: if rule.target == 'CREATE': modify = 'N' if ':' in rule.chain: # renaming a chain modify = 'E' Iptables.exe_rule(modify, rule) # schedule expiry timeout if present. Only for Insert rules and only if the rule didn't exist before (so it was added now) self.schedule_expiry(rule, directives) if rule.target != 'CREATE': ruleset.add(rule) else: if ':' in rule.chain: old_chain = rule.chain.split(':')[0] new_chain = rule.chain.split(':')[1] iptables.RULE_CHAINS.remove(old_chain) iptables.RULE_CHAINS.add(new_chain) iptables.RULE_TARGETS.add(rule.chain) else: iptables.RULE_CHAINS.add(rule.chain) iptables.RULE_TARGETS.add(rule.chain) elif modify == 'D': if rule_exists: if rule.target == 'CREATE': modify = 'X' #TODO delete rules in the loop to delete actual iptables duplicates. It's to satisfy idempotency and plays well with common sense Iptables.exe_rule(modify, rule) if rule.target != 'CREATE': ruleset.discard(rule) else: iptables.RULE_TARGETS.remove(rule.chain) iptables.RULE_CHAINS.remove(rule.chain) else: print("non existing rule") log.warn("Trying to delete not existing rule: {}. Command ignored.".format(rule)) elif modify == 'L': #TODO rereading the iptables? pass # Hack to prevent this exception to reach the threading code, preventing this thread from running more than this except Exception: pass finally: self.cmd_queue.task_done()