From ea5474d6051cb7c10b5a9ea5e1bcaeb060695a95 Mon Sep 17 00:00:00 2001 From: "Alexey I. Froloff" Date: Tue, 24 Feb 2015 17:42:34 +0300 Subject: [PATCH] linux_net.metadata_accept(): IPv6 support Even when using Neutron, Nova permits access to metadata service via iptables firewall. When metadata_ip configuration option contains IPv6 address, ip6tables should be used. Add IPv6 support to linux_net.metadata_accept(). Remove -s 0.0.0.0/0 from IPv4 iptables rule because it is redundant, which allows to use same rule syntax for IPv4 and IPv6. Change-Id: Ibd5830150011361edcaf3b06b01590087f295d03 Closes-Bug: #1425103 --- nova/network/linux_net.py | 21 +++++++++++++----- nova/tests/unit/network/test_linux_net.py | 27 +++++++++++++++++++++-- 2 files changed, 41 insertions(+), 7 deletions(-) diff --git a/nova/network/linux_net.py b/nova/network/linux_net.py index 099c8d16d0f6..1c55c137b518 100644 --- a/nova/network/linux_net.py +++ b/nova/network/linux_net.py @@ -678,14 +678,25 @@ def metadata_forward(): iptables_manager.apply() +def _iptables_dest(ip): + if ((netaddr.IPAddress(ip).version == 4 and ip == '127.0.0.1') + or ip == '::1'): + return '-m addrtype --dst-type LOCAL' + else: + return '-d %s' % ip + + def metadata_accept(): """Create the filter accept rule for metadata.""" - rule = '-s 0.0.0.0/0 -p tcp -m tcp --dport %s' % CONF.metadata_port - if CONF.metadata_host != '127.0.0.1': - rule += ' -d %s -j ACCEPT' % CONF.metadata_host + + rule = ('-p tcp -m tcp --dport %s %s -j ACCEPT' % + (CONF.metadata_port, _iptables_dest(CONF.metadata_host))) + + if netaddr.IPAddress(CONF.metadata_host).version == 4: + iptables_manager.ipv4['filter'].add_rule('INPUT', rule) else: - rule += ' -m addrtype --dst-type LOCAL -j ACCEPT' - iptables_manager.ipv4['filter'].add_rule('INPUT', rule) + iptables_manager.ipv6['filter'].add_rule('INPUT', rule) + iptables_manager.apply() diff --git a/nova/tests/unit/network/test_linux_net.py b/nova/tests/unit/network/test_linux_net.py index 02beed81a601..7760eca996ba 100644 --- a/nova/tests/unit/network/test_linux_net.py +++ b/nova/tests/unit/network/test_linux_net.py @@ -1046,20 +1046,43 @@ class LinuxNetworkTestCase(test.NoDBTestCase): 'add_rule', verify_add_rule) linux_net.metadata_accept() + def _test_add_metadata_accept_ipv6_rule(self, expected): + def verify_add_rule(chain, rule): + self.assertEqual(chain, 'INPUT') + self.assertEqual(expected, rule) + + self.stubs.Set(linux_net.iptables_manager.ipv6['filter'], + 'add_rule', verify_add_rule) + linux_net.metadata_accept() + def test_metadata_accept(self): self.flags(metadata_port='8775') self.flags(metadata_host='10.10.10.1') - expected = ('-s 0.0.0.0/0 -p tcp -m tcp --dport 8775 ' + expected = ('-p tcp -m tcp --dport 8775 ' '-d 10.10.10.1 -j ACCEPT') self._test_add_metadata_accept_rule(expected) + def test_metadata_accept_ipv6(self): + self.flags(metadata_port='8775') + self.flags(metadata_host='2600::') + expected = ('-p tcp -m tcp --dport 8775 ' + '-d 2600:: -j ACCEPT') + self._test_add_metadata_accept_ipv6_rule(expected) + def test_metadata_accept_localhost(self): self.flags(metadata_port='8775') self.flags(metadata_host='127.0.0.1') - expected = ('-s 0.0.0.0/0 -p tcp -m tcp --dport 8775 ' + expected = ('-p tcp -m tcp --dport 8775 ' '-m addrtype --dst-type LOCAL -j ACCEPT') self._test_add_metadata_accept_rule(expected) + def test_metadata_accept_ipv6_localhost(self): + self.flags(metadata_port='8775') + self.flags(metadata_host='::1') + expected = ('-p tcp -m tcp --dport 8775 ' + '-m addrtype --dst-type LOCAL -j ACCEPT') + self._test_add_metadata_accept_ipv6_rule(expected) + def _test_add_metadata_forward_rule(self, expected): def verify_add_rule(chain, rule): self.assertEqual(chain, 'PREROUTING')