Merge "Use ebtables to isolate dhcp traffic" into stable/icehouse
This commit is contained in:
commit
58ae4a6e3a
@ -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):
|
||||
|
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user