From 1a753ab95e68c60660d9cd5c7340b5d22a35fafa Mon Sep 17 00:00:00 2001 From: Christian Breunig Date: Sun, 14 Dec 2025 18:09:40 +0100 Subject: ssh: T8090: add support for config test mode (sshd -t) Add a safety-net for development to check if the rendered sshd(8) configuration can be applied at all. If it can't be applied - throw an error. From https://linux.die.net/man/8/sshd: -t Test mode. Only check the validity of the configuration file and sanity of the keys. This is useful for updating sshd reliably as configuration options may change. Explicitly forcing a broken config now results in: vyos@vyos# commit [ service ssh ] Unexpected error with SSH configuration! /run/sshd/sshd_config line 21: X11DisplayOffset integer value invalid. [[service ssh]] failed Commit failed --- src/conf_mode/service_ssh.py | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'src') diff --git a/src/conf_mode/service_ssh.py b/src/conf_mode/service_ssh.py index dca021d02..d67c1fa3f 100755 --- a/src/conf_mode/service_ssh.py +++ b/src/conf_mode/service_ssh.py @@ -29,6 +29,7 @@ from vyos.configverify import verify_pki_openssh_key from vyos.defaults import config_files from vyos.defaults import SSH_DSA_DEPRECATION_WARNING from vyos.utils.process import call +from vyos.utils.process import rc_cmd from vyos.template import render from vyos import ConfigError from vyos import airbag @@ -173,6 +174,11 @@ def apply(ssh): call(f'systemctl stop {systemd_service_sshguard}') return None + # Verify generated sshd configuration is correct + rc, out = rc_cmd(f'/usr/sbin/sshd -t -f {config_file}') + if rc: + raise ConfigError(f'Unexpected error with SSH configuration! {out}') + if 'dynamic_protection' not in ssh: call(f'systemctl stop {systemd_service_sshguard}') else: -- cgit v1.2.3 From 812eea9a3a20afebc20b374a30ceac7f0d87c9b4 Mon Sep 17 00:00:00 2001 From: Christian Breunig Date: Sun, 14 Dec 2025 18:41:08 +0100 Subject: ssh: T8098: remove support for deprecated "rijndael-cbc@lysator.liu.se" cipher According to an Arch Linux forum discussion, the cipher rijndael-cbc@lysator.liu.se was removed in OpenSSH 6.7. References: - https://bbs.archlinux.org/viewtopic.php?id=188613 - https://www.openssh.org/txt/release-6.7 - https://github.com/openssh/openssh-portable/commit/03e93c753d7c223063a --- .../include/version/ssh-version.xml.i | 2 +- interface-definitions/service_ssh.xml.in | 4 +-- smoketest/configs/assert/basic-vyos | 1 - src/migration-scripts/ssh/2-to-3 | 31 ++++++++++++++++++++++ 4 files changed, 34 insertions(+), 4 deletions(-) create mode 100644 src/migration-scripts/ssh/2-to-3 (limited to 'src') diff --git a/interface-definitions/include/version/ssh-version.xml.i b/interface-definitions/include/version/ssh-version.xml.i index 0f25caf98..05cf431a7 100644 --- a/interface-definitions/include/version/ssh-version.xml.i +++ b/interface-definitions/include/version/ssh-version.xml.i @@ -1,3 +1,3 @@ - + diff --git a/interface-definitions/service_ssh.xml.in b/interface-definitions/service_ssh.xml.in index c659a7db7..4d10de646 100644 --- a/interface-definitions/service_ssh.xml.in +++ b/interface-definitions/service_ssh.xml.in @@ -41,10 +41,10 @@ Allowed ciphers - 3des-cbc aes128-cbc aes192-cbc aes256-cbc rijndael-cbc@lysator.liu.se aes128-ctr aes192-ctr aes256-ctr aes128-gcm@openssh.com aes256-gcm@openssh.com chacha20-poly1305@openssh.com + 3des-cbc aes128-cbc aes192-cbc aes256-cbc aes128-ctr aes192-ctr aes256-ctr aes128-gcm@openssh.com aes256-gcm@openssh.com chacha20-poly1305@openssh.com - (3des-cbc|aes128-cbc|aes192-cbc|aes256-cbc|rijndael-cbc@lysator.liu.se|aes128-ctr|aes192-ctr|aes256-ctr|aes128-gcm@openssh.com|aes256-gcm@openssh.com|chacha20-poly1305@openssh.com) + (3des-cbc|aes128-cbc|aes192-cbc|aes256-cbc|aes128-ctr|aes192-ctr|aes256-ctr|aes128-gcm@openssh.com|aes256-gcm@openssh.com|chacha20-poly1305@openssh.com) diff --git a/smoketest/configs/assert/basic-vyos b/smoketest/configs/assert/basic-vyos index 601051d8f..20363b77f 100644 --- a/smoketest/configs/assert/basic-vyos +++ b/smoketest/configs/assert/basic-vyos @@ -85,7 +85,6 @@ set service ssh ciphers 'aes128-ctr' set service ssh ciphers 'aes192-ctr' set service ssh ciphers 'aes256-ctr' set service ssh ciphers 'chacha20-poly1305@openssh.com' -set service ssh ciphers 'rijndael-cbc@lysator.liu.se' set service ssh key-exchange 'curve25519-sha256@libssh.org' set service ssh key-exchange 'diffie-hellman-group1-sha1' set service ssh key-exchange 'diffie-hellman-group-exchange-sha1' diff --git a/src/migration-scripts/ssh/2-to-3 b/src/migration-scripts/ssh/2-to-3 new file mode 100644 index 000000000..e18a6aa05 --- /dev/null +++ b/src/migration-scripts/ssh/2-to-3 @@ -0,0 +1,31 @@ +# Copyright 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 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 +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this library. If not, see . + +# T8098: rijndael-cbc@lysator.liu.se was removed in OpenSSH 6.7 which is used +# starting with VyOS 1.4 + +from vyos.configtree import ConfigTree + +base = ['service', 'ssh'] + +def migrate(config: ConfigTree) -> None: + if not config.exists(base + ['ciphers']): + # Nothing to do + return + + deprecated_cipher = 'rijndael-cbc@lysator.liu.se' + for cipher in config.return_values(base + ['ciphers']): + if cipher == deprecated_cipher: + config.delete_value(base + ['ciphers'], value=deprecated_cipher) -- cgit v1.2.3 From ef13a6319a21c8030301aeebbeabf5148adb994c Mon Sep 17 00:00:00 2001 From: Christian Breunig Date: Sun, 14 Dec 2025 18:58:00 +0100 Subject: ssh: T8098: rename "ciphers" CLI node to "cipher" Follow VyOS CLI best practices for using singular whenever possible to build a CLI node. As we introduce a new migration 2 -> 3 for SSH we can correct this minor detail. --- data/templates/ssh/sshd_config.j2 | 6 +++--- interface-definitions/service_ssh.xml.in | 2 +- smoketest/configs/assert/basic-vyos | 8 ++++---- smoketest/scripts/cli/test_service_ssh.py | 2 +- src/migration-scripts/ssh/2-to-3 | 20 ++++++++++++++------ 5 files changed, 23 insertions(+), 15 deletions(-) (limited to 'src') diff --git a/data/templates/ssh/sshd_config.j2 b/data/templates/ssh/sshd_config.j2 index 1315bf2cb..d5d155340 100644 --- a/data/templates/ssh/sshd_config.j2 +++ b/data/templates/ssh/sshd_config.j2 @@ -57,9 +57,9 @@ ListenAddress {{ address }} {% endfor %} {% endif %} -{% if ciphers is vyos_defined %} -# Specifies the ciphers allowed for protocol version 2 -Ciphers {{ ciphers | join(',') }} +{% if cipher is vyos_defined %} +# Specifies allowed ciphers for protocol version 2 +Ciphers {{ cipher | join(',') }} {% endif %} {% if hostkey_algorithm is vyos_defined %} diff --git a/interface-definitions/service_ssh.xml.in b/interface-definitions/service_ssh.xml.in index 4d10de646..9fd9e32c3 100644 --- a/interface-definitions/service_ssh.xml.in +++ b/interface-definitions/service_ssh.xml.in @@ -36,7 +36,7 @@ - + Allowed ciphers diff --git a/smoketest/configs/assert/basic-vyos b/smoketest/configs/assert/basic-vyos index 20363b77f..48ba51b21 100644 --- a/smoketest/configs/assert/basic-vyos +++ b/smoketest/configs/assert/basic-vyos @@ -81,10 +81,10 @@ set service dns forwarding allow-from '192.168.0.0/16' set service dns forwarding cache-size '10000' set service dns forwarding dnssec 'off' set service dns forwarding listen-address '192.168.0.1' -set service ssh ciphers 'aes128-ctr' -set service ssh ciphers 'aes192-ctr' -set service ssh ciphers 'aes256-ctr' -set service ssh ciphers 'chacha20-poly1305@openssh.com' +set service ssh cipher 'aes128-ctr' +set service ssh cipher 'aes192-ctr' +set service ssh cipher 'aes256-ctr' +set service ssh cipher 'chacha20-poly1305@openssh.com' set service ssh key-exchange 'curve25519-sha256@libssh.org' set service ssh key-exchange 'diffie-hellman-group1-sha1' set service ssh key-exchange 'diffie-hellman-group-exchange-sha1' diff --git a/smoketest/scripts/cli/test_service_ssh.py b/smoketest/scripts/cli/test_service_ssh.py index 6935464a7..4ef3dd51d 100755 --- a/smoketest/scripts/cli/test_service_ssh.py +++ b/smoketest/scripts/cli/test_service_ssh.py @@ -378,7 +378,7 @@ class TestServiceSSH(VyOSUnitTestSHIM.TestCase): rekey_data = '1024' for cipher in ciphers: - self.cli_set(base_path + ['ciphers', cipher]) + self.cli_set(base_path + ['cipher', cipher]) for host_key in host_key_algs: self.cli_set(base_path + ['hostkey-algorithm', host_key]) for kex in kexes: diff --git a/src/migration-scripts/ssh/2-to-3 b/src/migration-scripts/ssh/2-to-3 index e18a6aa05..ac9f7156c 100644 --- a/src/migration-scripts/ssh/2-to-3 +++ b/src/migration-scripts/ssh/2-to-3 @@ -14,18 +14,26 @@ # along with this library. If not, see . # T8098: rijndael-cbc@lysator.liu.se was removed in OpenSSH 6.7 which is used -# starting with VyOS 1.4 +# starting with VyOS 1.4. Also rename "ciphers" -> "cipher" to follow our +# CLI guidelines to use singular when possible from vyos.configtree import ConfigTree base = ['service', 'ssh'] +old_path = base + ['ciphers'] +new_path = base + ['cipher'] + def migrate(config: ConfigTree) -> None: - if not config.exists(base + ['ciphers']): + if not config.exists(base): # Nothing to do return - deprecated_cipher = 'rijndael-cbc@lysator.liu.se' - for cipher in config.return_values(base + ['ciphers']): - if cipher == deprecated_cipher: - config.delete_value(base + ['ciphers'], value=deprecated_cipher) + if config.exists(old_path): + config.rename(old_path, new_path[-1]) + + if config.exists(new_path): + deprecated_cipher = 'rijndael-cbc@lysator.liu.se' + for cipher in config.return_values(new_path): + if cipher == deprecated_cipher: + config.delete_value(new_path, value=deprecated_cipher) -- cgit v1.2.3