diff options
| author | Daniil Baturin <daniil@vyos.io> | 2025-09-18 15:19:13 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-09-18 15:19:13 +0100 |
| commit | 05b826ae7294e48f4483d9586f8f12a72c97347c (patch) | |
| tree | 43efb7fac3e46801b89302a15154f92cbec0955e | |
| parent | 098988988d3126d084482821c30d5332ce5bb66b (diff) | |
| parent | 6deda171e8b5f5a65101436399bdbb308179e076 (diff) | |
| download | vyos-1x-05b826ae7294e48f4483d9586f8f12a72c97347c.tar.gz vyos-1x-05b826ae7294e48f4483d9586f8f12a72c97347c.zip | |
Merge pull request #4731 from c-po/openssh-T7787
T7787: add deprecation warning for ssh-dss keys
| -rw-r--r-- | Makefile | 8 | ||||
| -rw-r--r-- | data/templates/login/motd_user_dsa_warning.j2 | 18 | ||||
| -rw-r--r-- | data/templates/ssh/motd_ssh_dsa_warning.j2 | 8 | ||||
| -rw-r--r-- | python/vyos/defaults.py | 5 | ||||
| -rwxr-xr-x | src/conf_mode/service_ssh.py | 23 | ||||
| -rwxr-xr-x | src/conf_mode/system_login.py | 27 |
6 files changed, 84 insertions, 5 deletions
@@ -111,10 +111,10 @@ check_migration_scripts_executable: .PHONE: pylint pylint: interface_definitions - @echo Running "pylint --errors-only ..." - @PYTHONPATH=python/ pylint --errors-only $(shell git ls-files python/vyos/ifconfig/*.py python/vyos/utils/*.py src/conf_mode/*.py src/op_mode/*.py src/migration-scripts src/services/vyos*) - @echo Running "pylint to check for unused imports ..." - @PYTHONPATH=python/ pylint --disable=all --enable=W0611 $(shell git ls-files *.py src/migration-scripts src/services) + @echo Running "pylint ..." + @set -e; \ + PYTHONPATH=python/ pylint --errors-only $(shell git ls-files python/vyos/ifconfig/*.py python/vyos/utils/*.py src/conf_mode/*.py src/op_mode/*.py src/migration-scripts src/services/vyos*); \ + PYTHONPATH=python/ pylint --disable=all --enable=W0611 $(shell git ls-files *.py src/migration-scripts src/services) .PHONY: j2lint j2lint: diff --git a/data/templates/login/motd_user_dsa_warning.j2 b/data/templates/login/motd_user_dsa_warning.j2 new file mode 100644 index 000000000..f8164b184 --- /dev/null +++ b/data/templates/login/motd_user_dsa_warning.j2 @@ -0,0 +1,18 @@ +{% if user is vyos_defined %} +{% set ns = namespace (gen_header = True) %} +{% for user, user_config in user.items() %} +{% if user_config.authentication.public_keys is vyos_defined %} +{% for key, key_options in user_config.authentication.public_keys.items() %} +{% if key_options.type is vyos_defined('ssh-dss') %} +{% if ns.gen_header %} +{% set ns.gen_header = False %} +--- +{{ ssh_dsa_deprecation_warning | wordwrap(72) }} + +{% endif %} +User "{{ user }}" with deprecated public-key named: {{ key }} +{% endif %} +{% endfor %} +{% endif %} +{% endfor %} +{% endif %} diff --git a/data/templates/ssh/motd_ssh_dsa_warning.j2 b/data/templates/ssh/motd_ssh_dsa_warning.j2 new file mode 100644 index 000000000..2d4598fa8 --- /dev/null +++ b/data/templates/ssh/motd_ssh_dsa_warning.j2 @@ -0,0 +1,8 @@ +{% if hostkey_algorithm is vyos_defined %} +{% set tmp = hostkey_algorithm | select("in", deprecated_algos) %} +{% if tmp %} +{% set tmp = ssh_dsa_deprecation_warning ~ ' ' ~ tmp | join(', ') %} +--- +{{ tmp | wordwrap(72) }} +{% endif %} +{% endif %} diff --git a/python/vyos/defaults.py b/python/vyos/defaults.py index 027e4480d..43cde38e9 100644 --- a/python/vyos/defaults.py +++ b/python/vyos/defaults.py @@ -91,3 +91,8 @@ commit_hooks = {'pre': '/etc/commit/pre-hooks.d', } airbag_noteworthy_size = 20 + +SSH_DSA_DEPRECATION_WARNING: str = \ +'Support for SSH-DSA keys is deprecated and will be removed in VyOS 1.6. ' \ +'Please update affected keys to a supported algorithm (e.g., RSA, ECDSA or ' \ +'ED25519) to avoid authentication failures after the upgrade.' diff --git a/src/conf_mode/service_ssh.py b/src/conf_mode/service_ssh.py index bf8afe8b7..ca0e66207 100755 --- a/src/conf_mode/service_ssh.py +++ b/src/conf_mode/service_ssh.py @@ -16,15 +16,18 @@ import os +from copy import deepcopy from sys import exit from syslog import syslog from syslog import LOG_INFO +from vyos.base import DeprecationWarning from vyos.config import Config from vyos.configdict import is_node_changed from vyos.configverify import verify_vrf 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.template import render from vyos import ConfigError @@ -47,6 +50,13 @@ key_ed25519 = '/etc/ssh/ssh_host_ed25519_key' trusted_user_ca = config_files['sshd_user_ca'] +login_motd_dsa_warning = r'/run/motd.d/91-vyos-ssh-dsa-deprecation-warning' + +# As of OpenSSH 9.8p1 in Debian trixie, DSA keys are no longer supported +deprecated_algos = ['ssh-dss', 'ssh-dss-cert-v01@openssh.com'] +SSH_DSA_DEPRECATION_WARNING: str = f'{SSH_DSA_DEPRECATION_WARNING} '\ +'The following hostkey-algorithms are in use:' + def get_config(config=None): if config: conf = config @@ -100,6 +110,12 @@ def verify(ssh): if 'trusted_user_ca' in ssh: verify_pki_openssh_key(ssh, ssh['trusted_user_ca']) + if 'hostkey_algorithm' in ssh: + tmp = any(item in deprecated_algos for item in ssh['hostkey_algorithm']) + if deprecated_algos: + tmp = ', '.join(deprecated_algos) + DeprecationWarning(f'{SSH_DSA_DEPRECATION_WARNING} {tmp}') + verify_vrf(ssh) return None @@ -137,6 +153,13 @@ def generate(ssh): render(config_file, 'ssh/sshd_config.j2', ssh) + # Generate MOTD informing the user(s) for possible deprecated SSH hostkey-algorithm + tmp = deepcopy(ssh) + tmp['ssh_dsa_deprecation_warning'] = f'DEPRECATION WARNING: {SSH_DSA_DEPRECATION_WARNING}' + tmp['deprecated_algos'] = deprecated_algos + render(login_motd_dsa_warning, 'ssh/motd_ssh_dsa_warning.j2', tmp, + permission=0o644, user='root', group='root') + if 'dynamic_protection' in ssh: render(sshguard_config_file, 'ssh/sshguard_config.j2', ssh) render(sshguard_whitelist, 'ssh/sshguard_whitelist.j2', ssh) diff --git a/src/conf_mode/system_login.py b/src/conf_mode/system_login.py index c2562be7b..7ddcbff4a 100755 --- a/src/conf_mode/system_login.py +++ b/src/conf_mode/system_login.py @@ -18,6 +18,7 @@ import re import os import json +from copy import deepcopy from passlib.hosts import linux_context from psutil import users from pwd import getpwall @@ -27,10 +28,12 @@ from sys import exit from time import sleep from vyos.base import Warning +from vyos.base import DeprecationWarning from vyos.config import Config from vyos.configdep import set_dependents from vyos.configdep import call_dependents from vyos.configverify import verify_vrf +from vyos.defaults import SSH_DSA_DEPRECATION_WARNING from vyos.template import render from vyos.template import is_ipv4 from vyos.utils.auth import EPasswdStrength @@ -54,12 +57,13 @@ radius_config_file = "/etc/pam_radius_auth.conf" tacacs_pam_config_file = "/etc/tacplus_servers" tacacs_nss_config_file = "/etc/tacplus_nss.conf" nss_config_file = "/etc/nsswitch.conf" +login_motd_dsa_warning = r'/run/motd.d/92-vyos-user-dsa-deprecation-warning' # Minimum UID used when adding system users MIN_USER_UID: int = 1000 # Maximim UID used when adding system users MAX_USER_UID: int = 59999 -# LOGIN_TIMEOUT from /etc/loign.defs minus 10 sec +# LOGIN_TIMEOUT from /etc/loign.defs minus 10 sec0 MAX_RADIUS_TIMEOUT: int = 50 # MAX_RADIUS_TIMEOUT divided by 2 sec (minimum recomended timeout) MAX_RADIUS_COUNT: int = 8 @@ -73,6 +77,10 @@ SYSTEM_USER_SKIP_LIST: list = ['radius_user', 'radius_priv_user', 'tacacs0', 'ta 'tacacs7', 'tacacs8', 'tacacs9', 'tacacs10',' tacacs11', 'tacacs12', 'tacacs13', 'tacacs14', 'tacacs15'] +# As of OpenSSH 9.8p1 in Debian trixie, DSA keys are no longer supported +SSH_DSA_DEPRECATION_WARNING: str = f'{SSH_DSA_DEPRECATION_WARNING} '\ +'The following users are using SSH-DSS keys for authentication.' + def get_local_users(min_uid=MIN_USER_UID, max_uid=MAX_USER_UID): """Return list of dynamically allocated users (see Debian Policy Manual)""" local_users = [] @@ -182,6 +190,17 @@ def verify(login): else: raise ConfigError(f'User {user} is configured as an operator but is not assigned to any operator groups') + # Deprecation Warning for SSH DSS keys. + gen_header = True + if 'user' in login: + for user, user_config in login['user'].items(): + for pubkey, pubkey_options in (dict_search('authentication.public_keys', user_config) or {}).items(): + if 'type' in pubkey_options and pubkey_options['type'] == 'ssh-dss': + if gen_header: + gen_header = False + DeprecationWarning(SSH_DSA_DEPRECATION_WARNING) + print(f'User "{user}" with deprecated public-key named: {pubkey}') + if {'radius', 'tacacs'} <= set(login): raise ConfigError('Using both RADIUS and TACACS at the same time is not supported!') @@ -336,6 +355,12 @@ def generate(login): policy = list(map(lambda s: re.split(r'\s+', s), policy)) operator_config['groups'][g]['command_policy']['allow'] = policy + # Generate MOTD informing the user(s) for possible deprecated SSH keys + tmp = deepcopy(login) + tmp['ssh_dsa_deprecation_warning'] = f'DEPRECATION WARNING: {SSH_DSA_DEPRECATION_WARNING}' + render(login_motd_dsa_warning, 'login/motd_user_dsa_warning.j2', tmp, + permission=0o644, user='root', group='root') + with open('/etc/vyos/operators.json', 'w') as of: json.dump(operator_config, of) |
