summaryrefslogtreecommitdiff
path: root/src/migration-scripts/ipsec
diff options
context:
space:
mode:
authorDaniil Baturin <daniil@vyos.io>2024-09-12 13:59:18 +0100
committerGitHub <noreply@github.com>2024-09-12 13:59:18 +0100
commit205d957d092ade5708cc2182381864c04e4c0aff (patch)
treee78636efaa1332c5d49e1c2f023721dc030f8d6a /src/migration-scripts/ipsec
parent9652bfda0a7f3e7932aecb32262c34f3fede72b2 (diff)
parenteaa9c82670fa5ee90835266e6f7a24f81c49d17e (diff)
downloadvyos-1x-205d957d092ade5708cc2182381864c04e4c0aff.tar.gz
vyos-1x-205d957d092ade5708cc2182381864c04e4c0aff.zip
Merge pull request #4050 from jestabro/revise-migration-circinus
T6007: revise migration system
Diffstat (limited to 'src/migration-scripts/ipsec')
-rw-r--r--[-rwxr-xr-x]src/migration-scripts/ipsec/10-to-11126
-rw-r--r--[-rwxr-xr-x]src/migration-scripts/ipsec/11-to-1256
-rw-r--r--[-rwxr-xr-x]src/migration-scripts/ipsec/12-to-1350
-rw-r--r--[-rwxr-xr-x]src/migration-scripts/ipsec/4-to-555
-rw-r--r--[-rwxr-xr-x]src/migration-scripts/ipsec/5-to-6140
-rw-r--r--[-rwxr-xr-x]src/migration-scripts/ipsec/6-to-760
-rw-r--r--[-rwxr-xr-x]src/migration-scripts/ipsec/7-to-8137
-rw-r--r--[-rwxr-xr-x]src/migration-scripts/ipsec/8-to-950
-rw-r--r--[-rwxr-xr-x]src/migration-scripts/ipsec/9-to-10223
9 files changed, 364 insertions, 533 deletions
diff --git a/src/migration-scripts/ipsec/10-to-11 b/src/migration-scripts/ipsec/10-to-11
index 509216267..6c4ccb553 100755..100644
--- a/src/migration-scripts/ipsec/10-to-11
+++ b/src/migration-scripts/ipsec/10-to-11
@@ -1,83 +1,63 @@
-#!/usr/bin/env python3
+# Copyright 2023-2024 VyOS maintainers and contributors <maintainers@vyos.io>
#
-# Copyright (C) 2023 VyOS maintainers and contributors
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License version 2 or later as
-# published by the Free Software Foundation.
-#
-# This program is distributed in the hope that it will be useful,
+# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
#
-# You should have received a copy of the GNU General Public License
-# along with this program. If not, see <http://www.gnu.org/licenses/>.
+# You should have received a copy of the GNU Lesser General Public License
+# along with this library. If not, see <http://www.gnu.org/licenses/>.
-from sys import argv
-from sys import exit
+# T4916: Rewrite IPsec peer authentication and psk migration
from vyos.configtree import ConfigTree
-
-if len(argv) < 2:
- print("Must specify file name!")
- exit(1)
-
-file_name = argv[1]
-
-with open(file_name, 'r') as f:
- config_file = f.read()
-
base = ['vpn', 'ipsec']
-config = ConfigTree(config_file)
-
-if not config.exists(base):
- # Nothing to do
- exit(0)
-
-# PEER changes
-if config.exists(base + ['site-to-site', 'peer']):
- for peer in config.list_nodes(base + ['site-to-site', 'peer']):
- peer_base = base + ['site-to-site', 'peer', peer]
-
- # replace: 'ipsec site-to-site peer <tag> authentication pre-shared-secret xxx'
- # => 'ipsec authentication psk <tag> secret xxx'
- if config.exists(peer_base + ['authentication', 'pre-shared-secret']):
- tmp = config.return_value(peer_base + ['authentication', 'pre-shared-secret'])
- config.delete(peer_base + ['authentication', 'pre-shared-secret'])
- config.set(base + ['authentication', 'psk', peer, 'secret'], value=tmp)
- # format as tag node to avoid loading problems
- config.set_tag(base + ['authentication', 'psk'])
-
- # Get id's from peers for "ipsec auth psk <tag> id xxx"
- if config.exists(peer_base + ['authentication', 'local-id']):
- local_id = config.return_value(peer_base + ['authentication', 'local-id'])
- config.set(base + ['authentication', 'psk', peer, 'id'], value=local_id, replace=False)
- if config.exists(peer_base + ['authentication', 'remote-id']):
- remote_id = config.return_value(peer_base + ['authentication', 'remote-id'])
- config.set(base + ['authentication', 'psk', peer, 'id'], value=remote_id, replace=False)
-
- if config.exists(peer_base + ['local-address']):
- tmp = config.return_value(peer_base + ['local-address'])
- config.set(base + ['authentication', 'psk', peer, 'id'], value=tmp, replace=False)
- if config.exists(peer_base + ['remote-address']):
- tmp = config.return_values(peer_base + ['remote-address'])
- if tmp:
- for remote_addr in tmp:
- if remote_addr == 'any':
- remote_addr = '%any'
- config.set(base + ['authentication', 'psk', peer, 'id'], value=remote_addr, replace=False)
-
- # get DHCP peer interface as psk dhcp-interface
- if config.exists(peer_base + ['dhcp-interface']):
- tmp = config.return_value(peer_base + ['dhcp-interface'])
- config.set(base + ['authentication', 'psk', peer, 'dhcp-interface'], value=tmp)
-
-try:
- with open(file_name, 'w') as f:
- f.write(config.to_string())
-except OSError as e:
- print(f'Failed to save the modified config: {e}')
- exit(1)
+def migrate(config: ConfigTree) -> None:
+ if not config.exists(base):
+ # Nothing to do
+ return
+
+ # PEER changes
+ if config.exists(base + ['site-to-site', 'peer']):
+ for peer in config.list_nodes(base + ['site-to-site', 'peer']):
+ peer_base = base + ['site-to-site', 'peer', peer]
+
+ # replace: 'ipsec site-to-site peer <tag> authentication pre-shared-secret xxx'
+ # => 'ipsec authentication psk <tag> secret xxx'
+ if config.exists(peer_base + ['authentication', 'pre-shared-secret']):
+ tmp = config.return_value(peer_base + ['authentication', 'pre-shared-secret'])
+ config.delete(peer_base + ['authentication', 'pre-shared-secret'])
+ config.set(base + ['authentication', 'psk', peer, 'secret'], value=tmp)
+ # format as tag node to avoid loading problems
+ config.set_tag(base + ['authentication', 'psk'])
+
+ # Get id's from peers for "ipsec auth psk <tag> id xxx"
+ if config.exists(peer_base + ['authentication', 'local-id']):
+ local_id = config.return_value(peer_base + ['authentication', 'local-id'])
+ config.set(base + ['authentication', 'psk', peer, 'id'], value=local_id, replace=False)
+ if config.exists(peer_base + ['authentication', 'remote-id']):
+ remote_id = config.return_value(peer_base + ['authentication', 'remote-id'])
+ config.set(base + ['authentication', 'psk', peer, 'id'], value=remote_id, replace=False)
+
+ if config.exists(peer_base + ['local-address']):
+ tmp = config.return_value(peer_base + ['local-address'])
+ config.set(base + ['authentication', 'psk', peer, 'id'], value=tmp, replace=False)
+ if config.exists(peer_base + ['remote-address']):
+ tmp = config.return_values(peer_base + ['remote-address'])
+ if tmp:
+ for remote_addr in tmp:
+ if remote_addr == 'any':
+ remote_addr = '%any'
+ config.set(base + ['authentication', 'psk', peer, 'id'], value=remote_addr, replace=False)
+
+ # get DHCP peer interface as psk dhcp-interface
+ if config.exists(peer_base + ['dhcp-interface']):
+ tmp = config.return_value(peer_base + ['dhcp-interface'])
+ config.set(base + ['authentication', 'psk', peer, 'dhcp-interface'], value=tmp)
diff --git a/src/migration-scripts/ipsec/11-to-12 b/src/migration-scripts/ipsec/11-to-12
index 4833d0876..fc65f1825 100755..100644
--- a/src/migration-scripts/ipsec/11-to-12
+++ b/src/migration-scripts/ipsec/11-to-12
@@ -1,51 +1,31 @@
-#!/usr/bin/env python3
+# Copyright 2023-2024 VyOS maintainers and contributors <maintainers@vyos.io>
#
-# Copyright (C) 2023-2024 VyOS maintainers and contributors
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License version 2 or later as
-# published by the Free Software Foundation.
-#
-# This program is distributed in the hope that it will be useful,
+# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
#
-# You should have received a copy of the GNU General Public License
-# along with this program. If not, see <http://www.gnu.org/licenses/>.
+# You should have received a copy of the GNU Lesser General Public License
+# along with this library. If not, see <http://www.gnu.org/licenses/>.
# Remove legacy ipsec.conf and ipsec.secrets - Not supported with swanctl
-from sys import argv
-from sys import exit
-
from vyos.configtree import ConfigTree
-if len(argv) < 2:
- print("Must specify file name!")
- exit(1)
-
-file_name = argv[1]
-
-with open(file_name, 'r') as f:
- config_file = f.read()
-
base = ['vpn', 'ipsec']
-config = ConfigTree(config_file)
-
-if not config.exists(base):
- # Nothing to do
- exit(0)
-if config.exists(base + ['include-ipsec-conf']):
- config.delete(base + ['include-ipsec-conf'])
+def migrate(config: ConfigTree) -> None:
+ if not config.exists(base):
+ # Nothing to do
+ return
-if config.exists(base + ['include-ipsec-secrets']):
- config.delete(base + ['include-ipsec-secrets'])
+ if config.exists(base + ['include-ipsec-conf']):
+ config.delete(base + ['include-ipsec-conf'])
-try:
- with open(file_name, 'w') as f:
- f.write(config.to_string())
-except OSError as e:
- print(f'Failed to save the modified config: {e}')
- exit(1)
+ if config.exists(base + ['include-ipsec-secrets']):
+ config.delete(base + ['include-ipsec-secrets'])
diff --git a/src/migration-scripts/ipsec/12-to-13 b/src/migration-scripts/ipsec/12-to-13
index d90c70314..ffe766eb2 100755..100644
--- a/src/migration-scripts/ipsec/12-to-13
+++ b/src/migration-scripts/ipsec/12-to-13
@@ -1,43 +1,30 @@
-#!/usr/bin/env python3
+# Copyright 2024 VyOS maintainers and contributors <maintainers@vyos.io>
#
-# Copyright (C) 2024 VyOS maintainers and contributors
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License version 2 or later as
-# published by the Free Software Foundation.
-#
-# This program is distributed in the hope that it will be useful,
+# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
#
-# You should have received a copy of the GNU General Public License
-# along with this program. If not, see <http://www.gnu.org/licenses/>.
+# You should have received a copy of the GNU Lesser General Public License
+# along with this library. If not, see <http://www.gnu.org/licenses/>.
# Changed value of dead-peer-detection.action from hold to trap
# Changed value of close-action from hold to trap and from restart to start
-from sys import argv
-from sys import exit
-
from vyos.configtree import ConfigTree
-if len(argv) < 2:
- print("Must specify file name!")
- exit(1)
-
-file_name = argv[1]
-
-with open(file_name, 'r') as f:
- config_file = f.read()
-
base = ['vpn', 'ipsec', 'ike-group']
-config = ConfigTree(config_file)
-if not config.exists(base):
- # Nothing to do
- exit(0)
-else:
+def migrate(config: ConfigTree) -> None:
+ if not config.exists(base):
+ # Nothing to do
+ return
+
for ike_group in config.list_nodes(base):
base_dpd_action = base + [ike_group, 'dead-peer-detection', 'action']
base_close_action = base + [ike_group, 'close-action']
@@ -48,10 +35,3 @@ else:
config.set(base_close_action, 'trap', replace=True)
if config.return_value(base_close_action) == 'restart':
config.set(base_close_action, 'start', replace=True)
-
-try:
- with open(file_name, 'w') as f:
- f.write(config.to_string())
-except OSError as e:
- print(f'Failed to save the modified config: {e}')
- exit(1)
diff --git a/src/migration-scripts/ipsec/4-to-5 b/src/migration-scripts/ipsec/4-to-5
index 772d05787..a88a543d3 100755..100644
--- a/src/migration-scripts/ipsec/4-to-5
+++ b/src/migration-scripts/ipsec/4-to-5
@@ -1,47 +1,28 @@
-#!/usr/bin/env python3
+# Copyright 2019-2024 VyOS maintainers and contributors <maintainers@vyos.io>
#
-# Copyright (C) 2019 VyOS maintainers and contributors
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License version 2 or later as
-# published by the Free Software Foundation.
-#
-# This program is distributed in the hope that it will be useful,
+# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
#
-# You should have received a copy of the GNU General Public License
-# along with this program. If not, see <http://www.gnu.org/licenses/>.
+# You should have received a copy of the GNU Lesser General Public License
+# along with this library. If not, see <http://www.gnu.org/licenses/>.
# log-modes have changed, keyword all to any
-import sys
-
from vyos.configtree import ConfigTree
-if len(sys.argv) < 2:
- print("Must specify file name!")
- sys.exit(1)
-
-file_name = sys.argv[1]
-
-with open(file_name, 'r') as f:
- config_file = f.read()
-
-ctree = ConfigTree(config_file)
-
-if not ctree.exists(['vpn', 'ipsec', 'logging','log-modes']):
- # Nothing to do
- sys.exit(0)
-else:
- lmodes = ctree.return_values(['vpn', 'ipsec', 'logging','log-modes'])
- for mode in lmodes:
- if mode == 'all':
- ctree.set(['vpn', 'ipsec', 'logging','log-modes'], value='any', replace=True)
+def migrate(config: ConfigTree) -> None:
+ if not config.exists(['vpn', 'ipsec', 'logging','log-modes']):
+ # Nothing to do
+ return
- try:
- open(file_name,'w').write(ctree.to_string())
- except OSError as e:
- print("Failed to save the modified config: {}".format(e))
- sys.exit(1)
+ lmodes = config.return_values(['vpn', 'ipsec', 'logging','log-modes'])
+ for mode in lmodes:
+ if mode == 'all':
+ config.set(['vpn', 'ipsec', 'logging','log-modes'], value='any', replace=True)
diff --git a/src/migration-scripts/ipsec/5-to-6 b/src/migration-scripts/ipsec/5-to-6
index 7d7c777c6..373428d61 100755..100644
--- a/src/migration-scripts/ipsec/5-to-6
+++ b/src/migration-scripts/ipsec/5-to-6
@@ -1,93 +1,73 @@
-#!/usr/bin/env python3
+# Copyright 2021-2024 VyOS maintainers and contributors <maintainers@vyos.io>
#
-# Copyright (C) 2021 VyOS maintainers and contributors
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License version 2 or later as
-# published by the Free Software Foundation.
-#
-# This program is distributed in the hope that it will be useful,
+# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
#
-# You should have received a copy of the GNU General Public License
-# along with this program. If not, see <http://www.gnu.org/licenses/>.
+# You should have received a copy of the GNU Lesser General Public License
+# along with this library. If not, see <http://www.gnu.org/licenses/>.
# Remove deprecated strongSwan options from VyOS CLI
# - vpn ipsec nat-traversal enable
# - vpn ipsec nat-networks allowed-network
-from sys import argv
-from sys import exit
-
from vyos.configtree import ConfigTree
-if len(argv) < 2:
- print("Must specify file name!")
- exit(1)
-
-file_name = argv[1]
-
-with open(file_name, 'r') as f:
- config_file = f.read()
-
base = ['vpn', 'ipsec']
-config = ConfigTree(config_file)
-
-if not config.exists(base):
- # Nothing to do
- exit(0)
-
-# Delete CLI nodes whose config options got removed by strongSwan
-for cli_node in ['nat-traversal', 'nat-networks']:
- if config.exists(base + [cli_node]):
- config.delete(base + [cli_node])
-
-# Remove options only valid in Openswan
-if config.exists(base + ['site-to-site', 'peer']):
- for peer in config.list_nodes(base + ['site-to-site', 'peer']):
- if not config.exists(base + ['site-to-site', 'peer', peer, 'tunnel']):
- continue
- for tunnel in config.list_nodes(base + ['site-to-site', 'peer', peer, 'tunnel']):
- # allow-public-networks - Sets a value in ipsec.conf that was only ever valid in Openswan on kernel 2.6
- nat_networks = base + ['site-to-site', 'peer', peer, 'tunnel', tunnel, 'allow-nat-networks']
- if config.exists(nat_networks):
- config.delete(nat_networks)
-
- # allow-nat-networks - Also sets a value only valid in Openswan
- public_networks = base + ['site-to-site', 'peer', peer, 'tunnel', tunnel, 'allow-public-networks']
- if config.exists(public_networks):
- config.delete(public_networks)
-
-# Rename "logging log-level" and "logging log-modes" to something more human friendly
-log = base + ['logging']
-if config.exists(log):
- config.rename(log, 'log')
- log = base + ['log']
-
-log_level = log + ['log-level']
-if config.exists(log_level):
- config.rename(log_level, 'level')
-
-log_mode = log + ['log-modes']
-if config.exists(log_mode):
- config.rename(log_mode, 'subsystem')
-
-# Rename "ipsec-interfaces interface" to "interface"
-base_interfaces = base + ['ipsec-interfaces', 'interface']
-if config.exists(base_interfaces):
- config.copy(base_interfaces, base + ['interface'])
- config.delete(base + ['ipsec-interfaces'])
-
-# Remove deprecated "auto-update" option
-tmp = base + ['auto-update']
-if config.exists(tmp):
- config.delete(tmp)
-try:
- with open(file_name, 'w') as f:
- f.write(config.to_string())
-except OSError as e:
- print(f'Failed to save the modified config: {e}')
- exit(1)
+def migrate(config: ConfigTree) -> None:
+ if not config.exists(base):
+ # Nothing to do
+ return
+
+ # Delete CLI nodes whose config options got removed by strongSwan
+ for cli_node in ['nat-traversal', 'nat-networks']:
+ if config.exists(base + [cli_node]):
+ config.delete(base + [cli_node])
+
+ # Remove options only valid in Openswan
+ if config.exists(base + ['site-to-site', 'peer']):
+ for peer in config.list_nodes(base + ['site-to-site', 'peer']):
+ if not config.exists(base + ['site-to-site', 'peer', peer, 'tunnel']):
+ continue
+ for tunnel in config.list_nodes(base + ['site-to-site', 'peer', peer, 'tunnel']):
+ # allow-public-networks - Sets a value in ipsec.conf that was only ever valid in Openswan on kernel 2.6
+ nat_networks = base + ['site-to-site', 'peer', peer, 'tunnel', tunnel, 'allow-nat-networks']
+ if config.exists(nat_networks):
+ config.delete(nat_networks)
+
+ # allow-nat-networks - Also sets a value only valid in Openswan
+ public_networks = base + ['site-to-site', 'peer', peer, 'tunnel', tunnel, 'allow-public-networks']
+ if config.exists(public_networks):
+ config.delete(public_networks)
+
+ # Rename "logging log-level" and "logging log-modes" to something more human friendly
+ log = base + ['logging']
+ if config.exists(log):
+ config.rename(log, 'log')
+ log = base + ['log']
+
+ log_level = log + ['log-level']
+ if config.exists(log_level):
+ config.rename(log_level, 'level')
+
+ log_mode = log + ['log-modes']
+ if config.exists(log_mode):
+ config.rename(log_mode, 'subsystem')
+
+ # Rename "ipsec-interfaces interface" to "interface"
+ base_interfaces = base + ['ipsec-interfaces', 'interface']
+ if config.exists(base_interfaces):
+ config.copy(base_interfaces, base + ['interface'])
+ config.delete(base + ['ipsec-interfaces'])
+
+ # Remove deprecated "auto-update" option
+ tmp = base + ['auto-update']
+ if config.exists(tmp):
+ config.delete(tmp)
diff --git a/src/migration-scripts/ipsec/6-to-7 b/src/migration-scripts/ipsec/6-to-7
index f8b6de560..5679477c0 100755..100644
--- a/src/migration-scripts/ipsec/6-to-7
+++ b/src/migration-scripts/ipsec/6-to-7
@@ -1,26 +1,22 @@
-#!/usr/bin/env python3
+# Copyright 2021-2024 VyOS maintainers and contributors <maintainers@vyos.io>
#
-# Copyright (C) 2021-2023 VyOS maintainers and contributors
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License version 2 or later as
-# published by the Free Software Foundation.
-#
-# This program is distributed in the hope that it will be useful,
+# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
#
-# You should have received a copy of the GNU General Public License
-# along with this program. If not, see <http://www.gnu.org/licenses/>.
+# You should have received a copy of the GNU Lesser General Public License
+# along with this library. If not, see <http://www.gnu.org/licenses/>.
# Migrate /config/auth certificates and keys into PKI configuration
import os
-from sys import argv
-from sys import exit
-
from vyos.configtree import ConfigTree
from vyos.pki import load_certificate
from vyos.pki import load_crl
@@ -29,27 +25,27 @@ from vyos.pki import encode_certificate
from vyos.pki import encode_private_key
from vyos.utils.process import run
-if len(argv) < 2:
- print("Must specify file name!")
- exit(1)
-
-file_name = argv[1]
-
-with open(file_name, 'r') as f:
- config_file = f.read()
-
pki_base = ['pki']
ipsec_site_base = ['vpn', 'ipsec', 'site-to-site', 'peer']
-config = ConfigTree(config_file)
-changes_made = False
-
AUTH_DIR = '/config/auth'
def wrapped_pem_to_config_value(pem):
return "".join(pem.strip().split("\n")[1:-1])
-if config.exists(ipsec_site_base):
+def migrate(config: ConfigTree) -> None:
+ if not config.exists(ipsec_site_base):
+ return
+
+ migration_needed = False
+ for peer in config.list_nodes(ipsec_site_base):
+ if config.exists(ipsec_site_base + [peer, 'authentication', 'x509']):
+ migration_needed = True
+ break
+
+ if not migration_needed:
+ return
+
config.set(pki_base + ['ca'])
config.set_tag(pki_base + ['ca'])
@@ -60,8 +56,6 @@ if config.exists(ipsec_site_base):
if not config.exists(ipsec_site_base + [peer, 'authentication', 'x509']):
continue
- changes_made = True
-
peer_x509_base = ipsec_site_base + [peer, 'authentication', 'x509']
pki_name = 'peer_' + peer.replace(".", "-").replace("@", "")
@@ -159,11 +153,3 @@ if config.exists(ipsec_site_base):
print(f'Failed to migrate private key on peer "{peer}"')
config.delete(peer_x509_base + ['key'])
-
-if changes_made:
- try:
- with open(file_name, 'w') as f:
- f.write(config.to_string())
- except OSError as e:
- print("Failed to save the modified config: {}".format(e))
- sys.exit(1)
diff --git a/src/migration-scripts/ipsec/7-to-8 b/src/migration-scripts/ipsec/7-to-8
index 9acc737d5..481f00d29 100755..100644
--- a/src/migration-scripts/ipsec/7-to-8
+++ b/src/migration-scripts/ipsec/7-to-8
@@ -1,18 +1,17 @@
-#!/usr/bin/env python3
+# Copyright 2021-2024 VyOS maintainers and contributors <maintainers@vyos.io>
#
-# Copyright (C) 2021-2024 VyOS maintainers and contributors
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License version 2 or later as
-# published by the Free Software Foundation.
-#
-# This program is distributed in the hope that it will be useful,
+# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
#
-# You should have received a copy of the GNU General Public License
-# along with this program. If not, see <http://www.gnu.org/licenses/>.
+# You should have received a copy of the GNU Lesser General Public License
+# along with this library. If not, see <http://www.gnu.org/licenses/>.
# Migrate rsa keys into PKI configuration
@@ -22,29 +21,15 @@ import struct
from cryptography.hazmat.primitives.asymmetric import rsa
-from sys import argv
-from sys import exit
-
from vyos.configtree import ConfigTree
from vyos.pki import load_private_key
from vyos.pki import encode_public_key
from vyos.pki import encode_private_key
-if len(argv) < 2:
- print("Must specify file name!")
- exit(1)
-
-file_name = argv[1]
-
-with open(file_name, 'r') as f:
- config_file = f.read()
-
pki_base = ['pki']
ipsec_site_base = ['vpn', 'ipsec', 'site-to-site', 'peer']
rsa_keys_base = ['vpn', 'rsa-keys']
-config = ConfigTree(config_file)
-
LOCAL_KEY_PATHS = ['/config/auth/', '/config/ipsec.d/rsa-keys/']
def migrate_from_vyatta_key(data):
@@ -60,65 +45,59 @@ def wrapped_pem_to_config_value(pem):
local_key_name = 'localhost'
-if config.exists(rsa_keys_base):
- if not config.exists(pki_base + ['key-pair']):
- config.set(pki_base + ['key-pair'])
- config.set_tag(pki_base + ['key-pair'])
-
- if config.exists(rsa_keys_base + ['local-key', 'file']):
- local_file = config.return_value(rsa_keys_base + ['local-key', 'file'])
- local_path = None
- local_key = None
-
- for path in LOCAL_KEY_PATHS:
- full_path = os.path.join(path, local_file)
- if os.path.exists(full_path):
- local_path = full_path
- break
-
- if local_path:
- with open(local_path, 'r') as f:
- local_key_data = f.read()
- local_key = load_private_key(local_key_data, wrap_tags=False)
-
- if local_key:
- local_key_pem = encode_private_key(local_key)
- config.set(pki_base + ['key-pair', local_key_name, 'private', 'key'], value=wrapped_pem_to_config_value(local_key_pem))
- else:
- print('Failed to migrate local RSA key')
-
- if config.exists(rsa_keys_base + ['rsa-key-name']):
- for rsa_name in config.list_nodes(rsa_keys_base + ['rsa-key-name']):
- if not config.exists(rsa_keys_base + ['rsa-key-name', rsa_name, 'rsa-key']):
- continue
+def migrate(config: ConfigTree) -> None:
+ if config.exists(rsa_keys_base):
+ if not config.exists(pki_base + ['key-pair']):
+ config.set(pki_base + ['key-pair'])
+ config.set_tag(pki_base + ['key-pair'])
+
+ if config.exists(rsa_keys_base + ['local-key', 'file']):
+ local_file = config.return_value(rsa_keys_base + ['local-key', 'file'])
+ local_path = None
+ local_key = None
+
+ for path in LOCAL_KEY_PATHS:
+ full_path = os.path.join(path, local_file)
+ if os.path.exists(full_path):
+ local_path = full_path
+ break
+
+ if local_path:
+ with open(local_path, 'r') as f:
+ local_key_data = f.read()
+ local_key = load_private_key(local_key_data, wrap_tags=False)
+
+ if local_key:
+ local_key_pem = encode_private_key(local_key)
+ config.set(pki_base + ['key-pair', local_key_name, 'private', 'key'], value=wrapped_pem_to_config_value(local_key_pem))
+ else:
+ print('Failed to migrate local RSA key')
- vyatta_key = config.return_value(rsa_keys_base + ['rsa-key-name', rsa_name, 'rsa-key'])
- public_key = migrate_from_vyatta_key(vyatta_key)
+ if config.exists(rsa_keys_base + ['rsa-key-name']):
+ for rsa_name in config.list_nodes(rsa_keys_base + ['rsa-key-name']):
+ if not config.exists(rsa_keys_base + ['rsa-key-name', rsa_name, 'rsa-key']):
+ continue
- if public_key:
- public_key_pem = encode_public_key(public_key)
- config.set(pki_base + ['key-pair', rsa_name, 'public', 'key'], value=wrapped_pem_to_config_value(public_key_pem))
- else:
- print(f'Failed to migrate rsa-key "{rsa_name}"')
+ vyatta_key = config.return_value(rsa_keys_base + ['rsa-key-name', rsa_name, 'rsa-key'])
+ public_key = migrate_from_vyatta_key(vyatta_key)
- config.delete(rsa_keys_base)
+ if public_key:
+ public_key_pem = encode_public_key(public_key)
+ config.set(pki_base + ['key-pair', rsa_name, 'public', 'key'], value=wrapped_pem_to_config_value(public_key_pem))
+ else:
+ print(f'Failed to migrate rsa-key "{rsa_name}"')
-if config.exists(ipsec_site_base):
- for peer in config.list_nodes(ipsec_site_base):
- mode = config.return_value(ipsec_site_base + [peer, 'authentication', 'mode'])
+ config.delete(rsa_keys_base)
- if mode != 'rsa':
- continue
+ if config.exists(ipsec_site_base):
+ for peer in config.list_nodes(ipsec_site_base):
+ mode = config.return_value(ipsec_site_base + [peer, 'authentication', 'mode'])
- config.set(ipsec_site_base + [peer, 'authentication', 'rsa', 'local-key'], value=local_key_name)
+ if mode != 'rsa':
+ continue
- remote_key_name = config.return_value(ipsec_site_base + [peer, 'authentication', 'rsa-key-name'])
- config.set(ipsec_site_base + [peer, 'authentication', 'rsa', 'remote-key'], value=remote_key_name)
- config.delete(ipsec_site_base + [peer, 'authentication', 'rsa-key-name'])
+ config.set(ipsec_site_base + [peer, 'authentication', 'rsa', 'local-key'], value=local_key_name)
-try:
- with open(file_name, 'w') as f:
- f.write(config.to_string())
-except OSError as e:
- print("Failed to save the modified config: {}".format(e))
- sys.exit(1)
+ remote_key_name = config.return_value(ipsec_site_base + [peer, 'authentication', 'rsa-key-name'])
+ config.set(ipsec_site_base + [peer, 'authentication', 'rsa', 'remote-key'], value=remote_key_name)
+ config.delete(ipsec_site_base + [peer, 'authentication', 'rsa-key-name'])
diff --git a/src/migration-scripts/ipsec/8-to-9 b/src/migration-scripts/ipsec/8-to-9
index c08411f83..7f325139f 100755..100644
--- a/src/migration-scripts/ipsec/8-to-9
+++ b/src/migration-scripts/ipsec/8-to-9
@@ -1,48 +1,30 @@
-#!/usr/bin/env python3
+# Copyright 2022-2024 VyOS maintainers and contributors <maintainers@vyos.io>
#
-# Copyright (C) 2022 VyOS maintainers and contributors
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License version 2 or later as
-# published by the Free Software Foundation.
-#
-# This program is distributed in the hope that it will be useful,
+# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
#
-# You should have received a copy of the GNU General Public License
-# along with this program. If not, see <http://www.gnu.org/licenses/>.
+# You should have received a copy of the GNU Lesser General Public License
+# along with this library. If not, see <http://www.gnu.org/licenses/>.
-from sys import argv
-from sys import exit
+# T4288 : close-action is missing in swanctl.conf
from vyos.configtree import ConfigTree
-if len(argv) < 2:
- print("Must specify file name!")
- exit(1)
-
-file_name = argv[1]
-
-with open(file_name, 'r') as f:
- config_file = f.read()
-
base = ['vpn', 'ipsec', 'ike-group']
-config = ConfigTree(config_file)
-if not config.exists(base):
- # Nothing to do
- exit(0)
-else:
+def migrate(config: ConfigTree) -> None:
+ if not config.exists(base):
+ # Nothing to do
+ return
+
for ike_group in config.list_nodes(base):
base_closeaction = base + [ike_group, 'close-action']
if config.exists(base_closeaction) and config.return_value(base_closeaction) == 'clear':
config.set(base_closeaction, 'none', replace=True)
-
-try:
- with open(file_name, 'w') as f:
- f.write(config.to_string())
-except OSError as e:
- print(f'Failed to save the modified config: {e}')
- exit(1)
diff --git a/src/migration-scripts/ipsec/9-to-10 b/src/migration-scripts/ipsec/9-to-10
index bc10e1997..321a75973 100755..100644
--- a/src/migration-scripts/ipsec/9-to-10
+++ b/src/migration-scripts/ipsec/9-to-10
@@ -1,131 +1,114 @@
-#!/usr/bin/env python3
+# Copyright 2022-2024 VyOS maintainers and contributors <maintainers@vyos.io>
#
-# Copyright (C) 2022-2024 VyOS maintainers and contributors
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License version 2 or later as
-# published by the Free Software Foundation.
-#
-# This program is distributed in the hope that it will be useful,
+# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
#
-# You should have received a copy of the GNU General Public License
-# along with this program. If not, see <http://www.gnu.org/licenses/>.
+# You should have received a copy of the GNU Lesser General Public License
+# along with this library. If not, see <http://www.gnu.org/licenses/>.
-import re
+# T4118: Change vpn ipsec syntax for IKE ESP and peer
+# T4879: IPsec migration script remote-id for peer name eq address
-from sys import argv
-from sys import exit
+import re
from vyos.configtree import ConfigTree
-if len(argv) < 2:
- print("Must specify file name!")
- exit(1)
-
-file_name = argv[1]
-
-with open(file_name, 'r') as f:
- config_file = f.read()
-
base = ['vpn', 'ipsec']
-config = ConfigTree(config_file)
-
-if not config.exists(base):
- # Nothing to do
- exit(0)
-
-# IKE changes, T4118:
-if config.exists(base + ['ike-group']):
- for ike_group in config.list_nodes(base + ['ike-group']):
- # replace 'ipsec ike-group <tag> mobike disable'
- # => 'ipsec ike-group <tag> disable-mobike'
- mobike = base + ['ike-group', ike_group, 'mobike']
- if config.exists(mobike):
- if config.return_value(mobike) == 'disable':
- config.set(base + ['ike-group', ike_group, 'disable-mobike'])
- config.delete(mobike)
-
- # replace 'ipsec ike-group <tag> ikev2-reauth yes'
- # => 'ipsec ike-group <tag> ikev2-reauth'
- reauth = base + ['ike-group', ike_group, 'ikev2-reauth']
- if config.exists(reauth):
- if config.return_value(reauth) == 'yes':
- config.delete(reauth)
- config.set(reauth)
- else:
- config.delete(reauth)
-
-# ESP changes
-# replace 'ipsec esp-group <tag> compression enable'
-# => 'ipsec esp-group <tag> compression'
-if config.exists(base + ['esp-group']):
- for esp_group in config.list_nodes(base + ['esp-group']):
- compression = base + ['esp-group', esp_group, 'compression']
- if config.exists(compression):
- if config.return_value(compression) == 'enable':
- config.delete(compression)
- config.set(compression)
- else:
- config.delete(compression)
-
-# PEER changes
-if config.exists(base + ['site-to-site', 'peer']):
- for peer in config.list_nodes(base + ['site-to-site', 'peer']):
- peer_base = base + ['site-to-site', 'peer', peer]
-
- # replace: 'peer <tag> id x'
- # => 'peer <tag> local-id x'
- if config.exists(peer_base + ['authentication', 'id']):
- config.rename(peer_base + ['authentication', 'id'], 'local-id')
-
- # For the peer '@foo' set remote-id 'foo' if remote-id is not defined
- # For the peer '192.0.2.1' set remote-id '192.0.2.1' if remote-id is not defined
- if not config.exists(peer_base + ['authentication', 'remote-id']):
- tmp = peer.replace('@', '') if peer.startswith('@') else peer
- config.set(peer_base + ['authentication', 'remote-id'], value=tmp)
-
- # replace: 'peer <tag> force-encapsulation enable'
- # => 'peer <tag> force-udp-encapsulation'
- force_enc = peer_base + ['force-encapsulation']
- if config.exists(force_enc):
- if config.return_value(force_enc) == 'enable':
- config.delete(force_enc)
- config.set(peer_base + ['force-udp-encapsulation'])
- else:
- config.delete(force_enc)
-
- # add option: 'peer <tag> remote-address x.x.x.x'
- remote_address = peer
- if peer.startswith('@'):
- remote_address = 'any'
- config.set(peer_base + ['remote-address'], value=remote_address)
- # Peer name it is swanctl connection name and shouldn't contain dots or colons
- # rename peer:
- # peer 192.0.2.1 => peer peer_192-0-2-1
- # peer 2001:db8::2 => peer peer_2001-db8--2
- # peer @foo => peer peer_foo
- re_peer_name = re.sub(':|\.', '-', peer)
- if re_peer_name.startswith('@'):
- re_peer_name = re.sub('@', '', re_peer_name)
- new_peer_name = f'peer_{re_peer_name}'
-
- config.rename(peer_base, new_peer_name)
-
-# remote-access/road-warrior changes
-if config.exists(base + ['remote-access', 'connection']):
- for connection in config.list_nodes(base + ['remote-access', 'connection']):
- ra_base = base + ['remote-access', 'connection', connection]
- # replace: 'remote-access connection <tag> authentication id x'
- # => 'remote-access connection <tag> authentication local-id x'
- if config.exists(ra_base + ['authentication', 'id']):
- config.rename(ra_base + ['authentication', 'id'], 'local-id')
-try:
- with open(file_name, 'w') as f:
- f.write(config.to_string())
-except OSError as e:
- print(f'Failed to save the modified config: {e}')
- exit(1)
+def migrate(config: ConfigTree) -> None:
+ if not config.exists(base):
+ # Nothing to do
+ return
+
+ # IKE changes, T4118:
+ if config.exists(base + ['ike-group']):
+ for ike_group in config.list_nodes(base + ['ike-group']):
+ # replace 'ipsec ike-group <tag> mobike disable'
+ # => 'ipsec ike-group <tag> disable-mobike'
+ mobike = base + ['ike-group', ike_group, 'mobike']
+ if config.exists(mobike):
+ if config.return_value(mobike) == 'disable':
+ config.set(base + ['ike-group', ike_group, 'disable-mobike'])
+ config.delete(mobike)
+
+ # replace 'ipsec ike-group <tag> ikev2-reauth yes'
+ # => 'ipsec ike-group <tag> ikev2-reauth'
+ reauth = base + ['ike-group', ike_group, 'ikev2-reauth']
+ if config.exists(reauth):
+ if config.return_value(reauth) == 'yes':
+ config.delete(reauth)
+ config.set(reauth)
+ else:
+ config.delete(reauth)
+
+ # ESP changes
+ # replace 'ipsec esp-group <tag> compression enable'
+ # => 'ipsec esp-group <tag> compression'
+ if config.exists(base + ['esp-group']):
+ for esp_group in config.list_nodes(base + ['esp-group']):
+ compression = base + ['esp-group', esp_group, 'compression']
+ if config.exists(compression):
+ if config.return_value(compression) == 'enable':
+ config.delete(compression)
+ config.set(compression)
+ else:
+ config.delete(compression)
+
+ # PEER changes
+ if config.exists(base + ['site-to-site', 'peer']):
+ for peer in config.list_nodes(base + ['site-to-site', 'peer']):
+ peer_base = base + ['site-to-site', 'peer', peer]
+
+ # replace: 'peer <tag> id x'
+ # => 'peer <tag> local-id x'
+ if config.exists(peer_base + ['authentication', 'id']):
+ config.rename(peer_base + ['authentication', 'id'], 'local-id')
+
+ # For the peer '@foo' set remote-id 'foo' if remote-id is not defined
+ # For the peer '192.0.2.1' set remote-id '192.0.2.1' if remote-id is not defined
+ if not config.exists(peer_base + ['authentication', 'remote-id']):
+ tmp = peer.replace('@', '') if peer.startswith('@') else peer
+ config.set(peer_base + ['authentication', 'remote-id'], value=tmp)
+
+ # replace: 'peer <tag> force-encapsulation enable'
+ # => 'peer <tag> force-udp-encapsulation'
+ force_enc = peer_base + ['force-encapsulation']
+ if config.exists(force_enc):
+ if config.return_value(force_enc) == 'enable':
+ config.delete(force_enc)
+ config.set(peer_base + ['force-udp-encapsulation'])
+ else:
+ config.delete(force_enc)
+
+ # add option: 'peer <tag> remote-address x.x.x.x'
+ remote_address = peer
+ if peer.startswith('@'):
+ remote_address = 'any'
+ config.set(peer_base + ['remote-address'], value=remote_address)
+ # Peer name it is swanctl connection name and shouldn't contain dots or colons
+ # rename peer:
+ # peer 192.0.2.1 => peer peer_192-0-2-1
+ # peer 2001:db8::2 => peer peer_2001-db8--2
+ # peer @foo => peer peer_foo
+ re_peer_name = re.sub(':|\.', '-', peer)
+ if re_peer_name.startswith('@'):
+ re_peer_name = re.sub('@', '', re_peer_name)
+ new_peer_name = f'peer_{re_peer_name}'
+
+ config.rename(peer_base, new_peer_name)
+
+ # remote-access/road-warrior changes
+ if config.exists(base + ['remote-access', 'connection']):
+ for connection in config.list_nodes(base + ['remote-access', 'connection']):
+ ra_base = base + ['remote-access', 'connection', connection]
+ # replace: 'remote-access connection <tag> authentication id x'
+ # => 'remote-access connection <tag> authentication local-id x'
+ if config.exists(ra_base + ['authentication', 'id']):
+ config.rename(ra_base + ['authentication', 'id'], 'local-id')