Enhance IptablesFirewallDriver with remote address groups

This change enhances the IptablesFirewallDriver with support for remote
address groups. Previously, this feature was only available in the
OVSFirewallDriver. This commit harmonizes the capabilities across both
firewall drivers, and by inheritance also to OVSHybridIptablesFirewallDriver.

Background -
The Neutron API allows operators to configure remote address groups [1],
however the OVSHybridIptablesFirewallDriver and IptablesFirewallDriver do
not implement these remote group restrictions. When configuring security
group rules with remote address groups, connections get enabled
based on other rule parameters, ignoring the configured remote address
group restrictions.
This behaviour undocumented, and may lead to more-open-than-configured network
access.

Closes-Bug: #2058138
Change-Id: I76b3cb46ee603fa5e829537af41316bb42a6f30f
This commit is contained in:
Robert Breker 2024-03-17 14:43:50 +00:00
parent 1b3bc34f67
commit 5e1188ef38
3 changed files with 33 additions and 3 deletions

View File

@ -622,9 +622,15 @@ class IptablesFirewallDriver(firewall.FirewallDriver):
rule, port, direction))
return port_rules
def _get_any_remote_group_id_in_rule(self, rule):
remote_group_id = rule.get('remote_group_id')
if not remote_group_id:
remote_group_id = rule.get('remote_address_group_id')
return remote_group_id
def _expand_sg_rule_with_remote_ips(self, rule, port, direction):
"""Expand a remote group rule to rule per remote group IP."""
remote_group_id = rule.get('remote_group_id')
remote_group_id = self._get_any_remote_group_id_in_rule(rule)
if remote_group_id:
ethertype = rule['ethertype']
port_ips = port.get('fixed_ips', [])
@ -646,7 +652,7 @@ class IptablesFirewallDriver(firewall.FirewallDriver):
for sg_id in sg_ids:
for rule in self.sg_rules.get(sg_id, []):
if not direction or rule['direction'] == direction:
remote_sg_id = rule.get('remote_group_id')
remote_sg_id = self._get_any_remote_group_id_in_rule(rule)
ether_type = rule.get('ethertype')
if remote_sg_id and ether_type:
remote_sg_ids[ether_type].add(remote_sg_id)
@ -726,7 +732,7 @@ class IptablesFirewallDriver(firewall.FirewallDriver):
return args
def _convert_sg_rule_to_iptables_args(self, sg_rule):
remote_gid = sg_rule.get('remote_group_id')
remote_gid = self._get_any_remote_group_id_in_rule(sg_rule)
if self.enable_ipset and remote_gid:
return self._generate_ipset_rule_args(sg_rule, remote_gid)
else:

View File

@ -2457,6 +2457,22 @@ class IptablesFirewallEnhancedIpsetTestCase(BaseIptablesFirewallTestCase):
self.firewall.ipset.assert_has_calls(calls, True)
def test__get_any_remote_group_id_in_rule_with_remote_group(self):
sg_rule = {'direction': 'ingress',
'remote_group_id': FAKE_SGID,
'ethertype': _IPv4}
self.assertEqual(FAKE_SGID,
self.firewall._get_any_remote_group_id_in_rule(sg_rule))
def test__get_any_remote_group_id_in_rule_with_remote_address_group(self):
sg_rule = {'direction': 'ingress',
'remote_address_group_id': FAKE_SGID,
'ethertype': _IPv6}
self.assertEqual(FAKE_SGID,
self.firewall._get_any_remote_group_id_in_rule(sg_rule))
def test_sg_rule_expansion_with_remote_ips(self):
other_ips = [('10.0.0.2', 'fa:16:3e:aa:bb:c1'),
('10.0.0.3', 'fa:16:3e:aa:bb:c2'),

View File

@ -0,0 +1,8 @@
---
features:
- |
Remote address group support was added to the iptables-based firewall
drivers (IptablesFirewallDriver and OVSHybridIptablesFirewallDriver),
Previously it was only available in the OVSFirewallDriver.
For more information, see bug
`2058138 <https://bugs.launchpad.net/neutron/+bug/2058138>`_.