From fed1a9b92778df4e65bbe03976573d2c82f94163 Mon Sep 17 00:00:00 2001 From: Brent Eagles Date: Thu, 10 Sep 2015 10:45:47 -0230 Subject: [PATCH] Set owner to root for ipsec.secrets for LibreSwan LibreSwan runs as root and needs access to ipsec.secrets. Currently, ipsec.secrets is not owned by root and has 0600 permissions. This patch adds a rootwrap filter for the chown operation and sets the ipsec.secrets ownership to root. Change-Id: I414b5d9285d7a3ba9d3132bce9d7d5e3af43c37f Closes-Bug: #1493492 --- etc/neutron/rootwrap.d/vpnaas.filters | 1 + .../vpn/device_drivers/libreswan_ipsec.py | 8 ++++++++ .../services/vpn/device_drivers/test_ipsec.py | 16 +++++++++++----- 3 files changed, 20 insertions(+), 5 deletions(-) diff --git a/etc/neutron/rootwrap.d/vpnaas.filters b/etc/neutron/rootwrap.d/vpnaas.filters index f896a83a3..cfefdcf17 100644 --- a/etc/neutron/rootwrap.d/vpnaas.filters +++ b/etc/neutron/rootwrap.d/vpnaas.filters @@ -14,3 +14,4 @@ ipsec: CommandFilter, ipsec, root strongswan: CommandFilter, strongswan, root neutron_netns_wrapper: CommandFilter, neutron-vpn-netns-wrapper, root neutron_netns_wrapper_local: CommandFilter, /usr/local/bin/neutron-vpn-netns-wrapper, root +chown: CommandFilter, chown, root diff --git a/neutron_vpnaas/services/vpn/device_drivers/libreswan_ipsec.py b/neutron_vpnaas/services/vpn/device_drivers/libreswan_ipsec.py index d6dda6a4d..30336ec85 100644 --- a/neutron_vpnaas/services/vpn/device_drivers/libreswan_ipsec.py +++ b/neutron_vpnaas/services/vpn/device_drivers/libreswan_ipsec.py @@ -60,6 +60,14 @@ class LibreSwanProcess(ipsec.OpenSwanProcess): Initialise the nssdb, otherwise pluto daemon will fail to run. """ super(LibreSwanProcess, self).ensure_configs() + + # LibreSwan uses the capabilities library to restrict access to + # ipsec.secrets to users that have explicit access. Since pluto is + # running as root and the file has 0600 perms, we must set the + # owner of the file to root. + secrets_file = self._get_config_filename('ipsec.secrets') + self._execute(['chown', 'root:root', secrets_file]) + # Load the ipsec kernel module if not loaded self._execute([self.binary, '_stackmanager', 'start']) # checknss creates nssdb only if it is missing diff --git a/neutron_vpnaas/tests/unit/services/vpn/device_drivers/test_ipsec.py b/neutron_vpnaas/tests/unit/services/vpn/device_drivers/test_ipsec.py index 1fd3603a1..759a2e6e0 100644 --- a/neutron_vpnaas/tests/unit/services/vpn/device_drivers/test_ipsec.py +++ b/neutron_vpnaas/tests/unit/services/vpn/device_drivers/test_ipsec.py @@ -992,22 +992,28 @@ class TestLibreSwanProcess(base.BaseTestCase): openswan_ipsec.OpenSwanProcess.ensure_configs = mock.Mock() with mock.patch.object(self.ipsec_process, '_execute') as fake_execute: self.ipsec_process.ensure_configs() - expected = [mock.call(['ipsec', '_stackmanager', 'start']), + expected = [mock.call(['chown', 'root:root', + self.ipsec_process._get_config_filename( + 'ipsec.secrets')]), + mock.call(['ipsec', '_stackmanager', 'start']), mock.call(['ipsec', 'checknss', self.ipsec_process.etc_dir])] fake_execute.assert_has_calls(expected) - self.assertEqual(2, fake_execute.call_count) + self.assertEqual(3, fake_execute.call_count) with mock.patch.object(self.ipsec_process, '_execute') as fake_execute: - fake_execute.side_effect = [None, RuntimeError, None] + fake_execute.side_effect = [None, None, RuntimeError, None] self.ipsec_process.ensure_configs() - expected = [mock.call(['ipsec', '_stackmanager', 'start']), + expected = [mock.call(['chown', 'root:root', + self.ipsec_process._get_config_filename( + 'ipsec.secrets')]), + mock.call(['ipsec', '_stackmanager', 'start']), mock.call(['ipsec', 'checknss', self.ipsec_process.etc_dir]), mock.call(['ipsec', 'initnss', self.ipsec_process.etc_dir])] fake_execute.assert_has_calls(expected) - self.assertEqual(3, fake_execute.call_count) + self.assertEqual(4, fake_execute.call_count) class IPsecStrongswanDeviceDriverLegacy(IPSecDeviceLegacy):