def test_unfilter_instance_undefines_nwfilters(self): admin_ctxt = context.get_admin_context() fakefilter = NWFilterFakes() self.fw._conn.nwfilterDefineXML = fakefilter.filterDefineXMLMock self.fw._conn.nwfilterLookupByName = fakefilter.nwfilterLookupByName instance_ref = self._create_instance() inst_id = instance_ref['id'] inst_uuid = instance_ref['uuid'] self.security_group = self.setup_and_return_security_group() db.instance_add_security_group(self.context, inst_uuid, self.security_group['id']) instance = db.instance_get(self.context, inst_id) network_info = _fake_network_info(self.stubs, 1) self.fw.setup_basic_filtering(instance, network_info) original_filter_count = len(fakefilter.filters) self.fw.unfilter_instance(instance, network_info) self.assertEqual(original_filter_count - len(fakefilter.filters), 1) db.instance_destroy(admin_ctxt, instance_ref['uuid'])
def test_associate(self): self.stubs.Set(db, 'instance_get', return_server) self.stubs.Set(db, 'instance_get_by_uuid', return_server_by_uuid) self.mox.StubOutWithMock(db, 'instance_add_security_group') db.instance_add_security_group(mox.IgnoreArg(), mox.IgnoreArg(), mox.IgnoreArg()) self.stubs.Set(db, 'security_group_get_by_name', return_security_group_without_instances) self.mox.ReplayAll() body = dict(add_security_group=dict(name="test")) req = fakes.HTTPRequestV3.blank('/servers/1/action') self.manager._add_security_group(req, '1', body)
def test_redefining_nwfilters(self): fakefilter = NWFilterFakes() self.fw._conn.nwfilterDefineXML = fakefilter.filterDefineXMLMock self.fw._conn.nwfilterLookupByName = fakefilter.nwfilterLookupByName instance_ref = self._create_instance() inst_id = instance_ref['id'] inst_uuid = instance_ref['uuid'] self.security_group = self.setup_and_return_security_group() db.instance_add_security_group(self.context, inst_uuid, self.security_group['id']) instance = db.instance_get(self.context, inst_id) network_info = _fake_network_info(self.stubs, 1) self.fw.setup_basic_filtering(instance, network_info) self.fw.setup_basic_filtering(instance, network_info)
def test_multinic_base_filter_selection(self): fakefilter = NWFilterFakes() self.fw._conn.nwfilterDefineXML = fakefilter.filterDefineXMLMock self.fw._conn.nwfilterLookupByName = fakefilter.nwfilterLookupByName instance_ref = self._create_instance() inst_id = instance_ref['id'] inst_uuid = instance_ref['uuid'] self.security_group = self.setup_and_return_security_group() db.instance_add_security_group(self.context, inst_uuid, self.security_group['id']) instance = db.instance_get(self.context, inst_id) network_info = _fake_network_info(self.stubs, 2) network_info[0]['network']['subnets'][0]['meta']['dhcp_server'] = \ '1.1.1.1' self.fw.setup_basic_filtering(instance, network_info) def assert_filterref(instance, vif, expected=None): expected = expected or [] nic_id = vif['address'].replace(':', '') filter_name = self.fw._instance_filter_name(instance, nic_id) f = fakefilter.nwfilterLookupByName(filter_name) tree = etree.fromstring(f.xml) frefs = [fr.get('filter') for fr in tree.findall('filterref')] self.assertEqual(set(expected), set(frefs)) assert_filterref(instance, network_info[0], expected=['nova-base']) assert_filterref(instance, network_info[1], expected=['nova-nodhcp']) db.instance_remove_security_group(self.context, inst_uuid, self.security_group['id']) self.teardown_security_group() db.instance_destroy(context.get_admin_context(), instance_ref['uuid'])
def test_nwfilter_parameters(self): admin_ctxt = context.get_admin_context() fakefilter = NWFilterFakes() self.fw._conn.nwfilterDefineXML = fakefilter.filterDefineXMLMock self.fw._conn.nwfilterLookupByName = fakefilter.nwfilterLookupByName instance_ref = self._create_instance() inst_id = instance_ref['id'] inst_uuid = instance_ref['uuid'] self.security_group = self.setup_and_return_security_group() db.instance_add_security_group(self.context, inst_uuid, self.security_group['id']) instance = db.instance_get(self.context, inst_id) network_info = _fake_network_info(self.stubs, 1) self.fw.setup_basic_filtering(instance, network_info) vif = network_info[0] nic_id = vif['address'].replace(':', '') instance_filter_name = self.fw._instance_filter_name(instance, nic_id) f = fakefilter.nwfilterLookupByName(instance_filter_name) tree = etree.fromstring(f.xml) for fref in tree.findall('filterref'): parameters = fref.findall('./parameter') for parameter in parameters: subnet_v4, subnet_v6 = vif['network']['subnets'] if parameter.get('name') == 'IP': self.assertTrue( _ipv4_like(parameter.get('value'), '192.168')) elif parameter.get('name') == 'DHCPSERVER': dhcp_server = subnet_v4.get('dhcp_server') self.assertEqual(parameter.get('value'), dhcp_server) elif parameter.get('name') == 'RASERVER': ra_server = subnet_v6['gateway']['address'] + "/128" self.assertEqual(parameter.get('value'), ra_server) elif parameter.get('name') == 'PROJNET': ipv4_cidr = subnet_v4['cidr'] net, mask = netutils.get_net_and_mask(ipv4_cidr) self.assertEqual(parameter.get('value'), net) elif parameter.get('name') == 'PROJMASK': ipv4_cidr = subnet_v4['cidr'] net, mask = netutils.get_net_and_mask(ipv4_cidr) self.assertEqual(parameter.get('value'), mask) elif parameter.get('name') == 'PROJNET6': ipv6_cidr = subnet_v6['cidr'] net, prefix = netutils.get_net_and_prefixlen(ipv6_cidr) self.assertEqual(parameter.get('value'), net) elif parameter.get('name') == 'PROJMASK6': ipv6_cidr = subnet_v6['cidr'] net, prefix = netutils.get_net_and_prefixlen(ipv6_cidr) self.assertEqual(parameter.get('value'), prefix) else: raise exception.InvalidParameterValue('unknown parameter ' 'in filter') db.instance_destroy(admin_ctxt, instance_ref['uuid'])
def test_creates_base_rule_first(self): # These come pre-defined by libvirt self.defined_filters = [ 'no-mac-spoofing', 'no-ip-spoofing', 'no-arp-spoofing', 'allow-dhcp-server' ] self.recursive_depends = {} for f in self.defined_filters: self.recursive_depends[f] = [] def _filterDefineXMLMock(xml): dom = xml_to_dom(xml) name = dom.firstChild.getAttribute('name') self.recursive_depends[name] = [] for f in dom.getElementsByTagName('filterref'): ref = f.getAttribute('filter') self.assertTrue( ref in self.defined_filters, ('%s referenced filter that does ' + 'not yet exist: %s') % (name, ref)) dependencies = [ref] + self.recursive_depends[ref] self.recursive_depends[name] += dependencies self.defined_filters.append(name) return True self.fake_libvirt_connection.nwfilterDefineXML = _filterDefineXMLMock instance_ref = db.instance_create(self.context, { 'user_id': 'fake', 'project_id': 'fake' }) inst_id = instance_ref['id'] ip = '10.11.12.13' network_ref = db.project_get_network(self.context, 'fake') fixed_ip = {'address': ip, 'network_id': network_ref['id']} admin_ctxt = context.get_admin_context() db.fixed_ip_create(admin_ctxt, fixed_ip) db.fixed_ip_update(admin_ctxt, ip, { 'allocated': True, 'instance_id': instance_ref['id'] }) def _ensure_all_called(): instance_filter = 'nova-instance-%s' % instance_ref['name'] secgroup_filter = 'nova-secgroup-%s' % self.security_group['id'] for required in [ secgroup_filter, 'allow-dhcp-server', 'no-arp-spoofing', 'no-ip-spoofing', 'no-mac-spoofing' ]: self.assertTrue( required in self.recursive_depends[instance_filter], "Instance's filter does not include %s" % required) self.security_group = self.setup_and_return_security_group() db.instance_add_security_group(self.context, inst_id, self.security_group.id) instance = db.instance_get(self.context, inst_id) self.fw.setup_basic_filtering(instance) self.fw.prepare_instance_filter(instance) self.fw.apply_instance_filter(instance) _ensure_all_called() self.teardown_security_group() db.instance_destroy(admin_ctxt, instance_ref['id'])
def test_static_filters(self): instance_ref = db.instance_create( self.context, { 'user_id': 'fake', 'project_id': 'fake', 'mac_address': '56:12:12:12:12:12' }) ip = '10.11.12.13' network_ref = db.project_get_network(self.context, 'fake') fixed_ip = {'address': ip, 'network_id': network_ref['id']} admin_ctxt = context.get_admin_context() db.fixed_ip_create(admin_ctxt, fixed_ip) db.fixed_ip_update(admin_ctxt, ip, { 'allocated': True, 'instance_id': instance_ref['id'] }) secgroup = db.security_group_create( admin_ctxt, { 'user_id': 'fake', 'project_id': 'fake', 'name': 'testgroup', 'description': 'test group' }) db.security_group_rule_create( admin_ctxt, { 'parent_group_id': secgroup['id'], 'protocol': 'icmp', 'from_port': -1, 'to_port': -1, 'cidr': '192.168.11.0/24' }) db.security_group_rule_create( admin_ctxt, { 'parent_group_id': secgroup['id'], 'protocol': 'icmp', 'from_port': 8, 'to_port': -1, 'cidr': '192.168.11.0/24' }) db.security_group_rule_create( admin_ctxt, { 'parent_group_id': secgroup['id'], 'protocol': 'tcp', 'from_port': 80, 'to_port': 81, 'cidr': '192.168.10.0/24' }) db.instance_add_security_group(admin_ctxt, instance_ref['id'], secgroup['id']) instance_ref = db.instance_get(admin_ctxt, instance_ref['id']) # self.fw.add_instance(instance_ref) def fake_iptables_execute(*cmd, **kwargs): process_input = kwargs.get('process_input', None) if cmd == ('sudo', 'ip6tables-save', '-t', 'filter'): return '\n'.join(self.in6_filter_rules), None if cmd == ('sudo', 'iptables-save', '-t', 'filter'): return '\n'.join(self.in_filter_rules), None if cmd == ('sudo', 'iptables-save', '-t', 'nat'): return '\n'.join(self.in_nat_rules), None if cmd == ('sudo', 'iptables-restore'): lines = process_input.split('\n') if '*filter' in lines: self.out_rules = lines return '', '' if cmd == ('sudo', 'ip6tables-restore'): lines = process_input.split('\n') if '*filter' in lines: self.out6_rules = lines return '', '' print cmd, kwargs from nova.network import linux_net linux_net.iptables_manager.execute = fake_iptables_execute self.fw.prepare_instance_filter(instance_ref) self.fw.apply_instance_filter(instance_ref) in_rules = filter(lambda l: not l.startswith('#'), self.in_filter_rules) for rule in in_rules: if not 'nova' in rule: self.assertTrue(rule in self.out_rules, 'Rule went missing: %s' % rule) instance_chain = None for rule in self.out_rules: # This is pretty crude, but it'll do for now if '-d 10.11.12.13 -j' in rule: instance_chain = rule.split(' ')[-1] break self.assertTrue(instance_chain, "The instance chain wasn't added") security_group_chain = None for rule in self.out_rules: # This is pretty crude, but it'll do for now if '-A %s -j' % instance_chain in rule: security_group_chain = rule.split(' ')[-1] break self.assertTrue(security_group_chain, "The security group chain wasn't added") regex = re.compile('-A .* -p icmp -s 192.168.11.0/24 -j ACCEPT') self.assertTrue( len(filter(regex.match, self.out_rules)) > 0, "ICMP acceptance rule wasn't added") regex = re.compile('-A .* -p icmp -s 192.168.11.0/24 -m icmp ' '--icmp-type 8 -j ACCEPT') self.assertTrue( len(filter(regex.match, self.out_rules)) > 0, "ICMP Echo Request acceptance rule wasn't added") regex = re.compile('-A .* -p tcp -s 192.168.10.0/24 -m multiport ' '--dports 80:81 -j ACCEPT') self.assertTrue( len(filter(regex.match, self.out_rules)) > 0, "TCP port 80/81 acceptance rule wasn't added") db.instance_destroy(admin_ctxt, instance_ref['id'])
def test_creates_base_rule_first(self): # These come pre-defined by libvirt self.defined_filters = ["no-mac-spoofing", "no-ip-spoofing", "no-arp-spoofing", "allow-dhcp-server"] self.recursive_depends = {} for f in self.defined_filters: self.recursive_depends[f] = [] def _filterDefineXMLMock(xml): dom = xml_to_dom(xml) name = dom.firstChild.getAttribute("name") self.recursive_depends[name] = [] for f in dom.getElementsByTagName("filterref"): ref = f.getAttribute("filter") self.assertTrue( ref in self.defined_filters, ("%s referenced filter that does " + "not yet exist: %s") % (name, ref) ) dependencies = [ref] + self.recursive_depends[ref] self.recursive_depends[name] += dependencies self.defined_filters.append(name) return True self.fake_libvirt_connection.nwfilterDefineXML = _filterDefineXMLMock instance_ref = db.instance_create(self.context, {"user_id": "fake", "project_id": "fake"}) inst_id = instance_ref["id"] ip = "10.11.12.13" network_ref = db.project_get_network(self.context, "fake") fixed_ip = {"address": ip, "network_id": network_ref["id"]} admin_ctxt = context.get_admin_context() db.fixed_ip_create(admin_ctxt, fixed_ip) db.fixed_ip_update(admin_ctxt, ip, {"allocated": True, "instance_id": instance_ref["id"]}) def _ensure_all_called(): instance_filter = "nova-instance-%s" % instance_ref["name"] secgroup_filter = "nova-secgroup-%s" % self.security_group["id"] for required in [ secgroup_filter, "allow-dhcp-server", "no-arp-spoofing", "no-ip-spoofing", "no-mac-spoofing", ]: self.assertTrue( required in self.recursive_depends[instance_filter], "Instance's filter does not include %s" % required, ) self.security_group = self.setup_and_return_security_group() db.instance_add_security_group(self.context, inst_id, self.security_group.id) instance = db.instance_get(self.context, inst_id) self.fw.setup_basic_filtering(instance) self.fw.prepare_instance_filter(instance) self.fw.apply_instance_filter(instance) _ensure_all_called() self.teardown_security_group() db.instance_destroy(admin_ctxt, instance_ref["id"])
def test_static_filters(self): instance_ref = db.instance_create( self.context, {"user_id": "fake", "project_id": "fake", "mac_address": "56:12:12:12:12:12"} ) ip = "10.11.12.13" network_ref = db.project_get_network(self.context, "fake") fixed_ip = {"address": ip, "network_id": network_ref["id"]} admin_ctxt = context.get_admin_context() db.fixed_ip_create(admin_ctxt, fixed_ip) db.fixed_ip_update(admin_ctxt, ip, {"allocated": True, "instance_id": instance_ref["id"]}) secgroup = db.security_group_create( admin_ctxt, {"user_id": "fake", "project_id": "fake", "name": "testgroup", "description": "test group"} ) db.security_group_rule_create( admin_ctxt, { "parent_group_id": secgroup["id"], "protocol": "icmp", "from_port": -1, "to_port": -1, "cidr": "192.168.11.0/24", }, ) db.security_group_rule_create( admin_ctxt, { "parent_group_id": secgroup["id"], "protocol": "icmp", "from_port": 8, "to_port": -1, "cidr": "192.168.11.0/24", }, ) db.security_group_rule_create( admin_ctxt, { "parent_group_id": secgroup["id"], "protocol": "tcp", "from_port": 80, "to_port": 81, "cidr": "192.168.10.0/24", }, ) db.instance_add_security_group(admin_ctxt, instance_ref["id"], secgroup["id"]) instance_ref = db.instance_get(admin_ctxt, instance_ref["id"]) # self.fw.add_instance(instance_ref) def fake_iptables_execute(cmd, process_input=None): if cmd == "sudo ip6tables-save -t filter": return "\n".join(self.in6_rules), None if cmd == "sudo iptables-save -t filter": return "\n".join(self.in_rules), None if cmd == "sudo iptables-restore": self.out_rules = process_input.split("\n") return "", "" if cmd == "sudo ip6tables-restore": self.out6_rules = process_input.split("\n") return "", "" self.fw.execute = fake_iptables_execute self.fw.prepare_instance_filter(instance_ref) self.fw.apply_instance_filter(instance_ref) in_rules = filter(lambda l: not l.startswith("#"), self.in_rules) for rule in in_rules: if not "nova" in rule: self.assertTrue(rule in self.out_rules, "Rule went missing: %s" % rule) instance_chain = None for rule in self.out_rules: # This is pretty crude, but it'll do for now if "-d 10.11.12.13 -j" in rule: instance_chain = rule.split(" ")[-1] break self.assertTrue(instance_chain, "The instance chain wasn't added") security_group_chain = None for rule in self.out_rules: # This is pretty crude, but it'll do for now if "-A %s -j" % instance_chain in rule: security_group_chain = rule.split(" ")[-1] break self.assertTrue(security_group_chain, "The security group chain wasn't added") self.assertTrue( "-A %s -p icmp -s 192.168.11.0/24 -j ACCEPT" % security_group_chain in self.out_rules, "ICMP acceptance rule wasn't added", ) self.assertTrue( "-A %s -p icmp -s 192.168.11.0/24 -m icmp --icmp-type " "8 -j ACCEPT" % security_group_chain in self.out_rules, "ICMP Echo Request acceptance rule wasn't added", ) self.assertTrue( "-A %s -p tcp -s 192.168.10.0/24 -m multiport " "--dports 80:81 -j ACCEPT" % security_group_chain in self.out_rules, "TCP port 80/81 acceptance rule wasn't added", ) db.instance_destroy(admin_ctxt, instance_ref["id"])
def test_static_filters(self): instance_ref = db.instance_create(self.context, {'user_id': 'fake', 'project_id': 'fake', 'mac_address': '56:12:12:12:12:12'}) ip = '10.11.12.13' network_ref = db.project_get_network(self.context, 'fake') fixed_ip = {'address': ip, 'network_id': network_ref['id']} admin_ctxt = context.get_admin_context() db.fixed_ip_create(admin_ctxt, fixed_ip) db.fixed_ip_update(admin_ctxt, ip, {'allocated': True, 'instance_id': instance_ref['id']}) secgroup = db.security_group_create(admin_ctxt, {'user_id': 'fake', 'project_id': 'fake', 'name': 'testgroup', 'description': 'test group'}) db.security_group_rule_create(admin_ctxt, {'parent_group_id': secgroup['id'], 'protocol': 'icmp', 'from_port': -1, 'to_port': -1, 'cidr': '192.168.11.0/24'}) db.security_group_rule_create(admin_ctxt, {'parent_group_id': secgroup['id'], 'protocol': 'icmp', 'from_port': 8, 'to_port': -1, 'cidr': '192.168.11.0/24'}) db.security_group_rule_create(admin_ctxt, {'parent_group_id': secgroup['id'], 'protocol': 'tcp', 'from_port': 80, 'to_port': 81, 'cidr': '192.168.10.0/24'}) db.instance_add_security_group(admin_ctxt, instance_ref['id'], secgroup['id']) instance_ref = db.instance_get(admin_ctxt, instance_ref['id']) # self.fw.add_instance(instance_ref) def fake_iptables_execute(cmd, process_input=None): if cmd == 'sudo ip6tables-save -t filter': return '\n'.join(self.in6_rules), None if cmd == 'sudo iptables-save -t filter': return '\n'.join(self.in_rules), None if cmd == 'sudo iptables-restore': self.out_rules = process_input.split('\n') return '', '' if cmd == 'sudo ip6tables-restore': self.out6_rules = process_input.split('\n') return '', '' self.fw.execute = fake_iptables_execute self.fw.prepare_instance_filter(instance_ref) self.fw.apply_instance_filter(instance_ref) in_rules = filter(lambda l: not l.startswith('#'), self.in_rules) for rule in in_rules: if not 'nova' in rule: self.assertTrue(rule in self.out_rules, 'Rule went missing: %s' % rule) instance_chain = None for rule in self.out_rules: # This is pretty crude, but it'll do for now if '-d 10.11.12.13 -j' in rule: instance_chain = rule.split(' ')[-1] break self.assertTrue(instance_chain, "The instance chain wasn't added") security_group_chain = None for rule in self.out_rules: # This is pretty crude, but it'll do for now if '-A %s -j' % instance_chain in rule: security_group_chain = rule.split(' ')[-1] break self.assertTrue(security_group_chain, "The security group chain wasn't added") self.assertTrue('-A %s -p icmp -s 192.168.11.0/24 -j ACCEPT' % \ security_group_chain in self.out_rules, "ICMP acceptance rule wasn't added") self.assertTrue('-A %s -p icmp -s 192.168.11.0/24 -m icmp --icmp-type ' '8 -j ACCEPT' % security_group_chain in self.out_rules, "ICMP Echo Request acceptance rule wasn't added") self.assertTrue('-A %s -p tcp -s 192.168.10.0/24 -m multiport ' '--dports 80:81 -j ACCEPT' % security_group_chain \ in self.out_rules, "TCP port 80/81 acceptance rule wasn't added")
def test_creates_base_rule_first(self): # These come pre-defined by libvirt self.defined_filters = ['no-mac-spoofing', 'no-ip-spoofing', 'no-arp-spoofing', 'allow-dhcp-server'] self.recursive_depends = {} for f in self.defined_filters: self.recursive_depends[f] = [] def _filterDefineXMLMock(xml): dom = minidom.parseString(xml) name = dom.firstChild.getAttribute('name') self.recursive_depends[name] = [] for f in dom.getElementsByTagName('filterref'): ref = f.getAttribute('filter') self.assertTrue(ref in self.defined_filters, ('%s referenced filter that does ' + 'not yet exist: %s') % (name, ref)) dependencies = [ref] + self.recursive_depends[ref] self.recursive_depends[name] += dependencies self.defined_filters.append(name) return True self.fake_libvirt_connection.nwfilterDefineXML = _filterDefineXMLMock instance_ref = self._create_instance() inst_id = instance_ref['id'] inst_uuid = instance_ref['uuid'] def _ensure_all_called(mac, allow_dhcp): instance_filter = 'nova-instance-%s-%s' % (instance_ref['name'], mac.translate({ord(':'): None})) requiredlist = ['no-arp-spoofing', 'no-ip-spoofing', 'no-mac-spoofing'] required_not_list = [] if allow_dhcp: requiredlist.append('allow-dhcp-server') else: required_not_list.append('allow-dhcp-server') for required in requiredlist: self.assertTrue(required in self.recursive_depends[instance_filter], "Instance's filter does not include %s" % required) for required_not in required_not_list: self.assertFalse(required_not in self.recursive_depends[instance_filter], "Instance filter includes %s" % required_not) self.security_group = self.setup_and_return_security_group() db.instance_add_security_group(self.context, inst_uuid, self.security_group['id']) instance = db.instance_get(self.context, inst_id) network_info = _fake_network_info(self.stubs, 1) # since there is one (network_info) there is one vif # pass this vif's mac to _ensure_all_called() # to set the instance_filter properly mac = network_info[0]['address'] network_info[0]['network']['subnets'][0]['meta']['dhcp_server'] = \ '1.1.1.1' self.fw.setup_basic_filtering(instance, network_info) allow_dhcp = True _ensure_all_called(mac, allow_dhcp) network_info[0]['network']['subnets'][0]['meta']['dhcp_server'] = None self.fw.setup_basic_filtering(instance, network_info) allow_dhcp = False _ensure_all_called(mac, allow_dhcp) db.instance_remove_security_group(self.context, inst_uuid, self.security_group['id']) self.teardown_security_group() db.instance_destroy(context.get_admin_context(), instance_ref['uuid'])
def test_static_filters(self): instance_ref = self._create_instance_ref() ip = '10.11.12.13' network_ref = db.project_get_network(self.context, 'fake') fixed_ip = {'address': ip, 'network_id': network_ref['id']} admin_ctxt = context.get_admin_context() db.fixed_ip_create(admin_ctxt, fixed_ip) db.fixed_ip_update(admin_ctxt, ip, {'allocated': True, 'instance_id': instance_ref['id']}) secgroup = db.security_group_create(admin_ctxt, {'user_id': 'fake', 'project_id': 'fake', 'name': 'testgroup', 'description': 'test group'}) db.security_group_rule_create(admin_ctxt, {'parent_group_id': secgroup['id'], 'protocol': 'icmp', 'from_port': -1, 'to_port': -1, 'cidr': '192.168.11.0/24'}) db.security_group_rule_create(admin_ctxt, {'parent_group_id': secgroup['id'], 'protocol': 'icmp', 'from_port': 8, 'to_port': -1, 'cidr': '192.168.11.0/24'}) db.security_group_rule_create(admin_ctxt, {'parent_group_id': secgroup['id'], 'protocol': 'tcp', 'from_port': 80, 'to_port': 81, 'cidr': '192.168.10.0/24'}) db.instance_add_security_group(admin_ctxt, instance_ref['id'], secgroup['id']) instance_ref = db.instance_get(admin_ctxt, instance_ref['id']) # self.fw.add_instance(instance_ref) def fake_iptables_execute(*cmd, **kwargs): process_input = kwargs.get('process_input', None) if cmd == ('sudo', 'ip6tables-save', '-t', 'filter'): return '\n'.join(self.in6_filter_rules), None if cmd == ('sudo', 'iptables-save', '-t', 'filter'): return '\n'.join(self.in_filter_rules), None if cmd == ('sudo', 'iptables-save', '-t', 'nat'): return '\n'.join(self.in_nat_rules), None if cmd == ('sudo', 'iptables-restore'): lines = process_input.split('\n') if '*filter' in lines: self.out_rules = lines return '', '' if cmd == ('sudo', 'ip6tables-restore'): lines = process_input.split('\n') if '*filter' in lines: self.out6_rules = lines return '', '' print cmd, kwargs from nova.network import linux_net linux_net.iptables_manager.execute = fake_iptables_execute self.fw.prepare_instance_filter(instance_ref) self.fw.apply_instance_filter(instance_ref) in_rules = filter(lambda l: not l.startswith('#'), self.in_filter_rules) for rule in in_rules: if not 'nova' in rule: self.assertTrue(rule in self.out_rules, 'Rule went missing: %s' % rule) instance_chain = None for rule in self.out_rules: # This is pretty crude, but it'll do for now if '-d 10.11.12.13 -j' in rule: instance_chain = rule.split(' ')[-1] break self.assertTrue(instance_chain, "The instance chain wasn't added") security_group_chain = None for rule in self.out_rules: # This is pretty crude, but it'll do for now if '-A %s -j' % instance_chain in rule: security_group_chain = rule.split(' ')[-1] break self.assertTrue(security_group_chain, "The security group chain wasn't added") regex = re.compile('-A .* -p icmp -s 192.168.11.0/24 -j ACCEPT') self.assertTrue(len(filter(regex.match, self.out_rules)) > 0, "ICMP acceptance rule wasn't added") regex = re.compile('-A .* -p icmp -s 192.168.11.0/24 -m icmp ' '--icmp-type 8 -j ACCEPT') self.assertTrue(len(filter(regex.match, self.out_rules)) > 0, "ICMP Echo Request acceptance rule wasn't added") regex = re.compile('-A .* -p tcp -s 192.168.10.0/24 -m multiport ' '--dports 80:81 -j ACCEPT') self.assertTrue(len(filter(regex.match, self.out_rules)) > 0, "TCP port 80/81 acceptance rule wasn't added") db.instance_destroy(admin_ctxt, instance_ref['id'])
def test_nwfilter_parameters(self): admin_ctxt = context.get_admin_context() fakefilter = NWFilterFakes() self.fw._conn.nwfilterDefineXML = fakefilter.filterDefineXMLMock self.fw._conn.nwfilterLookupByName = fakefilter.nwfilterLookupByName instance_ref = self._create_instance() inst_id = instance_ref['id'] inst_uuid = instance_ref['uuid'] self.security_group = self.setup_and_return_security_group() db.instance_add_security_group(self.context, inst_uuid, self.security_group['id']) instance = db.instance_get(self.context, inst_id) network_info = _fake_network_info(self.stubs, 1) self.fw.setup_basic_filtering(instance, network_info) vif = network_info[0] nic_id = vif['address'].replace(':', '') instance_filter_name = self.fw._instance_filter_name(instance, nic_id) f = fakefilter.nwfilterLookupByName(instance_filter_name) tree = etree.fromstring(f.xml) for fref in tree.findall('filterref'): parameters = fref.findall('./parameter') for parameter in parameters: subnet_v4, subnet_v6 = vif['network']['subnets'] if parameter.get('name') == 'IP': self.assertTrue(_ipv4_like(parameter.get('value'), '192.168')) elif parameter.get('name') == 'DHCPSERVER': dhcp_server = subnet_v4.get('dhcp_server') self.assertEqual(parameter.get('value'), dhcp_server) elif parameter.get('name') == 'RASERVER': ra_server = subnet_v6['gateway']['address'] + "/128" self.assertEqual(parameter.get('value'), ra_server) elif parameter.get('name') == 'PROJNET': ipv4_cidr = subnet_v4['cidr'] net, mask = netutils.get_net_and_mask(ipv4_cidr) self.assertEqual(parameter.get('value'), net) elif parameter.get('name') == 'PROJMASK': ipv4_cidr = subnet_v4['cidr'] net, mask = netutils.get_net_and_mask(ipv4_cidr) self.assertEqual(parameter.get('value'), mask) elif parameter.get('name') == 'PROJNET6': ipv6_cidr = subnet_v6['cidr'] net, prefix = netutils.get_net_and_prefixlen(ipv6_cidr) self.assertEqual(parameter.get('value'), net) elif parameter.get('name') == 'PROJMASK6': ipv6_cidr = subnet_v6['cidr'] net, prefix = netutils.get_net_and_prefixlen(ipv6_cidr) self.assertEqual(parameter.get('value'), prefix) else: raise exception.InvalidParameterValue('unknown parameter ' 'in filter') db.instance_destroy(admin_ctxt, instance_ref['uuid'])
def test_creates_base_rule_first(self): # These come pre-defined by libvirt self.defined_filters = [ 'no-mac-spoofing', 'no-ip-spoofing', 'no-arp-spoofing', 'allow-dhcp-server' ] self.recursive_depends = {} for f in self.defined_filters: self.recursive_depends[f] = [] def _filterDefineXMLMock(xml): dom = minidom.parseString(xml) name = dom.firstChild.getAttribute('name') self.recursive_depends[name] = [] for f in dom.getElementsByTagName('filterref'): ref = f.getAttribute('filter') self.assertTrue( ref in self.defined_filters, ('%s referenced filter that does ' + 'not yet exist: %s') % (name, ref)) dependencies = [ref] + self.recursive_depends[ref] self.recursive_depends[name] += dependencies self.defined_filters.append(name) return True self.fake_libvirt_connection.nwfilterDefineXML = _filterDefineXMLMock instance_ref = self._create_instance() inst_id = instance_ref['id'] inst_uuid = instance_ref['uuid'] def _ensure_all_called(mac, allow_dhcp): instance_filter = 'nova-instance-%s-%s' % ( instance_ref['name'], mac.translate({ord(':'): None})) requiredlist = [ 'no-arp-spoofing', 'no-ip-spoofing', 'no-mac-spoofing' ] required_not_list = [] if allow_dhcp: requiredlist.append('allow-dhcp-server') else: required_not_list.append('allow-dhcp-server') for required in requiredlist: self.assertTrue( required in self.recursive_depends[instance_filter], "Instance's filter does not include %s" % required) for required_not in required_not_list: self.assertFalse( required_not in self.recursive_depends[instance_filter], "Instance filter includes %s" % required_not) self.security_group = self.setup_and_return_security_group() db.instance_add_security_group(self.context, inst_uuid, self.security_group['id']) instance = db.instance_get(self.context, inst_id) network_info = _fake_network_info(self.stubs, 1) # since there is one (network_info) there is one vif # pass this vif's mac to _ensure_all_called() # to set the instance_filter properly mac = network_info[0]['address'] network_info[0]['network']['subnets'][0]['meta']['dhcp_server'] = \ '1.1.1.1' self.fw.setup_basic_filtering(instance, network_info) allow_dhcp = True _ensure_all_called(mac, allow_dhcp) network_info[0]['network']['subnets'][0]['meta']['dhcp_server'] = None self.fw.setup_basic_filtering(instance, network_info) allow_dhcp = False _ensure_all_called(mac, allow_dhcp) db.instance_remove_security_group(self.context, inst_uuid, self.security_group['id']) self.teardown_security_group() db.instance_destroy(context.get_admin_context(), instance_ref['uuid'])
def test_static_filters(self, mock_lock): mock_lock.return_value = threading.Semaphore() instance_ref = self._create_instance_ref() src_instance_ref = self._create_instance_ref() admin_ctxt = context.get_admin_context() secgroup = db.security_group_create( admin_ctxt, { 'user_id': 'fake', 'project_id': 'fake', 'name': 'testgroup', 'description': 'test group' }) src_secgroup = db.security_group_create( admin_ctxt, { 'user_id': 'fake', 'project_id': 'fake', 'name': 'testsourcegroup', 'description': 'src group' }) db.security_group_rule_create( admin_ctxt, { 'parent_group_id': secgroup['id'], 'protocol': 'icmp', 'from_port': -1, 'to_port': -1, 'cidr': '192.168.11.0/24' }) db.security_group_rule_create( admin_ctxt, { 'parent_group_id': secgroup['id'], 'protocol': 'icmp', 'from_port': 8, 'to_port': -1, 'cidr': '192.168.11.0/24' }) db.security_group_rule_create( admin_ctxt, { 'parent_group_id': secgroup['id'], 'protocol': 'tcp', 'from_port': 80, 'to_port': 81, 'cidr': '192.168.10.0/24' }) db.security_group_rule_create( admin_ctxt, { 'parent_group_id': secgroup['id'], 'protocol': 'tcp', 'from_port': 80, 'to_port': 81, 'group_id': src_secgroup['id'] }) db.security_group_rule_create(admin_ctxt, { 'parent_group_id': secgroup['id'], 'group_id': src_secgroup['id'] }) db.instance_add_security_group(admin_ctxt, instance_ref['uuid'], secgroup['id']) db.instance_add_security_group(admin_ctxt, src_instance_ref['uuid'], src_secgroup['id']) instance_ref = db.instance_get(admin_ctxt, instance_ref['id']) src_instance_ref = db.instance_get(admin_ctxt, src_instance_ref['id']) def fake_iptables_execute(*cmd, **kwargs): process_input = kwargs.get('process_input', None) if cmd == ('ip6tables-save', '-c'): return '\n'.join(self.in6_filter_rules), None if cmd == ('iptables-save', '-c'): 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 '', '' network_model = _fake_network_info(self.stubs, 1) linux_net.iptables_manager.execute = fake_iptables_execute self.stubs.Set(compute_utils, 'get_nw_info_for_instance', lambda instance: network_model) self.fw.prepare_instance_filter(instance_ref, network_model) self.fw.apply_instance_filter(instance_ref, network_model) in_rules = filter(lambda l: not l.startswith('#'), self.in_rules) for rule in in_rules: if 'nova' not in rule: self.assertTrue(rule in self.out_rules, 'Rule went missing: %s' % rule) instance_chain = None for rule in self.out_rules: # This is pretty crude, but it'll do for now # last two octets change if re.search('-d 192.168.[0-9]{1,3}.[0-9]{1,3} -j', rule): instance_chain = rule.split(' ')[-1] break self.assertTrue(instance_chain, "The instance chain wasn't added") security_group_chain = None for rule in self.out_rules: # This is pretty crude, but it'll do for now if '-A %s -j' % instance_chain in rule: security_group_chain = rule.split(' ')[-1] break self.assertTrue(security_group_chain, "The security group chain wasn't added") regex = re.compile('\[0\:0\] -A .* -j ACCEPT -p icmp ' '-s 192.168.11.0/24') self.assertTrue( len(filter(regex.match, self.out_rules)) > 0, "ICMP acceptance rule wasn't added") regex = re.compile('\[0\:0\] -A .* -j ACCEPT -p icmp -m icmp ' '--icmp-type 8 -s 192.168.11.0/24') self.assertTrue( len(filter(regex.match, self.out_rules)) > 0, "ICMP Echo Request acceptance rule wasn't added") for ip in network_model.fixed_ips(): if ip['version'] != 4: continue regex = re.compile('\[0\:0\] -A .* -j ACCEPT -p tcp -m multiport ' '--dports 80:81 -s %s' % ip['address']) self.assertTrue( len(filter(regex.match, self.out_rules)) > 0, "TCP port 80/81 acceptance rule wasn't added") regex = re.compile('\[0\:0\] -A .* -j ACCEPT -s ' '%s' % ip['address']) self.assertTrue( len(filter(regex.match, self.out_rules)) > 0, "Protocol/port-less acceptance rule wasn't added") regex = re.compile('\[0\:0\] -A .* -j ACCEPT -p tcp ' '-m multiport --dports 80:81 -s 192.168.10.0/24') self.assertTrue( len(filter(regex.match, self.out_rules)) > 0, "TCP port 80/81 acceptance rule wasn't added") db.instance_destroy(admin_ctxt, instance_ref['uuid'])
def test_creates_base_rule_first(self): # These come pre-defined by libvirt self.defined_filters = ['no-mac-spoofing', 'no-ip-spoofing', 'no-arp-spoofing', 'allow-dhcp-server'] self.recursive_depends = {} for f in self.defined_filters: self.recursive_depends[f] = [] def _filterDefineXMLMock(xml): dom = xml_to_dom(xml) name = dom.firstChild.getAttribute('name') self.recursive_depends[name] = [] for f in dom.getElementsByTagName('filterref'): ref = f.getAttribute('filter') self.assertTrue(ref in self.defined_filters, ('%s referenced filter that does ' + 'not yet exist: %s') % (name, ref)) dependencies = [ref] + self.recursive_depends[ref] self.recursive_depends[name] += dependencies self.defined_filters.append(name) return True self.fake_libvirt_connection.nwfilterDefineXML = _filterDefineXMLMock instance_ref = self._create_instance() inst_id = instance_ref['id'] ip = '10.11.12.13' network_ref = db.project_get_network(self.context, 'fake') fixed_ip = {'address': ip, 'network_id': network_ref['id']} admin_ctxt = context.get_admin_context() db.fixed_ip_create(admin_ctxt, fixed_ip) db.fixed_ip_update(admin_ctxt, ip, {'allocated': True, 'instance_id': inst_id}) def _ensure_all_called(): instance_filter = 'nova-instance-%s-%s' % (instance_ref['name'], '00A0C914C829') secgroup_filter = 'nova-secgroup-%s' % self.security_group['id'] for required in [secgroup_filter, 'allow-dhcp-server', 'no-arp-spoofing', 'no-ip-spoofing', 'no-mac-spoofing']: self.assertTrue(required in self.recursive_depends[instance_filter], "Instance's filter does not include %s" % required) self.security_group = self.setup_and_return_security_group() db.instance_add_security_group(self.context, inst_id, self.security_group.id) instance = db.instance_get(self.context, inst_id) self.fw.setup_basic_filtering(instance) self.fw.prepare_instance_filter(instance) self.fw.apply_instance_filter(instance) _ensure_all_called() self.teardown_security_group() db.instance_destroy(admin_ctxt, instance_ref['id'])
def test_static_filters(self, mock_lock): mock_lock.return_value = threading.Semaphore() instance_ref = self._create_instance_ref() src_instance_ref = self._create_instance_ref() admin_ctxt = context.get_admin_context() secgroup = db.security_group_create(admin_ctxt, {'user_id': 'fake', 'project_id': 'fake', 'name': 'testgroup', 'description': 'test group'}) src_secgroup = db.security_group_create(admin_ctxt, {'user_id': 'fake', 'project_id': 'fake', 'name': 'testsourcegroup', 'description': 'src group'}) db.security_group_rule_create(admin_ctxt, {'parent_group_id': secgroup['id'], 'protocol': 'icmp', 'from_port': -1, 'to_port': -1, 'cidr': '192.168.11.0/24'}) db.security_group_rule_create(admin_ctxt, {'parent_group_id': secgroup['id'], 'protocol': 'icmp', 'from_port': 8, 'to_port': -1, 'cidr': '192.168.11.0/24'}) db.security_group_rule_create(admin_ctxt, {'parent_group_id': secgroup['id'], 'protocol': 'tcp', 'from_port': 80, 'to_port': 81, 'cidr': '192.168.10.0/24'}) db.security_group_rule_create(admin_ctxt, {'parent_group_id': secgroup['id'], 'protocol': 'tcp', 'from_port': 80, 'to_port': 81, 'group_id': src_secgroup['id']}) db.security_group_rule_create(admin_ctxt, {'parent_group_id': secgroup['id'], 'group_id': src_secgroup['id']}) db.instance_add_security_group(admin_ctxt, instance_ref['uuid'], secgroup['id']) db.instance_add_security_group(admin_ctxt, src_instance_ref['uuid'], src_secgroup['id']) instance_ref = db.instance_get(admin_ctxt, instance_ref['id']) src_instance_ref = db.instance_get(admin_ctxt, src_instance_ref['id']) def fake_iptables_execute(*cmd, **kwargs): process_input = kwargs.get('process_input', None) if cmd == ('ip6tables-save', '-c'): return '\n'.join(self.in6_filter_rules), None if cmd == ('iptables-save', '-c'): 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 '', '' network_model = _fake_network_info(self.stubs, 1) linux_net.iptables_manager.execute = fake_iptables_execute self.stubs.Set(compute_utils, 'get_nw_info_for_instance', lambda instance: network_model) self.fw.prepare_instance_filter(instance_ref, network_model) self.fw.apply_instance_filter(instance_ref, network_model) in_rules = filter(lambda l: not l.startswith('#'), self.in_rules) for rule in in_rules: if 'nova' not in rule: self.assertTrue(rule in self.out_rules, 'Rule went missing: %s' % rule) instance_chain = None for rule in self.out_rules: # This is pretty crude, but it'll do for now # last two octets change if re.search('-d 192.168.[0-9]{1,3}.[0-9]{1,3} -j', rule): instance_chain = rule.split(' ')[-1] break self.assertTrue(instance_chain, "The instance chain wasn't added") security_group_chain = None for rule in self.out_rules: # This is pretty crude, but it'll do for now if '-A %s -j' % instance_chain in rule: security_group_chain = rule.split(' ')[-1] break self.assertTrue(security_group_chain, "The security group chain wasn't added") regex = re.compile('\[0\:0\] -A .* -j ACCEPT -p icmp ' '-s 192.168.11.0/24') self.assertTrue(len(filter(regex.match, self.out_rules)) > 0, "ICMP acceptance rule wasn't added") regex = re.compile('\[0\:0\] -A .* -j ACCEPT -p icmp -m icmp ' '--icmp-type 8 -s 192.168.11.0/24') self.assertTrue(len(filter(regex.match, self.out_rules)) > 0, "ICMP Echo Request acceptance rule wasn't added") for ip in network_model.fixed_ips(): if ip['version'] != 4: continue regex = re.compile('\[0\:0\] -A .* -j ACCEPT -p tcp -m multiport ' '--dports 80:81 -s %s' % ip['address']) self.assertTrue(len(filter(regex.match, self.out_rules)) > 0, "TCP port 80/81 acceptance rule wasn't added") regex = re.compile('\[0\:0\] -A .* -j ACCEPT -s ' '%s' % ip['address']) self.assertTrue(len(filter(regex.match, self.out_rules)) > 0, "Protocol/port-less acceptance rule wasn't added") regex = re.compile('\[0\:0\] -A .* -j ACCEPT -p tcp ' '-m multiport --dports 80:81 -s 192.168.10.0/24') self.assertTrue(len(filter(regex.match, self.out_rules)) > 0, "TCP port 80/81 acceptance rule wasn't added") db.instance_destroy(admin_ctxt, instance_ref['uuid'])