summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOleksandr Kuchmystyi <o.kuchmystyi@vyos.io>2025-07-31 13:41:56 +0300
committerOleksandr Kuchmystyi <o.kuchmystyi@vyos.io>2025-08-12 12:11:05 +0300
commitc84c7cf16bf4a0222690f4ac2d93dafc88a7a0f7 (patch)
tree1a5f5712232b0fe6eae40a702c4650c1ee920490
parent7b42041ec7035a822bede3df4abbacb683f6d314 (diff)
downloadvyos-1x-c84c7cf16bf4a0222690f4ac2d93dafc88a7a0f7.tar.gz
vyos-1x-c84c7cf16bf4a0222690f4ac2d93dafc88a7a0f7.zip
ipsec: T7562: Add support for `disable-uniqreqids` option in IPsec configs
This commit makes `set vpn ipsec disable-uniqreqids` work with the modern StrongSwan backend by setting `unique=never` in swanctl.conf for connections. This restores legacy behavior about multiple connections with the same identity.
-rw-r--r--data/templates/ipsec/swanctl.conf.j28
-rw-r--r--data/templates/ipsec/swanctl/l2tp.j25
-rw-r--r--data/templates/ipsec/swanctl/peer.j25
-rw-r--r--data/templates/ipsec/swanctl/profile.j25
-rwxr-xr-xsmoketest/scripts/cli/test_vpn_ipsec.py10
-rwxr-xr-xsmoketest/scripts/cli/test_vpn_l2tp.py24
6 files changed, 49 insertions, 8 deletions
diff --git a/data/templates/ipsec/swanctl.conf.j2 b/data/templates/ipsec/swanctl.conf.j2
index 64e7ea860..e4e0b373d 100644
--- a/data/templates/ipsec/swanctl.conf.j2
+++ b/data/templates/ipsec/swanctl.conf.j2
@@ -4,15 +4,17 @@
{% import 'ipsec/swanctl/peer.j2' as peer_tmpl %}
{% import 'ipsec/swanctl/remote_access.j2' as remote_access_tmpl %}
+{% set uniqreqids = 'never' if disable_uniqreqids is vyos_defined else None %}
+
connections {
{% if profile is vyos_defined %}
{% for name, profile_conf in profile.items() if profile_conf.disable is not vyos_defined and profile_conf.bind.tunnel is vyos_defined %}
-{{ profile_tmpl.conn(name, profile_conf, ike_group, esp_group) }}
+{{ profile_tmpl.conn(name, profile_conf, ike_group, esp_group, uniqreqids) }}
{% endfor %}
{% endif %}
{% if site_to_site.peer is vyos_defined %}
{% for peer, peer_conf in site_to_site.peer.items() if peer not in dhcp_no_address and peer_conf.disable is not vyos_defined %}
-{{ peer_tmpl.conn(peer, peer_conf, ike_group, esp_group) }}
+{{ peer_tmpl.conn(peer, peer_conf, ike_group, esp_group, uniqreqids) }}
{% endfor %}
{% endif %}
{% if remote_access.connection is vyos_defined %}
@@ -21,7 +23,7 @@ connections {
{% endfor %}
{% endif %}
{% if l2tp %}
-{{ l2tp_tmpl.conn(l2tp, l2tp_outside_address, l2tp_ike_default, l2tp_esp_default, ike_group, esp_group) }}
+{{ l2tp_tmpl.conn(l2tp, l2tp_outside_address, l2tp_ike_default, l2tp_esp_default, ike_group, esp_group, uniqreqids) }}
{% endif %}
}
diff --git a/data/templates/ipsec/swanctl/l2tp.j2 b/data/templates/ipsec/swanctl/l2tp.j2
index 7e63865cc..7eaf9087d 100644
--- a/data/templates/ipsec/swanctl/l2tp.j2
+++ b/data/templates/ipsec/swanctl/l2tp.j2
@@ -1,4 +1,4 @@
-{% macro conn(l2tp, l2tp_outside_address, l2tp_ike_default, l2tp_esp_default, ike_group, esp_group) %}
+{% macro conn(l2tp, l2tp_outside_address, l2tp_ike_default, l2tp_esp_default, ike_group, esp_group, uniqreqids) %}
{% set l2tp_ike = ike_group[l2tp.ike_group] if l2tp.ike_group is vyos_defined else None %}
{% set l2tp_esp = esp_group[l2tp.esp_group] if l2tp.esp_group is vyos_defined else None %}
l2tp_remote_access {
@@ -8,6 +8,9 @@
dpd_timeout = 45s
rekey_time = {{ l2tp_ike.lifetime if l2tp_ike else l2tp.ike_lifetime }}s
reauth_time = 0
+{% if uniqreqids is vyos_defined %}
+ unique = {{ uniqreqids }}
+{% endif %}
local {
auth = {{ 'psk' if l2tp.authentication.mode == 'pre-shared-secret' else 'pubkey' }}
{% if l2tp.authentication.mode == 'x509' %}
diff --git a/data/templates/ipsec/swanctl/peer.j2 b/data/templates/ipsec/swanctl/peer.j2
index b6b5d2dac..518402c53 100644
--- a/data/templates/ipsec/swanctl/peer.j2
+++ b/data/templates/ipsec/swanctl/peer.j2
@@ -1,4 +1,4 @@
-{% macro conn(peer, peer_conf, ike_group, esp_group) %}
+{% macro conn(peer, peer_conf, ike_group, esp_group, uniqreqids) %}
{% set name = peer.replace("@", "") | dot_colon_to_dash %}
{# peer needs to reference the global IKE configuration for certain values #}
{% set ike = ike_group[peer_conf.ike_group] %}
@@ -33,6 +33,9 @@
{% if peer_conf.force_udp_encapsulation is vyos_defined %}
encap = yes
{% endif %}
+{% if uniqreqids is vyos_defined %}
+ unique = {{ uniqreqids }}
+{% endif %}
local {
{% if peer_conf.authentication.local_id is vyos_defined %}
id = "{{ peer_conf.authentication.local_id }}"
diff --git a/data/templates/ipsec/swanctl/profile.j2 b/data/templates/ipsec/swanctl/profile.j2
index 6a04b038a..10fe0a8ec 100644
--- a/data/templates/ipsec/swanctl/profile.j2
+++ b/data/templates/ipsec/swanctl/profile.j2
@@ -1,4 +1,4 @@
-{% macro conn(name, profile_conf, ike_group, esp_group) %}
+{% macro conn(name, profile_conf, ike_group, esp_group, uniqreqids) %}
{# peer needs to reference the global IKE configuration for certain values #}
{% set ike = ike_group[profile_conf.ike_group] %}
{% set esp = esp_group[profile_conf.esp_group] %}
@@ -13,6 +13,9 @@
dpd_timeout = {{ ike.dead_peer_detection.timeout }}
dpd_delay = {{ ike.dead_peer_detection.interval }}
{% endif %}
+{% if uniqreqids is vyos_defined %}
+ unique = {{ uniqreqids }}
+{% endif %}
{% if profile_conf.authentication.mode is vyos_defined('pre-shared-secret') %}
local {
auth = psk
diff --git a/smoketest/scripts/cli/test_vpn_ipsec.py b/smoketest/scripts/cli/test_vpn_ipsec.py
index 5437711ce..8206218b1 100755
--- a/smoketest/scripts/cli/test_vpn_ipsec.py
+++ b/smoketest/scripts/cli/test_vpn_ipsec.py
@@ -233,6 +233,9 @@ class TestVPNIPsec(VyOSUnitTestSHIM.TestCase):
self.cli_set(peer_base_path + ['tunnel', '2', 'remote', 'prefix', '10.2.0.0/16'])
self.cli_set(peer_base_path + ['tunnel', '2', 'priority', priority])
+ # Passing the 'unique = never' for StrongSwan's `connections.<conn>.unique` parameter
+ self.cli_set(base_path + ['disable-uniqreqids'])
+
self.cli_commit()
# Verify strongSwan configuration
@@ -259,6 +262,7 @@ class TestVPNIPsec(VyOSUnitTestSHIM.TestCase):
f'priority = {priority}',
f'mode = tunnel',
f'replay_window = 32',
+ 'unique = never',
]
for line in swanctl_conf_lines:
self.assertIn(line, swanctl_conf)
@@ -634,6 +638,9 @@ class TestVPNIPsec(VyOSUnitTestSHIM.TestCase):
self.cli_set(base_path + ['profile', 'NHRPVPN', 'esp-group', esp_group])
self.cli_set(base_path + ['profile', 'NHRPVPN', 'ike-group', ike_group])
+ # Passing the 'unique = never' for StrongSwan's `connections.<conn>.unique` parameter
+ self.cli_set(base_path + ['disable-uniqreqids'])
+
self.cli_commit()
swanctl_conf = read_file(swanctl_file)
@@ -646,7 +653,8 @@ class TestVPNIPsec(VyOSUnitTestSHIM.TestCase):
f'local_ts = dynamic[gre]',
f'remote_ts = dynamic[gre]',
f'mode = transport',
- f'secret = {nhrp_secret}'
+ f'secret = {nhrp_secret}',
+ 'unique = never',
]
for line in swanctl_lines:
self.assertIn(line, swanctl_conf)
diff --git a/smoketest/scripts/cli/test_vpn_l2tp.py b/smoketest/scripts/cli/test_vpn_l2tp.py
index 581ebd35d..98f04c088 100755
--- a/smoketest/scripts/cli/test_vpn_l2tp.py
+++ b/smoketest/scripts/cli/test_vpn_l2tp.py
@@ -19,6 +19,10 @@ import unittest
from base_accel_ppp_test import BasicAccelPPPTest
from configparser import ConfigParser
from vyos.utils.process import cmd
+from vyos.utils.file import read_file
+
+
+swanctl_file = '/etc/swanctl/swanctl.conf'
class TestVPNL2TPServer(BasicAccelPPPTest.TestCase):
@@ -57,11 +61,16 @@ class TestVPNL2TPServer(BasicAccelPPPTest.TestCase):
def test_vpn_l2tp_dependence_ipsec_swanctl(self):
# Test config vpn for tasks T3843 and T5926
+ outside_address = '203.0.113.1'
+
base_path = ['vpn', 'l2tp', 'remote-access']
# make precondition
self.cli_set(['interfaces', 'dummy', 'dum0', 'address', '203.0.113.1/32'])
self.cli_set(['vpn', 'ipsec', 'interface', 'dum0'])
+ # Passing the 'unique = never' for StrongSwan's `connections.<conn>.unique` parameter
+ self.cli_set(['vpn', 'ipsec', 'disable-uniqreqids'])
+
self.cli_commit()
# check ipsec apply to swanctl
self.assertEqual('', cmd('echo vyos | sudo -S swanctl -L '))
@@ -76,7 +85,7 @@ class TestVPNL2TPServer(BasicAccelPPPTest.TestCase):
self.cli_set(base_path + ['ipsec-settings', 'authentication', 'pre-shared-secret', 'SeCret'])
self.cli_set(base_path + ['ipsec-settings', 'ike-lifetime', '8600'])
self.cli_set(base_path + ['ipsec-settings', 'lifetime', '3600'])
- self.cli_set(base_path + ['outside-address', '203.0.113.1'])
+ self.cli_set(base_path + ['outside-address', outside_address])
self.cli_set(base_path + ['gateway-address', '203.0.113.1'])
self.cli_commit()
@@ -84,6 +93,19 @@ class TestVPNL2TPServer(BasicAccelPPPTest.TestCase):
# check l2tp apply to swanctl
self.assertTrue('l2tp_remote_access:' in cmd('echo vyos | sudo -S swanctl -L '))
+ swanctl_conf = read_file(swanctl_file)
+ swanctl_lines = [
+ f'local_addrs = {outside_address}',
+ 'proposals = aes256-sha1-modp1024,3des-sha1-modp1024',
+ 'dpd_delay = 15s',
+ 'dpd_timeout = 45s',
+ 'rekey_time = 8600s',
+ 'reauth_time = 0',
+ 'unique = never',
+ ]
+ for line in swanctl_lines:
+ self.assertIn(line, swanctl_conf)
+
self.cli_delete(['vpn', 'l2tp'])
self.cli_commit()