remove unused nwfilter methods and tests.

remove unused methods and classes in nova/virt/libvirt/firewall.py
and releative function tests. now,nova use nwfilter offered by
libvirt only for anti ARP and IP spoofing.other security policy use
iptables.

Change-Id: Ib9866802ef64668e2feba09124bdf7c7fee92f92
This commit is contained in:
Yaguang Tang
2012-02-14 10:43:39 +08:00
parent cc12819ade
commit b4fae4821f
3 changed files with 7 additions and 294 deletions
+1
View File
@@ -168,6 +168,7 @@ Vladimir Popovski <vladimir@zadarastorage.com>
William Henry <whenry@redhat.com>
William Kelly <william.kelly@rackspace.com>
William Wolf <throughnothing@gmail.com>
Yaguang Tang <heut2008@gmail.com>
Yoshiaki Tamura <yoshi@midokura.jp>
Youcef Laribi <Youcef.Laribi@eu.citrix.com>
Yun Mao <yunmao@gmail.com>
+2 -39
View File
@@ -1631,28 +1631,6 @@ class NWFilterTestCase(test.TestCase):
security_group = db.security_group_get_by_name(self.context,
'fake',
'testgroup')
xml = self.fw.security_group_to_nwfilter_xml(security_group.id)
dom = xml_to_dom(xml)
self.assertEqual(dom.firstChild.tagName, 'filter')
rules = dom.getElementsByTagName('rule')
self.assertEqual(len(rules), 1)
# It's supposed to allow inbound traffic.
self.assertEqual(rules[0].getAttribute('action'), 'accept')
self.assertEqual(rules[0].getAttribute('direction'), 'in')
# Must be lower priority than the base filter (which blocks everything)
self.assertTrue(int(rules[0].getAttribute('priority')) < 1000)
ip_conditions = rules[0].getElementsByTagName('tcp')
self.assertEqual(len(ip_conditions), 1)
self.assertEqual(ip_conditions[0].getAttribute('srcipaddr'), '0.0.0.0')
self.assertEqual(ip_conditions[0].getAttribute('srcipmask'), '0.0.0.0')
self.assertEqual(ip_conditions[0].getAttribute('dstportstart'), '80')
self.assertEqual(ip_conditions[0].getAttribute('dstportend'), '81')
self.teardown_security_group()
def teardown_security_group(self):
@@ -1732,8 +1710,7 @@ class NWFilterTestCase(test.TestCase):
def _ensure_all_called(mac):
instance_filter = 'nova-instance-%s-%s' % (instance_ref['name'],
mac.translate(None, ':'))
secgroup_filter = 'nova-secgroup-%s' % self.security_group['id']
for required in [secgroup_filter, 'allow-dhcp-server',
for required in ['allow-dhcp-server',
'no-arp-spoofing', 'no-ip-spoofing',
'no-mac-spoofing']:
self.assertTrue(required in
@@ -1754,20 +1731,10 @@ class NWFilterTestCase(test.TestCase):
mac = network_info[0][1]['mac']
self.fw.setup_basic_filtering(instance, network_info)
self.fw.prepare_instance_filter(instance, network_info)
self.fw.apply_instance_filter(instance, network_info)
_ensure_all_called(mac)
self.teardown_security_group()
db.instance_destroy(context.get_admin_context(), instance_ref['id'])
def test_create_network_filters(self):
instance_ref = self._create_instance()
network_info = _fake_network_info(self.stubs, 3)
result = self.fw._create_network_filters(instance_ref,
network_info,
"fake")
self.assertEquals(len(result), 3)
def test_unfilter_instance_undefines_nwfilters(self):
admin_ctxt = context.get_admin_context()
@@ -1788,13 +1755,9 @@ class NWFilterTestCase(test.TestCase):
network_info = _fake_network_info(self.stubs, 1)
self.fw.setup_basic_filtering(instance, network_info)
self.fw.prepare_instance_filter(instance, network_info)
self.fw.apply_instance_filter(instance, network_info)
original_filter_count = len(fakefilter.filters)
self.fw.unfilter_instance(instance, network_info)
# should undefine 2 filters: instance and instance-secgroup
self.assertEqual(original_filter_count - len(fakefilter.filters), 2)
self.assertEqual(original_filter_count - len(fakefilter.filters), 1)
db.instance_destroy(admin_ctxt, instance_ref['id'])
+4 -255
View File
@@ -45,48 +45,11 @@ except ImportError:
class NWFilterFirewall(base_firewall.FirewallDriver):
"""
This class implements a network filtering mechanism versatile
enough for EC2 style Security Group filtering by leveraging
This class implements a network filtering mechanism by using
libvirt's nwfilter.
First, all instances get a filter ("nova-base-filter") applied.
This filter provides some basic security such as protection against
MAC spoofing, IP spoofing, and ARP spoofing.
This filter drops all incoming ipv4 and ipv6 connections.
Outgoing connections are never blocked.
Second, every security group maps to a nwfilter filter(*).
NWFilters can be updated at runtime and changes are applied
immediately, so changes to security groups can be applied at
runtime (as mandated by the spec).
Security group rules are named "nova-secgroup-<id>" where <id>
is the internal id of the security group. They're applied only on
hosts that have instances in the security group in question.
Updates to security groups are done by updating the data model
(in response to API calls) followed by a request sent to all
the nodes with instances in the security group to refresh the
security group.
Each instance has its own NWFilter, which references the above
mentioned security group NWFilters. This was done because
interfaces can only reference one filter while filters can
reference multiple other filters. This has the added benefit of
actually being able to add and remove security groups from an
instance at run time. This functionality is not exposed anywhere,
though.
Outstanding questions:
The name is unique, so would there be any good reason to sync
the uuid across the nodes (by assigning it from the datamodel)?
(*) This sentence brought to you by the redundancy department of
redundancy.
all instances get a filter ("nova-base") applied. This filter
provides some basic security such as protection against MAC
spoofing, IP spoofing, and ARP spoofing.
"""
def __init__(self, get_connection, **kwargs):
@@ -125,16 +88,6 @@ class NWFilterFirewall(base_firewall.FirewallDriver):
</rule>
</filter>'''
@staticmethod
def nova_ra_filter():
return '''<filter name='nova-allow-ra-server' chain='root'>
<uuid>d707fa71-4fb5-4b27-9ab7-ba5ca19c8804</uuid>
<rule action='accept' direction='inout'
priority='100'>
<icmpv6 srcipaddr='$RASERVER'/>
</rule>
</filter>'''
def setup_basic_filtering(self, instance, network_info):
"""Set up basic filtering (MAC, IP, and ARP spoofing protection)"""
LOG.info(_('Called setup_basic_filtering in nwfilter'),
@@ -177,14 +130,7 @@ class NWFilterFirewall(base_firewall.FirewallDriver):
'allow-dhcp-server']))
self._define_filter(self._filter_container('nova-vpn',
['allow-dhcp-server']))
self._define_filter(self.nova_base_ipv4_filter)
self._define_filter(self.nova_base_ipv6_filter)
self._define_filter(self.nova_dhcp_filter)
self._define_filter(self.nova_ra_filter)
if FLAGS.allow_same_net_traffic:
self._define_filter(self.nova_project_filter)
if FLAGS.use_ipv6:
self._define_filter(self.nova_project_filter_v6)
self.static_filters_configured = True
@@ -194,54 +140,6 @@ class NWFilterFirewall(base_firewall.FirewallDriver):
''.join(["<filterref filter='%s'/>" % (f,) for f in filters]))
return xml
@staticmethod
def nova_base_ipv4_filter():
retval = "<filter name='nova-base-ipv4' chain='ipv4'>"
for protocol in ['tcp', 'udp', 'icmp']:
for direction, action, priority in [('out', 'accept', 399),
('in', 'drop', 400)]:
retval += """<rule action='%s' direction='%s' priority='%d'>
<%s />
</rule>""" % (action, direction,
priority, protocol)
retval += '</filter>'
return retval
@staticmethod
def nova_base_ipv6_filter():
retval = "<filter name='nova-base-ipv6' chain='ipv6'>"
for protocol in ['tcp-ipv6', 'udp-ipv6', 'icmpv6']:
for direction, action, priority in [('out', 'accept', 399),
('in', 'drop', 400)]:
retval += """<rule action='%s' direction='%s' priority='%d'>
<%s />
</rule>""" % (action, direction,
priority, protocol)
retval += '</filter>'
return retval
@staticmethod
def nova_project_filter():
retval = "<filter name='nova-project' chain='ipv4'>"
for protocol in ['tcp', 'udp', 'icmp']:
retval += """<rule action='accept' direction='in' priority='200'>
<%s srcipaddr='$PROJNET' srcipmask='$PROJMASK' />
</rule>""" % protocol
retval += '</filter>'
return retval
@staticmethod
def nova_project_filter_v6():
retval = "<filter name='nova-project-v6' chain='ipv6'>"
for protocol in ['tcp-ipv6', 'udp-ipv6', 'icmpv6']:
retval += """<rule action='accept' direction='inout'
priority='200'>
<%s srcipaddr='$PROJNETV6'
srcipmask='$PROJMASKV6' />
</rule>""" % (protocol)
retval += '</filter>'
return retval
def _define_filter(self, xml):
if callable(xml):
xml = xml()
@@ -263,61 +161,6 @@ class NWFilterFirewall(base_firewall.FirewallDriver):
'is not found.') % locals(),
instance=instance)
instance_secgroup_filter_name = ('%s-secgroup' %
self._instance_filter_name(instance))
try:
_nw = self._conn.nwfilterLookupByName(
instance_secgroup_filter_name)
_nw.undefine()
except libvirt.libvirtError:
LOG.debug(_('The nwfilter(%(instance_secgroup_filter_name)s) '
'is not found.') % locals(), instance=instance)
def prepare_instance_filter(self, instance, network_info):
"""Creates an NWFilter for the given instance.
In the process, it makes sure the filters for the provider blocks,
security groups, and base filter are all in place.
"""
self.refresh_provider_fw_rules()
ctxt = context.get_admin_context()
instance_secgroup_filter_name = ('%s-secgroup' %
self._instance_filter_name(instance))
instance_secgroup_filter_children = ['nova-base-ipv4',
'nova-base-ipv6',
'nova-allow-dhcp-server']
if FLAGS.use_ipv6:
networks = [network for (network, info) in network_info if
info['gateway_v6']]
if networks:
instance_secgroup_filter_children.append(
'nova-allow-ra-server')
for security_group in db.security_group_get_by_instance(ctxt,
instance['id']):
self.refresh_security_group_rules(security_group['id'])
instance_secgroup_filter_children.append('nova-secgroup-%s' %
security_group['id'])
self._define_filter(
self._filter_container(instance_secgroup_filter_name,
instance_secgroup_filter_children))
network_filters = self._create_network_filters(instance, network_info,
instance_secgroup_filter_name)
for (name, children) in network_filters:
self._define_filters(name, children)
def _create_network_filters(self, instance, network_info,
instance_secgroup_filter_name):
if instance['image_ref'] == str(FLAGS.vpn_image_id):
@@ -345,100 +188,6 @@ class NWFilterFirewall(base_firewall.FirewallDriver):
self._define_filter(self._filter_container(filter_name,
filter_children))
def refresh_security_group_rules(self, security_group_id):
return self._define_filter(
self.security_group_to_nwfilter_xml(security_group_id))
def refresh_provider_fw_rules(self):
"""Update rules for all instances.
This is part of the FirewallDriver API and is called when the
provider firewall rules change in the database. In the
`prepare_instance_filter` we add a reference to the
'nova-provider-rules' filter for each instance's firewall, and
by changing that filter we update them all.
"""
xml = self.provider_fw_to_nwfilter_xml()
return self._define_filter(xml)
@staticmethod
def security_group_to_nwfilter_xml(security_group_id):
security_group = db.security_group_get(context.get_admin_context(),
security_group_id)
rule_xml = ""
v6protocol = {'tcp': 'tcp-ipv6', 'udp': 'udp-ipv6', 'icmp': 'icmpv6'}
for rule in security_group.rules:
rule_xml += "<rule action='accept' direction='in' priority='300'>"
if rule.cidr:
version = netutils.get_ip_version(rule.cidr)
if(FLAGS.use_ipv6 and version == 6):
net, prefixlen = netutils.get_net_and_prefixlen(rule.cidr)
rule_xml += ("<%s srcipaddr='%s' srcipmask='%s' " %
(v6protocol[rule.protocol], net, prefixlen))
else:
net, mask = netutils.get_net_and_mask(rule.cidr)
rule_xml += ("<%s srcipaddr='%s' srcipmask='%s' " %
(rule.protocol, net, mask))
if rule.protocol in ['tcp', 'udp']:
rule_xml += ("dstportstart='%s' dstportend='%s' " %
(rule.from_port, rule.to_port))
elif rule.protocol == 'icmp':
LOG.info('rule.protocol: %r, rule.from_port: %r, '
'rule.to_port: %r', rule.protocol,
rule.from_port, rule.to_port)
if rule.from_port != -1:
rule_xml += "type='%s' " % rule.from_port
if rule.to_port != -1:
rule_xml += "code='%s' " % rule.to_port
rule_xml += '/>\n'
rule_xml += "</rule>\n"
xml = "<filter name='nova-secgroup-%s' " % security_group_id
if(FLAGS.use_ipv6):
xml += "chain='root'>%s</filter>" % rule_xml
else:
xml += "chain='ipv4'>%s</filter>" % rule_xml
return xml
@staticmethod
def provider_fw_to_nwfilter_xml():
"""Compose a filter of drop rules from specified cidrs."""
rule_xml = ""
v6protocol = {'tcp': 'tcp-ipv6', 'udp': 'udp-ipv6', 'icmp': 'icmpv6'}
rules = db.provider_fw_rule_get_all(context.get_admin_context())
for rule in rules:
rule_xml += "<rule action='block' direction='in' priority='150'>"
version = netutils.get_ip_version(rule.cidr)
if(FLAGS.use_ipv6 and version == 6):
net, prefixlen = netutils.get_net_and_prefixlen(rule.cidr)
rule_xml += ("<%s srcipaddr='%s' srcipmask='%s' " %
(v6protocol[rule.protocol], net, prefixlen))
else:
net, mask = netutils.get_net_and_mask(rule.cidr)
rule_xml += ("<%s srcipaddr='%s' srcipmask='%s' " %
(rule.protocol, net, mask))
if rule.protocol in ['tcp', 'udp']:
rule_xml += ("dstportstart='%s' dstportend='%s' " %
(rule.from_port, rule.to_port))
elif rule.protocol == 'icmp':
LOG.info('rule.protocol: %r, rule.from_port: %r, '
'rule.to_port: %r', rule.protocol,
rule.from_port, rule.to_port)
if rule.from_port != -1:
rule_xml += "type='%s' " % rule.from_port
if rule.to_port != -1:
rule_xml += "code='%s' " % rule.to_port
rule_xml += '/>\n'
rule_xml += "</rule>\n"
xml = "<filter name='nova-provider-rules' "
if(FLAGS.use_ipv6):
xml += "chain='root'>%s</filter>" % rule_xml
else:
xml += "chain='ipv4'>%s</filter>" % rule_xml
return xml
@staticmethod
def _instance_filter_name(instance, nic_id=None):
if not nic_id: