Move iptables rule fetching and setting to privsep.

Rules are fetched, edited, and set. Keep the edit logic in nova/network,
but move the bits requiring elevated permissions to privsep.

Change-Id: I1f8382c450b95d261f68ec8bae2a2077f9361fe0
This commit is contained in:
Michael Still 2019-02-10 23:43:57 +00:00 committed by Stephen Finucane
parent 872a823d9a
commit 54bf4694b9
9 changed files with 284 additions and 118 deletions

View File

@ -261,11 +261,14 @@ class IptablesManager(object):
"""
def __init__(self, execute=None):
if not execute:
self.execute = _execute
else:
self.execute = execute
def __init__(self, redirect_privsep_calls_to=None):
# NOTE(mikal): This is only used by the xenapi hypervisor driver,
# which wants to intercept our calls to iptables and redirect them
# to an agent running in dom0.
# TODO(mikal): We really should make the dom0 agent feel more like
# privsep. They really are the same thing, just one is from a simpler
# time in our past.
self.redirect_privsep = redirect_privsep_calls_to
self.ipv4 = {'filter': IptablesTable(),
'nat': IptablesTable(),
@ -358,23 +361,42 @@ class IptablesManager(object):
rules. This happens atomically, thanks to iptables-restore.
"""
s = [('iptables', self.ipv4)]
s = [(True, self.ipv4)]
if CONF.use_ipv6:
s += [('ip6tables', self.ipv6)]
s += [(False, self.ipv6)]
for is_ipv4, tables in s:
if not self.redirect_privsep:
all_tables, _err = nova.privsep.linux_net.iptables_get_rules(
ipv4=is_ipv4)
else:
if is_ipv4:
cmd = 'iptables-save'
else:
cmd = 'ip6tables-save'
all_tables, _err = self.redirect_privsep(
cmd, '-c', run_as_root=True, attempts=5)
for cmd, tables in s:
all_tables, _err = self.execute('%s-save' % (cmd,), '-c',
run_as_root=True,
attempts=5)
all_lines = all_tables.split('\n')
for table_name, table in tables.items():
start, end = self._find_table(all_lines, table_name)
all_lines[start:end] = self._modify_rules(
all_lines[start:end], table, table_name)
table.dirty = False
self.execute('%s-restore' % (cmd,), '-c', run_as_root=True,
process_input=six.b('\n'.join(all_lines)),
attempts=5)
if not self.redirect_privsep:
nova.privsep.linux_net.iptables_set_rules(all_lines,
ipv4=is_ipv4)
else:
if is_ipv4:
cmd = 'iptables-restore'
else:
cmd = 'ip6tables-restore'
self.redirect_privsep(
cmd, '-c', run_as_root=True,
process_input=six.b('\n'.join(all_lines)),
attempts=5)
LOG.debug("IPTablesManager.apply completed with success")
def _find_table(self, lines, table_name):

View File

@ -19,6 +19,7 @@ Linux network specific helpers.
import os
import six
from oslo_concurrency import processutils
from oslo_log import log as logging
@ -266,3 +267,25 @@ def add_vlan(bridge_interface, interface, vlan_num):
processutils.execute('ip', 'link', 'add', 'link', bridge_interface,
'name', interface, 'type', 'vlan',
'id', vlan_num, check_exit_code=[0, 2, 254])
@nova.privsep.sys_admin_pctxt.entrypoint
def iptables_get_rules(ipv4=True):
if ipv4:
cmd = 'iptables'
else:
cmd = 'ip6tables'
return processutils.execute('%s-save' % cmd, '-c', attempts=5)
@nova.privsep.sys_admin_pctxt.entrypoint
def iptables_set_rules(rules, ipv4=True):
if ipv4:
cmd = 'iptables'
else:
cmd = 'ip6tables'
processutils.execute('%s-restore' % cmd, '-c',
process_input=six.b('\n'.join(rules)),
attempts=5)

View File

@ -95,6 +95,13 @@ class ServiceFixture(fixtures.Fixture):
self.ctxt = context.get_admin_context()
if self.cell:
context.set_target_cell(self.ctxt, self.cell)
# NOTE(mikal): we don't have root to manipulate iptables, so just
# zero that bit out.
self.useFixture(fixtures.MonkeyPatch(
'nova.network.linux_net.IptablesManager._apply',
lambda _: None))
with mock.patch('nova.context.get_admin_context',
return_value=self.ctxt):
self.service = service.Service.create(**self.kwargs)

View File

@ -373,7 +373,13 @@ class LinuxNetworkTestCase(test.NoDBTestCase):
get_associated)
@mock.patch.object(linux_net.iptables_manager.ipv4['nat'], 'add_rule')
def _test_add_snat_rule(self, expected, is_external, mock_add_rule):
@mock.patch('nova.privsep.linux_net.iptables_get_rules',
return_value=('', ''))
@mock.patch('nova.privsep.linux_net.iptables_set_rules',
return_value=('', ''))
def _test_add_snat_rule(self, expected, is_external,
mock_iptables_set_rules, mock_iptables_get_rules,
mock_add_rule):
def verify_add_rule(chain, rule):
self.assertEqual('snat', chain)
@ -415,7 +421,13 @@ class LinuxNetworkTestCase(test.NoDBTestCase):
@mock.patch.object(fileutils, 'ensure_tree')
@mock.patch.object(os, 'chmod')
def test_update_dhcp_for_nw00(self, mock_chmod, mock_ensure_tree):
@mock.patch('nova.privsep.linux_net.iptables_get_rules',
return_value=('', ''))
@mock.patch('nova.privsep.linux_net.iptables_set_rules',
return_value=('', ''))
def test_update_dhcp_for_nw00(self, mock_iptables_set_rules,
mock_iptables_get_rules, mock_chmod,
mock_ensure_tree):
with mock.patch.object(self.driver, 'write_to_file') \
as mock_write_to_file:
self.flags(use_single_default_gateway=True)
@ -428,7 +440,13 @@ class LinuxNetworkTestCase(test.NoDBTestCase):
@mock.patch.object(fileutils, 'ensure_tree')
@mock.patch.object(os, 'chmod')
def test_update_dhcp_for_nw01(self, mock_chmod, mock_ensure_tree):
@mock.patch('nova.privsep.linux_net.iptables_get_rules',
return_value=('', ''))
@mock.patch('nova.privsep.linux_net.iptables_set_rules',
return_value=('', ''))
def test_update_dhcp_for_nw01(self, mock_iptables_set_rules,
mock_iptables_get_rules, mock_chmod,
mock_ensure_tree):
with mock.patch.object(self.driver, 'write_to_file') \
as mock_write_to_file:
self.flags(use_single_default_gateway=True)
@ -594,9 +612,14 @@ class LinuxNetworkTestCase(test.NoDBTestCase):
@mock.patch('nova.privsep.linux_net.routes_show',
return_value=('fake', 0))
@mock.patch('nova.privsep.linux_net.lookup_ip', return_value=('', ''))
def test_linux_bridge_driver_plug(self, mock_lookup_ip, mock_routes_show,
mock_enabled, mock_add_bridge,
mock_add_rule):
@mock.patch('nova.privsep.linux_net.iptables_get_rules',
return_value=('', ''))
@mock.patch('nova.privsep.linux_net.iptables_set_rules',
return_value=('', ''))
def test_linux_bridge_driver_plug(
self, mock_iptables_set_rules, mock_iptables_get_rules,
mock_lookup_ip, mock_routes_show, mock_enabled, mock_add_bridge,
mock_add_rule):
"""Makes sure plug doesn't drop FORWARD by default.
Ensures bug 890195 doesn't reappear.
@ -644,7 +667,12 @@ class LinuxNetworkTestCase(test.NoDBTestCase):
@mock.patch.object(linux_net.LinuxBridgeInterfaceDriver,
'ensure_vlan_bridge')
def test_vlan_override(self, mock_ensure_vlan_bridge):
@mock.patch('nova.privsep.linux_net.iptables_get_rules',
return_value=('', ''))
@mock.patch('nova.privsep.linux_net.iptables_set_rules',
return_value=('', ''))
def test_vlan_override(self, mock_iptables_set_rules,
mock_iptables_get_rules, mock_ensure_vlan_bridge):
"""Makes sure vlan_interface flag overrides network bridge_interface.
Allows heterogeneous networks a la bug 833426
@ -675,7 +703,12 @@ class LinuxNetworkTestCase(test.NoDBTestCase):
self.assertEqual(3, mock_ensure_vlan_bridge.call_count)
@mock.patch.object(linux_net.LinuxBridgeInterfaceDriver, 'ensure_bridge')
def test_flat_override(self, mock_ensure_bridge):
@mock.patch('nova.privsep.linux_net.iptables_get_rules',
return_value=('', ''))
@mock.patch('nova.privsep.linux_net.iptables_set_rules',
return_value=('', ''))
def test_flat_override(self, mock_iptables_set_rules,
mock_iptables_get_rules, mock_ensure_bridge):
"""Makes sure flat_interface flag overrides network bridge_interface.
Allows heterogeneous networks a la bug 833426
@ -707,7 +740,13 @@ class LinuxNetworkTestCase(test.NoDBTestCase):
@mock.patch('os.chmod')
@mock.patch.object(linux_net, '_add_dhcp_mangle_rule')
@mock.patch.object(linux_net, '_execute')
def _test_dnsmasq_execute(self, mock_execute, mock_add_dhcp_mangle_rule,
@mock.patch('nova.privsep.linux_net.iptables_get_rules',
return_value=('', ''))
@mock.patch('nova.privsep.linux_net.iptables_set_rules',
return_value=('', ''))
def _test_dnsmasq_execute(self, mock_iptables_set_rules,
mock_iptables_get_rules, mock_execute,
mock_add_dhcp_mangle_rule,
mock_chmod, mock_write_to_file,
mock_dnsmasq_pid_for, extra_expected=None):
network_ref = {'id': 'fake',
@ -775,7 +814,12 @@ class LinuxNetworkTestCase(test.NoDBTestCase):
def test_dnsmasq_execute(self):
self._test_dnsmasq_execute()
def test_dnsmasq_execute_dns_servers(self):
@mock.patch('nova.privsep.linux_net.iptables_get_rules',
return_value=('', ''))
@mock.patch('nova.privsep.linux_net.iptables_set_rules',
return_value=('', ''))
def test_dnsmasq_execute_dns_servers(self, mock_iptables_set_rules,
mock_iptables_get_rules):
self.flags(dns_server=['1.1.1.1', '2.2.2.2'])
expected = [
'--no-resolv',
@ -793,15 +837,14 @@ class LinuxNetworkTestCase(test.NoDBTestCase):
self._test_dnsmasq_execute(extra_expected=expected)
@mock.patch('nova.privsep.linux_net.modify_ebtables')
def test_isolated_host(self, mock_modify_ebtables):
@mock.patch('nova.privsep.linux_net.iptables_get_rules',
return_value=('', ''))
@mock.patch('nova.privsep.linux_net.iptables_set_rules',
return_value=('', ''))
def test_isolated_host(self, mock_iptables_set_rules,
mock_iptables_get_rules, mock_modify_ebtables):
self.flags(fake_network=False,
share_dhcp_address=True)
executes = []
def fake_execute(*args, **kwargs):
executes.append(args)
return "", ""
driver = linux_net.LinuxBridgeInterfaceDriver()
def fake_ensure(bridge, interface, network, gateway):
@ -810,7 +853,6 @@ class LinuxNetworkTestCase(test.NoDBTestCase):
self.stub_out('nova.network.linux_net.iptables_manager',
linux_net.IptablesManager())
self.stub_out('nova.network.linux_net.binary_name', 'test')
self.stub_out('nova.utils.execute', fake_execute)
self.stub_out(
'nova.network.linux_net.LinuxBridgeInterfaceDriver.ensure_bridge',
fake_ensure)
@ -823,13 +865,12 @@ class LinuxNetworkTestCase(test.NoDBTestCase):
'bridge_interface': iface}
driver.plug(network, 'fakemac')
expected = [
('iptables-save', '-c'),
('iptables-restore', '-c'),
('ip6tables-save', '-c'),
('ip6tables-restore', '-c'),
]
self.assertEqual(expected, executes)
mock_iptables_get_rules.assert_has_calls([
mock.call(ipv4=True),
mock.call(ipv4=False)])
mock_iptables_set_rules.assert_has_calls([
mock.call(mock.ANY, ipv4=True),
mock.call(mock.ANY, ipv4=False)])
mock_modify_ebtables.assert_has_calls([
mock.call('filter',
['INPUT', '-p', 'ARP', '-i', iface, '--arp-ip-dst',
@ -1084,7 +1125,12 @@ class LinuxNetworkTestCase(test.NoDBTestCase):
self.assertFalse(manager.iptables_apply_deferred)
@mock.patch.object(linux_net.iptables_manager.ipv4['filter'], 'add_rule')
def _test_add_metadata_accept_rule(self, expected, mock_add_rule):
@mock.patch('nova.privsep.linux_net.iptables_get_rules',
return_value=('', ''))
@mock.patch('nova.privsep.linux_net.iptables_set_rules',
return_value=('', ''))
def _test_add_metadata_accept_rule(self, expected, mock_iptables_set_rules,
mock_iptables_get_rules, mock_add_rule):
def verify_add_rule(chain, rule):
self.assertEqual('INPUT', chain)
self.assertEqual(expected, rule)
@ -1094,7 +1140,14 @@ class LinuxNetworkTestCase(test.NoDBTestCase):
mock_add_rule.assert_called_once()
@mock.patch.object(linux_net.iptables_manager.ipv6['filter'], 'add_rule')
def _test_add_metadata_accept_ipv6_rule(self, expected, mock_add_rule):
@mock.patch('nova.privsep.linux_net.iptables_get_rules',
return_value=('', ''))
@mock.patch('nova.privsep.linux_net.iptables_set_rules',
return_value=('', ''))
def _test_add_metadata_accept_ipv6_rule(self, expected,
mock_iptables_set_rules,
mock_iptables_get_rules,
mock_add_rule):
def verify_add_rule(chain, rule):
self.assertEqual('INPUT', chain)
self.assertEqual(expected, rule)
@ -1132,7 +1185,14 @@ class LinuxNetworkTestCase(test.NoDBTestCase):
self._test_add_metadata_accept_ipv6_rule(expected)
@mock.patch.object(linux_net.iptables_manager.ipv4['nat'], 'add_rule')
def _test_add_metadata_forward_rule(self, expected, mock_add_rule):
@mock.patch('nova.privsep.linux_net.iptables_get_rules',
return_value=('', ''))
@mock.patch('nova.privsep.linux_net.iptables_set_rules',
return_value=('', ''))
def _test_add_metadata_forward_rule(self, expected,
mock_iptables_set_rules,
mock_iptables_get_rules,
mock_add_rule):
def verify_add_rule(chain, rule):
self.assertEqual('PREROUTING', chain)
self.assertEqual(expected, rule)

View File

@ -947,12 +947,15 @@ class VlanNetworkTestCase(test.TestCase):
@mock.patch('nova.privsep.linux_net.ipv4_forwarding_check',
return_value=False)
@mock.patch('nova.privsep.linux_net._enable_ipv4_forwarding_inner')
def test_vpn_allocate_fixed_ip(self, mock_forwarding_enable,
mock_forwarding_check,
mock_address_command,
mock_change_ip, mock_lookup_ip,
mock_routes_show, mock_enabled,
mock_add_bridge):
@mock.patch('nova.privsep.linux_net.iptables_get_rules',
return_value=('', ''))
@mock.patch('nova.privsep.linux_net.iptables_set_rules',
return_value=('', ''))
def test_vpn_allocate_fixed_ip(
self, mock_iptables_set_rules, mock_iptables_get_rules,
mock_forwarding_enable, mock_forwarding_check,
mock_address_command, mock_change_ip, mock_lookup_ip,
mock_routes_show, mock_enabled, mock_add_bridge):
self.mox.StubOutWithMock(db, 'fixed_ip_associate')
self.mox.StubOutWithMock(db, 'fixed_ip_update')
self.mox.StubOutWithMock(db,
@ -994,11 +997,15 @@ class VlanNetworkTestCase(test.TestCase):
@mock.patch('nova.privsep.linux_net.ipv4_forwarding_check',
return_value=False)
@mock.patch('nova.privsep.linux_net._enable_ipv4_forwarding_inner')
def test_allocate_fixed_ip(self, mock_forwarding_enable,
mock_forwarding_check, mock_address_command,
mock_change_ip, mock_lookup_ip,
mock_routes_show, mock_enabled,
mock_add_bridge):
@mock.patch('nova.privsep.linux_net.iptables_get_rules',
return_value=('', ''))
@mock.patch('nova.privsep.linux_net.iptables_set_rules',
return_value=('', ''))
def test_allocate_fixed_ip(
self, mock_iptables_set_rules, mock_iptables_get_rules,
mock_forwarding_enable, mock_forwarding_check,
mock_address_command, mock_change_ip, mock_lookup_ip,
mock_routes_show, mock_enabled, mock_add_bridge):
self.stubs.Set(self.network,
'_do_trigger_security_group_members_refresh_for_instance',
lambda *a, **kw: None)
@ -1725,8 +1732,13 @@ class VlanNetworkTestCase(test.TestCase):
@mock.patch('nova.privsep.linux_net.ipv4_forwarding_check',
return_value=False)
@mock.patch('nova.privsep.linux_net._enable_ipv4_forwarding_inner')
@mock.patch('nova.privsep.linux_net.iptables_get_rules',
return_value=('', ''))
@mock.patch('nova.privsep.linux_net.iptables_set_rules',
return_value=('', ''))
def test_add_fixed_ip_instance_without_vpn_requested_networks(
self, mock_forwarding_enable, mock_forwarding_check,
self, mock_iptables_set_rules, mock_iptables_get_rules,
mock_forwarding_enable, mock_forwarding_check,
mock_address_command, mock_change_ip, mock_lookup_ip,
mock_routes_show, mock_enabled, mock_add_bridge):
self.stubs.Set(self.network,
@ -1773,8 +1785,13 @@ class VlanNetworkTestCase(test.TestCase):
@mock.patch('nova.privsep.linux_net.unbind_ip')
@mock.patch('nova.privsep.linux_net.clean_conntrack')
@mock.patch('nova.privsep.linux_net.modify_ebtables')
@mock.patch('nova.privsep.linux_net.iptables_get_rules',
return_value=('', ''))
@mock.patch('nova.privsep.linux_net.iptables_set_rules',
return_value=('', ''))
def test_ip_association_and_allocation_of_other_project(
self, modify_ebtables, clean_conntrack, unbind_ip, bind_ip,
self, mock_iptables_set_rules, mock_iptables_get_rules,
modify_ebtables, clean_conntrack, unbind_ip, bind_ip,
net_get, fixed_get):
"""Makes sure that we cannot deallocaate or disassociate
a public IP of other project.
@ -2895,16 +2912,17 @@ class AllocateTestCase(test.TestCase):
@mock.patch('nova.privsep.linux_net._enable_ipv4_forwarding_inner')
@mock.patch('nova.privsep.linux_net.modify_ebtables')
@mock.patch('nova.privsep.linux_net.add_vlan')
def test_allocate_for_instance(self, mock_add_vlan,
mock_modify_ebtables,
mock_forwarding_enable,
mock_forwarding_check,
mock_clean_conntrack,
mock_address_command,
mock_change_ip, mock_lookup_ip,
mock_routes_show, mock_unbind, mock_bind,
mock_set_macaddr, mock_set_enabled,
mock_set_mtu, mock_add_bridge):
@mock.patch('nova.privsep.linux_net.iptables_get_rules',
return_value=('', ''))
@mock.patch('nova.privsep.linux_net.iptables_set_rules',
return_value=('', ''))
def test_allocate_for_instance(
self, mock_iptables_set_rules, mock_iptables_get_rules,
mock_add_vlan, mock_modify_ebtables, mock_forwarding_enable,
mock_forwarding_check, mock_clean_conntrack, mock_address_command,
mock_change_ip, mock_lookup_ip, mock_routes_show, mock_unbind,
mock_bind, mock_set_macaddr, mock_set_enabled, mock_set_mtu,
mock_add_bridge):
address = "10.10.10.10"
self.flags(auto_assign_floating_ip=True)
@ -2980,15 +2998,16 @@ class AllocateTestCase(test.TestCase):
return_value=False)
@mock.patch('nova.privsep.linux_net._enable_ipv4_forwarding_inner')
@mock.patch('nova.privsep.linux_net.add_vlan')
def test_allocate_for_instance_with_mac(self, mock_add_vlan,
mock_forwarding_enable,
mock_forwarding_check,
mock_address_command,
mock_change_ip,
mock_lookup_ip,
mock_routes_show,
mock_set_addr, mock_enabled,
mock_set_mtu, mock_add_bridge):
@mock.patch('nova.privsep.linux_net.iptables_get_rules',
return_value=('', ''))
@mock.patch('nova.privsep.linux_net.iptables_set_rules',
return_value=('', ''))
def test_allocate_for_instance_with_mac(
self, mock_iptables_set_rules, mock_iptables_get_rules,
mock_add_vlan, mock_forwarding_enable,
mock_forwarding_check, mock_address_command,
mock_change_ip, mock_lookup_ip, mock_routes_show,
mock_set_addr, mock_enabled, mock_set_mtu, mock_add_bridge):
available_macs = set(['ca:fe:de:ad:be:ef'])
inst = db.instance_create(self.context, {'host': HOST,
'display_name': HOST,
@ -3146,10 +3165,13 @@ class FloatingIPTestCase(test.TestCase):
@mock.patch('nova.privsep.linux_net.unbind_ip')
@mock.patch('nova.privsep.linux_net.clean_conntrack')
@mock.patch('nova.privsep.linux_net.modify_ebtables')
def test_deallocation_deleted_instance(self,
mock_modify_ebtables,
mock_clean_conntrack,
mock_unbind_ip):
@mock.patch('nova.privsep.linux_net.iptables_get_rules',
return_value=('', ''))
@mock.patch('nova.privsep.linux_net.iptables_set_rules',
return_value=('', ''))
def test_deallocation_deleted_instance(
self, mock_iptables_set_rules, mock_iptables_get_rules,
mock_modify_ebtables, mock_clean_conntrack, mock_unbind_ip):
self.stubs.Set(self.network, '_teardown_network_on_host',
lambda *args, **kwargs: None)
instance = objects.Instance(context=self.context)
@ -3172,10 +3194,13 @@ class FloatingIPTestCase(test.TestCase):
@mock.patch('nova.privsep.linux_net.unbind_ip')
@mock.patch('nova.privsep.linux_net.clean_conntrack')
@mock.patch('nova.privsep.linux_net.modify_ebtables')
def test_deallocation_duplicate_floating_ip(self,
mock_modify_ebtables,
mock_clean_conntrack,
mock_unbind_ip):
@mock.patch('nova.privsep.linux_net.iptables_get_rules',
return_value=('', ''))
@mock.patch('nova.privsep.linux_net.iptables_set_rules',
return_value=('', ''))
def test_deallocation_duplicate_floating_ip(
self, mock_iptables_set_rules, mock_iptables_get_rules,
mock_modify_ebtables, mock_clean_conntrack, mock_unbind_ip):
self.stubs.Set(self.network, '_teardown_network_on_host',
lambda *args, **kwargs: None)
instance = objects.Instance(context=self.context)

View File

@ -153,7 +153,12 @@ class QuotaIntegrationTestCase(test.TestCase):
self._create_instance(flavor_name='m1.xlarge')
@mock.patch('nova.privsep.linux_net.bind_ip')
def test_too_many_addresses(self, mock_bind_ip):
@mock.patch('nova.privsep.linux_net.iptables_get_rules',
return_value=('', ''))
@mock.patch('nova.privsep.linux_net.iptables_set_rules',
return_value=('', ''))
def test_too_many_addresses(self, mock_iptables_set_rules,
mock_iptables_get_rules, mock_bind_ip):
# This test is specifically relying on nova-network.
self.flags(use_neutron=False,
network_manager='nova.network.manager.FlatDHCPManager')
@ -173,7 +178,12 @@ class QuotaIntegrationTestCase(test.TestCase):
db.floating_ip_destroy(context.get_admin_context(), address)
@mock.patch('nova.privsep.linux_net.bind_ip')
def test_auto_assigned(self, mock_bind_ip):
@mock.patch('nova.privsep.linux_net.iptables_get_rules',
return_value=('', ''))
@mock.patch('nova.privsep.linux_net.iptables_set_rules',
return_value=('', ''))
def test_auto_assigned(self, mock_iptables_set_rules,
mock_iptables_get_rules, mock_bind_ip):
# This test is specifically relying on nova-network.
self.flags(use_neutron=False,
network_manager='nova.network.manager.FlatDHCPManager')

View File

@ -149,10 +149,15 @@ class IptablesFirewallTestCase(test.NoDBTestCase):
inst.info_cache.deleted = False
return inst
@mock.patch.object(linux_net.iptables_manager, "execute")
@mock.patch.object(objects.InstanceList, "get_by_security_group_id")
@mock.patch.object(objects.SecurityGroupRuleList, "get_by_instance")
def test_static_filters(self, mock_secrule, mock_instlist, fake_execute):
@mock.patch('nova.privsep.linux_net.iptables_get_rules',
return_value=('', ''))
@mock.patch('nova.privsep.linux_net.iptables_set_rules',
return_value=('', ''))
def test_static_filters(self, mock_iptables_set_rules,
mock_iptables_get_rules, mock_secrule,
mock_instlist):
UUID = "2674993b-6adb-4733-abd9-a7c10cc1f146"
SRC_UUID = "0e0a76b2-7c52-4bc0-9a60-d83017e42c1a"
instance_ref = self._create_instance_ref(UUID)
@ -215,7 +220,7 @@ class IptablesFirewallTestCase(test.NoDBTestCase):
mock_secrule.return_value = objects.SecurityGroupRuleList(
objects=[r1, r2, r3, r4, r5])
def _fake_instlist(ctxt, id):
def fake_instlist(ctxt, id):
if id == src_secgroup.id:
insts = objects.InstanceList()
insts.objects.append(src_instance_ref)
@ -224,32 +229,26 @@ class IptablesFirewallTestCase(test.NoDBTestCase):
insts = objects.InstanceList()
insts.objects.append(instance_ref)
return insts
mock_instlist.side_effect = fake_instlist
mock_instlist.side_effect = _fake_instlist
def fake_iptables_execute(*cmd, **kwargs):
process_input = kwargs.get('process_input')
if process_input is not None and isinstance(process_input, bytes):
process_input = process_input.decode('utf-8')
if cmd == ('ip6tables-save', '-c'):
return '\n'.join(self.in6_filter_rules), None
if cmd == ('iptables-save', '-c'):
def fake_iptables_get(ipv4=True):
if ipv4:
return '\n'.join(self.in_rules), None
if cmd == ('iptables-restore', '-c'):
lines = process_input.split('\n')
if '*filter' in lines:
self.out_rules = lines
return '', ''
if cmd == ('ip6tables-restore', '-c',):
lines = process_input.split('\n')
if '*filter' in lines:
self.out6_rules = lines
return '', ''
else:
return '\n'.join(self.in6_filter_rules), None
mock_iptables_get_rules.side_effect = fake_iptables_get
def fake_iptables_set(rules, ipv4=True):
if '*filter' in rules:
if ipv4:
self.out_rules = rules
else:
self.out6_rules = rules
return '', ''
mock_iptables_set_rules.side_effect = fake_iptables_set
network_model = _fake_network_info(self, 1)
fake_execute.side_effect = fake_iptables_execute
self.stub_out('nova.objects.Instance.get_network_info',
lambda instance: network_model)
@ -322,7 +321,12 @@ class IptablesFirewallTestCase(test.NoDBTestCase):
self.assertEqual(len(rulesv6), 1)
@mock.patch.object(objects.SecurityGroupRuleList, "get_by_instance")
def test_multinic_iptables(self, mock_secrule):
@mock.patch('nova.privsep.linux_net.iptables_get_rules',
return_value=('', ''))
@mock.patch('nova.privsep.linux_net.iptables_set_rules',
return_value=('', ''))
def test_multinic_iptables(self, mock_iptables_set_rules,
mock_iptables_get_rules, mock_secrule):
mock_secrule.return_value = objects.SecurityGroupRuleList()
ipv4_rules_per_addr = 1
@ -356,8 +360,14 @@ class IptablesFirewallTestCase(test.NoDBTestCase):
@mock.patch.object(firewall.IptablesFirewallDriver,
'add_filters_for_instance')
@mock.patch.object(linux_net.IptablesTable, 'has_chain')
def test_do_refresh_security_group_rules(self, mock_has_chain,
mock_add_filters, mock_instance_rules):
@mock.patch('nova.privsep.linux_net.iptables_get_rules',
return_value=('', ''))
@mock.patch('nova.privsep.linux_net.iptables_set_rules',
return_value=('', ''))
def test_do_refresh_security_group_rules(
self, mock_iptables_set_rules,
mock_iptables_get_rules, mock_has_chain,
mock_add_filters, mock_instance_rules):
instance_ref = self._create_instance_ref()
mock_instance_rules.return_value = (None, None)
@ -402,11 +412,13 @@ class IptablesFirewallTestCase(test.NoDBTestCase):
@mock.patch.object(fakelibvirt.virConnect, "nwfilterDefineXML")
@mock.patch.object(objects.InstanceList, "get_by_security_group_id")
@mock.patch.object(objects.SecurityGroupRuleList, "get_by_instance")
def test_unfilter_instance_undefines_nwfilter(self,
mock_secrule,
mock_instlist,
mock_define,
mock_lookup):
@mock.patch('nova.privsep.linux_net.iptables_get_rules',
return_value=('', ''))
@mock.patch('nova.privsep.linux_net.iptables_set_rules',
return_value=('', ''))
def test_unfilter_instance_undefines_nwfilter(
self, mock_iptables_set_rules, mock_iptables_get_rules,
mock_secrule, mock_instlist, mock_define, mock_lookup):
fakefilter = NWFilterFakes()
mock_lookup.side_effect = fakefilter.nwfilterLookupByName
mock_define.side_effect = fakefilter.filterDefineXMLMock

View File

@ -1145,7 +1145,13 @@ class XenAPIVMTestCase(stubs.XenAPITestBase,
return_value=False)
@mock.patch('nova.privsep.linux_net._enable_ipv4_forwarding_inner')
@mock.patch('nova.privsep.linux_net.add_vlan')
def test_spawn_vlanmanager(self, mock_add_vlan, mock_forwarding_enable,
@mock.patch('nova.privsep.linux_net.iptables_get_rules',
return_value=('', ''))
@mock.patch('nova.privsep.linux_net.iptables_set_rules',
return_value=('', ''))
def test_spawn_vlanmanager(self, mock_iptables_set_rules,
mock_iptables_get_rules,
mock_add_vlan, mock_forwarding_enable,
mock_forwarding_check,
mock_address_command_horrid,
mock_change_ip, mock_set_macaddr,

View File

@ -44,7 +44,8 @@ class Dom0IptablesFirewallDriver(firewall.IptablesFirewallDriver):
super(Dom0IptablesFirewallDriver, self).__init__(**kwargs)
self._session = xenapi_session
# Create IpTablesManager with executor through plugin
self.iptables = linux_net.IptablesManager(self._plugin_execute)
self.iptables = linux_net.IptablesManager(
redirect_privsep_calls_to=self._plugin_execute)
self.iptables.ipv4['filter'].add_chain('sg-fallback')
self.iptables.ipv4['filter'].add_rule('sg-fallback', '-j DROP')
self.iptables.ipv6['filter'].add_chain('sg-fallback')