Merge "Default firewall group rules from configuration file"
This commit is contained in:
commit
3c9d294471
@ -17,7 +17,6 @@ import copy
|
|||||||
|
|
||||||
import netaddr
|
import netaddr
|
||||||
|
|
||||||
from neutron_lib.api.definitions import constants as fw_const
|
|
||||||
from neutron_lib import constants as nl_constants
|
from neutron_lib import constants as nl_constants
|
||||||
from neutron_lib.db import api as db_api
|
from neutron_lib.db import api as db_api
|
||||||
from neutron_lib.db import constants as db_constants
|
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.db import utils as db_utils
|
||||||
from neutron_lib import exceptions
|
from neutron_lib import exceptions
|
||||||
from neutron_lib.exceptions import firewall_v2 as f_exc
|
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_db import exception as db_exc
|
||||||
from oslo_log import log as logging
|
from oslo_log import log as logging
|
||||||
from oslo_utils import uuidutils
|
from oslo_utils import uuidutils
|
||||||
@ -409,39 +409,63 @@ class FirewallPluginDb(object):
|
|||||||
# NOTE(xgerman) Maybe generating the final set of rules from a
|
# NOTE(xgerman) Maybe generating the final set of rules from a
|
||||||
# configuration file makes sense. Can be done some time later
|
# 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 = {
|
in_fwr_v4 = {
|
||||||
'description': 'default ingress rule for IPv4',
|
'description': 'default ingress rule for IPv4',
|
||||||
'name': 'default ingress ipv4 (deny all)',
|
'name': 'default ingress ipv4',
|
||||||
'shared': False,
|
'shared': cfg.CONF.default_fwg_rules.shared,
|
||||||
'protocol': None,
|
'protocol': cfg.CONF.default_fwg_rules.protocol,
|
||||||
'tenant_id': tenant_id,
|
'tenant_id': tenant_id,
|
||||||
'ip_version': nl_constants.IP_VERSION_4,
|
'ip_version': nl_constants.IP_VERSION_4,
|
||||||
'action': fw_const.FWAAS_DENY,
|
'action': cfg.CONF.default_fwg_rules.ingress_action,
|
||||||
'enabled': True,
|
'enabled': cfg.CONF.default_fwg_rules.enabled,
|
||||||
'source_port': None,
|
'source_port': cfg.CONF.default_fwg_rules.ingress_source_port,
|
||||||
'source_ip_address': None,
|
'source_ip_address':
|
||||||
'destination_port': None,
|
cfg.CONF.default_fwg_rules.ingress_source_ipv4_address,
|
||||||
'destination_ip_address': None,
|
'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 = copy.deepcopy(in_fwr_v4)
|
||||||
in_fwr_v6['description'] = 'default ingress rule for IPv6'
|
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['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 = copy.deepcopy(in_fwr_v4)
|
||||||
eg_fwr_v4['description'] = 'default egress rule for IPv4'
|
eg_fwr_v4['description'] = 'default egress rule for IPv4'
|
||||||
eg_fwr_v4['action'] = fw_const.FWAAS_ALLOW
|
eg_fwr_v4['name'] = 'default egress ipv4'
|
||||||
eg_fwr_v4['name'] = 'default egress ipv4 (allow all)'
|
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 = copy.deepcopy(in_fwr_v6)
|
||||||
eg_fwr_v6['description'] = 'default egress rule for IPv6'
|
eg_fwr_v6['description'] = 'default egress rule for IPv6'
|
||||||
eg_fwr_v6['name'] = 'default egress ipv6 (allow all)'
|
eg_fwr_v6['name'] = 'default egress ipv6'
|
||||||
eg_fwr_v6['action'] = fw_const.FWAAS_ALLOW
|
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 {
|
return {
|
||||||
'in_ipv4': self.create_firewall_rule(context, in_fwr_v4)['id'],
|
'in_ipv4': self.create_firewall_rule(context, in_fwr_v4)['id'],
|
||||||
|
@ -21,8 +21,10 @@ from neutron_lib.api.definitions import firewall_v2
|
|||||||
from neutron_lib.api import extensions
|
from neutron_lib.api import extensions
|
||||||
from neutron_lib.exceptions import firewall_v2 as f_exc
|
from neutron_lib.exceptions import firewall_v2 as f_exc
|
||||||
from neutron_lib.services import base as service_base
|
from neutron_lib.services import base as service_base
|
||||||
|
from oslo_config import cfg
|
||||||
import six
|
import six
|
||||||
|
|
||||||
|
from neutron_fwaas._i18n import _
|
||||||
from neutron_fwaas.common import fwaas_constants
|
from neutron_fwaas.common import fwaas_constants
|
||||||
|
|
||||||
|
|
||||||
@ -86,6 +88,92 @@ FirewallRuleAlreadyAssociated = moves.moved_class(
|
|||||||
f_exc.FirewallRuleAlreadyAssociated, 'FirewallRuleAlreadyAssociated',
|
f_exc.FirewallRuleAlreadyAssociated, 'FirewallRuleAlreadyAssociated',
|
||||||
__name__)
|
__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.
|
# TODO(Reedip): Remove the convert_to functionality after bug1706061 is fixed.
|
||||||
def convert_to_string(value):
|
def convert_to_string(value):
|
||||||
|
@ -15,6 +15,7 @@ import neutron.conf.services.provider_configuration
|
|||||||
import neutron_fwaas.services.firewall.service_drivers.agents.\
|
import neutron_fwaas.services.firewall.service_drivers.agents.\
|
||||||
firewall_agent_api
|
firewall_agent_api
|
||||||
import neutron_fwaas.extensions.firewall
|
import neutron_fwaas.extensions.firewall
|
||||||
|
import neutron_fwaas.extensions.firewall_v2
|
||||||
|
|
||||||
|
|
||||||
def list_agent_opts():
|
def list_agent_opts():
|
||||||
@ -31,4 +32,6 @@ def list_opts():
|
|||||||
neutron_fwaas.extensions.firewall.firewall_quota_opts),
|
neutron_fwaas.extensions.firewall.firewall_quota_opts),
|
||||||
('service_providers',
|
('service_providers',
|
||||||
neutron.conf.services.provider_configuration.serviceprovider_opts),
|
neutron.conf.services.provider_configuration.serviceprovider_opts),
|
||||||
|
('default_fwg_rules',
|
||||||
|
neutron_fwaas.extensions.firewall_v2.default_fwg_rules_opts),
|
||||||
]
|
]
|
||||||
|
@ -20,6 +20,7 @@ import webob.exc
|
|||||||
|
|
||||||
from neutron_lib import constants as nl_constants
|
from neutron_lib import constants as nl_constants
|
||||||
from neutron_lib.exceptions import firewall_v2 as f_exc
|
from neutron_lib.exceptions import firewall_v2 as f_exc
|
||||||
|
from oslo_config import cfg
|
||||||
from oslo_utils import uuidutils
|
from oslo_utils import uuidutils
|
||||||
|
|
||||||
from neutron_fwaas.common import fwaas_constants as constants
|
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]),
|
self.assertEqual(set([ctx_admin.tenant_id, ctx.tenant_id]),
|
||||||
set([r['tenant_id'] for r in res]))
|
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):
|
def test_create_default_firewall_group(self):
|
||||||
self._build_default_fwg()
|
self._build_default_fwg()
|
||||||
result_map = {
|
result_map = {
|
||||||
@ -849,13 +931,13 @@ class TestFirewallDBPluginV2(test_fwaas_plugin_v2.FirewallPluginV2TestCase):
|
|||||||
"ip_version", "name"],
|
"ip_version", "name"],
|
||||||
"data": [
|
"data": [
|
||||||
("default ingress rule for IPv4", "deny", None, True, 4,
|
("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 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 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 rule for IPv6", "allow", None, True, 6,
|
||||||
"default egress ipv6 (allow all)")]
|
"default egress ipv6")]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
7
releasenotes/notes/bug-1799358-360c6ab27a32e0ac.yaml
Normal file
7
releasenotes/notes/bug-1799358-360c6ab27a32e0ac.yaml
Normal 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.
|
Loading…
Reference in New Issue
Block a user