From 9274c590a78444e9157afd4d41bff566b26c9323 Mon Sep 17 00:00:00 2001 From: sridhargaddam Date: Mon, 8 Dec 2014 16:11:38 +0000 Subject: [PATCH] Neutron to Drop Router Advts from VM ports As part of Spoofing filter chain Neutron drops all the outbound traffic where MAC/IP does not match the IP address assigned to the VM ports (inc' allowed_address_pairs). Along with this, we also drop traffic associated to dhcp[v6] server (i.e., do not allow a VM to run dhcp[v6] server). Currently we do not have any rules to drop Router Advts from VM ports. This can create issues in the network as other devices in the network may not have any protection for this kind of stuff. Even if we allow RAs from the VM ports, because of the Anti-Spoofing rules that are applied, a VM cannot act as a IPv6 router (i.e., it cannot forward IPv6 traffic). So there is no point in allowing Router Advts from VMs assuming that it would be useful in Service VM use-cases. In order to properly implement IPv6 router as a Service VM, one needs to use the port_security_extension [1] which allows us to disable security group rules/anti-spoofing filters on the VM ports. [1]https://review.openstack.org/#/c/99873/22/specs/kilo/ml2-ovs-portsecurity.rst This patch disables Router Advts from VM ports. Closes-Bug: #1372882 Change-Id: I8db5d6dbe60bf04f4e3754a886c6aa8a97a16bab --- neutron/agent/linux/iptables_comments.py | 3 ++- neutron/agent/linux/iptables_firewall.py | 8 ++++++-- neutron/tests/unit/agent/linux/test_iptables_firewall.py | 6 +++++- neutron/tests/unit/agent/test_securitygroups_rpc.py | 3 +++ 4 files changed, 16 insertions(+), 4 deletions(-) diff --git a/neutron/agent/linux/iptables_comments.py b/neutron/agent/linux/iptables_comments.py index 142f82b7257..b8883e06b03 100644 --- a/neutron/agent/linux/iptables_comments.py +++ b/neutron/agent/linux/iptables_comments.py @@ -32,5 +32,6 @@ INVALID_DROP = ("Drop packets that appear related to an existing connection " "(e.g. TCP ACK/FIN) but do not have an entry in conntrack.") ALLOW_ASSOC = ('Direct packets associated with a known session to the RETURN ' 'chain.') -IPV6_RA_ALLOW = 'Allow IPv6 ICMP traffic to allow RA packets.' PORT_SEC_ACCEPT = 'Accept all packets when port security is disabled.' +IPV6_RA_DROP = 'Drop IPv6 Router Advts from VM Instance.' +IPV6_ICMP_ALLOW = 'Allow IPv6 ICMP traffic.' diff --git a/neutron/agent/linux/iptables_firewall.py b/neutron/agent/linux/iptables_firewall.py index 613c49fd63f..4368dad856a 100644 --- a/neutron/agent/linux/iptables_firewall.py +++ b/neutron/agent/linux/iptables_firewall.py @@ -311,11 +311,15 @@ class IptablesFirewallDriver(firewall.FirewallDriver): mac_ipv6_pairs.append((mac, ip_address)) def _spoofing_rule(self, port, ipv4_rules, ipv6_rules): - #Note(nati) allow dhcp or RA packet + # Allow dhcp client packets ipv4_rules += [comment_rule('-p udp -m udp --sport 68 --dport 67 ' '-j RETURN', comment=ic.DHCP_CLIENT)] + # Drop Router Advts from the port. + ipv6_rules += [comment_rule('-p icmpv6 --icmpv6-type %s ' + '-j DROP' % constants.ICMPV6_TYPE_RA, + comment=ic.IPV6_RA_DROP)] ipv6_rules += [comment_rule('-p icmpv6 -j RETURN', - comment=ic.IPV6_RA_ALLOW)] + comment=ic.IPV6_ICMP_ALLOW)] ipv6_rules += [comment_rule('-p udp -m udp --sport 546 --dport 547 ' '-j RETURN', comment=None)] mac_ipv4_pairs = [] diff --git a/neutron/tests/unit/agent/linux/test_iptables_firewall.py b/neutron/tests/unit/agent/linux/test_iptables_firewall.py index 197326251c1..cca76a4e5b2 100644 --- a/neutron/tests/unit/agent/linux/test_iptables_firewall.py +++ b/neutron/tests/unit/agent/linux/test_iptables_firewall.py @@ -892,7 +892,11 @@ class IptablesFirewallTestCase(BaseIptablesFirewallTestCase): if ethertype == 'IPv6': filter_inst = self.v6filter_inst - dhcp_rule = [mock.call.add_rule('ofake_dev', + dhcp_rule = [mock.call.add_rule('ofake_dev', '-p icmpv6 ' + '--icmpv6-type %s -j DROP' + % constants.ICMPV6_TYPE_RA, + comment=None), + mock.call.add_rule('ofake_dev', '-p icmpv6 -j RETURN', comment=None), mock.call.add_rule('ofake_dev', '-p udp -m udp ' diff --git a/neutron/tests/unit/agent/test_securitygroups_rpc.py b/neutron/tests/unit/agent/test_securitygroups_rpc.py index 62cac76a766..8dd6c90b0a6 100644 --- a/neutron/tests/unit/agent/test_securitygroups_rpc.py +++ b/neutron/tests/unit/agent/test_securitygroups_rpc.py @@ -2345,6 +2345,7 @@ IPTABLES_FILTER_V6_1 = """# Generated by iptables_manager %(physdev_is_bridged)s -j %(bn)s-o_port1 [0:0] -A %(bn)s-INPUT %(physdev_mod)s --physdev-EGRESS tap_port1 \ %(physdev_is_bridged)s -j %(bn)s-o_port1 +[0:0] -A %(bn)s-o_port1 -p icmpv6 --icmpv6-type 134 -j DROP [0:0] -A %(bn)s-o_port1 -p icmpv6 -j RETURN [0:0] -A %(bn)s-o_port1 -p udp -m udp --sport 546 --dport 547 -j RETURN [0:0] -A %(bn)s-o_port1 -p udp -m udp --sport 547 --dport 546 -j DROP @@ -2397,6 +2398,7 @@ IPTABLES_FILTER_V6_2 = """# Generated by iptables_manager %(physdev_is_bridged)s -j %(bn)s-o_%(port1)s [0:0] -A %(bn)s-INPUT %(physdev_mod)s --physdev-EGRESS tap_%(port1)s \ %(physdev_is_bridged)s -j %(bn)s-o_%(port1)s +[0:0] -A %(bn)s-o_%(port1)s -p icmpv6 --icmpv6-type 134 -j DROP [0:0] -A %(bn)s-o_%(port1)s -p icmpv6 -j RETURN [0:0] -A %(bn)s-o_%(port1)s -p udp -m udp --sport 546 --dport 547 -j RETURN [0:0] -A %(bn)s-o_%(port1)s -p udp -m udp --sport 547 --dport 546 -j DROP @@ -2421,6 +2423,7 @@ IPTABLES_FILTER_V6_2 = """# Generated by iptables_manager %(physdev_is_bridged)s -j %(bn)s-o_%(port2)s [0:0] -A %(bn)s-INPUT %(physdev_mod)s --physdev-EGRESS tap_%(port2)s \ %(physdev_is_bridged)s -j %(bn)s-o_%(port2)s +[0:0] -A %(bn)s-o_%(port2)s -p icmpv6 --icmpv6-type 134 -j DROP [0:0] -A %(bn)s-o_%(port2)s -p icmpv6 -j RETURN [0:0] -A %(bn)s-o_%(port2)s -p udp -m udp --sport 546 --dport 547 -j RETURN [0:0] -A %(bn)s-o_%(port2)s -p udp -m udp --sport 547 --dport 546 -j DROP