def ldapRules(context, component, ruleset, rule_type, identifiers): logger = ContextLoggerChild(context, component) result = ApplyRulesResult(logger) if rule_type == 'acls-ipv6': rules = ruleset.acls_ipv6 elif rule_type == 'acls-ipv4': rules = ruleset.acls_ipv4 else: # NuFW (LDAP) doesn't authenticate NAT rules raise RulesetError(tr("LDAP doesn't support rule type: %s"), repr(rule_type)) if identifiers: rules = [ rules[id] for id in identifiers ] else: rules = rules ldap = WriteLdapRules(logger, component.config['ldap']) with TemplateInstanciation(ruleset): rules = filterRules(result, rules) lines = [] for dn, attr in ldap.createRules(rules): lines.append(unicode(dn)) attrs = attr.items() attrs.sort(key=lambda item: item[0]) for key, value in attrs: lines.append(u" %s=%r" % (key, value)) lines.append(u"") xmlrpc = result.exportXMLRPC() xmlrpc['ldap'] = lines return xmlrpc
def iptablesRules(context, component, ruleset, rule_type, identifiers, use_nufw): logger = ContextLoggerChild(context, component) result = ApplyRulesResult(logger) # Not NAT rules in IPv6! if rule_type == 'nats': rules = ruleset.nats use_ipv6 = False default_decisions = None elif rule_type == 'acls-ipv6': rules = ruleset.acls_ipv6 use_ipv6 = True default_decisions = rules.default_decisions else: rules = ruleset.acls_ipv4 use_ipv6 = False default_decisions = rules.default_decisions if identifiers: rules = [ rules[id] for id in identifiers ] else: rules = rules options = IptablesOptions() options.format = "iptables" options.ipv6 = use_ipv6 options.nufw = use_nufw with TemplateInstanciation(ruleset): rules = filterRules(result, rules) # Create iptables rules iptables = IptablesGenerator(logger, default_decisions, options, component.config, result) if rule_type != 'nats': lines = aclsRules(iptables, rules) else: lines = natsRules(iptables, rules, result) xmlrpc = result.exportXMLRPC() xmlrpc['iptables'] = [unicode(line) for line in lines] return xmlrpc
class ApplyRules: def __init__(self, context, component, ruleset, use_nufw, raise_error=False, only_consistency=False, consistency_error=False): self.context = context self.component = component self.ruleset = ruleset self.use_nufw = use_nufw self.only_consistency = only_consistency self.logger = ContextLoggerChild(context, component) self.result = ApplyRulesResult(self.logger, raise_error, not consistency_error) self.config = component.config self.lock_manager = component.core.lock_manager self.use_ipv6 = self.config['global']['use_ipv6'] if ruleset: # Some consistency checks if self.use_nufw and (not self.ruleset.useNuFW()): raise RulesetError(tr("NuFW is disabled")) if not self.only_consistency and self.ruleset.is_template: raise RulesetError(tr("Unable to apply rules of a rule set template")) # Get rules self.acls_ipv4 = [acl for acl in self.ruleset.acls_ipv4 if acl.enabled] self.acls_ipv6 = [acl for acl in self.ruleset.acls_ipv6 if acl.enabled] self.nats = [nat for nat in self.ruleset.nats if nat.enabled] self.custom_rules = self.ruleset.custom_rules self.ruleset_name = self.ruleset.name self.ipv4_default_decisions = self.ruleset.acls_ipv4.default_decisions self.ipv6_default_decisions = self.ruleset.acls_ipv6.default_decisions else: # Apply localfw rules with no ruleset self.acls_ipv4 = tuple() self.acls_ipv6 = tuple() self.nats = tuple() self.custom_rules = None self.ruleset_name = None self.ipv4_default_decisions = DefaultDecisions(self.config, False) self.ipv6_default_decisions = DefaultDecisions(self.config, True) def consistencyEngine(self): for rules in (self.acls_ipv4, self.acls_ipv6): chain = [] last_chain = None for rule in rules: new_chain = rule.createChainKey() if last_chain and last_chain != new_chain: aclsConsistencyTests(chain, self.result) chain = [] chain.append(rule) last_chain = new_chain aclsConsistencyTests(chain, self.result) # TODO: test self.nats def _applyRulesThread(self): if self.only_consistency: self.consistencyEngine() return self.result.exportXMLRPC() elif not self.result.ignore_consistency_error: self.consistencyEngine() if self.result.consistency_errors: return self.result.exportXMLRPC() options = IptablesOptions() options.nufw = self.use_nufw if self.ruleset_name: self.logger.critical("Apply rules: rule set %r" % self.ruleset_name) else: self.logger.critical("Apply rules: no rule set (only localfw rules)") write_ldap = WriteLdapRules(self.logger, self.config['ldap']) ufwi_ruleset_rules = { 'use_ipv6': self.use_ipv6, 'use_nufw': self.use_nufw, 'is_gateway': self.config.isGateway(), } if self.use_nufw: ufwi_ruleset_rules['ldap_config'] = self.config['ldap'] if self.use_ipv6: acls = itertools.chain(self.acls_ipv4, self.acls_ipv6) else: acls = self.acls_ipv4 ufwi_ruleset_rules['ldap_rules'] = write_ldap.createRules(acls) # TODO: disable IP forward at the beginning # TODO: FORWARD and INPUT: set policy to DROP # LDAP transactions = [] if self.use_nufw: filename = self.config['nufw']['periods_filename'] periods = TimeRangeFileTransaction(filename, self.acls_ipv4, self.acls_ipv6) transactions.append(periods) # iptables options.ipv6 = False write_iptables_ipv4 = WriteIptablesRules( self.logger, self.config, self.ipv4_default_decisions, self.acls_ipv4, self.nats, self.custom_rules, options, self.result) transactions.append(write_iptables_ipv4) ipv6_options = deepcopy(options) ipv6_options.ipv6 = True ipv6_options.deny_all = (not self.use_ipv6) write_iptables_ipv6 = WriteIptablesRules( self.logger, self.config, self.ipv6_default_decisions, self.acls_ipv6, None, self.custom_rules, ipv6_options, self.result) transactions.append(write_iptables_ipv6) # TODO: reload nuauth caches # TODO: reload nuauth periods # TODO: FORWARD and INPUT: set policy to ACCEPT write = WriteRules(self.logger, ufwi_ruleset_rules) transactions.append(write) script = RulesetScript(self.context, self.logger) transactions.append(script) save_ruleset = SaveRuleset(self.ruleset_name, self.use_nufw) transactions.append(save_ruleset) if self.ruleset \ and (self.ruleset.filename != PRODUCTION_RULESET): production = ProductionRuleset(self.ruleset.filename) transactions.append(production) executeTransactions(self.logger, transactions) self.result.applied = True return self.result.exportXMLRPC() def _checkUserGroup(self, require_group_name, user_group): if require_group_name: if user_group.name is None: raise RulesetError( tr('The firewall uses user group names, but the %s user group has no name'), user_group.formatID()) else: if user_group.group is None: raise RulesetError( tr('The firewall uses user group numbers, but the %s user group has no number'), user_group.formatID()) def checkUserGroups(self): require_group_name = self.config['nufw']['require_group_name'] user_groups = set() for rule in itertools.chain(self.acls_ipv4, self.acls_ipv6): user_groups |= set(flattenObjectList(rule.user_groups)) for user_group in user_groups: self._checkUserGroup(require_group_name, user_group) def applyRules(self): if not self.only_consistency: self.lock_manager.acquire(self.context, "ufwi_ruleset_applyRules") try: if self.ruleset: with TemplateInstanciation(self.ruleset): self.acls_ipv4 = filterRules(self.result, self.acls_ipv4) self.acls_ipv6 = filterRules(self.result, self.acls_ipv6) self.nats = filterRules(self.result, self.nats) self.checkUserGroups() if self.result.errors: return self.result.exportXMLRPC() return self._applyRulesThread() else: return self._applyRulesThread() finally: if not self.only_consistency: self.lock_manager.release(self.context, "ufwi_ruleset_applyRules")