Merge "Use ebtables to isolate dhcp traffic" into stable/icehouse

This commit is contained in:
Jenkins 2015-06-16 01:32:04 +00:00 committed by Gerrit Code Review
commit 58ae4a6e3a
2 changed files with 30 additions and 165 deletions

View File

@ -1638,29 +1638,14 @@ def isolate_dhcp_address(interface, address):
% (interface, address))
rules.append('OUTPUT -p ARP -o %s --arp-ip-src %s -j DROP'
% (interface, address))
rules.append('FORWARD -p IPv4 -i %s --ip-protocol udp '
'--ip-destination-port 67:68 -j DROP'
% interface)
rules.append('FORWARD -p IPv4 -o %s --ip-protocol udp '
'--ip-destination-port 67:68 -j DROP'
% interface)
# NOTE(vish): the above is not possible with iptables/arptables
ensure_ebtables_rules(rules)
# block dhcp broadcast traffic across the interface
ipv4_filter = iptables_manager.ipv4['filter']
ipv4_filter.add_rule('FORWARD',
('-m physdev --physdev-in %s -d 255.255.255.255 '
'-p udp --dport 67 -j %s'
% (interface, CONF.iptables_drop_action)),
top=True)
ipv4_filter.add_rule('FORWARD',
('-m physdev --physdev-out %s -d 255.255.255.255 '
'-p udp --dport 67 -j %s'
% (interface, CONF.iptables_drop_action)),
top=True)
# block ip traffic to address across the interface
ipv4_filter.add_rule('FORWARD',
('-m physdev --physdev-in %s -d %s -j %s'
% (interface, address, CONF.iptables_drop_action)),
top=True)
ipv4_filter.add_rule('FORWARD',
('-m physdev --physdev-out %s -s %s -j %s'
% (interface, address, CONF.iptables_drop_action)),
top=True)
def remove_isolate_dhcp_address(interface, address):
@ -1670,38 +1655,14 @@ def remove_isolate_dhcp_address(interface, address):
% (interface, address))
rules.append('OUTPUT -p ARP -o %s --arp-ip-src %s -j DROP'
% (interface, address))
rules.append('FORWARD -p IPv4 -i %s --ip-protocol udp '
'--ip-destination-port 67:68 -j DROP'
% interface)
rules.append('FORWARD -p IPv4 -o %s --ip-protocol udp '
'--ip-destination-port 67:68 -j DROP'
% interface)
remove_ebtables_rules(rules)
# NOTE(vish): the above is not possible with iptables/arptables
# block dhcp broadcast traffic across the interface
ipv4_filter = iptables_manager.ipv4['filter']
drop_actions = ['DROP']
if CONF.iptables_drop_action != 'DROP':
drop_actions.append(CONF.iptables_drop_action)
for drop_action in drop_actions:
ipv4_filter.remove_rule('FORWARD',
('-m physdev --physdev-in %s '
'-d 255.255.255.255 '
'-p udp --dport 67 -j %s'
% (interface, drop_action)),
top=True)
ipv4_filter.remove_rule('FORWARD',
('-m physdev --physdev-out %s '
'-d 255.255.255.255 '
'-p udp --dport 67 -j %s'
% (interface, drop_action)),
top=True)
# block ip traffic to address across the interface
ipv4_filter.remove_rule('FORWARD',
('-m physdev --physdev-in %s -d %s -j %s'
% (interface, address, drop_action)),
top=True)
ipv4_filter.remove_rule('FORWARD',
('-m physdev --physdev-out %s -s %s -j %s'
% (interface, address, drop_action)),
top=True)
def get_gateway_rules(bridge):

View File

@ -634,13 +634,9 @@ class LinuxNetworkTestCase(test.NoDBTestCase):
linux_net.IptablesManager())
self.stubs.Set(linux_net, 'binary_name', 'test')
executes = []
inputs = []
def fake_execute(*args, **kwargs):
executes.append(args)
process_input = kwargs.get('process_input')
if process_input:
inputs.append(process_input)
return "", ""
self.stubs.Set(utils, 'execute', fake_execute)
@ -669,27 +665,26 @@ class LinuxNetworkTestCase(test.NoDBTestCase):
iface, '--arp-ip-src', dhcp, '-j', 'DROP'),
('ebtables', '-t', 'filter', '-I', 'OUTPUT', '-p', 'ARP', '-o',
iface, '--arp-ip-src', dhcp, '-j', 'DROP'),
('ebtables', '-t', 'filter', '-D', 'FORWARD', '-p', 'IPv4', '-i',
iface, '--ip-protocol', 'udp', '--ip-destination-port', '67:68',
'-j', 'DROP'),
('ebtables', '-t', 'filter', '-I', 'FORWARD', '-p', 'IPv4', '-i',
iface, '--ip-protocol', 'udp', '--ip-destination-port', '67:68',
'-j', 'DROP'),
('ebtables', '-t', 'filter', '-D', 'FORWARD', '-p', 'IPv4', '-o',
iface, '--ip-protocol', 'udp', '--ip-destination-port', '67:68',
'-j', 'DROP'),
('ebtables', '-t', 'filter', '-I', 'FORWARD', '-p', 'IPv4', '-o',
iface, '--ip-protocol', 'udp', '--ip-destination-port', '67:68',
'-j', 'DROP'),
('iptables-save', '-c'),
('iptables-restore', '-c'),
('ip6tables-save', '-c'),
('ip6tables-restore', '-c'),
]
self.assertEqual(executes, expected)
expected_inputs = [
'-A test-FORWARD -m physdev --physdev-in %s '
'-d 255.255.255.255 -p udp --dport 67 -j DROP' % iface,
'-A test-FORWARD -m physdev --physdev-out %s '
'-d 255.255.255.255 -p udp --dport 67 -j DROP' % iface,
'-A test-FORWARD -m physdev --physdev-in %s '
'-d 192.168.1.1 -j DROP' % iface,
'-A test-FORWARD -m physdev --physdev-out %s '
'-s 192.168.1.1 -j DROP' % iface,
]
for inp in expected_inputs:
self.assertIn(inp, inputs[0])
executes = []
inputs = []
@staticmethod
def fake_remove(bridge, gateway):
@ -704,105 +699,14 @@ class LinuxNetworkTestCase(test.NoDBTestCase):
iface, '--arp-ip-dst', dhcp, '-j', 'DROP'),
('ebtables', '-t', 'filter', '-D', 'OUTPUT', '-p', 'ARP', '-o',
iface, '--arp-ip-src', dhcp, '-j', 'DROP'),
('iptables-save', '-c'),
('iptables-restore', '-c'),
('ip6tables-save', '-c'),
('ip6tables-restore', '-c'),
('ebtables', '-t', 'filter', '-D', 'FORWARD', '-p', 'IPv4', '-i',
iface, '--ip-protocol', 'udp', '--ip-destination-port', '67:68',
'-j', 'DROP'),
('ebtables', '-t', 'filter', '-D', 'FORWARD', '-p', 'IPv4', '-o',
iface, '--ip-protocol', 'udp', '--ip-destination-port', '67:68',
'-j', 'DROP'),
]
self.assertEqual(executes, expected)
for inp in expected_inputs:
self.assertNotIn(inp, inputs[0])
def test_isolated_host_iptables_logdrop(self):
# Ensure that a different drop action for iptables doesn't change
# the drop action for ebtables.
self.flags(fake_network=False,
share_dhcp_address=True,
iptables_drop_action='LOGDROP')
# NOTE(vish): use a fresh copy of the manager for each test
self.stubs.Set(linux_net, 'iptables_manager',
linux_net.IptablesManager())
self.stubs.Set(linux_net, 'binary_name', 'test')
executes = []
inputs = []
def fake_execute(*args, **kwargs):
executes.append(args)
process_input = kwargs.get('process_input')
if process_input:
inputs.append(process_input)
return "", ""
self.stubs.Set(utils, 'execute', fake_execute)
driver = linux_net.LinuxBridgeInterfaceDriver()
@staticmethod
def fake_ensure(bridge, interface, network, gateway):
return bridge
self.stubs.Set(linux_net.LinuxBridgeInterfaceDriver,
'ensure_bridge', fake_ensure)
iface = 'eth0'
dhcp = '192.168.1.1'
network = {'dhcp_server': dhcp,
'bridge': 'br100',
'bridge_interface': iface}
driver.plug(network, 'fakemac')
expected = [
('ebtables', '-t', 'filter', '-D', 'INPUT', '-p', 'ARP', '-i',
iface, '--arp-ip-dst', dhcp, '-j', 'DROP'),
('ebtables', '-t', 'filter', '-I', 'INPUT', '-p', 'ARP', '-i',
iface, '--arp-ip-dst', dhcp, '-j', 'DROP'),
('ebtables', '-t', 'filter', '-D', 'OUTPUT', '-p', 'ARP', '-o',
iface, '--arp-ip-src', dhcp, '-j', 'DROP'),
('ebtables', '-t', 'filter', '-I', 'OUTPUT', '-p', 'ARP', '-o',
iface, '--arp-ip-src', dhcp, '-j', 'DROP'),
('iptables-save', '-c'),
('iptables-restore', '-c'),
('ip6tables-save', '-c'),
('ip6tables-restore', '-c'),
]
self.assertEqual(executes, expected)
expected_inputs = [
('-A test-FORWARD -m physdev --physdev-in %s '
'-d 255.255.255.255 -p udp --dport 67 -j LOGDROP' % iface),
('-A test-FORWARD -m physdev --physdev-out %s '
'-d 255.255.255.255 -p udp --dport 67 -j LOGDROP' % iface),
('-A test-FORWARD -m physdev --physdev-in %s '
'-d 192.168.1.1 -j LOGDROP' % iface),
('-A test-FORWARD -m physdev --physdev-out %s '
'-s 192.168.1.1 -j LOGDROP' % iface),
]
for inp in expected_inputs:
self.assertIn(inp, inputs[0])
executes = []
inputs = []
@staticmethod
def fake_remove(bridge, gateway):
return
self.stubs.Set(linux_net.LinuxBridgeInterfaceDriver,
'remove_bridge', fake_remove)
driver.unplug(network)
expected = [
('ebtables', '-t', 'filter', '-D', 'INPUT', '-p', 'ARP', '-i',
iface, '--arp-ip-dst', dhcp, '-j', 'DROP'),
('ebtables', '-t', 'filter', '-D', 'OUTPUT', '-p', 'ARP', '-o',
iface, '--arp-ip-src', dhcp, '-j', 'DROP'),
('iptables-save', '-c'),
('iptables-restore', '-c'),
('ip6tables-save', '-c'),
('ip6tables-restore', '-c'),
]
self.assertEqual(executes, expected)
for inp in expected_inputs:
self.assertNotIn(inp, inputs[0])
def _test_initialize_gateway(self, existing, expected, routes=''):
self.flags(fake_network=False)