Add wrap_name param to the iptables_manager class
Use this optional parameter instead of binary_name to wrap the chain names. Fixes: bug #1194049 Change-Id: I69b4d9043769703248e19184eaedbdbf7a43d96e
This commit is contained in:
parent
6eae300755
commit
9aecb8f812
@ -62,11 +62,13 @@ class IptablesRule(object):
|
|||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, chain, rule, wrap=True, top=False):
|
def __init__(self, chain, rule, wrap=True, top=False,
|
||||||
|
binary_name=binary_name):
|
||||||
self.chain = get_chain_name(chain, wrap)
|
self.chain = get_chain_name(chain, wrap)
|
||||||
self.rule = rule
|
self.rule = rule
|
||||||
self.wrap = wrap
|
self.wrap = wrap
|
||||||
self.top = top
|
self.top = top
|
||||||
|
self.wrap_name = binary_name[:16]
|
||||||
|
|
||||||
def __eq__(self, other):
|
def __eq__(self, other):
|
||||||
return ((self.chain == other.chain) and
|
return ((self.chain == other.chain) and
|
||||||
@ -79,7 +81,7 @@ class IptablesRule(object):
|
|||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
if self.wrap:
|
if self.wrap:
|
||||||
chain = '%s-%s' % (binary_name, self.chain)
|
chain = '%s-%s' % (self.wrap_name, self.chain)
|
||||||
else:
|
else:
|
||||||
chain = self.chain
|
chain = self.chain
|
||||||
return '-A %s %s' % (chain, self.rule)
|
return '-A %s %s' % (chain, self.rule)
|
||||||
@ -88,12 +90,13 @@ class IptablesRule(object):
|
|||||||
class IptablesTable(object):
|
class IptablesTable(object):
|
||||||
"""An iptables table."""
|
"""An iptables table."""
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self, binary_name=binary_name):
|
||||||
self.rules = []
|
self.rules = []
|
||||||
self.remove_rules = []
|
self.remove_rules = []
|
||||||
self.chains = set()
|
self.chains = set()
|
||||||
self.unwrapped_chains = set()
|
self.unwrapped_chains = set()
|
||||||
self.remove_chains = set()
|
self.remove_chains = set()
|
||||||
|
self.wrap_name = binary_name[:16]
|
||||||
|
|
||||||
def add_chain(self, name, wrap=True):
|
def add_chain(self, name, wrap=True):
|
||||||
"""Adds a named chain to the table.
|
"""Adds a named chain to the table.
|
||||||
@ -168,7 +171,7 @@ class IptablesTable(object):
|
|||||||
self.remove_rules += [r for r in self.rules
|
self.remove_rules += [r for r in self.rules
|
||||||
if jump_snippet in r.rule]
|
if jump_snippet in r.rule]
|
||||||
else:
|
else:
|
||||||
jump_snippet = '-j %s-%s' % (binary_name, name)
|
jump_snippet = '-j %s-%s' % (self.wrap_name, name)
|
||||||
|
|
||||||
# finally, remove rules from list that have a matching jump chain
|
# finally, remove rules from list that have a matching jump chain
|
||||||
self.rules = [r for r in self.rules
|
self.rules = [r for r in self.rules
|
||||||
@ -192,11 +195,11 @@ class IptablesTable(object):
|
|||||||
if '$' in rule:
|
if '$' in rule:
|
||||||
rule = ' '.join(map(self._wrap_target_chain, rule.split(' ')))
|
rule = ' '.join(map(self._wrap_target_chain, rule.split(' ')))
|
||||||
|
|
||||||
self.rules.append(IptablesRule(chain, rule, wrap, top))
|
self.rules.append(IptablesRule(chain, rule, wrap, top, self.wrap_name))
|
||||||
|
|
||||||
def _wrap_target_chain(self, s):
|
def _wrap_target_chain(self, s):
|
||||||
if s.startswith('$'):
|
if s.startswith('$'):
|
||||||
return ('%s-%s' % (binary_name, s[1:]))
|
return ('%s-%s' % (self.wrap_name, s[1:]))
|
||||||
return s
|
return s
|
||||||
|
|
||||||
def remove_rule(self, chain, rule, wrap=True, top=False):
|
def remove_rule(self, chain, rule, wrap=True, top=False):
|
||||||
@ -209,9 +212,11 @@ class IptablesTable(object):
|
|||||||
"""
|
"""
|
||||||
chain = get_chain_name(chain, wrap)
|
chain = get_chain_name(chain, wrap)
|
||||||
try:
|
try:
|
||||||
self.rules.remove(IptablesRule(chain, rule, wrap, top))
|
self.rules.remove(IptablesRule(chain, rule, wrap, top,
|
||||||
|
self.wrap_name))
|
||||||
if not wrap:
|
if not wrap:
|
||||||
self.remove_rules.append(IptablesRule(chain, rule, wrap, top))
|
self.remove_rules.append(IptablesRule(chain, rule, wrap, top,
|
||||||
|
self.wrap_name))
|
||||||
except ValueError:
|
except ValueError:
|
||||||
LOG.warn(_('Tried to remove rule that was not there:'
|
LOG.warn(_('Tried to remove rule that was not there:'
|
||||||
' %(chain)r %(rule)r %(wrap)r %(top)r'),
|
' %(chain)r %(rule)r %(wrap)r %(top)r'),
|
||||||
@ -251,7 +256,8 @@ class IptablesManager(object):
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, _execute=None, state_less=False,
|
def __init__(self, _execute=None, state_less=False,
|
||||||
root_helper=None, use_ipv6=False, namespace=None):
|
root_helper=None, use_ipv6=False, namespace=None,
|
||||||
|
binary_name=binary_name):
|
||||||
if _execute:
|
if _execute:
|
||||||
self.execute = _execute
|
self.execute = _execute
|
||||||
else:
|
else:
|
||||||
@ -261,9 +267,10 @@ class IptablesManager(object):
|
|||||||
self.root_helper = root_helper
|
self.root_helper = root_helper
|
||||||
self.namespace = namespace
|
self.namespace = namespace
|
||||||
self.iptables_apply_deferred = False
|
self.iptables_apply_deferred = False
|
||||||
|
self.wrap_name = binary_name[:16]
|
||||||
|
|
||||||
self.ipv4 = {'filter': IptablesTable()}
|
self.ipv4 = {'filter': IptablesTable(binary_name=self.wrap_name)}
|
||||||
self.ipv6 = {'filter': IptablesTable()}
|
self.ipv6 = {'filter': IptablesTable(binary_name=self.wrap_name)}
|
||||||
|
|
||||||
# Add a neutron-filter-top chain. It's intended to be shared
|
# Add a neutron-filter-top chain. It's intended to be shared
|
||||||
# among the various nova components. It sits at the very top
|
# among the various nova components. It sits at the very top
|
||||||
@ -284,7 +291,8 @@ class IptablesManager(object):
|
|||||||
6: {'filter': ['INPUT', 'OUTPUT', 'FORWARD']}}
|
6: {'filter': ['INPUT', 'OUTPUT', 'FORWARD']}}
|
||||||
|
|
||||||
if not state_less:
|
if not state_less:
|
||||||
self.ipv4.update({'nat': IptablesTable()})
|
self.ipv4.update(
|
||||||
|
{'nat': IptablesTable(binary_name=self.wrap_name)})
|
||||||
builtin_chains[4].update({'nat': ['PREROUTING',
|
builtin_chains[4].update({'nat': ['PREROUTING',
|
||||||
'OUTPUT', 'POSTROUTING']})
|
'OUTPUT', 'POSTROUTING']})
|
||||||
|
|
||||||
@ -298,7 +306,7 @@ class IptablesManager(object):
|
|||||||
for chain in chains:
|
for chain in chains:
|
||||||
tables[table].add_chain(chain)
|
tables[table].add_chain(chain)
|
||||||
tables[table].add_rule(chain, '-j $%s' %
|
tables[table].add_rule(chain, '-j $%s' %
|
||||||
(chain), wrap=False)
|
(chain), wrap=False)
|
||||||
|
|
||||||
if not state_less:
|
if not state_less:
|
||||||
# Add a neutron-postrouting-bottom chain. It's intended to be
|
# Add a neutron-postrouting-bottom chain. It's intended to be
|
||||||
@ -412,13 +420,13 @@ class IptablesManager(object):
|
|||||||
# Fill new_filter with any chains or rules without our name in them.
|
# Fill new_filter with any chains or rules without our name in them.
|
||||||
old_filter, new_filter = [], []
|
old_filter, new_filter = [], []
|
||||||
for line in current_lines:
|
for line in current_lines:
|
||||||
(old_filter if binary_name in line else
|
(old_filter if self.wrap_name in line else
|
||||||
new_filter).append(line.strip())
|
new_filter).append(line.strip())
|
||||||
|
|
||||||
rules_index = self._find_rules_index(new_filter)
|
rules_index = self._find_rules_index(new_filter)
|
||||||
|
|
||||||
all_chains = [':%s' % name for name in unwrapped_chains]
|
all_chains = [':%s' % name for name in unwrapped_chains]
|
||||||
all_chains += [':%s-%s' % (binary_name, name) for name in chains]
|
all_chains += [':%s-%s' % (self.wrap_name, name) for name in chains]
|
||||||
|
|
||||||
# Iterate through all the chains, trying to find an existing
|
# Iterate through all the chains, trying to find an existing
|
||||||
# match.
|
# match.
|
||||||
|
@ -88,6 +88,182 @@ class IptablesManagerStateFulTestCase(base.BaseTestCase):
|
|||||||
self.assertEqual(iptables_manager.get_chain_name(name, wrap=True),
|
self.assertEqual(iptables_manager.get_chain_name(name, wrap=True),
|
||||||
name[:11])
|
name[:11])
|
||||||
|
|
||||||
|
def test_add_and_remove_chain_custom_binary_name(self):
|
||||||
|
bn = ("abcdef" * 5)
|
||||||
|
|
||||||
|
self.iptables = (iptables_manager.
|
||||||
|
IptablesManager(root_helper=self.root_helper,
|
||||||
|
binary_name=bn))
|
||||||
|
self.mox.StubOutWithMock(self.iptables, "execute")
|
||||||
|
|
||||||
|
self.iptables.execute(['iptables-save', '-c'],
|
||||||
|
root_helper=self.root_helper).AndReturn('')
|
||||||
|
|
||||||
|
iptables_args = {'bn': bn[:16]}
|
||||||
|
|
||||||
|
filter_dump = ('# Generated by iptables_manager\n'
|
||||||
|
'*filter\n'
|
||||||
|
':neutron-filter-top - [0:0]\n'
|
||||||
|
':%(bn)s-FORWARD - [0:0]\n'
|
||||||
|
':%(bn)s-INPUT - [0:0]\n'
|
||||||
|
':%(bn)s-local - [0:0]\n'
|
||||||
|
':%(bn)s-filter - [0:0]\n'
|
||||||
|
':%(bn)s-OUTPUT - [0:0]\n'
|
||||||
|
'[0:0] -A FORWARD -j neutron-filter-top\n'
|
||||||
|
'[0:0] -A OUTPUT -j neutron-filter-top\n'
|
||||||
|
'[0:0] -A neutron-filter-top -j %(bn)s-local\n'
|
||||||
|
'[0:0] -A INPUT -j %(bn)s-INPUT\n'
|
||||||
|
'[0:0] -A OUTPUT -j %(bn)s-OUTPUT\n'
|
||||||
|
'[0:0] -A FORWARD -j %(bn)s-FORWARD\n'
|
||||||
|
'COMMIT\n'
|
||||||
|
'# Completed by iptables_manager\n' % iptables_args)
|
||||||
|
|
||||||
|
filter_dump_mod = ('# Generated by iptables_manager\n'
|
||||||
|
'*filter\n'
|
||||||
|
':neutron-filter-top - [0:0]\n'
|
||||||
|
':%(bn)s-FORWARD - [0:0]\n'
|
||||||
|
':%(bn)s-INPUT - [0:0]\n'
|
||||||
|
':%(bn)s-local - [0:0]\n'
|
||||||
|
':%(bn)s-filter - [0:0]\n'
|
||||||
|
':%(bn)s-OUTPUT - [0:0]\n'
|
||||||
|
'[0:0] -A FORWARD -j neutron-filter-top\n'
|
||||||
|
'[0:0] -A OUTPUT -j neutron-filter-top\n'
|
||||||
|
'[0:0] -A neutron-filter-top -j %(bn)s-local\n'
|
||||||
|
'[0:0] -A INPUT -j %(bn)s-INPUT\n'
|
||||||
|
'[0:0] -A OUTPUT -j %(bn)s-OUTPUT\n'
|
||||||
|
'[0:0] -A FORWARD -j %(bn)s-FORWARD\n'
|
||||||
|
'COMMIT\n'
|
||||||
|
'# Completed by iptables_manager\n'
|
||||||
|
% iptables_args)
|
||||||
|
|
||||||
|
nat_dump = ('# Generated by iptables_manager\n'
|
||||||
|
'*nat\n'
|
||||||
|
':neutron-postrouting-bottom - [0:0]\n'
|
||||||
|
':%(bn)s-OUTPUT - [0:0]\n'
|
||||||
|
':%(bn)s-snat - [0:0]\n'
|
||||||
|
':%(bn)s-PREROUTING - [0:0]\n'
|
||||||
|
':%(bn)s-float-snat - [0:0]\n'
|
||||||
|
':%(bn)s-POSTROUTING - [0:0]\n'
|
||||||
|
'[0:0] -A PREROUTING -j %(bn)s-PREROUTING\n'
|
||||||
|
'[0:0] -A OUTPUT -j %(bn)s-OUTPUT\n'
|
||||||
|
'[0:0] -A POSTROUTING -j %(bn)s-POSTROUTING\n'
|
||||||
|
'[0:0] -A POSTROUTING -j neutron-postrouting-bottom\n'
|
||||||
|
'[0:0] -A neutron-postrouting-bottom -j %(bn)s-snat\n'
|
||||||
|
'[0:0] -A %(bn)s-snat -j '
|
||||||
|
'%(bn)s-float-snat\n'
|
||||||
|
'COMMIT\n'
|
||||||
|
'# Completed by iptables_manager\n' % iptables_args)
|
||||||
|
|
||||||
|
self.iptables.execute(['iptables-restore', '-c'],
|
||||||
|
process_input=nat_dump + filter_dump_mod,
|
||||||
|
root_helper=self.root_helper).AndReturn(None)
|
||||||
|
|
||||||
|
self.iptables.execute(['iptables-save', '-c'],
|
||||||
|
root_helper=self.root_helper).AndReturn('')
|
||||||
|
|
||||||
|
self.iptables.execute(['iptables-restore', '-c'],
|
||||||
|
process_input=nat_dump + filter_dump,
|
||||||
|
root_helper=self.root_helper).AndReturn(None)
|
||||||
|
|
||||||
|
self.mox.ReplayAll()
|
||||||
|
|
||||||
|
self.iptables.ipv4['filter'].add_chain('filter')
|
||||||
|
self.iptables.apply()
|
||||||
|
|
||||||
|
self.iptables.ipv4['filter'].empty_chain('filter')
|
||||||
|
self.iptables.apply()
|
||||||
|
|
||||||
|
self.mox.VerifyAll()
|
||||||
|
|
||||||
|
def test_empty_chain_custom_binary_name(self):
|
||||||
|
bn = ("abcdef" * 5)[:16]
|
||||||
|
|
||||||
|
self.iptables = (iptables_manager.
|
||||||
|
IptablesManager(root_helper=self.root_helper,
|
||||||
|
binary_name=bn))
|
||||||
|
self.mox.StubOutWithMock(self.iptables, "execute")
|
||||||
|
|
||||||
|
self.iptables.execute(['iptables-save', '-c'],
|
||||||
|
root_helper=self.root_helper).AndReturn('')
|
||||||
|
|
||||||
|
iptables_args = {'bn': bn}
|
||||||
|
|
||||||
|
filter_dump = ('# Generated by iptables_manager\n'
|
||||||
|
'*filter\n'
|
||||||
|
':neutron-filter-top - [0:0]\n'
|
||||||
|
':%(bn)s-FORWARD - [0:0]\n'
|
||||||
|
':%(bn)s-INPUT - [0:0]\n'
|
||||||
|
':%(bn)s-local - [0:0]\n'
|
||||||
|
':%(bn)s-OUTPUT - [0:0]\n'
|
||||||
|
'[0:0] -A FORWARD -j neutron-filter-top\n'
|
||||||
|
'[0:0] -A OUTPUT -j neutron-filter-top\n'
|
||||||
|
'[0:0] -A neutron-filter-top -j %(bn)s-local\n'
|
||||||
|
'[0:0] -A INPUT -j %(bn)s-INPUT\n'
|
||||||
|
'[0:0] -A OUTPUT -j %(bn)s-OUTPUT\n'
|
||||||
|
'[0:0] -A FORWARD -j %(bn)s-FORWARD\n'
|
||||||
|
'COMMIT\n'
|
||||||
|
'# Completed by iptables_manager\n' % iptables_args)
|
||||||
|
|
||||||
|
filter_dump_mod = ('# Generated by iptables_manager\n'
|
||||||
|
'*filter\n'
|
||||||
|
':neutron-filter-top - [0:0]\n'
|
||||||
|
':%(bn)s-FORWARD - [0:0]\n'
|
||||||
|
':%(bn)s-INPUT - [0:0]\n'
|
||||||
|
':%(bn)s-local - [0:0]\n'
|
||||||
|
':%(bn)s-filter - [0:0]\n'
|
||||||
|
':%(bn)s-OUTPUT - [0:0]\n'
|
||||||
|
'[0:0] -A FORWARD -j neutron-filter-top\n'
|
||||||
|
'[0:0] -A OUTPUT -j neutron-filter-top\n'
|
||||||
|
'[0:0] -A neutron-filter-top -j %(bn)s-local\n'
|
||||||
|
'[0:0] -A INPUT -j %(bn)s-INPUT\n'
|
||||||
|
'[0:0] -A OUTPUT -j %(bn)s-OUTPUT\n'
|
||||||
|
'[0:0] -A FORWARD -j %(bn)s-FORWARD\n'
|
||||||
|
'[0:0] -A %(bn)s-filter -s 0/0 -d 192.168.0.2\n'
|
||||||
|
'COMMIT\n'
|
||||||
|
'# Completed by iptables_manager\n'
|
||||||
|
% iptables_args)
|
||||||
|
|
||||||
|
nat_dump = ('# Generated by iptables_manager\n'
|
||||||
|
'*nat\n'
|
||||||
|
':neutron-postrouting-bottom - [0:0]\n'
|
||||||
|
':%(bn)s-OUTPUT - [0:0]\n'
|
||||||
|
':%(bn)s-snat - [0:0]\n'
|
||||||
|
':%(bn)s-PREROUTING - [0:0]\n'
|
||||||
|
':%(bn)s-float-snat - [0:0]\n'
|
||||||
|
':%(bn)s-POSTROUTING - [0:0]\n'
|
||||||
|
'[0:0] -A PREROUTING -j %(bn)s-PREROUTING\n'
|
||||||
|
'[0:0] -A OUTPUT -j %(bn)s-OUTPUT\n'
|
||||||
|
'[0:0] -A POSTROUTING -j %(bn)s-POSTROUTING\n'
|
||||||
|
'[0:0] -A POSTROUTING -j neutron-postrouting-bottom\n'
|
||||||
|
'[0:0] -A neutron-postrouting-bottom -j %(bn)s-snat\n'
|
||||||
|
'[0:0] -A %(bn)s-snat -j '
|
||||||
|
'%(bn)s-float-snat\n'
|
||||||
|
'COMMIT\n'
|
||||||
|
'# Completed by iptables_manager\n' % iptables_args)
|
||||||
|
|
||||||
|
self.iptables.execute(['iptables-restore', '-c'],
|
||||||
|
process_input=nat_dump + filter_dump_mod,
|
||||||
|
root_helper=self.root_helper).AndReturn(None)
|
||||||
|
|
||||||
|
self.iptables.execute(['iptables-save', '-c'],
|
||||||
|
root_helper=self.root_helper).AndReturn('')
|
||||||
|
|
||||||
|
self.iptables.execute(['iptables-restore', '-c'],
|
||||||
|
process_input=nat_dump + filter_dump,
|
||||||
|
root_helper=self.root_helper).AndReturn(None)
|
||||||
|
|
||||||
|
self.mox.ReplayAll()
|
||||||
|
|
||||||
|
self.iptables.ipv4['filter'].add_chain('filter')
|
||||||
|
self.iptables.ipv4['filter'].add_rule('filter',
|
||||||
|
'-s 0/0 -d 192.168.0.2')
|
||||||
|
self.iptables.apply()
|
||||||
|
|
||||||
|
self.iptables.ipv4['filter'].remove_chain('filter')
|
||||||
|
self.iptables.apply()
|
||||||
|
|
||||||
|
self.mox.VerifyAll()
|
||||||
|
|
||||||
def test_add_and_remove_chain(self):
|
def test_add_and_remove_chain(self):
|
||||||
self.iptables.execute(['iptables-save', '-c'],
|
self.iptables.execute(['iptables-save', '-c'],
|
||||||
root_helper=self.root_helper).AndReturn('')
|
root_helper=self.root_helper).AndReturn('')
|
||||||
|
Loading…
Reference in New Issue
Block a user