Merge "Fix IP spoofing filter blocking all packets."

This commit is contained in:
Jenkins
2013-06-20 12:59:15 +00:00
committed by Gerrit Code Review
2 changed files with 84 additions and 3 deletions

View File

@@ -28,8 +28,10 @@ LOG = logging.getLogger(__name__)
SG_CHAIN = 'sg-chain'
INGRESS_DIRECTION = 'ingress'
EGRESS_DIRECTION = 'egress'
IP_SPOOF_FILTER = 'ip-spoof-filter'
CHAIN_NAME_PREFIX = {INGRESS_DIRECTION: 'i',
EGRESS_DIRECTION: 'o'}
EGRESS_DIRECTION: 'o',
IP_SPOOF_FILTER: 's'}
LINUX_DEV_LEN = 14
@@ -94,6 +96,7 @@ class IptablesFirewallDriver(firewall.FirewallDriver):
for port in self.filtered_ports.values():
self._remove_chain(port, INGRESS_DIRECTION)
self._remove_chain(port, EGRESS_DIRECTION)
self._remove_chain(port, IP_SPOOF_FILTER)
self._remove_chain_by_name_v4v6(SG_CHAIN)
def _setup_chain(self, port, DIRECTION):
@@ -175,15 +178,32 @@ class IptablesFirewallDriver(firewall.FirewallDriver):
def _arp_spoofing_rule(self, port):
return ['-m mac ! --mac-source %s -j DROP' % port['mac_address']]
def _setup_ip_spoof_filter_chain(self, port, table, addresses, rules):
if len(addresses) == 1:
rules.append('! -s %s -j DROP' % addresses[0])
elif addresses:
chain_name = self._port_chain_name(port, IP_SPOOF_FILTER)
table.add_chain(chain_name)
for ip in addresses:
table.add_rule(chain_name, '-s %s -j RETURN' % ip)
table.add_rule(chain_name, '-j DROP')
rules.append('-j $%s' % chain_name)
def _ip_spoofing_rule(self, port, ipv4_rules, ipv6_rules):
#Note(nati) allow dhcp or RA packet
ipv4_rules += ['-p udp --sport 68 --dport 67 -j RETURN']
ipv6_rules += ['-p icmpv6 -j RETURN']
ipv4_addresses = []
ipv6_addresses = []
for ip in port['fixed_ips']:
if netaddr.IPAddress(ip).version == 4:
ipv4_rules += ['! -s %s -j DROP' % ip]
ipv4_addresses.append(ip)
else:
ipv6_rules += ['! -s %s -j DROP' % ip]
ipv6_addresses.append(ip)
self._setup_ip_spoof_filter_chain(port, self.iptables.ipv4['filter'],
ipv4_addresses, ipv4_rules)
self._setup_ip_spoof_filter_chain(port, self.iptables.ipv6['filter'],
ipv6_addresses, ipv6_rules)
def _drop_dhcp_rule(self):
#Note(nati) Drop dhcp packet from VM

View File

@@ -839,6 +839,7 @@ class IptablesFirewallTestCase(base.BaseTestCase):
call.add_rule('sg-chain', '-j ACCEPT'),
call.ensure_remove_chain('ifake_dev'),
call.ensure_remove_chain('ofake_dev'),
call.ensure_remove_chain('sfake_dev'),
call.ensure_remove_chain('sg-chain'),
call.add_chain('sg-chain'),
call.add_chain('ifake_dev'),
@@ -889,6 +890,7 @@ class IptablesFirewallTestCase(base.BaseTestCase):
call.add_rule('sg-chain', '-j ACCEPT'),
call.ensure_remove_chain('ifake_dev'),
call.ensure_remove_chain('ofake_dev'),
call.ensure_remove_chain('sfake_dev'),
call.ensure_remove_chain('sg-chain'),
call.add_chain('sg-chain')]
@@ -914,3 +916,62 @@ class IptablesFirewallTestCase(base.BaseTestCase):
pass
self.iptables_inst.assert_has_calls([call.defer_apply_on(),
call.defer_apply_off()])
def test_ip_spoofing_filter_with_multiple_ips(self):
port = {'device': 'tapfake_dev',
'mac_address': 'ff:ff:ff:ff',
'fixed_ips': ['10.0.0.1', 'fe80::1', '10.0.0.2']}
self.firewall.prepare_port_filter(port)
calls = [call.add_chain('sg-fallback'),
call.add_rule('sg-fallback', '-j DROP'),
call.ensure_remove_chain('sg-chain'),
call.add_chain('sg-chain'),
call.add_chain('ifake_dev'),
call.add_rule('FORWARD',
'-m physdev --physdev-is-bridged '
'--physdev-out tapfake_dev '
'-j $sg-chain'),
call.add_rule('sg-chain',
'-m physdev --physdev-is-bridged '
'--physdev-out tapfake_dev '
'-j $ifake_dev'),
call.add_rule(
'ifake_dev', '-m state --state INVALID -j DROP'),
call.add_rule(
'ifake_dev',
'-m state --state ESTABLISHED,RELATED -j RETURN'),
call.add_rule('ifake_dev', '-j $sg-fallback'),
call.add_chain('ofake_dev'),
call.add_rule('FORWARD',
'-m physdev --physdev-is-bridged '
'--physdev-in tapfake_dev '
'-j $sg-chain'),
call.add_rule('sg-chain',
'-m physdev --physdev-is-bridged '
'--physdev-in tapfake_dev '
'-j $ofake_dev'),
call.add_rule('INPUT',
'-m physdev --physdev-is-bridged '
'--physdev-in tapfake_dev '
'-j $ofake_dev'),
call.add_chain('sfake_dev'),
call.add_rule('sfake_dev', '-s 10.0.0.1 -j RETURN'),
call.add_rule('sfake_dev', '-s 10.0.0.2 -j RETURN'),
call.add_rule('sfake_dev', '-j DROP'),
call.add_rule(
'ofake_dev', '-m mac ! --mac-source ff:ff:ff:ff -j DROP'),
call.add_rule(
'ofake_dev',
'-p udp --sport 68 --dport 67 -j RETURN'),
call.add_rule('ofake_dev', '-j $sfake_dev'),
call.add_rule(
'ofake_dev',
'-p udp --sport 67 --dport 68 -j DROP'),
call.add_rule(
'ofake_dev', '-m state --state INVALID -j DROP'),
call.add_rule(
'ofake_dev',
'-m state --state ESTABLISHED,RELATED -j RETURN'),
call.add_rule('ofake_dev', '-j $sg-fallback'),
call.add_rule('sg-chain', '-j ACCEPT')]
self.v4filter_inst.assert_has_calls(calls)