Merge "Default firewall group rules from configuration file"

This commit is contained in:
Zuul 2019-09-12 17:22:07 +00:00 committed by Gerrit Code Review
commit 3c9d294471
5 changed files with 227 additions and 23 deletions

View File

@ -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'],

View File

@ -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):

View File

@ -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),
]

View File

@ -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")]
}
}

View File

@ -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.