From 07d403e568c2d459d44236217bebac5623087875 Mon Sep 17 00:00:00 2001 From: teacup-on-rockingchair <315160+teacup-on-rockingchair@users.noreply.github.com> Date: Thu, 26 Feb 2026 07:53:15 +0200 Subject: [PATCH 1/9] Make sure oval checks and remediations cover the case where default sshd config is in /usr subdir Add macros for ansible, bash and oval to check and set sshd config parameters for case where config can be both in /usr and /etc --- shared/macros/10-ansible.jinja | 117 ++++++++++++++++++++++++++ shared/macros/10-bash.jinja | 50 +++++++++++ shared/macros/10-oval.jinja | 147 +++++++++++++++++++++++++++++++++ 3 files changed, 314 insertions(+) diff --git a/shared/macros/10-ansible.jinja b/shared/macros/10-ansible.jinja index fe432b975fc5..7347a88c6775 100644 --- a/shared/macros/10-ansible.jinja +++ b/shared/macros/10-ansible.jinja @@ -2387,3 +2387,120 @@ lines will be inserted at the beginning of the profile. ansible.builtin.command: dconf update when: dconf_user_profile_blockinfile is changed {{%- endmacro -%}} + + +{{# + + Set a sshd configuration parameter to a value for system with /usr - located default config + +:parameter msg: Message to be set as Task Title, if not set the rule's title will be used instead +:type msg: str +:parameter parameter: Parameter to set +:type parameter: str +:parameter value: The value to set +:type value: str +:param copy_defaults: If true default sshd configuration in /usr/etc/ssh/sshd_config will be +copied onto /etc/ssh/sshd_config, if /etc/ssh/sshd_config does not exist +:type copy_defaults: bool +:parameter config_basename: drop-in filename of sshd configuration file +:type config_basename: str + +#}} +{{%- macro ansible_sshd_set_usr(msg='', parameter='', value='', copy_defaults=true, config_basename="00-complianceascode-hardening.conf", rule_title=None) %}} +{{%- set sshd_config_path = "/etc/ssh/sshd_config" %}} +{{%- set sshd_usr_config_path = "/usr/etc/ssh/sshd_config" %}} +{{%- set sshd_config_dir = "/etc/ssh/sshd_config.d" -%}} +{{%- set sshd_usr_config_dir = "/usr/etc/ssh/sshd_config.d" -%}} +{{%- set ssh_paths = ['/etc/ssh/sshd_config.d', '/usr/etc/ssh/sshd_config.d'] -%}} +{{%- set config_file = "/etc/ssh/sshd_config.d/" ~ config_basename -%}} +{{%- set new_line = parameter + ' ' + value -%}} +{{%- set line_regex = "(?i)^\s*" + "{{ \"" + parameter + "\"| regex_escape }}" + "\s+" -%}} +{{%- set dir_parameter = "sshd_config_d_has_parameter" -%}} +{{%- set lineinfile_items = "{{ " + dir_parameter + ".files }}" -%}} + +- name: Copy default {{{ sshd_usr_config_path }}} to {{{ sshd_config_path }}} + ansible.builtin.copy: + src: {{{ sshd_usr_config_path }}} + dest: {{{ sshd_config_path }}} + force: no + mode: '0600' +- name: {{{ rule_title }}} - Check if the parameter {{{ parameter }}} is configured in sshd configuration(s) + ansible.builtin.find: + paths: + - '/etc/ssh' + - '/usr/etc/ssh' + - {{{ sshd_config_dir }}} + - {{{ sshd_usr_config_dir }}} + contains: {{{ line_regex }}} + patterns: + - '*.conf' + - 'sshd_config' + register: _sshd_config_has_parameter +- name: {{{ rule_title }}} - Check if the parameter {{{ parameter }}} is configured correctly in sshd configuration(s) + ansible.builtin.find: + paths: + - '/etc/ssh' + - '/usr/etc/ssh' + - {{{ sshd_config_dir }}} + - {{{ sshd_usr_config_dir }}} + contains: {{{ line_regex ~ value ~ "$" }}} + patterns: + - '*.conf' + - 'sshd_config' + register: _sshd_config_correctly +- name: '{{{ msg or rule_title }}}' + block: + {{{ ansible_lineinfile( + "Deduplicate values from " + sshd_config_path, + sshd_config_path, + regex=line_regex, + insensitive='false', + create='no', + state='absent')|indent }}} + {{{ ansible_lineinfile( + "Deduplicate values from " + sshd_usr_config_path, + sshd_usr_config_path, + regex=line_regex, + insensitive='false', + create='no', + state='absent')|indent }}} + - name: "Check if the parameter {{{ parameter }}} is present in {{{ sshd_config_dir }}} and in {{{ sshd_usr_config_dir }}}" + ansible.builtin.find: + paths: {{{ ssh_paths }}} + recurse: 'yes' + follow: 'no' + contains: '(?i)^\s*{{ "{{{ parameter }}}"| regex_escape }}\s+' + register: {{{ dir_parameter }}} + {{{ ansible_lineinfile( + "Remove parameter from files in " + sshd_config_dir, + path="{{ item.path }}", + regex=line_regex, + state="absent", + with_items=lineinfile_items)|indent}}} + {{{ ansible_lineinfile( + "Remove parameter from files in " + sshd_usr_config_dir, + path="{{ item.path }}", + regex=line_regex, + state="absent", + with_items=lineinfile_items)|indent }}} + {{{ ansible_lineinfile( + "Insert correct line to " + config_file, + config_file, + regex=line_regex, + insensitive='false', + new_line=new_line, + create='yes', + state='present', + validate='/usr/sbin/sshd -t -f %s', + insert_after='', + insert_before="BOF" )|indent }}} + when: _sshd_config_correctly.matched == 0 or _sshd_config_has_parameter.matched != 1 + +- name: {{{ rule_title }}} - set file mode for {{{ config_file }}} + ansible.builtin.file: + path: {{{ config_file }}} + mode: '0600' + state: touch + modification_time: preserve + access_time: preserve +{{%- endmacro %}} diff --git a/shared/macros/10-bash.jinja b/shared/macros/10-bash.jinja index 8bcd4bec988c..9d8a759e3b01 100644 --- a/shared/macros/10-bash.jinja +++ b/shared/macros/10-bash.jinja @@ -2748,3 +2748,53 @@ This macro creates a Bash conditional which checks the system architecture in /p {{%- macro bash_arch_conditional(arch) -%}} ( grep -sqE "^.*\.{{{ arch }}}$" /proc/sys/kernel/osrelease || grep -sqE "^{{{ arch }}}$" /proc/sys/kernel/arch; ) {{%- endmacro -%}} + + +{{# + Set a sshd configuration parameter to a value for system with default configuration in /usr subdir + +:parameter parameter: Parameter to set +:type parameter: str +:parameter value: The value to set +:type value: str +:param copy_defaults: If true default sshd configuration in /usr/etc/ssh/sshd_config will be +copied onto /etc/ssh/sshd_config, if /etc/ssh/sshd_config does not exist +:type copy_defaults: bool +:parameter config_basename: drop-in filename of sshd configuration file +:type config_basename: str + +#}} +{{% macro bash_sshd_remediation_usr(parameter, value, copy_defaults="true", config_basename="00-complianceascode-hardening.conf", rule_id=None) -%}} +{{%- set sshd_config_path = "/etc/ssh/sshd_config" %}} +{{%- set sshd_config_dir = "/etc/ssh/sshd_config.d" -%}} +{{%- set sshd_usr_config_path = "/usr/etc/ssh/sshd_config" %}} +{{%- set sshd_usr_config_dir = "/usr/etc/ssh/sshd_config.d" -%}} +{{%- set prefix_regex = "^\s*" -%}} +{{%- set separator_regex = "\s\+" -%}} +{{%- set hardening_config_basename = config_basename %}} +{{%- set line_regex = prefix_regex ~ parameter ~ separator_regex %}} + +if ! [ -e "{{{ sshd_config_path }}}" ] ; then + cp "{{{ sshd_usr_config_path }}}" "{{{ sshd_config_path }}}" +fi + +mkdir -p {{{ sshd_config_dir }}} +touch {{{ sshd_config_dir }}}/{{{ hardening_config_basename }}} +chmod 0600 {{{ sshd_config_dir }}}/{{{ hardening_config_basename }}} +{{{ lineinfile_absent(sshd_config_path, line_regex, insensitive=true, rule_id=rule_id) }}} +{{{ lineinfile_absent_in_directory(sshd_config_dir, line_regex, insensitive=true, filename_glob="*.conf") }}} +{{{ lineinfile_absent(sshd_usr_config_path, line_regex, insensitive=true, rule_id=rule_id) }}} +{{{ lineinfile_absent_in_directory(sshd_usr_config_dir, line_regex, insensitive=true, filename_glob="*.conf") }}} +{{{ set_config_file( + path=sshd_config_dir ~ "/" ~ hardening_config_basename, + parameter=parameter, + value=value, + create=true, + insert_after="", + insert_before="BOF", + insensitive=true, + separator=" ", + separator_regex=separator_regex, + prefix_regex=prefix_regex, rule_id=rule_id) + }}} +{{%- endmacro %}} diff --git a/shared/macros/10-oval.jinja b/shared/macros/10-oval.jinja index 6466728189db..a755d21e0593 100644 --- a/shared/macros/10-oval.jinja +++ b/shared/macros/10-oval.jinja @@ -1878,3 +1878,150 @@ Macro generates an OVAL test definition to verify that a specified audit tool is {{%- endmacro -%}} + + +{{# + Create a full OVAL check for an sshd parameter and value in /etc/ssh/sshd_config or /usr/etc/ssh/sshd_config. + Including /etc/ssh/sshd_config.d/*.conf and /usr/etc/ssh/sshd_config.d/*.conf (default on SUSE Linux Enterprise Server 16) + +:param parameter: Parameter to check +:type parameter: str +:param value: Value to check +:type value: str +:param missing_parameter_pass: If true, the check will pass if the parameter missing. +:type missing_parameter_pass: bool +:param xccdf_variable: the name of an XCCDF variable carrying the value, this conflicts with the value parameter +:type xccdf_variable: str +:param datatype: a data type of the value +:type datatype: str + +#}} +{{%- macro sshd_oval_check_usr(parameter, value, missing_parameter_pass, xccdf_variable="", datatype="", rule_id=None, rule_title=None) -%}} +{{%- set sshd_config_path = "/etc/ssh/sshd_config" %}} +{{%- set sshd_usr_config_path = "/usr/etc/ssh/sshd_config" -%}} +{{%- set sshd_config_dir = "/etc/ssh/sshd_config.d" -%}} +{{%- set sshd_usr_config_dir = "/usr/etc/ssh/sshd_config.d" -%}} +{{%- if xccdf_variable -%}} +{{%- set description = "Ensure '" ~ parameter ~ "' is configured with value configured in " ~ xccdf_variable ~ " variable in " ~ sshd_config_path %}} +{{%- else -%}} +{{%- set description = "Ensure '" ~ parameter ~ "' is configured with value '" ~ value ~ "' in " ~ sshd_config_path -%}} +{{%- endif -%}} +{{%- set description = description ~ " or in " ~ sshd_config_dir -%}} +{{%- set description = description ~ " or in " ~ sshd_usr_config_path -%}} +{{%- set description = description ~ " or in " ~ sshd_usr_config_dir -%}} +{{%- set case_insensitivity_kwargs = dict(prefix_regex="^[ \\t]*(?i)", separator_regex = "(?-i)[ \\t]+") -%}} + + + + {{{ oval_metadata(description, rule_title=rule_title) }}} + + + + + + + + + + + + + {{{ oval_line_in_file_criterion(sshd_config_path, parameter, avoid_conflicting=true, rule_id=rule_id) | indent(12)}}} + {{{ oval_line_in_directory_criterion(sshd_config_dir, parameter, avoid_conflicting=true, rule_id=rule_id) | indent(12) }}} + {{{ oval_line_in_file_criterion(sshd_usr_config_dir, parameter, id_stem=rule_id ~ "_sshd_usr_config_dir") | indent(12) }}} + + {{%- if not missing_parameter_pass -%}} + + {{%- endif -%}} + + + + + + + + + + + {{{ oval_line_in_file_criterion(sshd_usr_config_path, parameter, avoid_conflicting=true, id_stem=rule_id ~ "_sshd_usr_config_path") | indent(12)}}} + {{{ oval_line_in_directory_criterion(sshd_config_dir, parameter, avoid_conflicting=true, rule_id=rule_id) | indent(12) }}} + {{{ oval_line_in_file_criterion(sshd_usr_config_dir, parameter, id_stem=rule_id ~ "_sshd_usr_config_dir") | indent(12) }}} + + {{%- if not missing_parameter_pass -%}} + + {{%- endif -%}} + + + + + + + {{{ oval_config_file_exists_test(sshd_config_path, rule_id=rule_id) }}} + {{{ oval_config_file_exists_object(sshd_config_path, rule_id=rule_id) }}} + + {{{ oval_line_in_file_test(sshd_config_path, parameter, avoid_conflicting=true, rule_id=rule_id) | indent (2) }}} + {{{ oval_line_in_file_object(sshd_config_path, parameter=parameter, rule_id=rule_id, ** case_insensitivity_kwargs)| indent (2) }}} + + {{{ oval_line_in_directory_test(sshd_config_dir, parameter, avoid_conflicting=true, rule_id=rule_id) | indent (2) }}} + {{{ oval_line_in_directory_object(sshd_config_dir, parameter=parameter, rule_id=rule_id, ** case_insensitivity_kwargs) | indent (2) }}} + {{%- if xccdf_variable -%}} + {{{ oval_line_in_file_define_variable(xccdf_variable, datatype) }}} + {{{ oval_line_in_file_state_xccdf_variable(xccdf_variable, datatype=datatype, rule_id=rule_id) }}} + {{{ oval_line_in_directory_state_xccdf_variable(xccdf_variable, datatype, rule_id=rule_id) | indent (2) }}} + {{{ oval_line_in_file_state_xccdf_variable(var_name=xccdf_variable, datatype=datatype, id_stem=rule_id ~ "_sshd_usr_config_path") | indent (2) }}} + {{{ oval_line_in_file_state_xccdf_variable(var_name=xccdf_variable, datatype=datatype, id_stem=rule_id ~ "_sshd_usr_config_dir") | indent (2) }}} + {{%- else -%}} + {{{ oval_line_in_file_state(value, rule_id=rule_id) | indent (2) }}} + {{{ oval_line_in_directory_state(value, rule_id=rule_id) | indent (2) }}} + {{{ oval_line_in_file_state(value, id_stem=rule_id ~ "_sshd_usr_config_path") | indent (2) }}} + {{{ oval_line_in_file_state(value, id_stem=rule_id ~ "_sshd_usr_config_dir") | indent (2) }}} + {{%- endif -%}} + + {{{ oval_line_in_file_test(sshd_usr_config_path, parameter, avoid_conflicting=true, id_stem=rule_id ~ "_sshd_usr_config_path") | indent (2) }}} + {{{ oval_line_in_file_object(sshd_usr_config_path, parameter=parameter, id_stem=rule_id ~ "_sshd_usr_config_path", ** case_insensitivity_kwargs)| indent (2) }}} + {{{ oval_line_in_file_test(sshd_usr_config_dir, parameter, avoid_conflicting=true, id_stem=rule_id ~ "_sshd_usr_config_dir") | indent (2) }}} + {{{ oval_line_in_file_object(sshd_usr_config_dir, parameter=parameter, filename_regex=".*\.conf$", id_stem=rule_id ~ "_sshd_usr_config_dir", ** case_insensitivity_kwargs) | indent (2) }}} + + {{%- if not missing_parameter_pass -%}} + + + + obj_{{{ rule_id }}} + obj_{{{ rule_id }}}_config_dir + + + obj_{{{ rule_id }}}_sshd_usr_config_dir + + + + + + + + + + + + obj_{{{ rule_id }}}_config_dir + + + obj_{{{ rule_id }}}_sshd_usr_config_path + obj_{{{ rule_id }}}_sshd_usr_config_dir + + + + + + + + {{%- endif -%}} + +{{%- endmacro -%}} From d094607042fa5635d41f5828622ed88b05bb7593 Mon Sep 17 00:00:00 2001 From: teacup-on-rockingchair <315160+teacup-on-rockingchair@users.noreply.github.com> Date: Thu, 26 Feb 2026 07:57:04 +0200 Subject: [PATCH 2/9] Use the new macros in sshd lineinfile context --- .../sshd_lineinfile/ansible.template | 53 +++++++++++++----- .../templates/sshd_lineinfile/bash.template | 18 +++++-- .../templates/sshd_lineinfile/oval.template | 54 +++++++++++++++++-- .../templates/sshd_lineinfile/tests/common.sh | 9 +++- .../tests/correct_value_directory.pass.sh | 3 +- .../correct_value_usr_config_dir.pass.sh | 9 ++++ .../correct_value_usr_config_path.pass.sh | 13 +++++ .../tests/duplicated_param.pass.sh | 9 ++-- .../tests/duplicated_param_directory.pass.sh | 11 ++-- .../tests/line_not_there.fail.sh | 5 ++ .../tests/param_conflict_directory.fail.sh | 2 +- ...param_conflict_file_with_directory.fail.sh | 2 +- .../tests/wrong_value_directory.fail.sh | 2 +- .../tests/wrong_value_usr_config_dir.fail.sh | 14 +++++ .../tests/wrong_value_usr_config_path.fail.sh | 16 ++++++ 15 files changed, 185 insertions(+), 35 deletions(-) create mode 100644 shared/templates/sshd_lineinfile/tests/correct_value_usr_config_dir.pass.sh create mode 100644 shared/templates/sshd_lineinfile/tests/correct_value_usr_config_path.pass.sh create mode 100644 shared/templates/sshd_lineinfile/tests/wrong_value_usr_config_dir.fail.sh create mode 100644 shared/templates/sshd_lineinfile/tests/wrong_value_usr_config_path.fail.sh diff --git a/shared/templates/sshd_lineinfile/ansible.template b/shared/templates/sshd_lineinfile/ansible.template index a5a1f2302d7b..0739450cdf24 100644 --- a/shared/templates/sshd_lineinfile/ansible.template +++ b/shared/templates/sshd_lineinfile/ansible.template @@ -6,19 +6,44 @@ {{% if XCCDF_VARIABLE %}} {{{ ansible_instantiate_variables(XCCDF_VARIABLE) }}} -{{{ - ansible_sshd_set( - parameter=PARAMETER, - value="{{ "+XCCDF_VARIABLE+" }}", - config_is_distributed=sshd_distributed_config, - config_basename=CONFIG_BASENAME, rule_title=rule_title) -}}} + {{%- if product == 'sle16' -%}} + {{{ + ansible_sshd_set_usr( + parameter=PARAMETER, + value="{{ "+XCCDF_VARIABLE+" }}", + copy_defaults='true', + config_basename=CONFIG_BASENAME, + rule_title=rule_title + ) + }}} + {{%- else -%}} + {{{ + ansible_sshd_set( + parameter=PARAMETER, + value="{{ "+XCCDF_VARIABLE+" }}", + config_is_distributed=sshd_distributed_config, + config_basename=CONFIG_BASENAME, rule_title=rule_title) + }}} + {{%- endif -%}} {{% else %}} -{{{ - ansible_sshd_set( - parameter=PARAMETER, - value=VALUE, - config_is_distributed=sshd_distributed_config, - config_basename=CONFIG_BASENAME, rule_title=rule_title) -}}} + {{%- if product == 'sle16' -%}} + {{{ + ansible_sshd_set_usr( + parameter=PARAMETER, + value=VALUE, + copy_defaults='true', + config_basename=CONFIG_BASENAME, + rule_title=rule_title + ) + }}} + {{%- else -%}} + {{{ + ansible_sshd_set( + parameter=PARAMETER, + value=VALUE, + config_is_distributed=sshd_distributed_config, + config_basename=CONFIG_BASENAME, rule_title=rule_title) + }}} + {{%- endif -%}} + {{% endif %}} diff --git a/shared/templates/sshd_lineinfile/bash.template b/shared/templates/sshd_lineinfile/bash.template index aec5c2029a3a..4bec19d82f43 100644 --- a/shared/templates/sshd_lineinfile/bash.template +++ b/shared/templates/sshd_lineinfile/bash.template @@ -5,8 +5,16 @@ # disruption = low {{% if XCCDF_VARIABLE %}} -{{{ bash_instantiate_variables(XCCDF_VARIABLE) }}} -{{{ bash_sshd_remediation(parameter=PARAMETER, value="$" ~ XCCDF_VARIABLE, config_is_distributed=sshd_distributed_config, config_basename=CONFIG_BASENAME, rule_id=rule_id) -}}} -{{% else %}} -{{{ bash_sshd_remediation(parameter=PARAMETER, value=VALUE, config_is_distributed=sshd_distributed_config, config_basename=CONFIG_BASENAME, rule_id=rule_id) -}}} -{{% endif %}} + {{{- bash_instantiate_variables(XCCDF_VARIABLE) -}}} + {{%- if product == 'sle16' -%}} + {{{- bash_sshd_remediation_usr(parameter=PARAMETER, value="$" ~ XCCDF_VARIABLE, copy_defaults=true, config_basename=CONFIG_BASENAME, rule_id=rule_id) -}}} + {{%- else -%}} + {{{- bash_sshd_remediation(parameter=PARAMETER, value="$" ~ XCCDF_VARIABLE, config_is_distributed=sshd_distributed_config, config_basename=CONFIG_BASENAME, rule_id=rule_id) -}}} + {{%- endif -%}} +{{%- else -%}} + {{%- if product == 'sle16' -%}} + {{{- bash_sshd_remediation_usr(parameter=PARAMETER, value=VALUE, copy_defaults=true, config_basename=CONFIG_BASENAME, rule_id=rule_id) -}}} + {{%- else -%}} + {{{- bash_sshd_remediation(parameter=PARAMETER, value=VALUE, config_is_distributed=sshd_distributed_config, config_basename=CONFIG_BASENAME, rule_id=rule_id) -}}} + {{%- endif -%}} +{{%- endif -%}} diff --git a/shared/templates/sshd_lineinfile/oval.template b/shared/templates/sshd_lineinfile/oval.template index d3f4218ec300..20e9534ff10f 100644 --- a/shared/templates/sshd_lineinfile/oval.template +++ b/shared/templates/sshd_lineinfile/oval.template @@ -1,5 +1,53 @@ -{{%- if XCCDF_VARIABLE -%}} -{{{ sshd_oval_check(parameter=PARAMETER, xccdf_variable=XCCDF_VARIABLE, missing_parameter_pass=MISSING_PARAMETER_PASS, config_is_distributed=sshd_distributed_config, runtime_check=sshd_runtime_check, datatype=DATATYPE, rule_id=rule_id, rule_title=rule_title) }}} +{{%- if product == 'sle16' -%}} + {{%- if XCCDF_VARIABLE -%}} + {{{ + sshd_oval_check_usr( + parameter=PARAMETER, + xccdf_variable=XCCDF_VARIABLE, + missing_parameter_pass=MISSING_PARAMETER_PASS, + datatype=DATATYPE, + rule_id=rule_id, + rule_title=rule_title + ) + }}} + {{%- else -%}} + {{{ + sshd_oval_check_usr( + parameter=PARAMETER, + value=VALUE, + missing_parameter_pass=MISSING_PARAMETER_PASS, + datatype=DATATYPE, + rule_id=rule_id, + rule_title=rule_title + ) + }}} + {{%- endif -%}} {{%- else -%}} -{{{ sshd_oval_check(parameter=PARAMETER, value=VALUE, missing_parameter_pass=MISSING_PARAMETER_PASS, config_is_distributed=sshd_distributed_config, runtime_check=sshd_runtime_check, datatype=DATATYPE, rule_id=rule_id, rule_title=rule_title) }}} + {{%- if XCCDF_VARIABLE -%}} + {{{ + sshd_oval_check( + parameter=PARAMETER, + xccdf_variable=XCCDF_VARIABLE, + missing_parameter_pass=MISSING_PARAMETER_PASS, + config_is_distributed=sshd_distributed_config, + runtime_check=sshd_runtime_check, + datatype=DATATYPE, + rule_id=rule_id, + rule_title=rule_title + ) + }}} + {{%- else -%}} + {{{ + sshd_oval_check( + parameter=PARAMETER, + value=VALUE, + missing_parameter_pass=MISSING_PARAMETER_PASS, + config_is_distributed=sshd_distributed_config, + runtime_check=sshd_runtime_check, + datatype=DATATYPE, + rule_id=rule_id, + rule_title=rule_title + ) + }}} + {{%- endif -%}} {{%- endif -%}} diff --git a/shared/templates/sshd_lineinfile/tests/common.sh b/shared/templates/sshd_lineinfile/tests/common.sh index 2f811821fde2..23d7937088af 100644 --- a/shared/templates/sshd_lineinfile/tests/common.sh +++ b/shared/templates/sshd_lineinfile/tests/common.sh @@ -3,8 +3,13 @@ mkdir -p /etc/ssh/sshd_config.d touch /etc/ssh/sshd_config.d/nothing -if grep -q "^\s*{{{ PARAMETER }}}" /etc/ssh/sshd_config /etc/ssh/sshd_config.d/* ; then - sed -i "s/^{{{ PARAMETER }}}.*/# {{{ PARAMETER }}} {{{ CORRECT_VALUE }}}/g" /etc/ssh/sshd_config /etc/ssh/sshd_config.d/* +declare -a SSHD_PATHS=("/etc/ssh/sshd_config" /etc/ssh/sshd_config.d/*) +{{% if product == 'sle16' %}} +SSHD_PATHS+=("/usr/etc/ssh/sshd_config" /usr/etc/ssh/sshd_config.d/*) +{{% endif %}} + +if grep -q "^\s*{{{ PARAMETER }}}" "${SSHD_PATHS[@]}" ; then + sed -i "s/^{{{ PARAMETER }}}.*/# {{{ PARAMETER }}} {{{ CORRECT_VALUE }}}/g" "${SSHD_PATHS[@]}" else echo "# {{{ PARAMETER }}} {{{ CORRECT_VALUE }}}" >> /etc/ssh/sshd_config fi diff --git a/shared/templates/sshd_lineinfile/tests/correct_value_directory.pass.sh b/shared/templates/sshd_lineinfile/tests/correct_value_directory.pass.sh index 3114b75fe541..c0926871f3a3 100644 --- a/shared/templates/sshd_lineinfile/tests/correct_value_directory.pass.sh +++ b/shared/templates/sshd_lineinfile/tests/correct_value_directory.pass.sh @@ -1,6 +1,6 @@ #!/bin/bash -# platform = multi_platform_fedora,Oracle Linux 8,Oracle Linux 9,Red Hat Enterprise Linux 9,Red Hat Enterprise Linux 10,multi_platform_ubuntu +# platform = Oracle Linux 8,Oracle Linux 9,Red Hat Enterprise Linux 10,Red Hat Enterprise Linux 9,SUSE Linux Enterprise 16,multi_platform_fedora,multi_platform_ubuntu {{%- if XCCDF_VARIABLE %}} # variables = {{{ XCCDF_VARIABLE }}}={{{ CORRECT_VALUE }}} {{%- endif %}} @@ -12,4 +12,3 @@ source common.sh {{% endif %}} {{{ bash_sshd_remediation(parameter=PARAMETER, value=CORRECT_VALUE, config_is_distributed=sshd_distributed_config, rule_id=rule_id) -}}} - diff --git a/shared/templates/sshd_lineinfile/tests/correct_value_usr_config_dir.pass.sh b/shared/templates/sshd_lineinfile/tests/correct_value_usr_config_dir.pass.sh new file mode 100644 index 000000000000..b853676b0552 --- /dev/null +++ b/shared/templates/sshd_lineinfile/tests/correct_value_usr_config_dir.pass.sh @@ -0,0 +1,9 @@ +#!/bin/bash +# platform = SUSE Linux Enterprise 16 +source common.sh + +{{%- if XCCDF_VARIABLE %}} +# variables = {{{ XCCDF_VARIABLE }}}={{{ CORRECT_VALUE }}} +{{%- endif %}} + +echo "{{{ PARAMETER }}} {{{ CORRECT_VALUE }}}" >> /usr/etc/ssh/sshd_config.d/oscap-sshd-config.conf diff --git a/shared/templates/sshd_lineinfile/tests/correct_value_usr_config_path.pass.sh b/shared/templates/sshd_lineinfile/tests/correct_value_usr_config_path.pass.sh new file mode 100644 index 000000000000..b5dfae159dac --- /dev/null +++ b/shared/templates/sshd_lineinfile/tests/correct_value_usr_config_path.pass.sh @@ -0,0 +1,13 @@ +#!/bin/bash +# platform = SUSE Linux Enterprise 16 +source common.sh + +{{%- if XCCDF_VARIABLE %}} +# variables = {{{ XCCDF_VARIABLE }}}={{{ CORRECT_VALUE }}} +{{%- endif %}} + +if [ -e "/etc/ssh/sshd_config" ] ; then + rm /etc/ssh/sshd_config +fi + +echo "{{{ PARAMETER }}} {{{ CORRECT_VALUE }}}" >> /usr/etc/ssh/sshd_config diff --git a/shared/templates/sshd_lineinfile/tests/duplicated_param.pass.sh b/shared/templates/sshd_lineinfile/tests/duplicated_param.pass.sh index aac35afbcad6..8d3d7be24f18 100644 --- a/shared/templates/sshd_lineinfile/tests/duplicated_param.pass.sh +++ b/shared/templates/sshd_lineinfile/tests/duplicated_param.pass.sh @@ -1,12 +1,15 @@ #!/bin/bash - +declare -a SSHD_PATHS=("/etc/ssh/sshd_config" /etc/ssh/sshd_config.d/*) +{{% if product == 'sle16' %}} +SSHD_PATHS+=("/usr/etc/ssh/sshd_config" /usr/etc/ssh/sshd_config.d/*) +{{% endif %}} mkdir -p /etc/ssh/sshd_config.d touch /etc/ssh/sshd_config.d/nothing -if grep -q "^\s*{{{ PARAMETER }}}" /etc/ssh/sshd_config /etc/ssh/sshd_config.d/* ; then - sed -i "/^\s*{{{ PARAMETER }}}.*/Id" /etc/ssh/sshd_config /etc/ssh/sshd_config.d/* +if grep -q "^\s*{{{ PARAMETER }}}" "${SSHD_PATHS[@]}" ; then + sed -i "/^\s*{{{ PARAMETER }}}.*/Id" "${SSHD_PATHS[@]}" fi {{% if XCCDF_VARIABLE %}} diff --git a/shared/templates/sshd_lineinfile/tests/duplicated_param_directory.pass.sh b/shared/templates/sshd_lineinfile/tests/duplicated_param_directory.pass.sh index b05adb222229..1b94be25b086 100644 --- a/shared/templates/sshd_lineinfile/tests/duplicated_param_directory.pass.sh +++ b/shared/templates/sshd_lineinfile/tests/duplicated_param_directory.pass.sh @@ -1,6 +1,6 @@ #!/bin/bash -# platform = multi_platform_fedora,Oracle Linux 8,Oracle Linux 9,Red Hat Enterprise Linux 9,Red Hat Enterprise Linux 10,multi_platform_ubuntu +# platform = Oracle Linux 8,Oracle Linux 9,Red Hat Enterprise Linux 10,Red Hat Enterprise Linux 9,SUSE Linux Enterprise 16,multi_platform_fedora,multi_platform_ubuntu mkdir -p /etc/ssh/sshd_config.d touch /etc/ssh/sshd_config.d/nothing @@ -9,8 +9,13 @@ touch /etc/ssh/sshd_config.d/nothing {{{ bash_replace_or_append("/etc/ssh/sshd_config", "Include", "/etc/ssh/sshd_config.d/*.conf", "%s %s", cce_identifiers=cce_identifiers) }}} {{% endif %}} -if grep -q "^\s*{{{ PARAMETER }}}" /etc/ssh/sshd_config /etc/ssh/sshd_config.d/* ; then - sed -i "/^\s*{{{ PARAMETER }}}.*/Id" /etc/ssh/sshd_config /etc/ssh/sshd_config.d/* +declare -a SSHD_PATHS=("/etc/ssh/sshd_config" /etc/ssh/sshd_config.d/*) +{{% if product == 'sle16' %}} +SSHD_PATHS+=("/usr/etc/ssh/sshd_config" /usr/etc/ssh/sshd_config.d/*) +{{% endif %}} + +if grep -q "^\s*{{{ PARAMETER }}}" "${SSHD_PATHS[@]}" ; then + sed -i "/^\s*{{{ PARAMETER }}}.*/Id" "${SSHD_PATHS[@]}" fi {{% if XCCDF_VARIABLE %}} diff --git a/shared/templates/sshd_lineinfile/tests/line_not_there.fail.sh b/shared/templates/sshd_lineinfile/tests/line_not_there.fail.sh index 5bc6d1043169..da6e5e46e494 100644 --- a/shared/templates/sshd_lineinfile/tests/line_not_there.fail.sh +++ b/shared/templates/sshd_lineinfile/tests/line_not_there.fail.sh @@ -5,4 +5,9 @@ SSHD_PARAM={{{ PARAMETER }}} mkdir -p /etc/ssh/sshd_config.d touch /etc/ssh/sshd_config.d/nothing +{{% if product == 'sle16' %}} +touch /etc/ssh/sshd_config +sed -i "/^\s*${SSHD_PARAM}.*/Id" /etc/ssh/sshd_config /etc/ssh/sshd_config.d/* /usr/etc/ssh/sshd_config /usr/etc/ssh/sshd_config.d/* +{{% else %}} sed -i "/^\s*${SSHD_PARAM}.*/Id" /etc/ssh/sshd_config /etc/ssh/sshd_config.d/* +{{% endif %}} diff --git a/shared/templates/sshd_lineinfile/tests/param_conflict_directory.fail.sh b/shared/templates/sshd_lineinfile/tests/param_conflict_directory.fail.sh index d91244f7a08a..73ed7000227b 100644 --- a/shared/templates/sshd_lineinfile/tests/param_conflict_directory.fail.sh +++ b/shared/templates/sshd_lineinfile/tests/param_conflict_directory.fail.sh @@ -1,6 +1,6 @@ #!/bin/bash -# platform = multi_platform_fedora,Oracle Linux 8,Oracle Linux 9,Red Hat Enterprise Linux 9,Red Hat Enterprise Linux 10,multi_platform_ubuntu +# platform = Oracle Linux 8,Oracle Linux 9,Red Hat Enterprise Linux 10,Red Hat Enterprise Linux 9,SUSE Linux Enterprise 16,multi_platform_fedora,multi_platform_ubuntu {{% if XCCDF_VARIABLE %}} diff --git a/shared/templates/sshd_lineinfile/tests/param_conflict_file_with_directory.fail.sh b/shared/templates/sshd_lineinfile/tests/param_conflict_file_with_directory.fail.sh index 15eb1d87033b..530ffdc2fb14 100644 --- a/shared/templates/sshd_lineinfile/tests/param_conflict_file_with_directory.fail.sh +++ b/shared/templates/sshd_lineinfile/tests/param_conflict_file_with_directory.fail.sh @@ -1,6 +1,6 @@ #!/bin/bash -# platform = multi_platform_fedora,Oracle Linux 8,Oracle Linux 9,Red Hat Enterprise Linux 9,Red Hat Enterprise Linux 10,multi_platform_ubuntu +# platform = Oracle Linux 8,Oracle Linux 9,Red Hat Enterprise Linux 10,Red Hat Enterprise Linux 9,SUSE Linux Enterprise 16,multi_platform_fedora,multi_platform_ubuntu {{% if XCCDF_VARIABLE %}} # variables = {{{ XCCDF_VARIABLE }}}={{{ CORRECT_VALUE }}} diff --git a/shared/templates/sshd_lineinfile/tests/wrong_value_directory.fail.sh b/shared/templates/sshd_lineinfile/tests/wrong_value_directory.fail.sh index c5f2c41e875a..c9bf477b34ca 100644 --- a/shared/templates/sshd_lineinfile/tests/wrong_value_directory.fail.sh +++ b/shared/templates/sshd_lineinfile/tests/wrong_value_directory.fail.sh @@ -1,6 +1,6 @@ #!/bin/bash -# platform = multi_platform_fedora,Oracle Linux 8,Oracle Linux 9,Red Hat Enterprise Linux 9,Red Hat Enterprise Linux 10,multi_platform_ubuntu +# platform = Oracle Linux 8,Oracle Linux 9,Red Hat Enterprise Linux 10,Red Hat Enterprise Linux 9,SUSE Linux Enterprise 16,multi_platform_fedora,multi_platform_ubuntu {{% if XCCDF_VARIABLE %}} # variables = {{{ XCCDF_VARIABLE }}}={{{ CORRECT_VALUE }}} diff --git a/shared/templates/sshd_lineinfile/tests/wrong_value_usr_config_dir.fail.sh b/shared/templates/sshd_lineinfile/tests/wrong_value_usr_config_dir.fail.sh new file mode 100644 index 000000000000..a073ad1c0991 --- /dev/null +++ b/shared/templates/sshd_lineinfile/tests/wrong_value_usr_config_dir.fail.sh @@ -0,0 +1,14 @@ +#!/bin/bash +# platform = SUSE Linux Enterprise 16 + +{{% if XCCDF_VARIABLE %}} +# variables = {{{ XCCDF_VARIABLE }}}={{{ CORRECT_VALUE }}} +{{% endif %}} + +touch /usr/etc/ssh/sshd_config.d/oscap-sshd-config.conf + +if grep -q "^\s*{{{ PARAMETER }}}" /usr/etc/ssh/sshd_config /usr/etc/ssh/sshd_config.d/* ; then + sed -i "/^\s*{{{ PARAMETER }}}.*/Id" /usr/etc/ssh/sshd_config /usr/etc/ssh/sshd_config.d/* +fi + +echo "{{{ PARAMETER }}} {{{ WRONG_VALUE }}}" > /usr/etc/ssh/sshd_config.d/oscap-sshd-config.conf diff --git a/shared/templates/sshd_lineinfile/tests/wrong_value_usr_config_path.fail.sh b/shared/templates/sshd_lineinfile/tests/wrong_value_usr_config_path.fail.sh new file mode 100644 index 000000000000..0ff115b7e45e --- /dev/null +++ b/shared/templates/sshd_lineinfile/tests/wrong_value_usr_config_path.fail.sh @@ -0,0 +1,16 @@ +#!/bin/bash +# platform = SUSE Linux Enterprise 16 + +{{% if XCCDF_VARIABLE %}} +# variables = {{{ XCCDF_VARIABLE }}}={{{ CORRECT_VALUE }}} +{{% endif %}} + +if [ -e "/etc/ssh/sshd_config" ] ; then + rm /etc/ssh/sshd_config +fi + +if grep -q "^\s*{{{ PARAMETER }}}" /usr/etc/ssh/sshd_config /usr/etc/ssh/sshd_config.d/* ; then + sed -i "/^\s*{{{ PARAMETER }}}.*/Id" /usr/etc/ssh/sshd_config /usr/etc/ssh/sshd_config.d/* +fi + +echo "{{{ PARAMETER }}} {{{ WRONG_VALUE }}}" >> /usr/etc/ssh/sshd_config From 5d65b420049525dd1cb8b849713625758116bad2 Mon Sep 17 00:00:00 2001 From: teacup-on-rockingchair <315160+teacup-on-rockingchair@users.noreply.github.com> Date: Thu, 26 Feb 2026 07:59:10 +0200 Subject: [PATCH 3/9] Use the new macros in sshd_use_strong_kex rule --- .../sshd_use_strong_kex/ansible/shared.yml | 20 +- .../sshd_use_strong_kex/bash/shared.sh | 21 ++- .../sshd_use_strong_kex/oval/sle16.xml | 171 ++++++++++++++++++ ...rect_value_etc_sshd_config_drop_in.pass.sh | 7 + ...lue_in_usr_etc_sshd_config_present.fail.sh | 7 + .../correct_value_usr_etc_sshd_config.pass.sh | 7 + ..._value_usr_etc_sshd_config_drop_in.pass.sh | 6 + .../sshd_use_strong_kex/tests/include.sh | 15 ++ ...rong_value_etc_sshd_config_drop_in.fail.sh | 6 + .../wrong_value_usr_etc_sshd_config.fail.sh | 6 + ..._value_usr_etc_sshd_config_drop_in.fail.sh | 6 + 11 files changed, 269 insertions(+), 3 deletions(-) create mode 100644 linux_os/guide/services/ssh/ssh_server/sshd_use_strong_kex/oval/sle16.xml create mode 100644 linux_os/guide/services/ssh/ssh_server/sshd_use_strong_kex/tests/correct_value_etc_sshd_config_drop_in.pass.sh create mode 100644 linux_os/guide/services/ssh/ssh_server/sshd_use_strong_kex/tests/correct_value_in_usr_etc_sshd_config_present.fail.sh create mode 100644 linux_os/guide/services/ssh/ssh_server/sshd_use_strong_kex/tests/correct_value_usr_etc_sshd_config.pass.sh create mode 100644 linux_os/guide/services/ssh/ssh_server/sshd_use_strong_kex/tests/correct_value_usr_etc_sshd_config_drop_in.pass.sh create mode 100644 linux_os/guide/services/ssh/ssh_server/sshd_use_strong_kex/tests/include.sh create mode 100644 linux_os/guide/services/ssh/ssh_server/sshd_use_strong_kex/tests/wrong_value_etc_sshd_config_drop_in.fail.sh create mode 100644 linux_os/guide/services/ssh/ssh_server/sshd_use_strong_kex/tests/wrong_value_usr_etc_sshd_config.fail.sh create mode 100644 linux_os/guide/services/ssh/ssh_server/sshd_use_strong_kex/tests/wrong_value_usr_etc_sshd_config_drop_in.fail.sh diff --git a/linux_os/guide/services/ssh/ssh_server/sshd_use_strong_kex/ansible/shared.yml b/linux_os/guide/services/ssh/ssh_server/sshd_use_strong_kex/ansible/shared.yml index fc2a78f3d79c..82b732e0e66b 100644 --- a/linux_os/guide/services/ssh/ssh_server/sshd_use_strong_kex/ansible/shared.yml +++ b/linux_os/guide/services/ssh/ssh_server/sshd_use_strong_kex/ansible/shared.yml @@ -6,4 +6,22 @@ {{{ ansible_instantiate_variables("sshd_strong_kex") }}} -{{{ ansible_sshd_set(parameter="KexAlgorithms", value="{{ sshd_strong_kex }}", config_is_distributed=sshd_distributed_config, rule_title=rule_title) }}} +{{%- if product == 'sle16' -%}} + {{{ + ansible_sshd_set_usr( + parameter="KexAlgorithms", + value="{{ sshd_strong_kex }}", + copy_defaults='true', + rule_title=rule_title + ) + }}} +{{%- else -%}} + {{{ + ansible_sshd_set( + parameter="KexAlgorithms", + value="{{ sshd_strong_kex }}", + config_is_distributed=sshd_distributed_config, + rule_title=rule_title + ) + }}} +{{%- endif -%}} diff --git a/linux_os/guide/services/ssh/ssh_server/sshd_use_strong_kex/bash/shared.sh b/linux_os/guide/services/ssh/ssh_server/sshd_use_strong_kex/bash/shared.sh index e5a56dbfc6ec..de205aedd670 100644 --- a/linux_os/guide/services/ssh/ssh_server/sshd_use_strong_kex/bash/shared.sh +++ b/linux_os/guide/services/ssh/ssh_server/sshd_use_strong_kex/bash/shared.sh @@ -5,5 +5,22 @@ # disruption = low {{{ bash_instantiate_variables("sshd_strong_kex") }}} -{{{ bash_sshd_remediation(parameter="KexAlgorithms", value="$sshd_strong_kex", config_is_distributed=sshd_distributed_config, rule_id=rule_id) }}} - +{{%- if product == 'sle16' -%}} + {{{ + bash_sshd_remediation_usr( + parameter="KexAlgorithms", + value="$sshd_strong_kex", + copy_defaults=true, + rule_id=rule_id + ) + }}} +{{%- else -%}} + {{{ + bash_sshd_remediation( + parameter="KexAlgorithms", + value="$sshd_strong_kex", + config_is_distributed=sshd_distributed_config, + rule_id=rule_id + ) + }}} +{{%- endif -%}} diff --git a/linux_os/guide/services/ssh/ssh_server/sshd_use_strong_kex/oval/sle16.xml b/linux_os/guide/services/ssh/ssh_server/sshd_use_strong_kex/oval/sle16.xml new file mode 100644 index 000000000000..d6c8fb2432cf --- /dev/null +++ b/linux_os/guide/services/ssh/ssh_server/sshd_use_strong_kex/oval/sle16.xml @@ -0,0 +1,171 @@ + + + {{{ oval_metadata("Limit the Key Exchange Algorithms to those which are FIPS-approved.", rule_title=rule_title) }}} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ^/etc/ssh/sshd_config + + + + + + + + + var_sshd_config_kex + + + + + + + + + + + + + + /etc/ssh/sshd_config + ^[\s]*(?i)KexAlgorithms(?-i)[\s]+([\w,-@]+)+[\s]*(?:#.*)?$ + 1 + + + + + + + + + + var_sshd_config_kex_usr + + + + + + + + + + + + + + /usr/etc/ssh/sshd_config + ^[\s]*(?i)KexAlgorithms(?-i)[\s]+([\w,-@]+)+[\s]*(?:#.*)?$ + 1 + + + + + + + + + var_sshd_config_kex_config_dir + + + + + + + + ^(/etc/ssh/sshd_config.d|/usr/etc/ssh/sshd_config.d) + .*\.conf$ + ^[\s]*(?i)KexAlgorithms(?-i)[\s]+([\w,-@]+)+[\s]*(?:#.*)?$ + 1 + + + + + + + + + + + + + + + obj_sshd_config_kex + obj_sshd_config_kex_config_dir + + + + + + + + + + obj_sshd_config_kex_usr + obj_sshd_config_kex_config_dir + + + + + + + + + + + diff --git a/linux_os/guide/services/ssh/ssh_server/sshd_use_strong_kex/tests/correct_value_etc_sshd_config_drop_in.pass.sh b/linux_os/guide/services/ssh/ssh_server/sshd_use_strong_kex/tests/correct_value_etc_sshd_config_drop_in.pass.sh new file mode 100644 index 000000000000..7a794f42a4b1 --- /dev/null +++ b/linux_os/guide/services/ssh/ssh_server/sshd_use_strong_kex/tests/correct_value_etc_sshd_config_drop_in.pass.sh @@ -0,0 +1,7 @@ +#!/bin/bash +# platform = SUSE Linux Enterprise 16 +# variables = sshd_strong_kex=curve25519-sha256,curve25519-sha256@libssh.org,ecdh-sha2-nistp256 + +source include.sh + +echo "KexAlgorithms curve25519-sha256,curve25519-sha256@libssh.org,ecdh-sha2-nistp256" >> /etc/ssh/sshd_config.d/01-complianceascode.conf diff --git a/linux_os/guide/services/ssh/ssh_server/sshd_use_strong_kex/tests/correct_value_in_usr_etc_sshd_config_present.fail.sh b/linux_os/guide/services/ssh/ssh_server/sshd_use_strong_kex/tests/correct_value_in_usr_etc_sshd_config_present.fail.sh new file mode 100644 index 000000000000..9c44448054f2 --- /dev/null +++ b/linux_os/guide/services/ssh/ssh_server/sshd_use_strong_kex/tests/correct_value_in_usr_etc_sshd_config_present.fail.sh @@ -0,0 +1,7 @@ +#!/bin/bash +# platform = SUSE Linux Enterprise 16 +# variables = sshd_strong_kex=curve25519-sha256,curve25519-sha256@libssh.org,ecdh-sha2-nistp256 +source include.sh + +touch /etc/ssh/sshd_config +echo "KexAlgorithms curve25519-sha256,curve25519-sha256@libssh.org,ecdh-sha2-nistp256" >> /usr/etc/ssh/sshd_config diff --git a/linux_os/guide/services/ssh/ssh_server/sshd_use_strong_kex/tests/correct_value_usr_etc_sshd_config.pass.sh b/linux_os/guide/services/ssh/ssh_server/sshd_use_strong_kex/tests/correct_value_usr_etc_sshd_config.pass.sh new file mode 100644 index 000000000000..0577aad9bd14 --- /dev/null +++ b/linux_os/guide/services/ssh/ssh_server/sshd_use_strong_kex/tests/correct_value_usr_etc_sshd_config.pass.sh @@ -0,0 +1,7 @@ +#!/bin/bash +# platform = SUSE Linux Enterprise 16 +# variables = sshd_strong_kex=curve25519-sha256,curve25519-sha256@libssh.org,ecdh-sha2-nistp256 + +source include.sh + +echo "KexAlgorithms curve25519-sha256,curve25519-sha256@libssh.org,ecdh-sha2-nistp256" >> /usr/etc/ssh/sshd_config diff --git a/linux_os/guide/services/ssh/ssh_server/sshd_use_strong_kex/tests/correct_value_usr_etc_sshd_config_drop_in.pass.sh b/linux_os/guide/services/ssh/ssh_server/sshd_use_strong_kex/tests/correct_value_usr_etc_sshd_config_drop_in.pass.sh new file mode 100644 index 000000000000..ab24bed01ba1 --- /dev/null +++ b/linux_os/guide/services/ssh/ssh_server/sshd_use_strong_kex/tests/correct_value_usr_etc_sshd_config_drop_in.pass.sh @@ -0,0 +1,6 @@ +#!/bin/bash +# platform = SUSE Linux Enterprise 16 +# variables = sshd_strong_kex=curve25519-sha256,curve25519-sha256@libssh.org,ecdh-sha2-nistp256 +source include.sh + +echo "KexAlgorithms curve25519-sha256,curve25519-sha256@libssh.org,ecdh-sha2-nistp256" >> /usr/etc/ssh/sshd_config.d/01-complianceascode.conf diff --git a/linux_os/guide/services/ssh/ssh_server/sshd_use_strong_kex/tests/include.sh b/linux_os/guide/services/ssh/ssh_server/sshd_use_strong_kex/tests/include.sh new file mode 100644 index 000000000000..179b7b36e808 --- /dev/null +++ b/linux_os/guide/services/ssh/ssh_server/sshd_use_strong_kex/tests/include.sh @@ -0,0 +1,15 @@ +#!/bin/bash + +declare -a SSHD_PATHS=("/etc/ssh/sshd_config") +{{% if product == 'sle16' %}} +SSHD_PATHS+=("/usr/etc/ssh/sshd_config" /usr/etc/ssh/sshd_config.d/* /etc/ssh/sshd_config.d/*) +{{% endif %}} +# clean up configurations +sed -i '/^KexAlgorithms.*/d' "${SSHD_PATHS[@]}" + +# restore to defaults for sle16 +{{% if product == 'sle16' %}} +if [ -e "/etc/ssh/sshd_config" ] ; then + rm /etc/ssh/sshd_config +fi +{{% endif %}} diff --git a/linux_os/guide/services/ssh/ssh_server/sshd_use_strong_kex/tests/wrong_value_etc_sshd_config_drop_in.fail.sh b/linux_os/guide/services/ssh/ssh_server/sshd_use_strong_kex/tests/wrong_value_etc_sshd_config_drop_in.fail.sh new file mode 100644 index 000000000000..a1a7b95bafff --- /dev/null +++ b/linux_os/guide/services/ssh/ssh_server/sshd_use_strong_kex/tests/wrong_value_etc_sshd_config_drop_in.fail.sh @@ -0,0 +1,6 @@ +#!/bin/bash +# platform = SUSE Linux Enterprise 16 +# variables = sshd_strong_kex=curve25519-sha256,curve25519-sha256@libssh.org,ecdh-sha2-nistp256 +source include.sh + +echo "KexAlgorithms diffie-hellman-group-exchange-sha1" >> /etc/ssh/sshd_config.d/01-complianceascode.conf diff --git a/linux_os/guide/services/ssh/ssh_server/sshd_use_strong_kex/tests/wrong_value_usr_etc_sshd_config.fail.sh b/linux_os/guide/services/ssh/ssh_server/sshd_use_strong_kex/tests/wrong_value_usr_etc_sshd_config.fail.sh new file mode 100644 index 000000000000..df52b52f680d --- /dev/null +++ b/linux_os/guide/services/ssh/ssh_server/sshd_use_strong_kex/tests/wrong_value_usr_etc_sshd_config.fail.sh @@ -0,0 +1,6 @@ +#!/bin/bash +# platform = SUSE Linux Enterprise 16 +# variables = sshd_strong_kex=curve25519-sha256,curve25519-sha256@libssh.org,ecdh-sha2-nistp256 +source include.sh + +echo "KexAlgorithms diffie-hellman-group-exchange-sha1" >> /usr/etc/ssh/sshd_config diff --git a/linux_os/guide/services/ssh/ssh_server/sshd_use_strong_kex/tests/wrong_value_usr_etc_sshd_config_drop_in.fail.sh b/linux_os/guide/services/ssh/ssh_server/sshd_use_strong_kex/tests/wrong_value_usr_etc_sshd_config_drop_in.fail.sh new file mode 100644 index 000000000000..2a71c2a3bd53 --- /dev/null +++ b/linux_os/guide/services/ssh/ssh_server/sshd_use_strong_kex/tests/wrong_value_usr_etc_sshd_config_drop_in.fail.sh @@ -0,0 +1,6 @@ +#!/bin/bash +# platform = SUSE Linux Enterprise 16 +# variables = sshd_strong_kex=curve25519-sha256,curve25519-sha256@libssh.org,ecdh-sha2-nistp256 +source include.sh + +echo "KexAlgorithms diffie-hellman-group-exchange-sha1" >> /usr/etc/ssh/sshd_config.d/01-complianceascode.conf From 0258f34e38e2c2e3e3c57d00e632066d1f917326 Mon Sep 17 00:00:00 2001 From: teacup-on-rockingchair <315160+teacup-on-rockingchair@users.noreply.github.com> Date: Thu, 26 Feb 2026 08:02:20 +0200 Subject: [PATCH 4/9] For sle16 enhance the check and the tests to cover cases with sshd_config in /usr and subfolders --- .../sshd_limit_user_access/oval/sle16.xml | 100 ++++++++++++++++++ .../tests/allow_groups.pass.sh | 2 +- ...low_groups_etc_ssh_sshd_config_dir.pass.sh | 4 + .../tests/allow_users.pass.sh | 2 +- .../tests/allow_users_groups.pass.sh | 2 +- ...llow_users_usr_etc_ssh_sshd_config.pass.sh | 5 + .../sshd_limit_user_access/tests/common.sh | 15 +++ .../deny_group_in_usr_etc_missing.fail.sh | 7 ++ .../tests/deny_groups.pass.sh | 2 +- .../tests/deny_users.pass.sh | 2 +- .../tests/deny_users_groups.pass.sh | 2 +- ..._users_usr_etc_ssh_sshd_config_dir.pass.sh | 5 + .../tests/empty_groups.fail.sh | 2 +- .../tests/empty_users.fail.sh | 2 +- .../tests/no_entry.fail.sh | 2 +- 15 files changed, 145 insertions(+), 9 deletions(-) create mode 100644 linux_os/guide/services/ssh/ssh_server/sshd_limit_user_access/oval/sle16.xml create mode 100644 linux_os/guide/services/ssh/ssh_server/sshd_limit_user_access/tests/allow_groups_etc_ssh_sshd_config_dir.pass.sh create mode 100644 linux_os/guide/services/ssh/ssh_server/sshd_limit_user_access/tests/allow_users_usr_etc_ssh_sshd_config.pass.sh create mode 100644 linux_os/guide/services/ssh/ssh_server/sshd_limit_user_access/tests/common.sh create mode 100644 linux_os/guide/services/ssh/ssh_server/sshd_limit_user_access/tests/deny_group_in_usr_etc_missing.fail.sh create mode 100644 linux_os/guide/services/ssh/ssh_server/sshd_limit_user_access/tests/deny_users_usr_etc_ssh_sshd_config_dir.pass.sh diff --git a/linux_os/guide/services/ssh/ssh_server/sshd_limit_user_access/oval/sle16.xml b/linux_os/guide/services/ssh/ssh_server/sshd_limit_user_access/oval/sle16.xml new file mode 100644 index 000000000000..8dce53384a11 --- /dev/null +++ b/linux_os/guide/services/ssh/ssh_server/sshd_limit_user_access/oval/sle16.xml @@ -0,0 +1,100 @@ +{{% macro test_sshd_lineinfile(filepath, param, id) %}} +{{%- set object_id = filepath | replace("/", "_") | replace("-", "_") | replace(".", "_") -%}} + + + + + ^{{{ filepath }}} + (?i)^[ ]*{{{ param }}}[ ]+((?:[^ \n]+[ ]*)+)$ + 1 + +{{% endmacro %}} + +{{% macro test_sshd_lineindir(filepath, param, id) %}} +{{%- set object_id = filepath | replace("/", "_") | replace("-", "_") | replace(".", "_") -%}} + + + + + {{{ filepath }}} + .*\.conf$ + (?i)^[ ]*{{{ param }}}[ ]+((?:[^ \n]+[ ]*)+)$ + 1 + +{{% endmacro %}} + + + + {{{ oval_metadata("One of the following parameters of the sshd configuration file is set: AllowUsers, DenyUsers, AllowGroups, DenyGroups.", rule_title=rule_title) }}} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ^/etc/ssh/sshd_config + + + {{{ test_sshd_lineinfile("/etc/ssh/sshd_config", "AllowUsers", "test_allow_user_is_configured_etc_ssh_sshdconfig") }}} + {{{ test_sshd_lineinfile("/etc/ssh/sshd_config", "AllowGroups", "test_allow_groups_is_configured_etc_ssh_sshdconfig") }}} + {{{ test_sshd_lineinfile("/etc/ssh/sshd_config", "DenyUsers", "test_deny_users_is_configured_etc_ssh_sshdconfig") }}} + {{{ test_sshd_lineinfile("/etc/ssh/sshd_config", "DenyGroups", "test_deny_groups_is_configured_etc_ssh_sshdconfig") }}} + + {{{ test_sshd_lineinfile("/usr/etc/ssh/sshd_config", "AllowUsers", "test_allow_user_is_configured_usr_etc_ssh_sshdconfig") }}} + {{{ test_sshd_lineinfile("/usr/etc/ssh/sshd_config", "AllowGroups", "test_allow_groups_is_configured_usr_etc_ssh_sshdconfig") }}} + {{{ test_sshd_lineinfile("/usr/etc/ssh/sshd_config", "DenyUsers", "test_deny_users_is_configured_usr_etc_ssh_sshdconfig") }}} + {{{ test_sshd_lineinfile("/usr/etc/ssh/sshd_config", "DenyGroups", "test_deny_groups_is_configured_usr_etc_ssh_sshdconfig") }}} + + {{{ test_sshd_lineindir("/etc/ssh/sshd_config.d", "AllowUsers", "test_allow_user_is_configured_etc_ssh_sshdconfig_dir") }}} + {{{ test_sshd_lineindir("/etc/ssh/sshd_config.d", "AllowGroups", "test_allow_groups_is_configured_etc_ssh_sshdconfig_dir") }}} + {{{ test_sshd_lineindir("/etc/ssh/sshd_config.d", "DenyUsers", "test_deny_users_is_configured_etc_ssh_sshdconfig_dir") }}} + {{{ test_sshd_lineindir("/etc/ssh/sshd_config.d", "DenyGroups", "test_deny_groups_is_configured_etc_ssh_sshdconfig_dir") }}} + + {{{ test_sshd_lineindir("/usr/etc/ssh/sshd_config.d", "AllowUsers", "test_allow_user_is_configured_usr_etc_ssh_sshdconfig_dir") }}} + {{{ test_sshd_lineindir("/usr/etc/ssh/sshd_config.d", "AllowGroups", "test_allow_groups_is_configured_usr_etc_ssh_sshdconfig_dir") }}} + {{{ test_sshd_lineindir("/usr/etc/ssh/sshd_config.d", "DenyUsers", "test_deny_users_is_configured_usr_etc_ssh_sshdconfig_dir") }}} + {{{ test_sshd_lineindir("/usr/etc/ssh/sshd_config.d", "DenyGroups", "test_deny_groups_is_configured_usr_etc_ssh_sshdconfig_dir") }}} + diff --git a/linux_os/guide/services/ssh/ssh_server/sshd_limit_user_access/tests/allow_groups.pass.sh b/linux_os/guide/services/ssh/ssh_server/sshd_limit_user_access/tests/allow_groups.pass.sh index 4a5255dc3c9f..0794a24e80a7 100644 --- a/linux_os/guide/services/ssh/ssh_server/sshd_limit_user_access/tests/allow_groups.pass.sh +++ b/linux_os/guide/services/ssh/ssh_server/sshd_limit_user_access/tests/allow_groups.pass.sh @@ -1,4 +1,4 @@ #!/bin/bash -find /etc/ssh/sshd_config* -type f -print0 | xargs -0 sed -i '/^(Allow|Deny)(Users|Groups).*/d' +source common.sh echo "AllowGroups testgroup1 testgroup2 testgroup3" >> /etc/ssh/sshd_config diff --git a/linux_os/guide/services/ssh/ssh_server/sshd_limit_user_access/tests/allow_groups_etc_ssh_sshd_config_dir.pass.sh b/linux_os/guide/services/ssh/ssh_server/sshd_limit_user_access/tests/allow_groups_etc_ssh_sshd_config_dir.pass.sh new file mode 100644 index 000000000000..2f5b763698b1 --- /dev/null +++ b/linux_os/guide/services/ssh/ssh_server/sshd_limit_user_access/tests/allow_groups_etc_ssh_sshd_config_dir.pass.sh @@ -0,0 +1,4 @@ +#!/bin/bash +# platform = SUSE Linux Enterprise 16 +source common.sh +echo "AllowGroups group" >> /etc/ssh/sshd_config.d/01-complianceascode-reinforce-os-defaults.conf diff --git a/linux_os/guide/services/ssh/ssh_server/sshd_limit_user_access/tests/allow_users.pass.sh b/linux_os/guide/services/ssh/ssh_server/sshd_limit_user_access/tests/allow_users.pass.sh index 9bde6d56cd92..520d0a048faa 100644 --- a/linux_os/guide/services/ssh/ssh_server/sshd_limit_user_access/tests/allow_users.pass.sh +++ b/linux_os/guide/services/ssh/ssh_server/sshd_limit_user_access/tests/allow_users.pass.sh @@ -1,4 +1,4 @@ #!/bin/bash -find /etc/ssh/sshd_config* -type f -print0 | xargs -0 sed -i '/^(Allow|Deny)(Users|Groups).*/d' +source common.sh echo "AllowUsers testuser1 testuser2 testuser3" >> /etc/ssh/sshd_config diff --git a/linux_os/guide/services/ssh/ssh_server/sshd_limit_user_access/tests/allow_users_groups.pass.sh b/linux_os/guide/services/ssh/ssh_server/sshd_limit_user_access/tests/allow_users_groups.pass.sh index 0b35e7039585..6d6bd04f37b6 100644 --- a/linux_os/guide/services/ssh/ssh_server/sshd_limit_user_access/tests/allow_users_groups.pass.sh +++ b/linux_os/guide/services/ssh/ssh_server/sshd_limit_user_access/tests/allow_users_groups.pass.sh @@ -1,5 +1,5 @@ #!/bin/bash -find /etc/ssh/sshd_config* -type f -print0 | xargs -0 sed -i '/^(Allow|Deny)(Users|Groups).*/d' +source common.sh echo "AllowUsers testuser1 testuser2 testuser3" >> /etc/ssh/sshd_config echo "AllowGroups testgroup1 testgroup2 testgroup3" >> /etc/ssh/sshd_config diff --git a/linux_os/guide/services/ssh/ssh_server/sshd_limit_user_access/tests/allow_users_usr_etc_ssh_sshd_config.pass.sh b/linux_os/guide/services/ssh/ssh_server/sshd_limit_user_access/tests/allow_users_usr_etc_ssh_sshd_config.pass.sh new file mode 100644 index 000000000000..04b090c1a148 --- /dev/null +++ b/linux_os/guide/services/ssh/ssh_server/sshd_limit_user_access/tests/allow_users_usr_etc_ssh_sshd_config.pass.sh @@ -0,0 +1,5 @@ +#!/bin/bash +# platform = SUSE Linux Enterprise 16 +source common.sh + +echo "AllowUsers testuser1 testuser2 testuser3" >> /usr/etc/ssh/sshd_config diff --git a/linux_os/guide/services/ssh/ssh_server/sshd_limit_user_access/tests/common.sh b/linux_os/guide/services/ssh/ssh_server/sshd_limit_user_access/tests/common.sh new file mode 100644 index 000000000000..3c936c2321ce --- /dev/null +++ b/linux_os/guide/services/ssh/ssh_server/sshd_limit_user_access/tests/common.sh @@ -0,0 +1,15 @@ +#!/bin/bash + +declare -a SSHD_PATHS=("/etc/ssh/sshd_config") +{{% if product == 'sle16' %}} +SSHD_PATHS+=("/usr/etc/ssh/sshd_config" /usr/etc/ssh/sshd_config.d/* /etc/ssh/sshd_config.d/*) +{{% endif %}} +# clean up configurations +sed -i '/^(Allow|Deny)(Users|Groups).*/d' "${SSHD_PATHS[@]}" + +# restore to defaults for sle16 +{{% if product == 'sle16' %}} +if [ -e "/etc/ssh/sshd_config" ] ; then + rm /etc/ssh/sshd_config +fi +{{% endif %}} diff --git a/linux_os/guide/services/ssh/ssh_server/sshd_limit_user_access/tests/deny_group_in_usr_etc_missing.fail.sh b/linux_os/guide/services/ssh/ssh_server/sshd_limit_user_access/tests/deny_group_in_usr_etc_missing.fail.sh new file mode 100644 index 000000000000..6d23da947c9d --- /dev/null +++ b/linux_os/guide/services/ssh/ssh_server/sshd_limit_user_access/tests/deny_group_in_usr_etc_missing.fail.sh @@ -0,0 +1,7 @@ +#!/bin/bash +# remediation = none +# platform = SUSE Linux Enterprise 16 +source common.sh + +touch /etc/ssh/sshd_config +echo "DenyGroups testgroup" >> /usr/etc/ssh/sshd_config diff --git a/linux_os/guide/services/ssh/ssh_server/sshd_limit_user_access/tests/deny_groups.pass.sh b/linux_os/guide/services/ssh/ssh_server/sshd_limit_user_access/tests/deny_groups.pass.sh index a324d89e397d..16f6e9d3d58f 100644 --- a/linux_os/guide/services/ssh/ssh_server/sshd_limit_user_access/tests/deny_groups.pass.sh +++ b/linux_os/guide/services/ssh/ssh_server/sshd_limit_user_access/tests/deny_groups.pass.sh @@ -1,4 +1,4 @@ #!/bin/bash -find /etc/ssh/sshd_config* -type f -print0 | xargs -0 sed -i '/^(Allow|Deny)(Users|Groups).*/d' +source common.sh echo "DenyGroups testgroup1 testgroup2 testgroup3" >> /etc/ssh/sshd_config diff --git a/linux_os/guide/services/ssh/ssh_server/sshd_limit_user_access/tests/deny_users.pass.sh b/linux_os/guide/services/ssh/ssh_server/sshd_limit_user_access/tests/deny_users.pass.sh index 35c7f65d7514..adb157baddd2 100644 --- a/linux_os/guide/services/ssh/ssh_server/sshd_limit_user_access/tests/deny_users.pass.sh +++ b/linux_os/guide/services/ssh/ssh_server/sshd_limit_user_access/tests/deny_users.pass.sh @@ -1,4 +1,4 @@ #!/bin/bash -find /etc/ssh/sshd_config* -type f -print0 | xargs -0 sed -i '/^(Allow|Deny)(Users|Groups).*/d' +source common.sh echo "DenyUsers testuser1 testuser2 testuser3" >> /etc/ssh/sshd_config diff --git a/linux_os/guide/services/ssh/ssh_server/sshd_limit_user_access/tests/deny_users_groups.pass.sh b/linux_os/guide/services/ssh/ssh_server/sshd_limit_user_access/tests/deny_users_groups.pass.sh index fc55098614a0..ebe08fb81dea 100644 --- a/linux_os/guide/services/ssh/ssh_server/sshd_limit_user_access/tests/deny_users_groups.pass.sh +++ b/linux_os/guide/services/ssh/ssh_server/sshd_limit_user_access/tests/deny_users_groups.pass.sh @@ -1,5 +1,5 @@ #!/bin/bash -find /etc/ssh/sshd_config* -type f -print0 | xargs -0 sed -i '/^(Allow|Deny)(Users|Groups).*/d' +source common.sh echo "DenyUsers testuser1 testuser2 testuser3" >> /etc/ssh/sshd_config echo "DenyGroups testgroup1 testgroup2 testgroup3" >> /etc/ssh/sshd_config diff --git a/linux_os/guide/services/ssh/ssh_server/sshd_limit_user_access/tests/deny_users_usr_etc_ssh_sshd_config_dir.pass.sh b/linux_os/guide/services/ssh/ssh_server/sshd_limit_user_access/tests/deny_users_usr_etc_ssh_sshd_config_dir.pass.sh new file mode 100644 index 000000000000..bee5f9991a7c --- /dev/null +++ b/linux_os/guide/services/ssh/ssh_server/sshd_limit_user_access/tests/deny_users_usr_etc_ssh_sshd_config_dir.pass.sh @@ -0,0 +1,5 @@ +#!/bin/bash +# platform = SUSE Linux Enterprise 16 +source common.sh + +echo "DenyUsers user" >> /usr/etc/ssh/sshd_config.d/01-complianceascode-reinforce-os-defaults.conf diff --git a/linux_os/guide/services/ssh/ssh_server/sshd_limit_user_access/tests/empty_groups.fail.sh b/linux_os/guide/services/ssh/ssh_server/sshd_limit_user_access/tests/empty_groups.fail.sh index 2f735305d2c5..1f6c11f7a4d1 100644 --- a/linux_os/guide/services/ssh/ssh_server/sshd_limit_user_access/tests/empty_groups.fail.sh +++ b/linux_os/guide/services/ssh/ssh_server/sshd_limit_user_access/tests/empty_groups.fail.sh @@ -1,6 +1,6 @@ #!/bin/bash # remediation = none -find /etc/ssh/sshd_config* -type f -print0 | xargs -0 sed -i '/^(Allow|Deny)(Users|Groups).*/d' +source common.sh echo "AllowGroups " >> /etc/ssh/sshd_config echo "DenyGroups " >> /etc/ssh/sshd_config diff --git a/linux_os/guide/services/ssh/ssh_server/sshd_limit_user_access/tests/empty_users.fail.sh b/linux_os/guide/services/ssh/ssh_server/sshd_limit_user_access/tests/empty_users.fail.sh index 4affe4b4d598..55ea7d01cde3 100644 --- a/linux_os/guide/services/ssh/ssh_server/sshd_limit_user_access/tests/empty_users.fail.sh +++ b/linux_os/guide/services/ssh/ssh_server/sshd_limit_user_access/tests/empty_users.fail.sh @@ -1,6 +1,6 @@ #!/bin/bash # remediation = none -find /etc/ssh/sshd_config* -type f -print0 | xargs -0 sed -i '/^(Allow|Deny)(Users|Groups).*/d' +source common.sh echo "AllowUsers " >> /etc/ssh/sshd_config echo "DenyUsers " >> /etc/ssh/sshd_config diff --git a/linux_os/guide/services/ssh/ssh_server/sshd_limit_user_access/tests/no_entry.fail.sh b/linux_os/guide/services/ssh/ssh_server/sshd_limit_user_access/tests/no_entry.fail.sh index bc8a67e7fbad..8ab213a16a18 100644 --- a/linux_os/guide/services/ssh/ssh_server/sshd_limit_user_access/tests/no_entry.fail.sh +++ b/linux_os/guide/services/ssh/ssh_server/sshd_limit_user_access/tests/no_entry.fail.sh @@ -1,4 +1,4 @@ #!/bin/bash # remediation = none -find /etc/ssh/sshd_config* -type f -print0 | xargs -0 sed -i '/^(Allow|Deny)(Users|Groups).*/d' +source common.sh From 4e938f74b8afb37879c54fc39ab2bccdfbb6e4b6 Mon Sep 17 00:00:00 2001 From: teacup-on-rockingchair <315160+teacup-on-rockingchair@users.noreply.github.com> Date: Thu, 26 Feb 2026 08:04:26 +0200 Subject: [PATCH 5/9] For sle16 enhance the check to cover cases with sshd_config in /usr and subfolders for sshd_set_idle_timeout rule --- .../sshd_set_idle_timeout/oval/sle16.xml | 153 ++++++++++++++++++ 1 file changed, 153 insertions(+) create mode 100644 linux_os/guide/services/ssh/ssh_server/sshd_set_idle_timeout/oval/sle16.xml diff --git a/linux_os/guide/services/ssh/ssh_server/sshd_set_idle_timeout/oval/sle16.xml b/linux_os/guide/services/ssh/ssh_server/sshd_set_idle_timeout/oval/sle16.xml new file mode 100644 index 000000000000..9c2ae2f9a78a --- /dev/null +++ b/linux_os/guide/services/ssh/ssh_server/sshd_set_idle_timeout/oval/sle16.xml @@ -0,0 +1,153 @@ + + + {{{ oval_metadata("The SSH idle timeout interval should be set to an appropriate value.", rule_title=rule_title) }}} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ^/etc/ssh/sshd_config + + + + + + + + + + /etc/ssh/sshd_config + ^[\s]*(?i)ClientAliveInterval[\s]+(\d+)[\s]*(?:#.*)?$ + 1 + + + + + + + + + + /usr/etc/ssh/sshd_config + ^[\s]*(?i)ClientAliveInterval[\s]+(\d+)[\s]*(?:#.*)?$ + 1 + + + + + + + + + + /etc/ssh/sshd_config.d + .*\.conf$ + ^[\s]*(?i)ClientAliveInterval[\s]+(\d+)[\s]*(?:#.*)?$ + 1 + + + + + + + + + + /usr/etc/ssh/sshd_config.d + .*\.conf$ + ^[\s]*(?i)ClientAliveInterval[\s]+(\d+)[\s]*(?:#.*)?$ + 1 + + + + + + + + 0 + + + + + + + + + + object_sshd_idle_timeout_etc + + + object_sshd_idle_timeout_config_dir + object_sshd_idle_timeout_usr_config_dir + + + + + + + + + + + + object_sshd_idle_timeout_usr + + + object_sshd_idle_timeout_config_dir + object_sshd_idle_timeout_usr_config_dir + + + + + + + From 5aedfa62ddff7f6a175ee39f885ad66435255493 Mon Sep 17 00:00:00 2001 From: teacup-on-rockingchair <315160+teacup-on-rockingchair@users.noreply.github.com> Date: Thu, 26 Feb 2026 08:05:10 +0200 Subject: [PATCH 6/9] For sle16 enhance the check to cover cases with sshd_config in /usr and subfolders for sshd_set_login_grace_time rule --- .../sshd_set_login_grace_time/oval/sle16.xml | 153 ++++++++++++++++++ ...rect_value_etc_sshd_config_drop_in.pass.sh | 5 + ...lue_in_usr_etc_sshd_config_present.fail.sh | 6 + .../correct_value_usr_etc_sshd_config.pass.sh | 5 + ..._value_usr_etc_sshd_config_drop_in.pass.sh | 5 + .../tests/include.sh | 15 ++ .../tests/lower_bound.pass.sh | 2 +- .../tests/no_limit.fail.sh | 2 +- .../tests/too_high.fail.sh | 2 +- .../too_high_etc_sshd_config_drop_in.fail.sh | 5 + .../too_high_usr_etc_sshd_config.fail.sh | 5 + ...o_high_usr_etc_sshd_config_drop_in.fail.sh | 5 + 12 files changed, 207 insertions(+), 3 deletions(-) create mode 100644 linux_os/guide/services/ssh/ssh_server/sshd_set_login_grace_time/oval/sle16.xml create mode 100644 linux_os/guide/services/ssh/ssh_server/sshd_set_login_grace_time/tests/correct_value_etc_sshd_config_drop_in.pass.sh create mode 100644 linux_os/guide/services/ssh/ssh_server/sshd_set_login_grace_time/tests/correct_value_in_usr_etc_sshd_config_present.fail.sh create mode 100644 linux_os/guide/services/ssh/ssh_server/sshd_set_login_grace_time/tests/correct_value_usr_etc_sshd_config.pass.sh create mode 100644 linux_os/guide/services/ssh/ssh_server/sshd_set_login_grace_time/tests/correct_value_usr_etc_sshd_config_drop_in.pass.sh create mode 100644 linux_os/guide/services/ssh/ssh_server/sshd_set_login_grace_time/tests/include.sh create mode 100644 linux_os/guide/services/ssh/ssh_server/sshd_set_login_grace_time/tests/too_high_etc_sshd_config_drop_in.fail.sh create mode 100644 linux_os/guide/services/ssh/ssh_server/sshd_set_login_grace_time/tests/too_high_usr_etc_sshd_config.fail.sh create mode 100644 linux_os/guide/services/ssh/ssh_server/sshd_set_login_grace_time/tests/too_high_usr_etc_sshd_config_drop_in.fail.sh diff --git a/linux_os/guide/services/ssh/ssh_server/sshd_set_login_grace_time/oval/sle16.xml b/linux_os/guide/services/ssh/ssh_server/sshd_set_login_grace_time/oval/sle16.xml new file mode 100644 index 000000000000..23137efd78b8 --- /dev/null +++ b/linux_os/guide/services/ssh/ssh_server/sshd_set_login_grace_time/oval/sle16.xml @@ -0,0 +1,153 @@ + + + {{{ oval_metadata("The SSH number seconds for login grace time should be set to an appropriate value.", rule_title=rule_title) }}} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ^/etc/ssh/sshd_config + + + + + + + + + + /etc/ssh/sshd_config + ^[\s]*(?i)LoginGraceTime[\s]+(\d+)[\s]*(?:#.*)?$ + 1 + + + + + + + + + + /usr/etc/ssh/sshd_config + ^[\s]*(?i)LoginGraceTime[\s]+(\d+)[\s]*(?:#.*)?$ + 1 + + + + + + + + + + /etc/ssh/sshd_config.d + .*\.conf$ + ^[\s]*(?i)LoginGraceTime[\s]+(\d+)[\s]*(?:#.*)?$ + 1 + + + + + + + + + + /usr/etc/ssh/sshd_config.d + .*\.conf$ + ^[\s]*(?i)LoginGraceTime[\s]+(\d+)[\s]*(?:#.*)?$ + 1 + + + + + + + + 0 + + + + + + + + + + object_sshd_login_grace_time_etc + + + object_sshd_login_grace_time_config_dir + object_sshd_login_grace_time_usr_config_dir + + + + + + + + + + + + object_sshd_login_grace_time_usr + + + object_sshd_login_grace_time_config_dir + object_sshd_login_grace_time_usr_config_dir + + + + + + + diff --git a/linux_os/guide/services/ssh/ssh_server/sshd_set_login_grace_time/tests/correct_value_etc_sshd_config_drop_in.pass.sh b/linux_os/guide/services/ssh/ssh_server/sshd_set_login_grace_time/tests/correct_value_etc_sshd_config_drop_in.pass.sh new file mode 100644 index 000000000000..a0f68b4a5ccb --- /dev/null +++ b/linux_os/guide/services/ssh/ssh_server/sshd_set_login_grace_time/tests/correct_value_etc_sshd_config_drop_in.pass.sh @@ -0,0 +1,5 @@ +#!/bin/bash +# platform = SUSE Linux Enterprise 16 +source include.sh + +echo "LoginGraceTime 60" >> /etc/ssh/sshd_config.d/01-complianceascode.conf diff --git a/linux_os/guide/services/ssh/ssh_server/sshd_set_login_grace_time/tests/correct_value_in_usr_etc_sshd_config_present.fail.sh b/linux_os/guide/services/ssh/ssh_server/sshd_set_login_grace_time/tests/correct_value_in_usr_etc_sshd_config_present.fail.sh new file mode 100644 index 000000000000..b80e3832b591 --- /dev/null +++ b/linux_os/guide/services/ssh/ssh_server/sshd_set_login_grace_time/tests/correct_value_in_usr_etc_sshd_config_present.fail.sh @@ -0,0 +1,6 @@ +#!/bin/bash +# platform = SUSE Linux Enterprise 16 +source include.sh + +touch /etc/ssh/sshd_config +echo "LoginGraceTime 1" >> /usr/etc/ssh/sshd_config diff --git a/linux_os/guide/services/ssh/ssh_server/sshd_set_login_grace_time/tests/correct_value_usr_etc_sshd_config.pass.sh b/linux_os/guide/services/ssh/ssh_server/sshd_set_login_grace_time/tests/correct_value_usr_etc_sshd_config.pass.sh new file mode 100644 index 000000000000..3ed15582de0b --- /dev/null +++ b/linux_os/guide/services/ssh/ssh_server/sshd_set_login_grace_time/tests/correct_value_usr_etc_sshd_config.pass.sh @@ -0,0 +1,5 @@ +#!/bin/bash +# platform = SUSE Linux Enterprise 16 +source include.sh + +echo "LoginGraceTime 1" >> /usr/etc/ssh/sshd_config diff --git a/linux_os/guide/services/ssh/ssh_server/sshd_set_login_grace_time/tests/correct_value_usr_etc_sshd_config_drop_in.pass.sh b/linux_os/guide/services/ssh/ssh_server/sshd_set_login_grace_time/tests/correct_value_usr_etc_sshd_config_drop_in.pass.sh new file mode 100644 index 000000000000..1e72b109d85e --- /dev/null +++ b/linux_os/guide/services/ssh/ssh_server/sshd_set_login_grace_time/tests/correct_value_usr_etc_sshd_config_drop_in.pass.sh @@ -0,0 +1,5 @@ +#!/bin/bash +# platform = SUSE Linux Enterprise 16 +source include.sh + +echo "LoginGraceTime 60" >> /usr/etc/ssh/sshd_config.d/01-complianceascode.conf diff --git a/linux_os/guide/services/ssh/ssh_server/sshd_set_login_grace_time/tests/include.sh b/linux_os/guide/services/ssh/ssh_server/sshd_set_login_grace_time/tests/include.sh new file mode 100644 index 000000000000..aee5eb2d0bec --- /dev/null +++ b/linux_os/guide/services/ssh/ssh_server/sshd_set_login_grace_time/tests/include.sh @@ -0,0 +1,15 @@ +#!/bin/bash + +declare -a SSHD_PATHS=("/etc/ssh/sshd_config") +{{% if product == 'sle16' %}} +SSHD_PATHS+=("/usr/etc/ssh/sshd_config" /usr/etc/ssh/sshd_config.d/* /etc/ssh/sshd_config.d/*) +{{% endif %}} +# clean up configurations +sed -i '/^LoginGraceTime.*/d' "${SSHD_PATHS[@]}" + +# restore to defaults for sle16 +{{% if product == 'sle16' %}} +if [ -e "/etc/ssh/sshd_config" ] ; then + rm /etc/ssh/sshd_config +fi +{{% endif %}} diff --git a/linux_os/guide/services/ssh/ssh_server/sshd_set_login_grace_time/tests/lower_bound.pass.sh b/linux_os/guide/services/ssh/ssh_server/sshd_set_login_grace_time/tests/lower_bound.pass.sh index f5236501ca01..809d3c1f4659 100644 --- a/linux_os/guide/services/ssh/ssh_server/sshd_set_login_grace_time/tests/lower_bound.pass.sh +++ b/linux_os/guide/services/ssh/ssh_server/sshd_set_login_grace_time/tests/lower_bound.pass.sh @@ -1,5 +1,5 @@ #!/bin/bash -# profiles = xccdf_org.ssgproject.content_profile_cis +# profiles = xccdf_org.ssgproject.content_profile_cis,xccdf_org.ssgproject.content_profile_pci-dss-4 # platform = multi_platform_all SSHD_CONFIG="/etc/ssh/sshd_config" diff --git a/linux_os/guide/services/ssh/ssh_server/sshd_set_login_grace_time/tests/no_limit.fail.sh b/linux_os/guide/services/ssh/ssh_server/sshd_set_login_grace_time/tests/no_limit.fail.sh index 63a0aee97f7d..738969589112 100644 --- a/linux_os/guide/services/ssh/ssh_server/sshd_set_login_grace_time/tests/no_limit.fail.sh +++ b/linux_os/guide/services/ssh/ssh_server/sshd_set_login_grace_time/tests/no_limit.fail.sh @@ -1,5 +1,5 @@ #!/bin/bash -# profiles = xccdf_org.ssgproject.content_profile_cis +# profiles = xccdf_org.ssgproject.content_profile_cis,xccdf_org.ssgproject.content_profile_pci-dss-4 # platform = multi_platform_all SSHD_CONFIG="/etc/ssh/sshd_config" diff --git a/linux_os/guide/services/ssh/ssh_server/sshd_set_login_grace_time/tests/too_high.fail.sh b/linux_os/guide/services/ssh/ssh_server/sshd_set_login_grace_time/tests/too_high.fail.sh index 6d109091b8b9..959f7d699345 100644 --- a/linux_os/guide/services/ssh/ssh_server/sshd_set_login_grace_time/tests/too_high.fail.sh +++ b/linux_os/guide/services/ssh/ssh_server/sshd_set_login_grace_time/tests/too_high.fail.sh @@ -1,5 +1,5 @@ #!/bin/bash -# profiles = xccdf_org.ssgproject.content_profile_cis +# profiles = xccdf_org.ssgproject.content_profile_cis,xccdf_org.ssgproject.content_profile_pci-dss-4 # platform = multi_platform_all SSHD_CONFIG="/etc/ssh/sshd_config" diff --git a/linux_os/guide/services/ssh/ssh_server/sshd_set_login_grace_time/tests/too_high_etc_sshd_config_drop_in.fail.sh b/linux_os/guide/services/ssh/ssh_server/sshd_set_login_grace_time/tests/too_high_etc_sshd_config_drop_in.fail.sh new file mode 100644 index 000000000000..35ea7b48f5f4 --- /dev/null +++ b/linux_os/guide/services/ssh/ssh_server/sshd_set_login_grace_time/tests/too_high_etc_sshd_config_drop_in.fail.sh @@ -0,0 +1,5 @@ +#!/bin/bash +# platform = SUSE Linux Enterprise 16 +source include.sh + +echo "LoginGraceTime 61" >> /etc/ssh/sshd_config.d/01-complianceascode.conf diff --git a/linux_os/guide/services/ssh/ssh_server/sshd_set_login_grace_time/tests/too_high_usr_etc_sshd_config.fail.sh b/linux_os/guide/services/ssh/ssh_server/sshd_set_login_grace_time/tests/too_high_usr_etc_sshd_config.fail.sh new file mode 100644 index 000000000000..7010af0181bd --- /dev/null +++ b/linux_os/guide/services/ssh/ssh_server/sshd_set_login_grace_time/tests/too_high_usr_etc_sshd_config.fail.sh @@ -0,0 +1,5 @@ +#!/bin/bash +# platform = SUSE Linux Enterprise 16 +source include.sh + +echo "LoginGraceTime 61" >> /usr/etc/ssh/sshd_config diff --git a/linux_os/guide/services/ssh/ssh_server/sshd_set_login_grace_time/tests/too_high_usr_etc_sshd_config_drop_in.fail.sh b/linux_os/guide/services/ssh/ssh_server/sshd_set_login_grace_time/tests/too_high_usr_etc_sshd_config_drop_in.fail.sh new file mode 100644 index 000000000000..1cdd63bb777a --- /dev/null +++ b/linux_os/guide/services/ssh/ssh_server/sshd_set_login_grace_time/tests/too_high_usr_etc_sshd_config_drop_in.fail.sh @@ -0,0 +1,5 @@ +#!/bin/bash +# platform = SUSE Linux Enterprise 16 +source include.sh + +echo "LoginGraceTime 61" >> /usr/etc/ssh/sshd_config.d/01-complianceascode.conf From 676a554cbe9d8f3ab575f28105946540a89e5d15 Mon Sep 17 00:00:00 2001 From: teacup-on-rockingchair <315160+teacup-on-rockingchair@users.noreply.github.com> Date: Thu, 26 Feb 2026 08:05:48 +0200 Subject: [PATCH 7/9] For sle16 enhance the check to cover cases with sshd_config in /usr and subfolders for sshd_set_max_auth_tries rule --- .../sshd_set_max_auth_tries/oval/sle16.xml | 153 ++++++++++++++++++ ...rect_value_etc_sshd_config_drop_in.pass.sh | 6 + ...lue_in_usr_etc_sshd_config_present.fail.sh | 7 + .../correct_value_usr_etc_sshd_config.pass.sh | 6 + ..._value_usr_etc_sshd_config_drop_in.pass.sh | 6 + .../sshd_set_max_auth_tries/tests/include.sh | 15 ++ ...rong_value_etc_sshd_config_drop_in.fail.sh | 6 + .../wrong_value_usr_etc_sshd_config.fail.sh | 6 + ..._value_usr_etc_sshd_config_drop_in.fail.sh | 6 + 9 files changed, 211 insertions(+) create mode 100644 linux_os/guide/services/ssh/ssh_server/sshd_set_max_auth_tries/oval/sle16.xml create mode 100644 linux_os/guide/services/ssh/ssh_server/sshd_set_max_auth_tries/tests/correct_value_etc_sshd_config_drop_in.pass.sh create mode 100644 linux_os/guide/services/ssh/ssh_server/sshd_set_max_auth_tries/tests/correct_value_in_usr_etc_sshd_config_present.fail.sh create mode 100644 linux_os/guide/services/ssh/ssh_server/sshd_set_max_auth_tries/tests/correct_value_usr_etc_sshd_config.pass.sh create mode 100644 linux_os/guide/services/ssh/ssh_server/sshd_set_max_auth_tries/tests/correct_value_usr_etc_sshd_config_drop_in.pass.sh create mode 100644 linux_os/guide/services/ssh/ssh_server/sshd_set_max_auth_tries/tests/include.sh create mode 100644 linux_os/guide/services/ssh/ssh_server/sshd_set_max_auth_tries/tests/wrong_value_etc_sshd_config_drop_in.fail.sh create mode 100644 linux_os/guide/services/ssh/ssh_server/sshd_set_max_auth_tries/tests/wrong_value_usr_etc_sshd_config.fail.sh create mode 100644 linux_os/guide/services/ssh/ssh_server/sshd_set_max_auth_tries/tests/wrong_value_usr_etc_sshd_config_drop_in.fail.sh diff --git a/linux_os/guide/services/ssh/ssh_server/sshd_set_max_auth_tries/oval/sle16.xml b/linux_os/guide/services/ssh/ssh_server/sshd_set_max_auth_tries/oval/sle16.xml new file mode 100644 index 000000000000..a9452bfb71aa --- /dev/null +++ b/linux_os/guide/services/ssh/ssh_server/sshd_set_max_auth_tries/oval/sle16.xml @@ -0,0 +1,153 @@ + + + {{{ oval_metadata("The SSH MaxAuthTries should be set to an appropriate value.", rule_title=rule_title) }}} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ^/etc/ssh/sshd_config + + + + + + + + + + /etc/ssh/sshd_config + ^[\s]*(?i)MaxAuthTries[\s]+(\d+)[\s]*(?:#.*)?$ + 1 + + + + + + + + + + /usr/etc/ssh/sshd_config + ^[\s]*(?i)MaxAuthTries[\s]+(\d+)[\s]*(?:#.*)?$ + 1 + + + + + + + + + + /etc/ssh/sshd_config.d + .*\.conf$ + ^[\s]*(?i)MaxAuthTries[\s]+(\d+)[\s]*(?:#.*)?$ + 1 + + + + + + + + + + /usr/etc/ssh/sshd_config.d + .*\.conf$ + ^[\s]*(?i)MaxAuthTries[\s]+(\d+)[\s]*(?:#.*)?$ + 1 + + + + + + + + 0 + + + + + + + + + + object_sshd_max_auth_tries_etc + + + object_sshd_max_auth_tries_config_dir + object_sshd_max_auth_tries_usr_config_dir + + + + + + + + + + + + object_sshd_max_auth_tries_usr + + + object_sshd_max_auth_tries_config_dir + object_sshd_max_auth_tries_usr_config_dir + + + + + + + diff --git a/linux_os/guide/services/ssh/ssh_server/sshd_set_max_auth_tries/tests/correct_value_etc_sshd_config_drop_in.pass.sh b/linux_os/guide/services/ssh/ssh_server/sshd_set_max_auth_tries/tests/correct_value_etc_sshd_config_drop_in.pass.sh new file mode 100644 index 000000000000..4262a6713622 --- /dev/null +++ b/linux_os/guide/services/ssh/ssh_server/sshd_set_max_auth_tries/tests/correct_value_etc_sshd_config_drop_in.pass.sh @@ -0,0 +1,6 @@ +#!/bin/bash +# platform = SUSE Linux Enterprise 16 +# variables = sshd_max_auth_tries_value=4 +source include.sh + +echo "MaxAuthTries 4" >> /etc/ssh/sshd_config.d/01-complianceascode.conf diff --git a/linux_os/guide/services/ssh/ssh_server/sshd_set_max_auth_tries/tests/correct_value_in_usr_etc_sshd_config_present.fail.sh b/linux_os/guide/services/ssh/ssh_server/sshd_set_max_auth_tries/tests/correct_value_in_usr_etc_sshd_config_present.fail.sh new file mode 100644 index 000000000000..7b327ed220ce --- /dev/null +++ b/linux_os/guide/services/ssh/ssh_server/sshd_set_max_auth_tries/tests/correct_value_in_usr_etc_sshd_config_present.fail.sh @@ -0,0 +1,7 @@ +#!/bin/bash +# platform = SUSE Linux Enterprise 16 +# variables = sshd_max_auth_tries_value=4 +source include.sh + +touch /etc/ssh/sshd_config +echo "MaxAuthTries 4" >> /usr/etc/ssh/sshd_config diff --git a/linux_os/guide/services/ssh/ssh_server/sshd_set_max_auth_tries/tests/correct_value_usr_etc_sshd_config.pass.sh b/linux_os/guide/services/ssh/ssh_server/sshd_set_max_auth_tries/tests/correct_value_usr_etc_sshd_config.pass.sh new file mode 100644 index 000000000000..d902aa806c16 --- /dev/null +++ b/linux_os/guide/services/ssh/ssh_server/sshd_set_max_auth_tries/tests/correct_value_usr_etc_sshd_config.pass.sh @@ -0,0 +1,6 @@ +#!/bin/bash +# platform = SUSE Linux Enterprise 16 +# variables = sshd_max_auth_tries_value=4 +source include.sh + +echo "MaxAuthTries 4" >> /usr/etc/ssh/sshd_config diff --git a/linux_os/guide/services/ssh/ssh_server/sshd_set_max_auth_tries/tests/correct_value_usr_etc_sshd_config_drop_in.pass.sh b/linux_os/guide/services/ssh/ssh_server/sshd_set_max_auth_tries/tests/correct_value_usr_etc_sshd_config_drop_in.pass.sh new file mode 100644 index 000000000000..0c0ad79ef4fe --- /dev/null +++ b/linux_os/guide/services/ssh/ssh_server/sshd_set_max_auth_tries/tests/correct_value_usr_etc_sshd_config_drop_in.pass.sh @@ -0,0 +1,6 @@ +#!/bin/bash +# platform = SUSE Linux Enterprise 16 +# variables = sshd_max_auth_tries_value=4 +source include.sh + +echo "MaxAuthTries 4" >> /usr/etc/ssh/sshd_config.d/01-complianceascode.conf diff --git a/linux_os/guide/services/ssh/ssh_server/sshd_set_max_auth_tries/tests/include.sh b/linux_os/guide/services/ssh/ssh_server/sshd_set_max_auth_tries/tests/include.sh new file mode 100644 index 000000000000..9790bbcd68d0 --- /dev/null +++ b/linux_os/guide/services/ssh/ssh_server/sshd_set_max_auth_tries/tests/include.sh @@ -0,0 +1,15 @@ +#!/bin/bash + +declare -a SSHD_PATHS=("/etc/ssh/sshd_config") +{{% if product == 'sle16' %}} +SSHD_PATHS+=("/usr/etc/ssh/sshd_config" /usr/etc/ssh/sshd_config.d/* /etc/ssh/sshd_config.d/*) +{{% endif %}} +# clean up configurations +sed -i '/^MaxAuthTries.*/d' "${SSHD_PATHS[@]}" + +# restore to defaults for sle16 +{{% if product == 'sle16' %}} +if [ -e "/etc/ssh/sshd_config" ] ; then + rm /etc/ssh/sshd_config +fi +{{% endif %}} diff --git a/linux_os/guide/services/ssh/ssh_server/sshd_set_max_auth_tries/tests/wrong_value_etc_sshd_config_drop_in.fail.sh b/linux_os/guide/services/ssh/ssh_server/sshd_set_max_auth_tries/tests/wrong_value_etc_sshd_config_drop_in.fail.sh new file mode 100644 index 000000000000..41136d9eb40b --- /dev/null +++ b/linux_os/guide/services/ssh/ssh_server/sshd_set_max_auth_tries/tests/wrong_value_etc_sshd_config_drop_in.fail.sh @@ -0,0 +1,6 @@ +#!/bin/bash +# platform = SUSE Linux Enterprise 16 +# variables = sshd_max_auth_tries_value=4 +source include.sh + +echo "MaxAuthTries 20" >> /etc/ssh/sshd_config.d/01-complianceascode.conf diff --git a/linux_os/guide/services/ssh/ssh_server/sshd_set_max_auth_tries/tests/wrong_value_usr_etc_sshd_config.fail.sh b/linux_os/guide/services/ssh/ssh_server/sshd_set_max_auth_tries/tests/wrong_value_usr_etc_sshd_config.fail.sh new file mode 100644 index 000000000000..218e4deb2407 --- /dev/null +++ b/linux_os/guide/services/ssh/ssh_server/sshd_set_max_auth_tries/tests/wrong_value_usr_etc_sshd_config.fail.sh @@ -0,0 +1,6 @@ +#!/bin/bash +# platform = SUSE Linux Enterprise 16 +# variables = sshd_max_auth_tries_value=4 +source include.sh + +echo "MaxAuthTries 5" >> /usr/etc/ssh/sshd_config diff --git a/linux_os/guide/services/ssh/ssh_server/sshd_set_max_auth_tries/tests/wrong_value_usr_etc_sshd_config_drop_in.fail.sh b/linux_os/guide/services/ssh/ssh_server/sshd_set_max_auth_tries/tests/wrong_value_usr_etc_sshd_config_drop_in.fail.sh new file mode 100644 index 000000000000..753e15c14404 --- /dev/null +++ b/linux_os/guide/services/ssh/ssh_server/sshd_set_max_auth_tries/tests/wrong_value_usr_etc_sshd_config_drop_in.fail.sh @@ -0,0 +1,6 @@ +#!/bin/bash +# platform = SUSE Linux Enterprise 16 +# variables = sshd_max_auth_tries_value=4 +source include.sh + +echo "MaxAuthTries 0" >> /usr/etc/ssh/sshd_config.d/01-complianceascode.conf From 5de048fc42cf8406ecc5b97c891db4b846ed4519 Mon Sep 17 00:00:00 2001 From: teacup-on-rockingchair <315160+teacup-on-rockingchair@users.noreply.github.com> Date: Thu, 26 Feb 2026 08:06:35 +0200 Subject: [PATCH 8/9] For sle16 enhance the check to cover cases with sshd_config in /usr and subfolders for sshd_set_max_sessions rule --- .../sshd_set_max_sessions/oval/sle16.xml | 153 ++++++++++++++++++ ...rect_value_etc_sshd_config_drop_in.pass.sh | 6 + ...lue_in_usr_etc_sshd_config_present.fail.sh | 7 + .../correct_value_usr_etc_sshd_config.pass.sh | 6 + ..._value_usr_etc_sshd_config_drop_in.pass.sh | 6 + .../sshd_set_max_sessions/tests/include.sh | 15 ++ ...rong_value_etc_sshd_config_drop_in.fail.sh | 6 + .../wrong_value_usr_etc_sshd_config.fail.sh | 6 + ..._value_usr_etc_sshd_config_drop_in.fail.sh | 6 + 9 files changed, 211 insertions(+) create mode 100644 linux_os/guide/services/ssh/ssh_server/sshd_set_max_sessions/oval/sle16.xml create mode 100644 linux_os/guide/services/ssh/ssh_server/sshd_set_max_sessions/tests/correct_value_etc_sshd_config_drop_in.pass.sh create mode 100644 linux_os/guide/services/ssh/ssh_server/sshd_set_max_sessions/tests/correct_value_in_usr_etc_sshd_config_present.fail.sh create mode 100644 linux_os/guide/services/ssh/ssh_server/sshd_set_max_sessions/tests/correct_value_usr_etc_sshd_config.pass.sh create mode 100644 linux_os/guide/services/ssh/ssh_server/sshd_set_max_sessions/tests/correct_value_usr_etc_sshd_config_drop_in.pass.sh create mode 100644 linux_os/guide/services/ssh/ssh_server/sshd_set_max_sessions/tests/include.sh create mode 100644 linux_os/guide/services/ssh/ssh_server/sshd_set_max_sessions/tests/wrong_value_etc_sshd_config_drop_in.fail.sh create mode 100644 linux_os/guide/services/ssh/ssh_server/sshd_set_max_sessions/tests/wrong_value_usr_etc_sshd_config.fail.sh create mode 100644 linux_os/guide/services/ssh/ssh_server/sshd_set_max_sessions/tests/wrong_value_usr_etc_sshd_config_drop_in.fail.sh diff --git a/linux_os/guide/services/ssh/ssh_server/sshd_set_max_sessions/oval/sle16.xml b/linux_os/guide/services/ssh/ssh_server/sshd_set_max_sessions/oval/sle16.xml new file mode 100644 index 000000000000..3acd7b75327d --- /dev/null +++ b/linux_os/guide/services/ssh/ssh_server/sshd_set_max_sessions/oval/sle16.xml @@ -0,0 +1,153 @@ + + + {{{ oval_metadata("The SSH MaxSessions should be set to an appropriate value.", rule_title=rule_title) }}} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ^/etc/ssh/sshd_config + + + + + + + + + + /etc/ssh/sshd_config + ^[\s]*(?i)MaxSessions[\s]+(\d+)[\s]*(?:#.*)?$ + 1 + + + + + + + + + + /usr/etc/ssh/sshd_config + ^[\s]*(?i)MaxSessions[\s]+(\d+)[\s]*(?:#.*)?$ + 1 + + + + + + + + + + /etc/ssh/sshd_config.d + .*\.conf$ + ^[\s]*(?i)MaxSessions[\s]+(\d+)[\s]*(?:#.*)?$ + 1 + + + + + + + + + + /usr/etc/ssh/sshd_config.d + .*\.conf$ + ^[\s]*(?i)MaxSessions[\s]+(\d+)[\s]*(?:#.*)?$ + 1 + + + + + + + + 0 + + + + + + + + + + object_sshd_max_session_etc + + + object_sshd_max_session_config_dir + object_sshd_max_session_usr_config_dir + + + + + + + + + + + + object_sshd_max_session_usr + + + object_sshd_max_session_config_dir + object_sshd_max_session_usr_config_dir + + + + + + + diff --git a/linux_os/guide/services/ssh/ssh_server/sshd_set_max_sessions/tests/correct_value_etc_sshd_config_drop_in.pass.sh b/linux_os/guide/services/ssh/ssh_server/sshd_set_max_sessions/tests/correct_value_etc_sshd_config_drop_in.pass.sh new file mode 100644 index 000000000000..7fdb6123803b --- /dev/null +++ b/linux_os/guide/services/ssh/ssh_server/sshd_set_max_sessions/tests/correct_value_etc_sshd_config_drop_in.pass.sh @@ -0,0 +1,6 @@ +#!/bin/bash +# platform = SUSE Linux Enterprise 16 +# variables = var_sshd_max_sessions=4 +source include.sh + +echo "MaxSessions 4" >> /etc/ssh/sshd_config.d/01-complianceascode.conf diff --git a/linux_os/guide/services/ssh/ssh_server/sshd_set_max_sessions/tests/correct_value_in_usr_etc_sshd_config_present.fail.sh b/linux_os/guide/services/ssh/ssh_server/sshd_set_max_sessions/tests/correct_value_in_usr_etc_sshd_config_present.fail.sh new file mode 100644 index 000000000000..7f19908dcaea --- /dev/null +++ b/linux_os/guide/services/ssh/ssh_server/sshd_set_max_sessions/tests/correct_value_in_usr_etc_sshd_config_present.fail.sh @@ -0,0 +1,7 @@ +#!/bin/bash +# platform = SUSE Linux Enterprise 16 +# variables = var_sshd_max_sessions=4 +source include.sh + +touch /etc/ssh/sshd_config +echo "MaxSessions 4" >> /usr/etc/ssh/sshd_config diff --git a/linux_os/guide/services/ssh/ssh_server/sshd_set_max_sessions/tests/correct_value_usr_etc_sshd_config.pass.sh b/linux_os/guide/services/ssh/ssh_server/sshd_set_max_sessions/tests/correct_value_usr_etc_sshd_config.pass.sh new file mode 100644 index 000000000000..180bd49bed98 --- /dev/null +++ b/linux_os/guide/services/ssh/ssh_server/sshd_set_max_sessions/tests/correct_value_usr_etc_sshd_config.pass.sh @@ -0,0 +1,6 @@ +#!/bin/bash +# platform = SUSE Linux Enterprise 16 +# variables = var_sshd_max_sessions=4 +source include.sh + +echo "MaxSessions 4" >> /usr/etc/ssh/sshd_config diff --git a/linux_os/guide/services/ssh/ssh_server/sshd_set_max_sessions/tests/correct_value_usr_etc_sshd_config_drop_in.pass.sh b/linux_os/guide/services/ssh/ssh_server/sshd_set_max_sessions/tests/correct_value_usr_etc_sshd_config_drop_in.pass.sh new file mode 100644 index 000000000000..622d36446727 --- /dev/null +++ b/linux_os/guide/services/ssh/ssh_server/sshd_set_max_sessions/tests/correct_value_usr_etc_sshd_config_drop_in.pass.sh @@ -0,0 +1,6 @@ +#!/bin/bash +# platform = SUSE Linux Enterprise 16 +# variables = var_sshd_max_sessions=4 +source include.sh + +echo "MaxSessions 4" >> /usr/etc/ssh/sshd_config.d/01-complianceascode.conf diff --git a/linux_os/guide/services/ssh/ssh_server/sshd_set_max_sessions/tests/include.sh b/linux_os/guide/services/ssh/ssh_server/sshd_set_max_sessions/tests/include.sh new file mode 100644 index 000000000000..4c8d058295d8 --- /dev/null +++ b/linux_os/guide/services/ssh/ssh_server/sshd_set_max_sessions/tests/include.sh @@ -0,0 +1,15 @@ +#!/bin/bash + +declare -a SSHD_PATHS=("/etc/ssh/sshd_config") +{{% if product == 'sle16' %}} +SSHD_PATHS+=("/usr/etc/ssh/sshd_config" /usr/etc/ssh/sshd_config.d/* /etc/ssh/sshd_config.d/*) +{{% endif %}} +# clean up configurations +sed -i '/^MaxSessions.*/d' "${SSHD_PATHS[@]}" + +# restore to defaults for sle16 +{{% if product == 'sle16' %}} +if [ -e "/etc/ssh/sshd_config" ] ; then + rm /etc/ssh/sshd_config +fi +{{% endif %}} diff --git a/linux_os/guide/services/ssh/ssh_server/sshd_set_max_sessions/tests/wrong_value_etc_sshd_config_drop_in.fail.sh b/linux_os/guide/services/ssh/ssh_server/sshd_set_max_sessions/tests/wrong_value_etc_sshd_config_drop_in.fail.sh new file mode 100644 index 000000000000..606d55099420 --- /dev/null +++ b/linux_os/guide/services/ssh/ssh_server/sshd_set_max_sessions/tests/wrong_value_etc_sshd_config_drop_in.fail.sh @@ -0,0 +1,6 @@ +#!/bin/bash +# platform = SUSE Linux Enterprise 16 +# variables = var_sshd_max_sessions=4 +source include.sh + +echo "MaxSessions 20" >> /etc/ssh/sshd_config.d/01-complianceascode.conf diff --git a/linux_os/guide/services/ssh/ssh_server/sshd_set_max_sessions/tests/wrong_value_usr_etc_sshd_config.fail.sh b/linux_os/guide/services/ssh/ssh_server/sshd_set_max_sessions/tests/wrong_value_usr_etc_sshd_config.fail.sh new file mode 100644 index 000000000000..fe6f5a820988 --- /dev/null +++ b/linux_os/guide/services/ssh/ssh_server/sshd_set_max_sessions/tests/wrong_value_usr_etc_sshd_config.fail.sh @@ -0,0 +1,6 @@ +#!/bin/bash +# platform = SUSE Linux Enterprise 16 +# variables = var_sshd_max_sessions=4 +source include.sh + +echo "MaxSessions 5" >> /usr/etc/ssh/sshd_config diff --git a/linux_os/guide/services/ssh/ssh_server/sshd_set_max_sessions/tests/wrong_value_usr_etc_sshd_config_drop_in.fail.sh b/linux_os/guide/services/ssh/ssh_server/sshd_set_max_sessions/tests/wrong_value_usr_etc_sshd_config_drop_in.fail.sh new file mode 100644 index 000000000000..0c07b9608d42 --- /dev/null +++ b/linux_os/guide/services/ssh/ssh_server/sshd_set_max_sessions/tests/wrong_value_usr_etc_sshd_config_drop_in.fail.sh @@ -0,0 +1,6 @@ +#!/bin/bash +# platform = SUSE Linux Enterprise 16 +# variables = var_sshd_max_sessions=4 +source include.sh + +echo "MaxSessions 10" >> /usr/etc/ssh/sshd_config.d/01-complianceascode.conf From 8f0e0ed0693492e6d249ebf6f00c607f7a33d87b Mon Sep 17 00:00:00 2001 From: teacup-on-rockingchair <315160+teacup-on-rockingchair@users.noreply.github.com> Date: Thu, 26 Feb 2026 08:07:03 +0200 Subject: [PATCH 9/9] For sle16 enhance the check to cover cases with sshd_config in /usr and subfolders for sshd_set_maxstartups rule --- .../sshd_set_maxstartups/oval/sle16.xml | 151 ++++++++++++++++++ ...rect_value_etc_sshd_config_drop_in.pass.sh | 6 + ...lue_in_usr_etc_sshd_config_present.fail.sh | 7 + .../correct_value_usr_etc_sshd_config.pass.sh | 6 + ..._value_usr_etc_sshd_config_drop_in.pass.sh | 6 + .../sshd_set_maxstartups/tests/include.sh | 15 ++ ...rong_value_etc_sshd_config_drop_in.fail.sh | 6 + .../wrong_value_usr_etc_sshd_config.fail.sh | 6 + ..._value_usr_etc_sshd_config_drop_in.fail.sh | 6 + 9 files changed, 209 insertions(+) create mode 100644 linux_os/guide/services/ssh/ssh_server/sshd_set_maxstartups/oval/sle16.xml create mode 100644 linux_os/guide/services/ssh/ssh_server/sshd_set_maxstartups/tests/correct_value_etc_sshd_config_drop_in.pass.sh create mode 100644 linux_os/guide/services/ssh/ssh_server/sshd_set_maxstartups/tests/correct_value_in_usr_etc_sshd_config_present.fail.sh create mode 100644 linux_os/guide/services/ssh/ssh_server/sshd_set_maxstartups/tests/correct_value_usr_etc_sshd_config.pass.sh create mode 100644 linux_os/guide/services/ssh/ssh_server/sshd_set_maxstartups/tests/correct_value_usr_etc_sshd_config_drop_in.pass.sh create mode 100644 linux_os/guide/services/ssh/ssh_server/sshd_set_maxstartups/tests/include.sh create mode 100644 linux_os/guide/services/ssh/ssh_server/sshd_set_maxstartups/tests/wrong_value_etc_sshd_config_drop_in.fail.sh create mode 100644 linux_os/guide/services/ssh/ssh_server/sshd_set_maxstartups/tests/wrong_value_usr_etc_sshd_config.fail.sh create mode 100644 linux_os/guide/services/ssh/ssh_server/sshd_set_maxstartups/tests/wrong_value_usr_etc_sshd_config_drop_in.fail.sh diff --git a/linux_os/guide/services/ssh/ssh_server/sshd_set_maxstartups/oval/sle16.xml b/linux_os/guide/services/ssh/ssh_server/sshd_set_maxstartups/oval/sle16.xml new file mode 100644 index 000000000000..5ca10680c2a8 --- /dev/null +++ b/linux_os/guide/services/ssh/ssh_server/sshd_set_maxstartups/oval/sle16.xml @@ -0,0 +1,151 @@ + + + {{{ oval_metadata("Ensure 'MaxStartups' is properly configured in SSH configuration files.", rule_title=rule_title) }}} + + + + + + + + + + + + + + + + + + + + + + + + + + + ^/etc/ssh/sshd_config + + + + + + + + + + + + + + + + + ^(/etc/ssh|/etc/ssh/sshd_config.d|/usr/etc/ssh/sshd_config.d) + (sshd_config|.*\.conf)$ + (?i)^\s*MaxStartups\s+(\d+):\d+:\d+\s*$ + 1 + + + ^(/etc/ssh|/etc/ssh/sshd_config.d|/usr/etc/ssh/sshd_config.d) + (sshd_config|.*\.conf)$ + (?i)^\s*MaxStartups\s+\d+:(\d+):\d+\s*$ + 1 + + + ^(/etc/ssh|/etc/ssh/sshd_config.d|/usr/etc/ssh/sshd_config.d) + (sshd_config|.*\.conf)$ + (?i)^\s*MaxStartups\s+\d+:\d+:(\d+)\s*$ + 1 + + + + + + + + + + + + + + + + + ^(/usr/etc/ssh|/etc/ssh/sshd_config.d|/usr/etc/ssh/sshd_config.d) + (sshd_config|.*\.conf)$ + (?i)^\s*MaxStartups\s+(\d+):\d+:\d+\s*$ + 1 + + + ^(/usr/etc/ssh|/etc/ssh/sshd_config.d|/usr/etc/ssh/sshd_config.d) + (sshd_config|.*\.conf)$ + (?i)^\s*MaxStartups\s+\d+:(\d+):\d+\s*$ + 1 + + + ^(/usr/etc/ssh|/etc/ssh/sshd_config.d|/usr/etc/ssh/sshd_config.d) + (sshd_config|.*\.conf)$ + (?i)^\s*MaxStartups\s+\d+:\d+:(\d+)\s*$ + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/linux_os/guide/services/ssh/ssh_server/sshd_set_maxstartups/tests/correct_value_etc_sshd_config_drop_in.pass.sh b/linux_os/guide/services/ssh/ssh_server/sshd_set_maxstartups/tests/correct_value_etc_sshd_config_drop_in.pass.sh new file mode 100644 index 000000000000..fc6371be73be --- /dev/null +++ b/linux_os/guide/services/ssh/ssh_server/sshd_set_maxstartups/tests/correct_value_etc_sshd_config_drop_in.pass.sh @@ -0,0 +1,6 @@ +#!/bin/bash +# platform = SUSE Linux Enterprise 16 +# variables = var_sshd_set_maxstartups=10:30:60 +source include.sh + +echo "MaxStartups 10:30:60" >> /etc/ssh/sshd_config.d/01-complianceascode.conf diff --git a/linux_os/guide/services/ssh/ssh_server/sshd_set_maxstartups/tests/correct_value_in_usr_etc_sshd_config_present.fail.sh b/linux_os/guide/services/ssh/ssh_server/sshd_set_maxstartups/tests/correct_value_in_usr_etc_sshd_config_present.fail.sh new file mode 100644 index 000000000000..6905e07c838e --- /dev/null +++ b/linux_os/guide/services/ssh/ssh_server/sshd_set_maxstartups/tests/correct_value_in_usr_etc_sshd_config_present.fail.sh @@ -0,0 +1,7 @@ +#!/bin/bash +# platform = SUSE Linux Enterprise 16 +# variables = var_sshd_set_maxstartups=10:30:60 +source include.sh + +touch /etc/ssh/sshd_config +echo "MaxStartups 10:30:60" >> /usr/etc/ssh/sshd_config diff --git a/linux_os/guide/services/ssh/ssh_server/sshd_set_maxstartups/tests/correct_value_usr_etc_sshd_config.pass.sh b/linux_os/guide/services/ssh/ssh_server/sshd_set_maxstartups/tests/correct_value_usr_etc_sshd_config.pass.sh new file mode 100644 index 000000000000..0a93fe6e32ec --- /dev/null +++ b/linux_os/guide/services/ssh/ssh_server/sshd_set_maxstartups/tests/correct_value_usr_etc_sshd_config.pass.sh @@ -0,0 +1,6 @@ +#!/bin/bash +# platform = SUSE Linux Enterprise 16 +# variables = var_sshd_set_maxstartups=10:30:60 +source include.sh + +echo "MaxStartups 10:30:60" >> /usr/etc/ssh/sshd_config diff --git a/linux_os/guide/services/ssh/ssh_server/sshd_set_maxstartups/tests/correct_value_usr_etc_sshd_config_drop_in.pass.sh b/linux_os/guide/services/ssh/ssh_server/sshd_set_maxstartups/tests/correct_value_usr_etc_sshd_config_drop_in.pass.sh new file mode 100644 index 000000000000..d2835b507b40 --- /dev/null +++ b/linux_os/guide/services/ssh/ssh_server/sshd_set_maxstartups/tests/correct_value_usr_etc_sshd_config_drop_in.pass.sh @@ -0,0 +1,6 @@ +#!/bin/bash +# platform = SUSE Linux Enterprise 16 +# variables = var_sshd_set_maxstartups=10:30:60 +source include.sh + +echo "MaxStartups 10:30:60" >> /usr/etc/ssh/sshd_config.d/01-complianceascode.conf diff --git a/linux_os/guide/services/ssh/ssh_server/sshd_set_maxstartups/tests/include.sh b/linux_os/guide/services/ssh/ssh_server/sshd_set_maxstartups/tests/include.sh new file mode 100644 index 000000000000..1f5b69d60b54 --- /dev/null +++ b/linux_os/guide/services/ssh/ssh_server/sshd_set_maxstartups/tests/include.sh @@ -0,0 +1,15 @@ +#!/bin/bash + +declare -a SSHD_PATHS=("/etc/ssh/sshd_config") +{{% if product == 'sle16' %}} +SSHD_PATHS+=("/usr/etc/ssh/sshd_config" /usr/etc/ssh/sshd_config.d/* /etc/ssh/sshd_config.d/*) +{{% endif %}} +# clean up configurations +sed -i '/^MaxStartups.*/d' "${SSHD_PATHS[@]}" + +# restore to defaults for sle16 +{{% if product == 'sle16' %}} +if [ -e "/etc/ssh/sshd_config" ] ; then + rm /etc/ssh/sshd_config +fi +{{% endif %}} diff --git a/linux_os/guide/services/ssh/ssh_server/sshd_set_maxstartups/tests/wrong_value_etc_sshd_config_drop_in.fail.sh b/linux_os/guide/services/ssh/ssh_server/sshd_set_maxstartups/tests/wrong_value_etc_sshd_config_drop_in.fail.sh new file mode 100644 index 000000000000..39d6dae3afc2 --- /dev/null +++ b/linux_os/guide/services/ssh/ssh_server/sshd_set_maxstartups/tests/wrong_value_etc_sshd_config_drop_in.fail.sh @@ -0,0 +1,6 @@ +#!/bin/bash +# platform = SUSE Linux Enterprise 16 +# variables = var_sshd_set_maxstartups=10:30:60 +source include.sh + +echo "MaxStartups 10:30:61" >> /etc/ssh/sshd_config.d/01-complianceascode.conf diff --git a/linux_os/guide/services/ssh/ssh_server/sshd_set_maxstartups/tests/wrong_value_usr_etc_sshd_config.fail.sh b/linux_os/guide/services/ssh/ssh_server/sshd_set_maxstartups/tests/wrong_value_usr_etc_sshd_config.fail.sh new file mode 100644 index 000000000000..9bfce7c33062 --- /dev/null +++ b/linux_os/guide/services/ssh/ssh_server/sshd_set_maxstartups/tests/wrong_value_usr_etc_sshd_config.fail.sh @@ -0,0 +1,6 @@ +#!/bin/bash +# platform = SUSE Linux Enterprise 16 +# variables = var_sshd_set_maxstartups=10:30:60 +source include.sh + +echo "MaxStartups 10:29:60" >> /usr/etc/ssh/sshd_config diff --git a/linux_os/guide/services/ssh/ssh_server/sshd_set_maxstartups/tests/wrong_value_usr_etc_sshd_config_drop_in.fail.sh b/linux_os/guide/services/ssh/ssh_server/sshd_set_maxstartups/tests/wrong_value_usr_etc_sshd_config_drop_in.fail.sh new file mode 100644 index 000000000000..a0781811a3a3 --- /dev/null +++ b/linux_os/guide/services/ssh/ssh_server/sshd_set_maxstartups/tests/wrong_value_usr_etc_sshd_config_drop_in.fail.sh @@ -0,0 +1,6 @@ +#!/bin/bash +# platform = SUSE Linux Enterprise 16 +# variables = var_sshd_set_maxstartups=10:30:60 +source include.sh + +echo "MaxStartups 11:30:60">> /usr/etc/ssh/sshd_config.d/01-complianceascode.conf