From 55558e8f3b5a1d0108771d712b699e87839146a3 Mon Sep 17 00:00:00 2001 From: Bodo Petermann Date: Tue, 19 Sep 2023 15:58:56 +0200 Subject: [PATCH] Support for libreswan 4 With libreswan 4 some command line option changed, the rundir is now /run/pluto instead of /var/run/pluto, and nat_traversal must not be set in ipsec.conf. Adapt the libreswan device driver accordingly. Users will require libreswan v4.0 or higher, compatibility with v3.x is not maintained. Closes-Bug: #1938571 Change-Id: Ib55e3c3f9cfbe3dfe1241ace8c821256d7fc174a --- .../services/vpn/device_drivers/ipsec.py | 7 ++++++- .../vpn/device_drivers/libreswan_ipsec.py | 6 ++++-- .../template/openswan/ipsec.conf.template | 4 +++- .../services/vpn/device_drivers/test_ipsec.py | 18 ++++++++++++++---- .../notes/libreswan4-0e43b4cc41a5c0bc.yaml | 8 ++++++++ 5 files changed, 35 insertions(+), 8 deletions(-) create mode 100644 releasenotes/notes/libreswan4-0e43b4cc41a5c0bc.yaml diff --git a/neutron_vpnaas/services/vpn/device_drivers/ipsec.py b/neutron_vpnaas/services/vpn/device_drivers/ipsec.py index 849c2c0fc..e07c75ac7 100644 --- a/neutron_vpnaas/services/vpn/device_drivers/ipsec.py +++ b/neutron_vpnaas/services/vpn/device_drivers/ipsec.py @@ -445,6 +445,10 @@ class OpenSwanProcess(BaseSwanProcess): (2) ipsec addconn: Adds new ipsec addconn (3) ipsec whack: control interface for IPSEC keying daemon """ + # Derived classes can set IPSEC_CONF_NAT_TRAVERSAL to None to + # omit the nat_traversal line in ipsec.conf + IPSEC_CONF_NAT_TRAVERSAL = "yes" + def __init__(self, conf, process_id, vpnservice, namespace): super(OpenSwanProcess, self).__init__(conf, process_id, vpnservice, namespace) @@ -641,7 +645,8 @@ class OpenSwanProcess(BaseSwanProcess): virtual_privates = self._virtual_privates(vpnservice) return template.render( {'vpnservice': vpnservice, - 'virtual_privates': virtual_privates}) + 'virtual_privates': virtual_privates, + 'nat_traversal': self.IPSEC_CONF_NAT_TRAVERSAL}) def start_pluto(self): cmd = [self.binary, diff --git a/neutron_vpnaas/services/vpn/device_drivers/libreswan_ipsec.py b/neutron_vpnaas/services/vpn/device_drivers/libreswan_ipsec.py index 90731f7a4..6813e47e2 100644 --- a/neutron_vpnaas/services/vpn/device_drivers/libreswan_ipsec.py +++ b/neutron_vpnaas/services/vpn/device_drivers/libreswan_ipsec.py @@ -25,6 +25,8 @@ class LibreSwanProcess(ipsec.OpenSwanProcess): Libreswan needs nssdb initialised before running pluto daemon. """ + IPSEC_CONF_NAT_TRAVERSAL = None + # pylint: disable=useless-super-delegation def __init__(self, conf, process_id, vpnservice, namespace): self._rootwrap_cfg = self._get_rootwrap_config() @@ -39,7 +41,7 @@ class LibreSwanProcess(ipsec.OpenSwanProcess): """ ip_wrapper = ip_lib.IPWrapper(namespace=self.namespace) mount_paths = {'/etc': '%s/etc' % self.config_dir, - '/var/run': '%s/var/run' % self.config_dir} + '/run': '%s/var/run' % self.config_dir} mount_paths_str = ','.join( "%s:%s" % (source, target) for source, target in mount_paths.items()) @@ -106,7 +108,7 @@ class LibreSwanProcess(ipsec.OpenSwanProcess): def start_pluto(self): cmd = ['pluto', - '--use-netkey', + '--use-xfrm', '--uniqueids'] if self.conf.ipsec.enable_detailed_logging: diff --git a/neutron_vpnaas/services/vpn/device_drivers/template/openswan/ipsec.conf.template b/neutron_vpnaas/services/vpn/device_drivers/template/openswan/ipsec.conf.template index 450bef517..6bc336dcb 100644 --- a/neutron_vpnaas/services/vpn/device_drivers/template/openswan/ipsec.conf.template +++ b/neutron_vpnaas/services/vpn/device_drivers/template/openswan/ipsec.conf.template @@ -1,6 +1,8 @@ # Configuration for {{vpnservice.id}} config setup - nat_traversal=yes + {% if nat_traversal is defined and nat_traversal is not none -%} + nat_traversal={{nat_traversal}} + {% endif -%} virtual_private={{virtual_privates}} conn %default keylife=60m 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 eab6ff2b8..cc0ff674a 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 @@ -998,10 +998,10 @@ class TestOpenSwanConfigGeneration(BaseIPsecDeviceDriver): self.conf.register_opts(openswan_ipsec.openswan_opts, 'openswan') self.conf.set_override('state_path', '/tmp') self.ipsec_template = self.conf.openswan.ipsec_config_template - self.process = openswan_ipsec.OpenSwanProcess(self.conf, - 'foo-process-id', - self.vpnservice, - mock.ANY) + self.process = ipsec_process(self.conf, + 'foo-process-id', + self.vpnservice, + mock.ANY) def build_ipsec_expected_config_for_test(self, info): """Modify OpenSwan ipsec expected config files for test variations.""" @@ -1206,6 +1206,16 @@ class IPsecStrongswanConfigGeneration(BaseIPsecDeviceDriver): self.check_config_file(expected, actual) +class TestLibreSwanConfigGeneration(TestOpenSwanConfigGeneration): + def setUp(self, driver=libreswan_ipsec.LibreSwanDriver, + ipsec_process=libreswan_ipsec.LibreSwanProcess): + super().setUp(driver=driver, ipsec_process=ipsec_process) + + def build_ipsec_expected_config_for_test(self, info): + expected = super().build_ipsec_expected_config_for_test(info) + return expected.replace(' nat_traversal=yes\n', '') + + class TestOpenSwanProcess(IPSecDeviceLegacy): _test_timeout = 1 diff --git a/releasenotes/notes/libreswan4-0e43b4cc41a5c0bc.yaml b/releasenotes/notes/libreswan4-0e43b4cc41a5c0bc.yaml new file mode 100644 index 000000000..6f23e74d2 --- /dev/null +++ b/releasenotes/notes/libreswan4-0e43b4cc41a5c0bc.yaml @@ -0,0 +1,8 @@ +--- +upgrade: + - | + The updated VPNaaS driver for libreswan requires libreswan v4.0 or later. +fixes: + - | + Fixed the VPNaaS driver for libreswan to be compatible with libreswan v4 + and dropped support for libreswan v3.x.