diff --git a/neutron_fwaas/db/firewall/v2/firewall_db_v2.py b/neutron_fwaas/db/firewall/v2/firewall_db_v2.py index 2a8e18eb8..20977f499 100644 --- a/neutron_fwaas/db/firewall/v2/firewall_db_v2.py +++ b/neutron_fwaas/db/firewall/v2/firewall_db_v2.py @@ -17,7 +17,6 @@ import copy import netaddr -from neutron_lib.api.definitions import constants as fw_const from neutron_lib import constants as nl_constants from neutron_lib.db import api as db_api from neutron_lib.db import constants as db_constants @@ -26,6 +25,7 @@ from neutron_lib.db import model_query from neutron_lib.db import utils as db_utils from neutron_lib import exceptions from neutron_lib.exceptions import firewall_v2 as f_exc +from oslo_config import cfg from oslo_db import exception as db_exc from oslo_log import log as logging from oslo_utils import uuidutils @@ -409,39 +409,63 @@ class FirewallPluginDb(object): # NOTE(xgerman) Maybe generating the final set of rules from a # configuration file makes sense. Can be done some time later - # 1. Drop any IPv4 packets for ingress traffic + # 1. Firewall rule for ingress IPv4 packets (DROP by default) in_fwr_v4 = { 'description': 'default ingress rule for IPv4', - 'name': 'default ingress ipv4 (deny all)', - 'shared': False, - 'protocol': None, + 'name': 'default ingress ipv4', + 'shared': cfg.CONF.default_fwg_rules.shared, + 'protocol': cfg.CONF.default_fwg_rules.protocol, 'tenant_id': tenant_id, 'ip_version': nl_constants.IP_VERSION_4, - 'action': fw_const.FWAAS_DENY, - 'enabled': True, - 'source_port': None, - 'source_ip_address': None, - 'destination_port': None, - 'destination_ip_address': None, + 'action': cfg.CONF.default_fwg_rules.ingress_action, + 'enabled': cfg.CONF.default_fwg_rules.enabled, + 'source_port': cfg.CONF.default_fwg_rules.ingress_source_port, + 'source_ip_address': + cfg.CONF.default_fwg_rules.ingress_source_ipv4_address, + 'destination_port': + cfg.CONF.default_fwg_rules.ingress_destination_port, + 'destination_ip_address': + cfg.CONF.default_fwg_rules. + ingress_destination_ipv4_address, } - # 2. Drop any IPv6 packets for ingress traffic + # 2. Firewall rule for ingress IPv6 packets (DROP by default) in_fwr_v6 = copy.deepcopy(in_fwr_v4) in_fwr_v6['description'] = 'default ingress rule for IPv6' - in_fwr_v6['name'] = 'default ingress ipv6 (deny all)' + in_fwr_v6['name'] = 'default ingress ipv6' in_fwr_v6['ip_version'] = nl_constants.IP_VERSION_6 + in_fwr_v6['source_ip_address'] = \ + cfg.CONF.default_fwg_rules.ingress_source_ipv6_address + in_fwr_v6['destination_ip_address'] = \ + cfg.CONF.default_fwg_rules.ingress_destination_ipv6_address - # 3. Allow any IPv4 packets for egress traffic + # 3. Firewall rule for egress IPv4 packets (ALLOW by default) eg_fwr_v4 = copy.deepcopy(in_fwr_v4) eg_fwr_v4['description'] = 'default egress rule for IPv4' - eg_fwr_v4['action'] = fw_const.FWAAS_ALLOW - eg_fwr_v4['name'] = 'default egress ipv4 (allow all)' + eg_fwr_v4['name'] = 'default egress ipv4' + eg_fwr_v4['action'] = cfg.CONF.default_fwg_rules.egress_action + eg_fwr_v4['source_port'] = \ + cfg.CONF.default_fwg_rules.egress_source_port + eg_fwr_v4['source_ip_address'] = \ + cfg.CONF.default_fwg_rules.egress_source_ipv4_address + eg_fwr_v4['destination_port'] = \ + cfg.CONF.default_fwg_rules.egress_destination_port + eg_fwr_v4['destination_ip_address'] = \ + cfg.CONF.default_fwg_rules.egress_destination_ipv4_address - # 4. Allow any IPv6 packets for egress traffic + # 4. Firewall rule for egress IPv6 packets (ALLOW by default) eg_fwr_v6 = copy.deepcopy(in_fwr_v6) eg_fwr_v6['description'] = 'default egress rule for IPv6' - eg_fwr_v6['name'] = 'default egress ipv6 (allow all)' - eg_fwr_v6['action'] = fw_const.FWAAS_ALLOW + eg_fwr_v6['name'] = 'default egress ipv6' + eg_fwr_v6['action'] = cfg.CONF.default_fwg_rules.egress_action + eg_fwr_v6['source_port'] = \ + cfg.CONF.default_fwg_rules.egress_source_port + eg_fwr_v6['source_ip_address'] = \ + cfg.CONF.default_fwg_rules.egress_source_ipv6_address + eg_fwr_v6['destination_port'] = \ + cfg.CONF.default_fwg_rules.egress_destination_port + eg_fwr_v6['destination_ip_address'] = \ + cfg.CONF.default_fwg_rules.egress_destination_ipv6_address return { 'in_ipv4': self.create_firewall_rule(context, in_fwr_v4)['id'], diff --git a/neutron_fwaas/extensions/firewall_v2.py b/neutron_fwaas/extensions/firewall_v2.py index 372b9d716..d8745e971 100644 --- a/neutron_fwaas/extensions/firewall_v2.py +++ b/neutron_fwaas/extensions/firewall_v2.py @@ -21,8 +21,10 @@ from neutron_lib.api.definitions import firewall_v2 from neutron_lib.api import extensions from neutron_lib.exceptions import firewall_v2 as f_exc from neutron_lib.services import base as service_base +from oslo_config import cfg import six +from neutron_fwaas._i18n import _ from neutron_fwaas.common import fwaas_constants @@ -86,6 +88,92 @@ FirewallRuleAlreadyAssociated = moves.moved_class( f_exc.FirewallRuleAlreadyAssociated, 'FirewallRuleAlreadyAssociated', __name__) +default_fwg_rules_opts = [ + cfg.StrOpt('ingress_action', + default=api_const.FWAAS_DENY, + help=_('Firewall group rule action allow or ' + 'deny or reject for ingress. ' + 'Default is deny.')), + cfg.StrOpt('ingress_source_ipv4_address', + default=None, + help=_('IPv4 source address for ingress ' + '(address or address/netmask). ' + 'Default is None.')), + cfg.StrOpt('ingress_source_ipv6_address', + default=None, + help=_('IPv6 source address for ingress ' + '(address or address/netmask). ' + 'Default is None.')), + cfg.StrOpt('ingress_source_port', + default=None, + help=_('Source port number or range ' + '(min:max) for ingress. ' + 'Default is None.')), + cfg.StrOpt('ingress_destination_ipv4_address', + default=None, + help=_('IPv4 destination address for ingress ' + '(address or address/netmask). ' + 'Default is None.')), + cfg.StrOpt('ingress_destination_ipv6_address', + default=None, + help=_('IPv6 destination address for ingress ' + '(address or address/netmask). ' + 'Default is deny.')), + cfg.StrOpt('ingress_destination_port', + default=None, + help=_('Destination port number or range ' + '(min:max) for ingress. ' + 'Default is None.')), + cfg.StrOpt('egress_action', + default=api_const.FWAAS_ALLOW, + help=_('Firewall group rule action allow or ' + 'deny or reject for egress. ' + 'Default is allow.')), + cfg.StrOpt('egress_source_ipv4_address', + default=None, + help=_('IPv4 source address for egress ' + '(address or address/netmask). ' + 'Default is None.')), + cfg.StrOpt('egress_source_ipv6_address', + default=None, + help=_('IPv6 source address for egress ' + '(address or address/netmask). ' + 'Default is deny.')), + cfg.StrOpt('egress_source_port', + default=None, + help=_('Source port number or range ' + '(min:max) for egress. ' + 'Default is None.')), + cfg.StrOpt('egress_destination_ipv4_address', + default=None, + help=_('IPv4 destination address for egress ' + '(address or address/netmask). ' + 'Default is deny.')), + cfg.StrOpt('egress_destination_ipv6_address', + default=None, + help=_('IPv6 destination address for egress ' + '(address or address/netmask). ' + 'Default is deny.')), + cfg.StrOpt('egress_destination_port', + default=None, + help=_('Destination port number or range ' + '(min:max) for egress. ' + 'Default is None.')), + cfg.BoolOpt('shared', + default=False, + help=_('Firewall group rule shared. ' + 'Default is False.')), + cfg.StrOpt('protocol', + default=None, + help=_('Network protocols (tcp, udp, ...). ' + 'Default is None.')), + cfg.BoolOpt('enabled', + default=True, + help=_('Firewall group rule enabled. ' + 'Default is True.')), +] +cfg.CONF.register_opts(default_fwg_rules_opts, 'default_fwg_rules') + # TODO(Reedip): Remove the convert_to functionality after bug1706061 is fixed. def convert_to_string(value): diff --git a/neutron_fwaas/opts.py b/neutron_fwaas/opts.py index 069445d39..bc6a2e2f7 100644 --- a/neutron_fwaas/opts.py +++ b/neutron_fwaas/opts.py @@ -15,6 +15,7 @@ import neutron.conf.services.provider_configuration import neutron_fwaas.services.firewall.service_drivers.agents.\ firewall_agent_api import neutron_fwaas.extensions.firewall +import neutron_fwaas.extensions.firewall_v2 def list_agent_opts(): @@ -31,4 +32,6 @@ def list_opts(): neutron_fwaas.extensions.firewall.firewall_quota_opts), ('service_providers', neutron.conf.services.provider_configuration.serviceprovider_opts), + ('default_fwg_rules', + neutron_fwaas.extensions.firewall_v2.default_fwg_rules_opts), ] diff --git a/neutron_fwaas/tests/unit/db/firewall/v2/test_firewall_db_v2.py b/neutron_fwaas/tests/unit/db/firewall/v2/test_firewall_db_v2.py index 32b57f0ba..41c21db5d 100644 --- a/neutron_fwaas/tests/unit/db/firewall/v2/test_firewall_db_v2.py +++ b/neutron_fwaas/tests/unit/db/firewall/v2/test_firewall_db_v2.py @@ -20,6 +20,7 @@ import webob.exc from neutron_lib import constants as nl_constants from neutron_lib.exceptions import firewall_v2 as f_exc +from oslo_config import cfg from oslo_utils import uuidutils from neutron_fwaas.common import fwaas_constants as constants @@ -831,6 +832,87 @@ class TestFirewallDBPluginV2(test_fwaas_plugin_v2.FirewallPluginV2TestCase): self.assertEqual(set([ctx_admin.tenant_id, ctx.tenant_id]), set([r['tenant_id'] for r in res])) + def test_create_default_firewall_group_from_config(self): + group = 'default_fwg_rules' + + cfg.CONF.set_override('shared', True, group) + cfg.CONF.set_override('protocol', 'tcp', group) + cfg.CONF.set_override('enabled', False, group) + cfg.CONF.set_override('ingress_action', 'allow', group) + cfg.CONF.set_override('egress_action', 'deny', group) + cfg.CONF.set_override('ingress_source_port', '7777', group) + cfg.CONF.set_override('egress_source_port', '8888', group) + cfg.CONF.set_override('ingress_destination_port', '6666', group) + cfg.CONF.set_override('egress_destination_port', '5555', group) + cfg.CONF.set_override('ingress_source_ipv4_address', '1.2.3.4', group) + cfg.CONF.set_override('ingress_source_ipv6_address', '1:2:3:4:5:6:7:8', + group) + cfg.CONF.set_override('egress_source_ipv4_address', '4.3.2.1', group) + cfg.CONF.set_override('egress_source_ipv6_address', '8:7:6:5:4:3:2:1', + group) + cfg.CONF.set_override('ingress_destination_ipv4_address', + '251.252.253.254', group) + cfg.CONF.set_override('ingress_destination_ipv6_address', + '88:99:aa:bb:cc:dd:ee:ff', group) + cfg.CONF.set_override('egress_destination_ipv4_address', + '255.254.253.252', group) + cfg.CONF.set_override('egress_destination_ipv6_address', + 'ff:ee:dd:cc:bb:aa:99:88', group) + + self._build_default_fwg() + results = self._list_req('firewall_rules') + for res in results: + res.pop('id') + + base = { + 'shared': True, + 'protocol': 'tcp', + 'enabled': False, + 'tenant_id': 'admin-tenant', + 'project_id': 'admin-tenant', + 'firewall_policy_id': None + } + + ingress_base = dict(base, **{ + 'source_port': '7777', + 'destination_port': '6666', + 'action': 'allow' + }) + + egress_base = dict(base, **{ + 'source_port': '8888', + 'destination_port': '5555', + 'action': 'deny' + }) + + expected = [dict(ingress_base, **{ + 'name': 'default ingress ipv4', + 'description': 'default ingress rule for IPv4', + 'ip_version': 4, + 'source_ip_address': '1.2.3.4', + 'destination_ip_address': '251.252.253.254', + }), dict(ingress_base, **{ + 'name': 'default ingress ipv6', + 'description': 'default ingress rule for IPv6', + 'ip_version': 6, + 'source_ip_address': '1:2:3:4:5:6:7:8', + 'destination_ip_address': '88:99:aa:bb:cc:dd:ee:ff', + }), dict(egress_base, **{ + 'name': 'default egress ipv4', + 'description': 'default egress rule for IPv4', + 'ip_version': 4, + 'source_ip_address': '4.3.2.1', + 'destination_ip_address': '255.254.253.252', + }), dict(egress_base, **{ + 'name': 'default egress ipv6', + 'description': 'default egress rule for IPv6', + 'ip_version': 6, + 'source_ip_address': '8:7:6:5:4:3:2:1', + 'destination_ip_address': 'ff:ee:dd:cc:bb:aa:99:88', + })] + + self.assertEqual(expected, results) + def test_create_default_firewall_group(self): self._build_default_fwg() result_map = { @@ -849,13 +931,13 @@ class TestFirewallDBPluginV2(test_fwaas_plugin_v2.FirewallPluginV2TestCase): "ip_version", "name"], "data": [ ("default ingress rule for IPv4", "deny", None, True, 4, - "default ingress ipv4 (deny all)"), + "default ingress ipv4"), ("default egress rule for IPv4", "allow", None, True, 4, - "default egress ipv4 (allow all)"), + "default egress ipv4"), ("default ingress rule for IPv6", "deny", None, True, 6, - "default ingress ipv6 (deny all)"), + "default ingress ipv6"), ("default egress rule for IPv6", "allow", None, True, 6, - "default egress ipv6 (allow all)")] + "default egress ipv6")] } } diff --git a/releasenotes/notes/bug-1799358-360c6ab27a32e0ac.yaml b/releasenotes/notes/bug-1799358-360c6ab27a32e0ac.yaml new file mode 100644 index 000000000..05a8774c8 --- /dev/null +++ b/releasenotes/notes/bug-1799358-360c6ab27a32e0ac.yaml @@ -0,0 +1,7 @@ +--- +fixes: + - | + There was no way to define default firewall group rules. + Default firewall group rules can be now defined in neutron_fwaas.conf + in section ``default_fwg_rules``. + Default firewall group rules are same as hardcoded values before.