def _get_router_ids_for_fw(self, context, fw, to_delete=False):
     """Return the router_ids either from fw dict or tenant routers."""
     routers_in_proj = self._get_routers_in_project(context,
                                                    fw['tenant_id'])
     if self._has_router_insertion_fields(fw):
         # it is a new version of plugin (supports specific routers)
         ids = (fw['del-router-ids'] if to_delete else fw['add-router-ids'])
         project_ids = [
             router['id'] for router in routers_in_proj
             if router['id'] in ids
         ]
         if len(project_ids) < len(ids):
             # This means that there is a router from another project.
             LOG.error(
                 "Failed to attach routers from a different project "
                 "to firewall %(fw)s: %(routers)s", {
                     'fw': fw['id'],
                     'routers': list(set(ids) - set(project_ids))
                 })
             self.fwplugin_rpc.set_firewall_status(context, fw['id'],
                                                   nl_constants.ERROR)
             raise exceptions.FirewallInternalDriverError(
                 driver=self.fwaas_driver.driver_name)
         return ids
     else:
         return [router['id'] for router in routers_in_proj]
Beispiel #2
0
    def apply_default_policy(self, agent_mode, apply_list, firewall):
        LOG.debug('Applying firewall %(fw_id)s for tenant %(tid)s',
                  {'fw_id': firewall['id'], 'tid': firewall['tenant_id']})
        fwid = firewall['id']
        try:
            for router_info in apply_list:
                ipt_if_prefix_list = self._get_ipt_mgrs_with_if_prefix(
                    agent_mode, router_info)
                for ipt_if_prefix in ipt_if_prefix_list:
                    # the following only updates local memory; no hole in FW
                    ipt_mgr = ipt_if_prefix['ipt']
                    self._remove_chains(fwid, ipt_mgr)
                    self._remove_default_chains(ipt_mgr)

                    # create default 'DROP ALL' policy chain
                    self._add_default_policy_chain_v4v6(ipt_mgr)
                    self._enable_policy_chain(fwid, ipt_if_prefix)

                    # apply the changes immediately (no defer in firewall path)
                    ipt_mgr.defer_apply_off()
        except (LookupError, RuntimeError):
            # catch known library exceptions and raise Fwaas generic exception
            LOG.exception(
                _LE("Failed to apply default policy on firewall: %s"), fwid)
            raise fw_ext.FirewallInternalDriverError(driver=FWAAS_DRIVER_NAME)
    def _set_rules_on_router_edge(self, context, router_id, neutron_id,
                                  edge_id, fw_id, translated_rules,
                                  delete_fw=False):
        """Recreate router edge firewall rules

        Using the plugin code to recreate all the rules with the additional
        FWaaS rules.

        router_id is the is of the router about to be updated
            (in case of distributed router - the plr)
        neutron_id is the neutron router id
        """
        # update the backend
        router_db = self.core_plugin._get_router(context, neutron_id)
        try:
            with locking.LockManager.get_lock(str(edge_id)):
                self.core_plugin.update_router_firewall(
                    context, router_id, router_db,
                    fwaas_rules=translated_rules)
        except Exception as e:
            # catch known library exceptions and raise Fwaas generic exception
            LOG.error("Failed to update firewall %(fw)s on edge %(edge_id)s: "
                      "%(e)s", {'e': e, 'fw': fw_id, 'edge_id': edge_id})
            raise exceptions.FirewallInternalDriverError(
                driver=self.driver_name)
Beispiel #4
0
 def create_firewall(self, agent_mode, apply_list, firewall):
     LOG.debug('Creating firewall %(fw_id)s for tenant %(tid)s)', {
         'fw_id': firewall['id'],
         'tid': firewall['tenant_id']
     })
     try:
         if firewall['admin_state_up']:
             self._setup_firewall(agent_mode, apply_list, firewall)
         else:
             self.apply_default_policy(agent_mode, apply_list, firewall)
     except (LookupError, RuntimeError):
         # catch known library exceptions and raise Fwaas generic exception
         LOG.exception(_LE("Failed to create firewall: %s"), firewall['id'])
         raise fw_ext.FirewallInternalDriverError(driver=FWAAS_DRIVER_NAME)
    def should_apply_firewall_to_router(self, router_data,
                                        raise_exception=True):
        """Return True if the firewall rules should be added the router

        Return False in those cases:
        - router without an external gateway (rule may be added later when
                                              there is a gateway)

        Raise an exception if the router is unsupported
        (and raise_exception is True):
        - shared router (not supported)
        - md proxy router (not supported)

        """
        if (not router_data.get('distributed') and
            router_data.get('router_type') == 'shared'):
            LOG.error("Cannot apply firewall to shared router %s",
                      router_data['id'])
            if raise_exception:
                raise exceptions.FirewallInternalDriverError(
                    driver=self.driver_name)
            return False

        if router_data.get('name', '').startswith('metadata_proxy_router'):
            LOG.error("Cannot apply firewall to the metadata proxy router %s",
                      router_data['id'])
            if raise_exception:
                raise exceptions.FirewallInternalDriverError(
                    driver=self.driver_name)
            return False

        if not router_data.get('external_gateway_info'):
            LOG.info("Cannot apply firewall to router %s with no gateway",
                     router_data['id'])
            return False

        return True
Beispiel #6
0
    def _get_backend_router_and_fw_section(self, context, router_id):
        # find the backend router id in the DB
        nsx_router_id = nsx_db.get_nsx_router_id(context.session, router_id)
        if nsx_router_id is None:
            LOG.error("Didn't find nsx router for router %s", router_id)
            raise exceptions.FirewallInternalDriverError(
                driver=self.driver_name)

        # get the FW section id of the backend router
        try:
            section_id = self.nsx_router.get_firewall_section_id(
                nsx_router_id)
        except Exception as e:
            LOG.error("Failed to find router firewall section for router "
                      "%(id)s: %(e)s", {'id': router_id, 'e': e})
            raise exceptions.FirewallInternalDriverError(
                driver=self.driver_name)
        if section_id is None:
            LOG.error("Failed to find router firewall section for router "
                      "%(id)s.", {'id': router_id})
            raise exceptions.FirewallInternalDriverError(
                driver=self.driver_name)

        return nsx_router_id, section_id
Beispiel #7
0
 def delete_firewall(self, agent_mode, apply_list, firewall):
     LOG.debug('Deleting firewall %(fw_id)s for tenant %(tid)s',
               {'fw_id': firewall['id'], 'tid': firewall['tenant_id']})
     fwid = firewall['id']
     try:
         for router_info in apply_list:
             ipt_if_prefix_list = self._get_ipt_mgrs_with_if_prefix(
                 agent_mode, router_info)
             for ipt_if_prefix in ipt_if_prefix_list:
                 ipt_mgr = ipt_if_prefix['ipt']
                 self._remove_chains(fwid, ipt_mgr)
                 self._remove_default_chains(ipt_mgr)
                 # apply the changes immediately (no defer in firewall path)
                 ipt_mgr.defer_apply_off()
         self.pre_firewall = None
     except (LookupError, RuntimeError):
         # catch known library exceptions and raise Fwaas generic exception
         LOG.exception(_LE("Failed to delete firewall: %s"), fwid)
         raise fw_ext.FirewallInternalDriverError(driver=FWAAS_DRIVER_NAME)
Beispiel #8
0
 def _translate_action(fwaas_action, fwaas_rule_id):
     """Translate FWaaS action to NSX action"""
     if fwaas_action == fwaas_consts.FWAAS_ALLOW:
         return consts.FW_ACTION_ALLOW
     if fwaas_action == fwaas_consts.FWAAS_DENY:
         return consts.FW_ACTION_DROP
     if fwaas_action == fwaas_consts.FWAAS_REJECT:
         # reject is not supported by the nsx router firewall
         LOG.warning("Reject action is not supported by the NSX backend "
                     "for router firewall. Using %(action)s instead for "
                     "rule %(id)s",
               {'action': consts.FW_ACTION_DROP,
                'id': fwaas_rule_id})
         return consts.FW_ACTION_DROP
     # Unexpected action
     LOG.error("Unsupported FWAAS action %(action)s for rule %(id)s", {
         'action': fwaas_action, 'id': fwaas_rule_id})
     raise exceptions.FirewallInternalDriverError(
         driver=FWAAS_DRIVER_NAME)
 def update_firewall_group(self, agent_mode, apply_list, firewall):
     LOG.debug('Updating firewall %(fw_id)s for tenant %(tid)s',
               {'fw_id': firewall['id'], 'tid': firewall['tenant_id']})
     try:
         if firewall['admin_state_up']:
             if self.pre_firewall:
                 self._remove_conntrack_updated_firewall(agent_mode,
                                 apply_list, self.pre_firewall, firewall)
             else:
                 self._remove_conntrack_new_firewall(agent_mode,
                                                 apply_list, firewall)
             self._setup_firewall(agent_mode, apply_list, firewall)
         else:
             self.apply_default_policy(agent_mode, apply_list, firewall)
         self.pre_firewall = dict(firewall)
     except (LookupError, RuntimeError):
         # catch known library exceptions and raise Fwaas generic exception
         LOG.exception(_LE("Failed to update firewall: %s"), firewall['id'])
         raise fw_ext.FirewallInternalDriverError(driver=FWAAS_DRIVER_NAME)
    def _apply_firewall(self, context, **fw_with_rules):
        tenant_id = fw_with_rules['tenant_id']
        default_fwr = self._make_default_firewall_rule_dict(tenant_id)
        try:
            if fw_with_rules.get('del-router-ids', None):
                for fwr in list(fw_with_rules.get('firewall_rule_list', None)):
                    self._delete_firewall_rule(context, tenant_id, **fwr)
                if default_fwr:
                    self._delete_firewall_rule(context, tenant_id,
                                               **default_fwr)
                self.update_firewall_status(context, fw_with_rules['id'],
                                            const.INACTIVE)

            if fw_with_rules.get('add-router-ids', None):
                vdom = getattr(
                    fortinet_db.Fortinet_ML2_Namespace.query_one(
                        context, tenant_id=tenant_id), 'vdom', None)
                if not vdom:
                    raise fw_ext.FirewallInternalDriverError(
                        driver='Fortinet_fwaas_plugin')
                if default_fwr:
                    self._add_firewall_rule(context, tenant_id, **default_fwr)
                for fwr in reversed(
                        list(fw_with_rules.get('firewall_rule_list', None))):
                    self._add_firewall_rule(context, tenant_id, **fwr)
                self.update_firewall_status(context, fw_with_rules['id'],
                                            const.ACTIVE)
            else:
                self.update_firewall_status(context, fw_with_rules['id'],
                                            const.INACTIVE)
        except Exception as e:
            with excutils.save_and_reraise_exception():
                LOG.error(_LE("apply_firewall %(fws)s failed"),
                          {'fws': fw_with_rules})
                utils._rollback_on_err(self, context, e)
        utils.update_status(self, context, t_consts.TaskStatus.COMPLETED)
Beispiel #11
0
 def validate_backend_version(self):
     # prevent firewall actions if the backend does not support it
     if not self.backend_support:
         LOG.error("The NSX backend does not support router firewall")
         raise exceptions.FirewallInternalDriverError(
             driver=self.driver_name)