Merge "IPtables firewall prevent ICMPv6 spoofing" into stable/liberty

This commit is contained in:
Jenkins 2016-05-14 02:33:24 +00:00 committed by Gerrit Code Review
commit b1c83a928a
3 changed files with 96 additions and 42 deletions

View File

@ -43,6 +43,7 @@ CHAIN_NAME_PREFIX = {firewall.INGRESS_DIRECTION: 'i',
SPOOF_FILTER: 's'}
DIRECTION_IP_PREFIX = {firewall.INGRESS_DIRECTION: 'source_ip_prefix',
firewall.EGRESS_DIRECTION: 'dest_ip_prefix'}
ICMPV6_ALLOWED_UNSPEC_ADDR_TYPES = [131, 135, 143]
IPSET_DIRECTION = {firewall.INGRESS_DIRECTION: 'src',
firewall.EGRESS_DIRECTION: 'dst'}
# length of all device prefixes (e.g. qvo, tap, qvb)
@ -384,21 +385,25 @@ class IptablesFirewallDriver(firewall.FirewallDriver):
mac_ipv4_pairs.append((mac, ip_address))
else:
mac_ipv6_pairs.append((mac, ip_address))
lla = str(ipv6_utils.get_ipv6_addr_by_EUI64(
constants.IPV6_LLA_PREFIX, mac))
mac_ipv6_pairs.append((mac, lla))
def _spoofing_rule(self, port, ipv4_rules, ipv6_rules):
# Fixed rules for traffic sourced from unspecified addresses: 0.0.0.0
# and ::
# Allow dhcp client discovery and request
ipv4_rules += [comment_rule('-s 0.0.0.0/32 -d 255.255.255.255/32 '
'-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 ipv6-icmp -m icmp6 --icmpv6-type %s '
'-j DROP' % constants.ICMPV6_TYPE_RA,
comment=ic.IPV6_RA_DROP)]
ipv6_rules += [comment_rule('-p ipv6-icmp -j RETURN',
comment=ic.IPV6_ICMP_ALLOW)]
ipv6_rules += [comment_rule('-p udp -m udp --sport 546 '
'-m udp --dport 547 '
'-j RETURN', comment=ic.DHCP_CLIENT)]
# Allow neighbor solicitation and multicast listener discovery
# from the unspecified address for duplicate address detection
for icmp6_type in ICMPV6_ALLOWED_UNSPEC_ADDR_TYPES:
ipv6_rules += [comment_rule('-s ::/128 -d ff02::/16 '
'-p ipv6-icmp -m icmp6 '
'--icmpv6-type %s -j RETURN' %
icmp6_type,
comment=ic.IPV6_ICMP_ALLOW)]
mac_ipv4_pairs = []
mac_ipv6_pairs = []
@ -420,9 +425,19 @@ class IptablesFirewallDriver(firewall.FirewallDriver):
mac_ipv4_pairs, ipv4_rules)
self._setup_spoof_filter_chain(port, self.iptables.ipv6['filter'],
mac_ipv6_pairs, ipv6_rules)
# Fixed rules for traffic after source address is verified
# Allow dhcp client renewal and rebinding
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 ipv6-icmp -m icmp6 --icmpv6-type %s '
'-j DROP' % constants.ICMPV6_TYPE_RA,
comment=ic.IPV6_RA_DROP)]
ipv6_rules += [comment_rule('-p ipv6-icmp -j RETURN',
comment=ic.IPV6_ICMP_ALLOW)]
ipv6_rules += [comment_rule('-p udp -m udp --sport 546 '
'-m udp --dport 547 '
'-j RETURN', comment=ic.DHCP_CLIENT)]
def _drop_dhcp_rule(self, ipv4_rules, ipv6_rules):
#Note(nati) Drop dhcp packet from VM

View File

@ -952,17 +952,21 @@ class IptablesFirewallTestCase(BaseIptablesFirewallTestCase):
if ethertype == 'IPv6':
filter_inst = self.v6filter_inst
dhcp_rule = [mock.call.add_rule('ofake_dev', '-p ipv6-icmp '
'-m icmp6 '
'--icmpv6-type %s -j DROP'
% constants.ICMPV6_TYPE_RA,
dhcp_rule = [mock.call.add_rule('ofake_dev',
'-s ::/128 -d ff02::/16 '
'-p ipv6-icmp -m icmp6 '
'--icmpv6-type 131 -j RETURN',
comment=None),
mock.call.add_rule('ofake_dev',
'-p ipv6-icmp -j RETURN',
'-s ::/128 -d ff02::/16 '
'-p ipv6-icmp -m icmp6 '
'--icmpv6-type 135 -j RETURN',
comment=None),
mock.call.add_rule('ofake_dev', '-p udp -m udp '
'--sport 546 -m udp --dport 547 '
'-j RETURN', comment=None)]
mock.call.add_rule('ofake_dev',
'-s ::/128 -d ff02::/16 '
'-p ipv6-icmp -m icmp6 '
'--icmpv6-type 143 -j RETURN',
comment=None)]
sg = [rule]
port['security_group_rules'] = sg
self.firewall.prepare_port_filter(port)
@ -1025,10 +1029,15 @@ class IptablesFirewallTestCase(BaseIptablesFirewallTestCase):
'sfake_dev',
'-s %s -m mac --mac-source FF:FF:FF:FF:FF:FF -j RETURN'
% prefix,
comment=ic.PAIR_ALLOW),
mock.call.add_rule(
'sfake_dev', '-j DROP',
comment=ic.PAIR_DROP)]
comment=ic.PAIR_ALLOW)]
if ethertype == 'IPv6':
calls.append(mock.call.add_rule('sfake_dev',
'-s fe80::fdff:ffff:feff:ffff/128 -m mac '
'--mac-source FF:FF:FF:FF:FF:FF -j RETURN',
comment=ic.PAIR_ALLOW))
calls.append(mock.call.add_rule('sfake_dev', '-j DROP',
comment=ic.PAIR_DROP))
calls += dhcp_rule
calls.append(mock.call.add_rule('ofake_dev', '-j $sfake_dev',
comment=None))
@ -1042,6 +1051,17 @@ class IptablesFirewallTestCase(BaseIptablesFirewallTestCase):
'-p udp -m udp --sport 67 -m udp --dport 68 -j DROP',
comment=None))
if ethertype == 'IPv6':
calls.append(mock.call.add_rule('ofake_dev',
'-p ipv6-icmp -m icmp6 '
'--icmpv6-type %s -j DROP' %
constants.ICMPV6_TYPE_RA,
comment=None))
calls.append(mock.call.add_rule('ofake_dev',
'-p ipv6-icmp -j RETURN',
comment=None))
calls.append(mock.call.add_rule('ofake_dev', '-p udp -m udp '
'--sport 546 -m udp --dport 547 '
'-j RETURN', comment=None))
calls.append(mock.call.add_rule(
'ofake_dev',
'-p udp -m udp --sport 547 -m udp --dport 546 -j DROP',
@ -1862,6 +1882,7 @@ class IptablesFirewallEnhancedIpsetTestCase(BaseIptablesFirewallTestCase):
fake_ipv4_pair.append((mac_unix, ipv4))
fake_ipv6_pair = []
fake_ipv6_pair.append((mac_unix, ipv6))
fake_ipv6_pair.append((mac_unix, 'fe80::fdff:ffff:fe0f:ffff'))
mac_ipv4_pairs = []
mac_ipv6_pairs = []

View File

@ -2440,13 +2440,19 @@ IPTABLES_FILTER_V6_1 = """# Generated by iptables_manager
-I %(bn)s-i_port1 6 -m state --state RELATED,ESTABLISHED -j RETURN
-I %(bn)s-i_port1 7 -m state --state INVALID -j DROP
-I %(bn)s-i_port1 8 -j %(bn)s-sg-fallback
-I %(bn)s-o_port1 1 -p ipv6-icmp -m icmp6 --icmpv6-type 134 -j DROP
-I %(bn)s-o_port1 2 -p ipv6-icmp -j RETURN
-I %(bn)s-o_port1 3 -p udp -m udp --sport 546 -m udp --dport 547 -j RETURN
-I %(bn)s-o_port1 4 -p udp -m udp --sport 547 -m udp --dport 546 -j DROP
-I %(bn)s-o_port1 5 -m state --state RELATED,ESTABLISHED -j RETURN
-I %(bn)s-o_port1 6 -m state --state INVALID -j DROP
-I %(bn)s-o_port1 7 -j %(bn)s-sg-fallback
-I %(bn)s-o_port1 1 -s ::/128 -d ff02::/16 -p ipv6-icmp -m icmp6 \
--icmpv6-type 131 -j RETURN
-I %(bn)s-o_port1 2 -s ::/128 -d ff02::/16 -p ipv6-icmp -m icmp6 \
--icmpv6-type 135 -j RETURN
-I %(bn)s-o_port1 3 -s ::/128 -d ff02::/16 -p ipv6-icmp -m icmp6 \
--icmpv6-type 143 -j RETURN
-I %(bn)s-o_port1 4 -p ipv6-icmp -m icmp6 --icmpv6-type 134 -j DROP
-I %(bn)s-o_port1 5 -p ipv6-icmp -j RETURN
-I %(bn)s-o_port1 6 -p udp -m udp --sport 546 -m udp --dport 547 -j RETURN
-I %(bn)s-o_port1 7 -p udp -m udp --sport 547 -m udp --dport 546 -j DROP
-I %(bn)s-o_port1 8 -m state --state RELATED,ESTABLISHED -j RETURN
-I %(bn)s-o_port1 9 -m state --state INVALID -j DROP
-I %(bn)s-o_port1 10 -j %(bn)s-sg-fallback
-I %(bn)s-sg-chain 1 %(physdev_mod)s --physdev-INGRESS tap_port1 \
%(physdev_is_bridged)s -j %(bn)s-i_port1
-I %(bn)s-sg-chain 2 %(physdev_mod)s --physdev-EGRESS tap_port1 \
@ -2510,20 +2516,32 @@ IPTABLES_FILTER_V6_2 = """# Generated by iptables_manager
-I %(bn)s-i_%(port2)s 6 -m state --state RELATED,ESTABLISHED -j RETURN
-I %(bn)s-i_%(port2)s 7 -m state --state INVALID -j DROP
-I %(bn)s-i_%(port2)s 8 -j %(bn)s-sg-fallback
-I %(bn)s-o_%(port1)s 1 -p ipv6-icmp -m icmp6 --icmpv6-type 134 -j DROP
-I %(bn)s-o_%(port1)s 2 -p ipv6-icmp -j RETURN
-I %(bn)s-o_%(port1)s 3 -p udp -m udp --sport 546 -m udp --dport 547 -j RETURN
-I %(bn)s-o_%(port1)s 4 -p udp -m udp --sport 547 -m udp --dport 546 -j DROP
-I %(bn)s-o_%(port1)s 5 -m state --state RELATED,ESTABLISHED -j RETURN
-I %(bn)s-o_%(port1)s 6 -m state --state INVALID -j DROP
-I %(bn)s-o_%(port1)s 7 -j %(bn)s-sg-fallback
-I %(bn)s-o_%(port2)s 1 -p ipv6-icmp -m icmp6 --icmpv6-type 134 -j DROP
-I %(bn)s-o_%(port2)s 2 -p ipv6-icmp -j RETURN
-I %(bn)s-o_%(port2)s 3 -p udp -m udp --sport 546 -m udp --dport 547 -j RETURN
-I %(bn)s-o_%(port2)s 4 -p udp -m udp --sport 547 -m udp --dport 546 -j DROP
-I %(bn)s-o_%(port2)s 5 -m state --state RELATED,ESTABLISHED -j RETURN
-I %(bn)s-o_%(port2)s 6 -m state --state INVALID -j DROP
-I %(bn)s-o_%(port2)s 7 -j %(bn)s-sg-fallback
-I %(bn)s-o_%(port1)s 1 -s ::/128 -d ff02::/16 -p ipv6-icmp -m icmp6 \
--icmpv6-type 131 -j RETURN
-I %(bn)s-o_%(port1)s 2 -s ::/128 -d ff02::/16 -p ipv6-icmp -m icmp6 \
--icmpv6-type 135 -j RETURN
-I %(bn)s-o_%(port1)s 3 -s ::/128 -d ff02::/16 -p ipv6-icmp -m icmp6 \
--icmpv6-type 143 -j RETURN
-I %(bn)s-o_%(port1)s 4 -p ipv6-icmp -m icmp6 --icmpv6-type 134 -j DROP
-I %(bn)s-o_%(port1)s 5 -p ipv6-icmp -j RETURN
-I %(bn)s-o_%(port1)s 6 -p udp -m udp --sport 546 -m udp --dport 547 -j RETURN
-I %(bn)s-o_%(port1)s 7 -p udp -m udp --sport 547 -m udp --dport 546 -j DROP
-I %(bn)s-o_%(port1)s 8 -m state --state RELATED,ESTABLISHED -j RETURN
-I %(bn)s-o_%(port1)s 9 -m state --state INVALID -j DROP
-I %(bn)s-o_%(port1)s 10 -j %(bn)s-sg-fallback
-I %(bn)s-o_%(port2)s 1 -s ::/128 -d ff02::/16 -p ipv6-icmp -m icmp6 \
--icmpv6-type 131 -j RETURN
-I %(bn)s-o_%(port2)s 2 -s ::/128 -d ff02::/16 -p ipv6-icmp -m icmp6 \
--icmpv6-type 135 -j RETURN
-I %(bn)s-o_%(port2)s 3 -s ::/128 -d ff02::/16 -p ipv6-icmp -m icmp6 \
--icmpv6-type 143 -j RETURN
-I %(bn)s-o_%(port2)s 4 -p ipv6-icmp -m icmp6 --icmpv6-type 134 -j DROP
-I %(bn)s-o_%(port2)s 5 -p ipv6-icmp -j RETURN
-I %(bn)s-o_%(port2)s 6 -p udp -m udp --sport 546 -m udp --dport 547 -j RETURN
-I %(bn)s-o_%(port2)s 7 -p udp -m udp --sport 547 -m udp --dport 546 -j DROP
-I %(bn)s-o_%(port2)s 8 -m state --state RELATED,ESTABLISHED -j RETURN
-I %(bn)s-o_%(port2)s 9 -m state --state INVALID -j DROP
-I %(bn)s-o_%(port2)s 10 -j %(bn)s-sg-fallback
-I %(bn)s-sg-chain 1 %(physdev_mod)s --physdev-INGRESS tap_%(port1)s \
%(physdev_is_bridged)s -j %(bn)s-i_%(port1)s
-I %(bn)s-sg-chain 2 %(physdev_mod)s --physdev-EGRESS tap_%(port1)s \