From a80d7de98bca17ff2e8b0e89f3a128fcac48c005 Mon Sep 17 00:00:00 2001 From: Israel Villar Boillos Date: Sun, 29 Mar 2026 22:41:08 +0100 Subject: [PATCH 01/61] Add Debian 13 product skeleton based on Debian 12 --- .../profiles/anssi_bp28_enhanced.profile | 83 ------------------- .../debian13/profiles/anssi_bp28_high.profile | 76 ----------------- .../profiles/anssi_bp28_intermediary.profile | 64 -------------- .../profiles/anssi_bp28_minimal.profile | 47 ----------- .../profiles/cis_level1_workstation.profile | 19 +++++ .../profiles/cis_level2_server.profile | 19 +++++ .../profiles/cis_level2_workstation.profile | 19 +++++ products/debian13/profiles/standard.profile | 57 ------------- 8 files changed, 57 insertions(+), 327 deletions(-) delete mode 100644 products/debian13/profiles/anssi_bp28_enhanced.profile delete mode 100644 products/debian13/profiles/anssi_bp28_high.profile delete mode 100644 products/debian13/profiles/anssi_bp28_intermediary.profile delete mode 100644 products/debian13/profiles/anssi_bp28_minimal.profile create mode 100644 products/debian13/profiles/cis_level1_workstation.profile create mode 100644 products/debian13/profiles/cis_level2_server.profile create mode 100644 products/debian13/profiles/cis_level2_workstation.profile delete mode 100644 products/debian13/profiles/standard.profile diff --git a/products/debian13/profiles/anssi_bp28_enhanced.profile b/products/debian13/profiles/anssi_bp28_enhanced.profile deleted file mode 100644 index 67fdd5cfbc33..000000000000 --- a/products/debian13/profiles/anssi_bp28_enhanced.profile +++ /dev/null @@ -1,83 +0,0 @@ ---- -documentation_complete: true - -title: 'ANSSI-BP-028 (enhanced)' - -description: |- - This profile contains configurations that align to ANSSI-BP-028 v2.0 at the enhanced hardening level. - - ANSSI is the French National Information Security Agency, and stands for Agence nationale de la sécurité des systèmes d'information. - ANSSI-BP-028 is a configuration recommendation for GNU/Linux systems. - - A copy of the ANSSI-BP-028 can be found at the ANSSI website: - https://www.ssi.gouv.fr/administration/guide/recommandations-de-securite-relatives-a-un-systeme-gnulinux/ - -selections: - - anssi:all:enhanced - - 'package_rsyslog_installed' - - 'service_rsyslog_enabled' - # PASS_MIN_LEN is handled by PAM on debian systems. - - '!accounts_password_minlen_login_defs' - # ANSSI BP 28 suggest using libpam_pwquality, which isn't deployed by default - - 'package_pam_pwquality_installed' - # PAM honour login.defs file for algorithm - - 'set_password_hashing_algorithm_logindefs' - # Debian uses apparmor - - '!selinux_state' - - '!audit_rules_mac_modification' - - '!selinux_policytype' - - '!sebool_selinuxuser_execheap' - - '!sebool_deny_execmem' - - '!sebool_selinuxuser_execstack' - - '!sebool_secure_mode_insmod' - - '!sebool_ssh_sysadm_login' - - # this rule is incompatible with R38 - - '!file_groupownership_system_commands_dirs' - - # The following are MLS related rules (not part of ANSSI-BP-028) - - '!accounts_polyinstantiated_tmp' - - '!accounts_polyinstantiated_var_tmp' - - '!enable_pam_namespace' - # there is no tmp.mount unit on Debian 12. - - '!systemd_tmp_mount_enabled' - # this rule cannot handle /etc/chrony/chrony.conf path properly. - # chronyd_specify_remote_server still report wether chrony is configured. - - '!chronyd_configure_pool_and_server' - - # Following rules aren't compatible with Debian 13 - - '!accounts_passwords_pam_tally2_deny_root' - - '!ensure_redhat_gpgkey_installed' - - '!package_sequoia-sq_installed' - - '!set_password_hashing_algorithm_systemauth' - - '!package_dnf-automatic_installed' - - '!dnf-automatic_security_updates_only' - - '!cracklib_accounts_password_pam_lcredit' - - '!dnf-automatic_apply_updates' - - '!cracklib_accounts_password_pam_ocredit' - - '!accounts_password_pam_unix_rounds_system_auth' - - '!timer_dnf-automatic_enabled' - - '!accounts_passwords_pam_tally2' - - '!cracklib_accounts_password_pam_ucredit' - - '!file_permissions_unauthorized_sgid' - - '!ensure_gpgcheck_local_packages' - - '!accounts_passwords_pam_tally2_unlock_time' - - '!enable_authselect' - - '!cracklib_accounts_password_pam_minlen' - - '!cracklib_accounts_password_pam_dcredit' - - '!ensure_gpgcheck_globally_activated' - - '!file_permissions_unauthorized_suid' - - '!ensure_gpgcheck_never_disabled' - - '!ensure_oracle_gpgkey_installed' - - '!ensure_almalinux_gpgkey_installed' - - '!package_dracut-fips-aesni_installed' - - '!audit_rules_file_deletion_events_renameat2' - - '!audit_rules_dac_modification_fchmodat2' - - '!ldap_client_start_tls' - - '!ldap_client_tls_cacertpath' - - # The following rule is not applicable to Debian 13 - - '!logind_session_timeout' - - '!audit_rules_mac_modification_etc_selinux' - - '!no_nis_in_nsswitch' - - '!service_chronyd_enabled' diff --git a/products/debian13/profiles/anssi_bp28_high.profile b/products/debian13/profiles/anssi_bp28_high.profile deleted file mode 100644 index d5aae9cf346f..000000000000 --- a/products/debian13/profiles/anssi_bp28_high.profile +++ /dev/null @@ -1,76 +0,0 @@ -documentation_complete: true - -title: 'ANSSI-BP-028 (high)' - -description: |- - This profile contains configurations that align to ANSSI-BP-028 v2.0 at the high hardening level. - - ANSSI is the French National Information Security Agency, and stands for Agence nationale de la sécurité des systèmes d'information. - ANSSI-BP-028 is a configuration recommendation for GNU/Linux systems. - - A copy of the ANSSI-BP-028 can be found at the ANSSI website: - https://www.ssi.gouv.fr/administration/guide/recommandations-de-securite-relatives-a-un-systeme-gnulinux/ - -selections: - - anssi:all:high - - package_rsyslog_installed - - service_rsyslog_enabled - # PASS_MIN_LEN is handled by PAM on debian systems. - - '!accounts_password_minlen_login_defs' - # ANSSI BP 28 suggest using libpam_pwquality, which isn't deployed by default - - 'package_pam_pwquality_installed' - # PAM honour login.defs file for algorithm - - 'set_password_hashing_algorithm_logindefs' - # Debian uses apparmor - - '!selinux_state' - - '!audit_rules_mac_modification' - - '!selinux_policytype' - - '!sebool_selinuxuser_execheap' - - '!sebool_deny_execmem' - - '!sebool_selinuxuser_execstack' - - '!sebool_secure_mode_insmod' - - '!sebool_ssh_sysadm_login' - - # The following are MLS related rules (not part of ANSSI-BP-028) - - '!accounts_polyinstantiated_tmp' - - '!accounts_polyinstantiated_var_tmp' - - '!enable_pam_namespace' - # there is no tmp.mount unit on Debian 12. - - '!systemd_tmp_mount_enabled' - # this rule cannot handle /etc/chrony/chrony.conf path properly. - # chronyd_specify_remote_server still reports whether chrony is configured. - - '!chronyd_configure_pool_and_server' - - # Following rules aren't compatible with Debian 13 - - '!accounts_passwords_pam_tally2_deny_root' - - '!ensure_redhat_gpgkey_installed' - - '!package_sequoia-sq_installed' - - '!set_password_hashing_algorithm_systemauth' - - '!package_dnf-automatic_installed' - - '!dnf-automatic_security_updates_only' - - '!cracklib_accounts_password_pam_lcredit' - - '!dnf-automatic_apply_updates' - - '!cracklib_accounts_password_pam_ocredit' - - '!accounts_password_pam_unix_rounds_system_auth' - - '!timer_dnf-automatic_enabled' - - '!accounts_passwords_pam_tally2' - - '!cracklib_accounts_password_pam_ucredit' - - '!file_permissions_unauthorized_sgid' - - '!ensure_gpgcheck_local_packages' - - '!accounts_passwords_pam_tally2_unlock_time' - - '!enable_authselect' - - '!cracklib_accounts_password_pam_minlen' - - '!cracklib_accounts_password_pam_dcredit' - - '!ensure_gpgcheck_globally_activated' - - '!file_permissions_unauthorized_suid' - - '!ensure_gpgcheck_never_disabled' - - '!ensure_oracle_gpgkey_installed' - - '!ensure_almalinux_gpgkey_installed' - - '!package_dracut-fips-aesni_installed' - - '!audit_rules_file_deletion_events_renameat2' - - '!audit_rules_dac_modification_fchmodat2' - - '!ldap_client_tls_cacertpath' - - '!ldap_client_start_tls' - - '!service_chronyd_enabled' - - '!audit_rules_mac_modification_etc_selinux' - - '!no_nis_in_nsswitch' diff --git a/products/debian13/profiles/anssi_bp28_intermediary.profile b/products/debian13/profiles/anssi_bp28_intermediary.profile deleted file mode 100644 index b1c9bf586cbf..000000000000 --- a/products/debian13/profiles/anssi_bp28_intermediary.profile +++ /dev/null @@ -1,64 +0,0 @@ -documentation_complete: true - -title: 'ANSSI-BP-028 (intermediary)' - -description: |- - This profile contains configurations that align to ANSSI-BP-028 v2.0 at the intermediary hardening level. - - ANSSI is the French National Information Security Agency, and stands for Agence nationale de la sécurité des systèmes d'information. - ANSSI-BP-028 is a configuration recommendation for GNU/Linux systems. - - A copy of the ANSSI-BP-028 can be found at the ANSSI website: - https://www.ssi.gouv.fr/administration/guide/recommandations-de-securite-relatives-a-un-systeme-gnulinux/ - -# selinux_state: not applicable -# postfix_client_configure_mail_alias: not applicable. should be exim -# grub2_l1tf_argument debian kernels are not vulnerable, but switching from -# conditional cache flush to force mode prevent protection disabling. - -selections: - - anssi:all:intermediary - # PASS_MIN_LEN is handled by PAM on debian systems. - - '!accounts_password_minlen_login_defs' - # ANSSI BP 28 suggest using libpam_pwquality, which isn't deployed by default - - 'package_pam_pwquality_installed' - # PAM honour login.defs file for algorithm - - 'set_password_hashing_algorithm_logindefs' - # Debian uses apparmor - - '!selinux_state' - # The following are MLS related rules (not part of ANSSI-BP-028) - - '!accounts_polyinstantiated_tmp' - - '!accounts_polyinstantiated_var_tmp' - - '!enable_pam_namespace' - - # Following rules aren't compatible with Debian 13 - - '!accounts_passwords_pam_tally2_deny_root' - - '!ensure_redhat_gpgkey_installed' - - '!package_sequoia-sq_installed' - - '!set_password_hashing_algorithm_systemauth' - - '!package_dnf-automatic_installed' - - '!dnf-automatic_security_updates_only' - - '!cracklib_accounts_password_pam_lcredit' - - '!dnf-automatic_apply_updates' - - '!cracklib_accounts_password_pam_ocredit' - - '!accounts_password_pam_unix_rounds_system_auth' - - '!timer_dnf-automatic_enabled' - - '!accounts_passwords_pam_tally2' - - '!cracklib_accounts_password_pam_ucredit' - - '!file_permissions_unauthorized_sgid' - - '!ensure_gpgcheck_local_packages' - - '!accounts_passwords_pam_tally2_unlock_time' - - '!enable_authselect' - - '!cracklib_accounts_password_pam_minlen' - - '!cracklib_accounts_password_pam_dcredit' - - '!ensure_gpgcheck_globally_activated' - - '!file_permissions_unauthorized_suid' - - '!ensure_gpgcheck_never_disabled' - - '!ensure_oracle_gpgkey_installed' - - '!ensure_almalinux_gpgkey_installed' - - # The following rule is not applicable to Debian 13 - - '!logind_session_timeout' - - '!ldap_client_tls_cacertpath' - - '!ldap_client_start_tls' - - '!no_nis_in_nsswitch' diff --git a/products/debian13/profiles/anssi_bp28_minimal.profile b/products/debian13/profiles/anssi_bp28_minimal.profile deleted file mode 100644 index 1fa965edd67d..000000000000 --- a/products/debian13/profiles/anssi_bp28_minimal.profile +++ /dev/null @@ -1,47 +0,0 @@ -documentation_complete: true - -title: 'ANSSI-BP-028 (minimal)' - -description: |- - This profile contains configurations that align to ANSSI-BP-028 v2.0 at the minimal hardening level. - - ANSSI is the French National Information Security Agency, and stands for Agence nationale de la sécurité des systèmes d'information. - ANSSI-BP-028 is a configuration recommendation for GNU/Linux systems. - - A copy of the ANSSI-BP-028 can be found at the ANSSI website: - https://www.ssi.gouv.fr/administration/guide/recommandations-de-securite-relatives-a-un-systeme-gnulinux/ - -selections: - - anssi:all:minimal - # PASS_MIN_LEN is handled by PAM on debian systems. - - '!accounts_password_minlen_login_defs' - # ANSSI BP 28 suggest using libpam_pwquality, which isn't deployed by default - - 'package_pam_pwquality_installed' - # PAM honour login.defs file for algorithm - - 'set_password_hashing_algorithm_logindefs' - - # Following rules aren't compatible with Debian 13 - - '!accounts_passwords_pam_tally2_deny_root' - - '!ensure_redhat_gpgkey_installed' - - '!package_sequoia-sq_installed' - - '!set_password_hashing_algorithm_systemauth' - - '!package_dnf-automatic_installed' - - '!dnf-automatic_security_updates_only' - - '!cracklib_accounts_password_pam_lcredit' - - '!dnf-automatic_apply_updates' - - '!cracklib_accounts_password_pam_ocredit' - - '!accounts_password_pam_unix_rounds_system_auth' - - '!timer_dnf-automatic_enabled' - - '!accounts_passwords_pam_tally2' - - '!cracklib_accounts_password_pam_ucredit' - - '!file_permissions_unauthorized_sgid' - - '!ensure_gpgcheck_local_packages' - - '!accounts_passwords_pam_tally2_unlock_time' - - '!enable_authselect' - - '!cracklib_accounts_password_pam_minlen' - - '!cracklib_accounts_password_pam_dcredit' - - '!ensure_gpgcheck_globally_activated' - - '!file_permissions_unauthorized_suid' - - '!ensure_gpgcheck_never_disabled' - - '!ensure_oracle_gpgkey_installed' - - '!ensure_almalinux_gpgkey_installed' diff --git a/products/debian13/profiles/cis_level1_workstation.profile b/products/debian13/profiles/cis_level1_workstation.profile new file mode 100644 index 000000000000..4d21e7a78370 --- /dev/null +++ b/products/debian13/profiles/cis_level1_workstation.profile @@ -0,0 +1,19 @@ +documentation_complete: true + +metadata: + version: 1.1.0 + +reference: https://www.cisecurity.org/benchmark/debian_linux + +title: 'CIS Debian Benchmark for Level 1 - Workstation' + +description: |- + This profile defines a baseline that aligns to the "Level 1 - Workstation" + configuration from the Center for Internet Security® + Debian 13 Benchmark™, v1.0.0, released 2025-12-16. + + This profile includes Center for Internet Security® + Debian 13 Benchmark™ content. + +selections: + - cis_debian12:all:l1_workstation diff --git a/products/debian13/profiles/cis_level2_server.profile b/products/debian13/profiles/cis_level2_server.profile new file mode 100644 index 000000000000..330980e144e7 --- /dev/null +++ b/products/debian13/profiles/cis_level2_server.profile @@ -0,0 +1,19 @@ +documentation_complete: true + +metadata: + version: 1.1.0 + +reference: https://www.cisecurity.org/benchmark/debian_linux + +title: 'CIS Debian Benchmark for Level 2 - Server' + +description: |- + This profile defines a baseline that aligns to the "Level 2 - Server" + configuration from the Center for Internet Security® + Debian 13 Benchmark™, v1.0.0, released 2025-12-16. + + This profile includes Center for Internet Security® + Debian 13 Benchmark™ content. + +selections: + - cis_debian12:all:l2_server diff --git a/products/debian13/profiles/cis_level2_workstation.profile b/products/debian13/profiles/cis_level2_workstation.profile new file mode 100644 index 000000000000..f928458a0261 --- /dev/null +++ b/products/debian13/profiles/cis_level2_workstation.profile @@ -0,0 +1,19 @@ +documentation_complete: true + +metadata: + version: 1.1.0 + +reference: https://www.cisecurity.org/benchmark/debian_linux + +title: 'CIS Debian Benchmark for Level 2 - Workstation' + +description: |- + This profile defines a baseline that aligns to the "Level 2 - Workstation" + configuration from the Center for Internet Security® + Debian 13 Benchmark™, v1.0.0, released 2025-12-16. + + This profile includes Center for Internet Security® + Debian 13 Benchmark™ content. + +selections: + - cis_debian12:all:l2_workstation diff --git a/products/debian13/profiles/standard.profile b/products/debian13/profiles/standard.profile deleted file mode 100644 index 5e52ca223928..000000000000 --- a/products/debian13/profiles/standard.profile +++ /dev/null @@ -1,57 +0,0 @@ -documentation_complete: true - -title: 'Standard System Security Profile for Debian 13' - -description: |- - This profile contains rules to ensure standard security baseline - of a Debian 13 system. Regardless of your system's workload - all of these checks should pass. - -selections: - - partition_for_tmp - - partition_for_var - - partition_for_var_log - - partition_for_var_log_audit - - partition_for_home - - package_audit_installed - - package_cron_installed - - package_ntp_installed - - package_rsyslog_installed - - package_telnetd_removed - - package_inetutils-telnetd_removed - - package_telnetd-ssl_removed - - package_nis_removed - - package_ntpdate_removed - - service_auditd_enabled - - service_cron_enabled - - service_ntp_enabled - - service_rsyslog_enabled - - sshd_idle_timeout_value=5_minutes - - sshd_set_idle_timeout - - sshd_disable_root_login - - sshd_disable_empty_passwords - - sshd_allow_only_protocol2 - - var_sshd_set_keepalive=1 - - sshd_set_keepalive - - rsyslog_files_ownership - - rsyslog_files_groupownership - - rsyslog_files_permissions - - "!rsyslog_remote_loghost" - - ensure_logrotate_activated - - file_permissions_systemmap - - file_permissions_etc_shadow - - file_owner_etc_shadow - - file_groupowner_etc_shadow - - file_permissions_etc_gshadow - - file_owner_etc_gshadow - - file_groupowner_etc_gshadow - - file_permissions_etc_passwd - - file_owner_etc_passwd - - file_groupowner_etc_passwd - - file_permissions_etc_group - - file_owner_etc_group - - file_groupowner_etc_group - - sysctl_fs_protected_symlinks - - sysctl_fs_protected_hardlinks - - sysctl_fs_suid_dumpable - - sysctl_kernel_randomize_va_space From e4fa427da545596f1bc0b1bdbfc64ed05da47dc8 Mon Sep 17 00:00:00 2001 From: Israel Villar Boillos Date: Sun, 29 Mar 2026 22:52:44 +0100 Subject: [PATCH 02/61] Add Debian 13 CIS policy and product skeleton --- controls/cis_debian13.yml | 2857 ++++++++++++++++- .../profiles/cis_level1_workstation.profile | 2 +- .../profiles/cis_level2_server.profile | 2 +- .../profiles/cis_level2_workstation.profile | 2 +- 4 files changed, 2692 insertions(+), 171 deletions(-) diff --git a/controls/cis_debian13.yml b/controls/cis_debian13.yml index f409e5958dfd..9717e1ca537c 100644 --- a/controls/cis_debian13.yml +++ b/controls/cis_debian13.yml @@ -92,15 +92,6 @@ controls: status: automated - id: 1.1.1.9 - title: Ensure firewire-core kernel module is not available (Automated) - levels: - - l1_server - - l2_workstation - rules: - - kernel_module_firewire-core_disabled - status: automated - - - id: 1.1.1.10 title: Ensure usb-storage kernel module is not available (Automated) levels: - l1_server @@ -109,7 +100,7 @@ controls: - kernel_module_usb-storage_disabled status: automated - - id: 1.1.1.11 + - id: 1.1.1.10 title: Ensure unused filesystems kernel modules are not available (Manual) levels: - l1_server @@ -153,7 +144,7 @@ controls: status: automated - id: 1.1.2.2.1 - title: Ensure /dev/shm is tmpfs or a separate partition (Automated) + title: Ensure /dev/shm is a separate partition (Automated) levels: - l1_server - l1_workstation @@ -351,102 +342,34 @@ controls: status: automated - id: 1.2.1.1 - title: Ensure the source.list and .source files use the Signed-By option (Manual) + title: Ensure GPG keys are configured (Manual) levels: - l1_server - l1_workstation status: manual - id: 1.2.1.2 - title: Ensure weak dependencies are configured (Automated) - levels: - - l2_server - - l2_workstation - status: pending - notes: |- - Needs a new Debian-specific rule checking weak dependencies - - - id: 1.2.1.3 - title: Ensure access to gpg key files are configured (Automated) - levels: - - l1_server - - l2_server - status: pending - notes: |- - Needs a new Debian-specific rule for GPG key file access checks. - Check if all .gpg key files in /usr/share/keyrings/ and /etc/apt/trusted.gpg.d have permissions 0644 and owned by root:root - Check if .list and .sources in /etc/apt/sources.list.d have permissions 0644 and owned by root:root and include option signed-by - - - id: 1.2.1.4 - title: Ensure access to /etc/apt/trusted.gpg.d directory is configured - levels: - - l1_server - - l2_server - status: pending - notes: |- - Needs a new Debian-specific rule for /etc/apt/trusted.gpg.d directory access checks. - Check if /etc/apt/trusted.gpg.d has permissions 0755 and owned by root:root - - - id: 1.2.1.5 - title: Ensure access to /etc/apt/auth.conf.d directory is configured (Automated) - levels: - - l1_server - - l2_server - status: pending - notes: |- - Check if /etc/apt/auth.conf.d has permissions 0755 and owned by root:root - - - id: 1.2.1.6 - title: Ensure access to files in the /etc/apt/auth.conf.d/ directory is configured (Automated) - levels: - - l1_server - - l1_workstation - status: pending - notes: |- - Check if /etc/apt/auth.conf.d/* has permissions 0755 and owned by root:root - - - id: 1.2.1.7 - title: Ensure access to /usr/share/keyrings directory is configured (Automated) - levels: - - l1_server - - l2_server - status: pending - notes: |- - Check if /usr/share/keyrings has permissions 0755 and owned by root:root - - - id: 1.2.1.8 - title: Ensure access to /etc/apt/sources.list.d directory is configured (Automated) - levels: - - l1_server - - l2_server - status: pending - notes: |- - Check if /etc/apt/sources.list.d has permissions 0755 and owned by root:root - - - id: 1.2.1.9 - title: Ensure access to files in /etc/apt/sources.list.d are configured (Automated) + title: Ensure package manager repositories are configured (Manual) levels: - l1_server - - l2_server - status: pending - notes: |- - Check if /etc/apt/sources.list.d/* has permissions 0755 and owned by root:root + - l1_workstation + status: manual - id: 1.2.2.1 title: Ensure updates, patches, and additional security software are installed (Manual) levels: - - l1_server - - l1_workstation + - l1_server + - l1_workstation status: manual - id: 1.3.1.1 - title: Ensure AppArmor is installed (Automated) + title: Ensure AppArmor is installed (Automated) levels: - - l1_server - - l1_workstation + - l1_server + - l1_workstation rules: - - package_apparmor_installed - - package_apparmor-utils_installed + - package_apparmor_installed + - package_apparmor-utils_installed status: automated - id: 1.3.1.2 @@ -459,6 +382,24 @@ controls: status: automated - id: 1.3.1.3 + title: Ensure all AppArmor Profiles are in enforce or complain mode (Automated) + levels: + - l1_server + - l1_workstation + rules: + - var_apparmor_mode=complain + - all_apparmor_profiles_in_enforce_complain_mode + status: automated + notes: | + CIS recommendation does not adequately address the nuances + of various profiles, including disabled, force-complain, + and unconfined. Currently, the control changes the default apparmor + mode for all profiles in /etc/apparmor.d which can + break certain applications. See https://workbench.cisecurity.org/benchmarks/18959/tickets/23987 + The remediation for this rule sets apparmor in complain mode. The remediation can be + deactivated by setting var_apparmor_mode to keep_existing_mode + + - id: 1.3.1.4 title: Ensure all AppArmor Profiles are enforcing (Automated) levels: - l2_server @@ -473,15 +414,6 @@ controls: mode for all profiles in /etc/apparmor.d which can break certain applications. See https://workbench.cisecurity.org/benchmarks/18959/tickets/23987 - - id: 1.3.1.4 - title: Ensure apparmor_restrict_unprivileged_unconfined is enabled (Automated) - levels: - - l1_server - - l1_workstation - status: pending - notes: |- - Check if sysctl kernel.apparmor_restrict_unprivileged_unconfined = 1 - - id: 1.4.1 title: Ensure bootloader password is set (Automated) levels: @@ -503,129 +435,2718 @@ controls: status: automated - id: 1.5.1 - title: Ensure fs.protected_hardlinks is configured (Automated) + title: Ensure address space layout randomization is enabled (Automated) levels: - l1_server - l1_workstation rules: - - sysctl_fs_protected_hardlinks + - sysctl_kernel_randomize_va_space status: automated - id: 1.5.2 - title: Ensure fs.protected_symlinks is configured (Automated) + title: Ensure ptrace_scope is restricted (Automated) + levels: + - l1_server + - l1_workstation + rules: + - sysctl_kernel_yama_ptrace_scope_value=1 + - sysctl_kernel_yama_ptrace_scope + status: automated + + - id: 1.5.3 + title: Ensure core dumps are restricted (Automated) + levels: + - l1_server + - l1_workstation + rules: + - disable_users_coredumps + - sysctl_fs_suid_dumpable + status: automated + + - id: 1.6.1 + title: Ensure message of the day is configured properly (Automated) + levels: + - l1_server + - l1_workstation + rules: + - cis_banner_text=cis + - banner_etc_motd_cis + status: automated + + - id: 1.6.2 + title: Ensure local login warning banner is configured properly (Automated) + levels: + - l1_server + - l1_workstation + rules: + - cis_banner_text=cis + - banner_etc_issue_cis + status: automated + + - id: 1.6.3 + title: Ensure remote login warning banner is configured properly (Automated) + levels: + - l1_server + - l1_workstation + rules: + - cis_banner_text=cis + - banner_etc_issue_net_cis + status: automated + + - id: 1.6.4 + title: Ensure access to /etc/motd is configured (Automated) + levels: + - l1_server + - l1_workstation + rules: + - file_groupowner_etc_motd + - file_owner_etc_motd + - file_permissions_etc_motd + status: automated + + - id: 1.6.5 + title: Ensure access to /etc/issue is configured (Automated) + levels: + - l1_server + - l1_workstation + rules: + - file_groupowner_etc_issue + - file_owner_etc_issue + - file_permissions_etc_issue + status: automated + + - id: 1.6.6 + title: Ensure access to /etc/issue.net is configured (Automated) + levels: + - l1_server + - l1_workstation + rules: + - file_groupowner_etc_issue_net + - file_owner_etc_issue_net + - file_permissions_etc_issue_net + status: automated + + - id: 1.7.1 + title: Ensure GDM is removed (Automated) levels: - l2_server + rules: + - package_gdm_removed + status: automated + + - id: 1.7.2 + title: Ensure GDM login banner is configured (Automated) + levels: + - l1_server + - l1_workstation + rules: + - dconf_login_banner_text=cis_default + - dconf_login_banner_contents=cis_default + - dconf_gnome_banner_enabled + - dconf_gnome_login_banner_text + status: automated + + - id: 1.7.3 + title: Ensure GDM disable-user-list option is enabled (Automated) + levels: + - l1_server + - l1_workstation + rules: + - dconf_gnome_disable_user_list + status: automated + + - id: 1.7.4 + title: Ensure GDM screen locks when the user is idle (Automated) + levels: + - l1_server + - l1_workstation + rules: + - inactivity_timeout_value=15_minutes + - var_screensaver_lock_delay=5_seconds + - dconf_gnome_screensaver_idle_delay + - dconf_gnome_screensaver_lock_enabled + - dconf_gnome_screensaver_lock_delay + status: automated + notes: | + The rules satisfy both controls 1.7.4 and 1.7.5. + Rule lock_enabled is not part of CIS recommendation but is + required to assure the lock is enabled and cannot be manually disabled. + See https://workbench.cisecurity.org/benchmarks/18959/tickets/23123 + + - id: 1.7.5 + title: Ensure GDM screen locks cannot be overridden (Automated) + levels: + - l1_server + - l1_workstation + rules: + - dconf_gnome_screensaver_idle_delay + - dconf_gnome_screensaver_lock_enabled + - dconf_gnome_screensaver_lock_delay + status: automated + notes: | + The rules satisfy both controls 1.7.4 and 1.7.5. + Rule lock_enabled is not part of CIS recommendation but is + required to assure the lock is enabled and cannot be manually disabled. + See https://workbench.cisecurity.org/benchmarks/18959/tickets/23123 + + - id: 1.7.6 + title: Ensure GDM automatic mounting of removable media is disabled (Automated) + levels: + - l1_server - l2_workstation rules: - - sysctl_fs_protected_symlinks + - dconf_gnome_disable_automount + - dconf_gnome_disable_automount_open status: automated + notes: | + The rules satisfy both controls 1.7.6 and 1.7.7 - - id: 1.5.3 - title: Ensure kernel.yama.ptrace_scope is configured (Automated) + - id: 1.7.7 + title: Ensure GDM disabling automatic mounting of removable media is not overridden (Automated) + levels: + - l1_server + - l2_workstation + rules: + - dconf_gnome_disable_automount + - dconf_gnome_disable_automount_open + status: automated + notes: | + The rules satisfy both controls 1.7.6 and 1.7.7 + + - id: 1.7.8 + title: Ensure GDM autorun-never is enabled (Automated) + levels: + - l1_server + - l1_workstation + rules: + - dconf_gnome_disable_autorun + status: automated + notes: | + The rule satisfies both controls 1.7.8 and 1.7.9 + + - id: 1.7.9 + title: Ensure GDM autorun-never is not overridden (Automated) + levels: + - l1_server + - l1_workstation + rules: + - dconf_gnome_disable_autorun + status: automated + notes: | + The rule satisfies both controls 1.7.8 and 1.7.9 + + - id: 1.7.10 + title: Ensure XDMCP is not enabled (Automated) levels: - - l1_server - - l1_workstation + - l1_server + - l1_workstation rules: - - sysctl_kernel_yama_ptrace_scope + - gnome_gdm_disable_xdmcp status: automated - - id: 1.5.4 - title: Ensure fs.suid_dumpable is configured (Automated) + - id: 2.1.1 + title: Ensure autofs services are not in use (Automated) levels: - - l1_server - - l1_workstation - rules: - - sysctl_fs_suid_dumpable + - l1_server + - l2_workstation + rules: + - service_autofs_disabled + - package_autofs_removed status: automated - - id: 1.5.5 - title: Ensure kernel.dmesg_restrict is configured (Automated) + - id: 2.1.2 + title: Ensure avahi daemon services are not in use (Automated) levels: - - l1_server - - l1_workstation + - l1_server + - l2_workstation rules: - - sysctl_kernel_dmesg_restrict + - package_avahi_removed + - service_avahi-daemon_disabled status: automated - - id: 1.5.6 - title: Ensure prelink is not installed (Automated) + - id: 2.1.3 + title: Ensure dhcp server services are not in use (Automated) levels: - - l1_server - - l1_workstation + - l1_server + - l1_workstation rules: - - disable_prelink + - package_dhcp_removed + - service_dhcpd_disabled + - service_dhcpd6_disabled status: automated - - id: 1.5.7 - title: Ensure Automatic Error Reporting is configured (Automated) + - id: 2.1.4 + title: Ensure dns server services are not in use (Automated) levels: - - l1_server - - l1_workstation - status: pending - notes: |- - Check if systemctl is-active apport.service , fail if it's active - Check if apport is installed , if it's not installed pass + - l1_server + - l1_workstation + rules: + - package_bind_removed + - service_named_disabled + status: automated - - id: 1.5.8 - title: Ensure kernel.kptr_restrict is configured (Automated) + - id: 2.1.5 + title: Ensure dnsmasq services are not in use (Automated) levels: - - l1_server - - l1_workstation + - l1_server + - l1_workstation rules: - - sysctl_kernel_kptr_restrict + - package_dnsmasq_removed + - service_dnsmasq_disabled status: automated - - id: 1.5.9 - title: Ensure kernel.randomize_va_space is configured (Automated) + - id: 2.1.6 + title: Ensure ftp server services are not in use (Automated) levels: - - l1_server - - l1_workstation + - l1_server + - l1_workstation rules: - - sysctl_kernel_randomize_va_space + - package_vsftpd_removed + - service_vsftpd_disabled status: automated - - id: 1.5.10 - title: Ensure kernel.yama.ptrace_scope is configured (Automated) + - id: 2.1.7 + title: Ensure ldap server services are not in use (Automated) levels: - - l1_server - - l1_workstation + - l1_server + - l1_workstation rules: - - sysctl_kernel_yama_ptrace_scope + - package_openldap-servers_removed + - service_slapd_disabled status: automated - - id: 1.5.11 - title: Ensure core file size is configured (Automated) + - id: 2.1.8 + title: Ensure message access server services are not in use (Automated) levels: - - l1_server - - l1_workstation + - l1_server + - l1_workstation rules: - - disable_users_coredumps + - package_dovecot_removed + - service_dovecot_disabled + status: automated - - id: 1.5.12 - title: Ensure systemd-coredump ProcessSizeMax is configured (Automated) + - id: 2.1.9 + title: Ensure network file system services are not in use (Automated) levels: - - l1_server - - l1_workstation + - l1_server + - l1_workstation rules: - - coredump_disable_backtraces + - package_nfs-kernel-server_removed + - service_nfs_disabled status: automated - - id: 1.5.13 - title: Ensure systemd-coredump Storage is configured (Automated) + - id: 2.1.10 + title: Ensure nis server services are not in use (Automated) levels: - - l1_server - - l1_workstation + - l1_server + - l1_workstation rules: - - coredump_disable_storage + - package_ypserv_removed + - service_ypserv_disabled status: automated - - id: 1.6.1 - title: Ensure /etc/motd is configured (Automated) + - id: 2.1.11 + title: Ensure print server services are not in use (Automated) + levels: + - l1_server + - l2_workstation + rules: + - package_cups_removed + - service_cups_disabled + status: automated + + - id: 2.1.12 + title: Ensure rpcbind services are not in use (Automated) + levels: + - l1_server + - l1_workstation + rules: + - package_rpcbind_removed + - service_rpcbind_disabled + status: automated + + - id: 2.1.13 + title: Ensure rsync services are not in use (Automated) + levels: + - l1_server + - l1_workstation + rules: + - package_rsync_removed + - service_rsyncd_disabled + status: automated + + - id: 2.1.14 + title: Ensure samba file server services are not in use (Automated) + levels: + - l1_server + - l1_workstation + rules: + - package_samba_removed + - service_smb_disabled + status: automated + + - id: 2.1.15 + title: Ensure snmp services are not in use (Automated) + levels: + - l1_server + - l1_workstation + rules: + - package_net-snmp_removed + - service_snmpd_disabled + status: automated + + - id: 2.1.16 + title: Ensure tftp server services are not in use (Automated) + levels: + - l1_server + - l1_workstation + rules: + - package_tftp-server_removed + - service_tftp_disabled + status: automated + + - id: 2.1.17 + title: Ensure web proxy server services are not in use (Automated) + levels: + - l1_server + - l1_workstation + rules: + - package_squid_removed + - service_squid_disabled + status: automated + + - id: 2.1.18 + title: Ensure web server services are not in use (Automated) + levels: + - l1_server + - l1_workstation + rules: + - package_httpd_removed + - package_nginx_removed + - service_httpd_disabled + - service_nginx_disabled + status: automated + + - id: 2.1.19 + title: Ensure xinetd services are not in use (Automated) + levels: + - l1_server + - l1_workstation + rules: + - package_xinetd_removed + - service_xinetd_disabled + status: automated + + - id: 2.1.20 + title: Ensure X window server services are not in use (Automated) + levels: + - l2_server + rules: + - package_xorg-x11-server-common_removed + status: automated + + - id: 2.1.21 + title: Ensure mail transfer agent is configured for local-only mode (Automated) levels: - - l1_server - - l1_workstation + - l1_server + - l1_workstation rules: - - banner_etc_motd_cis - - cis_banner_text=cis + - has_nonlocal_mta + - var_postfix_inet_interfaces=loopback-only + - postfix_network_listening_disabled status: automated + - id: 2.1.22 + title: Ensure only approved services are listening on a network interface (Manual) + levels: + - l1_server + - l1_workstation + status: manual + + - id: 2.2.1 + title: Ensure NIS Client is not installed (Automated) + levels: + - l1_server + - l1_workstation + rules: + - package_nis_removed + status: automated + + - id: 2.2.2 + title: Ensure rsh client is not installed (Automated) + levels: + - l1_server + - l1_workstation + rules: + - package_rsh_removed + status: automated + + - id: 2.2.3 + title: Ensure talk client is not installed (Automated) + levels: + - l1_server + - l1_workstation + rules: + - package_talk_removed + status: automated + + - id: 2.2.4 + title: Ensure telnet client is not installed (Automated) + levels: + - l1_server + - l1_workstation + rules: + - package_inetutils-telnet_removed + - package_telnet_removed + status: automated + + - id: 2.2.5 + title: Ensure ldap client is not installed (Automated) + levels: + - l1_server + - l1_workstation + rules: + - package_openldap-clients_removed + status: automated + + - id: 2.2.6 + title: Ensure ftp client is not installed (Automated) + levels: + - l1_server + - l1_workstation + rules: + - package_ftp_removed + - package_tnftp_removed + status: automated + + - id: 2.3.1.1 + title: Ensure a single time synchronization daemon is in use (Automated) + levels: + - l1_server + - l1_workstation + rules: + - var_timesync_service=systemd-timesyncd + - package_chrony_installed + - service_chronyd_enabled + - service_chronyd_disabled + - package_timesyncd_installed + - service_timesyncd_enabled + - service_timesyncd_disabled + - ntp_single_service_active + status: automated + notes: | + To select which timesync daemon to install and configure, use the + profile variable var_timesync_service. + + - id: 2.3.2.1 + title: Ensure systemd-timesyncd configured with authorized timeserver (Automated) + levels: + - l1_server + - l1_workstation + rules: + - var_multiple_time_servers=debian + - service_timesyncd_configured + status: automated + + - id: 2.3.2.2 + title: Ensure systemd-timesyncd is enabled and running (Automated) + levels: + - l1_server + - l1_workstation + related_rules: + - service_timesyncd_enabled + - service_timesyncd_disabled + status: automated + notes: Implemented in 2.3.1.1 + + - id: 2.3.3.1 + title: Ensure chrony is configured with authorized timeserver (Automated) + levels: + - l1_server + - l1_workstation + rules: + - var_multiple_time_servers=debian + - var_multiple_time_pools=debian + - chronyd_configure_pool_and_server + status: partial + notes: | + Rule does not check or remediate config files included via + confdir and sourcedir directives. + + - id: 2.3.3.2 + title: Ensure chrony is running as user _chrony (Automated) + levels: + - l1_server + - l1_workstation + rules: + - chronyd_run_as_chrony_user + status: automated + + - id: 2.3.3.3 + title: Ensure chrony is enabled and running (Automated) + levels: + - l1_server + - l1_workstation + related_rules: + - service_chronyd_enabled + - service_chronyd_disabled + status: automated + notes: Implemented in 2.3.1.1 + + - id: 2.4.1.1 + title: Ensure cron daemon is enabled and active (Automated) + levels: + - l1_server + - l1_workstation + rules: + - package_cron_installed + - service_cron_enabled + status: automated + + - id: 2.4.1.2 + title: Ensure permissions on /etc/crontab are configured (Automated) + levels: + - l1_server + - l1_workstation + rules: + - file_cron_allow_exists + - file_groupowner_crontab + - file_owner_crontab + - file_permissions_crontab + status: automated + + - id: 2.4.1.3 + title: Ensure permissions on /etc/cron.hourly are configured (Automated) + levels: + - l1_server + - l1_workstation + rules: + - file_groupowner_cron_hourly + - file_owner_cron_hourly + - file_permissions_cron_hourly + status: automated + + - id: 2.4.1.4 + title: Ensure permissions on /etc/cron.daily are configured (Automated) + levels: + - l1_server + - l1_workstation + rules: + - file_groupowner_cron_daily + - file_owner_cron_daily + - file_permissions_cron_daily + status: automated + + - id: 2.4.1.5 + title: Ensure permissions on /etc/cron.weekly are configured (Automated) + levels: + - l1_server + - l1_workstation + rules: + - file_groupowner_cron_weekly + - file_owner_cron_weekly + - file_permissions_cron_weekly + status: automated + + - id: 2.4.1.6 + title: Ensure permissions on /etc/cron.monthly are configured (Automated) + levels: + - l1_server + - l1_workstation + rules: + - file_groupowner_cron_monthly + - file_owner_cron_monthly + - file_permissions_cron_monthly + status: automated + + - id: 2.4.1.7 + title: Ensure permissions on /etc/cron.d are configured (Automated) + levels: + - l1_server + - l1_workstation + rules: + - file_groupowner_cron_d + - file_owner_cron_d + - file_permissions_cron_d + status: automated + + - id: 2.4.1.8 + title: Ensure crontab is restricted to authorized users (Automated) + levels: + - l1_server + - l1_workstation + rules: + - file_cron_deny_not_exist + - file_groupowner_cron_allow + - file_owner_cron_allow + - file_permissions_cron_allow + status: automated + + - id: 2.4.2.1 + title: Ensure at is restricted to authorized users (Automated) + levels: + - l1_server + - l1_workstation + rules: + - file_at_allow_exists + - file_groupowner_at_allow + - file_owner_at_allow + - file_permissions_at_allow + - file_groupowner_at_deny + - file_owner_at_deny + - file_permissions_at_deny + status: automated + notes: file_owner_at_deny and file_owner_at_allow currently require root as owner and don't accept + daemon + + - id: 3.1.1 + title: Ensure IPv6 status is identified (Manual) + levels: + - l1_server + - l1_workstation + status: manual + + - id: 3.1.2 + title: Ensure wireless interfaces are disabled (Automated) + levels: + - l1_server + rules: + - wireless_disable_interfaces + status: automated + + - id: 3.1.3 + title: Ensure bluetooth services are not in use (Automated) + levels: + - l1_server + - l2_workstation + rules: + - service_bluetooth_disabled + status: automated + + - id: 3.2.1 + title: Ensure dccp kernel module is not available (Automated) + levels: + - l2_server + - l2_workstation + rules: + - kernel_module_dccp_disabled + status: automated + + - id: 3.2.2 + title: Ensure tipc kernel module is not available (Automated) + levels: + - l2_server + - l2_workstation + rules: + - kernel_module_tipc_disabled + status: automated + + - id: 3.2.3 + title: Ensure rds kernel module is not available (Automated) + levels: + - l2_server + - l2_workstation + rules: + - kernel_module_rds_disabled + status: automated + + - id: 3.2.4 + title: Ensure sctp kernel module is not available (Automated) + levels: + - l2_server + - l2_workstation + rules: + - kernel_module_sctp_disabled + status: automated + + - id: 3.3.1 + title: Ensure ip forwarding is disabled (Automated) + levels: + - l1_server + - l1_workstation + rules: + - sysctl_net_ipv6_conf_all_forwarding + - sysctl_net_ipv4_ip_forward + status: automated + + - id: 3.3.2 + title: Ensure packet redirect sending is disabled (Automated) + levels: + - l1_server + - l1_workstation + rules: + - sysctl_net_ipv4_conf_all_send_redirects + - sysctl_net_ipv4_conf_default_send_redirects + status: automated + + - id: 3.3.3 + title: Ensure bogus icmp responses are ignored (Automated) + levels: + - l1_server + - l1_workstation + rules: + - sysctl_net_ipv4_icmp_ignore_bogus_error_responses + status: automated + + - id: 3.3.4 + title: Ensure broadcast icmp requests are ignored (Automated) + levels: + - l1_server + - l1_workstation + rules: + - sysctl_net_ipv4_icmp_echo_ignore_broadcasts + status: automated + + - id: 3.3.5 + title: Ensure icmp redirects are not accepted (Automated) + levels: + - l1_server + - l1_workstation + rules: + - sysctl_net_ipv6_conf_all_accept_redirects + - sysctl_net_ipv6_conf_default_accept_redirects + - sysctl_net_ipv4_conf_all_accept_redirects + - sysctl_net_ipv4_conf_default_accept_redirects + status: automated + + - id: 3.3.6 + title: Ensure secure icmp redirects are not accepted (Automated) + levels: + - l1_server + - l1_workstation + rules: + - sysctl_net_ipv4_conf_all_secure_redirects + - sysctl_net_ipv4_conf_default_secure_redirects + status: automated + + - id: 3.3.7 + title: Ensure reverse path filtering is enabled (Automated) + levels: + - l1_server + - l1_workstation + rules: + - sysctl_net_ipv4_conf_all_rp_filter + - sysctl_net_ipv4_conf_default_rp_filter + status: automated + + - id: 3.3.8 + title: Ensure source routed packets are not accepted (Automated) + levels: + - l1_server + - l1_workstation + rules: + - sysctl_net_ipv6_conf_all_accept_source_route + - sysctl_net_ipv6_conf_default_accept_source_route + - sysctl_net_ipv4_conf_all_accept_source_route + - sysctl_net_ipv4_conf_default_accept_source_route + status: automated + + - id: 3.3.9 + title: Ensure suspicious packets are logged (Automated) + levels: + - l1_server + - l1_workstation + rules: + - sysctl_net_ipv4_conf_all_log_martians + - sysctl_net_ipv4_conf_default_log_martians + status: automated + + - id: 3.3.10 + title: Ensure tcp syn cookies is enabled (Automated) + levels: + - l1_server + - l1_workstation + rules: + - sysctl_net_ipv4_tcp_syncookies + status: automated + + - id: 3.3.11 + title: Ensure ipv6 router advertisements are not accepted (Automated) + levels: + - l1_server + - l1_workstation + rules: + - sysctl_net_ipv6_conf_all_accept_ra + - sysctl_net_ipv6_conf_default_accept_ra + status: automated + + - id: 4.1.1 + title: Ensure a single firewall configuration utility is in use (Automated) + levels: + - l1_server + - l1_workstation + rules: + - firewall_single_service_active + - var_network_filtering_service=nftables + status: automated + notes: | + Remediation is not automated. To select which firewall to + install and configure, use the profile variable var_network_filtering_service. + + - id: 4.2.1 + title: Ensure ufw is installed (Automated) + levels: + - l1_server + - l1_workstation + rules: + - package_ufw_installed + status: automated + + - id: 4.2.2 + title: Ensure iptables-persistent is not installed with ufw (Automated) + levels: + - l1_server + - l1_workstation + rules: + - package_iptables-persistent_removed + status: automated + + - id: 4.2.3 + title: Ensure ufw service is enabled (Automated) + levels: + - l1_server + - l1_workstation + rules: + - check_ufw_active + - service_ufw_enabled + status: automated + + - id: 4.2.4 + title: Ensure ufw loopback traffic is configured (Automated) + levels: + - l1_server + - l1_workstation + rules: + - set_ufw_loopback_traffic + status: automated + + - id: 4.2.5 + title: Ensure ufw outbound connections are configured (Manual) + levels: + - l1_server + - l1_workstation + status: manual + + - id: 4.2.6 + title: Ensure ufw firewall rules exist for all open ports (Automated) + levels: + - l1_server + - l1_workstation + rules: + - ufw_rules_for_open_ports + status: automated + + - id: 4.2.7 + title: Ensure ufw default deny firewall policy (Automated) + levels: + - l1_server + - l1_workstation + rules: + - set_ufw_default_rule + status: automated + + - id: 4.3.1 + title: Ensure nftables is installed (Automated) + levels: + - l1_server + - l1_workstation + rules: + - package_nftables_installed + status: automated + + - id: 4.3.2 + title: Ensure ufw is uninstalled or disabled with nftables (Automated) + levels: + - l1_server + - l1_workstation + rules: + - package_ufw_removed + status: automated + + - id: 4.3.3 + title: Ensure iptables are flushed with nftables (Manual) + levels: + - l1_server + - l1_workstation + status: manual + + - id: 4.3.4 + title: Ensure a nftables table exists (Automated) + levels: + - l1_server + - l1_workstation + rules: + - var_nftables_family=inet + - var_nftables_table=filter + - set_nftables_table + status: automated + + - id: 4.3.5 + title: Ensure nftables base chains exist (Automated) + levels: + - l1_server + - l1_workstation + rules: + - var_nftables_base_chain_names=chain_names + - var_nftables_base_chain_types=chain_types + - var_nftables_base_chain_hooks=chain_hooks + - var_nftables_base_chain_priorities=chain_priorities + - var_nftables_base_chain_policies=chain_policies + - set_nftables_base_chain + status: automated + + - id: 4.3.6 + title: Ensure nftables loopback traffic is configured (Automated) + levels: + - l1_server + - l1_workstation + rules: + - set_nftables_loopback_traffic + status: automated + + - id: 4.3.7 + title: Ensure nftables outbound and established connections are configured (Manual) + levels: + - l1_server + - l1_workstation + status: manual + + - id: 4.3.8 + title: Ensure nftables default deny firewall policy (Automated) + levels: + - l1_server + - l1_workstation + rules: + - nftables_ensure_default_deny_policy + status: automated + + - id: 4.3.9 + title: Ensure nftables service is enabled (Automated) + levels: + - l1_server + - l1_workstation + rules: + - service_nftables_enabled + status: automated + + - id: 4.3.10 + title: Ensure nftables rules are permanent (Automated) + levels: + - l1_server + - l1_workstation + rules: + - var_nftables_master_config_file=etc + - nftables_rules_permanent + status: automated + notes: | + Audit procedure for 4.3.10 depends on local site policy thus + it cannot be fully automated. Upstream ticket: + https://workbench.cisecurity.org/benchmarks/18959/tickets/23190 + + - id: 4.4.1.1 + title: Ensure iptables packages are installed (Automated) + levels: + - l1_server + - l1_workstation + rules: + - package_iptables-persistent_installed + - package_iptables_installed + status: automated + + - id: 4.4.1.2 + title: Ensure nftables is not in use with iptables (Automated) + levels: + - l1_server + - l1_workstation + rules: + - service_nftables_disabled + status: automated + + - id: 4.4.1.3 + title: Ensure ufw is not in use with iptables (Automated) + levels: + - l1_server + - l1_workstation + rules: + - package_ufw_removed + status: automated + + - id: 4.4.2.1 + title: Ensure iptables default deny firewall policy (Automated) + levels: + - l1_server + - l1_workstation + rules: + - set_iptables_default_rule + status: automated + + - id: 4.4.2.2 + title: Ensure iptables loopback traffic is configured (Automated) + levels: + - l1_server + - l1_workstation + rules: + - set_loopback_traffic + status: automated + + - id: 4.4.2.3 + title: Ensure iptables outbound and established connections are configured (Manual) + levels: + - l1_server + - l1_workstation + status: manual + + - id: 4.4.2.4 + title: Ensure iptables firewall rules exist for all open ports (Automated) + levels: + - l1_server + - l1_workstation + rules: + - iptables_rules_for_open_ports + status: automated + + - id: 4.4.3.1 + title: Ensure ip6tables default deny firewall policy (Automated) + levels: + - l1_server + - l1_workstation + rules: + - set_ip6tables_default_rule + status: automated + + - id: 4.4.3.2 + title: Ensure ip6tables loopback traffic is configured (Automated) + levels: + - l1_server + - l1_workstation + rules: + - set_ipv6_loopback_traffic + status: automated + + - id: 4.4.3.3 + title: Ensure ip6tables outbound and established connections are configured (Manual) + levels: + - l1_server + - l1_workstation + status: manual + + - id: 4.4.3.4 + title: Ensure ip6tables firewall rules exist for all open ports (Automated) + levels: + - l1_server + - l1_workstation + rules: + - ip6tables_rules_for_open_ports + status: automated + notes: | + Remediation is not automated to avoid lockout. + + - id: 5.1.1 + title: Ensure permissions on /etc/ssh/sshd_config are configured (Automated) + levels: + - l1_server + - l1_workstation + rules: + - file_groupowner_sshd_config + - file_owner_sshd_config + - file_permissions_sshd_config + status: automated + + - id: 5.1.2 + title: Ensure permissions on SSH private host key files are configured (Automated) + levels: + - l1_server + - l1_workstation + rules: + - file_permissions_sshd_private_key + status: automated + + - id: 5.1.3 + title: Ensure permissions on SSH public host key files are configured (Automated) + levels: + - l1_server + - l1_workstation + rules: + - file_permissions_sshd_pub_key + status: automated + + - id: 5.1.4 + title: Ensure sshd access is configured (Automated) + levels: + - l1_server + - l1_workstation + rules: + - sshd_limit_user_access + status: automated + + - id: 5.1.5 + title: Ensure sshd Banner is configured (Automated) + levels: + - l1_server + - l1_workstation + rules: + - sshd_enable_warning_banner_net + status: automated + + - id: 5.1.6 + title: Ensure sshd Ciphers are configured (Automated) + levels: + - l1_server + - l1_workstation + rules: + - sshd_use_strong_ciphers + status: automated + + - id: 5.1.7 + title: Ensure sshd ClientAliveInterval and ClientAliveCountMax are configured (Automated) + levels: + - l1_server + - l1_workstation + rules: + - sshd_idle_timeout_value=5_minutes + - var_sshd_set_keepalive=3 + - sshd_set_idle_timeout + - sshd_set_keepalive + status: partial + notes: | + The current implementation imposes an upper boundary on the + values. The CIS benchmark requires only that the values + are greater than 0. + + - id: 5.1.8 + title: Ensure sshd DisableForwarding is enabled (Automated) + levels: + - l1_workstation + - l2_server + rules: + - sshd_disable_forwarding + status: automated + + - id: 5.1.9 + title: Ensure sshd GSSAPIAuthentication is disabled (Automated) + levels: + - l1_workstation + - l2_server + rules: + - sshd_disable_gssapi_auth + status: automated + + - id: 5.1.10 + title: Ensure sshd HostbasedAuthentication is disabled (Automated) + levels: + - l1_server + - l1_workstation + rules: + - disable_host_auth + status: automated + + - id: 5.1.11 + title: Ensure sshd IgnoreRhosts is enabled (Automated) + levels: + - l1_server + - l1_workstation + rules: + - sshd_disable_rhosts + status: automated + + - id: 5.1.12 + title: Ensure sshd KexAlgorithms is configured (Automated) + levels: + - l1_server + - l1_workstation + rules: + - sshd_strong_kex=cis_debian13 + - sshd_use_strong_kex + status: automated + + - id: 5.1.13 + title: Ensure sshd LoginGraceTime is configured (Automated) + levels: + - l1_server + - l1_workstation + rules: + - var_sshd_set_login_grace_time=60 + - sshd_set_login_grace_time + status: automated + + - id: 5.1.14 + title: Ensure sshd LogLevel is configured (Automated) + levels: + - l1_server + - l1_workstation + rules: + - sshd_set_loglevel_info + status: automated + + - id: 5.1.15 + title: Ensure sshd MACs are configured (Automated) + levels: + - l1_server + - l1_workstation + rules: + - sshd_strong_macs=cis_debian13 + - sshd_use_strong_macs + status: automated + + - id: 5.1.16 + title: Ensure sshd MaxAuthTries is configured (Automated) + levels: + - l1_server + - l1_workstation + rules: + - sshd_max_auth_tries_value=4 + - sshd_set_max_auth_tries + status: automated + + - id: 5.1.17 + title: Ensure sshd MaxSessions is configured (Automated) + levels: + - l1_server + - l1_workstation + rules: + - var_sshd_max_sessions=10 + - sshd_set_max_sessions + status: automated + + - id: 5.1.18 + title: Ensure sshd MaxStartups is configured (Automated) + levels: + - l1_server + - l1_workstation + rules: + - var_sshd_set_maxstartups=10:30:60 + - sshd_set_maxstartups + status: automated + + - id: 5.1.19 + title: Ensure sshd PermitEmptyPasswords is disabled (Automated) + levels: + - l1_server + - l1_workstation + rules: + - sshd_disable_empty_passwords + status: automated + + - id: 5.1.20 + title: Ensure sshd PermitRootLogin is disabled (Automated) + levels: + - l1_server + - l1_workstation + rules: + - sshd_disable_root_login + status: automated + + - id: 5.1.21 + title: Ensure sshd PermitUserEnvironment is disabled (Automated) + levels: + - l1_server + - l1_workstation + rules: + - sshd_do_not_permit_user_env + status: automated + + - id: 5.1.22 + title: Ensure sshd UsePAM is enabled (Automated) + levels: + - l1_server + - l1_workstation + rules: + - sshd_enable_pam + status: automated + + - id: 5.2.1 + title: Ensure sudo is installed (Automated) + levels: + - l1_server + - l1_workstation + rules: + - package_sudo_installed + status: automated + + - id: 5.2.2 + title: Ensure sudo commands use pty (Automated) + levels: + - l1_server + - l1_workstation + rules: + - sudo_add_use_pty + status: automated + + - id: 5.2.3 + title: Ensure sudo log file exists (Automated) + levels: + - l1_server + - l1_workstation + rules: + - sudo_custom_logfile + status: automated + + - id: 5.2.4 + title: Ensure users must provide password for privilege escalation (Automated) + levels: + - l2_server + - l2_workstation + rules: + - sudo_require_authentication + status: automated + + - id: 5.2.5 + title: Ensure re-authentication for privilege escalation is not disabled globally (Automated) + levels: + - l1_server + - l1_workstation + rules: + - sudo_remove_no_authenticate + status: automated + + - id: 5.2.6 + title: Ensure sudo authentication timeout is configured correctly (Automated) + levels: + - l1_server + - l1_workstation + rules: + - var_sudo_timestamp_timeout=15_minutes + - sudo_require_reauthentication + status: automated + + - id: 5.2.7 + title: Ensure access to the su command is restricted (Automated) + levels: + - l1_server + - l1_workstation + rules: + - var_pam_wheel_group_for_su=cis + - ensure_pam_wheel_group_empty + - use_pam_wheel_group_for_su + status: automated + + - id: 5.3.1.1 + title: Ensure latest version of pam is installed (Automated) + levels: + - l1_server + - l1_workstation + rules: + - package_pam_runtime_installed + status: automated + notes: | + The CIS control checks that version >= 1.5.2-6 and not that + it is the latest version as the title suggests. + + - id: 5.3.1.2 + title: Ensure libpam-modules is installed (Automated) + levels: + - l1_server + - l1_workstation + rules: + - package_pam_modules_installed + status: automated + + - id: 5.3.1.3 + title: Ensure libpam-pwquality is installed (Automated) + levels: + - l1_server + - l1_workstation + rules: + - package_pam_pwquality_installed + status: automated + + - id: 5.3.2.1 + title: Ensure pam_unix module is enabled (Automated) + levels: + - l1_server + - l1_workstation + rules: + - accounts_password_pam_unix_enabled + status: automated + + - id: 5.3.2.2 + title: Ensure pam_faillock module is enabled (Automated) + levels: + - l1_server + - l1_workstation + rules: + - accounts_passwords_pam_faillock_enabled + status: automated + + - id: 5.3.2.3 + title: Ensure pam_pwquality module is enabled (Automated) + levels: + - l1_server + - l1_workstation + rules: + - accounts_password_pam_pwquality_enabled + status: automated + + - id: 5.3.2.4 + title: Ensure pam_pwhistory module is enabled (Automated) + levels: + - l1_server + - l1_workstation + rules: + - accounts_password_pam_pwhistory_enabled + status: automated + + - id: 5.3.3.1.1 + title: Ensure password failed attempts lockout is configured (Automated) + levels: + - l1_server + - l1_workstation + rules: + - var_accounts_passwords_pam_faillock_deny=4 + - accounts_passwords_pam_faillock_deny + status: automated + + - id: 5.3.3.1.2 + title: Ensure password unlock time is configured (Automated) + levels: + - l1_server + - l1_workstation + rules: + - var_accounts_passwords_pam_faillock_unlock_time=900 + - accounts_passwords_pam_faillock_unlock_time + status: automated + + - id: 5.3.3.1.3 + title: Ensure password failed attempts lockout includes root account (Automated) + levels: + - l2_server + - l2_workstation + rules: + - var_accounts_passwords_pam_faillock_root_unlock_time=900 + - accounts_passwords_pam_faillock_root_unlock_time + status: automated + + - id: 5.3.3.2.1 + title: Ensure password number of changed characters is configured (Automated) + levels: + - l1_server + - l1_workstation + rules: + - var_password_pam_difok=2 + - accounts_password_pam_difok + status: automated + + - id: 5.3.3.2.2 + title: Ensure minimum password length is configured (Automated) + levels: + - l1_server + - l1_workstation + rules: + - var_password_pam_minlen=14 + - accounts_password_pam_minlen + status: automated + + - id: 5.3.3.2.3 + title: Ensure password complexity is configured (Manual) + levels: + - l1_server + - l1_workstation + rules: + - var_password_pam_minclass=4 + - var_password_pam_dcredit=1 + - var_password_pam_lcredit=1 + - var_password_pam_ocredit=1 + - var_password_pam_ucredit=1 + - accounts_password_pam_minclass + - accounts_password_pam_dcredit + - accounts_password_pam_lcredit + - accounts_password_pam_ocredit + - accounts_password_pam_ucredit + status: automated + + - id: 5.3.3.2.4 + title: Ensure password same consecutive characters is configured (Automated) + levels: + - l1_server + - l1_workstation + rules: + - var_password_pam_maxrepeat=3 + - accounts_password_pam_maxrepeat + status: automated + + - id: 5.3.3.2.5 + title: Ensure password maximum sequential characters is configured (Automated) + levels: + - l1_server + - l1_workstation + rules: + - accounts_password_pam_maxsequence + status: automated + + - id: 5.3.3.2.6 + title: Ensure password dictionary check is enabled (Automated) + levels: + - l1_server + - l1_workstation + rules: + - var_password_pam_dictcheck=1 + - accounts_password_pam_dictcheck + status: automated + + - id: 5.3.3.2.7 + title: Ensure password quality checking is enforced (Automated) + levels: + - l1_server + - l1_workstation + rules: + - var_password_pam_enforcing=1 + - accounts_password_pam_enforcing + status: automated + + - id: 5.3.3.2.8 + title: Ensure password quality is enforced for the root user (Automated) + levels: + - l1_server + - l1_workstation + rules: + - accounts_password_pam_enforce_root + status: automated + + - id: 5.3.3.3.1 + title: Ensure password history remember is configured (Automated) + levels: + - l1_server + - l1_workstation + rules: + - var_password_pam_remember=24 + - accounts_password_pam_pwhistory_remember + status: automated + + - id: 5.3.3.3.2 + title: Ensure password history is enforced for the root user (Automated) + levels: + - l1_server + - l1_workstation + rules: + - accounts_password_pam_pwhistory_enforce_root + status: automated + + - id: 5.3.3.3.3 + title: Ensure pam_pwhistory includes use_authtok (Automated) + levels: + - l1_server + - l1_workstation + rules: + - accounts_password_pam_pwhistory_use_authtok + status: automated + + - id: 5.3.3.4.1 + title: Ensure pam_unix does not include nullok (Automated) + levels: + - l1_server + - l1_workstation + rules: + - no_empty_passwords_unix + status: automated + + - id: 5.3.3.4.2 + title: Ensure pam_unix does not include remember (Automated) + levels: + - l1_server + - l1_workstation + rules: + - accounts_password_pam_unix_no_remember + status: automated + + - id: 5.3.3.4.3 + title: Ensure pam_unix includes a strong password hashing algorithm (Automated) + levels: + - l1_server + - l1_workstation + rules: + - var_password_hashing_algorithm_pam=yescrypt + - set_password_hashing_algorithm_systemauth + status: automated + + - id: 5.3.3.4.4 + title: Ensure pam_unix includes use_authtok (Automated) + levels: + - l1_server + - l1_workstation + rules: + - accounts_password_pam_unix_authtok + status: automated + + - id: 5.4.1.1 + title: Ensure password expiration is configured (Automated) + levels: + - l1_server + - l1_workstation + rules: + - var_accounts_maximum_age_login_defs=365 + - accounts_maximum_age_login_defs + - accounts_password_set_max_life_existing + status: automated + + - id: 5.4.1.2 + title: Ensure minimum password days is configured (Manual) + levels: + - l2_server + - l2_workstation + rules: + - var_accounts_minimum_age_login_defs=1 + - accounts_minimum_age_login_defs + - accounts_password_set_min_life_existing + status: automated + + - id: 5.4.1.3 + title: Ensure password expiration warning days is configured (Automated) + levels: + - l1_server + - l1_workstation + rules: + - var_accounts_password_warn_age_login_defs=7 + - accounts_password_warn_age_login_defs + status: automated + + - id: 5.4.1.4 + title: Ensure strong password hashing algorithm is configured (Automated) + levels: + - l1_server + - l1_workstation + rules: + - set_password_hashing_algorithm_logindefs + - var_password_hashing_algorithm=yescrypt + status: automated + notes: Rule allows either SHA512 or YESCRYPT + + - id: 5.4.1.5 + title: Ensure inactive password lock is configured (Automated) + levels: + - l1_server + - l1_workstation + rules: + - var_account_disable_post_pw_expiration=45 + - account_disable_post_pw_expiration + - accounts_set_post_pw_existing + status: automated + notes: CIS setting now 45 days. + + - id: 5.4.1.6 + title: Ensure all users last password change date is in the past (Automated) + levels: + - l1_server + - l1_workstation + rules: + - accounts_password_last_change_is_in_past + status: automated + + - id: 5.4.2.1 + title: Ensure root is the only UID 0 account (Automated) + levels: + - l1_server + - l1_workstation + rules: + - accounts_no_uid_except_zero + status: automated + + - id: 5.4.2.2 + title: Ensure root is the only GID 0 account (Automated) + levels: + - l1_server + - l1_workstation + rules: + - accounts_root_gid_zero + status: automated + notes: | + The remediation is not automated as the removal or modification + of group IDs from a system is too disruptive. + + - id: 5.4.2.3 + title: Ensure group root is the only GID 0 group (Automated) + levels: + - l1_server + - l1_workstation + rules: + - groups_no_zero_gid_except_root + status: automated + notes: | + The remediation is not automated as the removal or modification + of group IDs from a system is too disruptive. + + - id: 5.4.2.4 + title: Ensure root account access is controlled (Automated) + levels: + - l1_server + - l1_workstation + rules: + - ensure_root_access_controlled + status: automated + notes: This rule doesn't come with a remediation, as the exact requirement allows root to either + have a password or be locked. + + - id: 5.4.2.5 + title: Ensure root path integrity (Automated) + levels: + - l1_server + - l1_workstation + rules: + - accounts_root_path_dirs_no_write + - root_path_all_dirs + - root_path_no_dot + - no_dirs_unowned_by_root + status: automated + + - id: 5.4.2.6 + title: Ensure root user umask is configured (Automated) + levels: + - l1_server + - l1_workstation + rules: + - accounts_umask_root + status: automated + + - id: 5.4.2.7 + title: Ensure system accounts do not have a valid login shell (Automated) + levels: + - l1_server + - l1_workstation + rules: + - no_shelllogin_for_systemaccounts + status: automated + + - id: 5.4.2.8 + title: Ensure accounts without a valid login shell are locked (Automated) + levels: + - l1_server + - l1_workstation + rules: + - no_invalid_shell_accounts_unlocked + status: automated + notes: | + Remediation is not automated. + + - id: 5.4.3.1 + title: Ensure nologin is not listed in /etc/shells (Automated) + levels: + - l2_server + - l2_workstation + rules: + - no_nologin_in_shells + status: automated + + - id: 5.4.3.2 + title: Ensure default user shell timeout is configured (Automated) + levels: + - l1_server + - l1_workstation + rules: + - var_accounts_tmout=15_min + - accounts_tmout + status: automated + + - id: 5.4.3.3 + title: Ensure default user umask is configured (Automated) + levels: + - l1_server + - l1_workstation + rules: + - var_accounts_user_umask=027 + - accounts_umask_etc_bashrc + - accounts_umask_etc_login_defs + - accounts_umask_etc_profile + status: automated + + - id: 6.1.1.1 + title: Ensure journald service is enabled and active (Automated) + levels: + - l1_server + - l1_workstation + rules: + - service_systemd-journald_enabled + status: automated + + - id: 6.1.1.2 + title: Ensure journald log file access is configured (Manual) + levels: + - l1_server + - l1_workstation + status: manual + + - id: 6.1.1.3 + title: Ensure journald log file rotation is configured (Manual) + levels: + - l1_server + - l1_workstation + status: manual + + - id: 6.1.1.4 + title: Ensure only one logging system is in use (Automated) + levels: + - l1_server + - l1_workstation + rules: + - logging_services_active + status: automated + notes: | + The title of this rule is misleading. The actual audit checks that at least + one of "rsyslogd" and "systemd-journald" is active. + See https://workbench.cisecurity.org/benchmarks/18959/tickets/23601 + + Remediation is not automated as the choice of correct logging service + is dependent on site policy. + + - id: 6.1.2.1.1 + title: Ensure systemd-journal-remote is installed (Automated) + levels: + - l1_server + - l1_workstation + rules: + - package_systemd-journal-remote_installed + status: automated + + - id: 6.1.2.1.2 + title: Ensure systemd-journal-upload authentication is configured (Manual) + levels: + - l1_server + - l1_workstation + rules: + - systemd_journal_upload_server_tls + - systemd_journal_upload_url + status: automated + + - id: 6.1.2.1.3 + title: Ensure systemd-journal-upload is enabled and active (Automated) + levels: + - l1_server + - l1_workstation + rules: + - service_systemd-journal-upload_enabled + status: automated + + - id: 6.1.2.1.4 + title: Ensure systemd-journal-remote service is not in use (Automated) + levels: + - l1_server + - l1_workstation + rules: + - socket_systemd-journal-remote_disabled + status: automated + + - id: 6.1.2.2 + title: Ensure journald ForwardToSyslog is disabled (Automated) + levels: + - l1_server + - l1_workstation + rules: + - journald_disable_forward_to_syslog + status: automated + + - id: 6.1.2.3 + title: Ensure journald Compress is configured (Automated) + levels: + - l1_server + - l1_workstation + rules: + - journald_compress + status: automated + + - id: 6.1.2.4 + title: Ensure journald Storage is configured (Automated) + levels: + - l1_server + - l1_workstation + rules: + - journald_storage + status: automated + + - id: 6.1.3.1 + title: Ensure rsyslog is installed (Automated) + levels: + - l1_server + - l1_workstation + rules: + - package_rsyslog_installed + status: automated + + - id: 6.1.3.2 + title: Ensure rsyslog service is enabled and active (Automated) + levels: + - l1_server + - l1_workstation + rules: + - service_rsyslog_enabled + status: automated + + - id: 6.1.3.3 + title: Ensure journald is configured to send logs to rsyslog (Automated) + levels: + - l1_server + - l1_workstation + rules: + - journald_forward_to_syslog + status: automated + + - id: 6.1.3.4 + title: Ensure rsyslog log file creation mode is configured (Automated) + levels: + - l1_server + - l1_workstation + rules: + - rsyslog_filecreatemode + status: automated + + - id: 6.1.3.5 + title: Ensure rsyslog logging is configured (Manual) + levels: + - l1_server + - l1_workstation + status: manual + + - id: 6.1.3.6 + title: Ensure rsyslog is configured to send logs to a remote log host (Manual) + levels: + - l1_server + - l1_workstation + related_rules: + - rsyslog_remote_loghost + status: manual + notes: | + Existing rule (rsyslog_remote_loghost) is not used because rsyslog configuration + is site-specific and can be too complex to reliably audit and remediate. + See also https://github.com/ComplianceAsCode/content/issues/11812 + + - id: 6.1.3.7 + title: Ensure rsyslog is not configured to receive logs from a remote client (Automated) + levels: + - l1_server + - l1_workstation + rules: + - rsyslog_nolisten + status: automated + + - id: 6.1.3.8 + title: Ensure logrotate is configured (Manual) + levels: + - l1_server + - l1_workstation + status: manual + + - id: 6.1.4.1 + title: Ensure access to all logfiles has been configured (Automated) + levels: + - l1_server + - l1_workstation + rules: + - file_groupownerships_var_log_apt + - file_groupownerships_var_log_gdm + - file_groupownerships_var_log_gdm3 + - file_groupownerships_var_log_landscape + - file_groupownerships_var_log_sssd + - file_groupowner_var_log_auth + - file_groupowner_var_log_cloud_init + - file_groupowner_var_log_journal + - file_groupowner_var_log_lastlog + - file_groupowner_var_log_localmessages + - file_groupowner_var_log_messages + - file_groupowner_var_log_secure + - file_groupowner_var_log_syslog + - file_groupowner_var_log_waagent + - file_groupowner_var_log_wbtmp + - file_ownerships_var_log_apt + - file_ownerships_var_log_gdm + - file_ownerships_var_log_gdm3 + - file_ownerships_var_log_landscape + - file_ownerships_var_log_sssd + - file_owner_var_log_auth + - file_owner_var_log_cloud_init + - file_owner_var_log_journal + - file_owner_var_log_lastlog + - file_owner_var_log_localmessages + - file_owner_var_log_messages + - file_owner_var_log_secure + - file_owner_var_log_syslog + - file_owner_var_log_waagent + - file_owner_var_log_wbtmp + - file_permissions_var_log_apt + - file_permissions_var_log_auth + - file_permissions_var_log_cloud-init + - file_permissions_var_log_gdm + - file_permissions_var_log_gdm3 + - file_permissions_var_log_lastlog + - file_permissions_var_log_cloud-init + - file_permissions_var_log_localmessages + - file_permissions_var_log_messages + - file_permissions_var_log_secure + - file_permissions_var_log_sssd + - file_permissions_var_log_syslog + - file_permissions_var_log_waagent + - file_permissions_var_log_wbtmp + - file_groupownerships_var_log + - file_ownerships_var_log + - permissions_local_var_log + status: automated + + - id: 6.2.1.1 + title: Ensure auditd packages are installed (Automated) + levels: + - l2_server + - l2_workstation + rules: + - package_audit_installed + - package_audit-audispd-plugins_installed + status: automated + notes: | + Implementation analogous to ubuntu2204/4.1.1.1. + Added also the missing rule for audispd. + + - id: 6.2.1.2 + title: Ensure auditd service is enabled and active (Automated) + levels: + - l2_server + - l2_workstation + rules: + - service_auditd_enabled + status: automated + + - id: 6.2.1.3 + title: Ensure auditing for processes that start prior to auditd is enabled (Automated) + levels: + - l2_server + - l2_workstation + rules: + - grub2_audit_argument + - zipl_audit_argument + status: automated + + - id: 6.2.1.4 + title: Ensure audit_backlog_limit is sufficient (Automated) + levels: + - l2_server + - l2_workstation + rules: + - grub2_audit_backlog_limit_argument + - var_audit_backlog_limit=8192 + - zipl_audit_backlog_limit_argument + status: automated + + - id: 6.2.2.1 + title: Ensure audit log storage size is configured (Automated) + levels: + - l2_server + - l2_workstation + rules: + - var_auditd_max_log_file=6 + - auditd_data_retention_max_log_file + status: automated + + - id: 6.2.2.2 + title: Ensure audit logs are not automatically deleted (Automated) + levels: + - l2_server + - l2_workstation + rules: + - var_auditd_max_log_file_action=keep_logs + - auditd_data_retention_max_log_file_action + status: automated + + - id: 6.2.2.3 + title: Ensure system is disabled when audit logs are full (Automated) + levels: + - l2_server + - l2_workstation + rules: + - var_auditd_disk_error_action=cis_debian13 + - var_auditd_disk_full_action=cis_debian13 + - auditd_data_disk_error_action + - auditd_data_disk_full_action + status: automated + + - id: 6.2.2.4 + title: Ensure system warns when audit logs are low on space (Automated) + levels: + - l2_server + - l2_workstation + rules: + - var_auditd_action_mail_acct=root + - var_auditd_space_left_action=email + - var_auditd_admin_space_left_action=halt + - auditd_data_retention_action_mail_acct + - auditd_data_retention_admin_space_left_action + - auditd_data_retention_space_left_action + status: partial + notes: | + The variables should allow multiple options. + + - id: 6.2.3.1 + title: Ensure changes to system administration scope (sudoers) is collected (Automated) + levels: + - l2_server + - l2_workstation + rules: + - audit_rules_sysadmin_actions + status: automated + + - id: 6.2.3.2 + title: Ensure actions as another user are always logged (Automated) + levels: + - l2_server + - l2_workstation + rules: + - audit_rules_suid_auid_privilege_function + status: automated + + - id: 6.2.3.3 + title: Ensure events that modify the sudo log file are collected (Automated) + levels: + - l2_server + - l2_workstation + rules: + - audit_sudo_log_events + status: automated + + - id: 6.2.3.4 + title: Ensure events that modify date and time information are collected (Automated) + levels: + - l2_server + - l2_workstation + rules: + - audit_rules_time_adjtimex + - audit_rules_time_clock_settime + - audit_rules_time_settimeofday + - audit_rules_time_watch_localtime + status: automated + + - id: 6.2.3.5 + title: Ensure events that modify the system's network environment are collected (Automated) + levels: + - l2_server + - l2_workstation + rules: + - audit_rules_networkconfig_modification + status: automated + + - id: 6.2.3.6 + title: Ensure use of privileged commands are collected (Automated) + levels: + - l2_server + - l2_workstation + rules: + - audit_rules_privileged_commands + status: automated + + - id: 6.2.3.7 + title: Ensure unsuccessful file access attempts are collected (Automated) + levels: + - l2_server + - l2_workstation + rules: + - audit_rules_unsuccessful_file_modification_creat + - audit_rules_unsuccessful_file_modification_ftruncate + - audit_rules_unsuccessful_file_modification_open + - audit_rules_unsuccessful_file_modification_openat + - audit_rules_unsuccessful_file_modification_truncate + status: automated + + - id: 6.2.3.8 + title: Ensure events that modify user/group information are collected (Automated) + levels: + - l2_server + - l2_workstation + rules: + - audit_rules_usergroup_modification_group + - audit_rules_usergroup_modification_gshadow + - audit_rules_usergroup_modification_opasswd + - audit_rules_usergroup_modification_passwd + - audit_rules_usergroup_modification_shadow + - audit_rules_usergroup_modification_nsswitch_conf + - audit_rules_usergroup_modification_pam_conf + - audit_rules_usergroup_modification_pamd + status: automated + + - id: 6.2.3.9 + title: Ensure discretionary access control permission modification events are collected (Automated) + levels: + - l2_server + - l2_workstation + rules: + - audit_rules_dac_modification_chmod + - audit_rules_dac_modification_chown + - audit_rules_dac_modification_fchmod + - audit_rules_dac_modification_fchmodat + - audit_rules_dac_modification_fchown + - audit_rules_dac_modification_fchownat + - audit_rules_dac_modification_fremovexattr + - audit_rules_dac_modification_fsetxattr + - audit_rules_dac_modification_lchown + - audit_rules_dac_modification_lremovexattr + - audit_rules_dac_modification_lsetxattr + - audit_rules_dac_modification_removexattr + - audit_rules_dac_modification_setxattr + status: automated + + - id: 6.2.3.10 + title: Ensure successful file system mounts are collected (Automated) + levels: + - l2_server + - l2_workstation + rules: + - audit_rules_media_export + status: automated + + - id: 6.2.3.11 + title: Ensure session initiation information is collected (Automated) + levels: + - l2_server + - l2_workstation + rules: + - audit_rules_session_events + status: automated + + - id: 6.2.3.12 + title: Ensure login and logout events are collected (Automated) + levels: + - l2_server + - l2_workstation + rules: + - var_accounts_passwords_pam_faillock_dir=run + - audit_rules_login_events_faillock + - audit_rules_login_events_lastlog + status: automated + + - id: 6.2.3.13 + title: Ensure file deletion events by users are collected (Automated) + levels: + - l2_server + - l2_workstation + rules: + - audit_rules_file_deletion_events_rename + - audit_rules_file_deletion_events_renameat + - audit_rules_file_deletion_events_unlink + - audit_rules_file_deletion_events_unlinkat + status: automated + + - id: 6.2.3.14 + title: Ensure events that modify the system's Mandatory Access Controls are collected (Automated) + levels: + - l2_server + - l2_workstation + rules: + - audit_rules_mac_modification_etc_apparmor + - audit_rules_mac_modification_etc_apparmor_d + status: automated + + - id: 6.2.3.15 + title: Ensure successful and unsuccessful attempts to use the chcon command are collected (Automated) + levels: + - l2_server + - l2_workstation + rules: + - audit_rules_execution_chcon + status: automated + + - id: 6.2.3.16 + title: Ensure successful and unsuccessful attempts to use the setfacl command are collected (Automated) + levels: + - l2_server + - l2_workstation + rules: + - audit_rules_execution_setfacl + status: automated + + - id: 6.2.3.17 + title: Ensure successful and unsuccessful attempts to use the chacl command are collected (Automated) + levels: + - l2_server + - l2_workstation + rules: + - audit_rules_execution_chacl + status: automated + + - id: 6.2.3.18 + title: Ensure successful and unsuccessful attempts to use the usermod command are collected (Automated) + levels: + - l2_server + - l2_workstation + rules: + - audit_rules_privileged_commands_usermod + status: automated + + - id: 6.2.3.19 + title: Ensure kernel module loading unloading and modification is collected (Automated) + levels: + - l2_server + - l2_workstation + rules: + - audit_rules_kernel_module_loading_delete + - audit_rules_kernel_module_loading_init + - audit_rules_kernel_module_loading_finit + - audit_rules_kernel_module_loading_create + - audit_rules_kernel_module_loading_query + - audit_rules_privileged_commands_kmod + status: automated + + - id: 6.2.3.20 + title: Ensure the audit configuration is immutable (Automated) + levels: + - l2_server + - l2_workstation + rules: + - audit_rules_immutable + status: automated + + - id: 6.2.3.21 + title: Ensure the running and on disk configuration is the same (Manual) + levels: + - l2_server + - l2_workstation + status: manual + + - id: 6.2.4.1 + title: Ensure audit log files mode is configured (Automated) + levels: + - l2_server + - l2_workstation + rules: + - file_permissions_var_log_audit + status: automated + + - id: 6.2.4.2 + title: Ensure audit log files owner is configured (Automated) + levels: + - l2_server + - l2_workstation + rules: + - file_ownership_var_log_audit_stig + status: automated + + - id: 6.2.4.3 + title: Ensure audit log files group owner is configured (Automated) + levels: + - l2_server + - l2_workstation + rules: + - file_group_ownership_var_log_audit + status: automated + + - id: 6.2.4.4 + title: Ensure the audit log file directory mode is configured (Automated) + levels: + - l2_server + - l2_workstation + rules: + - directory_permissions_var_log_audit + status: automated + + - id: 6.2.4.5 + title: Ensure audit configuration files mode is configured (Automated) + levels: + - l2_server + - l2_workstation + rules: + - file_permissions_etc_audit_auditd + - file_permissions_etc_audit_rules + - file_permissions_etc_audit_rulesd + status: automated + + - id: 6.2.4.6 + title: Ensure audit configuration files owner is configured (Automated) + levels: + - l2_server + - l2_workstation + rules: + - file_ownership_audit_configuration + status: automated + + - id: 6.2.4.7 + title: Ensure audit configuration files group owner is configured (Automated) + levels: + - l2_server + - l2_workstation + rules: + - file_groupownership_audit_configuration + status: automated + + - id: 6.2.4.8 + title: Ensure audit tools mode is configured (Automated) + levels: + - l2_server + - l2_workstation + rules: + - file_permissions_audit_binaries + status: automated + + - id: 6.2.4.9 + title: Ensure audit tools owner is configured (Automated) + levels: + - l2_server + - l2_workstation + rules: + - file_ownership_audit_binaries + status: automated + + - id: 6.2.4.10 + title: Ensure audit tools group owner is configured (Automated) + levels: + - l2_server + - l2_workstation + rules: + - file_groupownership_audit_binaries + status: automated + + - id: 6.3.1 + title: Ensure AIDE is installed (Automated) + levels: + - l1_server + - l1_workstation + rules: + - aide_build_database + - package_aide_installed + status: automated + + - id: 6.3.2 + title: Ensure filesystem integrity is regularly checked (Automated) + levels: + - l1_server + - l1_workstation + rules: + - aide_periodic_checking_systemd_timer + status: automated + + - id: 6.3.3 + title: Ensure cryptographic mechanisms are used to protect the integrity of audit tools (Automated) + levels: + - l2_server + - l2_workstation + rules: + - aide_check_audit_tools + status: automated + + - id: 7.1.1 + title: Ensure permissions on /etc/passwd are configured (Automated) + levels: + - l1_server + - l1_workstation + rules: + - file_groupowner_etc_passwd + - file_owner_etc_passwd + - file_permissions_etc_passwd + status: automated + + - id: 7.1.2 + title: Ensure permissions on /etc/passwd- are configured (Automated) + levels: + - l1_server + - l1_workstation + rules: + - file_groupowner_backup_etc_passwd + - file_owner_backup_etc_passwd + - file_permissions_backup_etc_passwd + status: automated + + - id: 7.1.3 + title: Ensure permissions on /etc/group are configured (Automated) + levels: + - l1_server + - l1_workstation + rules: + - file_groupowner_etc_group + - file_owner_etc_group + - file_permissions_etc_group + status: automated + + - id: 7.1.4 + title: Ensure permissions on /etc/group- are configured (Automated) + levels: + - l1_server + - l1_workstation + rules: + - file_groupowner_backup_etc_group + - file_owner_backup_etc_group + - file_permissions_backup_etc_group + status: automated + + - id: 7.1.5 + title: Ensure permissions on /etc/shadow are configured (Automated) + levels: + - l1_server + - l1_workstation + rules: + - file_groupowner_etc_shadow + - file_owner_etc_shadow + - file_permissions_etc_shadow + status: automated + + - id: 7.1.6 + title: Ensure permissions on /etc/shadow- are configured (Automated) + levels: + - l1_server + - l1_workstation + rules: + - file_groupowner_backup_etc_shadow + - file_owner_backup_etc_shadow + - file_permissions_backup_etc_shadow + status: automated + + - id: 7.1.7 + title: Ensure permissions on /etc/gshadow are configured (Automated) + levels: + - l1_server + - l1_workstation + rules: + - file_groupowner_etc_gshadow + - file_owner_etc_gshadow + - file_permissions_etc_gshadow + status: automated + + - id: 7.1.8 + title: Ensure permissions on /etc/gshadow- are configured (Automated) + levels: + - l1_server + - l1_workstation + rules: + - file_groupowner_backup_etc_gshadow + - file_owner_backup_etc_gshadow + - file_permissions_backup_etc_gshadow + status: automated + + - id: 7.1.9 + title: Ensure permissions on /etc/shells are configured (Automated) + levels: + - l1_server + - l1_workstation + rules: + - file_owner_etc_shells + - file_groupowner_etc_shells + - file_permissions_etc_shells + status: automated + + - id: 7.1.10 + title: Ensure permissions on /etc/security/opasswd are configured (Automated) + levels: + - l1_server + - l1_workstation + rules: + - file_owner_etc_security_opasswd + - file_groupowner_etc_security_opasswd + - file_permissions_etc_security_opasswd + - file_owner_etc_security_opasswd_old + - file_groupowner_etc_security_opasswd_old + - file_permissions_etc_security_opasswd_old + status: automated + + - id: 7.1.11 + title: Ensure world writable files and directories are secured (Automated) + levels: + - l1_server + - l1_workstation + rules: + - file_permissions_unauthorized_world_writable + status: automated + + - id: 7.1.12 + title: Ensure no files or directories without an owner and a group exist (Automated) + levels: + - l1_server + - l1_workstation + rules: + - no_files_unowned_by_user + - file_permissions_ungroupowned + status: automated + + - id: 7.1.13 + title: Ensure SUID and SGID files are reviewed (Manual) + levels: + - l1_server + - l1_workstation + status: manual + + - id: 7.2.1 + title: Ensure accounts in /etc/passwd use shadowed passwords (Automated) + levels: + - l1_server + - l1_workstation + rules: + - accounts_password_all_shadowed + status: automated + + - id: 7.2.2 + title: Ensure /etc/shadow password fields are not empty (Automated) + levels: + - l1_server + - l1_workstation + rules: + - no_empty_passwords_etc_shadow + status: automated + + - id: 7.2.3 + title: Ensure all groups in /etc/passwd exist in /etc/group (Automated) + levels: + - l1_server + - l1_workstation + rules: + - gid_passwd_group_same + status: automated + + - id: 7.2.4 + title: Ensure shadow group is empty (Automated) + levels: + - l1_server + - l1_workstation + rules: + - ensure_shadow_group_empty + status: automated + + - id: 7.2.5 + title: Ensure no duplicate UIDs exist (Automated) + levels: + - l1_server + - l1_workstation + rules: + - account_unique_id + status: automated + + - id: 7.2.6 + title: Ensure no duplicate GIDs exist (Automated) + levels: + - l1_server + - l1_workstation + rules: + - group_unique_id + status: automated + + - id: 7.2.7 + title: Ensure no duplicate user names exist (Automated) + levels: + - l1_server + - l1_workstation + rules: + - account_unique_name + status: automated + + - id: 7.2.8 + title: Ensure no duplicate group names exist (Automated) + levels: + - l1_server + - l1_workstation + rules: + - group_unique_name + status: automated + + - id: 7.2.9 + title: Ensure local interactive user home directories are configured (Automated) + levels: + - l1_server + - l1_workstation + rules: + - accounts_user_interactive_home_directory_exists + - file_groupownership_home_directories + - file_ownership_home_directories + - file_permissions_home_directories + status: automated + + - id: 7.2.10 + title: Ensure local interactive user dot files access is configured (Automated) + levels: + - l1_server + - l1_workstation + rules: + - no_rsh_trust_files + - no_forward_files + - no_netrc_files + - accounts_user_dot_user_ownership + - accounts_user_dot_group_ownership + - var_user_initialization_files_regex=all_dotfiles + - file_permission_user_init_files + - file_permission_user_bash_history + status: automated diff --git a/products/debian13/profiles/cis_level1_workstation.profile b/products/debian13/profiles/cis_level1_workstation.profile index 4d21e7a78370..52b81b18a867 100644 --- a/products/debian13/profiles/cis_level1_workstation.profile +++ b/products/debian13/profiles/cis_level1_workstation.profile @@ -16,4 +16,4 @@ description: |- Debian 13 Benchmark™ content. selections: - - cis_debian12:all:l1_workstation + - cis_debian13:all:l1_workstation diff --git a/products/debian13/profiles/cis_level2_server.profile b/products/debian13/profiles/cis_level2_server.profile index 330980e144e7..e486c0e4e367 100644 --- a/products/debian13/profiles/cis_level2_server.profile +++ b/products/debian13/profiles/cis_level2_server.profile @@ -16,4 +16,4 @@ description: |- Debian 13 Benchmark™ content. selections: - - cis_debian12:all:l2_server + - cis_debian13:all:l2_server diff --git a/products/debian13/profiles/cis_level2_workstation.profile b/products/debian13/profiles/cis_level2_workstation.profile index f928458a0261..d1afb3766917 100644 --- a/products/debian13/profiles/cis_level2_workstation.profile +++ b/products/debian13/profiles/cis_level2_workstation.profile @@ -16,4 +16,4 @@ description: |- Debian 13 Benchmark™ content. selections: - - cis_debian12:all:l2_workstation + - cis_debian13:all:l2_workstation From 1b56513969f3586b101db1cd3adf448c3be24053 Mon Sep 17 00:00:00 2001 From: Israel Villar Boillos Date: Mon, 30 Mar 2026 00:22:46 +0100 Subject: [PATCH 03/61] Align Debian 13 AppArmor controls with CIS benchmark --- controls/cis_debian13.yml | 106 ++++++++++++++++++++++++++------------ 1 file changed, 74 insertions(+), 32 deletions(-) diff --git a/controls/cis_debian13.yml b/controls/cis_debian13.yml index 9717e1ca537c..33bfb0929cca 100644 --- a/controls/cis_debian13.yml +++ b/controls/cis_debian13.yml @@ -65,7 +65,7 @@ controls: status: automated - id: 1.1.1.6 - title: Ensure overlayfs kernel module is not available (Automated) + title: Ensure overlay kernel module is not available (Automated) levels: - l2_server - l2_workstation @@ -78,7 +78,7 @@ controls: levels: - l2_server - l2_workstation - related_rules: + rules: - kernel_module_squashfs_disabled status: automated @@ -92,6 +92,15 @@ controls: status: automated - id: 1.1.1.9 + title: Ensure firewire-core kernel module is not available (Automated) + levels: + - l1_server + - l2_workstation + rules: + - kernel_module_firewire-core_disabled + status: automated + + - id: 1.1.1.10 title: Ensure usb-storage kernel module is not available (Automated) levels: - l1_server @@ -100,7 +109,7 @@ controls: - kernel_module_usb-storage_disabled status: automated - - id: 1.1.1.10 + - id: 1.1.1.11 title: Ensure unused filesystems kernel modules are not available (Manual) levels: - l1_server @@ -108,7 +117,7 @@ controls: status: manual - id: 1.1.2.1.1 - title: Ensure /tmp is a separate partition (Automated) + title: Ensure /tmp is tmpfs or a separate partition (Automated) levels: - l1_server - l1_workstation @@ -144,7 +153,7 @@ controls: status: automated - id: 1.1.2.2.1 - title: Ensure /dev/shm is a separate partition (Automated) + title: Ensure /dev/shm is tmpfs or a separate partition (Automated) levels: - l1_server - l1_workstation @@ -342,18 +351,67 @@ controls: status: automated - id: 1.2.1.1 - title: Ensure GPG keys are configured (Manual) + title: Ensure the source.list and .source files use the Signed-By option (Manual) levels: - l1_server - l1_workstation status: manual - id: 1.2.1.2 - title: Ensure package manager repositories are configured (Manual) + title: Ensure weak dependencies are configured (Automated) levels: - l1_server - l1_workstation - status: manual + status: automated + + - id: 1.2.1.3 + title: Ensure access to gpg key files are configured (Automated) + levels: + - l1_server + - l1_workstation + status: automated + + - id: 1.2.1.4 + title: Ensure access to /etc/apt/trusted.gpg.d directory is configured (Automated) + levels: + - l1_server + - l1_workstation + status: automated + + - id: 1.2.1.5 + title: Ensure access to /etc/apt/auth.conf.d directory is configured (Automated) + levels: + - l1_server + - l1_workstation + status: automated + + - id: 1.2.1.6 + title: Ensure access to files in the /etc/apt/auth.conf.d/ directory is configured (Automated) + levels: + - l1_server + - l1_workstation + status: automated + + - id: 1.2.1.7 + title: Ensure access to /usr/share/keyrings directory is configured (Automated) + levels: + - l1_server + - l1_workstation + status: automated + + - id: 1.2.1.8 + title: Ensure access to /etc/apt/sources.list.d directory is configured (Automated) + levels: + - l1_server + - l1_workstation + status: automated + + - id: 1.2.1.9 + title: Ensure access to files in /etc/apt/sources.list.d are configured (Automated) + levels: + - l1_server + - l1_workstation + status: automated - id: 1.2.2.1 title: Ensure updates, patches, and additional security software are installed (Manual) @@ -363,7 +421,7 @@ controls: status: manual - id: 1.3.1.1 - title: Ensure AppArmor is installed (Automated) + title: Ensure apparmor packages are installed (Automated) levels: - l1_server - l1_workstation @@ -373,46 +431,30 @@ controls: status: automated - id: 1.3.1.2 - title: Ensure AppArmor is enabled in the bootloader configuration (Automated) + title: Ensure AppArmor is enabled (Automated) levels: - l1_server - l1_workstation rules: - grub2_enable_apparmor + - apparmor_configured status: automated - id: 1.3.1.3 - title: Ensure all AppArmor Profiles are in enforce or complain mode (Automated) + title: Ensure all AppArmor Profiles are enforcing (Automated) levels: - l1_server - l1_workstation rules: - - var_apparmor_mode=complain - - all_apparmor_profiles_in_enforce_complain_mode + - all_apparmor_profiles_enforced status: automated - notes: | - CIS recommendation does not adequately address the nuances - of various profiles, including disabled, force-complain, - and unconfined. Currently, the control changes the default apparmor - mode for all profiles in /etc/apparmor.d which can - break certain applications. See https://workbench.cisecurity.org/benchmarks/18959/tickets/23987 - The remediation for this rule sets apparmor in complain mode. The remediation can be - deactivated by setting var_apparmor_mode to keep_existing_mode - id: 1.3.1.4 - title: Ensure all AppArmor Profiles are enforcing (Automated) + title: Ensure apparmor_restrict_unprivileged_unconfined is enabled (Automated) levels: - - l2_server - - l2_workstation - rules: - - all_apparmor_profiles_enforced + - l1_server + - l1_workstation status: automated - notes: | - CIS recommendation does not adequately address the nuances - of various profiles, including disabled, force-complain, - and unconfined. Currently, the control changes the default apparmor - mode for all profiles in /etc/apparmor.d which can - break certain applications. See https://workbench.cisecurity.org/benchmarks/18959/tickets/23987 - id: 1.4.1 title: Ensure bootloader password is set (Automated) From d42191b654e9cdc8e42ced3acfa4abbce8fd447a Mon Sep 17 00:00:00 2001 From: Israel Villar Boillos Date: Mon, 30 Mar 2026 18:24:04 +0100 Subject: [PATCH 04/61] Align Debian 13 CIS warning banner controls with benchmark --- controls/cis_debian13.yml | 108 ++++++++++++++++++++++++++++++++++---- 1 file changed, 99 insertions(+), 9 deletions(-) diff --git a/controls/cis_debian13.yml b/controls/cis_debian13.yml index 33bfb0929cca..6cb3fa01f2f8 100644 --- a/controls/cis_debian13.yml +++ b/controls/cis_debian13.yml @@ -477,16 +477,27 @@ controls: status: automated - id: 1.5.1 - title: Ensure address space layout randomization is enabled (Automated) + title: Ensure fs.protected_hardlinks is configured (Automated) levels: - l1_server - l1_workstation rules: - - sysctl_kernel_randomize_va_space + - sysctl_fs_protected_hardlinks status: automated - id: 1.5.2 - title: Ensure ptrace_scope is restricted (Automated) + title: Ensure fs.protected_symlinks is configured (Automated) + levels: + - l1_server + - l1_workstation + rules: + - sysctl_fs_protected_symlinks + status: automated + + # Note: CIS Debian 13 v1.0.0 appears to duplicate kernel.yama.ptrace_scope + # in both 1.5.3 and 1.5.10. Keeping both IDs for traceability to the benchmark. + - id: 1.5.3 + title: Ensure kernel.yama.ptrace_scope is configured (Automated) levels: - l1_server - l1_workstation @@ -495,18 +506,97 @@ controls: - sysctl_kernel_yama_ptrace_scope status: automated - - id: 1.5.3 - title: Ensure core dumps are restricted (Automated) + - id: 1.5.4 + title: Ensure fs.suid_dumpable is configured (Automated) levels: - l1_server - l1_workstation rules: - - disable_users_coredumps - sysctl_fs_suid_dumpable status: automated + - id: 1.5.5 + title: Ensure kernel.dmesg_restrict is configured (Automated) + levels: + - l1_server + - l1_workstation + rules: + - sysctl_kernel_dmesg_restrict + status: automated + + - id: 1.5.6 + title: Ensure prelink is not installed (Automated) + levels: + - l1_server + - l1_workstation + rules: + - package_prelink_removed + status: automated + + - id: 1.5.7 + title: Ensure Automatic Error Reporting is configured (Automated) + levels: + - l1_server + - l1_workstation + status: automated + + - id: 1.5.8 + title: Ensure kernel.kptr_restrict is configured (Automated) + levels: + - l1_server + - l1_workstation + rules: + - sysctl_kernel_kptr_restrict + status: automated + + - id: 1.5.9 + title: Ensure kernel.randomize_va_space is configured (Automated) + levels: + - l1_server + - l1_workstation + rules: + - sysctl_kernel_randomize_va_space + status: automated + + - id: 1.5.10 + title: Ensure kernel.yama.ptrace_scope is configured (Automated) + levels: + - l1_server + - l1_workstation + rules: + - sysctl_kernel_yama_ptrace_scope_value=1 + - sysctl_kernel_yama_ptrace_scope + status: automated + + - id: 1.5.11 + title: Ensure core file size is configured (Automated) + levels: + - l1_server + - l1_workstation + rules: + - disable_users_coredumps + status: automated + + - id: 1.5.12 + title: Ensure systemd-coredump ProcessSizeMax is configured (Automated) + levels: + - l1_server + - l1_workstation + rules: + - coredump_disable_backtraces + status: automated + + - id: 1.5.13 + title: Ensure systemd-coredump Storage is configured (Automated) + levels: + - l1_server + - l1_workstation + rules: + - coredump_disable_storage + status: automated + - id: 1.6.1 - title: Ensure message of the day is configured properly (Automated) + title: Ensure /etc/motd is configured (Automated) levels: - l1_server - l1_workstation @@ -516,7 +606,7 @@ controls: status: automated - id: 1.6.2 - title: Ensure local login warning banner is configured properly (Automated) + title: Ensure /etc/issue is configured (Automated) levels: - l1_server - l1_workstation @@ -526,7 +616,7 @@ controls: status: automated - id: 1.6.3 - title: Ensure remote login warning banner is configured properly (Automated) + title: Ensure /etc/issue.net is configured (Automated) levels: - l1_server - l1_workstation From d69bfca06241d509afb4a6a7b3ff08307904699e Mon Sep 17 00:00:00 2001 From: Israel Villar Boillos Date: Mon, 30 Mar 2026 18:40:25 +0100 Subject: [PATCH 05/61] Align Debian 13 CIS GDM controls with benchmark --- controls/cis_debian13.yml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/controls/cis_debian13.yml b/controls/cis_debian13.yml index 6cb3fa01f2f8..884245830295 100644 --- a/controls/cis_debian13.yml +++ b/controls/cis_debian13.yml @@ -776,6 +776,14 @@ controls: - gnome_gdm_disable_xdmcp status: automated + - id: 1.7.11 + title: Ensure Xwayland is configured (Automated) + levels: + - l1_workstation + rules: + - xwayland_disabled + status: automated + - id: 2.1.1 title: Ensure autofs services are not in use (Automated) levels: From abbda5007eb8398a9687086be7fcb401eb6c3a86 Mon Sep 17 00:00:00 2001 From: Israel Villar Boillos Date: Mon, 30 Mar 2026 19:22:55 +0100 Subject: [PATCH 06/61] Align section 2.4 with CIS Debian 13 (cron access, cron.yearly, titles update) --- controls/cis_debian13.yml | 30 ++++++++++++++++++++---------- 1 file changed, 20 insertions(+), 10 deletions(-) diff --git a/controls/cis_debian13.yml b/controls/cis_debian13.yml index 884245830295..2c31c42788ca 100644 --- a/controls/cis_debian13.yml +++ b/controls/cis_debian13.yml @@ -1144,19 +1144,18 @@ controls: status: automated - id: 2.4.1.2 - title: Ensure permissions on /etc/crontab are configured (Automated) + title: Ensure access to /etc/crontab are configured (Automated) levels: - l1_server - l1_workstation rules: - - file_cron_allow_exists - file_groupowner_crontab - file_owner_crontab - file_permissions_crontab status: automated - id: 2.4.1.3 - title: Ensure permissions on /etc/cron.hourly are configured (Automated) + title: Ensure access to /etc/cron.hourly are configured (Automated) levels: - l1_server - l1_workstation @@ -1167,7 +1166,7 @@ controls: status: automated - id: 2.4.1.4 - title: Ensure permissions on /etc/cron.daily are configured (Automated) + title: Ensure access ton /etc/cron.daily are configured (Automated) levels: - l1_server - l1_workstation @@ -1178,7 +1177,7 @@ controls: status: automated - id: 2.4.1.5 - title: Ensure permissions on /etc/cron.weekly are configured (Automated) + title: Ensure access to /etc/cron.weekly are configured (Automated) levels: - l1_server - l1_workstation @@ -1189,7 +1188,7 @@ controls: status: automated - id: 2.4.1.6 - title: Ensure permissions on /etc/cron.monthly are configured (Automated) + title: Ensure access to /etc/cron.monthly are configured (Automated) levels: - l1_server - l1_workstation @@ -1198,9 +1197,19 @@ controls: - file_owner_cron_monthly - file_permissions_cron_monthly status: automated - - id: 2.4.1.7 - title: Ensure permissions on /etc/cron.d are configured (Automated) + title: Ensure access to /etc/cron.yearly is configured (Automated) + levels: + - l1_server + - l1_workstation + rules: + - file_groupowner_cron_yearly + - file_owner_cron_yearly + - file_permissions_cron_yearly + status: automated + + - id: 2.4.1.8 + title: Ensure access to /etc/cron.d are configured (Automated) levels: - l1_server - l1_workstation @@ -1210,12 +1219,13 @@ controls: - file_permissions_cron_d status: automated - - id: 2.4.1.8 - title: Ensure crontab is restricted to authorized users (Automated) + - id: 2.4.1.9 + title: Ensure access to crontab is configured (Automated) levels: - l1_server - l1_workstation rules: + - file_cron_allow_exists - file_cron_deny_not_exist - file_groupowner_cron_allow - file_owner_cron_allow From 9bf74d8e000a6fd5bd5aad4c39efecb795d217b4 Mon Sep 17 00:00:00 2001 From: Israel Villar Boillos Date: Mon, 30 Mar 2026 19:28:58 +0100 Subject: [PATCH 07/61] CIS Debian 13: fix section 2.4 - Align control IDs with CIS benchmark - Add /etc/cron.yearly control (2.4.1.7) - Update titles from 'permissions' to 'access' - Fix crontab access control (2.4.1.9) - Remove incorrect cron_allow reference in 2.4.1.2 --- controls/cis_debian13.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/controls/cis_debian13.yml b/controls/cis_debian13.yml index 2c31c42788ca..52167e0575e0 100644 --- a/controls/cis_debian13.yml +++ b/controls/cis_debian13.yml @@ -1233,7 +1233,7 @@ controls: status: automated - id: 2.4.2.1 - title: Ensure at is restricted to authorized users (Automated) + title: Ensure access to at is configured (Automated) levels: - l1_server - l1_workstation From 87ea2239ccc74c5e13c1894702cc6f88dbf4a818 Mon Sep 17 00:00:00 2001 From: Israel Villar Boillos Date: Tue, 31 Mar 2026 21:37:43 +0100 Subject: [PATCH 08/61] Align section 3.3 with CIS Debian 13 --- controls/cis_debian13.yml | 212 +++++++++++++++++++++++++++++++------- 1 file changed, 172 insertions(+), 40 deletions(-) diff --git a/controls/cis_debian13.yml b/controls/cis_debian13.yml index 52167e0575e0..45f7deefd64a 100644 --- a/controls/cis_debian13.yml +++ b/controls/cis_debian13.yml @@ -1257,7 +1257,7 @@ controls: status: manual - id: 3.1.2 - title: Ensure wireless interfaces are disabled (Automated) + title: Ensure wireless interfaces are not available (Automated) levels: - l1_server rules: @@ -1273,64 +1273,98 @@ controls: - service_bluetooth_disabled status: automated - - id: 3.2.1 + - id: 3.2.1 + title: Ensure atm kernel module is not available (Automated) + levels: + - l1_server + - l1_workstation + rules: + - kernel_module_atm_disabled + status: automated + + - id: 3.2.2 title: Ensure dccp kernel module is not available (Automated) levels: - - l2_server - - l2_workstation + - l1_server + - l1_workstation rules: - kernel_module_dccp_disabled status: automated - - id: 3.2.2 + - id: 3.2.3 title: Ensure tipc kernel module is not available (Automated) levels: - - l2_server - - l2_workstation + - l1_server + - l1_workstation rules: - kernel_module_tipc_disabled status: automated - - id: 3.2.3 + - id: 3.2.4 title: Ensure rds kernel module is not available (Automated) levels: - - l2_server - - l2_workstation + - l1_server + - l1_workstation rules: - kernel_module_rds_disabled status: automated - - id: 3.2.4 + - id: 3.2.5 title: Ensure sctp kernel module is not available (Automated) levels: - - l2_server - - l2_workstation + - l1_server + - l1_workstation rules: - kernel_module_sctp_disabled status: automated - - id: 3.3.1 - title: Ensure ip forwarding is disabled (Automated) + - id: 3.3.1.1 + title: Ensure net.ipv4.ip_forward is configured (Automated) levels: - l1_server - l1_workstation rules: - - sysctl_net_ipv6_conf_all_forwarding - sysctl_net_ipv4_ip_forward status: automated - - id: 3.3.2 - title: Ensure packet redirect sending is disabled (Automated) + - id: 3.3.1.2 + title: Ensure net.ipv4.conf.all.forwarding is configured (Automated) + levels: + - l1_server + - l1_workstation + rules: + - sysctl_net_ipv4_conf_all_forwarding + status: automated + + - id: 3.3.1.3 + title: Ensure net.ipv4.conf.default.forwarding is configured (Automated) + levels: + - l1_server + - l1_workstation + rules: + - sysctl_net_ipv4_conf_default_forwarding + status: automated + + - id: 3.3.1.4 + title: Ensure net.ipv4.conf.all.send_redirects is configured (Automated) levels: - l1_server - l1_workstation rules: - sysctl_net_ipv4_conf_all_send_redirects + status: automated + + - id: 3.3.1.5 + title: Ensure net.ipv4.conf.default.send_redirects is configured (Automated) + levels: + - l1_server + - l1_workstation + rules: - sysctl_net_ipv4_conf_default_send_redirects status: automated - - id: 3.3.3 - title: Ensure bogus icmp responses are ignored (Automated) + - id: 3.3.1.6 + title: Ensure net.ipv4.icmp_ignore_bogus_error_responses is configured (Automated) levels: - l1_server - l1_workstation @@ -1338,8 +1372,8 @@ controls: - sysctl_net_ipv4_icmp_ignore_bogus_error_responses status: automated - - id: 3.3.4 - title: Ensure broadcast icmp requests are ignored (Automated) + - id: 3.3.1.7 + title: Ensure net.ipv4.icmp_echo_ignore_broadcasts is configured (Automated) levels: - l1_server - l1_workstation @@ -1347,62 +1381,98 @@ controls: - sysctl_net_ipv4_icmp_echo_ignore_broadcasts status: automated - - id: 3.3.5 - title: Ensure icmp redirects are not accepted (Automated) + - id: 3.3.1.8 + title: Ensure net.ipv4.conf.all.accept_redirects is configured (Automated) levels: - l1_server - l1_workstation rules: - - sysctl_net_ipv6_conf_all_accept_redirects - - sysctl_net_ipv6_conf_default_accept_redirects - sysctl_net_ipv4_conf_all_accept_redirects + status: automated + + - id: 3.3.1.9 + title: Ensure net.ipv4.conf.default.accept_redirects is configured (Automated) + levels: + - l1_server + - l1_workstation + rules: - sysctl_net_ipv4_conf_default_accept_redirects status: automated - - id: 3.3.6 - title: Ensure secure icmp redirects are not accepted (Automated) + - id: 3.3.1.10 + title: Ensure net.ipv4.conf.all.secure_redirects is configured (Automated) levels: - l1_server - l1_workstation rules: - sysctl_net_ipv4_conf_all_secure_redirects + status: automated + + - id: 3.3.1.11 + title: Ensure net.ipv4.conf.default.secure_redirects is configured (Automated) + levels: + - l1_server + - l1_workstation + rules: - sysctl_net_ipv4_conf_default_secure_redirects status: automated - - id: 3.3.7 - title: Ensure reverse path filtering is enabled (Automated) + - id: 3.3.1.12 + title: Ensure net.ipv4.conf.all.rp_filter is configured (Automated) levels: - l1_server - l1_workstation rules: - sysctl_net_ipv4_conf_all_rp_filter + status: automated + + - id: 3.3.1.13 + title: Ensure net.ipv4.conf.default.rp_filter is configured (Automated) + levels: + - l1_server + - l1_workstation + rules: - sysctl_net_ipv4_conf_default_rp_filter status: automated - - id: 3.3.8 - title: Ensure source routed packets are not accepted (Automated) + - id: 3.3.1.14 + title: Ensure net.ipv4.conf.all.accept_source_route is configured (Automated) levels: - l1_server - l1_workstation rules: - - sysctl_net_ipv6_conf_all_accept_source_route - - sysctl_net_ipv6_conf_default_accept_source_route - sysctl_net_ipv4_conf_all_accept_source_route + status: automated + + - id: 3.3.1.15 + title: Ensure net.ipv4.conf.default.accept_source_route is configured (Automated) + levels: + - l1_server + - l1_workstation + rules: - sysctl_net_ipv4_conf_default_accept_source_route status: automated - - id: 3.3.9 - title: Ensure suspicious packets are logged (Automated) + - id: 3.3.1.16 + title: Ensure net.ipv4.conf.all.log_martians is configured (Automated) levels: - l1_server - l1_workstation rules: - sysctl_net_ipv4_conf_all_log_martians + status: automated + + - id: 3.3.1.17 + title: Ensure net.ipv4.conf.default.log_martians is configured (Automated) + levels: + - l1_server + - l1_workstation + rules: - sysctl_net_ipv4_conf_default_log_martians status: automated - - id: 3.3.10 - title: Ensure tcp syn cookies is enabled (Automated) + - id: 3.3.1.18 + title: Ensure net.ipv4.tcp_syncookies is configured (Automated) levels: - l1_server - l1_workstation @@ -1410,13 +1480,75 @@ controls: - sysctl_net_ipv4_tcp_syncookies status: automated - - id: 3.3.11 - title: Ensure ipv6 router advertisements are not accepted (Automated) + - id: 3.3.2.1 + title: Ensure net.ipv6.conf.all.forwarding is configured (Automated) + levels: + - l1_server + - l1_workstation + rules: + - sysctl_net_ipv6_conf_all_forwarding + status: automated + + - id: 3.3.2.2 + title: Ensure net.ipv6.conf.default.forwarding is configured (Automated) + levels: + - l1_server + - l1_workstation + rules: + - sysctl_net_ipv6_conf_default_forwarding + status: automated + + - id: 3.3.2.3 + title: Ensure net.ipv6.conf.all.accept_redirects is configured (Automated) + levels: + - l1_server + - l1_workstation + rules: + - sysctl_net_ipv6_conf_all_accept_redirects + status: automated + + - id: 3.3.2.4 + title: Ensure net.ipv6.conf.default.accept_redirects is configured (Automated) + levels: + - l1_server + - l1_workstation + rules: + - sysctl_net_ipv6_conf_default_accept_redirects + status: automated + + - id: 3.3.2.5 + title: Ensure net.ipv6.conf.all.accept_source_route is configured (Automated) + levels: + - l1_server + - l1_workstation + rules: + - sysctl_net_ipv6_conf_all_accept_source_route + status: automated + + - id: 3.3.2.6 + title: Ensure net.ipv6.conf.default.accept_source_route is configured (Automated) + levels: + - l1_server + - l1_workstation + rules: + - sysctl_net_ipv6_conf_default_accept_source_route + status: automated + + - id: 3.3.2.7 + title: Ensure net.ipv6.conf.all.accept_ra is configured (Automated) levels: - l1_server - l1_workstation rules: - sysctl_net_ipv6_conf_all_accept_ra + status: automated + + - id: 3.3.2.8 + title: Ensure net.ipv6.conf.default.accept_ra is configured (Automated) + levels: + - l1_server + - l1_workstation + rules: - sysctl_net_ipv6_conf_default_accept_ra status: automated From d8d3afb9e4ff63a17c2ae7cd5c3cb43362a31364 Mon Sep 17 00:00:00 2001 From: Israel Villar Boillos Date: Tue, 31 Mar 2026 21:57:07 +0100 Subject: [PATCH 09/61] Align section 4 with CIS Debian 13 --- controls/cis_debian13.yml | 252 +++----------------------------------- 1 file changed, 18 insertions(+), 234 deletions(-) diff --git a/controls/cis_debian13.yml b/controls/cis_debian13.yml index 45f7deefd64a..04cb950b88af 100644 --- a/controls/cis_debian13.yml +++ b/controls/cis_debian13.yml @@ -1552,20 +1552,7 @@ controls: - sysctl_net_ipv6_conf_default_accept_ra status: automated - - id: 4.1.1 - title: Ensure a single firewall configuration utility is in use (Automated) - levels: - - l1_server - - l1_workstation - rules: - - firewall_single_service_active - - var_network_filtering_service=nftables - status: automated - notes: | - Remediation is not automated. To select which firewall to - install and configure, use the profile variable var_network_filtering_service. - - - id: 4.2.1 + - id: 4.1.1 title: Ensure ufw is installed (Automated) levels: - l1_server @@ -1574,17 +1561,8 @@ controls: - package_ufw_installed status: automated - - id: 4.2.2 - title: Ensure iptables-persistent is not installed with ufw (Automated) - levels: - - l1_server - - l1_workstation - rules: - - package_iptables-persistent_removed - status: automated - - - id: 4.2.3 - title: Ensure ufw service is enabled (Automated) + - id: 4.1.2 + title: Ensure ufw service is configured (Automated) levels: - l1_server - l1_workstation @@ -1593,235 +1571,41 @@ controls: - service_ufw_enabled status: automated - - id: 4.2.4 - title: Ensure ufw loopback traffic is configured (Automated) - levels: - - l1_server - - l1_workstation - rules: - - set_ufw_loopback_traffic - status: automated - - - id: 4.2.5 - title: Ensure ufw outbound connections are configured (Manual) - levels: - - l1_server - - l1_workstation - status: manual - - - id: 4.2.6 - title: Ensure ufw firewall rules exist for all open ports (Automated) - levels: - - l1_server - - l1_workstation - rules: - - ufw_rules_for_open_ports - status: automated - - - id: 4.2.7 - title: Ensure ufw default deny firewall policy (Automated) + - id: 4.1.3 + title: Ensure ufw incoming default is configured (Automated) levels: - l1_server - l1_workstation rules: - set_ufw_default_rule status: automated - - - id: 4.3.1 - title: Ensure nftables is installed (Automated) - levels: - - l1_server - - l1_workstation - rules: - - package_nftables_installed - status: automated - - - id: 4.3.2 - title: Ensure ufw is uninstalled or disabled with nftables (Automated) - levels: - - l1_server - - l1_workstation - rules: - - package_ufw_removed - status: automated - - - id: 4.3.3 - title: Ensure iptables are flushed with nftables (Manual) - levels: - - l1_server - - l1_workstation - status: manual - - - id: 4.3.4 - title: Ensure a nftables table exists (Automated) - levels: - - l1_server - - l1_workstation - rules: - - var_nftables_family=inet - - var_nftables_table=filter - - set_nftables_table - status: automated - - - id: 4.3.5 - title: Ensure nftables base chains exist (Automated) - levels: - - l1_server - - l1_workstation - rules: - - var_nftables_base_chain_names=chain_names - - var_nftables_base_chain_types=chain_types - - var_nftables_base_chain_hooks=chain_hooks - - var_nftables_base_chain_priorities=chain_priorities - - var_nftables_base_chain_policies=chain_policies - - set_nftables_base_chain - status: automated - - - id: 4.3.6 - title: Ensure nftables loopback traffic is configured (Automated) - levels: - - l1_server - - l1_workstation - rules: - - set_nftables_loopback_traffic - status: automated - - - id: 4.3.7 - title: Ensure nftables outbound and established connections are configured (Manual) - levels: - - l1_server - - l1_workstation - status: manual - - - id: 4.3.8 - title: Ensure nftables default deny firewall policy (Automated) - levels: - - l1_server - - l1_workstation - rules: - - nftables_ensure_default_deny_policy - status: automated - - - id: 4.3.9 - title: Ensure nftables service is enabled (Automated) - levels: - - l1_server - - l1_workstation - rules: - - service_nftables_enabled - status: automated - - - id: 4.3.10 - title: Ensure nftables rules are permanent (Automated) - levels: - - l1_server - - l1_workstation - rules: - - var_nftables_master_config_file=etc - - nftables_rules_permanent - status: automated notes: | - Audit procedure for 4.3.10 depends on local site policy thus - it cannot be fully automated. Upstream ticket: - https://workbench.cisecurity.org/benchmarks/18959/tickets/23190 - - - id: 4.4.1.1 - title: Ensure iptables packages are installed (Automated) - levels: - - l1_server - - l1_workstation - rules: - - package_iptables-persistent_installed - - package_iptables_installed - status: automated - - - id: 4.4.1.2 - title: Ensure nftables is not in use with iptables (Automated) - levels: - - l1_server - - l1_workstation - rules: - - service_nftables_disabled - status: automated + The existing rule set_ufw_default_rule covers the default incoming, + outgoing, and routed UFW policies together. - - id: 4.4.1.3 - title: Ensure ufw is not in use with iptables (Automated) + - id: 4.1.4 + title: Ensure ufw outgoing default is configured (Automated) levels: - l1_server - l1_workstation rules: - - package_ufw_removed - status: automated - - - id: 4.4.2.1 - title: Ensure iptables default deny firewall policy (Automated) - levels: - - l1_server - - l1_workstation - rules: - - set_iptables_default_rule - status: automated - - - id: 4.4.2.2 - title: Ensure iptables loopback traffic is configured (Automated) - levels: - - l1_server - - l1_workstation - rules: - - set_loopback_traffic - status: automated - - - id: 4.4.2.3 - title: Ensure iptables outbound and established connections are configured (Manual) - levels: - - l1_server - - l1_workstation - status: manual - - - id: 4.4.2.4 - title: Ensure iptables firewall rules exist for all open ports (Automated) - levels: - - l1_server - - l1_workstation - rules: - - iptables_rules_for_open_ports - status: automated - - - id: 4.4.3.1 - title: Ensure ip6tables default deny firewall policy (Automated) - levels: - - l1_server - - l1_workstation - rules: - - set_ip6tables_default_rule - status: automated - - - id: 4.4.3.2 - title: Ensure ip6tables loopback traffic is configured (Automated) - levels: - - l1_server - - l1_workstation - rules: - - set_ipv6_loopback_traffic + - set_ufw_default_rule status: automated + notes: | + The existing rule set_ufw_default_rule covers the default incoming, + outgoing, and routed UFW policies together. - - id: 4.4.3.3 - title: Ensure ip6tables outbound and established connections are configured (Manual) - levels: - - l1_server - - l1_workstation - status: manual - - - id: 4.4.3.4 - title: Ensure ip6tables firewall rules exist for all open ports (Automated) + - id: 4.1.5 + title: Ensure ufw routed default is configured (Automated) levels: - l1_server - l1_workstation rules: - - ip6tables_rules_for_open_ports + - set_ufw_default_rule status: automated notes: | - Remediation is not automated to avoid lockout. + The existing rule set_ufw_default_rule covers the default incoming, + outgoing, and routed UFW policies together. - id: 5.1.1 title: Ensure permissions on /etc/ssh/sshd_config are configured (Automated) From 52b0b1f0dc58f1f061f7a56fe358797a054792fc Mon Sep 17 00:00:00 2001 From: Israel Villar Boillos Date: Tue, 31 Mar 2026 22:47:12 +0100 Subject: [PATCH 10/61] Align section 5 with CIS Debian 13 --- controls/cis_debian13.yml | 48 ++++++++++++++++++++++++++------------- 1 file changed, 32 insertions(+), 16 deletions(-) diff --git a/controls/cis_debian13.yml b/controls/cis_debian13.yml index 04cb950b88af..63d4926b0557 100644 --- a/controls/cis_debian13.yml +++ b/controls/cis_debian13.yml @@ -1273,7 +1273,7 @@ controls: - service_bluetooth_disabled status: automated - - id: 3.2.1 + - id: 3.2.1 title: Ensure atm kernel module is not available (Automated) levels: - l1_server @@ -1552,7 +1552,7 @@ controls: - sysctl_net_ipv6_conf_default_accept_ra status: automated - - id: 4.1.1 + - id: 4.1.1 title: Ensure ufw is installed (Automated) levels: - l1_server @@ -1608,7 +1608,7 @@ controls: outgoing, and routed UFW policies together. - id: 5.1.1 - title: Ensure permissions on /etc/ssh/sshd_config are configured (Automated) + title: Ensure access to /etc/ssh/sshd_config is configured (Automated) levels: - l1_server - l1_workstation @@ -1619,7 +1619,7 @@ controls: status: automated - id: 5.1.2 - title: Ensure permissions on SSH private host key files are configured (Automated) + title: Ensure access to SSH private host key files is configured (Automated) levels: - l1_server - l1_workstation @@ -1628,7 +1628,7 @@ controls: status: automated - id: 5.1.3 - title: Ensure permissions on SSH public host key files are configured (Automated) + title: Ensure access to SSH public host key files is configured (Automated) levels: - l1_server - l1_workstation @@ -1724,8 +1724,24 @@ controls: - sshd_strong_kex=cis_debian13 - sshd_use_strong_kex status: automated + notes: | + The selected KEX set includes the benchmark-required post-quantum + SSH key exchange algorithm(s). - id: 5.1.13 + title: Ensure sshd post-quantum cryptography key exchange algorithms are configured (Automated) + levels: + - l1_server + - l1_workstation + rules: + - sshd_strong_kex=cis_debian13 + - sshd_use_strong_kex + status: automated + notes: | + This control is implemented through the same KexAlgorithms setting + used in 5.1.12. + + - id: 5.1.14 title: Ensure sshd LoginGraceTime is configured (Automated) levels: - l1_server @@ -1735,7 +1751,7 @@ controls: - sshd_set_login_grace_time status: automated - - id: 5.1.14 + - id: 5.1.15 title: Ensure sshd LogLevel is configured (Automated) levels: - l1_server @@ -1744,7 +1760,7 @@ controls: - sshd_set_loglevel_info status: automated - - id: 5.1.15 + - id: 5.1.16 title: Ensure sshd MACs are configured (Automated) levels: - l1_server @@ -1754,7 +1770,7 @@ controls: - sshd_use_strong_macs status: automated - - id: 5.1.16 + - id: 5.1.17 title: Ensure sshd MaxAuthTries is configured (Automated) levels: - l1_server @@ -1764,7 +1780,7 @@ controls: - sshd_set_max_auth_tries status: automated - - id: 5.1.17 + - id: 5.1.18 title: Ensure sshd MaxSessions is configured (Automated) levels: - l1_server @@ -1774,7 +1790,7 @@ controls: - sshd_set_max_sessions status: automated - - id: 5.1.18 + - id: 5.1.19 title: Ensure sshd MaxStartups is configured (Automated) levels: - l1_server @@ -1784,7 +1800,7 @@ controls: - sshd_set_maxstartups status: automated - - id: 5.1.19 + - id: 5.1.20 title: Ensure sshd PermitEmptyPasswords is disabled (Automated) levels: - l1_server @@ -1793,7 +1809,7 @@ controls: - sshd_disable_empty_passwords status: automated - - id: 5.1.20 + - id: 5.1.21 title: Ensure sshd PermitRootLogin is disabled (Automated) levels: - l1_server @@ -1802,7 +1818,7 @@ controls: - sshd_disable_root_login status: automated - - id: 5.1.21 + - id: 5.1.22 title: Ensure sshd PermitUserEnvironment is disabled (Automated) levels: - l1_server @@ -1811,7 +1827,7 @@ controls: - sshd_do_not_permit_user_env status: automated - - id: 5.1.22 + - id: 5.1.23 title: Ensure sshd UsePAM is enabled (Automated) levels: - l1_server @@ -1899,7 +1915,7 @@ controls: it is the latest version as the title suggests. - id: 5.3.1.2 - title: Ensure libpam-modules is installed (Automated) + title: Ensure lastest version of libpam-modules is installed (Automated) levels: - l1_server - l1_workstation @@ -1908,7 +1924,7 @@ controls: status: automated - id: 5.3.1.3 - title: Ensure libpam-pwquality is installed (Automated) + title: Ensure lastes version of libpam-pwquality is installed (Automated) levels: - l1_server - l1_workstation From b1a12d3ee6aaa389f4cdde97d7900c94d8b646bb Mon Sep 17 00:00:00 2001 From: Israel Villar Boillos Date: Sun, 5 Apr 2026 22:08:52 +0100 Subject: [PATCH 11/61] Add CIS Debian 13 6.x & 7.x profile mappings --- controls/cis_debian13.yml | 386 +++++++++++++++++++++++--------------- 1 file changed, 234 insertions(+), 152 deletions(-) diff --git a/controls/cis_debian13.yml b/controls/cis_debian13.yml index 63d4926b0557..d3b3225d2bbd 100644 --- a/controls/cis_debian13.yml +++ b/controls/cis_debian13.yml @@ -2329,8 +2329,8 @@ controls: - accounts_umask_etc_profile status: automated - - id: 6.1.1.1 - title: Ensure journald service is enabled and active (Automated) + - id: 6.1.1.1.1 + title: Ensure journald service is active (Automated) levels: - l1_server - l1_workstation @@ -2338,101 +2338,85 @@ controls: - service_systemd-journald_enabled status: automated - - id: 6.1.1.2 + - id: 6.1.1.1.2 title: Ensure journald log file access is configured (Manual) levels: - l1_server - l1_workstation status: manual - - id: 6.1.1.3 + - id: 6.1.1.1.3 title: Ensure journald log file rotation is configured (Manual) levels: - l1_server - l1_workstation status: manual - - id: 6.1.1.4 - title: Ensure only one logging system is in use (Automated) - levels: - - l1_server - - l1_workstation - rules: - - logging_services_active - status: automated - notes: | - The title of this rule is misleading. The actual audit checks that at least - one of "rsyslogd" and "systemd-journald" is active. - See https://workbench.cisecurity.org/benchmarks/18959/tickets/23601 - - Remediation is not automated as the choice of correct logging service - is dependent on site policy. - - - id: 6.1.2.1.1 - title: Ensure systemd-journal-remote is installed (Automated) + - id: 6.1.1.1.4 + title: Ensure journald ForwardToSyslog is disabled (Automated) levels: - l1_server - l1_workstation rules: - - package_systemd-journal-remote_installed + - journald_disable_forward_to_syslog status: automated - - id: 6.1.2.1.2 - title: Ensure systemd-journal-upload authentication is configured (Manual) + - id: 6.1.1.1.5 + title: Ensure journald Storage is configured (Automated) levels: - l1_server - l1_workstation rules: - - systemd_journal_upload_server_tls - - systemd_journal_upload_url + - journald_storage status: automated - - id: 6.1.2.1.3 - title: Ensure systemd-journal-upload is enabled and active (Automated) + - id: 6.1.1.1.6 + title: Ensure journald Compress is configured (Automated) levels: - l1_server - l1_workstation rules: - - service_systemd-journal-upload_enabled + - journald_compress status: automated - - id: 6.1.2.1.4 - title: Ensure systemd-journal-remote service is not in use (Automated) + - id: 6.1.1.2.1 + title: Ensure systemd-journal-remote is installed (Automated) levels: - l1_server - l1_workstation rules: - - socket_systemd-journal-remote_disabled + - package_systemd-journal-remote_installed status: automated - - id: 6.1.2.2 - title: Ensure journald ForwardToSyslog is disabled (Automated) + - id: 6.1.1.2.2 + title: Ensure systemd-journal-upload authentication is configured (Manual) levels: - l1_server - l1_workstation rules: - - journald_disable_forward_to_syslog + - systemd_journal_upload_server_tls + - systemd_journal_upload_url status: automated - - id: 6.1.2.3 - title: Ensure journald Compress is configured (Automated) + - id: 6.1.1.2.3 + title: Ensure systemd-journal-upload is enabled and active (Automated) levels: - l1_server - l1_workstation rules: - - journald_compress + - service_systemd-journal-upload_enabled status: automated - - id: 6.1.2.4 - title: Ensure journald Storage is configured (Automated) + - id: 6.1.1.2.4 + title: Ensure systemd-journal-remote service is not in use (Automated) levels: - l1_server - l1_workstation rules: - - journald_storage + - socket_systemd-journal-remote_disabled status: automated - - id: 6.1.3.1 + - id: 6.1.2.1 title: Ensure rsyslog is installed (Automated) levels: - l1_server @@ -2441,7 +2425,7 @@ controls: - package_rsyslog_installed status: automated - - id: 6.1.3.2 + - id: 6.1.2.2 title: Ensure rsyslog service is enabled and active (Automated) levels: - l1_server @@ -2450,7 +2434,7 @@ controls: - service_rsyslog_enabled status: automated - - id: 6.1.3.3 + - id: 6.1.2.3 title: Ensure journald is configured to send logs to rsyslog (Automated) levels: - l1_server @@ -2459,7 +2443,7 @@ controls: - journald_forward_to_syslog status: automated - - id: 6.1.3.4 + - id: 6.1.2.4 title: Ensure rsyslog log file creation mode is configured (Automated) levels: - l1_server @@ -2468,14 +2452,14 @@ controls: - rsyslog_filecreatemode status: automated - - id: 6.1.3.5 + - id: 6.1.2.5 title: Ensure rsyslog logging is configured (Manual) levels: - l1_server - l1_workstation status: manual - - id: 6.1.3.6 + - id: 6.1.2.6 title: Ensure rsyslog is configured to send logs to a remote log host (Manual) levels: - l1_server @@ -2483,12 +2467,8 @@ controls: related_rules: - rsyslog_remote_loghost status: manual - notes: | - Existing rule (rsyslog_remote_loghost) is not used because rsyslog configuration - is site-specific and can be too complex to reliably audit and remediate. - See also https://github.com/ComplianceAsCode/content/issues/11812 - - id: 6.1.3.7 + - id: 6.1.2.7 title: Ensure rsyslog is not configured to receive logs from a remote client (Automated) levels: - l1_server @@ -2497,68 +2477,38 @@ controls: - rsyslog_nolisten status: automated - - id: 6.1.3.8 + - id: 6.1.2.8 title: Ensure logrotate is configured (Manual) levels: - l1_server - l1_workstation status: manual - - id: 6.1.4.1 - title: Ensure access to all logfiles has been configured (Automated) - levels: - - l1_server - - l1_workstation - rules: - - file_groupownerships_var_log_apt - - file_groupownerships_var_log_gdm - - file_groupownerships_var_log_gdm3 - - file_groupownerships_var_log_landscape - - file_groupownerships_var_log_sssd - - file_groupowner_var_log_auth - - file_groupowner_var_log_cloud_init - - file_groupowner_var_log_journal - - file_groupowner_var_log_lastlog - - file_groupowner_var_log_localmessages - - file_groupowner_var_log_messages - - file_groupowner_var_log_secure - - file_groupowner_var_log_syslog - - file_groupowner_var_log_waagent - - file_groupowner_var_log_wbtmp - - file_ownerships_var_log_apt - - file_ownerships_var_log_gdm - - file_ownerships_var_log_gdm3 - - file_ownerships_var_log_landscape - - file_ownerships_var_log_sssd - - file_owner_var_log_auth - - file_owner_var_log_cloud_init - - file_owner_var_log_journal - - file_owner_var_log_lastlog - - file_owner_var_log_localmessages - - file_owner_var_log_messages - - file_owner_var_log_secure - - file_owner_var_log_syslog - - file_owner_var_log_waagent - - file_owner_var_log_wbtmp - - file_permissions_var_log_apt - - file_permissions_var_log_auth - - file_permissions_var_log_cloud-init - - file_permissions_var_log_gdm - - file_permissions_var_log_gdm3 - - file_permissions_var_log_lastlog - - file_permissions_var_log_cloud-init - - file_permissions_var_log_localmessages - - file_permissions_var_log_messages - - file_permissions_var_log_secure - - file_permissions_var_log_sssd - - file_permissions_var_log_syslog - - file_permissions_var_log_waagent - - file_permissions_var_log_wbtmp - - file_groupownerships_var_log - - file_ownerships_var_log - - permissions_local_var_log + - id: 6.1.2.9 + title: Ensure rsyslog-gnutls is installed (Automated) + levels: + - l1_server + - l1_workstation + rules: + - package_rsyslog-gnutls_installed + status: automated + + - id: 6.1.2.10 + title: Ensure rsyslog forwarding uses gtls (Automated) + levels: + - l1_server + - l1_workstation + rules: + - rsyslog_use_gtls status: automated + - id: 6.1.2.11 + title: Ensure rsyslog CA certificates are configured (Manual) + levels: + - l1_server + - l1_workstation + status: manual + - id: 6.2.1.1 title: Ensure auditd packages are installed (Automated) levels: @@ -2628,8 +2578,8 @@ controls: - l2_server - l2_workstation rules: - - var_auditd_disk_error_action=cis_debian13 - - var_auditd_disk_full_action=cis_debian13 + - var_auditd_disk_error_action=cis_debian12 + - var_auditd_disk_full_action=cis_debian12 - auditd_data_disk_error_action - auditd_data_disk_full_action status: automated @@ -2651,7 +2601,7 @@ controls: The variables should allow multiple options. - id: 6.2.3.1 - title: Ensure changes to system administration scope (sudoers) is collected (Automated) + title: Ensure modification of the /etc/sudoers file is collected (Automated) levels: - l2_server - l2_workstation @@ -2690,7 +2640,7 @@ controls: status: automated - id: 6.2.3.5 - title: Ensure events that modify the system's network environment are collected (Automated) + title: Ensure events that modify sethostname and setdomainname are collected (Automated) levels: - l2_server - l2_workstation @@ -2699,6 +2649,43 @@ controls: status: automated - id: 6.2.3.6 + title: Ensure events that modify /etc/issue and /etc/issue.net are collected (Automated) + levels: + - l2_server + - l2_workstation + rules: + - audit_rules_networkconfig_modification + status: automated + + - id: 6.2.3.7 + title: Ensure events that modify /etc/hosts and /etc/hostname are collected (Automated) + levels: + - l2_server + - l2_workstation + rules: + - audit_rules_networkconfig_modification + status: automated + + - id: 6.2.3.8 + title: Ensure events that modify the system's network environment are collected (Automated) + levels: + - l2_server + - l2_workstation + rules: + - audit_rules_networkconfig_modification + status: automated + + - id: 6.2.3.9 + title: Ensure events that modify /etc/NetworkManager directory are collected (Automated) + levels: + - l2_server + - l2_workstation + rules: + - audit_rules_networkconfig_modification_etc_networkmanager_system_connections + - audit_rules_networkconfig_modification_networkmanager + status: automated + + - id: 6.2.3.10 title: Ensure use of privileged commands are collected (Automated) levels: - l2_server @@ -2707,7 +2694,7 @@ controls: - audit_rules_privileged_commands status: automated - - id: 6.2.3.7 + - id: 6.2.3.11 title: Ensure unsuccessful file access attempts are collected (Automated) levels: - l2_server @@ -2720,44 +2707,100 @@ controls: - audit_rules_unsuccessful_file_modification_truncate status: automated - - id: 6.2.3.8 - title: Ensure events that modify user/group information are collected (Automated) + - id: 6.2.3.12 + title: Ensure events that modify /etc/group information are collected (Automated) levels: - l2_server - l2_workstation rules: - audit_rules_usergroup_modification_group - - audit_rules_usergroup_modification_gshadow - - audit_rules_usergroup_modification_opasswd + status: automated + + - id: 6.2.3.13 + title: Ensure events that modify /etc/passwd information are collected (Automated) + levels: + - l2_server + - l2_workstation + rules: - audit_rules_usergroup_modification_passwd + status: automated + + - id: 6.2.3.14 + title: Ensure events that modify /etc/shadow and /etc/gshadow are collected (Automated) + levels: + - l2_server + - l2_workstation + rules: - audit_rules_usergroup_modification_shadow + - audit_rules_usergroup_modification_gshadow + status: automated + + - id: 6.2.3.15 + title: Ensure events that modify /etc/security/opasswd are collected (Automated) + levels: + - l2_server + - l2_workstation + rules: + - audit_rules_usergroup_modification_opasswd + status: automated + + - id: 6.2.3.16 + title: Ensure events that modify /etc/nsswitch.conf file are collected (Automated) + levels: + - l2_server + - l2_workstation + rules: - audit_rules_usergroup_modification_nsswitch_conf + status: automated + + - id: 6.2.3.17 + title: Ensure events that modify /etc/pam.conf and /etc/pam.d/ information are collected (Automated) + levels: + - l2_server + - l2_workstation + rules: - audit_rules_usergroup_modification_pam_conf - audit_rules_usergroup_modification_pamd status: automated - - id: 6.2.3.9 - title: Ensure discretionary access control permission modification events are collected (Automated) + - id: 6.2.3.18 + title: Ensure discretionary access control permission modification events chmod,fchmod,fchmodat,fchmodat2 are collected (Automated) levels: - l2_server - l2_workstation rules: - audit_rules_dac_modification_chmod - - audit_rules_dac_modification_chown - audit_rules_dac_modification_fchmod - audit_rules_dac_modification_fchmodat + status: automated + + - id: 6.2.3.19 + title: Ensure discretionary access control permission modification events chown,fchown,lchown,fchownat are collected (Automated) + levels: + - l2_server + - l2_workstation + rules: + - audit_rules_dac_modification_chown - audit_rules_dac_modification_fchown - - audit_rules_dac_modification_fchownat - - audit_rules_dac_modification_fremovexattr - - audit_rules_dac_modification_fsetxattr - audit_rules_dac_modification_lchown - - audit_rules_dac_modification_lremovexattr + - audit_rules_dac_modification_fchownat + status: automated + + - id: 6.2.3.20 + title: Ensure discretionary access control permission modification events setxattr,lsetxattr,fsetxattr,removexattr,lremovexattr,fremovexattr collected (Automated) + levels: + - l2_server + - l2_workstation + rules: + - audit_rules_dac_modification_setxattr - audit_rules_dac_modification_lsetxattr + - audit_rules_dac_modification_fsetxattr - audit_rules_dac_modification_removexattr - - audit_rules_dac_modification_setxattr + - audit_rules_dac_modification_lremovexattr + - audit_rules_dac_modification_fremovexattr status: automated - - id: 6.2.3.10 + - id: 6.2.3.21 title: Ensure successful file system mounts are collected (Automated) levels: - l2_server @@ -2766,7 +2809,7 @@ controls: - audit_rules_media_export status: automated - - id: 6.2.3.11 + - id: 6.2.3.22 title: Ensure session initiation information is collected (Automated) levels: - l2_server @@ -2775,7 +2818,7 @@ controls: - audit_rules_session_events status: automated - - id: 6.2.3.12 + - id: 6.2.3.23 title: Ensure login and logout events are collected (Automated) levels: - l2_server @@ -2786,19 +2829,27 @@ controls: - audit_rules_login_events_lastlog status: automated - - id: 6.2.3.13 - title: Ensure file deletion events by users are collected (Automated) + - id: 6.2.3.24 + title: Ensure unlink file deletion events by users are collected (Automated) levels: - l2_server - l2_workstation rules: - - audit_rules_file_deletion_events_rename - - audit_rules_file_deletion_events_renameat - audit_rules_file_deletion_events_unlink - audit_rules_file_deletion_events_unlinkat status: automated - - id: 6.2.3.14 + - id: 6.2.3.25 + title: Ensure rename file deletion events by users are collected (Automated) + levels: + - l2_server + - l2_workstation + rules: + - audit_rules_file_deletion_events_rename + - audit_rules_file_deletion_events_renameat + status: automated + + - id: 6.2.3.26 title: Ensure events that modify the system's Mandatory Access Controls are collected (Automated) levels: - l2_server @@ -2808,7 +2859,7 @@ controls: - audit_rules_mac_modification_etc_apparmor_d status: automated - - id: 6.2.3.15 + - id: 6.2.3.27 title: Ensure successful and unsuccessful attempts to use the chcon command are collected (Automated) levels: - l2_server @@ -2817,7 +2868,7 @@ controls: - audit_rules_execution_chcon status: automated - - id: 6.2.3.16 + - id: 6.2.3.28 title: Ensure successful and unsuccessful attempts to use the setfacl command are collected (Automated) levels: - l2_server @@ -2826,7 +2877,7 @@ controls: - audit_rules_execution_setfacl status: automated - - id: 6.2.3.17 + - id: 6.2.3.29 title: Ensure successful and unsuccessful attempts to use the chacl command are collected (Automated) levels: - l2_server @@ -2835,7 +2886,7 @@ controls: - audit_rules_execution_chacl status: automated - - id: 6.2.3.18 + - id: 6.2.3.30 title: Ensure successful and unsuccessful attempts to use the usermod command are collected (Automated) levels: - l2_server @@ -2844,21 +2895,52 @@ controls: - audit_rules_privileged_commands_usermod status: automated - - id: 6.2.3.19 + - id: 6.2.3.31 title: Ensure kernel module loading unloading and modification is collected (Automated) levels: - l2_server - l2_workstation rules: - - audit_rules_kernel_module_loading_delete + - audit_rules_kernel_module_loading_create + - audit_rules_privileged_commands_kmod + status: automated + + - id: 6.2.3.32 + title: Ensure kernel "init_module" and "finit_module" loading unloading and modification is collected (Automated) + levels: + - l2_server + - l2_workstation + rules: - audit_rules_kernel_module_loading_init - audit_rules_kernel_module_loading_finit - - audit_rules_kernel_module_loading_create + status: automated + + - id: 6.2.3.33 + title: Ensure kernel "delete_module" loading unloading and modification is collected (Automated) + levels: + - l2_server + - l2_workstation + rules: + - audit_rules_kernel_module_loading_delete + status: automated + + - id: 6.2.3.34 + title: Ensure kernel query_module loading unloading and modification is collected (Automated) + levels: + - l2_server + - l2_workstation + rules: - audit_rules_kernel_module_loading_query - - audit_rules_privileged_commands_kmod status: automated - - id: 6.2.3.20 + - id: 6.2.3.35 + title: Ensure the audit configuration is loaded regardless of errors (Automated) + levels: + - l2_server + - l2_workstation + status: manual + + - id: 6.2.3.36 title: Ensure the audit configuration is immutable (Automated) levels: - l2_server @@ -2867,7 +2949,7 @@ controls: - audit_rules_immutable status: automated - - id: 6.2.3.21 + - id: 6.2.3.37 title: Ensure the running and on disk configuration is the same (Manual) levels: - l2_server @@ -2995,7 +3077,7 @@ controls: status: automated - id: 7.1.1 - title: Ensure permissions on /etc/passwd are configured (Automated) + title: Ensure access to /etc/passwd is configured (Automated) levels: - l1_server - l1_workstation @@ -3006,7 +3088,7 @@ controls: status: automated - id: 7.1.2 - title: Ensure permissions on /etc/passwd- are configured (Automated) + title: Ensure access to /etc/passwd- is configured (Automated) levels: - l1_server - l1_workstation @@ -3017,7 +3099,7 @@ controls: status: automated - id: 7.1.3 - title: Ensure permissions on /etc/group are configured (Automated) + title: Ensure access to /etc/group is configured (Automated) levels: - l1_server - l1_workstation @@ -3028,7 +3110,7 @@ controls: status: automated - id: 7.1.4 - title: Ensure permissions on /etc/group- are configured (Automated) + title: Ensure access to /etc/group- is configured (Automated) levels: - l1_server - l1_workstation @@ -3039,7 +3121,7 @@ controls: status: automated - id: 7.1.5 - title: Ensure permissions on /etc/shadow are configured (Automated) + title: Ensure access to /etc/shadow is configured (Automated) levels: - l1_server - l1_workstation @@ -3050,7 +3132,7 @@ controls: status: automated - id: 7.1.6 - title: Ensure permissions on /etc/shadow- are configured (Automated) + title: Ensure access to /etc/shadow- is configured (Automated) levels: - l1_server - l1_workstation @@ -3061,7 +3143,7 @@ controls: status: automated - id: 7.1.7 - title: Ensure permissions on /etc/gshadow are configured (Automated) + title: Ensure access to /etc/gshadow is configured (Automated) levels: - l1_server - l1_workstation @@ -3072,7 +3154,7 @@ controls: status: automated - id: 7.1.8 - title: Ensure permissions on /etc/gshadow- are configured (Automated) + title: Ensure access to /etc/gshadow- is configured (Automated) levels: - l1_server - l1_workstation @@ -3083,7 +3165,7 @@ controls: status: automated - id: 7.1.9 - title: Ensure permissions on /etc/shells are configured (Automated) + title: Ensure access to /etc/shells is configured (Automated) levels: - l1_server - l1_workstation @@ -3094,7 +3176,7 @@ controls: status: automated - id: 7.1.10 - title: Ensure permissions on /etc/security/opasswd are configured (Automated) + title: Ensure access to /etc/security/opasswd is configured (Automated) levels: - l1_server - l1_workstation From 4a42a023a1dc5a511e3aa736e7a126eda09f069f Mon Sep 17 00:00:00 2001 From: Israel Villar Boillos Date: Sun, 26 Apr 2026 15:08:31 +0100 Subject: [PATCH 12/61] Refine CIS Debian 13 profile mappings --- controls/cis_debian13.yml | 16 +++++++++------- .../var_auditd_disk_error_action.var | 1 + .../var_auditd_disk_full_action.var | 1 + 3 files changed, 11 insertions(+), 7 deletions(-) diff --git a/controls/cis_debian13.yml b/controls/cis_debian13.yml index d3b3225d2bbd..7f6c0a35f368 100644 --- a/controls/cis_debian13.yml +++ b/controls/cis_debian13.yml @@ -2393,10 +2393,10 @@ controls: levels: - l1_server - l1_workstation - rules: + related_rules: - systemd_journal_upload_server_tls - systemd_journal_upload_url - status: automated + status: manual - id: 6.1.1.2.3 title: Ensure systemd-journal-upload is enabled and active (Automated) @@ -2519,7 +2519,6 @@ controls: - package_audit-audispd-plugins_installed status: automated notes: | - Implementation analogous to ubuntu2204/4.1.1.1. Added also the missing rule for audispd. - id: 6.2.1.2 @@ -2542,7 +2541,7 @@ controls: status: automated - id: 6.2.1.4 - title: Ensure audit_backlog_limit is sufficient (Automated) + title: Ensure audit_backlog_limit is configured (Automated) levels: - l2_server - l2_workstation @@ -2578,8 +2577,8 @@ controls: - l2_server - l2_workstation rules: - - var_auditd_disk_error_action=cis_debian12 - - var_auditd_disk_full_action=cis_debian12 + - var_auditd_disk_error_action=cis_debian13 + - var_auditd_disk_full_action=cis_debian13 - auditd_data_disk_error_action - auditd_data_disk_full_action status: automated @@ -2596,7 +2595,7 @@ controls: - auditd_data_retention_action_mail_acct - auditd_data_retention_admin_space_left_action - auditd_data_retention_space_left_action - status: partial + status: automated notes: | The variables should allow multiple options. @@ -2664,6 +2663,7 @@ controls: - l2_workstation rules: - audit_rules_networkconfig_modification + - audit_rules_networkconfig_modification_hostname_file status: automated - id: 6.2.3.8 @@ -2938,6 +2938,8 @@ controls: levels: - l2_server - l2_workstation + rules: + - audit_rules_continue_loading status: manual - id: 6.2.3.36 diff --git a/linux_os/guide/auditing/configure_auditd_data_retention/var_auditd_disk_error_action.var b/linux_os/guide/auditing/configure_auditd_data_retention/var_auditd_disk_error_action.var index ace5c84912c5..c235c6ac4560 100644 --- a/linux_os/guide/auditing/configure_auditd_data_retention/var_auditd_disk_error_action.var +++ b/linux_os/guide/auditing/configure_auditd_data_retention/var_auditd_disk_error_action.var @@ -28,3 +28,4 @@ options: cis_ubuntu2204: syslog|single|halt cis_ubuntu2404: syslog|single|halt cis_debian12: syslog|single|halt + cis_debian13: syslog|single|halt diff --git a/linux_os/guide/auditing/configure_auditd_data_retention/var_auditd_disk_full_action.var b/linux_os/guide/auditing/configure_auditd_data_retention/var_auditd_disk_full_action.var index bde0d87fbfb6..ed5e8b182a88 100644 --- a/linux_os/guide/auditing/configure_auditd_data_retention/var_auditd_disk_full_action.var +++ b/linux_os/guide/auditing/configure_auditd_data_retention/var_auditd_disk_full_action.var @@ -29,3 +29,4 @@ options: cis_ubuntu2204: halt|single cis_ubuntu2404: halt|single cis_debian12: halt|single + cis_debian13: halt|single From d5171600dd0fc45137dbcba8492f946c3a645414 Mon Sep 17 00:00:00 2001 From: Israel Villar Boillos Date: Sun, 26 Apr 2026 20:53:48 +0100 Subject: [PATCH 13/61] Fix CIS Debian 13 control mappings and consistency --- build/.gitkeep | 0 controls/cis_debian13.yml | 48 ++++++++++++++----- .../guide/services/ssh/sshd_strong_kex.var | 1 + .../guide/services/ssh/sshd_strong_macs.var | 1 + .../rule.yml | 27 +++++++++++ products/debian13/product.yml | 6 ++- 6 files changed, 68 insertions(+), 15 deletions(-) delete mode 100644 build/.gitkeep create mode 100644 linux_os/guide/system/permissions/restrictions/sysctl_kernel_apparmor_restrict_unprivileged_unconfined/rule.yml diff --git a/build/.gitkeep b/build/.gitkeep deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/controls/cis_debian13.yml b/controls/cis_debian13.yml index 7f6c0a35f368..a5f6278f53fd 100644 --- a/controls/cis_debian13.yml +++ b/controls/cis_debian13.yml @@ -362,56 +362,76 @@ controls: levels: - l1_server - l1_workstation - status: automated + status: manual + notes: | + Debian guidance requires configuring APT with: + APT::Install-Recommends "0"; + APT::Install-Suggests "0"; + in /etc/apt/apt.conf.d/60-no-weak-dependencies. + No SSG rule currently implements this check/remediation for Debian. - id: 1.2.1.3 title: Ensure access to gpg key files are configured (Automated) levels: - l1_server - l1_workstation - status: automated + status: manual + notes: | + No SSG rule currently implements this check/remediation for Debian. - id: 1.2.1.4 title: Ensure access to /etc/apt/trusted.gpg.d directory is configured (Automated) levels: - l1_server - l1_workstation - status: automated + status: manual + notes: | + No SSG rule currently implements this check/remediation for Debian. - id: 1.2.1.5 title: Ensure access to /etc/apt/auth.conf.d directory is configured (Automated) levels: - l1_server - l1_workstation - status: automated + status: manual + notes: | + No SSG rule currently implements this check/remediation for Debian. - id: 1.2.1.6 title: Ensure access to files in the /etc/apt/auth.conf.d/ directory is configured (Automated) levels: - l1_server - l1_workstation - status: automated + status: manual + notes: | + No SSG rule currently implements this check/remediation for Debian. - id: 1.2.1.7 title: Ensure access to /usr/share/keyrings directory is configured (Automated) levels: - l1_server - l1_workstation - status: automated + status: manual + notes: | + No SSG rule currently implements this check/remediation for Debian. - id: 1.2.1.8 title: Ensure access to /etc/apt/sources.list.d directory is configured (Automated) levels: - l1_server - l1_workstation - status: automated + status: manual + notes: | + No SSG rule currently implements this check/remediation for Debian. - id: 1.2.1.9 title: Ensure access to files in /etc/apt/sources.list.d are configured (Automated) levels: - l1_server - l1_workstation - status: automated + status: manual + notes: | + No SSG rule currently implements this check/remediation for Debian. - id: 1.2.2.1 title: Ensure updates, patches, and additional security software are installed (Manual) @@ -454,6 +474,8 @@ controls: levels: - l1_server - l1_workstation + rules: + - sysctl_kernel_apparmor_restrict_unprivileged_unconfined status: automated - id: 1.4.1 @@ -1480,7 +1502,7 @@ controls: - sysctl_net_ipv4_tcp_syncookies status: automated - - id: 3.3.2.1 + - id: 3.3.2.1 title: Ensure net.ipv6.conf.all.forwarding is configured (Automated) levels: - l1_server @@ -1571,7 +1593,7 @@ controls: - service_ufw_enabled status: automated - - id: 4.1.3 + - id: 4.1.3 title: Ensure ufw incoming default is configured (Automated) levels: - l1_server @@ -2499,7 +2521,7 @@ controls: - l1_server - l1_workstation rules: - - rsyslog_use_gtls + - rsyslog_remote_tls status: automated - id: 6.1.2.11 @@ -2939,8 +2961,8 @@ controls: - l2_server - l2_workstation rules: - - audit_rules_continue_loading - status: manual + - audit_rules_continue_loading + status: automated - id: 6.2.3.36 title: Ensure the audit configuration is immutable (Automated) diff --git a/linux_os/guide/services/ssh/sshd_strong_kex.var b/linux_os/guide/services/ssh/sshd_strong_kex.var index d4a78a3fe45e..a3d8e31fc444 100644 --- a/linux_os/guide/services/ssh/sshd_strong_kex.var +++ b/linux_os/guide/services/ssh/sshd_strong_kex.var @@ -22,3 +22,4 @@ options: cis_ubuntu2404: sntrup761x25519-sha512@openssh.com,curve25519-sha256,curve25519-sha256@libssh.org,ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,diffie-hellman-group-exchange-sha256,diffie-hellman-group16-sha512,diffie-hellman-group18-sha512,diffie-hellman-group14-sha256 std_openeuler: curve25519-sha256,curve25519-sha256@libssh.org,diffie-hellman-group-exchange-sha256 cis_debian12: sntrup761x25519-sha512@openssh.com,curve25519-sha256,curve25519-sha256@libssh.org,ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,diffie-hellman-group-exchange-sha256,diffie-hellman-group16-sha512,diffie-hellman-group18-sha512,diffie-hellman-group14-sha256 + cis_debian13: sntrup761x25519-sha512@openssh.com,curve25519-sha256,curve25519-sha256@libssh.org,ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,diffie-hellman-group-exchange-sha256,diffie-hellman-group16-sha512,diffie-hellman-group18-sha512,diffie-hellman-group14-sha256 diff --git a/linux_os/guide/services/ssh/sshd_strong_macs.var b/linux_os/guide/services/ssh/sshd_strong_macs.var index a0a75f544ff8..988e89ff56fa 100644 --- a/linux_os/guide/services/ssh/sshd_strong_macs.var +++ b/linux_os/guide/services/ssh/sshd_strong_macs.var @@ -23,3 +23,4 @@ options: stig_rhel9: hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com,hmac-sha2-256,hmac-sha2-512 stig_ol9: hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com,hmac-sha2-256,hmac-sha2-512 cis_debian12: hmac-sha2-512-etm@openssh.com,hmac-sha2-256-etm@openssh.com,hmac-sha2-512,hmac-sha2-256 + cis_debian13: hmac-sha2-512-etm@openssh.com,hmac-sha2-256-etm@openssh.com,hmac-sha2-512,hmac-sha2-256 diff --git a/linux_os/guide/system/permissions/restrictions/sysctl_kernel_apparmor_restrict_unprivileged_unconfined/rule.yml b/linux_os/guide/system/permissions/restrictions/sysctl_kernel_apparmor_restrict_unprivileged_unconfined/rule.yml new file mode 100644 index 000000000000..8a9a50f70d4c --- /dev/null +++ b/linux_os/guide/system/permissions/restrictions/sysctl_kernel_apparmor_restrict_unprivileged_unconfined/rule.yml @@ -0,0 +1,27 @@ +documentation_complete: true + +title: 'Enable kernel.apparmor_restrict_unprivileged_unconfined' + +description: '{{{ describe_sysctl_option_value(sysctl="kernel.apparmor_restrict_unprivileged_unconfined", value="1") }}}' + +rationale: |- + Restricting unprivileged unconfined processes with AppArmor reduces the + attack surface available to local users and helps enforce additional + kernel-level hardening. + +severity: medium + +{{{ complete_ocil_entry_sysctl_option_value(sysctl="kernel.apparmor_restrict_unprivileged_unconfined", value="1") }}} + +fixtext: |- + Configure {{{ full_name }}} to enable AppArmor restrictions for + unprivileged unconfined processes. + {{{ fixtext_sysctl("kernel.apparmor_restrict_unprivileged_unconfined", "1") | indent(4) }}} + +platform: system_with_kernel + +template: + name: sysctl + vars: + sysctlvar: kernel.apparmor_restrict_unprivileged_unconfined + datatype: int diff --git a/products/debian13/product.yml b/products/debian13/product.yml index 26258a81b9ff..920de73dcfe4 100644 --- a/products/debian13/product.yml +++ b/products/debian13/product.yml @@ -11,13 +11,13 @@ major_version_ordinal: 13 benchmark_id: DEBIAN-13 benchmark_root: "../../linux_os/guide" -components_root: "../../components" profiles_root: "./profiles" pkg_manager: "apt_get" + init_system: "systemd" -oval_feed_url: "https://www.debian.org/security/oval/oval-definitions-trixie.xml.bz2" +oval_feed_url: "https://www.debian.org/security/oval/oval-definitions-bookworm.xml.bz2" chrony_conf_path: "/etc/chrony/chrony.conf" chrony_d_path: "/etc/chrony/chrony.d/" @@ -44,3 +44,5 @@ platform_package_overrides: sssd: sssd-common audit: auditd +reference_uris: + cis: 'https://www.cisecurity.org/benchmark/debian_linux/' From 50505cb8fef954acd23295342cdecc517961cbda Mon Sep 17 00:00:00 2001 From: Israel Villar Boillos Date: Sun, 3 May 2026 19:33:53 +0100 Subject: [PATCH 14/61] Fix CIS Debian 13 section 1.x control statuses and levels MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Change 1.2.1.2-1.2.1.9 from manual to pending (CIS marks them Automated but no SSG rules exist for Debian yet) - Fix levels for 1.2.1.2 (l1→l2 server/workstation) and remove incorrect l1_workstation from 1.2.1.3-1.2.1.5, 1.2.1.7-1.2.1.9 - Add service_apport_disabled rule to 1.5.7 (was automated with no rules) Co-Authored-By: Claude Sonnet 4.6 --- controls/cis_debian13.yml | 28 ++++++++++++---------------- 1 file changed, 12 insertions(+), 16 deletions(-) diff --git a/controls/cis_debian13.yml b/controls/cis_debian13.yml index a5f6278f53fd..aaaff973d872 100644 --- a/controls/cis_debian13.yml +++ b/controls/cis_debian13.yml @@ -360,9 +360,9 @@ controls: - id: 1.2.1.2 title: Ensure weak dependencies are configured (Automated) levels: - - l1_server - - l1_workstation - status: manual + - l2_server + - l2_workstation + status: pending notes: | Debian guidance requires configuring APT with: APT::Install-Recommends "0"; @@ -374,8 +374,7 @@ controls: title: Ensure access to gpg key files are configured (Automated) levels: - l1_server - - l1_workstation - status: manual + status: pending notes: | No SSG rule currently implements this check/remediation for Debian. @@ -383,8 +382,7 @@ controls: title: Ensure access to /etc/apt/trusted.gpg.d directory is configured (Automated) levels: - l1_server - - l1_workstation - status: manual + status: pending notes: | No SSG rule currently implements this check/remediation for Debian. @@ -392,8 +390,7 @@ controls: title: Ensure access to /etc/apt/auth.conf.d directory is configured (Automated) levels: - l1_server - - l1_workstation - status: manual + status: pending notes: | No SSG rule currently implements this check/remediation for Debian. @@ -402,7 +399,7 @@ controls: levels: - l1_server - l1_workstation - status: manual + status: pending notes: | No SSG rule currently implements this check/remediation for Debian. @@ -410,8 +407,7 @@ controls: title: Ensure access to /usr/share/keyrings directory is configured (Automated) levels: - l1_server - - l1_workstation - status: manual + status: pending notes: | No SSG rule currently implements this check/remediation for Debian. @@ -419,8 +415,7 @@ controls: title: Ensure access to /etc/apt/sources.list.d directory is configured (Automated) levels: - l1_server - - l1_workstation - status: manual + status: pending notes: | No SSG rule currently implements this check/remediation for Debian. @@ -428,8 +423,7 @@ controls: title: Ensure access to files in /etc/apt/sources.list.d are configured (Automated) levels: - l1_server - - l1_workstation - status: manual + status: pending notes: | No SSG rule currently implements this check/remediation for Debian. @@ -560,6 +554,8 @@ controls: levels: - l1_server - l1_workstation + rules: + - service_apport_disabled status: automated - id: 1.5.8 From 0996e5c193885e2f11133b8c971a01f10388e6db Mon Sep 17 00:00:00 2001 From: Israel Villar Boillos Date: Sun, 3 May 2026 22:28:19 +0100 Subject: [PATCH 15/61] Fix CIS Debian 13 section 2.x and 3.x controls MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Add 2.1.16 and renumber 2.1.16→2.1.17 through 2.1.22→2.1.23 - Fix 2.2.5 change openldap-clients package to ldap-utils - Add 3.2.2, renumber 3.2.2→3.2.3 and move 3.2.3→3.2.6 --- CLAUDE.md | 247 ++++++++++++++++++ controls/cis_debian13.yml | 43 ++- .../package_openldap-clients_removed/rule.yml | 3 +- 3 files changed, 280 insertions(+), 13 deletions(-) create mode 100644 CLAUDE.md diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 000000000000..e4052f8e351c --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,247 @@ +# CLAUDE.md + +This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. + +## Project Overview + +This repository produces SCAP data streams, Ansible playbooks, Bash scripts, and other artifacts for compliance scanning and remediation. Each supported OS or platform is a **product** (subdirectory under `products/`). The core Python library that drives the build system lives in `ssg/`. + +## Build Commands + +```bash +# Build a single product (full build including guides and tables) +./build_product rhel9 + +# Build data stream only (faster — skips guides and tables) +./build_product rhel9 --datastream-only + +# Build targeting a single rule (fastest — for development) +./build_product rhel9 --datastream-only --rule-id accounts_password_minlen_login_defs + +# Build output: build/ssg--ds.xml +``` + +## Linting and Testing + +```bash +# Lint Python code +ruff check ssg utils tests build-scripts + +# Lint YAML files +yamllint -c .yamllint + +# Auto-fix YAML lint issues +yamlfix -c yamlfix.toml + +# Run Python unit tests +python -m pytest tests/unit/ssg-module/ + +# Run utils that import ssg/ — must set PYTHONPATH first +PYTHONPATH=. python utils/controleval.py --help +PYTHONPATH=. python utils/find_duplicates.py --help +``` + +Python style: PEP 8 with a 99-character line limit. YAML style: 4-space indentation for new files (some older files use 2-space), `.yml` extension, one blank line between sections. + +## Repository Structure + +``` +applications/openshift/ # OCP4/Kubernetes rules, organized by component (api-server/, kubelet/, etcd/, …) +linux_os/guide/ # Linux rules organized by area (system/, services/, auditing/, …) +controls/ # Compliance framework mappings (CIS, STIG, SRG, NIST, …) +products/ # Product definitions, profiles, and product-specific controls +shared/templates/ # ~40 reusable check/remediation templates +shared/macros/ # Jinja2 macro files for OVAL, Ansible, Bash generation +components/ # Component definitions mapping rules to packages (e.g., audit.yml) +ssg/ # Python library used by build-scripts/ and utils/ +build-scripts/ # CMake-invoked scripts that assemble the build artifacts +utils/ # Developer utilities (controleval, find_duplicates, compare_ds, …) +``` + +## Discovering Rule Directories + +- **OCP4/Kubernetes rules**: `applications/openshift//`, where the rule ID prefix matches the component name with hyphens → underscores (e.g., `api-server/` → `api_server_` prefix). +- **Linux rules**: `linux_os/guide//`, e.g., `system/accounts/`, `services/ssh/`, `auditing/`. +- Each rule lives in its own directory; the **directory name is the rule ID**. It contains `rule.yml` and optionally `tests/`. +- Each category directory contains a `group.yml` describing the group. Rules must belong to a group that covers the same software or service. + +## Rule Format (`rule.yml`) + +Sections **must appear in this order** when present: + +```yaml +documentation_complete: true # Must be true to be built + +title: 'Title Case Short Title' # One line; must match directory name + +description: |- # HTML-Like: supports ,
, , , 
    ,
  • +rationale: |- +severity: medium # low | medium | high | unknown + +identifiers: # Keys alphabetical order + cce@rhel9: CCE-XXXXX-X + +references: # Keys alphabetical order + cis@rhel9: 1.2.3 + nist: CM-6,CM-6(1) + stigid@rhel9: RHEL-09-XXXXXX + +platform: machine # Use platform (not platforms) for new rules + +ocil_clause: 'the value is not set' +ocil: |- # Manual check instructions (HTML-Like) + +fixtext: |- # STIG fix instructions (HTML-Like) +checktext: |- # STIG check instructions (HTML-Like) +srg_requirement: '...' + +warnings: + - general: |- + +conflicts: + - some_rule_id +requires: + - other_rule_id + +template: + name: + vars: ... +``` + +One rule = one configuration change. Create a variable (`.var` file) when a setting can take multiple valid values. + +## Available Templates (`shared/templates/`) + +Key templates for Linux: `sysctl`, `file_permissions`, `file_owner`, `file_groupowner`, `shell_lineinfile`, `sshd_lineinfile`, `service_enabled`, `service_disabled`, `package_installed`, `package_removed`, `audit_rules_*`, `kernel_module_disabled`, `grub2_bootloader_argument`, `sudo_defaults_option`, `sebool`, `dconf_ini_file`. + +Key templates for OCP4: `yamlfile_value`. + +When a template fits, always use it rather than writing custom OVAL/Ansible/Bash checks. + +### `yamlfile_value` (primary OCP4 template) + +```yaml +template: + name: yamlfile_value + vars: + ocp_data: "true" + filepath: '/apis/...' + yamlpath: '.spec.field' + check_existence: "at_least_one_exists" # optional + entity_check: "at least one" # optional + values: + - value: 'expected' + type: "string" # string | int | boolean + operation: "pattern match" # equals | not equal | pattern match | greater than or equal | less than or equal +``` + +### Other common templates + +```yaml +# sysctl +template: + name: sysctl + vars: + sysctlvar: net.ipv6.conf.all.accept_ra + datatype: int + +# file_permissions +template: + name: file_permissions + vars: + filepath: /etc/ssh/sshd_config + filemode: '0600' + +# shell_lineinfile +template: + name: shell_lineinfile + vars: + path: /etc/login.defs + parameter: PASS_MIN_LEN + value: '15' + +# package_installed / package_removed +template: + name: package_removed + vars: + pkgname: avahi + pkgname@ubuntu2204: avahi-daemon # product-scoped override +``` + +## Common Jinja2 Macros + +``` +{{{ full_name }}} → product full name +{{{ xccdf_value("var_name") }}} → XCCDF variable reference +{{{ describe_sysctl_option_value(sysctl="key", value="val") }}} +{{{ complete_ocil_entry_sysctl_option_value(sysctl="key", value="val") }}} +{{{ fixtext_sysctl("key", "value") }}} +{{{ describe_service_disable(service="name") }}} +{{{ describe_service_enable(service="name") }}} +{{{ describe_file_permissions(file="/path", perms="0700") }}} +{{{ fixtext_directory_permissions(file="/path", mode="0600") }}} +{{{ complete_ocil_entry_package_installed("name") }}} +{{{ complete_ocil_entry_package_removed("name") }}} +{{{ fixtext_package_removed("name") }}} +{{{ weblink("https://...") }}} + +# OCP4 specific +{{{ openshift_cluster_setting("/api/path") }}} +{{{ openshift_filtered_cluster_setting({'/api/path': jqfilter}) }}} +{{{ openshift_filtered_path('/api/path', jqfilter) }}} +``` + +## Control File Format + +Two layouts exist: + +**Single file** (`controls/.yml` or `products//controls/.yml`): +```yaml +policy: 'Policy Title' +title: 'Full Title' +id: policy_id +version: V1R1 +reference_type: stigid # or cis, srg, etc. +product: rhel9 +levels: + - id: high +controls: + - id: RHEL-09-211010 + levels: [high] + title: '...' + rules: [installed_OS_is_vendor_supported] + status: automated # automated | manual | inherently met | does not meet | pending | not applicable + notes: '...' +``` + +**Split directory** (`controls/.yml` + `controls//section-N.yml`): used for large frameworks like CIS. The top-level file holds `policy`, `title`, `id`, `levels`; section files hold nested `controls:` lists. + +## Profile Format + +`products//profiles/.profile`: + +```yaml +documentation_complete: true +title: 'Profile Title' +description: |- +platform: rhel9 +metadata: + version: V2R7 + SMEs: [github_username] +selections: + - stig_rhel9:all # all rules from a control file + - specific_rule_id + - '!excluded_rule_id' + - var_name=value +``` + +## Guidelines for Claude + +1. **Always show proposals before making changes.** Present the full content of any new or modified file and wait for explicit approval. +2. **Follow existing patterns.** Before creating a rule, find 2-3 similar existing rules and match their style exactly. +3. **Check for duplicates.** Search before creating a new rule; use `PYTHONPATH=. python utils/find_duplicates.py`. +4. **Use the correct directory.** Find existing rules with the same prefix to locate the right subdirectory. +5. **Preserve formatting.** 4-space YAML indentation for new files; match surrounding file style. +6. **Don't invent references.** Only use CCE, CIS, STIG, SRG, NIST IDs the user provides or that exist in authoritative source documents. +7. **Use templates.** When a shared template covers the requirement, use it instead of writing custom checks. +8. **Rule sections order.** Follow the exact field order listed in the Rule Format section above. diff --git a/controls/cis_debian13.yml b/controls/cis_debian13.yml index aaaff973d872..fef0bc077873 100644 --- a/controls/cis_debian13.yml +++ b/controls/cis_debian13.yml @@ -954,6 +954,16 @@ controls: status: automated - id: 2.1.16 + title: Ensure telnet server services are not in use (Automated) + levels: + - l1_server + - l1_workstation + rules: + - package_inetutils-telnetd_removed + - package_telnetd_removed + status: automated + + - id: 2.1.17 title: Ensure tftp server services are not in use (Automated) levels: - l1_server @@ -963,7 +973,7 @@ controls: - service_tftp_disabled status: automated - - id: 2.1.17 + - id: 2.1.18 title: Ensure web proxy server services are not in use (Automated) levels: - l1_server @@ -973,7 +983,7 @@ controls: - service_squid_disabled status: automated - - id: 2.1.18 + - id: 2.1.19 title: Ensure web server services are not in use (Automated) levels: - l1_server @@ -985,7 +995,7 @@ controls: - service_nginx_disabled status: automated - - id: 2.1.19 + - id: 2.1.20 title: Ensure xinetd services are not in use (Automated) levels: - l1_server @@ -995,7 +1005,7 @@ controls: - service_xinetd_disabled status: automated - - id: 2.1.20 + - id: 2.1.21 title: Ensure X window server services are not in use (Automated) levels: - l2_server @@ -1003,7 +1013,7 @@ controls: - package_xorg-x11-server-common_removed status: automated - - id: 2.1.21 + - id: 2.1.22 title: Ensure mail transfer agent is configured for local-only mode (Automated) levels: - l1_server @@ -1014,7 +1024,7 @@ controls: - postfix_network_listening_disabled status: automated - - id: 2.1.22 + - id: 2.1.23 title: Ensure only approved services are listening on a network interface (Manual) levels: - l1_server @@ -1184,7 +1194,7 @@ controls: status: automated - id: 2.4.1.4 - title: Ensure access ton /etc/cron.daily are configured (Automated) + title: Ensure access to /etc/cron.daily is configured (Automated) levels: - l1_server - l1_workstation @@ -1301,21 +1311,21 @@ controls: status: automated - id: 3.2.2 - title: Ensure dccp kernel module is not available (Automated) + title: Ensure can kernel module is not available (Automated) levels: - l1_server - l1_workstation rules: - - kernel_module_dccp_disabled + - kernel_module_can_disabled status: automated - id: 3.2.3 - title: Ensure tipc kernel module is not available (Automated) + title: Ensure dccp kernel module is not available (Automated) levels: - l1_server - l1_workstation rules: - - kernel_module_tipc_disabled + - kernel_module_dccp_disabled status: automated - id: 3.2.4 @@ -1336,10 +1346,19 @@ controls: - kernel_module_sctp_disabled status: automated + - id: 3.2.6 + title: Ensure tipc kernel module is not available (Automated) + levels: + - l1_server + - l1_workstation + rules: + - kernel_module_tipc_disabled + status: automated + - id: 3.3.1.1 title: Ensure net.ipv4.ip_forward is configured (Automated) levels: - - l1_server + - l2_server - l1_workstation rules: - sysctl_net_ipv4_ip_forward diff --git a/linux_os/guide/services/ldap/openldap_client/package_openldap-clients_removed/rule.yml b/linux_os/guide/services/ldap/openldap_client/package_openldap-clients_removed/rule.yml index 5ff291774a91..9dea007eb537 100644 --- a/linux_os/guide/services/ldap/openldap_client/package_openldap-clients_removed/rule.yml +++ b/linux_os/guide/services/ldap/openldap_client/package_openldap-clients_removed/rule.yml @@ -1,6 +1,6 @@ {{% if product in ["sle12", "sle15", "slmicro5"] %}} {{%- set package = "openldap2-client" %}} -{{% elif "ubuntu" in product %}} +{{% elif "ubuntu" in product or "debian" in product %}} {{%- set package = "ldap-utils" %}} {{% else %}} {{%- set package = "openldap-clients" %}} @@ -46,3 +46,4 @@ template: pkgname@slmicro5: openldap2-client pkgname@ubuntu2204: ldap-utils pkgname@ubuntu2404: ldap-utils + pkgname@debian13: ldap-utils From aa59a04ef58c7fdb2425ff7013c05d10a112deaf Mon Sep 17 00:00:00 2001 From: Israel Villar Boillos Date: Thu, 7 May 2026 20:04:25 +0100 Subject: [PATCH 16/61] Add CIS Debian 13 APT repository controls --- controls/cis_debian13.yml | 166 ++++++++++++------ .../bash/shared.sh | 7 + .../oval/shared.xml | 40 +++++ .../apt_disable_weak_dependencies/rule.yml | 27 +++ .../rule.yml | 24 +++ .../rule.yml | 24 +++ .../rule.yml | 24 +++ .../rule.yml | 24 +++ .../directory_owner_apt_auth_conf_d/rule.yml | 24 +++ .../rule.yml | 24 +++ .../rule.yml | 24 +++ .../rule.yml | 24 +++ .../rule.yml | 24 +++ .../rule.yml | 24 +++ .../rule.yml | 24 +++ .../rule.yml | 24 +++ .../file_groupowner_apt_auth_conf_d/rule.yml | 25 +++ .../apt/file_groupowner_apt_gpg_keys/rule.yml | 29 +++ .../rule.yml | 25 +++ .../apt/file_owner_apt_auth_conf_d/rule.yml | 25 +++ .../apt/file_owner_apt_gpg_keys/rule.yml | 29 +++ .../file_owner_apt_sources_list_d/rule.yml | 25 +++ .../file_permissions_apt_auth_conf_d/rule.yml | 25 +++ .../file_permissions_apt_gpg_keys/rule.yml | 29 +++ .../rule.yml | 25 +++ 25 files changed, 716 insertions(+), 49 deletions(-) create mode 100644 linux_os/guide/services/apt/apt_disable_weak_dependencies/bash/shared.sh create mode 100644 linux_os/guide/services/apt/apt_disable_weak_dependencies/oval/shared.xml create mode 100644 linux_os/guide/services/apt/apt_disable_weak_dependencies/rule.yml create mode 100644 linux_os/guide/services/apt/directory_groupowner_apt_auth_conf_d/rule.yml create mode 100644 linux_os/guide/services/apt/directory_groupowner_apt_sources_list_d/rule.yml create mode 100644 linux_os/guide/services/apt/directory_groupowner_apt_trusted_gpg_d/rule.yml create mode 100644 linux_os/guide/services/apt/directory_groupowner_usr_share_keyrings/rule.yml create mode 100644 linux_os/guide/services/apt/directory_owner_apt_auth_conf_d/rule.yml create mode 100644 linux_os/guide/services/apt/directory_owner_apt_sources_list_d/rule.yml create mode 100644 linux_os/guide/services/apt/directory_owner_apt_trusted_gpg_d/rule.yml create mode 100644 linux_os/guide/services/apt/directory_owner_usr_share_keyrings/rule.yml create mode 100644 linux_os/guide/services/apt/directory_permissions_apt_auth_conf_d/rule.yml create mode 100644 linux_os/guide/services/apt/directory_permissions_apt_sources_list_d/rule.yml create mode 100644 linux_os/guide/services/apt/directory_permissions_apt_trusted_gpg_d/rule.yml create mode 100644 linux_os/guide/services/apt/directory_permissions_usr_share_keyrings/rule.yml create mode 100644 linux_os/guide/services/apt/file_groupowner_apt_auth_conf_d/rule.yml create mode 100644 linux_os/guide/services/apt/file_groupowner_apt_gpg_keys/rule.yml create mode 100644 linux_os/guide/services/apt/file_groupowner_apt_sources_list_d/rule.yml create mode 100644 linux_os/guide/services/apt/file_owner_apt_auth_conf_d/rule.yml create mode 100644 linux_os/guide/services/apt/file_owner_apt_gpg_keys/rule.yml create mode 100644 linux_os/guide/services/apt/file_owner_apt_sources_list_d/rule.yml create mode 100644 linux_os/guide/services/apt/file_permissions_apt_auth_conf_d/rule.yml create mode 100644 linux_os/guide/services/apt/file_permissions_apt_gpg_keys/rule.yml create mode 100644 linux_os/guide/services/apt/file_permissions_apt_sources_list_d/rule.yml diff --git a/controls/cis_debian13.yml b/controls/cis_debian13.yml index fef0bc077873..bf92a387f002 100644 --- a/controls/cis_debian13.yml +++ b/controls/cis_debian13.yml @@ -362,70 +362,83 @@ controls: levels: - l2_server - l2_workstation - status: pending - notes: | - Debian guidance requires configuring APT with: - APT::Install-Recommends "0"; - APT::Install-Suggests "0"; - in /etc/apt/apt.conf.d/60-no-weak-dependencies. - No SSG rule currently implements this check/remediation for Debian. + rules: + - apt_disable_weak_dependencies + status: automated - id: 1.2.1.3 title: Ensure access to gpg key files are configured (Automated) levels: - l1_server - status: pending - notes: | - No SSG rule currently implements this check/remediation for Debian. + rules: + - file_groupowner_apt_gpg_keys + - file_groupowner_apt_sources_list_d + - file_owner_apt_gpg_keys + - file_owner_apt_sources_list_d + - file_permissions_apt_gpg_keys + - file_permissions_apt_sources_list_d + status: automated - id: 1.2.1.4 title: Ensure access to /etc/apt/trusted.gpg.d directory is configured (Automated) levels: - l1_server - status: pending - notes: | - No SSG rule currently implements this check/remediation for Debian. + rules: + - directory_groupowner_apt_trusted_gpg_d + - directory_owner_apt_trusted_gpg_d + - directory_permissions_apt_trusted_gpg_d + status: automated - id: 1.2.1.5 title: Ensure access to /etc/apt/auth.conf.d directory is configured (Automated) levels: - l1_server - status: pending - notes: | - No SSG rule currently implements this check/remediation for Debian. + rules: + - directory_groupowner_apt_auth_conf_d + - directory_owner_apt_auth_conf_d + - directory_permissions_apt_auth_conf_d + status: automated - id: 1.2.1.6 title: Ensure access to files in the /etc/apt/auth.conf.d/ directory is configured (Automated) levels: - l1_server - l1_workstation - status: pending - notes: | - No SSG rule currently implements this check/remediation for Debian. + rules: + - file_groupowner_apt_auth_conf_d + - file_owner_apt_auth_conf_d + - file_permissions_apt_auth_conf_d + status: automated - id: 1.2.1.7 title: Ensure access to /usr/share/keyrings directory is configured (Automated) levels: - l1_server - status: pending - notes: | - No SSG rule currently implements this check/remediation for Debian. + rules: + - directory_groupowner_usr_share_keyrings + - directory_owner_usr_share_keyrings + - directory_permissions_usr_share_keyrings + status: automated - id: 1.2.1.8 title: Ensure access to /etc/apt/sources.list.d directory is configured (Automated) levels: - l1_server - status: pending - notes: | - No SSG rule currently implements this check/remediation for Debian. + rules: + - directory_groupowner_apt_sources_list_d + - directory_owner_apt_sources_list_d + - directory_permissions_apt_sources_list_d + status: automated - id: 1.2.1.9 title: Ensure access to files in /etc/apt/sources.list.d are configured (Automated) levels: - l1_server - status: pending - notes: | - No SSG rule currently implements this check/remediation for Debian. + rules: + - file_groupowner_apt_sources_list_d + - file_owner_apt_sources_list_d + - file_permissions_apt_sources_list_d + status: automated - id: 1.2.2.1 title: Ensure updates, patches, and additional security software are installed (Manual) @@ -954,7 +967,7 @@ controls: status: automated - id: 2.1.16 - title: Ensure telnet server services are not in use (Automated) + title: Ensure telnet-server services are not in use (Automated) levels: - l1_server - l1_workstation @@ -1014,7 +1027,7 @@ controls: status: automated - id: 2.1.22 - title: Ensure mail transfer agent is configured for local-only mode (Automated) + title: Ensure mail transfer agents are configured for local-only mode (Automated) levels: - l1_server - l1_workstation @@ -1032,7 +1045,7 @@ controls: status: manual - id: 2.2.1 - title: Ensure NIS Client is not installed (Automated) + title: Ensure nis client is not installed (Automated) levels: - l1_server - l1_workstation @@ -1172,7 +1185,7 @@ controls: status: automated - id: 2.4.1.2 - title: Ensure access to /etc/crontab are configured (Automated) + title: Ensure access to /etc/crontab is configured (Automated) levels: - l1_server - l1_workstation @@ -1183,7 +1196,7 @@ controls: status: automated - id: 2.4.1.3 - title: Ensure access to /etc/cron.hourly are configured (Automated) + title: Ensure access to /etc/cron.hourly is configured (Automated) levels: - l1_server - l1_workstation @@ -1205,7 +1218,7 @@ controls: status: automated - id: 2.4.1.5 - title: Ensure access to /etc/cron.weekly are configured (Automated) + title: Ensure access to /etc/cron.weekly is configured (Automated) levels: - l1_server - l1_workstation @@ -1216,7 +1229,7 @@ controls: status: automated - id: 2.4.1.6 - title: Ensure access to /etc/cron.monthly are configured (Automated) + title: Ensure access to /etc/cron.monthly is configured (Automated) levels: - l1_server - l1_workstation @@ -1225,6 +1238,7 @@ controls: - file_owner_cron_monthly - file_permissions_cron_monthly status: automated + - id: 2.4.1.7 title: Ensure access to /etc/cron.yearly is configured (Automated) levels: @@ -1237,7 +1251,7 @@ controls: status: automated - id: 2.4.1.8 - title: Ensure access to /etc/cron.d are configured (Automated) + title: Ensure access to /etc/cron.d is configured (Automated) levels: - l1_server - l1_workstation @@ -1623,8 +1637,8 @@ controls: - id: 4.1.4 title: Ensure ufw outgoing default is configured (Automated) levels: - - l1_server - - l1_workstation + - l2_server + - l2_workstation rules: - set_ufw_default_rule status: automated @@ -1901,7 +1915,7 @@ controls: status: automated - id: 5.2.4 - title: Ensure users must provide password for privilege escalation (Automated) + title: Ensure users must provide password for escalation (Automated) levels: - l2_server - l2_workstation @@ -1919,7 +1933,7 @@ controls: status: automated - id: 5.2.6 - title: Ensure sudo authentication timeout is configured correctly (Automated) + title: Ensure sudo timestamp_timeout is configured (Automated) levels: - l1_server - l1_workstation @@ -1952,7 +1966,7 @@ controls: it is the latest version as the title suggests. - id: 5.3.1.2 - title: Ensure lastest version of libpam-modules is installed (Automated) + title: Ensure latest version of libpam-modules is installed (Automated) levels: - l1_server - l1_workstation @@ -1961,7 +1975,7 @@ controls: status: automated - id: 5.3.1.3 - title: Ensure lastes version of libpam-pwquality is installed (Automated) + title: Ensure latest version of libpam-pwquality is installed (Automated) levels: - l1_server - l1_workstation @@ -2046,7 +2060,7 @@ controls: status: automated - id: 5.3.3.2.2 - title: Ensure minimum password length is configured (Automated) + title: Ensure password length is configured (Automated) levels: - l1_server - l1_workstation @@ -2524,8 +2538,8 @@ controls: - id: 6.1.2.9 title: Ensure rsyslog-gnutls is installed (Automated) levels: - - l1_server - - l1_workstation + - l2_server + - l2_workstation rules: - package_rsyslog-gnutls_installed status: automated @@ -2533,8 +2547,8 @@ controls: - id: 6.1.2.10 title: Ensure rsyslog forwarding uses gtls (Automated) levels: - - l1_server - - l1_workstation + - l2_server + - l2_workstation rules: - rsyslog_remote_tls status: automated @@ -2542,10 +2556,64 @@ controls: - id: 6.1.2.11 title: Ensure rsyslog CA certificates are configured (Manual) levels: - - l1_server - - l1_workstation + - l2_server + - l2_workstation status: manual + - id: 6.1.3.1 + title: Ensure access to all logfiles has been configured (Automated) + levels: + - l1_server + - l1_workstation + rules: + - file_groupownerships_var_log_apt + - file_groupownerships_var_log_gdm + - file_groupownerships_var_log_gdm3 + - file_groupownerships_var_log_landscape + - file_groupownerships_var_log_sssd + - file_groupowner_var_log_auth + - file_groupowner_var_log_cloud_init + - file_groupowner_var_log_journal + - file_groupowner_var_log_lastlog + - file_groupowner_var_log_localmessages + - file_groupowner_var_log_messages + - file_groupowner_var_log_secure + - file_groupowner_var_log_syslog + - file_groupowner_var_log_waagent + - file_groupowner_var_log_wbtmp + - file_ownerships_var_log_apt + - file_ownerships_var_log_gdm + - file_ownerships_var_log_gdm3 + - file_ownerships_var_log_landscape + - file_ownerships_var_log_sssd + - file_owner_var_log_auth + - file_owner_var_log_cloud_init + - file_owner_var_log_journal + - file_owner_var_log_lastlog + - file_owner_var_log_localmessages + - file_owner_var_log_messages + - file_owner_var_log_secure + - file_owner_var_log_syslog + - file_owner_var_log_waagent + - file_owner_var_log_wbtmp + - file_permissions_var_log_apt + - file_permissions_var_log_auth + - file_permissions_var_log_cloud-init + - file_permissions_var_log_gdm + - file_permissions_var_log_gdm3 + - file_permissions_var_log_lastlog + - file_permissions_var_log_localmessages + - file_permissions_var_log_messages + - file_permissions_var_log_secure + - file_permissions_var_log_sssd + - file_permissions_var_log_syslog + - file_permissions_var_log_waagent + - file_permissions_var_log_wbtmp + - file_groupownerships_var_log + - file_ownerships_var_log + - permissions_local_var_log + status: automated + - id: 6.2.1.1 title: Ensure auditd packages are installed (Automated) levels: diff --git a/linux_os/guide/services/apt/apt_disable_weak_dependencies/bash/shared.sh b/linux_os/guide/services/apt/apt_disable_weak_dependencies/bash/shared.sh new file mode 100644 index 000000000000..fcbbdc590eed --- /dev/null +++ b/linux_os/guide/services/apt/apt_disable_weak_dependencies/bash/shared.sh @@ -0,0 +1,7 @@ +# platform = multi_platform_debian + +mkdir -p /etc/apt/apt.conf.d +cat > /etc/apt/apt.conf.d/60-no-weak-dependencies <<'EOF' +APT::Install-Recommends "0"; +APT::Install-Suggests "0"; +EOF diff --git a/linux_os/guide/services/apt/apt_disable_weak_dependencies/oval/shared.xml b/linux_os/guide/services/apt/apt_disable_weak_dependencies/oval/shared.xml new file mode 100644 index 000000000000..158bdeb8d6e2 --- /dev/null +++ b/linux_os/guide/services/apt/apt_disable_weak_dependencies/oval/shared.xml @@ -0,0 +1,40 @@ + + + {{{ oval_metadata("APT weak dependencies should be disabled.", rule_title=rule_title) }}} + + + + + + + + + + + + + + + + + + + /etc/apt/apt.conf(\.d/.*)?$ + ^[\s]*(?i)APT::Install-Recommends(?-i)[\s]+(.*)$ + 1 + + + + /etc/apt/apt.conf(\.d/.*)?$ + ^[\s]*(?i)APT::Install-Suggests(?-i)[\s]+(.*)$ + 1 + + + + ^"0";[\s]*$ + + diff --git a/linux_os/guide/services/apt/apt_disable_weak_dependencies/rule.yml b/linux_os/guide/services/apt/apt_disable_weak_dependencies/rule.yml new file mode 100644 index 000000000000..5e0287ec9f65 --- /dev/null +++ b/linux_os/guide/services/apt/apt_disable_weak_dependencies/rule.yml @@ -0,0 +1,27 @@ +documentation_complete: true + +title: 'Disable APT Weak Dependencies' + +description: |- + APT should be configured to avoid installing packages listed only as + Recommends or Suggests dependencies. + +rationale: |- + Unless a system specifically requires the additional capabilities provided by + weak dependencies, those packages should not be installed in order to reduce + the potential attack surface. + +severity: medium + +ocil_clause: 'APT weak dependency options are not disabled' + +ocil: |- + Run the following command: +
    $ apt-config dump | grep "APT::Install-"
    + The output should include: +
    APT::Install-Recommends "0";
    +    APT::Install-Suggests "0";
    + +fixtext: |- + Create an APT configuration file that disables weak dependencies: +
    # printf '%s\n%s\n' 'APT::Install-Recommends "0";' 'APT::Install-Suggests "0";' > /etc/apt/apt.conf.d/60-no-weak-dependencies
    diff --git a/linux_os/guide/services/apt/directory_groupowner_apt_auth_conf_d/rule.yml b/linux_os/guide/services/apt/directory_groupowner_apt_auth_conf_d/rule.yml new file mode 100644 index 000000000000..9a22110abd85 --- /dev/null +++ b/linux_os/guide/services/apt/directory_groupowner_apt_auth_conf_d/rule.yml @@ -0,0 +1,24 @@ +documentation_complete: true + +title: 'Verify Group Owner on /etc/apt/auth.conf.d Directory' + +description: '{{{ describe_directory_group_owner(directory="/etc/apt/auth.conf.d", group="root") }}}' + +rationale: |- + The /etc/apt/auth.conf.d directory should be group-owned by root to prevent + unauthorized changes to APT authentication configuration. + +severity: medium + +ocil_clause: '{{{ ocil_clause_directory_group_owner(directory="/etc/apt/auth.conf.d", group="root") }}}' + +ocil: |- + {{{ ocil_directory_group_owner(directory="/etc/apt/auth.conf.d", group="root") }}} + +fixtext: '{{{ fixtext_directory_group_owner(file="/etc/apt/auth.conf.d", group="root") }}}' + +template: + name: file_groupowner + vars: + filepath: /etc/apt/auth.conf.d/ + gid_or_name: '0' diff --git a/linux_os/guide/services/apt/directory_groupowner_apt_sources_list_d/rule.yml b/linux_os/guide/services/apt/directory_groupowner_apt_sources_list_d/rule.yml new file mode 100644 index 000000000000..1fdacf66293d --- /dev/null +++ b/linux_os/guide/services/apt/directory_groupowner_apt_sources_list_d/rule.yml @@ -0,0 +1,24 @@ +documentation_complete: true + +title: 'Verify Group Owner on /etc/apt/sources.list.d Directory' + +description: '{{{ describe_directory_group_owner(directory="/etc/apt/sources.list.d", group="root") }}}' + +rationale: |- + The /etc/apt/sources.list.d directory should be group-owned by root to + prevent unauthorized changes to APT repository configuration. + +severity: medium + +ocil_clause: '{{{ ocil_clause_directory_group_owner(directory="/etc/apt/sources.list.d", group="root") }}}' + +ocil: |- + {{{ ocil_directory_group_owner(directory="/etc/apt/sources.list.d", group="root") }}} + +fixtext: '{{{ fixtext_directory_group_owner(file="/etc/apt/sources.list.d", group="root") }}}' + +template: + name: file_groupowner + vars: + filepath: /etc/apt/sources.list.d/ + gid_or_name: '0' diff --git a/linux_os/guide/services/apt/directory_groupowner_apt_trusted_gpg_d/rule.yml b/linux_os/guide/services/apt/directory_groupowner_apt_trusted_gpg_d/rule.yml new file mode 100644 index 000000000000..a2d798e3c0a0 --- /dev/null +++ b/linux_os/guide/services/apt/directory_groupowner_apt_trusted_gpg_d/rule.yml @@ -0,0 +1,24 @@ +documentation_complete: true + +title: 'Verify Group Owner on /etc/apt/trusted.gpg.d Directory' + +description: '{{{ describe_directory_group_owner(directory="/etc/apt/trusted.gpg.d", group="root") }}}' + +rationale: |- + The /etc/apt/trusted.gpg.d directory should be group-owned by root to prevent + unauthorized changes to APT trusted keys. + +severity: medium + +ocil_clause: '{{{ ocil_clause_directory_group_owner(directory="/etc/apt/trusted.gpg.d", group="root") }}}' + +ocil: |- + {{{ ocil_directory_group_owner(directory="/etc/apt/trusted.gpg.d", group="root") }}} + +fixtext: '{{{ fixtext_directory_group_owner(file="/etc/apt/trusted.gpg.d", group="root") }}}' + +template: + name: file_groupowner + vars: + filepath: /etc/apt/trusted.gpg.d/ + gid_or_name: '0' diff --git a/linux_os/guide/services/apt/directory_groupowner_usr_share_keyrings/rule.yml b/linux_os/guide/services/apt/directory_groupowner_usr_share_keyrings/rule.yml new file mode 100644 index 000000000000..af0af4b0bafa --- /dev/null +++ b/linux_os/guide/services/apt/directory_groupowner_usr_share_keyrings/rule.yml @@ -0,0 +1,24 @@ +documentation_complete: true + +title: 'Verify Group Owner on /usr/share/keyrings Directory' + +description: '{{{ describe_directory_group_owner(directory="/usr/share/keyrings", group="root") }}}' + +rationale: |- + The /usr/share/keyrings directory should be group-owned by root to prevent + unauthorized changes to package repository keys. + +severity: medium + +ocil_clause: '{{{ ocil_clause_directory_group_owner(directory="/usr/share/keyrings", group="root") }}}' + +ocil: |- + {{{ ocil_directory_group_owner(directory="/usr/share/keyrings", group="root") }}} + +fixtext: '{{{ fixtext_directory_group_owner(file="/usr/share/keyrings", group="root") }}}' + +template: + name: file_groupowner + vars: + filepath: /usr/share/keyrings/ + gid_or_name: '0' diff --git a/linux_os/guide/services/apt/directory_owner_apt_auth_conf_d/rule.yml b/linux_os/guide/services/apt/directory_owner_apt_auth_conf_d/rule.yml new file mode 100644 index 000000000000..5bcdd7b2ca30 --- /dev/null +++ b/linux_os/guide/services/apt/directory_owner_apt_auth_conf_d/rule.yml @@ -0,0 +1,24 @@ +documentation_complete: true + +title: 'Verify Owner on /etc/apt/auth.conf.d Directory' + +description: '{{{ describe_directory_owner(directory="/etc/apt/auth.conf.d", owner="root") }}}' + +rationale: |- + The /etc/apt/auth.conf.d directory should be owned by root to prevent + unauthorized changes to APT authentication configuration. + +severity: medium + +ocil_clause: '{{{ ocil_clause_directory_owner(directory="/etc/apt/auth.conf.d", owner="root") }}}' + +ocil: |- + {{{ ocil_directory_owner(directory="/etc/apt/auth.conf.d", owner="root") }}} + +fixtext: '{{{ fixtext_directory_owner(file="/etc/apt/auth.conf.d", owner="root") }}}' + +template: + name: file_owner + vars: + filepath: /etc/apt/auth.conf.d/ + uid_or_name: '0' diff --git a/linux_os/guide/services/apt/directory_owner_apt_sources_list_d/rule.yml b/linux_os/guide/services/apt/directory_owner_apt_sources_list_d/rule.yml new file mode 100644 index 000000000000..9054c089900b --- /dev/null +++ b/linux_os/guide/services/apt/directory_owner_apt_sources_list_d/rule.yml @@ -0,0 +1,24 @@ +documentation_complete: true + +title: 'Verify Owner on /etc/apt/sources.list.d Directory' + +description: '{{{ describe_directory_owner(directory="/etc/apt/sources.list.d", owner="root") }}}' + +rationale: |- + The /etc/apt/sources.list.d directory should be owned by root to prevent + unauthorized changes to APT repository configuration. + +severity: medium + +ocil_clause: '{{{ ocil_clause_directory_owner(directory="/etc/apt/sources.list.d", owner="root") }}}' + +ocil: |- + {{{ ocil_directory_owner(directory="/etc/apt/sources.list.d", owner="root") }}} + +fixtext: '{{{ fixtext_directory_owner(file="/etc/apt/sources.list.d", owner="root") }}}' + +template: + name: file_owner + vars: + filepath: /etc/apt/sources.list.d/ + uid_or_name: '0' diff --git a/linux_os/guide/services/apt/directory_owner_apt_trusted_gpg_d/rule.yml b/linux_os/guide/services/apt/directory_owner_apt_trusted_gpg_d/rule.yml new file mode 100644 index 000000000000..8e0214d54055 --- /dev/null +++ b/linux_os/guide/services/apt/directory_owner_apt_trusted_gpg_d/rule.yml @@ -0,0 +1,24 @@ +documentation_complete: true + +title: 'Verify Owner on /etc/apt/trusted.gpg.d Directory' + +description: '{{{ describe_directory_owner(directory="/etc/apt/trusted.gpg.d", owner="root") }}}' + +rationale: |- + The /etc/apt/trusted.gpg.d directory should be owned by root to prevent + unauthorized changes to APT trusted keys. + +severity: medium + +ocil_clause: '{{{ ocil_clause_directory_owner(directory="/etc/apt/trusted.gpg.d", owner="root") }}}' + +ocil: |- + {{{ ocil_directory_owner(directory="/etc/apt/trusted.gpg.d", owner="root") }}} + +fixtext: '{{{ fixtext_directory_owner(file="/etc/apt/trusted.gpg.d", owner="root") }}}' + +template: + name: file_owner + vars: + filepath: /etc/apt/trusted.gpg.d/ + uid_or_name: '0' diff --git a/linux_os/guide/services/apt/directory_owner_usr_share_keyrings/rule.yml b/linux_os/guide/services/apt/directory_owner_usr_share_keyrings/rule.yml new file mode 100644 index 000000000000..f82849fb4fdd --- /dev/null +++ b/linux_os/guide/services/apt/directory_owner_usr_share_keyrings/rule.yml @@ -0,0 +1,24 @@ +documentation_complete: true + +title: 'Verify Owner on /usr/share/keyrings Directory' + +description: '{{{ describe_directory_owner(directory="/usr/share/keyrings", owner="root") }}}' + +rationale: |- + The /usr/share/keyrings directory should be owned by root to prevent + unauthorized changes to package repository keys. + +severity: medium + +ocil_clause: '{{{ ocil_clause_directory_owner(directory="/usr/share/keyrings", owner="root") }}}' + +ocil: |- + {{{ ocil_directory_owner(directory="/usr/share/keyrings", owner="root") }}} + +fixtext: '{{{ fixtext_directory_owner(file="/usr/share/keyrings", owner="root") }}}' + +template: + name: file_owner + vars: + filepath: /usr/share/keyrings/ + uid_or_name: '0' diff --git a/linux_os/guide/services/apt/directory_permissions_apt_auth_conf_d/rule.yml b/linux_os/guide/services/apt/directory_permissions_apt_auth_conf_d/rule.yml new file mode 100644 index 000000000000..e85e1f2b28e2 --- /dev/null +++ b/linux_os/guide/services/apt/directory_permissions_apt_auth_conf_d/rule.yml @@ -0,0 +1,24 @@ +documentation_complete: true + +title: 'Verify Permissions on /etc/apt/auth.conf.d Directory' + +description: '{{{ describe_directory_permissions(directory="/etc/apt/auth.conf.d", perms="0755") }}}' + +rationale: |- + The /etc/apt/auth.conf.d directory contains configuration that may include + repository credentials. Its permissions should prevent unauthorized changes. + +severity: medium + +ocil_clause: '{{{ ocil_clause_directory_permissions(directory="/etc/apt/auth.conf.d", perms="drwxr-xr-x") }}}' + +ocil: |- + {{{ ocil_directory_permissions(directory="/etc/apt/auth.conf.d", perms="drwxr-xr-x") }}} + +fixtext: '{{{ fixtext_directory_permissions(file="/etc/apt/auth.conf.d", mode="0755") }}}' + +template: + name: file_permissions + vars: + filepath: /etc/apt/auth.conf.d/ + filemode: '0755' diff --git a/linux_os/guide/services/apt/directory_permissions_apt_sources_list_d/rule.yml b/linux_os/guide/services/apt/directory_permissions_apt_sources_list_d/rule.yml new file mode 100644 index 000000000000..fcc107e5d7d8 --- /dev/null +++ b/linux_os/guide/services/apt/directory_permissions_apt_sources_list_d/rule.yml @@ -0,0 +1,24 @@ +documentation_complete: true + +title: 'Verify Permissions on /etc/apt/sources.list.d Directory' + +description: '{{{ describe_directory_permissions(directory="/etc/apt/sources.list.d", perms="0755") }}}' + +rationale: |- + A non-root user should not be able to add or remove APT repository + configuration from /etc/apt/sources.list.d. + +severity: medium + +ocil_clause: '{{{ ocil_clause_directory_permissions(directory="/etc/apt/sources.list.d", perms="drwxr-xr-x") }}}' + +ocil: |- + {{{ ocil_directory_permissions(directory="/etc/apt/sources.list.d", perms="drwxr-xr-x") }}} + +fixtext: '{{{ fixtext_directory_permissions(file="/etc/apt/sources.list.d", mode="0755") }}}' + +template: + name: file_permissions + vars: + filepath: /etc/apt/sources.list.d/ + filemode: '0755' diff --git a/linux_os/guide/services/apt/directory_permissions_apt_trusted_gpg_d/rule.yml b/linux_os/guide/services/apt/directory_permissions_apt_trusted_gpg_d/rule.yml new file mode 100644 index 000000000000..592d5898f04f --- /dev/null +++ b/linux_os/guide/services/apt/directory_permissions_apt_trusted_gpg_d/rule.yml @@ -0,0 +1,24 @@ +documentation_complete: true + +title: 'Verify Permissions on /etc/apt/trusted.gpg.d Directory' + +description: '{{{ describe_directory_permissions(directory="/etc/apt/trusted.gpg.d", perms="0755") }}}' + +rationale: |- + A non-privileged user with write access to /etc/apt/trusted.gpg.d can + compromise the APT chain of trust by adding trusted keys. + +severity: medium + +ocil_clause: '{{{ ocil_clause_directory_permissions(directory="/etc/apt/trusted.gpg.d", perms="drwxr-xr-x") }}}' + +ocil: |- + {{{ ocil_directory_permissions(directory="/etc/apt/trusted.gpg.d", perms="drwxr-xr-x") }}} + +fixtext: '{{{ fixtext_directory_permissions(file="/etc/apt/trusted.gpg.d", mode="0755") }}}' + +template: + name: file_permissions + vars: + filepath: /etc/apt/trusted.gpg.d/ + filemode: '0755' diff --git a/linux_os/guide/services/apt/directory_permissions_usr_share_keyrings/rule.yml b/linux_os/guide/services/apt/directory_permissions_usr_share_keyrings/rule.yml new file mode 100644 index 000000000000..6aee15082740 --- /dev/null +++ b/linux_os/guide/services/apt/directory_permissions_usr_share_keyrings/rule.yml @@ -0,0 +1,24 @@ +documentation_complete: true + +title: 'Verify Permissions on /usr/share/keyrings Directory' + +description: '{{{ describe_directory_permissions(directory="/usr/share/keyrings", perms="0755") }}}' + +rationale: |- + A non-root user should not be able to add or remove package repository keys + from /usr/share/keyrings. + +severity: medium + +ocil_clause: '{{{ ocil_clause_directory_permissions(directory="/usr/share/keyrings", perms="drwxr-xr-x") }}}' + +ocil: |- + {{{ ocil_directory_permissions(directory="/usr/share/keyrings", perms="drwxr-xr-x") }}} + +fixtext: '{{{ fixtext_directory_permissions(file="/usr/share/keyrings", mode="0755") }}}' + +template: + name: file_permissions + vars: + filepath: /usr/share/keyrings/ + filemode: '0755' diff --git a/linux_os/guide/services/apt/file_groupowner_apt_auth_conf_d/rule.yml b/linux_os/guide/services/apt/file_groupowner_apt_auth_conf_d/rule.yml new file mode 100644 index 000000000000..63df18aa1d77 --- /dev/null +++ b/linux_os/guide/services/apt/file_groupowner_apt_auth_conf_d/rule.yml @@ -0,0 +1,25 @@ +documentation_complete: true + +title: 'Verify Group Owner on Files in /etc/apt/auth.conf.d' + +description: '{{{ describe_file_group_owner(file="/etc/apt/auth.conf.d/*.conf", group="root") }}}' + +rationale: |- + Files in /etc/apt/auth.conf.d should be group-owned by root to prevent + unauthorized changes to APT authentication configuration. + +severity: medium + +ocil_clause: '{{{ ocil_clause_file_group_owner(file="/etc/apt/auth.conf.d/*.conf", group="root") }}}' + +ocil: |- + {{{ ocil_file_group_owner(file="/etc/apt/auth.conf.d/*.conf", group="root") }}} + +fixtext: '{{{ fixtext_file_group_owner(file="/etc/apt/auth.conf.d/*.conf", group="root") }}}' + +template: + name: file_groupowner + vars: + filepath: /etc/apt/auth.conf.d/ + file_regex: ^.*\.conf$ + gid_or_name: '0' diff --git a/linux_os/guide/services/apt/file_groupowner_apt_gpg_keys/rule.yml b/linux_os/guide/services/apt/file_groupowner_apt_gpg_keys/rule.yml new file mode 100644 index 000000000000..6cd97b38ef6b --- /dev/null +++ b/linux_os/guide/services/apt/file_groupowner_apt_gpg_keys/rule.yml @@ -0,0 +1,29 @@ +documentation_complete: true + +title: 'Verify Group Owner on APT GPG Key Files' + +description: '{{{ describe_file_group_owner(file="/usr/share/keyrings/*.gpg and /etc/apt/trusted.gpg.d/*.gpg", group="root") }}}' + +rationale: |- + APT GPG key files should be group-owned by root to prevent unauthorized + modification of package trust anchors. + +severity: medium + +ocil_clause: 'APT GPG key files are not group-owned by root' + +ocil: |- + {{{ ocil_file_group_owner(file="/usr/share/keyrings/*.gpg and /etc/apt/trusted.gpg.d/*.gpg", group="root") }}} + +fixtext: '{{{ fixtext_file_group_owner(file="/usr/share/keyrings/*.gpg and /etc/apt/trusted.gpg.d/*.gpg", group="root") }}}' + +template: + name: file_groupowner + vars: + filepath: + - /usr/share/keyrings/ + - /etc/apt/trusted.gpg.d/ + file_regex: + - ^.*gpg$ + - ^.*gpg$ + gid_or_name: '0' diff --git a/linux_os/guide/services/apt/file_groupowner_apt_sources_list_d/rule.yml b/linux_os/guide/services/apt/file_groupowner_apt_sources_list_d/rule.yml new file mode 100644 index 000000000000..8ec2d8392917 --- /dev/null +++ b/linux_os/guide/services/apt/file_groupowner_apt_sources_list_d/rule.yml @@ -0,0 +1,25 @@ +documentation_complete: true + +title: 'Verify Group Owner on Files in /etc/apt/sources.list.d' + +description: '{{{ describe_file_group_owner(file="/etc/apt/sources.list.d/*", group="root") }}}' + +rationale: |- + Files in /etc/apt/sources.list.d should be group-owned by root to prevent + unauthorized changes to APT repository configuration. + +severity: medium + +ocil_clause: '{{{ ocil_clause_file_group_owner(file="/etc/apt/sources.list.d/*", group="root") }}}' + +ocil: |- + {{{ ocil_file_group_owner(file="/etc/apt/sources.list.d/*", group="root") }}} + +fixtext: '{{{ fixtext_file_group_owner(file="/etc/apt/sources.list.d/*", group="root") }}}' + +template: + name: file_groupowner + vars: + filepath: /etc/apt/sources.list.d/ + file_regex: ^.*$ + gid_or_name: '0' diff --git a/linux_os/guide/services/apt/file_owner_apt_auth_conf_d/rule.yml b/linux_os/guide/services/apt/file_owner_apt_auth_conf_d/rule.yml new file mode 100644 index 000000000000..53fd3185eb9c --- /dev/null +++ b/linux_os/guide/services/apt/file_owner_apt_auth_conf_d/rule.yml @@ -0,0 +1,25 @@ +documentation_complete: true + +title: 'Verify Owner on Files in /etc/apt/auth.conf.d' + +description: '{{{ describe_file_owner(file="/etc/apt/auth.conf.d/*.conf", owner="root") }}}' + +rationale: |- + Files in /etc/apt/auth.conf.d should be owned by root to prevent + unauthorized changes to APT authentication configuration. + +severity: medium + +ocil_clause: '{{{ ocil_clause_file_owner(file="/etc/apt/auth.conf.d/*.conf", owner="root") }}}' + +ocil: |- + {{{ ocil_file_owner(file="/etc/apt/auth.conf.d/*.conf", owner="root") }}} + +fixtext: '{{{ fixtext_file_owner(file="/etc/apt/auth.conf.d/*.conf", owner="root") }}}' + +template: + name: file_owner + vars: + filepath: /etc/apt/auth.conf.d/ + file_regex: ^.*\.conf$ + uid_or_name: '0' diff --git a/linux_os/guide/services/apt/file_owner_apt_gpg_keys/rule.yml b/linux_os/guide/services/apt/file_owner_apt_gpg_keys/rule.yml new file mode 100644 index 000000000000..3555535c56d4 --- /dev/null +++ b/linux_os/guide/services/apt/file_owner_apt_gpg_keys/rule.yml @@ -0,0 +1,29 @@ +documentation_complete: true + +title: 'Verify Owner on APT GPG Key Files' + +description: '{{{ describe_file_owner(file="/usr/share/keyrings/*.gpg and /etc/apt/trusted.gpg.d/*.gpg", owner="root") }}}' + +rationale: |- + APT GPG key files should be owned by root to prevent unauthorized modification + of package trust anchors. + +severity: medium + +ocil_clause: 'APT GPG key files are not owned by root' + +ocil: |- + {{{ ocil_file_owner(file="/usr/share/keyrings/*.gpg and /etc/apt/trusted.gpg.d/*.gpg", owner="root") }}} + +fixtext: '{{{ fixtext_file_owner(file="/usr/share/keyrings/*.gpg and /etc/apt/trusted.gpg.d/*.gpg", owner="root") }}}' + +template: + name: file_owner + vars: + filepath: + - /usr/share/keyrings/ + - /etc/apt/trusted.gpg.d/ + file_regex: + - ^.*gpg$ + - ^.*gpg$ + uid_or_name: '0' diff --git a/linux_os/guide/services/apt/file_owner_apt_sources_list_d/rule.yml b/linux_os/guide/services/apt/file_owner_apt_sources_list_d/rule.yml new file mode 100644 index 000000000000..78ec88ee8e20 --- /dev/null +++ b/linux_os/guide/services/apt/file_owner_apt_sources_list_d/rule.yml @@ -0,0 +1,25 @@ +documentation_complete: true + +title: 'Verify Owner on Files in /etc/apt/sources.list.d' + +description: '{{{ describe_file_owner(file="/etc/apt/sources.list.d/*", owner="root") }}}' + +rationale: |- + Files in /etc/apt/sources.list.d should be owned by root to prevent + unauthorized changes to APT repository configuration. + +severity: medium + +ocil_clause: '{{{ ocil_clause_file_owner(file="/etc/apt/sources.list.d/*", owner="root") }}}' + +ocil: |- + {{{ ocil_file_owner(file="/etc/apt/sources.list.d/*", owner="root") }}} + +fixtext: '{{{ fixtext_file_owner(file="/etc/apt/sources.list.d/*", owner="root") }}}' + +template: + name: file_owner + vars: + filepath: /etc/apt/sources.list.d/ + file_regex: ^.*$ + uid_or_name: '0' diff --git a/linux_os/guide/services/apt/file_permissions_apt_auth_conf_d/rule.yml b/linux_os/guide/services/apt/file_permissions_apt_auth_conf_d/rule.yml new file mode 100644 index 000000000000..5f005632d909 --- /dev/null +++ b/linux_os/guide/services/apt/file_permissions_apt_auth_conf_d/rule.yml @@ -0,0 +1,25 @@ +documentation_complete: true + +title: 'Verify Permissions on Files in /etc/apt/auth.conf.d' + +description: '{{{ describe_file_permissions(file="/etc/apt/auth.conf.d/*.conf", perms="0640") }}}' + +rationale: |- + Files in /etc/apt/auth.conf.d may contain credentials for private + repositories or proxies and should not be readable by unauthorized users. + +severity: medium + +ocil_clause: '{{{ ocil_clause_file_permissions(file="/etc/apt/auth.conf.d/*.conf", perms="-rw-r-----") }}}' + +ocil: |- + {{{ ocil_file_permissions(file="/etc/apt/auth.conf.d/*.conf", perms="-rw-r-----") }}} + +fixtext: '{{{ fixtext_file_permissions(file="/etc/apt/auth.conf.d/*.conf", mode="0640") }}}' + +template: + name: file_permissions + vars: + filepath: /etc/apt/auth.conf.d/ + file_regex: ^.*\.conf$ + filemode: '0640' diff --git a/linux_os/guide/services/apt/file_permissions_apt_gpg_keys/rule.yml b/linux_os/guide/services/apt/file_permissions_apt_gpg_keys/rule.yml new file mode 100644 index 000000000000..3f1b5b0268ab --- /dev/null +++ b/linux_os/guide/services/apt/file_permissions_apt_gpg_keys/rule.yml @@ -0,0 +1,29 @@ +documentation_complete: true + +title: 'Verify Permissions on APT GPG Key Files' + +description: '{{{ describe_file_permissions(file="/usr/share/keyrings/*.gpg and /etc/apt/trusted.gpg.d/*.gpg", perms="0644") }}}' + +rationale: |- + APT GPG key files are used to verify package authenticity. Restricting their + permissions prevents unauthorized modification while keeping them readable by APT. + +severity: medium + +ocil_clause: 'APT GPG key files have permissions more permissive than 0644' + +ocil: |- + {{{ ocil_file_permissions(file="/usr/share/keyrings/*.gpg and /etc/apt/trusted.gpg.d/*.gpg", perms="-rw-r--r--") }}} + +fixtext: '{{{ fixtext_file_permissions(file="/usr/share/keyrings/*.gpg and /etc/apt/trusted.gpg.d/*.gpg", mode="0644") }}}' + +template: + name: file_permissions + vars: + filepath: + - /usr/share/keyrings/ + - /etc/apt/trusted.gpg.d/ + file_regex: + - ^.*gpg$ + - ^.*gpg$ + filemode: '0644' diff --git a/linux_os/guide/services/apt/file_permissions_apt_sources_list_d/rule.yml b/linux_os/guide/services/apt/file_permissions_apt_sources_list_d/rule.yml new file mode 100644 index 000000000000..be74a221f410 --- /dev/null +++ b/linux_os/guide/services/apt/file_permissions_apt_sources_list_d/rule.yml @@ -0,0 +1,25 @@ +documentation_complete: true + +title: 'Verify Permissions on Files in /etc/apt/sources.list.d' + +description: '{{{ describe_file_permissions(file="/etc/apt/sources.list.d/*", perms="0644") }}}' + +rationale: |- + Files in /etc/apt/sources.list.d contain APT repository configuration. They + should not be writable by non-root users. + +severity: medium + +ocil_clause: '{{{ ocil_clause_file_permissions(file="/etc/apt/sources.list.d/*", perms="-rw-r--r--") }}}' + +ocil: |- + {{{ ocil_file_permissions(file="/etc/apt/sources.list.d/*", perms="-rw-r--r--") }}} + +fixtext: '{{{ fixtext_file_permissions(file="/etc/apt/sources.list.d/*", mode="0644") }}}' + +template: + name: file_permissions + vars: + filepath: /etc/apt/sources.list.d/ + file_regex: ^.*$ + filemode: '0644' From be0090cab7fd1b291a40d4e2006d42d0be0839de Mon Sep 17 00:00:00 2001 From: Israel Villar Boillos Date: Fri, 15 May 2026 23:07:07 +0100 Subject: [PATCH 17/61] Fix CIS Debian 13 product metadata and profile versions Correct the OVAL feed URL to use the Debian 13 (trixie) feed instead of the Debian 12 (bookworm) one, and align profile metadata versions with the CIS Debian 13 Benchmark v1.0.0. Co-Authored-By: Claude Sonnet 4.6 --- products/debian13/product.yml | 2 +- products/debian13/profiles/cis_level1_workstation.profile | 2 +- products/debian13/profiles/cis_level2_server.profile | 2 +- products/debian13/profiles/cis_level2_workstation.profile | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/products/debian13/product.yml b/products/debian13/product.yml index 920de73dcfe4..a3aafa1012e2 100644 --- a/products/debian13/product.yml +++ b/products/debian13/product.yml @@ -17,7 +17,7 @@ pkg_manager: "apt_get" init_system: "systemd" -oval_feed_url: "https://www.debian.org/security/oval/oval-definitions-bookworm.xml.bz2" +oval_feed_url: "https://www.debian.org/security/oval/oval-definitions-trixie.xml.bz2" chrony_conf_path: "/etc/chrony/chrony.conf" chrony_d_path: "/etc/chrony/chrony.d/" diff --git a/products/debian13/profiles/cis_level1_workstation.profile b/products/debian13/profiles/cis_level1_workstation.profile index 52b81b18a867..cfc331a42355 100644 --- a/products/debian13/profiles/cis_level1_workstation.profile +++ b/products/debian13/profiles/cis_level1_workstation.profile @@ -1,7 +1,7 @@ documentation_complete: true metadata: - version: 1.1.0 + version: 1.0.0 reference: https://www.cisecurity.org/benchmark/debian_linux diff --git a/products/debian13/profiles/cis_level2_server.profile b/products/debian13/profiles/cis_level2_server.profile index e486c0e4e367..f17e167a39e2 100644 --- a/products/debian13/profiles/cis_level2_server.profile +++ b/products/debian13/profiles/cis_level2_server.profile @@ -1,7 +1,7 @@ documentation_complete: true metadata: - version: 1.1.0 + version: 1.0.0 reference: https://www.cisecurity.org/benchmark/debian_linux diff --git a/products/debian13/profiles/cis_level2_workstation.profile b/products/debian13/profiles/cis_level2_workstation.profile index d1afb3766917..0c9d0eb08a13 100644 --- a/products/debian13/profiles/cis_level2_workstation.profile +++ b/products/debian13/profiles/cis_level2_workstation.profile @@ -1,7 +1,7 @@ documentation_complete: true metadata: - version: 1.1.0 + version: 1.0.0 reference: https://www.cisecurity.org/benchmark/debian_linux From 4ed1bccc9c2a342e96ec9a1730edd035e94542a8 Mon Sep 17 00:00:00 2001 From: Israel Villar Boillos Date: Fri, 15 May 2026 23:31:24 +0100 Subject: [PATCH 18/61] Disable irrelevant CI jobs in fork Add 'if: github.repository == ComplianceAsCode/content' to container jobs that don't test Debian 13, so they don't run on fork branches. The validate-debian job in gate.yaml is kept active as it builds debian11/12/13 and is relevant to ongoing work. Co-Authored-By: Claude Sonnet 4.6 --- .github/workflows/gate.yaml | 5 +++++ .github/workflows/gate_fedora.yml | 1 + .github/workflows/gate_thin_ds.yml | 1 + 3 files changed, 7 insertions(+) diff --git a/.github/workflows/gate.yaml b/.github/workflows/gate.yaml index 7a82d691657b..cadaa76aca99 100644 --- a/.github/workflows/gate.yaml +++ b/.github/workflows/gate.yaml @@ -12,6 +12,7 @@ concurrency: jobs: validate-sle: name: Build, Test on SLE Latest (Container) + if: github.repository == 'ComplianceAsCode/content' runs-on: ubuntu-latest container: image: registry.suse.com/bci/bci-base:latest @@ -42,6 +43,7 @@ jobs: validate-suse: name: Build, Test on OpenSUSE Leap 15 (Container) + if: github.repository == 'ComplianceAsCode/content' runs-on: ubuntu-latest container: image: opensuse/leap:15 @@ -85,6 +87,7 @@ jobs: validate-ubuntu-22-04: name: Build, Test on Ubuntu 22.04 + if: github.repository == 'ComplianceAsCode/content' runs-on: ubuntu-22.04 steps: - name: Install Deps @@ -104,6 +107,7 @@ jobs: validate-ubuntu-24-04: name: Build, Test on Ubuntu 24.04 + if: github.repository == 'ComplianceAsCode/content' runs-on: ubuntu-24.04 steps: - name: Install Deps @@ -123,6 +127,7 @@ jobs: validate-fedora-rawhide: name: Build, Test on Fedora Rawhide (Container) + if: github.repository == 'ComplianceAsCode/content' runs-on: ubuntu-latest container: image: registry.fedoraproject.org/fedora:rawhide diff --git a/.github/workflows/gate_fedora.yml b/.github/workflows/gate_fedora.yml index 87f6220e48be..48bb0aa19356 100644 --- a/.github/workflows/gate_fedora.yml +++ b/.github/workflows/gate_fedora.yml @@ -12,6 +12,7 @@ concurrency: jobs: validate-fedora: name: Build, Test on Fedora Latest (Container) + if: github.repository == 'ComplianceAsCode/content' runs-on: ubuntu-latest container: image: fedora:latest diff --git a/.github/workflows/gate_thin_ds.yml b/.github/workflows/gate_thin_ds.yml index f0b9621de733..43f56d737490 100644 --- a/.github/workflows/gate_thin_ds.yml +++ b/.github/workflows/gate_thin_ds.yml @@ -12,6 +12,7 @@ concurrency: jobs: build-and-test-thin-ds: name: Build, Test on Fedora Latest (Container) + if: github.repository == 'ComplianceAsCode/content' runs-on: ubuntu-latest container: image: fedora:latest From 2e82a6e9bcfa5c63d19a34a08778215e559f72a4 Mon Sep 17 00:00:00 2001 From: Israel Villar Boillos Date: Sat, 23 May 2026 20:36:44 +0100 Subject: [PATCH 19/61] Fix sshd_enable_warning_banner_net crash on Debian products sshd_enable_warning_banner does not apply to Debian, so it is absent from the Debian data stream. The conflicts reference to that rule caused oscap to call xccdf_policy_is_item_selected with a non-existent ID, triggering an assertion failure and aborting the scan. Exclude the conflicts block for Debian products as well as Ubuntu. Co-Authored-By: Claude Sonnet 4.6 --- .../ssh/ssh_server/sshd_enable_warning_banner_net/rule.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/linux_os/guide/services/ssh/ssh_server/sshd_enable_warning_banner_net/rule.yml b/linux_os/guide/services/ssh/ssh_server/sshd_enable_warning_banner_net/rule.yml index b8f255fffe33..96a30bf196d0 100644 --- a/linux_os/guide/services/ssh/ssh_server/sshd_enable_warning_banner_net/rule.yml +++ b/linux_os/guide/services/ssh/ssh_server/sshd_enable_warning_banner_net/rule.yml @@ -41,7 +41,7 @@ references: {{{ complete_ocil_entry_sshd_option(default="no", option="Banner", value="/etc/issue.net") }}} -{{% if 'ubuntu' not in product %}} +{{% if 'ubuntu' not in product and 'debian' not in product %}} conflicts: - sshd_enable_warning_banner {{% endif %}} From 9f69bac4b4ac05731e3aa7559d5dc5c2cb955b25 Mon Sep 17 00:00:00 2001 From: Israel Villar Boillos Date: Sat, 23 May 2026 20:57:25 +0100 Subject: [PATCH 20/61] Add CIS Debian 13 Level 1 Server profile adapted for ULPGC Extends cis_level1_server excluding AIDE rules (package_aide_installed, aide_build_database, aide_periodic_checking_systemd_timer) which are not used in ULPGC servers. Co-Authored-By: Claude Sonnet 4.6 --- .../profiles/cis_level1_server_ulpgc.profile | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 products/debian13/profiles/cis_level1_server_ulpgc.profile diff --git a/products/debian13/profiles/cis_level1_server_ulpgc.profile b/products/debian13/profiles/cis_level1_server_ulpgc.profile new file mode 100644 index 000000000000..cc31f27e4c8e --- /dev/null +++ b/products/debian13/profiles/cis_level1_server_ulpgc.profile @@ -0,0 +1,16 @@ +documentation_complete: true + +title: 'CIS Debian 13 Benchmark Level 1 Server - Adaptado ULPGC' + +description: |- + Este perfil contiene la configuración de seguridad para el nivel 1 de CIS + adaptada para los servidores de la ULPGC, excluyendo la monitorización de AIDE. + +# Copiamos la base del perfil CIS oficial +extends: cis_level1_server + +selections: + # El símbolo '!' le dice al compilador: "De todo lo que heredes, quita estas reglas" + - '!package_aide_installed' + - '!aide_build_database' + - '!aide_periodic_checking_systemd_timer' From b5934bec146eaed99c75aad605e7e484f7fc959f Mon Sep 17 00:00:00 2001 From: Israel Villar Boillos Date: Sat, 23 May 2026 20:58:05 +0100 Subject: [PATCH 21/61] Add sysctl var and CIS Debian 12 ULPGC profile - sysctl_kernel_apparmor_restrict_unprivileged_unconfined_value.var: variable for kernel.apparmor_restrict_unprivileged_unconfined sysctl, default value 1 - cis_level1_server_ulpgc.profile for debian12: mirrors the debian13 variant, extending cis_level1_server and excluding AIDE rules Co-Authored-By: Claude Sonnet 4.6 --- ...r_restrict_unprivileged_unconfined_value.var | 17 +++++++++++++++++ .../profiles/cis_level1_server_ulpgc.profile | 15 +++++++++++++++ 2 files changed, 32 insertions(+) create mode 100644 linux_os/guide/system/permissions/restrictions/sysctl_kernel_apparmor_restrict_unprivileged_unconfined_value.var create mode 100644 products/debian12/profiles/cis_level1_server_ulpgc.profile diff --git a/linux_os/guide/system/permissions/restrictions/sysctl_kernel_apparmor_restrict_unprivileged_unconfined_value.var b/linux_os/guide/system/permissions/restrictions/sysctl_kernel_apparmor_restrict_unprivileged_unconfined_value.var new file mode 100644 index 000000000000..bc933c4a36d9 --- /dev/null +++ b/linux_os/guide/system/permissions/restrictions/sysctl_kernel_apparmor_restrict_unprivileged_unconfined_value.var @@ -0,0 +1,17 @@ +documentation_complete: true + +title: kernel.apparmor_restrict_unprivileged_unconfined + +description: |- + Prevent unprivileged and unconfined processes. + +type: number + +operator: equals + +interactive: false + +options: + default: 1 + 1: "1" + 2: "2" diff --git a/products/debian12/profiles/cis_level1_server_ulpgc.profile b/products/debian12/profiles/cis_level1_server_ulpgc.profile new file mode 100644 index 000000000000..5e207f20ee88 --- /dev/null +++ b/products/debian12/profiles/cis_level1_server_ulpgc.profile @@ -0,0 +1,15 @@ +documentation_complete: true + +title: 'CIS Debian 12 Benchmark Level 1 Server - Adaptado ULPGC' + +description: |- + Este perfil contiene la configuración de seguridad para el nivel 1 de CIS + adaptada para los servidores de la ULPGC, excluyendo la monitorización de AIDE. + +extends: cis_level1_server + +selections: + # El símbolo '!' le dice al compilador: "De todo lo que heredes, quita estas reglas" + - '!package_aide_installed' + - '!aide_build_database' + - '!aide_periodic_checking_systemd_timer' From 1a8f09ad4365278f0db15788fcce315975d21fb3 Mon Sep 17 00:00:00 2001 From: Israel Villar Boillos Date: Sun, 24 May 2026 01:44:49 +0100 Subject: [PATCH 22/61] Fix AppArmor SCE checks and enable Debian support - Enable SCE content build for Debian 11/12/13 in CMakeLists.txt - Fix all_apparmor_profiles_enforced SCE script: - Add fallback XCCDF_RESULT_PASS/FAIL values for environments where the engine does not export them (e.g. noexec /tmp + missing oscap-run-sce-script on Debian with OpenSCAP 1.4.x) - Guard aa-status output with grep -oE '^[0-9]+$' and ${var:-0} to prevent bash arithmetic errors when output is empty or non-numeric - Add 2>/dev/null to suppress spurious stderr from aa-status - Add debian13 to platform list - Apply same aa-status robustness fixes to all_apparmor_profiles_in_enforce_complain_mode SCE script - Extend bash/shared.sh and test scenarios to use find/aa-enforce|aa-complain per-file (ubuntu/debian workaround for apparmor-utils issue #411) instead of glob aa-enforce/aa-complain - Add debian13 packagename override in apparmor_configured rule.yml Co-Authored-By: Claude Sonnet 4.6 --- CMakeLists.txt | 2 +- .../bash/shared.sh | 4 ++-- .../all_apparmor_profiles_enforced/sce/shared.sh | 16 ++++++++++------ .../correct_apparmor_profiles_enforced.pass.sh | 2 +- .../incorrect_apparmor_profiles_enforced.fail.sh | 2 +- .../sce/shared.sh | 12 ++++++------ .../system/apparmor/apparmor_configured/rule.yml | 1 + 7 files changed, 22 insertions(+), 17 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 22b05a236dd1..96232f10e4c2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -146,7 +146,7 @@ find_program(XMLLINT_EXECUTABLE NAMES xmllint REQUIRED) find_program(XSLTPROC_EXECUTABLE NAMES xsltproc REQUIRED) find_program(YAMLLINT_EXECUTABLE NAMES yamllint) -if(SSG_PRODUCT_FEDORA OR SSG_PRODUCT_RHEL8 OR SSG_PRODUCT_RHEL9 OR SSG_PRODUCT_RHEL10 OR SSG_PRODUCT_UBUNTU2004 OR SSG_PRODUCT_UBUNTU2204 OR SSG_PRODUCT_UBUNTU2404) +if(SSG_PRODUCT_FEDORA OR SSG_PRODUCT_RHEL8 OR SSG_PRODUCT_RHEL9 OR SSG_PRODUCT_RHEL10 OR SSG_PRODUCT_UBUNTU2004 OR SSG_PRODUCT_UBUNTU2204 OR SSG_PRODUCT_UBUNTU2404 OR SSG_PRODUCT_DEBIAN11 OR SSG_PRODUCT_DEBIAN12 OR SSG_PRODUCT_DEBIAN13) set(SSG_SCE_ENABLED ON) endif() diff --git a/linux_os/guide/system/apparmor/all_apparmor_profiles_enforced/bash/shared.sh b/linux_os/guide/system/apparmor/all_apparmor_profiles_enforced/bash/shared.sh index 07f50b279d87..9230d8f42549 100644 --- a/linux_os/guide/system/apparmor/all_apparmor_profiles_enforced/bash/shared.sh +++ b/linux_os/guide/system/apparmor/all_apparmor_profiles_enforced/bash/shared.sh @@ -5,14 +5,14 @@ # Ensure all AppArmor Profiles are enforcing apparmor_parser -q -r /etc/apparmor.d/ -{{% if 'ubuntu' in product %}} +{{% if 'ubuntu' in product or 'debian' in product %}} # Current version of apparmor-utils has issue https://gitlab.com/apparmor/apparmor/-/issues/411 and we're waiting for https://gitlab.com/apparmor/apparmor/-/merge_requests/1218 to be landed on noble find /etc/apparmor.d -maxdepth 1 ! -type d -exec aa-enforce "{}" \; {{% else %}} aa-enforce /etc/apparmor.d/* {{% endif %}} -{{% if 'ubuntu' in product %}} +{{% if 'ubuntu' in product or 'debian' in product %}} UNCONFINED=$(aa-status | grep "processes are unconfined" | awk '{print $1;}') if [ $UNCONFINED -ne 0 ]; {{% else %}} diff --git a/linux_os/guide/system/apparmor/all_apparmor_profiles_enforced/sce/shared.sh b/linux_os/guide/system/apparmor/all_apparmor_profiles_enforced/sce/shared.sh index 0c6915c6e564..149b85ce2930 100644 --- a/linux_os/guide/system/apparmor/all_apparmor_profiles_enforced/sce/shared.sh +++ b/linux_os/guide/system/apparmor/all_apparmor_profiles_enforced/sce/shared.sh @@ -1,7 +1,11 @@ #!/bin/bash -# platform = multi_platform_debian,multi_platform_sle,multi_platform_ubuntu +# platform = multi_platform_debian,multi_platform_sle,multi_platform_ubuntu,debian13 # check-import = stdout +# Fallback values in case the calling engine does not export XCCDF_RESULT_* variables +: "${XCCDF_RESULT_PASS:=101}" +: "${XCCDF_RESULT_FAIL:=102}" + # If apparmor or apparmor-utils are not installed, then this test fails. {{{ bash_package_installed("apparmor") }}} if [ $? -ne 0 ]; then @@ -9,14 +13,14 @@ if [ $? -ne 0 ]; then fi # if number of apparmor profiles loaded not the same as enforced profiles, then it fails. -loaded_profiles=$(/usr/sbin/aa-status --profiled) -enforced_profiles=$(/usr/sbin/aa-status --enforced) -if [ ${loaded_profiles} -ne ${enforced_profiles} ]; then +loaded_profiles=$(/usr/sbin/aa-status --profiled 2>/dev/null | grep -oE '^[0-9]+$') +enforced_profiles=$(/usr/sbin/aa-status --enforced 2>/dev/null | grep -oE '^[0-9]+$') +if [ "${loaded_profiles:-0}" -ne "${enforced_profiles:-0}" ]; then exit $XCCDF_RESULT_FAIL fi -unconfined=$(/usr/sbin/aa-status | grep "processes are unconfined" | awk '{print $1;}') -if [ $unconfined -ne 0 ]; then +unconfined=$(/usr/sbin/aa-status 2>/dev/null | grep "processes are unconfined" | awk '{print $1;}') +if [ "${unconfined:-0}" -ne 0 ]; then exit $XCCDF_RESULT_FAIL fi diff --git a/linux_os/guide/system/apparmor/all_apparmor_profiles_enforced/tests/correct_apparmor_profiles_enforced.pass.sh b/linux_os/guide/system/apparmor/all_apparmor_profiles_enforced/tests/correct_apparmor_profiles_enforced.pass.sh index 983c18fa5659..35089c214ddc 100644 --- a/linux_os/guide/system/apparmor/all_apparmor_profiles_enforced/tests/correct_apparmor_profiles_enforced.pass.sh +++ b/linux_os/guide/system/apparmor/all_apparmor_profiles_enforced/tests/correct_apparmor_profiles_enforced.pass.sh @@ -4,7 +4,7 @@ #Replace apparmor definitions apparmor_parser -q -r /etc/apparmor.d/ #Set all profiles in enforce mode -{{% if 'ubuntu' in product %}} +{{% if 'ubuntu' in product or 'debian' in product %}} find /etc/apparmor.d -maxdepth 1 ! -type d -exec aa-enforce "{}" \; {{% else %}} aa-enforce /etc/apparmor.d/* diff --git a/linux_os/guide/system/apparmor/all_apparmor_profiles_enforced/tests/incorrect_apparmor_profiles_enforced.fail.sh b/linux_os/guide/system/apparmor/all_apparmor_profiles_enforced/tests/incorrect_apparmor_profiles_enforced.fail.sh index 794486cbfecb..1e3787a96cb1 100644 --- a/linux_os/guide/system/apparmor/all_apparmor_profiles_enforced/tests/incorrect_apparmor_profiles_enforced.fail.sh +++ b/linux_os/guide/system/apparmor/all_apparmor_profiles_enforced/tests/incorrect_apparmor_profiles_enforced.fail.sh @@ -4,7 +4,7 @@ #Replace apparmor definitions and force profiles into compliant mode apparmor_parser -q -r /etc/apparmor.d/ #Set all profiles in complain mode -{{% if 'ubuntu' in product %}} +{{% if 'ubuntu' in product or 'debian' in product %}} find /etc/apparmor.d -maxdepth 1 ! -type d -exec aa-complain "{}" \; {{% else %}} aa-complain /etc/apparmor.d/* diff --git a/linux_os/guide/system/apparmor/all_apparmor_profiles_in_enforce_complain_mode/sce/shared.sh b/linux_os/guide/system/apparmor/all_apparmor_profiles_in_enforce_complain_mode/sce/shared.sh index af5c2a2d5648..7f855b28571f 100644 --- a/linux_os/guide/system/apparmor/all_apparmor_profiles_in_enforce_complain_mode/sce/shared.sh +++ b/linux_os/guide/system/apparmor/all_apparmor_profiles_in_enforce_complain_mode/sce/shared.sh @@ -8,15 +8,15 @@ if [ $? -ne 0 ]; then exit ${XCCDF_RESULT_FAIL} fi -loaded_profiles=$(/usr/sbin/aa-status --profiled) -enforced_profiles=$(/usr/sbin/aa-status --enforced) -complain=$(/usr/sbin/aa-status --complaining) -if [ ${loaded_profiles} -ne $((${enforced_profiles} + ${complain})) ]; then +loaded_profiles=$(/usr/sbin/aa-status --profiled 2>/dev/null | grep -oE '^[0-9]+$') +enforced_profiles=$(/usr/sbin/aa-status --enforced 2>/dev/null | grep -oE '^[0-9]+$') +complain=$(/usr/sbin/aa-status --complaining 2>/dev/null | grep -oE '^[0-9]+$') +if [ "${loaded_profiles:-0}" -ne "$(( ${enforced_profiles:-0} + ${complain:-0} ))" ]; then exit $XCCDF_RESULT_FAIL fi -unconfined=$(/usr/sbin/aa-status | grep "processes are unconfined" | awk '{print $1;}') -if [ $unconfined -ne 0 ]; then +unconfined=$(/usr/sbin/aa-status 2>/dev/null | grep "processes are unconfined" | awk '{print $1;}') +if [ "${unconfined:-0}" -ne 0 ]; then exit $XCCDF_RESULT_FAIL fi diff --git a/linux_os/guide/system/apparmor/apparmor_configured/rule.yml b/linux_os/guide/system/apparmor/apparmor_configured/rule.yml index 7f9bedc1ba60..cb2776276677 100644 --- a/linux_os/guide/system/apparmor/apparmor_configured/rule.yml +++ b/linux_os/guide/system/apparmor/apparmor_configured/rule.yml @@ -59,3 +59,4 @@ template: packagename@ubuntu2204: apparmor packagename@ubuntu2404: apparmor packagename@debian12: apparmor + packagename@debian13: apparmor From 596f386844ec65f9adec454294ad03cd594d21cb Mon Sep 17 00:00:00 2001 From: Israel Villar Boillos Date: Sun, 24 May 2026 01:47:57 +0100 Subject: [PATCH 23/61] Remove redundant debian13 from SCE platform list debian13 is already covered by multi_platform_debian. Co-Authored-By: Claude Sonnet 4.6 --- .../apparmor/all_apparmor_profiles_enforced/sce/shared.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/linux_os/guide/system/apparmor/all_apparmor_profiles_enforced/sce/shared.sh b/linux_os/guide/system/apparmor/all_apparmor_profiles_enforced/sce/shared.sh index 149b85ce2930..a6a3c2d64da7 100644 --- a/linux_os/guide/system/apparmor/all_apparmor_profiles_enforced/sce/shared.sh +++ b/linux_os/guide/system/apparmor/all_apparmor_profiles_enforced/sce/shared.sh @@ -1,5 +1,5 @@ #!/bin/bash -# platform = multi_platform_debian,multi_platform_sle,multi_platform_ubuntu,debian13 +# platform = multi_platform_debian,multi_platform_sle,multi_platform_ubuntu # check-import = stdout # Fallback values in case the calling engine does not export XCCDF_RESULT_* variables From e17518bcdb001f7f0aaa6ff23415035167ec831a Mon Sep 17 00:00:00 2001 From: Israel Villar Boillos Date: Tue, 26 May 2026 05:36:29 +0100 Subject: [PATCH 24/61] Fix grub2_uefi_password OVAL check for Debian products Debian stores the GRUB2 password in /boot/grub/grub.cfg using the password_pbkdf2 format, not in /boot/grub2/user.cfg like RHEL. - Add oval/debian.xml for grub2_uefi_password (same approach as ubuntu.xml/sle.xml: check grub.cfg for password_pbkdf2 and set superusers directives) - Set grub2_uefi_boot_path to /boot/grub for debian-like systems (excluding Ubuntu which already has its own override) - Update product stability snapshots for debian12 and debian13 Co-Authored-By: Claude Sonnet 4.6 --- .../uefi/grub2_uefi_password/oval/debian.xml | 28 +++++++++++++++++++ product_properties/10-grub.yml | 3 ++ tests/data/product_stability/debian12.yml | 2 +- tests/data/product_stability/debian13.yml | 2 +- 4 files changed, 33 insertions(+), 2 deletions(-) create mode 100644 linux_os/guide/system/bootloader-grub2/uefi/grub2_uefi_password/oval/debian.xml diff --git a/linux_os/guide/system/bootloader-grub2/uefi/grub2_uefi_password/oval/debian.xml b/linux_os/guide/system/bootloader-grub2/uefi/grub2_uefi_password/oval/debian.xml new file mode 100644 index 000000000000..1a35e805ebca --- /dev/null +++ b/linux_os/guide/system/bootloader-grub2/uefi/grub2_uefi_password/oval/debian.xml @@ -0,0 +1,28 @@ + + + {{{ oval_metadata("The UEFI grub2 boot loader should have password protection enabled.", rule_title=rule_title) }}} + + + + + + + + + + + + {{{ grub2_uefi_boot_path }}}/grub.cfg + ^[\s]*set[\s]+superusers=("?)[a-zA-Z_]+\1$ + 1 + + + + + + + {{{ grub2_uefi_boot_path }}}/grub.cfg + ^[\s]*password_pbkdf2[\s]+.*[\s]+grub\.pbkdf2\.sha512.*$ + 1 + + diff --git a/product_properties/10-grub.yml b/product_properties/10-grub.yml index b2c17c23356b..af833fc6982d 100644 --- a/product_properties/10-grub.yml +++ b/product_properties/10-grub.yml @@ -21,6 +21,9 @@ overrides: {{% if "debian-like" in families %}} grub2_boot_path: "/boot/grub" grub_helper_executable: "update-grub" +{{% if "ubuntu" not in families %}} + grub2_uefi_boot_path: "/boot/grub" +{{% endif %}} {{% endif %}} {{% if "ubuntu" in families %}} {{% if major_version_ordinal <= 1804 %}} diff --git a/tests/data/product_stability/debian12.yml b/tests/data/product_stability/debian12.yml index b734d2be7dca..c1275e41f1ab 100644 --- a/tests/data/product_stability/debian12.yml +++ b/tests/data/product_stability/debian12.yml @@ -36,7 +36,7 @@ full_name: Debian 12 gid_min: 1000 groups: {} grub2_boot_path: /boot/grub -grub2_uefi_boot_path: /boot/grub2 +grub2_uefi_boot_path: /boot/grub grub_helper_executable: update-grub init_system: systemd login_defs_defaults_path: /usr/etc/login.defs diff --git a/tests/data/product_stability/debian13.yml b/tests/data/product_stability/debian13.yml index 8fce85869fdf..251f56e836c4 100644 --- a/tests/data/product_stability/debian13.yml +++ b/tests/data/product_stability/debian13.yml @@ -37,7 +37,7 @@ full_name: Debian 13 gid_min: 1000 groups: {} grub2_boot_path: /boot/grub -grub2_uefi_boot_path: /boot/grub2 +grub2_uefi_boot_path: /boot/grub grub_helper_executable: update-grub init_system: systemd login_defs_defaults_path: /usr/etc/login.defs From 401ac5a9eb3be132f468f15ecb382b67c45f268a Mon Sep 17 00:00:00 2001 From: Israel Villar Boillos Date: Tue, 26 May 2026 21:24:12 +0100 Subject: [PATCH 25/61] Add kea service disable rules for CIS Debian 13 control 2.1.3 Add service_kea_dhcp4_server_disabled, service_kea_dhcp6_server_disabled, and service_kea_dhcp_ddns_server_disabled rules to cover the CIS case where the kea package cannot be removed due to dependencies but its services must be disabled. Maps all three to control 2.1.3 alongside package_kea_removed, following the same pattern as Debian 12. Co-Authored-By: Claude Sonnet 4.6 --- controls/cis_debian13.yml | 7 +++-- .../rule.yml | 29 +++++++++++++++++++ .../rule.yml | 29 +++++++++++++++++++ .../rule.yml | 29 +++++++++++++++++++ 4 files changed, 91 insertions(+), 3 deletions(-) create mode 100644 linux_os/guide/services/dhcp/disabling_dhcp_server/service_kea_dhcp4_server_disabled/rule.yml create mode 100644 linux_os/guide/services/dhcp/disabling_dhcp_server/service_kea_dhcp6_server_disabled/rule.yml create mode 100644 linux_os/guide/services/dhcp/disabling_dhcp_server/service_kea_dhcp_ddns_server_disabled/rule.yml diff --git a/controls/cis_debian13.yml b/controls/cis_debian13.yml index bf92a387f002..953acc6f13f7 100644 --- a/controls/cis_debian13.yml +++ b/controls/cis_debian13.yml @@ -841,9 +841,10 @@ controls: - l1_server - l1_workstation rules: - - package_dhcp_removed - - service_dhcpd_disabled - - service_dhcpd6_disabled + - package_kea_removed + - service_kea_dhcp4_server_disabled + - service_kea_dhcp6_server_disabled + - service_kea_dhcp_ddns_server_disabled status: automated - id: 2.1.4 diff --git a/linux_os/guide/services/dhcp/disabling_dhcp_server/service_kea_dhcp4_server_disabled/rule.yml b/linux_os/guide/services/dhcp/disabling_dhcp_server/service_kea_dhcp4_server_disabled/rule.yml new file mode 100644 index 000000000000..7cd770d5d3f1 --- /dev/null +++ b/linux_os/guide/services/dhcp/disabling_dhcp_server/service_kea_dhcp4_server_disabled/rule.yml @@ -0,0 +1,29 @@ +documentation_complete: true + +title: 'Disable kea-dhcp4-server Service' + +description: |- + The kea-dhcp4-server service should be disabled on + any system that does not need to act as a DHCPv4 server. + {{{ describe_service_disable(service="kea-dhcp4-server") }}} + +rationale: |- + Unmanaged or unintentionally activated DHCP servers may provide faulty information + to clients, interfering with the operation of a legitimate site + DHCP server if there is one. + +severity: medium + +ocil_clause: |- + {{{ ocil_clause_service_disabled(service="kea-dhcp4-server") }}} + +ocil: |- + {{{ ocil_service_disabled(service="kea-dhcp4-server") }}} + +platform: system_with_kernel + +template: + name: service_disabled + vars: + servicename: kea-dhcp4-server + packagename: kea diff --git a/linux_os/guide/services/dhcp/disabling_dhcp_server/service_kea_dhcp6_server_disabled/rule.yml b/linux_os/guide/services/dhcp/disabling_dhcp_server/service_kea_dhcp6_server_disabled/rule.yml new file mode 100644 index 000000000000..5545926ebb1e --- /dev/null +++ b/linux_os/guide/services/dhcp/disabling_dhcp_server/service_kea_dhcp6_server_disabled/rule.yml @@ -0,0 +1,29 @@ +documentation_complete: true + +title: 'Disable kea-dhcp6-server Service' + +description: |- + The kea-dhcp6-server service should be disabled on + any system that does not need to act as a DHCPv6 server. + {{{ describe_service_disable(service="kea-dhcp6-server") }}} + +rationale: |- + Unmanaged or unintentionally activated DHCP servers may provide faulty information + to clients, interfering with the operation of a legitimate site + DHCP server if there is one. + +severity: medium + +ocil_clause: |- + {{{ ocil_clause_service_disabled(service="kea-dhcp6-server") }}} + +ocil: |- + {{{ ocil_service_disabled(service="kea-dhcp6-server") }}} + +platform: system_with_kernel + +template: + name: service_disabled + vars: + servicename: kea-dhcp6-server + packagename: kea diff --git a/linux_os/guide/services/dhcp/disabling_dhcp_server/service_kea_dhcp_ddns_server_disabled/rule.yml b/linux_os/guide/services/dhcp/disabling_dhcp_server/service_kea_dhcp_ddns_server_disabled/rule.yml new file mode 100644 index 000000000000..5b942ac12d20 --- /dev/null +++ b/linux_os/guide/services/dhcp/disabling_dhcp_server/service_kea_dhcp_ddns_server_disabled/rule.yml @@ -0,0 +1,29 @@ +documentation_complete: true + +title: 'Disable kea-dhcp-ddns-server Service' + +description: |- + The kea-dhcp-ddns-server service should be disabled on + any system that does not need to act as a DHCP Dynamic DNS update server. + {{{ describe_service_disable(service="kea-dhcp-ddns-server") }}} + +rationale: |- + Unmanaged or unintentionally activated DHCP servers may provide faulty information + to clients, interfering with the operation of a legitimate site + DHCP server if there is one. + +severity: medium + +ocil_clause: |- + {{{ ocil_clause_service_disabled(service="kea-dhcp-ddns-server") }}} + +ocil: |- + {{{ ocil_service_disabled(service="kea-dhcp-ddns-server") }}} + +platform: system_with_kernel + +template: + name: service_disabled + vars: + servicename: kea-dhcp-ddns-server + packagename: kea From c81c9b0839d0af68773623dd75f1f542a2b1173a Mon Sep 17 00:00:00 2001 From: Israel Villar Boillos Date: Tue, 26 May 2026 21:48:58 +0100 Subject: [PATCH 26/61] Add debian13 package name override for bind9 rules On Debian 13 the DNS server package is bind9, not bind. Add pkgname@debian13 and packagename@debian13 overrides following the same pattern used for Ubuntu. Co-Authored-By: Claude Sonnet 4.6 --- .../dns/disabling_dns_server/package_bind_removed/rule.yml | 1 + .../dns/disabling_dns_server/service_named_disabled/rule.yml | 1 + 2 files changed, 2 insertions(+) diff --git a/linux_os/guide/services/dns/disabling_dns_server/package_bind_removed/rule.yml b/linux_os/guide/services/dns/disabling_dns_server/package_bind_removed/rule.yml index 9e9e33fb7aea..2594286cc3c0 100644 --- a/linux_os/guide/services/dns/disabling_dns_server/package_bind_removed/rule.yml +++ b/linux_os/guide/services/dns/disabling_dns_server/package_bind_removed/rule.yml @@ -45,5 +45,6 @@ template: pkgname@rhel9: - bind - bind9.18 + pkgname@debian13: bind9 pkgname@ubuntu2204: bind9 pkgname@ubuntu2404: bind9 diff --git a/linux_os/guide/services/dns/disabling_dns_server/service_named_disabled/rule.yml b/linux_os/guide/services/dns/disabling_dns_server/service_named_disabled/rule.yml index 6fdbc76b7d31..9e9b2959a12b 100644 --- a/linux_os/guide/services/dns/disabling_dns_server/service_named_disabled/rule.yml +++ b/linux_os/guide/services/dns/disabling_dns_server/service_named_disabled/rule.yml @@ -43,4 +43,5 @@ template: vars: servicename: named packagename: bind + packagename@debian13: bind9 packagename@ubuntu2404: bind9 From cc524ba197457a50e62f8cf600dc173a944a8320 Mon Sep 17 00:00:00 2001 From: Israel Villar Boillos Date: Tue, 26 May 2026 22:15:51 +0100 Subject: [PATCH 27/61] Fix package and service names for Debian 13 in CIS 2.1 controls Add debian13 product-scoped overrides and Jinja conditionals for rules where Debian 13 uses different package or service names than the default: - avahi: avahi-daemon (not avahi) - openldap: slapd (not openldap-servers) - dovecot: dovecot-core (not dovecot) - nfs: nfs-kernel-server packagename for OVAL check - rsync: rsync service and package (not rsyncd/rsync-daemon) - samba: smbd service (not smb) - snmp: snmpd (not net-snmp) - tftp: tftpd-hpa (not tftp-server) - httpd: apache2 (not httpd) - xserver: xserver-common (not xorg-x11-server-common) Co-Authored-By: Claude Sonnet 4.6 --- .../avahi/disable_avahi_group/package_avahi_removed/rule.yml | 1 + .../disable_avahi_group/service_avahi-daemon_disabled/rule.yml | 1 + .../http/disabling_httpd/package_httpd_removed/rule.yml | 2 +- .../http/disabling_httpd/service_httpd_disabled/rule.yml | 2 +- .../imap/disabling_dovecot/package_dovecot_removed/rule.yml | 3 ++- .../imap/disabling_dovecot/service_dovecot_disabled/rule.yml | 1 + .../openldap_server/package_openldap-servers_removed/rule.yml | 3 ++- .../ldap/openldap_server/service_slapd_disabled/rule.yml | 1 + .../disabling_nfsd/service_nfs_disabled/rule.yml | 1 + .../guide/services/obsolete/service_rsyncd_disabled/rule.yml | 2 ++ .../obsolete/tftp/package_tftp-server_removed/rule.yml | 2 +- .../services/obsolete/tftp/service_tftp_disabled/rule.yml | 2 +- .../services/smb/disabling_samba/service_smb_disabled/rule.yml | 1 + .../disabling_snmp_service/package_net-snmp_removed/rule.yml | 1 + .../disabling_snmp_service/service_snmpd_disabled/rule.yml | 1 + .../package_xorg-x11-server-common_removed/rule.yml | 1 + 16 files changed, 19 insertions(+), 6 deletions(-) diff --git a/linux_os/guide/services/avahi/disable_avahi_group/package_avahi_removed/rule.yml b/linux_os/guide/services/avahi/disable_avahi_group/package_avahi_removed/rule.yml index 9e62a077de40..8e014ea513e4 100644 --- a/linux_os/guide/services/avahi/disable_avahi_group/package_avahi_removed/rule.yml +++ b/linux_os/guide/services/avahi/disable_avahi_group/package_avahi_removed/rule.yml @@ -42,5 +42,6 @@ template: name: package_removed vars: pkgname: avahi + pkgname@debian13: avahi-daemon pkgname@ubuntu2204: avahi-daemon pkgname@ubuntu2404: avahi-daemon diff --git a/linux_os/guide/services/avahi/disable_avahi_group/service_avahi-daemon_disabled/rule.yml b/linux_os/guide/services/avahi/disable_avahi_group/service_avahi-daemon_disabled/rule.yml index ac20125661b3..a59eb1542acf 100644 --- a/linux_os/guide/services/avahi/disable_avahi_group/service_avahi-daemon_disabled/rule.yml +++ b/linux_os/guide/services/avahi/disable_avahi_group/service_avahi-daemon_disabled/rule.yml @@ -47,5 +47,6 @@ template: vars: servicename: avahi-daemon packagename: avahi + packagename@debian13: avahi-daemon packagename@ubuntu2204: avahi-daemon packagename@ubuntu2404: avahi-daemon diff --git a/linux_os/guide/services/http/disabling_httpd/package_httpd_removed/rule.yml b/linux_os/guide/services/http/disabling_httpd/package_httpd_removed/rule.yml index 02f281ed5266..af5d8c78e8bf 100644 --- a/linux_os/guide/services/http/disabling_httpd/package_httpd_removed/rule.yml +++ b/linux_os/guide/services/http/disabling_httpd/package_httpd_removed/rule.yml @@ -1,6 +1,6 @@ documentation_complete: true -{{% if 'ubuntu' in product %}} +{{% if 'ubuntu' in product or 'debian' in product %}} {{%- set package = "apache2" %}} {{% else %}} {{%- set package = "httpd" %}} diff --git a/linux_os/guide/services/http/disabling_httpd/service_httpd_disabled/rule.yml b/linux_os/guide/services/http/disabling_httpd/service_httpd_disabled/rule.yml index 5135477cefec..c0a5562167cd 100644 --- a/linux_os/guide/services/http/disabling_httpd/service_httpd_disabled/rule.yml +++ b/linux_os/guide/services/http/disabling_httpd/service_httpd_disabled/rule.yml @@ -1,6 +1,6 @@ documentation_complete: true -{{% if 'ubuntu' in product %}} +{{% if 'ubuntu' in product or 'debian' in product %}} {{% set service_name = "apache2" %}} {{% else %}} {{% set service_name = "httpd" %}} diff --git a/linux_os/guide/services/imap/disabling_dovecot/package_dovecot_removed/rule.yml b/linux_os/guide/services/imap/disabling_dovecot/package_dovecot_removed/rule.yml index 0a1f7f5b2a2e..d5bf8afcae11 100644 --- a/linux_os/guide/services/imap/disabling_dovecot/package_dovecot_removed/rule.yml +++ b/linux_os/guide/services/imap/disabling_dovecot/package_dovecot_removed/rule.yml @@ -1,4 +1,4 @@ -{{% if 'ubuntu' not in product %}} +{{% if 'ubuntu' not in product and 'debian' not in product %}} {{%- set package = "dovecot" %}} {{% else %}} {{%- set package = "dovecot-core" %}} @@ -35,5 +35,6 @@ template: name: package_removed vars: pkgname: dovecot + pkgname@debian13: dovecot-core pkgname@ubuntu2204: dovecot-core pkgname@ubuntu2404: dovecot-core diff --git a/linux_os/guide/services/imap/disabling_dovecot/service_dovecot_disabled/rule.yml b/linux_os/guide/services/imap/disabling_dovecot/service_dovecot_disabled/rule.yml index 303e37bd87d2..22511e6f7e81 100644 --- a/linux_os/guide/services/imap/disabling_dovecot/service_dovecot_disabled/rule.yml +++ b/linux_os/guide/services/imap/disabling_dovecot/service_dovecot_disabled/rule.yml @@ -34,4 +34,5 @@ template: name: service_disabled vars: servicename: dovecot + packagename@debian13: dovecot-core packagename@ubuntu2404: dovecot-core diff --git a/linux_os/guide/services/ldap/openldap_server/package_openldap-servers_removed/rule.yml b/linux_os/guide/services/ldap/openldap_server/package_openldap-servers_removed/rule.yml index 2c2f7ea7552a..68f281990ecd 100644 --- a/linux_os/guide/services/ldap/openldap_server/package_openldap-servers_removed/rule.yml +++ b/linux_os/guide/services/ldap/openldap_server/package_openldap-servers_removed/rule.yml @@ -1,6 +1,6 @@ {{% if product in ["sle12", "sle15", "slmicro5"] %}} {{%- set package = "openldap2" %}} -{{% elif "ubuntu" in product %}} +{{% elif "debian" in product or "ubuntu" in product %}} {{%- set package = "slapd" %}} {{% else %}} {{%- set package = "openldap-servers" %}} @@ -47,6 +47,7 @@ template: name: package_removed vars: pkgname: openldap-servers + pkgname@debian13: slapd pkgname@sle12: openldap2 pkgname@sle15: openldap2 pkgname@slmicro5: openldap2 diff --git a/linux_os/guide/services/ldap/openldap_server/service_slapd_disabled/rule.yml b/linux_os/guide/services/ldap/openldap_server/service_slapd_disabled/rule.yml index af9de4746320..bc63db664410 100644 --- a/linux_os/guide/services/ldap/openldap_server/service_slapd_disabled/rule.yml +++ b/linux_os/guide/services/ldap/openldap_server/service_slapd_disabled/rule.yml @@ -30,4 +30,5 @@ template: vars: servicename: slapd packagename: openldap-servers + packagename@debian13: slapd packagename@ubuntu2404: slapd diff --git a/linux_os/guide/services/nfs_and_rpc/nfs_configuring_clients/disabling_nfsd/service_nfs_disabled/rule.yml b/linux_os/guide/services/nfs_and_rpc/nfs_configuring_clients/disabling_nfsd/service_nfs_disabled/rule.yml index 0fb7af297083..17c38a189721 100644 --- a/linux_os/guide/services/nfs_and_rpc/nfs_configuring_clients/disabling_nfsd/service_nfs_disabled/rule.yml +++ b/linux_os/guide/services/nfs_and_rpc/nfs_configuring_clients/disabling_nfsd/service_nfs_disabled/rule.yml @@ -44,5 +44,6 @@ template: vars: servicename: nfs-server packagename: nfs-utils + packagename@debian13: nfs-kernel-server packagename@ubuntu2404: nfs-kernel-server packagename@sle15: nfs-kernel-server diff --git a/linux_os/guide/services/obsolete/service_rsyncd_disabled/rule.yml b/linux_os/guide/services/obsolete/service_rsyncd_disabled/rule.yml index d4ed1fb801e0..fe7b621c885f 100644 --- a/linux_os/guide/services/obsolete/service_rsyncd_disabled/rule.yml +++ b/linux_os/guide/services/obsolete/service_rsyncd_disabled/rule.yml @@ -38,6 +38,8 @@ template: vars: servicename: rsyncd packagename: rsync-daemon + packagename@debian13: rsync + servicename@debian13: rsync packagename@ol7: rsync packagename@sle12: rsync packagename@sle15: rsync diff --git a/linux_os/guide/services/obsolete/tftp/package_tftp-server_removed/rule.yml b/linux_os/guide/services/obsolete/tftp/package_tftp-server_removed/rule.yml index 1aa283f3983a..7b33fb6a2452 100644 --- a/linux_os/guide/services/obsolete/tftp/package_tftp-server_removed/rule.yml +++ b/linux_os/guide/services/obsolete/tftp/package_tftp-server_removed/rule.yml @@ -1,4 +1,4 @@ -{{% if 'ubuntu' in product %}} +{{% if 'ubuntu' in product or 'debian' in product %}} {{%- set package = "tftpd-hpa" %}} {{% elif 'sle' in product %}} {{%- set package = "tftp" %}} diff --git a/linux_os/guide/services/obsolete/tftp/service_tftp_disabled/rule.yml b/linux_os/guide/services/obsolete/tftp/service_tftp_disabled/rule.yml index 510779e396e9..771275d4d102 100644 --- a/linux_os/guide/services/obsolete/tftp/service_tftp_disabled/rule.yml +++ b/linux_os/guide/services/obsolete/tftp/service_tftp_disabled/rule.yml @@ -1,6 +1,6 @@ documentation_complete: true -{{% if 'ubuntu' in product %}} +{{% if 'ubuntu' in product or 'debian' in product %}} {{%- set service_name = "tftpd-hpa" %}} {{%- set package = "tftpd-hpa" %}} {{% elif 'sle' in product or product == "slmicro5" %}} diff --git a/linux_os/guide/services/smb/disabling_samba/service_smb_disabled/rule.yml b/linux_os/guide/services/smb/disabling_samba/service_smb_disabled/rule.yml index 1043e53b6d29..ea0cbf6135eb 100644 --- a/linux_os/guide/services/smb/disabling_samba/service_smb_disabled/rule.yml +++ b/linux_os/guide/services/smb/disabling_samba/service_smb_disabled/rule.yml @@ -34,6 +34,7 @@ template: name: service_disabled vars: servicename: smb + servicename@debian13: smbd servicename@ubuntu2204: smbd servicename@ubuntu2404: smbd packagename: samba diff --git a/linux_os/guide/services/snmp/disabling_snmp_service/package_net-snmp_removed/rule.yml b/linux_os/guide/services/snmp/disabling_snmp_service/package_net-snmp_removed/rule.yml index 3d86a465a82e..5fcb1b044831 100644 --- a/linux_os/guide/services/snmp/disabling_snmp_service/package_net-snmp_removed/rule.yml +++ b/linux_os/guide/services/snmp/disabling_snmp_service/package_net-snmp_removed/rule.yml @@ -43,5 +43,6 @@ template: vars: pkgname: net-snmp pkgname@debian11: snmp + pkgname@debian13: snmpd pkgname@ubuntu2204: snmp pkgname@ubuntu2404: snmpd diff --git a/linux_os/guide/services/snmp/disabling_snmp_service/service_snmpd_disabled/rule.yml b/linux_os/guide/services/snmp/disabling_snmp_service/service_snmpd_disabled/rule.yml index 0453930173d0..8fea1564215f 100644 --- a/linux_os/guide/services/snmp/disabling_snmp_service/service_snmpd_disabled/rule.yml +++ b/linux_os/guide/services/snmp/disabling_snmp_service/service_snmpd_disabled/rule.yml @@ -38,5 +38,6 @@ template: servicename: snmpd packagename@debian11: snmpd packagename@debian12: snmpd + packagename@debian13: snmpd packagename@ubuntu2404: snmpd packagename: net-snmp diff --git a/linux_os/guide/services/xwindows/disabling_xwindows/package_xorg-x11-server-common_removed/rule.yml b/linux_os/guide/services/xwindows/disabling_xwindows/package_xorg-x11-server-common_removed/rule.yml index 0c29abce28b6..1635b31334c3 100644 --- a/linux_os/guide/services/xwindows/disabling_xwindows/package_xorg-x11-server-common_removed/rule.yml +++ b/linux_os/guide/services/xwindows/disabling_xwindows/package_xorg-x11-server-common_removed/rule.yml @@ -60,5 +60,6 @@ template: name: package_removed vars: pkgname: xorg-x11-server-common + pkgname@debian13: xserver-common pkgname@ubuntu2204: xserver-common pkgname@ubuntu2404: xserver-common From 56f6a66dce7f1183b77baad5f363e4344ad9dca4 Mon Sep 17 00:00:00 2001 From: Israel Villar Boillos Date: Tue, 26 May 2026 22:21:33 +0100 Subject: [PATCH 28/61] Add debian13 package name override for rsh rule On Debian 13 the rsh client package is rsh-client, not rsh. Add pkgname@debian13 override and update Jinja conditionals to match the same pattern used for Ubuntu. Co-Authored-By: Claude Sonnet 4.6 --- .../obsolete/r_services/package_rsh_removed/rule.yml | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/linux_os/guide/services/obsolete/r_services/package_rsh_removed/rule.yml b/linux_os/guide/services/obsolete/r_services/package_rsh_removed/rule.yml index 8b8cc34064e4..269e1acba30f 100644 --- a/linux_os/guide/services/obsolete/r_services/package_rsh_removed/rule.yml +++ b/linux_os/guide/services/obsolete/r_services/package_rsh_removed/rule.yml @@ -4,7 +4,7 @@ documentation_complete: true title: 'Uninstall rsh Package' description: |- - {{% if 'ubuntu' not in product %}} + {{% if 'ubuntu' not in product and 'debian' not in product %}} The rsh package contains the client commands {{% else %}} The rsh-client package contains the client commands @@ -16,7 +16,7 @@ rationale: |- been replaced with the more secure SSH package. Even if the server is removed, it is best to ensure the clients are also removed to prevent users from inadvertently attempting to use these commands and therefore exposing - {{% if 'ubuntu' not in product %}} + {{% if 'ubuntu' not in product and 'debian' not in product %}} their credentials. Note that removing the rsh package removes {{% else %}} their credentials. Note that removing the rsh-client package removes @@ -40,7 +40,7 @@ references: hipaa: 164.308(a)(4)(i),164.308(b)(1),164.308(b)(3),164.310(b),164.312(e)(1),164.312(e)(2)(ii) iso27001-2013: A.8.2.3,A.13.1.1,A.13.2.1,A.13.2.3,A.14.1.2,A.14.1.3 -{{% if 'ubuntu' not in product %}} +{{% if 'ubuntu' not in product and 'debian' not in product %}} ocil: '{{{ describe_package_remove(package="rsh") }}}' {{% else %}} ocil: '{{{ describe_package_remove(package="rsh-client") }}}' @@ -50,6 +50,7 @@ template: name: package_removed vars: pkgname: rsh + pkgname@debian13: rsh-client pkgname@ubuntu2204: rsh-client pkgname@ubuntu2404: rsh-client From 9548f6f8845b35e72a43aabb2d42f2f8cd66a1e1 Mon Sep 17 00:00:00 2001 From: Israel Villar Boillos Date: Tue, 26 May 2026 22:24:42 +0100 Subject: [PATCH 29/61] Add debian13 service name override for chronyd_disabled rule On Debian 13 the chrony service is named chrony, not chronyd. The enabled counterpart already had this override; add it to the disabled rule for consistency. Co-Authored-By: Claude Sonnet 4.6 --- linux_os/guide/services/ntp/service_chronyd_disabled/rule.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/linux_os/guide/services/ntp/service_chronyd_disabled/rule.yml b/linux_os/guide/services/ntp/service_chronyd_disabled/rule.yml index 1f12127a45a1..ae20cc58f8cd 100644 --- a/linux_os/guide/services/ntp/service_chronyd_disabled/rule.yml +++ b/linux_os/guide/services/ntp/service_chronyd_disabled/rule.yml @@ -27,6 +27,7 @@ template: vars: packagename: chrony servicename: chronyd - servicename@ubuntu2204: chrony servicename@debian12: chrony + servicename@debian13: chrony + servicename@ubuntu2204: chrony {{%- endif %}} From 1ea773cfac69bb50e487d78437da52f2a6e00c1a Mon Sep 17 00:00:00 2001 From: Israel Villar Boillos Date: Tue, 26 May 2026 22:29:53 +0100 Subject: [PATCH 30/61] Add debian13 package name override for gdm rule On Debian 13 the GDM package is gdm3, not gdm. Add pkgname@debian13 override and update Jinja conditionals to match the same pattern used for Ubuntu. Co-Authored-By: Claude Sonnet 4.6 --- .../system/software/gnome/package_gdm_removed/rule.yml | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/linux_os/guide/system/software/gnome/package_gdm_removed/rule.yml b/linux_os/guide/system/software/gnome/package_gdm_removed/rule.yml index 2e453c22b4f8..2654ff448e53 100644 --- a/linux_os/guide/system/software/gnome/package_gdm_removed/rule.yml +++ b/linux_os/guide/system/software/gnome/package_gdm_removed/rule.yml @@ -4,7 +4,7 @@ documentation_complete: true title: 'Remove the GDM Package Group' description: |- - {{% if 'ubuntu' not in product %}} + {{% if 'ubuntu' not in product and 'debian' not in product %}} By removing the gdm package, the system no longer has GNOME installed. {{% else %}} By removing the gdm3 package, the system no longer has GNOME installed. @@ -12,7 +12,7 @@ description: |- If X Windows is not installed then the system cannot boot into graphical user mode. This prevents the system from being accidentally or maliciously booted into a graphical.target mode. To do so, run the following command: - {{% if 'ubuntu' not in product %}} + {{% if 'ubuntu' not in product and 'debian' not in product %}}
    $ sudo yum remove gdm
    {{% else %}}
    $ sudo apt remove gdm3
    @@ -38,7 +38,7 @@ references: nist: CM-7(a),CM-7(b),CM-6(a) srg: SRG-OS-000480-GPOS-00227 -{{% if 'ubuntu' not in product %}} +{{% if 'ubuntu' not in product and 'debian' not in product %}} ocil_clause: 'gdm has not been removed' ocil: |- @@ -66,5 +66,6 @@ template: name: package_removed vars: pkgname: gdm + pkgname@debian13: gdm3 pkgname@ubuntu2204: gdm3 pkgname@ubuntu2404: gdm3 From 4efd733df98826b6f79415ddc71a36504f2611c6 Mon Sep 17 00:00:00 2001 From: Israel Villar Boillos Date: Tue, 26 May 2026 22:48:32 +0100 Subject: [PATCH 31/61] Extend guard_var template to Debian for timesyncd/chronyd disabled rules On Debian, service_timesyncd_disabled and service_chronyd_disabled were using the plain service_disabled template, which always checks that the service is inactive regardless of var_timesync_service. This caused a false failure when var_timesync_service=systemd-timesyncd and timesyncd was legitimately the active time sync daemon. Co-Authored-By: Claude Sonnet 4.6 --- .../guide/services/ntp/service_chronyd_disabled/rule.yml | 5 +---- .../guide/services/ntp/service_timesyncd_disabled/rule.yml | 2 +- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/linux_os/guide/services/ntp/service_chronyd_disabled/rule.yml b/linux_os/guide/services/ntp/service_chronyd_disabled/rule.yml index ae20cc58f8cd..8e88e19d2fad 100644 --- a/linux_os/guide/services/ntp/service_chronyd_disabled/rule.yml +++ b/linux_os/guide/services/ntp/service_chronyd_disabled/rule.yml @@ -13,7 +13,7 @@ severity: medium platform: package[chrony] -{{%- if 'ubuntu' in product %}} +{{%- if 'ubuntu' in product or 'debian' in product %}} template: name: service_disabled_guard_var vars: @@ -27,7 +27,4 @@ template: vars: packagename: chrony servicename: chronyd - servicename@debian12: chrony - servicename@debian13: chrony - servicename@ubuntu2204: chrony {{%- endif %}} diff --git a/linux_os/guide/services/ntp/service_timesyncd_disabled/rule.yml b/linux_os/guide/services/ntp/service_timesyncd_disabled/rule.yml index 7b0676b077ce..b6a0845d4dbe 100644 --- a/linux_os/guide/services/ntp/service_timesyncd_disabled/rule.yml +++ b/linux_os/guide/services/ntp/service_timesyncd_disabled/rule.yml @@ -17,7 +17,7 @@ severity: medium platform: package[systemd-timesyncd] -{{%- if 'ubuntu' in product %}} +{{%- if 'ubuntu' in product or 'debian' in product %}} template: name: service_disabled_guard_var vars: From cd1240b2eafeef43e88765c19c9b49b4271ff5a0 Mon Sep 17 00:00:00 2001 From: Israel Villar Boillos Date: Tue, 26 May 2026 22:58:11 +0100 Subject: [PATCH 32/61] Add fallback to remove nullok directly from PAM common-* files When pam-auth-update is blocked by local modifications to /etc/pam.d/common-*, the existing fix updated the pam-configs source but left nullok in the actual files. The fallback sed loop ensures nullok is removed regardless. Co-Authored-By: Claude Sonnet 4.6 --- .../no_empty_passwords_unix/bash/shared.sh | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/linux_os/guide/system/accounts/accounts-restrictions/password_storage/no_empty_passwords_unix/bash/shared.sh b/linux_os/guide/system/accounts/accounts-restrictions/password_storage/no_empty_passwords_unix/bash/shared.sh index 39767a05643b..d85a76cd1567 100644 --- a/linux_os/guide/system/accounts/accounts-restrictions/password_storage/no_empty_passwords_unix/bash/shared.sh +++ b/linux_os/guide/system/accounts/accounts-restrictions/password_storage/no_empty_passwords_unix/bash/shared.sh @@ -9,3 +9,11 @@ config_file="/usr/share/pam-configs/cac_unix" sed -i '/pam_unix\.so/s/nullok//g' "$config_file" DEBIAN_FRONTEND=noninteractive pam-auth-update + +# Fallback: remove nullok directly in case pam-auth-update was blocked +# by local modifications to /etc/pam.d/common-* +for pam_file in /etc/pam.d/common-password /etc/pam.d/common-auth \ + /etc/pam.d/common-account /etc/pam.d/common-session \ + /etc/pam.d/common-session-noninteractive; do + [ -f "$pam_file" ] && sed -i '/pam_unix\.so/s/\bnullok\b//g' "$pam_file" +done From 623eeea40a59e338602843b970e99e1c8e21474c Mon Sep 17 00:00:00 2001 From: Israel Villar Boillos Date: Tue, 26 May 2026 23:22:20 +0100 Subject: [PATCH 33/61] Switch ULPGC profile to chrony and fix Debian chrony rules CIS Debian 13 Benchmark (p.336) states: "If systemd-timesyncd is being used, chrony should be removed and this section skipped." The ULPGC profile is switched to chrony (var_timesync_service=chronyd) and the 2.3.2.x timesyncd-config rule is excluded. Additionally: - service_disabled_guard_var bash.template: add multi_platform_debian so a bash fix is generated for service_chronyd_disabled on Debian - chronyd_run_as_chrony_user OVAL: extend Ubuntu branch to Debian so the check uses /etc/chrony/chrony.conf (user _chrony) instead of the non-existent /etc/sysconfig/chronyd - chronyd_run_as_chrony_user bash: add debian.sh fix that sets user _chrony in /etc/chrony/chrony.conf Co-Authored-By: Claude Sonnet 4.6 --- .../services/ntp/chronyd_run_as_chrony_user/bash/debian.sh | 3 +++ .../services/ntp/chronyd_run_as_chrony_user/oval/shared.xml | 2 +- products/debian13/profiles/cis_level1_server_ulpgc.profile | 6 ++++++ shared/templates/service_disabled_guard_var/bash.template | 2 +- 4 files changed, 11 insertions(+), 2 deletions(-) create mode 100644 linux_os/guide/services/ntp/chronyd_run_as_chrony_user/bash/debian.sh diff --git a/linux_os/guide/services/ntp/chronyd_run_as_chrony_user/bash/debian.sh b/linux_os/guide/services/ntp/chronyd_run_as_chrony_user/bash/debian.sh new file mode 100644 index 000000000000..84f0c626d920 --- /dev/null +++ b/linux_os/guide/services/ntp/chronyd_run_as_chrony_user/bash/debian.sh @@ -0,0 +1,3 @@ +# platform = multi_platform_debian + +{{{ bash_replace_or_append(chrony_conf_path, '^user', '_chrony', '%s %s', cce_identifiers=cce_identifiers) }}} diff --git a/linux_os/guide/services/ntp/chronyd_run_as_chrony_user/oval/shared.xml b/linux_os/guide/services/ntp/chronyd_run_as_chrony_user/oval/shared.xml index 88b20cd2f9b0..ff4295d60ca3 100644 --- a/linux_os/guide/services/ntp/chronyd_run_as_chrony_user/oval/shared.xml +++ b/linux_os/guide/services/ntp/chronyd_run_as_chrony_user/oval/shared.xml @@ -29,7 +29,7 @@ -{{%- elif 'ubuntu' in product -%}} +{{%- elif 'ubuntu' in product or 'debian' in product -%}} {{{ oval_check_config_file(path='/etc/chrony/chrony.conf', prefix_regex='^[ \\t]*', parameter='user', separator_regex='[[:space:]]', value='_chrony', missing_parameter_pass=true, missing_config_file_fail=false, rule_id=rule_id, rule_title=rule_title) }}} {{%- else -%}} {{{ oval_check_config_file(path='/etc/sysconfig/chronyd', prefix_regex='^[ \\t]*', parameter='OPTIONS', separator_regex='=', value='["]?.*-u[\s]*chrony.*["]?', missing_parameter_pass=ok_by_default, missing_config_file_fail=true, rule_id=rule_id, rule_title=rule_title) }}} diff --git a/products/debian13/profiles/cis_level1_server_ulpgc.profile b/products/debian13/profiles/cis_level1_server_ulpgc.profile index cc31f27e4c8e..fe31a873eaa2 100644 --- a/products/debian13/profiles/cis_level1_server_ulpgc.profile +++ b/products/debian13/profiles/cis_level1_server_ulpgc.profile @@ -14,3 +14,9 @@ selections: - '!package_aide_installed' - '!aide_build_database' - '!aide_periodic_checking_systemd_timer' + # Sincronización horaria: usar chrony en lugar de systemd-timesyncd + # Según CIS 2.3.3: "If systemd-timesyncd is being used, chrony should be removed + # and this section skipped". El perfil usa chrony, por tanto se excluyen los + # controles 2.3.2.x (configuración de systemd-timesyncd). + - var_timesync_service=chronyd + - '!service_timesyncd_configured' diff --git a/shared/templates/service_disabled_guard_var/bash.template b/shared/templates/service_disabled_guard_var/bash.template index 0afd3332d867..38535e386905 100644 --- a/shared/templates/service_disabled_guard_var/bash.template +++ b/shared/templates/service_disabled_guard_var/bash.template @@ -1,4 +1,4 @@ -# platform = multi_platform_rhel,multi_platform_fedora,multi_platform_ol,multi_platform_rhv,multi_platform_sle,multi_platform_ubuntu +# platform = multi_platform_rhel,multi_platform_fedora,multi_platform_ol,multi_platform_rhv,multi_platform_sle,multi_platform_ubuntu,multi_platform_debian # reboot = false # strategy = disable # complexity = low From 6074f81c0895baf33b7d11fdee24b4d613c4c2de Mon Sep 17 00:00:00 2001 From: Israel Villar Boillos Date: Thu, 28 May 2026 07:35:13 +0100 Subject: [PATCH 34/61] Fix chrony/timesyncd rules for Debian and update ULPGC profile - Extend package_timesyncd_installed guard_var to Debian (was Ubuntu-only) - Change service_timesyncd_configured platform to package[systemd-timesyncd] so it becomes inapplicable when timesyncd is not installed - Fix chronyd_configure_pool_and_server OVAL and Ansible patterns to allow chrony options (e.g. iburst) after pool/server addresses - Add test scenarios for pool/server entries with options - Update ULPGC profile: remove now-unnecessary explicit exclusions and set var_multiple_time_servers/pools to pool.ntp.ulpgc.es Co-Authored-By: Claude Sonnet 4.6 --- .../chronyd_configure_pool_and_server/ansible/shared.yml | 4 ++-- .../chronyd_configure_pool_and_server/oval/shared.xml | 4 ++-- .../tests/pool_with_options.pass.sh | 6 ++++++ .../tests/server_with_options.pass.sh | 6 ++++++ .../services/ntp/package_timesyncd_installed/rule.yml | 2 +- .../services/ntp/service_timesyncd_configured/rule.yml | 2 +- .../debian13/profiles/cis_level1_server_ulpgc.profile | 9 ++++----- 7 files changed, 22 insertions(+), 11 deletions(-) create mode 100644 linux_os/guide/services/ntp/chronyd_configure_pool_and_server/tests/pool_with_options.pass.sh create mode 100644 linux_os/guide/services/ntp/chronyd_configure_pool_and_server/tests/server_with_options.pass.sh diff --git a/linux_os/guide/services/ntp/chronyd_configure_pool_and_server/ansible/shared.yml b/linux_os/guide/services/ntp/chronyd_configure_pool_and_server/ansible/shared.yml index 54f7f2e53b9d..3b925a5a1632 100644 --- a/linux_os/guide/services/ntp/chronyd_configure_pool_and_server/ansible/shared.yml +++ b/linux_os/guide/services/ntp/chronyd_configure_pool_and_server/ansible/shared.yml @@ -9,7 +9,7 @@ - name: {{{ rule_title }}} - Add missing / update wrong records for remote time servers ansible.builtin.lineinfile: path: {{{ chrony_conf_path }}} - regexp: '^\s*\bserver\b\s*\b{{ item }}\b$' + regexp: '^\s*\bserver\b\s*\b{{ item }}\b' state: present line: 'server {{ item }}' create: true @@ -19,7 +19,7 @@ - name: {{{ rule_title }}} - Add missing / update wrong records for remote time pools ansible.builtin.lineinfile: path: {{{ chrony_conf_path }}} - regexp: '^\s*\bpool\b\s*\b{{ item }}\b$' + regexp: '^\s*\bpool\b\s*\b{{ item }}\b' state: present line: 'pool {{ item }}' create: true diff --git a/linux_os/guide/services/ntp/chronyd_configure_pool_and_server/oval/shared.xml b/linux_os/guide/services/ntp/chronyd_configure_pool_and_server/oval/shared.xml index 46caf86dd361..6512a93ae74d 100644 --- a/linux_os/guide/services/ntp/chronyd_configure_pool_and_server/oval/shared.xml +++ b/linux_os/guide/services/ntp/chronyd_configure_pool_and_server/oval/shared.xml @@ -16,7 +16,7 @@ - $ + ([[:space:]].*)?$ @@ -29,7 +29,7 @@ - $ + ([[:space:]].*)?$ diff --git a/linux_os/guide/services/ntp/chronyd_configure_pool_and_server/tests/pool_with_options.pass.sh b/linux_os/guide/services/ntp/chronyd_configure_pool_and_server/tests/pool_with_options.pass.sh new file mode 100644 index 000000000000..0f455decb98f --- /dev/null +++ b/linux_os/guide/services/ntp/chronyd_configure_pool_and_server/tests/pool_with_options.pass.sh @@ -0,0 +1,6 @@ +#!/bin/bash +# packages = chrony +# variables = var_multiple_time_servers=0.debian.pool.ntp.org,1.debian.pool.ntp.org,2.debian.pool.ntp.org,3.debian.pool.ntp.org,var_multiple_time_pools=0.debian.pool.ntp.org,1.debian.pool.ntp.org,2.debian.pool.ntp.org,3.debian.pool.ntp.org + +echo "" > {{{ chrony_conf_path }}} +echo "pool 2.debian.pool.ntp.org iburst" >> {{{ chrony_conf_path }}} diff --git a/linux_os/guide/services/ntp/chronyd_configure_pool_and_server/tests/server_with_options.pass.sh b/linux_os/guide/services/ntp/chronyd_configure_pool_and_server/tests/server_with_options.pass.sh new file mode 100644 index 000000000000..9a3729eadd8b --- /dev/null +++ b/linux_os/guide/services/ntp/chronyd_configure_pool_and_server/tests/server_with_options.pass.sh @@ -0,0 +1,6 @@ +#!/bin/bash +# packages = chrony +# variables = var_multiple_time_servers=0.debian.pool.ntp.org,1.debian.pool.ntp.org,2.debian.pool.ntp.org,3.debian.pool.ntp.org,var_multiple_time_pools=0.debian.pool.ntp.org,1.debian.pool.ntp.org,2.debian.pool.ntp.org,3.debian.pool.ntp.org + +echo "" > {{{ chrony_conf_path }}} +echo "server 2.debian.pool.ntp.org iburst maxpoll 10" >> {{{ chrony_conf_path }}} diff --git a/linux_os/guide/services/ntp/package_timesyncd_installed/rule.yml b/linux_os/guide/services/ntp/package_timesyncd_installed/rule.yml index a1546145887b..fd82653ed4a6 100644 --- a/linux_os/guide/services/ntp/package_timesyncd_installed/rule.yml +++ b/linux_os/guide/services/ntp/package_timesyncd_installed/rule.yml @@ -19,7 +19,7 @@ references: nist-csf: PR.PT-1 pcidss: Req-10.4 -{{%- if 'ubuntu' in product %}} +{{%- if 'ubuntu' in product or 'debian' in product %}} template: name: package_installed_guard_var vars: diff --git a/linux_os/guide/services/ntp/service_timesyncd_configured/rule.yml b/linux_os/guide/services/ntp/service_timesyncd_configured/rule.yml index 3b9c304b952d..4188ef4bf010 100644 --- a/linux_os/guide/services/ntp/service_timesyncd_configured/rule.yml +++ b/linux_os/guide/services/ntp/service_timesyncd_configured/rule.yml @@ -19,7 +19,7 @@ rationale: |- severity: medium -platform: package[systemd] +platform: package[systemd-timesyncd] identifiers: cce@sle12: CCE-92374-8 diff --git a/products/debian13/profiles/cis_level1_server_ulpgc.profile b/products/debian13/profiles/cis_level1_server_ulpgc.profile index fe31a873eaa2..4d138b30218b 100644 --- a/products/debian13/profiles/cis_level1_server_ulpgc.profile +++ b/products/debian13/profiles/cis_level1_server_ulpgc.profile @@ -14,9 +14,8 @@ selections: - '!package_aide_installed' - '!aide_build_database' - '!aide_periodic_checking_systemd_timer' - # Sincronización horaria: usar chrony en lugar de systemd-timesyncd - # Según CIS 2.3.3: "If systemd-timesyncd is being used, chrony should be removed - # and this section skipped". El perfil usa chrony, por tanto se excluyen los - # controles 2.3.2.x (configuración de systemd-timesyncd). + # Sincronización horaria: usar chrony. Las reglas de systemd-timesyncd quedan + # automáticamente inaplicables gracias a los guards de var_timesync_service. - var_timesync_service=chronyd - - '!service_timesyncd_configured' + - var_multiple_time_servers=pool.ntp.ulpgc.es + - var_multiple_time_pools=pool.ntp.ulpgc.es From 18c9fc1387c7df70ce9812aef9bab799bce0d778 Mon Sep 17 00:00:00 2001 From: Israel Villar Boillos Date: Thu, 28 May 2026 07:40:19 +0100 Subject: [PATCH 35/61] Add ulpgc NTP option and fix profile variable syntax Literal URLs with dots in profile selections cause a parse error in apply_selection (dots are mistaken for rule refinement syntax). Add a named option 'ulpgc' to var_multiple_time_servers and var_multiple_time_pools, and update the ULPGC profile to reference it instead of the raw URL. Co-Authored-By: Claude Sonnet 4.6 --- linux_os/guide/services/ntp/var_multiple_time_pools.var | 1 + linux_os/guide/services/ntp/var_multiple_time_servers.var | 1 + products/debian13/profiles/cis_level1_server_ulpgc.profile | 4 ++-- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/linux_os/guide/services/ntp/var_multiple_time_pools.var b/linux_os/guide/services/ntp/var_multiple_time_pools.var index 17e2f18c976a..b28ce40d6cf8 100644 --- a/linux_os/guide/services/ntp/var_multiple_time_pools.var +++ b/linux_os/guide/services/ntp/var_multiple_time_pools.var @@ -19,3 +19,4 @@ options: ubuntu: "0.ubuntu.pool.ntp.org,1.ubuntu.pool.ntp.org,2.ubuntu.pool.ntp.org,3.ubuntu.pool.ntp.org" debian: "0.debian.pool.ntp.org,1.debian.pool.ntp.org,2.debian.pool.ntp.org,3.debian.pool.ntp.org" nist: "time.nist.gov" + ulpgc: "pool.ntp.ulpgc.es" diff --git a/linux_os/guide/services/ntp/var_multiple_time_servers.var b/linux_os/guide/services/ntp/var_multiple_time_servers.var index 4ecfd28488b0..9ee263f1d09f 100644 --- a/linux_os/guide/services/ntp/var_multiple_time_servers.var +++ b/linux_os/guide/services/ntp/var_multiple_time_servers.var @@ -22,3 +22,4 @@ options: almalinux: "0.almalinux.pool.ntp.org,1.almalinux.pool.ntp.org,2.almalinux.pool.ntp.org,3.almalinux.pool.ntp.org" debian: "0.debian.pool.ntp.org,1.debian.pool.ntp.org,2.debian.pool.ntp.org,3.debian.pool.ntp.org" nist: "time.nist.gov,time-a-g.nist.gov,time-b-g.nist.gov,time-c-g.nist.gov" + ulpgc: "pool.ntp.ulpgc.es" diff --git a/products/debian13/profiles/cis_level1_server_ulpgc.profile b/products/debian13/profiles/cis_level1_server_ulpgc.profile index 4d138b30218b..00808c874909 100644 --- a/products/debian13/profiles/cis_level1_server_ulpgc.profile +++ b/products/debian13/profiles/cis_level1_server_ulpgc.profile @@ -17,5 +17,5 @@ selections: # Sincronización horaria: usar chrony. Las reglas de systemd-timesyncd quedan # automáticamente inaplicables gracias a los guards de var_timesync_service. - var_timesync_service=chronyd - - var_multiple_time_servers=pool.ntp.ulpgc.es - - var_multiple_time_pools=pool.ntp.ulpgc.es + - var_multiple_time_servers=ulpgc + - var_multiple_time_pools=ulpgc From c03fad8027f97b403e01a80d44eac8a43f9681a6 Mon Sep 17 00:00:00 2001 From: Israel Villar Boillos Date: Thu, 28 May 2026 23:03:01 +0100 Subject: [PATCH 36/61] Add syslog-ng rules and switch ULPGC profile from rsyslog to syslog-ng - Create linux_os/guide/system/logging/syslogng/ group with its own group.yml, mirroring the structure of rsyslog and journald groups - Move package_syslogng_installed and service_syslogng_enabled from rsyslog_accepting_remote_messages/ into the new syslogng/ group - Add syslogng_filecreatemode rule (OVAL + bash): checks and sets perm(0640) in syslog-ng global options block - Add syslogng_accepting_remote_messages subgroup with syslogng_nolisten rule (OVAL + bash): verifies no tcp/udp/network source drivers are active, parallel to rsyslog_nolisten - Extend logging_services_active OVAL and description to recognise syslog-ng as a valid logging service alongside rsyslog and journald - Update cis_level1_server_ulpgc.profile: exclude journald-standalone rules (6.1.1.1.4, 6.1.1.2.x), replace rsyslog rules with syslog-ng equivalents for CIS 6.1.2 controls Co-Authored-By: Claude Sonnet 4.6 --- .../logging_services_active/oval/shared.xml | 2 +- .../logging/logging_services_active/rule.yml | 2 +- .../guide/system/logging/syslogng/group.yml | 11 ++++ .../package_syslogng_installed/rule.yml | 0 .../service_syslogng_enabled/rule.yml | 0 .../group.yml | 13 ++++ .../syslogng_nolisten/bash/shared.sh | 21 +++++++ .../syslogng_nolisten/oval/shared.xml | 49 +++++++++++++++ .../syslogng_nolisten/rule.yml | 40 ++++++++++++ .../syslogng_filecreatemode/bash/shared.sh | 14 +++++ .../syslogng_filecreatemode/oval/shared.xml | 62 +++++++++++++++++++ .../syslogng/syslogng_filecreatemode/rule.yml | 34 ++++++++++ .../profiles/cis_level1_server_ulpgc.profile | 15 +++++ 13 files changed, 261 insertions(+), 2 deletions(-) create mode 100644 linux_os/guide/system/logging/syslogng/group.yml rename linux_os/guide/system/logging/{rsyslog_accepting_remote_messages => syslogng}/package_syslogng_installed/rule.yml (100%) rename linux_os/guide/system/logging/{rsyslog_accepting_remote_messages => syslogng}/service_syslogng_enabled/rule.yml (100%) create mode 100644 linux_os/guide/system/logging/syslogng/syslogng_accepting_remote_messages/group.yml create mode 100644 linux_os/guide/system/logging/syslogng/syslogng_accepting_remote_messages/syslogng_nolisten/bash/shared.sh create mode 100644 linux_os/guide/system/logging/syslogng/syslogng_accepting_remote_messages/syslogng_nolisten/oval/shared.xml create mode 100644 linux_os/guide/system/logging/syslogng/syslogng_accepting_remote_messages/syslogng_nolisten/rule.yml create mode 100644 linux_os/guide/system/logging/syslogng/syslogng_filecreatemode/bash/shared.sh create mode 100644 linux_os/guide/system/logging/syslogng/syslogng_filecreatemode/oval/shared.xml create mode 100644 linux_os/guide/system/logging/syslogng/syslogng_filecreatemode/rule.yml diff --git a/linux_os/guide/system/logging/logging_services_active/oval/shared.xml b/linux_os/guide/system/logging/logging_services_active/oval/shared.xml index ed5653530e3f..8738f59ffb97 100644 --- a/linux_os/guide/system/logging/logging_services_active/oval/shared.xml +++ b/linux_os/guide/system/logging/logging_services_active/oval/shared.xml @@ -11,7 +11,7 @@ - ^(rsyslog|systemd-journald).service$ + ^(rsyslog|syslog-ng|systemd-journald).service$ ActiveState ste_{{{ rule_id }}}_logging_services diff --git a/linux_os/guide/system/logging/logging_services_active/rule.yml b/linux_os/guide/system/logging/logging_services_active/rule.yml index 2ccd6666d100..c3a5c3f8cb4c 100644 --- a/linux_os/guide/system/logging/logging_services_active/rule.yml +++ b/linux_os/guide/system/logging/logging_services_active/rule.yml @@ -5,7 +5,7 @@ title: 'Ensure One Logging Service Is In Use' description: |- Ensure that a logging system is active and in use.
    -    systemctl is-active rsyslog systemd-journald
    +    systemctl is-active rsyslog syslog-ng systemd-journald
         
    The command should return at least one active. diff --git a/linux_os/guide/system/logging/syslogng/group.yml b/linux_os/guide/system/logging/syslogng/group.yml new file mode 100644 index 000000000000..13f0b74090fb --- /dev/null +++ b/linux_os/guide/system/logging/syslogng/group.yml @@ -0,0 +1,11 @@ +documentation_complete: true + +title: 'Configure syslog-ng' + +description: |- + syslog-ng is an enhanced syslog daemon that can be used as a replacement + for rsyslog. It provides advanced log routing, filtering, and forwarding + capabilities, including reliable and encrypted transport of log messages. + This section discusses how to configure syslog-ng for best effect. + +platform: system_with_kernel diff --git a/linux_os/guide/system/logging/rsyslog_accepting_remote_messages/package_syslogng_installed/rule.yml b/linux_os/guide/system/logging/syslogng/package_syslogng_installed/rule.yml similarity index 100% rename from linux_os/guide/system/logging/rsyslog_accepting_remote_messages/package_syslogng_installed/rule.yml rename to linux_os/guide/system/logging/syslogng/package_syslogng_installed/rule.yml diff --git a/linux_os/guide/system/logging/rsyslog_accepting_remote_messages/service_syslogng_enabled/rule.yml b/linux_os/guide/system/logging/syslogng/service_syslogng_enabled/rule.yml similarity index 100% rename from linux_os/guide/system/logging/rsyslog_accepting_remote_messages/service_syslogng_enabled/rule.yml rename to linux_os/guide/system/logging/syslogng/service_syslogng_enabled/rule.yml diff --git a/linux_os/guide/system/logging/syslogng/syslogng_accepting_remote_messages/group.yml b/linux_os/guide/system/logging/syslogng/syslogng_accepting_remote_messages/group.yml new file mode 100644 index 000000000000..fa63841c4309 --- /dev/null +++ b/linux_os/guide/system/logging/syslogng/syslogng_accepting_remote_messages/group.yml @@ -0,0 +1,13 @@ +documentation_complete: true + +title: 'Configure syslog-ng to Accept Remote Messages If Acting as a Log Server' + +description: |- + By default, syslog-ng does not listen over the network + for log messages. If needed, network source drivers (tcp(), + udp(), or network()) can be added to allow + the syslog-ng daemon to receive messages from other systems and for the + system thus to act as a log server. + If the system is not a log server, then such source entries should not + appear in the syslog-ng configuration files. +

    diff --git a/linux_os/guide/system/logging/syslogng/syslogng_accepting_remote_messages/syslogng_nolisten/bash/shared.sh b/linux_os/guide/system/logging/syslogng/syslogng_accepting_remote_messages/syslogng_nolisten/bash/shared.sh new file mode 100644 index 000000000000..79584a3503d7 --- /dev/null +++ b/linux_os/guide/system/logging/syslogng/syslogng_accepting_remote_messages/syslogng_nolisten/bash/shared.sh @@ -0,0 +1,21 @@ +# platform = multi_platform_all +# reboot = false +# strategy = configure +# complexity = low +# disruption = low + +network_regex='^\s*(tcp|udp|network)\(' + +readarray -t targets < <(grep -l -E -r "${network_regex}" /etc/syslog-ng/ 2>/dev/null) + +config_changed=false +if [ ${#targets[@]} -gt 0 ]; then + for target in "${targets[@]}"; do + sed -E -i "/${network_regex}/ s/^/# /" "$target" + done + config_changed=true +fi + +if $config_changed; then + systemctl restart syslog-ng.service +fi diff --git a/linux_os/guide/system/logging/syslogng/syslogng_accepting_remote_messages/syslogng_nolisten/oval/shared.xml b/linux_os/guide/system/logging/syslogng/syslogng_accepting_remote_messages/syslogng_nolisten/oval/shared.xml new file mode 100644 index 000000000000..b5704023c51d --- /dev/null +++ b/linux_os/guide/system/logging/syslogng/syslogng_accepting_remote_messages/syslogng_nolisten/oval/shared.xml @@ -0,0 +1,49 @@ + + + {{{ oval_metadata("syslog-ng should not accept remote messages unless acting as a log server", rule_title=rule_title) }}} + + + + + + + + + + + + + ^\/etc\/syslog-ng\/(syslog-ng\.conf|conf\.d\/.*\.conf)$ + ^\s*tcp\( + 1 + + + + + + + + ^\/etc\/syslog-ng\/(syslog-ng\.conf|conf\.d\/.*\.conf)$ + ^\s*udp\( + 1 + + + + + + + + ^\/etc\/syslog-ng\/(syslog-ng\.conf|conf\.d\/.*\.conf)$ + ^\s*network\( + 1 + + diff --git a/linux_os/guide/system/logging/syslogng/syslogng_accepting_remote_messages/syslogng_nolisten/rule.yml b/linux_os/guide/system/logging/syslogng/syslogng_accepting_remote_messages/syslogng_nolisten/rule.yml new file mode 100644 index 000000000000..c3e654f2dec7 --- /dev/null +++ b/linux_os/guide/system/logging/syslogng/syslogng_accepting_remote_messages/syslogng_nolisten/rule.yml @@ -0,0 +1,40 @@ +documentation_complete: true + +title: 'Ensure syslog-ng Does Not Accept Remote Messages Unless Acting As Log Server' + +description: |- + The syslog-ng daemon should not accept remote messages unless the + system acts as a log server. To ensure that it is not listening on the + network, verify that none of the following source driver calls appear + uncommented in syslog-ng configuration files: +
    tcp()
    +    udp()
    +    network()
    + +rationale: |- + Any process which receives messages from the network incurs some risk of + receiving malicious messages. This risk can be eliminated for syslog-ng by + configuring it not to listen on the network. + +severity: medium + +references: + nist: CM-7(a),CM-7(b),CM-6(a) + +ocil_clause: 'syslog-ng accepts remote messages and is not documented as a log aggregation system' + +ocil: |- + Verify that the system is not accepting syslog-ng messages from other systems + unless it is documented as a log aggregation server. + Display the contents of the syslog-ng configuration files: +
    find /etc/syslog-ng -name "*.conf" -exec cat '{}' \;
    + If any source block contains tcp(), udp(), or + network() source drivers, ask to see the documentation for the + system being used for log aggregation. + +fixtext: |- + Edit the syslog-ng configuration files under /etc/syslog-ng/ and + comment out or remove any tcp(), udp(), or + network() driver entries from source blocks. + Restart the service: +
    # systemctl restart syslog-ng.service
    diff --git a/linux_os/guide/system/logging/syslogng/syslogng_filecreatemode/bash/shared.sh b/linux_os/guide/system/logging/syslogng/syslogng_filecreatemode/bash/shared.sh new file mode 100644 index 000000000000..630558d14ba4 --- /dev/null +++ b/linux_os/guide/system/logging/syslogng/syslogng_filecreatemode/bash/shared.sh @@ -0,0 +1,14 @@ +# platform = multi_platform_all +# reboot = false +# strategy = configure +# complexity = low +# disruption = low + +# Remove any existing perm() directives to avoid duplicates +sed -i '/^\s*perm(/d' /etc/syslog-ng/syslog-ng.conf +find /etc/syslog-ng/conf.d/ -name "*.conf" -exec sed -i '/^\s*perm(/d' {} \; + +# Add perm(0640) via a drop-in options block +echo 'options { perm(0640); };' > /etc/syslog-ng/conf.d/00-syslogng_filecreatemode.conf + +systemctl restart syslog-ng.service diff --git a/linux_os/guide/system/logging/syslogng/syslogng_filecreatemode/oval/shared.xml b/linux_os/guide/system/logging/syslogng/syslogng_filecreatemode/oval/shared.xml new file mode 100644 index 000000000000..ce968b5bddd1 --- /dev/null +++ b/linux_os/guide/system/logging/syslogng/syslogng_filecreatemode/oval/shared.xml @@ -0,0 +1,62 @@ + + + {{{ oval_metadata("perm() setting controls permissions applied to newly created log files by syslog-ng.", rule_title=rule_title) }}} + + + + + + + + + + + + ^\/etc\/syslog-ng\/(syslog-ng\.conf|conf\.d\/.*\.conf)$ + perm\((\d+)\) + 1 + + + + + + + 64 + + + + + + 8 + + + + + + + + + + + + + + + + + var_syslogng_perm_dec + + + + + 416 + + diff --git a/linux_os/guide/system/logging/syslogng/syslogng_filecreatemode/rule.yml b/linux_os/guide/system/logging/syslogng/syslogng_filecreatemode/rule.yml new file mode 100644 index 000000000000..c7eac686893b --- /dev/null +++ b/linux_os/guide/system/logging/syslogng/syslogng_filecreatemode/rule.yml @@ -0,0 +1,34 @@ +documentation_complete: true + +title: 'Ensure syslog-ng Default File Permissions Configured' + +description: |- + syslog-ng will create logfiles that do not already exist on the system. + The perm() option in the global options block controls + what permissions will be applied to these newly created files. + +rationale: |- + It is important to ensure that log files have the correct permissions + to ensure that sensitive data is archived and protected. + +severity: medium + +references: + nist: CM-6(a) + +ocil_clause: 'perm() is not set or is more permissive than 0640' + +ocil: |- + Run the following command: +
    # grep -r 'perm(' /etc/syslog-ng/syslog-ng.conf /etc/syslog-ng/conf.d/
    + Verify the output contains perm(0640) or a more restrictive value + in the global options block. + +fixtext: |- + Edit /etc/syslog-ng/syslog-ng.conf or a dedicated file in + /etc/syslog-ng/conf.d/ and ensure the global options block contains: +
    options {
    +        perm(0640);
    +    };
    + Restart the service: +
    # systemctl restart syslog-ng.service
    diff --git a/products/debian13/profiles/cis_level1_server_ulpgc.profile b/products/debian13/profiles/cis_level1_server_ulpgc.profile index 00808c874909..a76b8f2e06e4 100644 --- a/products/debian13/profiles/cis_level1_server_ulpgc.profile +++ b/products/debian13/profiles/cis_level1_server_ulpgc.profile @@ -19,3 +19,18 @@ selections: - var_timesync_service=chronyd - var_multiple_time_servers=ulpgc - var_multiple_time_pools=ulpgc + # 6.1.1 (journald standalone) y 6.1.2 (syslog daemon) son excluyentes. El perfil ULPGC + # usa syslog-ng (6.1.2), por lo que se excluyen las reglas de la ruta journald-solo. + - '!journald_disable_forward_to_syslog' + - '!package_systemd-journal-remote_installed' + - '!service_systemd-journal-upload_enabled' + - '!socket_systemd-journal-remote_disabled' + # 6.1.2: sustituir rsyslog por syslog-ng + - '!package_rsyslog_installed' + - '!service_rsyslog_enabled' + - '!rsyslog_filecreatemode' + - '!rsyslog_nolisten' + - package_syslogng_installed + - service_syslogng_enabled + - syslogng_filecreatemode + - syslogng_nolisten From eb2b922b37289e659438ae8b1853ea0c2a9d5cce Mon Sep 17 00:00:00 2001 From: Israel Villar Boillos Date: Thu, 28 May 2026 23:13:13 +0100 Subject: [PATCH 37/61] Enable sysctl drop-in file remediation for Debian 13 Set sysctl_remediate_drop_in_file to true in product.yml so that bash remediations write each sysctl parameter to its own file under /etc/sysctl.d/ instead of /etc/sysctl.conf, ensuring values persist across reboots regardless of file load ordering. Co-Authored-By: Claude Sonnet 4.6 --- products/debian13/product.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/products/debian13/product.yml b/products/debian13/product.yml index a3aafa1012e2..4a1fe7f68719 100644 --- a/products/debian13/product.yml +++ b/products/debian13/product.yml @@ -17,6 +17,8 @@ pkg_manager: "apt_get" init_system: "systemd" +sysctl_remediate_drop_in_file: "true" + oval_feed_url: "https://www.debian.org/security/oval/oval-definitions-trixie.xml.bz2" chrony_conf_path: "/etc/chrony/chrony.conf" From dd4f049eb33c4571b78c84cd2c899cd02b93607c Mon Sep 17 00:00:00 2001 From: Israel Villar Boillos Date: Thu, 28 May 2026 23:32:22 +0100 Subject: [PATCH 38/61] Add rule to ensure /etc/sysctl.d/99-sysctl.conf symlink exists on Debian 13 Without /etc/sysctl.d/99-sysctl.conf -> /etc/sysctl.conf, systemd-sysctl silently ignores /etc/sysctl.conf at boot, causing all sysctl hardening settings written there by remediations to not persist across reboots. Add sysctl_conf_symlink_etc_sysctl_d rule with OVAL check (unix:symlink_test) and bash remediation (ln -sf + systemctl restart systemd-sysctl.service). Select the rule in cis_level1_server_ulpgc.profile. Co-Authored-By: Claude Sonnet 4.6 --- .../bash/shared.sh | 8 ++++ .../oval/shared.xml | 24 +++++++++++ .../sysctl_conf_symlink_etc_sysctl_d/rule.yml | 40 +++++++++++++++++++ .../profiles/cis_level1_server_ulpgc.profile | 1 + 4 files changed, 73 insertions(+) create mode 100644 linux_os/guide/system/permissions/restrictions/sysctl_conf_symlink_etc_sysctl_d/bash/shared.sh create mode 100644 linux_os/guide/system/permissions/restrictions/sysctl_conf_symlink_etc_sysctl_d/oval/shared.xml create mode 100644 linux_os/guide/system/permissions/restrictions/sysctl_conf_symlink_etc_sysctl_d/rule.yml diff --git a/linux_os/guide/system/permissions/restrictions/sysctl_conf_symlink_etc_sysctl_d/bash/shared.sh b/linux_os/guide/system/permissions/restrictions/sysctl_conf_symlink_etc_sysctl_d/bash/shared.sh new file mode 100644 index 000000000000..301217feb176 --- /dev/null +++ b/linux_os/guide/system/permissions/restrictions/sysctl_conf_symlink_etc_sysctl_d/bash/shared.sh @@ -0,0 +1,8 @@ +# platform = multi_platform_all +# reboot = false +# strategy = configure +# complexity = low +# disruption = low + +ln -sf /etc/sysctl.conf /etc/sysctl.d/99-sysctl.conf +systemctl restart systemd-sysctl.service diff --git a/linux_os/guide/system/permissions/restrictions/sysctl_conf_symlink_etc_sysctl_d/oval/shared.xml b/linux_os/guide/system/permissions/restrictions/sysctl_conf_symlink_etc_sysctl_d/oval/shared.xml new file mode 100644 index 000000000000..b727b825523a --- /dev/null +++ b/linux_os/guide/system/permissions/restrictions/sysctl_conf_symlink_etc_sysctl_d/oval/shared.xml @@ -0,0 +1,24 @@ + + + {{{ oval_metadata("/etc/sysctl.d/99-sysctl.conf must be a symlink to /etc/sysctl.conf so that systemd-sysctl loads it at boot.", rule_title=rule_title) }}} + + + + + + + + + + + + /etc/sysctl.d/99-sysctl.conf + + + + /etc/sysctl.conf + + diff --git a/linux_os/guide/system/permissions/restrictions/sysctl_conf_symlink_etc_sysctl_d/rule.yml b/linux_os/guide/system/permissions/restrictions/sysctl_conf_symlink_etc_sysctl_d/rule.yml new file mode 100644 index 000000000000..bfebe5fd8056 --- /dev/null +++ b/linux_os/guide/system/permissions/restrictions/sysctl_conf_symlink_etc_sysctl_d/rule.yml @@ -0,0 +1,40 @@ +documentation_complete: true + +title: 'Ensure /etc/sysctl.d/99-sysctl.conf Is a Symlink to /etc/sysctl.conf' + +description: |- + The file /etc/sysctl.d/99-sysctl.conf must be a symbolic link + pointing to /etc/sysctl.conf. This symlink is normally created by + the procps package and ensures that systemd-sysctl + processes /etc/sysctl.conf with the correct priority during boot. + Without it, kernel parameter settings written to /etc/sysctl.conf + are silently ignored by systemd-sysctl and do not persist across + reboots. + +rationale: |- + When /etc/sysctl.d/99-sysctl.conf is absent or is not a symlink to + /etc/sysctl.conf, systemd-sysctl does not load + /etc/sysctl.conf during boot. As a result, any kernel parameters + configured in that file — including security hardening settings — are not + applied at startup, undermining system hardening. + +severity: medium + +platform: machine + +references: + nist: CM-6(a) + +ocil_clause: '/etc/sysctl.d/99-sysctl.conf does not exist or is not a symlink to /etc/sysctl.conf' + +ocil: |- + Verify that /etc/sysctl.d/99-sysctl.conf is a symbolic link + pointing to /etc/sysctl.conf: +
    $ ls -l /etc/sysctl.d/99-sysctl.conf
    + The output should show a symlink pointing to /etc/sysctl.conf. + +fixtext: |- + Create the symbolic link: +
    # ln -sf /etc/sysctl.conf /etc/sysctl.d/99-sysctl.conf
    + Apply the settings immediately: +
    # systemctl restart systemd-sysctl.service
    diff --git a/products/debian13/profiles/cis_level1_server_ulpgc.profile b/products/debian13/profiles/cis_level1_server_ulpgc.profile index a76b8f2e06e4..e3f46f5bbb89 100644 --- a/products/debian13/profiles/cis_level1_server_ulpgc.profile +++ b/products/debian13/profiles/cis_level1_server_ulpgc.profile @@ -11,6 +11,7 @@ extends: cis_level1_server selections: # El símbolo '!' le dice al compilador: "De todo lo que heredes, quita estas reglas" + - sysctl_conf_symlink_etc_sysctl_d - '!package_aide_installed' - '!aide_build_database' - '!aide_periodic_checking_systemd_timer' From 9fee258fe412d1835152e259597aaec33576db8a Mon Sep 17 00:00:00 2001 From: Israel Villar Boillos Date: Fri, 29 May 2026 00:10:39 +0100 Subject: [PATCH 39/61] Fix syslogng_filecreatemode OVAL: replace arithmetic with direct regex match MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The previous OVAL used a local_variable with octal-to-decimal arithmetic and bitwise OR to check perm() ≤ 0640, which failed on OpenSCAP 1.4.2 (Debian 13). Replace with a single textfilecontent54_test using the regex perm\(0[0-6][0-4][0-7]\) which directly matches all octal values that are 0640 or more restrictive, avoiding the problematic variable arithmetic. Co-Authored-By: Claude Sonnet 4.6 --- .../syslogng_filecreatemode/oval/shared.xml | 66 ++++--------------- 1 file changed, 14 insertions(+), 52 deletions(-) diff --git a/linux_os/guide/system/logging/syslogng/syslogng_filecreatemode/oval/shared.xml b/linux_os/guide/system/logging/syslogng/syslogng_filecreatemode/oval/shared.xml index ce968b5bddd1..183025bf73f9 100644 --- a/linux_os/guide/system/logging/syslogng/syslogng_filecreatemode/oval/shared.xml +++ b/linux_os/guide/system/logging/syslogng/syslogng_filecreatemode/oval/shared.xml @@ -1,62 +1,24 @@ - + {{{ oval_metadata("perm() setting controls permissions applied to newly created log files by syslog-ng.", rule_title=rule_title) }}} - - - + + - - + + + - - ^\/etc\/syslog-ng\/(syslog-ng\.conf|conf\.d\/.*\.conf)$ - perm\((\d+)\) + + ^/etc/syslog-ng/(syslog-ng\.conf|conf\.d/.*\.conf)$ + perm\(0[0-6][0-4][0-7]\) 1 - - - - - - 64 - - - - - - 8 - - - - - - - - - - - - - - - - - var_syslogng_perm_dec - - - - - 416 - From 92d9973c8219d4bd10214755525943fcd6f33e67 Mon Sep 17 00:00:00 2001 From: Israel Villar Boillos Date: Fri, 29 May 2026 23:05:52 +0100 Subject: [PATCH 40/61] Add Debian 13 UFW default policy rules and remediations for CIS 4.1 Split the generic set_ufw_default_rule into three dedicated rules (ufw_default_incoming_rule, ufw_default_outgoing_rule, ufw_disabled_routed) so each CIS Debian 13 control (4.1.3/4.1.4/4.1.5) maps to its own check and bash remediation. Each rule uses grep -E instead of grep -oP to avoid PCRE dependency on Debian. The routed rule uses 'ufw default deny routed' since 'disabled' is not a valid ufw default policy argument. Also extend check_ufw_active SCE and add bash remediation (unmask + enable service + ufw --force enable) for Debian 13 coverage of CIS 4.1.2. Co-Authored-By: Claude Sonnet 4.6 --- controls/cis_debian13.yml | 15 ++------- .../check_ufw_active/bash/shared.sh | 5 +++ .../check_ufw_active/sce/shared.sh | 2 +- .../ufw_default_incoming_rule/bash/shared.sh | 3 ++ .../ufw_default_incoming_rule/rule.yml | 33 +++++++++++++++++++ .../ufw_default_incoming_rule/sce/shared.sh | 13 ++++++++ .../ufw_default_outgoing_rule/bash/shared.sh | 3 ++ .../ufw_default_outgoing_rule/rule.yml | 33 +++++++++++++++++++ .../ufw_default_outgoing_rule/sce/shared.sh | 13 ++++++++ .../ufw_disabled_routed/bash/shared.sh | 3 ++ .../network-ufw/ufw_disabled_routed/rule.yml | 31 +++++++++++++++++ .../ufw_disabled_routed/sce/shared.sh | 13 ++++++++ 12 files changed, 154 insertions(+), 13 deletions(-) create mode 100644 linux_os/guide/system/network/network-ufw/check_ufw_active/bash/shared.sh create mode 100644 linux_os/guide/system/network/network-ufw/ufw_default_incoming_rule/bash/shared.sh create mode 100644 linux_os/guide/system/network/network-ufw/ufw_default_incoming_rule/rule.yml create mode 100644 linux_os/guide/system/network/network-ufw/ufw_default_incoming_rule/sce/shared.sh create mode 100644 linux_os/guide/system/network/network-ufw/ufw_default_outgoing_rule/bash/shared.sh create mode 100644 linux_os/guide/system/network/network-ufw/ufw_default_outgoing_rule/rule.yml create mode 100644 linux_os/guide/system/network/network-ufw/ufw_default_outgoing_rule/sce/shared.sh create mode 100644 linux_os/guide/system/network/network-ufw/ufw_disabled_routed/bash/shared.sh create mode 100644 linux_os/guide/system/network/network-ufw/ufw_disabled_routed/rule.yml create mode 100644 linux_os/guide/system/network/network-ufw/ufw_disabled_routed/sce/shared.sh diff --git a/controls/cis_debian13.yml b/controls/cis_debian13.yml index 953acc6f13f7..74442b61961a 100644 --- a/controls/cis_debian13.yml +++ b/controls/cis_debian13.yml @@ -1629,11 +1629,8 @@ controls: - l1_server - l1_workstation rules: - - set_ufw_default_rule + - ufw_default_incoming_rule status: automated - notes: | - The existing rule set_ufw_default_rule covers the default incoming, - outgoing, and routed UFW policies together. - id: 4.1.4 title: Ensure ufw outgoing default is configured (Automated) @@ -1641,11 +1638,8 @@ controls: - l2_server - l2_workstation rules: - - set_ufw_default_rule + - ufw_default_outgoing_rule status: automated - notes: | - The existing rule set_ufw_default_rule covers the default incoming, - outgoing, and routed UFW policies together. - id: 4.1.5 title: Ensure ufw routed default is configured (Automated) @@ -1653,11 +1647,8 @@ controls: - l1_server - l1_workstation rules: - - set_ufw_default_rule + - ufw_disabled_routed status: automated - notes: | - The existing rule set_ufw_default_rule covers the default incoming, - outgoing, and routed UFW policies together. - id: 5.1.1 title: Ensure access to /etc/ssh/sshd_config is configured (Automated) diff --git a/linux_os/guide/system/network/network-ufw/check_ufw_active/bash/shared.sh b/linux_os/guide/system/network/network-ufw/check_ufw_active/bash/shared.sh new file mode 100644 index 000000000000..2ddb6d28c5c7 --- /dev/null +++ b/linux_os/guide/system/network/network-ufw/check_ufw_active/bash/shared.sh @@ -0,0 +1,5 @@ +# platform = multi_platform_ubuntu,multi_platform_debian + +systemctl unmask ufw.service +systemctl --now enable ufw.service +ufw --force enable diff --git a/linux_os/guide/system/network/network-ufw/check_ufw_active/sce/shared.sh b/linux_os/guide/system/network/network-ufw/check_ufw_active/sce/shared.sh index 4b7f4b0bd1f1..c657aaf36e9d 100644 --- a/linux_os/guide/system/network/network-ufw/check_ufw_active/sce/shared.sh +++ b/linux_os/guide/system/network/network-ufw/check_ufw_active/sce/shared.sh @@ -1,5 +1,5 @@ #!/usr/bin/env bash -# platform = multi_platform_ubuntu +# platform = multi_platform_ubuntu,multi_platform_debian # check-import = stdout result=$XCCDF_RESULT_FAIL diff --git a/linux_os/guide/system/network/network-ufw/ufw_default_incoming_rule/bash/shared.sh b/linux_os/guide/system/network/network-ufw/ufw_default_incoming_rule/bash/shared.sh new file mode 100644 index 000000000000..02030a017bf6 --- /dev/null +++ b/linux_os/guide/system/network/network-ufw/ufw_default_incoming_rule/bash/shared.sh @@ -0,0 +1,3 @@ +# platform = multi_platform_ubuntu,multi_platform_debian + +ufw default deny incoming diff --git a/linux_os/guide/system/network/network-ufw/ufw_default_incoming_rule/rule.yml b/linux_os/guide/system/network/network-ufw/ufw_default_incoming_rule/rule.yml new file mode 100644 index 000000000000..96ed807d3b6d --- /dev/null +++ b/linux_os/guide/system/network/network-ufw/ufw_default_incoming_rule/rule.yml @@ -0,0 +1,33 @@ +documentation_complete: true + +title: 'Ensure ufw Default Deny Policy for Incoming Connections' + +description: |- + A default deny policy on incoming connections ensures that any unconfigured + inbound network traffic will be rejected. + + Note: Any port or protocol without an explicit allow before the default + deny will be blocked. + +rationale: |- + With a default accept policy the firewall will accept any incoming packet + that is not configured to be denied. It is easier to allow acceptable + usage than to block unacceptable usage. + +severity: medium + +platform: package[ufw] + +ocil_clause: 'the default policy for incoming connections is not set to deny or reject' + +ocil: |- + Run the following command and verify that the default policy for incoming + connections is deny or reject: +
    # ufw status verbose | grep Default:
    + Example output: +
    Default: deny (incoming), ...
    + +warnings: + - general: |- + Changing firewall settings while connected over network can + result in being locked out of the system. diff --git a/linux_os/guide/system/network/network-ufw/ufw_default_incoming_rule/sce/shared.sh b/linux_os/guide/system/network/network-ufw/ufw_default_incoming_rule/sce/shared.sh new file mode 100644 index 000000000000..789963d70be1 --- /dev/null +++ b/linux_os/guide/system/network/network-ufw/ufw_default_incoming_rule/sce/shared.sh @@ -0,0 +1,13 @@ +#!/usr/bin/env bash +# platform = multi_platform_ubuntu,multi_platform_debian +# check-import = stdout + +result=$XCCDF_RESULT_FAIL + +ufw_default_line=$(ufw status verbose 2>/dev/null | grep "^Default:") + +if echo "$ufw_default_line" | grep -Eq "(deny|reject|disabled) \(incoming\)"; then + result=${XCCDF_RESULT_PASS} +fi + +exit $result diff --git a/linux_os/guide/system/network/network-ufw/ufw_default_outgoing_rule/bash/shared.sh b/linux_os/guide/system/network/network-ufw/ufw_default_outgoing_rule/bash/shared.sh new file mode 100644 index 000000000000..7e8b8edb4ff9 --- /dev/null +++ b/linux_os/guide/system/network/network-ufw/ufw_default_outgoing_rule/bash/shared.sh @@ -0,0 +1,3 @@ +# platform = multi_platform_ubuntu,multi_platform_debian + +ufw default deny outgoing diff --git a/linux_os/guide/system/network/network-ufw/ufw_default_outgoing_rule/rule.yml b/linux_os/guide/system/network/network-ufw/ufw_default_outgoing_rule/rule.yml new file mode 100644 index 000000000000..73b8e90eb183 --- /dev/null +++ b/linux_os/guide/system/network/network-ufw/ufw_default_outgoing_rule/rule.yml @@ -0,0 +1,33 @@ +documentation_complete: true + +title: 'Ensure ufw Default Deny Policy for Outgoing Connections' + +description: |- + A default deny policy on outgoing connections ensures that only explicitly + allowed outbound network traffic will be permitted. + + Note: Any port or protocol without an explicit allow before the default + deny will be blocked. + +rationale: |- + With a default accept policy the firewall will allow any outgoing packet + that is not configured to be denied. Restricting outgoing traffic reduces + the risk of data exfiltration and limits the impact of a compromised host. + +severity: medium + +platform: package[ufw] + +ocil_clause: 'the default policy for outgoing connections is not set to deny or reject' + +ocil: |- + Run the following command and verify that the default policy for outgoing + connections is deny or reject: +
    # ufw status verbose | grep Default:
    + Example output: +
    Default: ..., deny (outgoing), ...
    + +warnings: + - general: |- + Changing firewall settings while connected over network can + result in being locked out of the system. diff --git a/linux_os/guide/system/network/network-ufw/ufw_default_outgoing_rule/sce/shared.sh b/linux_os/guide/system/network/network-ufw/ufw_default_outgoing_rule/sce/shared.sh new file mode 100644 index 000000000000..1fed07ac7cca --- /dev/null +++ b/linux_os/guide/system/network/network-ufw/ufw_default_outgoing_rule/sce/shared.sh @@ -0,0 +1,13 @@ +#!/usr/bin/env bash +# platform = multi_platform_ubuntu,multi_platform_debian +# check-import = stdout + +result=$XCCDF_RESULT_FAIL + +ufw_default_line=$(ufw status verbose 2>/dev/null | grep "^Default:") + +if echo "$ufw_default_line" | grep -Eq "(deny|reject|disabled) \(outgoing\)"; then + result=${XCCDF_RESULT_PASS} +fi + +exit $result diff --git a/linux_os/guide/system/network/network-ufw/ufw_disabled_routed/bash/shared.sh b/linux_os/guide/system/network/network-ufw/ufw_disabled_routed/bash/shared.sh new file mode 100644 index 000000000000..17330f3df230 --- /dev/null +++ b/linux_os/guide/system/network/network-ufw/ufw_disabled_routed/bash/shared.sh @@ -0,0 +1,3 @@ +# platform = multi_platform_ubuntu,multi_platform_debian + +ufw default deny routed diff --git a/linux_os/guide/system/network/network-ufw/ufw_disabled_routed/rule.yml b/linux_os/guide/system/network/network-ufw/ufw_disabled_routed/rule.yml new file mode 100644 index 000000000000..64b47612ec1e --- /dev/null +++ b/linux_os/guide/system/network/network-ufw/ufw_disabled_routed/rule.yml @@ -0,0 +1,31 @@ +documentation_complete: true + +title: 'Ensure ufw Default Policy for Routed (Forwarded) Traffic is Disabled' + +description: |- + The default policy for routed (forwarded) traffic in ufw should be set to + disabled or deny, ensuring that the system does not forward packets between + interfaces unless explicitly configured to do so. + +rationale: |- + Unless the system is intended to act as a router, forwarding traffic between + network interfaces should be disabled. Disabling the routed default policy + prevents the system from accidentally or maliciously forwarding traffic. + +severity: medium + +platform: package[ufw] + +ocil_clause: 'the default policy for routed traffic is not set to disabled or deny' + +ocil: |- + Run the following command and verify that the default policy for routed + traffic is disabled or deny: +
    # ufw status verbose | grep Default:
    + Example output: +
    Default: ..., disabled (routed)
    + +warnings: + - general: |- + Changing firewall settings while connected over network can + result in being locked out of the system. diff --git a/linux_os/guide/system/network/network-ufw/ufw_disabled_routed/sce/shared.sh b/linux_os/guide/system/network/network-ufw/ufw_disabled_routed/sce/shared.sh new file mode 100644 index 000000000000..85bc888aa99e --- /dev/null +++ b/linux_os/guide/system/network/network-ufw/ufw_disabled_routed/sce/shared.sh @@ -0,0 +1,13 @@ +#!/usr/bin/env bash +# platform = multi_platform_ubuntu,multi_platform_debian +# check-import = stdout + +result=$XCCDF_RESULT_FAIL + +ufw_default_line=$(ufw status verbose 2>/dev/null | grep "^Default:") + +if echo "$ufw_default_line" | grep -Eq "(deny|reject|disabled) \(routed\)"; then + result=${XCCDF_RESULT_PASS} +fi + +exit $result From 48695a0c18f1d8d378f5226d927e88213e7d1ab6 Mon Sep 17 00:00:00 2001 From: Israel Villar Boillos Date: Wed, 3 Jun 2026 18:09:19 +0100 Subject: [PATCH 41/61] Review and fix Debian 13 CIS section 5.3 PAM controls - Add notes to 5.3.1.x package controls clarifying that automated check covers installation only; latest version requires manual check - Fix bash platform comments to include multi_platform_debian for pam_unix_enabled, pam_faillock_enabled, pam_pwhistory_enabled, pam_pwquality_enabled, and pam_unix_no_remember rules - Add oval/debian.xml for pam_pwquality_enabled (was Ubuntu-only) - Add oval/debian.xml and bash/debian.sh for pam_pwhistory_remember using pam-auth-update approach instead of direct PAM file editing - Add bash/debian.sh for pam_pwhistory_use_authtok using pam-auth-update - Add bash/debian.sh for pam_unix_authtok using pam-auth-update - Add var_password_pam_maxsequence=3 to control 5.3.3.2.5 - Add cis_debian13 selector to var_password_hashing_algorithm_pam (yescrypt|sha512) and update 5.3.3.4.3 to accept both algorithms Co-Authored-By: Claude Sonnet 4.6 --- controls/cis_debian13.yml | 17 +++++- .../bash/shared.sh | 2 +- .../bash/shared.sh | 2 +- .../bash/debian.sh | 21 +++++++ .../oval/debian.xml | 58 +++++++++++++++++++ .../bash/debian.sh | 13 +++++ .../bash/debian.sh | 12 ++++ .../bash/shared.sh | 2 +- .../bash/shared.sh | 2 +- .../oval/debian.xml | 37 ++++++++++++ .../var_password_hashing_algorithm_pam.var | 1 + .../bash/shared.sh | 2 +- 12 files changed, 161 insertions(+), 8 deletions(-) create mode 100644 linux_os/guide/system/accounts/accounts-pam/locking_out_password_attempts/accounts_password_pam_pwhistory_remember/bash/debian.sh create mode 100644 linux_os/guide/system/accounts/accounts-pam/locking_out_password_attempts/accounts_password_pam_pwhistory_remember/oval/debian.xml create mode 100644 linux_os/guide/system/accounts/accounts-pam/locking_out_password_attempts/accounts_password_pam_pwhistory_use_authtok/bash/debian.sh create mode 100644 linux_os/guide/system/accounts/accounts-pam/locking_out_password_attempts/accounts_password_pam_unix_authtok/bash/debian.sh create mode 100644 linux_os/guide/system/accounts/accounts-pam/password_quality/password_quality_pwquality/accounts_password_pam_pwquality_enabled/oval/debian.xml diff --git a/controls/cis_debian13.yml b/controls/cis_debian13.yml index 74442b61961a..15e9ae7f088b 100644 --- a/controls/cis_debian13.yml +++ b/controls/cis_debian13.yml @@ -1954,8 +1954,9 @@ controls: - package_pam_runtime_installed status: automated notes: | - The CIS control checks that version >= 1.5.2-6 and not that - it is the latest version as the title suggests. + The CIS benchmark requires that libpam-runtime is installed and is the latest + version available. The automated check only covers installation; verifying the + latest version requires a manual check. - id: 5.3.1.2 title: Ensure latest version of libpam-modules is installed (Automated) @@ -1965,6 +1966,10 @@ controls: rules: - package_pam_modules_installed status: automated + notes: | + The CIS benchmark requires that libpam-modules is installed and is the latest + version available. The automated check only covers installation; verifying the + latest version requires a manual check. - id: 5.3.1.3 title: Ensure latest version of libpam-pwquality is installed (Automated) @@ -1974,6 +1979,10 @@ controls: rules: - package_pam_pwquality_installed status: automated + notes: | + The CIS benchmark requires that libpam-pwquality is installed and is the latest + version available. The automated check only covers installation; verifying the + latest version requires a manual check. - id: 5.3.2.1 title: Ensure pam_unix module is enabled (Automated) @@ -2095,6 +2104,7 @@ controls: - l1_server - l1_workstation rules: + - var_password_pam_maxsequence=3 - accounts_password_pam_maxsequence status: automated @@ -2179,7 +2189,7 @@ controls: - l1_server - l1_workstation rules: - - var_password_hashing_algorithm_pam=yescrypt + - var_password_hashing_algorithm_pam=cis_debian13 - set_password_hashing_algorithm_systemauth status: automated @@ -2222,6 +2232,7 @@ controls: rules: - var_accounts_password_warn_age_login_defs=7 - accounts_password_warn_age_login_defs + - accounts_password_set_warn_age_existing status: automated - id: 5.4.1.4 diff --git a/linux_os/guide/system/accounts/accounts-pam/accounts_password_pam_unix_enabled/bash/shared.sh b/linux_os/guide/system/accounts/accounts-pam/accounts_password_pam_unix_enabled/bash/shared.sh index d3ed274a302a..c3d13462234b 100644 --- a/linux_os/guide/system/accounts/accounts-pam/accounts_password_pam_unix_enabled/bash/shared.sh +++ b/linux_os/guide/system/accounts/accounts-pam/accounts_password_pam_unix_enabled/bash/shared.sh @@ -1,4 +1,4 @@ -# platform = multi_platform_ubuntu +# platform = multi_platform_ubuntu,multi_platform_debian {{% if 'ubuntu' in product or 'debian' in product %}} {{{ bash_pam_unix_enable() }}} diff --git a/linux_os/guide/system/accounts/accounts-pam/locking_out_password_attempts/accounts_password_pam_pwhistory_enabled/bash/shared.sh b/linux_os/guide/system/accounts/accounts-pam/locking_out_password_attempts/accounts_password_pam_pwhistory_enabled/bash/shared.sh index bd7ef67ddd77..eddf0d6281bb 100644 --- a/linux_os/guide/system/accounts/accounts-pam/locking_out_password_attempts/accounts_password_pam_pwhistory_enabled/bash/shared.sh +++ b/linux_os/guide/system/accounts/accounts-pam/locking_out_password_attempts/accounts_password_pam_pwhistory_enabled/bash/shared.sh @@ -1,3 +1,3 @@ -# platform = multi_platform_ubuntu +# platform = multi_platform_ubuntu,multi_platform_debian {{{ bash_pam_pwhistory_enable('cac_pwhistory','requisite') }}} diff --git a/linux_os/guide/system/accounts/accounts-pam/locking_out_password_attempts/accounts_password_pam_pwhistory_remember/bash/debian.sh b/linux_os/guide/system/accounts/accounts-pam/locking_out_password_attempts/accounts_password_pam_pwhistory_remember/bash/debian.sh new file mode 100644 index 000000000000..519e94d8077b --- /dev/null +++ b/linux_os/guide/system/accounts/accounts-pam/locking_out_password_attempts/accounts_password_pam_pwhistory_remember/bash/debian.sh @@ -0,0 +1,21 @@ +# platform = multi_platform_debian + +{{{ bash_pam_pwhistory_enable('cac_pwhistory','requisite') }}} + +{{{ bash_instantiate_variables("var_password_pam_remember") }}} + +sed -i -E '/^Password:/,/^[^[:space:]]/ { + /pam_pwhistory\.so/ { + s/\s*remember=[^[:space:]]*//g + s/$/ remember='"$var_password_pam_remember"'/g + } +}' /usr/share/pam-configs/cac_pwhistory + +sed -i -E '/^Password-Initial:/,/^[^[:space:]]/ { + /pam_pwhistory\.so/ { + s/\s*remember=[^[:space:]]*//g + s/$/ remember='"$var_password_pam_remember"'/g + } +}' /usr/share/pam-configs/cac_pwhistory + +DEBIAN_FRONTEND=noninteractive pam-auth-update --enable cac_pwhistory diff --git a/linux_os/guide/system/accounts/accounts-pam/locking_out_password_attempts/accounts_password_pam_pwhistory_remember/oval/debian.xml b/linux_os/guide/system/accounts/accounts-pam/locking_out_password_attempts/accounts_password_pam_pwhistory_remember/oval/debian.xml new file mode 100644 index 000000000000..739ade74c36e --- /dev/null +++ b/linux_os/guide/system/accounts/accounts-pam/locking_out_password_attempts/accounts_password_pam_pwhistory_remember/oval/debian.xml @@ -0,0 +1,58 @@ +{{% if "debian" in product %}} +{{%- set accounts_password_pam_file = '/etc/pam.d/common-password' -%}} +{{% endif %}} + + + + {{{ oval_metadata("The passwords to remember of pam_pwhistory should be set correctly.", rule_title=rule_title) }}} + + + + + + + + + + + + + + + {{{ accounts_password_pam_file }}} + + 1 + + + + + ^[ \t]*password[ \t]+(?:(?:sufficient)|(?:required)|(?:requisite)|(?:\[.*\]))[ \t]+pam_pwhistory\.so.*$ + + + + + + + + + + + + + + {{{ accounts_password_pam_file }}} + ^[ \t]*password[ \t]+(?:(?:sufficient)|(?:required)|(?:requisite)|(?:\[.*\]))[ \t]+pam_pwhistory\.so[ \t]+[^#\n\r]*\bremember=([0-9]*)\b.*$ + 1 + + + diff --git a/linux_os/guide/system/accounts/accounts-pam/locking_out_password_attempts/accounts_password_pam_pwhistory_use_authtok/bash/debian.sh b/linux_os/guide/system/accounts/accounts-pam/locking_out_password_attempts/accounts_password_pam_pwhistory_use_authtok/bash/debian.sh new file mode 100644 index 000000000000..6696cccfdb36 --- /dev/null +++ b/linux_os/guide/system/accounts/accounts-pam/locking_out_password_attempts/accounts_password_pam_pwhistory_use_authtok/bash/debian.sh @@ -0,0 +1,13 @@ +# platform = multi_platform_debian + +{{{ bash_pam_pwhistory_enable('cac_pwhistory','requisite') }}} +conf_file=/usr/share/pam-configs/cac_pwhistory +if ! grep -qE 'pam_pwhistory\.so\s+[^#]*\buse_authtok\b' "$conf_file"; then + sed -i -E '/^Password:/,/^[^[:space:]]/ { + /pam_pwhistory\.so/ { + s/$/ use_authtok/g + } + }' "$conf_file" +fi + +DEBIAN_FRONTEND=noninteractive pam-auth-update --enable cac_pwhistory diff --git a/linux_os/guide/system/accounts/accounts-pam/locking_out_password_attempts/accounts_password_pam_unix_authtok/bash/debian.sh b/linux_os/guide/system/accounts/accounts-pam/locking_out_password_attempts/accounts_password_pam_unix_authtok/bash/debian.sh new file mode 100644 index 000000000000..bb9b98b0a059 --- /dev/null +++ b/linux_os/guide/system/accounts/accounts-pam/locking_out_password_attempts/accounts_password_pam_unix_authtok/bash/debian.sh @@ -0,0 +1,12 @@ +# platform = multi_platform_debian + +config_file="/usr/share/pam-configs/cac_unix" +{{{ bash_pam_unix_enable() }}} +sed -i -E '/^Password:/,/^[^[:space:]]/ { + /pam_unix\.so/ { + /use_authtok/! s/$/ use_authtok/g + } +}' "$config_file" + + +DEBIAN_FRONTEND=noninteractive pam-auth-update --remove unix --enable cac_unix diff --git a/linux_os/guide/system/accounts/accounts-pam/locking_out_password_attempts/accounts_passwords_pam_faillock_enabled/bash/shared.sh b/linux_os/guide/system/accounts/accounts-pam/locking_out_password_attempts/accounts_passwords_pam_faillock_enabled/bash/shared.sh index 43feff6ed1e8..d3d6d6c575b0 100644 --- a/linux_os/guide/system/accounts/accounts-pam/locking_out_password_attempts/accounts_passwords_pam_faillock_enabled/bash/shared.sh +++ b/linux_os/guide/system/accounts/accounts-pam/locking_out_password_attempts/accounts_passwords_pam_faillock_enabled/bash/shared.sh @@ -1,3 +1,3 @@ -# platform = multi_platform_ubuntu +# platform = multi_platform_ubuntu,multi_platform_debian {{{ bash_pam_faillock_enable() }}} diff --git a/linux_os/guide/system/accounts/accounts-pam/password_quality/password_quality_pwquality/accounts_password_pam_pwquality_enabled/bash/shared.sh b/linux_os/guide/system/accounts/accounts-pam/password_quality/password_quality_pwquality/accounts_password_pam_pwquality_enabled/bash/shared.sh index f79004374922..aff806f7f3be 100644 --- a/linux_os/guide/system/accounts/accounts-pam/password_quality/password_quality_pwquality/accounts_password_pam_pwquality_enabled/bash/shared.sh +++ b/linux_os/guide/system/accounts/accounts-pam/password_quality/password_quality_pwquality/accounts_password_pam_pwquality_enabled/bash/shared.sh @@ -1,4 +1,4 @@ -# platform = multi_platform_sle,multi_platform_ubuntu +# platform = multi_platform_sle,multi_platform_ubuntu,multi_platform_debian {{% if product in ['sle15', 'sle16'] %}} {{{ bash_ensure_pam_module_configuration('/etc/pam.d/common-password', 'password', 'requisite', 'pam_pwquality.so', '', '', 'BOF') }}} diff --git a/linux_os/guide/system/accounts/accounts-pam/password_quality/password_quality_pwquality/accounts_password_pam_pwquality_enabled/oval/debian.xml b/linux_os/guide/system/accounts/accounts-pam/password_quality/password_quality_pwquality/accounts_password_pam_pwquality_enabled/oval/debian.xml new file mode 100644 index 000000000000..860c199a4ca7 --- /dev/null +++ b/linux_os/guide/system/accounts/accounts-pam/password_quality/password_quality_pwquality/accounts_password_pam_pwquality_enabled/oval/debian.xml @@ -0,0 +1,37 @@ +{{% if 'debian' in product %}} +{{% set configuration_files = ["common-password"] %}} +{{% endif %}} + + + {{{ oval_metadata("Check pam_pwquality module is enabled", rule_title=rule_title) }}} + + {{% for file in configuration_files %}} + + {{% endfor %}} + + + + {{% macro test_pwquality_enabled(path, test_ref) %}} + + + + {{% endmacro %}} + + {{% macro object_pwquality_enabled(path, test_ref) %}} + + {{{ path }}} + ^\s*password\s+(?:(?:required)|(?:requisite))\s+pam_pwquality\.so.*$ + 1 + + {{% endmacro %}} + + {{% for file in configuration_files %}} + {{{ test_pwquality_enabled( path="/etc/pam.d/" ~ file , + test_ref="password_pam_pwquality_enabled_" ~ (file | escape_id)) }}} + {{{ object_pwquality_enabled( path="/etc/pam.d/" ~ file , + test_ref="password_pam_pwquality_enabled_" ~ (file | escape_id)) }}} + {{% endfor %}} + diff --git a/linux_os/guide/system/accounts/accounts-pam/var_password_hashing_algorithm_pam.var b/linux_os/guide/system/accounts/accounts-pam/var_password_hashing_algorithm_pam.var index b6e46765560f..52a076c46313 100644 --- a/linux_os/guide/system/accounts/accounts-pam/var_password_hashing_algorithm_pam.var +++ b/linux_os/guide/system/accounts/accounts-pam/var_password_hashing_algorithm_pam.var @@ -18,3 +18,4 @@ options: yescrypt: yescrypt cis_rhel8: yescrypt|sha512 cis_rhel10: yescrypt|sha512 + cis_debian13: yescrypt|sha512 diff --git a/linux_os/guide/system/accounts/accounts-restrictions/password_storage/accounts_password_pam_unix_no_remember/bash/shared.sh b/linux_os/guide/system/accounts/accounts-restrictions/password_storage/accounts_password_pam_unix_no_remember/bash/shared.sh index 03336f17073a..0b60e18bc2d9 100644 --- a/linux_os/guide/system/accounts/accounts-restrictions/password_storage/accounts_password_pam_unix_no_remember/bash/shared.sh +++ b/linux_os/guide/system/accounts/accounts-restrictions/password_storage/accounts_password_pam_unix_no_remember/bash/shared.sh @@ -1,4 +1,4 @@ -# platform = multi_platform_rhel,multi_platform_fedora,multi_platform_ol,multi_platform_rhv,multi_platform_almalinux,multi_platform_ubuntu +# platform = multi_platform_rhel,multi_platform_fedora,multi_platform_ol,multi_platform_rhv,multi_platform_almalinux,multi_platform_ubuntu,multi_platform_debian # reboot = false # strategy = configure # complexity = low From c7d473d2bb12309cba462fb1feec9f13e761ed51 Mon Sep 17 00:00:00 2001 From: Israel Villar Boillos Date: Wed, 3 Jun 2026 18:11:02 +0100 Subject: [PATCH 42/61] Add mlkem768x25519-sha256 to Debian 13 SSH KEX algorithms Add the NIST-standardized ML-KEM-768 hybrid post-quantum key exchange algorithm to the cis_debian13 KEX selector, placing it first as the preferred algorithm. Debian 13 ships OpenSSH 9.9+ which supports it. The older sntrup761x25519-sha512@openssh.com remains as fallback. Satisfies CIS Debian 13 5.1.13 (post-quantum KEX requirement). Co-Authored-By: Claude Sonnet 4.6 --- linux_os/guide/services/ssh/sshd_strong_kex.var | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/linux_os/guide/services/ssh/sshd_strong_kex.var b/linux_os/guide/services/ssh/sshd_strong_kex.var index a3d8e31fc444..2f5295003d6c 100644 --- a/linux_os/guide/services/ssh/sshd_strong_kex.var +++ b/linux_os/guide/services/ssh/sshd_strong_kex.var @@ -22,4 +22,4 @@ options: cis_ubuntu2404: sntrup761x25519-sha512@openssh.com,curve25519-sha256,curve25519-sha256@libssh.org,ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,diffie-hellman-group-exchange-sha256,diffie-hellman-group16-sha512,diffie-hellman-group18-sha512,diffie-hellman-group14-sha256 std_openeuler: curve25519-sha256,curve25519-sha256@libssh.org,diffie-hellman-group-exchange-sha256 cis_debian12: sntrup761x25519-sha512@openssh.com,curve25519-sha256,curve25519-sha256@libssh.org,ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,diffie-hellman-group-exchange-sha256,diffie-hellman-group16-sha512,diffie-hellman-group18-sha512,diffie-hellman-group14-sha256 - cis_debian13: sntrup761x25519-sha512@openssh.com,curve25519-sha256,curve25519-sha256@libssh.org,ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,diffie-hellman-group-exchange-sha256,diffie-hellman-group16-sha512,diffie-hellman-group18-sha512,diffie-hellman-group14-sha256 + cis_debian13: mlkem768x25519-sha256,sntrup761x25519-sha512@openssh.com,curve25519-sha256,curve25519-sha256@libssh.org,ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,diffie-hellman-group-exchange-sha256,diffie-hellman-group16-sha512,diffie-hellman-group18-sha512,diffie-hellman-group14-sha256 From 075685fbb1bcfbb51bc08ee242a9100d1597a7d0 Mon Sep 17 00:00:00 2001 From: Israel Villar Boillos Date: Wed, 3 Jun 2026 20:56:08 +0100 Subject: [PATCH 43/61] Replace SCE checks with OVAL for AppArmor and UFW rules on Debian 13 SCE scripts fail with 'Unexpected error' on systems where /tmp is mounted noexec (required by CIS 1.1.2.4), because OpenSCAP extracts SCE scripts to /tmp before executing them. Replace with OVAL checks that read configuration files and sysfs directly. - all_apparmor_profiles_enforced: read /sys/kernel/security/apparmor/profiles, compare total profile count against enforce-mode count - check_ufw_active: match ENABLED=yes in /etc/ufw/ufw.conf - ufw_default_incoming_rule: match DEFAULT_INPUT_POLICY="DROP|REJECT" in /etc/default/ufw - ufw_disabled_routed: match DEFAULT_FORWARD_POLICY="DROP|REJECT" in /etc/default/ufw Co-Authored-By: Claude Sonnet 4.6 --- .../oval/shared.xml | 52 +++++++++++++++++++ .../sce/shared.sh | 27 ---------- .../check_ufw_active/oval/shared.xml | 21 ++++++++ .../check_ufw_active/sce/shared.sh | 11 ---- .../ufw_default_incoming_rule/oval/shared.xml | 21 ++++++++ .../ufw_default_incoming_rule/sce/shared.sh | 13 ----- .../ufw_disabled_routed/oval/shared.xml | 21 ++++++++ .../ufw_disabled_routed/sce/shared.sh | 13 ----- 8 files changed, 115 insertions(+), 64 deletions(-) create mode 100644 linux_os/guide/system/apparmor/all_apparmor_profiles_enforced/oval/shared.xml delete mode 100644 linux_os/guide/system/apparmor/all_apparmor_profiles_enforced/sce/shared.sh create mode 100644 linux_os/guide/system/network/network-ufw/check_ufw_active/oval/shared.xml delete mode 100644 linux_os/guide/system/network/network-ufw/check_ufw_active/sce/shared.sh create mode 100644 linux_os/guide/system/network/network-ufw/ufw_default_incoming_rule/oval/shared.xml delete mode 100644 linux_os/guide/system/network/network-ufw/ufw_default_incoming_rule/sce/shared.sh create mode 100644 linux_os/guide/system/network/network-ufw/ufw_disabled_routed/oval/shared.xml delete mode 100644 linux_os/guide/system/network/network-ufw/ufw_disabled_routed/sce/shared.sh diff --git a/linux_os/guide/system/apparmor/all_apparmor_profiles_enforced/oval/shared.xml b/linux_os/guide/system/apparmor/all_apparmor_profiles_enforced/oval/shared.xml new file mode 100644 index 000000000000..571743c13e0a --- /dev/null +++ b/linux_os/guide/system/apparmor/all_apparmor_profiles_enforced/oval/shared.xml @@ -0,0 +1,52 @@ + + + {{{ oval_metadata("Ensure all AppArmor profiles are in enforce mode", rule_title=rule_title) }}} + + + + + + + /sys/kernel/security/apparmor/profiles + ^(.*)$ + 1 + + + + /sys/kernel/security/apparmor/profiles + ^.*(\(enforce\))$ + 1 + + + + + + + + + + + + + + + + {{{ rule_id }}}_var_num_all_profiles + + + + + + + + + + + diff --git a/linux_os/guide/system/apparmor/all_apparmor_profiles_enforced/sce/shared.sh b/linux_os/guide/system/apparmor/all_apparmor_profiles_enforced/sce/shared.sh deleted file mode 100644 index a6a3c2d64da7..000000000000 --- a/linux_os/guide/system/apparmor/all_apparmor_profiles_enforced/sce/shared.sh +++ /dev/null @@ -1,27 +0,0 @@ -#!/bin/bash -# platform = multi_platform_debian,multi_platform_sle,multi_platform_ubuntu -# check-import = stdout - -# Fallback values in case the calling engine does not export XCCDF_RESULT_* variables -: "${XCCDF_RESULT_PASS:=101}" -: "${XCCDF_RESULT_FAIL:=102}" - -# If apparmor or apparmor-utils are not installed, then this test fails. -{{{ bash_package_installed("apparmor") }}} -if [ $? -ne 0 ]; then - exit ${XCCDF_RESULT_FAIL} -fi - -# if number of apparmor profiles loaded not the same as enforced profiles, then it fails. -loaded_profiles=$(/usr/sbin/aa-status --profiled 2>/dev/null | grep -oE '^[0-9]+$') -enforced_profiles=$(/usr/sbin/aa-status --enforced 2>/dev/null | grep -oE '^[0-9]+$') -if [ "${loaded_profiles:-0}" -ne "${enforced_profiles:-0}" ]; then - exit $XCCDF_RESULT_FAIL -fi - -unconfined=$(/usr/sbin/aa-status 2>/dev/null | grep "processes are unconfined" | awk '{print $1;}') -if [ "${unconfined:-0}" -ne 0 ]; then - exit $XCCDF_RESULT_FAIL -fi - -exit $XCCDF_RESULT_PASS diff --git a/linux_os/guide/system/network/network-ufw/check_ufw_active/oval/shared.xml b/linux_os/guide/system/network/network-ufw/check_ufw_active/oval/shared.xml new file mode 100644 index 000000000000..342e05891405 --- /dev/null +++ b/linux_os/guide/system/network/network-ufw/check_ufw_active/oval/shared.xml @@ -0,0 +1,21 @@ + + + {{{ oval_metadata("Verify ufw is active", rule_title=rule_title) }}} + + + + + + + + + + + /etc/ufw/ufw.conf + ^ENABLED=yes$ + 1 + + diff --git a/linux_os/guide/system/network/network-ufw/check_ufw_active/sce/shared.sh b/linux_os/guide/system/network/network-ufw/check_ufw_active/sce/shared.sh deleted file mode 100644 index c657aaf36e9d..000000000000 --- a/linux_os/guide/system/network/network-ufw/check_ufw_active/sce/shared.sh +++ /dev/null @@ -1,11 +0,0 @@ -#!/usr/bin/env bash -# platform = multi_platform_ubuntu,multi_platform_debian -# check-import = stdout - -result=$XCCDF_RESULT_FAIL - -if ufw status | grep -qw "active"; then - result=${XCCDF_RESULT_PASS} -fi - -exit $result diff --git a/linux_os/guide/system/network/network-ufw/ufw_default_incoming_rule/oval/shared.xml b/linux_os/guide/system/network/network-ufw/ufw_default_incoming_rule/oval/shared.xml new file mode 100644 index 000000000000..0de9a6969b80 --- /dev/null +++ b/linux_os/guide/system/network/network-ufw/ufw_default_incoming_rule/oval/shared.xml @@ -0,0 +1,21 @@ + + + {{{ oval_metadata("Ensure ufw default incoming policy is deny or reject", rule_title=rule_title) }}} + + + + + + + + + + + /etc/default/ufw + ^DEFAULT_INPUT_POLICY="(DROP|REJECT)"$ + 1 + + diff --git a/linux_os/guide/system/network/network-ufw/ufw_default_incoming_rule/sce/shared.sh b/linux_os/guide/system/network/network-ufw/ufw_default_incoming_rule/sce/shared.sh deleted file mode 100644 index 789963d70be1..000000000000 --- a/linux_os/guide/system/network/network-ufw/ufw_default_incoming_rule/sce/shared.sh +++ /dev/null @@ -1,13 +0,0 @@ -#!/usr/bin/env bash -# platform = multi_platform_ubuntu,multi_platform_debian -# check-import = stdout - -result=$XCCDF_RESULT_FAIL - -ufw_default_line=$(ufw status verbose 2>/dev/null | grep "^Default:") - -if echo "$ufw_default_line" | grep -Eq "(deny|reject|disabled) \(incoming\)"; then - result=${XCCDF_RESULT_PASS} -fi - -exit $result diff --git a/linux_os/guide/system/network/network-ufw/ufw_disabled_routed/oval/shared.xml b/linux_os/guide/system/network/network-ufw/ufw_disabled_routed/oval/shared.xml new file mode 100644 index 000000000000..865a40672089 --- /dev/null +++ b/linux_os/guide/system/network/network-ufw/ufw_disabled_routed/oval/shared.xml @@ -0,0 +1,21 @@ + + + {{{ oval_metadata("Ensure ufw default routed policy is disabled or deny", rule_title=rule_title) }}} + + + + + + + + + + + /etc/default/ufw + ^DEFAULT_FORWARD_POLICY="(DROP|REJECT)"$ + 1 + + diff --git a/linux_os/guide/system/network/network-ufw/ufw_disabled_routed/sce/shared.sh b/linux_os/guide/system/network/network-ufw/ufw_disabled_routed/sce/shared.sh deleted file mode 100644 index 85bc888aa99e..000000000000 --- a/linux_os/guide/system/network/network-ufw/ufw_disabled_routed/sce/shared.sh +++ /dev/null @@ -1,13 +0,0 @@ -#!/usr/bin/env bash -# platform = multi_platform_ubuntu,multi_platform_debian -# check-import = stdout - -result=$XCCDF_RESULT_FAIL - -ufw_default_line=$(ufw status verbose 2>/dev/null | grep "^Default:") - -if echo "$ufw_default_line" | grep -Eq "(deny|reject|disabled) \(routed\)"; then - result=${XCCDF_RESULT_PASS} -fi - -exit $result From 44afdbf7ab3a3c85a4275682a9488f4949d6e6e5 Mon Sep 17 00:00:00 2001 From: Israel Villar Boillos Date: Wed, 3 Jun 2026 20:56:53 +0100 Subject: [PATCH 44/61] Allow SHA512 or YESCRYPT for password hashing in CIS Debian 13 profile CIS Debian 13 section 5.3 accepts either SHA512 or YESCRYPT as valid password hashing algorithms. Add a cis_debian13 option to var_password_hashing_algorithm (YESCRYPT|SHA512) and use it in the control file instead of the fixed yescrypt value. Co-Authored-By: Claude Sonnet 4.6 --- controls/cis_debian13.yml | 2 +- .../accounts/accounts-pam/var_password_hashing_algorithm.var | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/controls/cis_debian13.yml b/controls/cis_debian13.yml index 15e9ae7f088b..acfd391b11ca 100644 --- a/controls/cis_debian13.yml +++ b/controls/cis_debian13.yml @@ -2242,7 +2242,7 @@ controls: - l1_workstation rules: - set_password_hashing_algorithm_logindefs - - var_password_hashing_algorithm=yescrypt + - var_password_hashing_algorithm=cis_debian13 status: automated notes: Rule allows either SHA512 or YESCRYPT diff --git a/linux_os/guide/system/accounts/accounts-pam/var_password_hashing_algorithm.var b/linux_os/guide/system/accounts/accounts-pam/var_password_hashing_algorithm.var index d955dbe9c17d..2238e4df257e 100644 --- a/linux_os/guide/system/accounts/accounts-pam/var_password_hashing_algorithm.var +++ b/linux_os/guide/system/accounts/accounts-pam/var_password_hashing_algorithm.var @@ -22,3 +22,4 @@ options: cis_rhel8: YESCRYPT|SHA512 cis_rhel10: YESCRYPT|SHA512 cis_fedora: YESCRYPT|SHA512 + cis_debian13: YESCRYPT|SHA512 From 8c5e22f2e0eb3a9b2a1de0d64e62db51f96e4243 Mon Sep 17 00:00:00 2001 From: Israel Villar Boillos Date: Wed, 3 Jun 2026 21:04:58 +0100 Subject: [PATCH 45/61] Fix sysctl_conf_symlink OVAL: use at_least_one_exists to get fail not error With check_existence="all_exist", a missing symlink returns 0 items and OpenSCAP reports the test as error instead of fail. OpenSCAP only triggers remediation on fail, so the symlink was never created across repeated runs. Change to at_least_one_exists so a missing symlink produces fail, which allows the bash remediation to run and create the symlink. Co-Authored-By: Claude Sonnet 4.6 --- .../sysctl_conf_symlink_etc_sysctl_d/oval/shared.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/linux_os/guide/system/permissions/restrictions/sysctl_conf_symlink_etc_sysctl_d/oval/shared.xml b/linux_os/guide/system/permissions/restrictions/sysctl_conf_symlink_etc_sysctl_d/oval/shared.xml index b727b825523a..8d874e2fe112 100644 --- a/linux_os/guide/system/permissions/restrictions/sysctl_conf_symlink_etc_sysctl_d/oval/shared.xml +++ b/linux_os/guide/system/permissions/restrictions/sysctl_conf_symlink_etc_sysctl_d/oval/shared.xml @@ -7,7 +7,7 @@ - From 143b6fe854fa2fa92430ba2e17a120878e031894 Mon Sep 17 00:00:00 2001 From: Israel Villar Boillos Date: Wed, 3 Jun 2026 21:28:26 +0100 Subject: [PATCH 46/61] Write sysctl settings to /etc/sysctl.conf on Debian 13 Switch sysctl_remediate_drop_in_file to false so all sysctl remediations write to /etc/sysctl.conf instead of individual drop-in files in /etc/sysctl.d/. The drop-in approach left /etc/sysctl.conf uncreated, making the 99-sysctl.conf symlink dangling and breaking the sysctl_conf_symlink_etc_sysctl_d OVAL check. Also fix the sysctl_conf_symlink_etc_sysctl_d rule: - bash: create /etc/sysctl.conf if absent before creating the symlink - oval: use path+filename instead of filepath in symlink_object so that a missing symlink returns an empty set (fail) rather than a collect error Co-Authored-By: Claude Sonnet 4.6 --- .../sysctl_conf_symlink_etc_sysctl_d/bash/shared.sh | 1 + .../sysctl_conf_symlink_etc_sysctl_d/oval/shared.xml | 3 ++- products/debian13/product.yml | 2 +- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/linux_os/guide/system/permissions/restrictions/sysctl_conf_symlink_etc_sysctl_d/bash/shared.sh b/linux_os/guide/system/permissions/restrictions/sysctl_conf_symlink_etc_sysctl_d/bash/shared.sh index 301217feb176..6964b1a5d77e 100644 --- a/linux_os/guide/system/permissions/restrictions/sysctl_conf_symlink_etc_sysctl_d/bash/shared.sh +++ b/linux_os/guide/system/permissions/restrictions/sysctl_conf_symlink_etc_sysctl_d/bash/shared.sh @@ -4,5 +4,6 @@ # complexity = low # disruption = low +[ -f /etc/sysctl.conf ] || install -m 0644 /dev/null /etc/sysctl.conf ln -sf /etc/sysctl.conf /etc/sysctl.d/99-sysctl.conf systemctl restart systemd-sysctl.service diff --git a/linux_os/guide/system/permissions/restrictions/sysctl_conf_symlink_etc_sysctl_d/oval/shared.xml b/linux_os/guide/system/permissions/restrictions/sysctl_conf_symlink_etc_sysctl_d/oval/shared.xml index 8d874e2fe112..d42405351478 100644 --- a/linux_os/guide/system/permissions/restrictions/sysctl_conf_symlink_etc_sysctl_d/oval/shared.xml +++ b/linux_os/guide/system/permissions/restrictions/sysctl_conf_symlink_etc_sysctl_d/oval/shared.xml @@ -15,7 +15,8 @@ - /etc/sysctl.d/99-sysctl.conf + /etc/sysctl.d + 99-sysctl.conf diff --git a/products/debian13/product.yml b/products/debian13/product.yml index 4a1fe7f68719..774ea0641c72 100644 --- a/products/debian13/product.yml +++ b/products/debian13/product.yml @@ -17,7 +17,7 @@ pkg_manager: "apt_get" init_system: "systemd" -sysctl_remediate_drop_in_file: "true" +sysctl_remediate_drop_in_file: "false" oval_feed_url: "https://www.debian.org/security/oval/oval-definitions-trixie.xml.bz2" From 0d01474a0807d93866b104c56ab4c3fb517b70a9 Mon Sep 17 00:00:00 2001 From: Israel Villar Boillos Date: Wed, 3 Jun 2026 21:38:53 +0100 Subject: [PATCH 47/61] Fix sysctl_conf_symlink OVAL: use unix:file_test instead of symlink_test unix:symlink_object with filepath returns error (not does_not_exist) for dangling symlinks (target missing), which blocked remediation. Replace with unix:file_test using follow_symlinks=false and type="symbolic link": - file doesn't exist -> does_not_exist -> fail -> remediation runs - file is not a symlink -> type mismatch -> fail -> remediation runs - file is a symlink -> pass Co-Authored-By: Claude Sonnet 4.6 --- .../oval/shared.xml | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/linux_os/guide/system/permissions/restrictions/sysctl_conf_symlink_etc_sysctl_d/oval/shared.xml b/linux_os/guide/system/permissions/restrictions/sysctl_conf_symlink_etc_sysctl_d/oval/shared.xml index d42405351478..adf8e2197d58 100644 --- a/linux_os/guide/system/permissions/restrictions/sysctl_conf_symlink_etc_sysctl_d/oval/shared.xml +++ b/linux_os/guide/system/permissions/restrictions/sysctl_conf_symlink_etc_sysctl_d/oval/shared.xml @@ -2,24 +2,24 @@ {{{ oval_metadata("/etc/sysctl.d/99-sysctl.conf must be a symlink to /etc/sysctl.conf so that systemd-sysctl loads it at boot.", rule_title=rule_title) }}} - - - + - - /etc/sysctl.d - 99-sysctl.conf - + + + /etc/sysctl.d/99-sysctl.conf + - - /etc/sysctl.conf - + + symbolic link + From 3c351e1896e2af867ac0b99b1fae8dd8100412ff Mon Sep 17 00:00:00 2001 From: Israel Villar Boillos Date: Wed, 3 Jun 2026 21:41:45 +0100 Subject: [PATCH 48/61] Fix sysctl_conf_symlink OVAL: remove invalid follow_symlinks behavior unix:FileBehaviors does not have a follow_symlinks attribute. Remove it. unix:file_object uses lstat() by default so symlinks are already reported as type "symbolic link" without any special behavior needed. Co-Authored-By: Claude Sonnet 4.6 --- .../sysctl_conf_symlink_etc_sysctl_d/oval/shared.xml | 1 - 1 file changed, 1 deletion(-) diff --git a/linux_os/guide/system/permissions/restrictions/sysctl_conf_symlink_etc_sysctl_d/oval/shared.xml b/linux_os/guide/system/permissions/restrictions/sysctl_conf_symlink_etc_sysctl_d/oval/shared.xml index adf8e2197d58..0852c36aa01c 100644 --- a/linux_os/guide/system/permissions/restrictions/sysctl_conf_symlink_etc_sysctl_d/oval/shared.xml +++ b/linux_os/guide/system/permissions/restrictions/sysctl_conf_symlink_etc_sysctl_d/oval/shared.xml @@ -15,7 +15,6 @@ - /etc/sysctl.d/99-sysctl.conf From c5f6a5830e6faf210b9d2ff4d956ab938660b540 Mon Sep 17 00:00:00 2001 From: Israel Villar Boillos Date: Wed, 3 Jun 2026 21:55:15 +0100 Subject: [PATCH 49/61] Add bash remediation for sshd_limit_user_access via AllowGroups variable The rule previously had no automated remediation. Add: - var_sshd_allow_groups.var: string variable with default "users" for the AllowGroups sshd parameter - bash/shared.sh: remediation using bash_sshd_remediation to insert AllowGroups into /etc/ssh/sshd_config - Remove the "no automated remediation" warning from rule.yml - Set var_sshd_allow_groups=users in the CIS Debian 13 control file Co-Authored-By: Claude Sonnet 4.6 --- controls/cis_debian13.yml | 1 + .../sshd_limit_user_access/bash/shared.sh | 9 +++++++++ .../ssh_server/sshd_limit_user_access/rule.yml | 5 ----- .../guide/services/ssh/var_sshd_allow_groups.var | 16 ++++++++++++++++ 4 files changed, 26 insertions(+), 5 deletions(-) create mode 100644 linux_os/guide/services/ssh/ssh_server/sshd_limit_user_access/bash/shared.sh create mode 100644 linux_os/guide/services/ssh/var_sshd_allow_groups.var diff --git a/controls/cis_debian13.yml b/controls/cis_debian13.yml index acfd391b11ca..9e12025e76f2 100644 --- a/controls/cis_debian13.yml +++ b/controls/cis_debian13.yml @@ -1686,6 +1686,7 @@ controls: - l1_workstation rules: - sshd_limit_user_access + - var_sshd_allow_groups=users status: automated - id: 5.1.5 diff --git a/linux_os/guide/services/ssh/ssh_server/sshd_limit_user_access/bash/shared.sh b/linux_os/guide/services/ssh/ssh_server/sshd_limit_user_access/bash/shared.sh new file mode 100644 index 000000000000..314ab5ec1f18 --- /dev/null +++ b/linux_os/guide/services/ssh/ssh_server/sshd_limit_user_access/bash/shared.sh @@ -0,0 +1,9 @@ +# platform = multi_platform_all +# reboot = false +# strategy = configure +# complexity = low +# disruption = low + +{{{ bash_instantiate_variables("var_sshd_allow_groups") }}} + +{{{ bash_sshd_remediation(parameter="AllowGroups", value="$var_sshd_allow_groups", config_is_distributed=sshd_distributed_config, rule_id=rule_id) }}} diff --git a/linux_os/guide/services/ssh/ssh_server/sshd_limit_user_access/rule.yml b/linux_os/guide/services/ssh/ssh_server/sshd_limit_user_access/rule.yml index 45268c1823fc..2bafe99b91c6 100644 --- a/linux_os/guide/services/ssh/ssh_server/sshd_limit_user_access/rule.yml +++ b/linux_os/guide/services/ssh/ssh_server/sshd_limit_user_access/rule.yml @@ -65,8 +65,3 @@ references: nist: AC-3,CM-6(a) nist-csf: PR.AC-4,PR.AC-6,PR.PT-3 pcidss: Req-2.2.4 - -warnings: - - general: |- - Automated remediation is not available for this configuration check - because each system has unique user names and group names. diff --git a/linux_os/guide/services/ssh/var_sshd_allow_groups.var b/linux_os/guide/services/ssh/var_sshd_allow_groups.var new file mode 100644 index 000000000000..9caf34024c62 --- /dev/null +++ b/linux_os/guide/services/ssh/var_sshd_allow_groups.var @@ -0,0 +1,16 @@ +documentation_complete: true + +title: 'SSH AllowGroups' + +description: 'Space-separated list of groups allowed to log in via SSH.' + +type: string + +operator: equals + +interactive: false + +options: + root: root + users: users + default: users From 88706a5c753074afb8c56c02471dde6d7192c009 Mon Sep 17 00:00:00 2001 From: Israel Villar Boillos Date: Wed, 3 Jun 2026 22:04:08 +0100 Subject: [PATCH 50/61] Add sshd_set_allow_groups rule for CIS 5.1.4 remediation in ULPGC profile The upstream sshd_limit_user_access rule cannot be auto-remediated because AllowGroups values are site-specific. Instead of modifying the upstream rule, add a new ULPGC-specific rule: - var_sshd_allow_groups.var: string variable, default "users" - sshd_set_allow_groups: uses sshd_lineinfile template to check and set AllowGroups in /etc/ssh/sshd_config - Add rule + var_sshd_allow_groups=users only to cis_level1_server_ulpgc - Revert changes to sshd_limit_user_access (restore warning, no bash) Co-Authored-By: Claude Sonnet 4.6 --- controls/cis_debian13.yml | 1 - .../sshd_limit_user_access/rule.yml | 5 +++ .../ssh_server/sshd_set_allow_groups/rule.yml | 31 +++++++++++++++++++ .../profiles/cis_level1_server_ulpgc.profile | 3 ++ 4 files changed, 39 insertions(+), 1 deletion(-) create mode 100644 linux_os/guide/services/ssh/ssh_server/sshd_set_allow_groups/rule.yml diff --git a/controls/cis_debian13.yml b/controls/cis_debian13.yml index 9e12025e76f2..acfd391b11ca 100644 --- a/controls/cis_debian13.yml +++ b/controls/cis_debian13.yml @@ -1686,7 +1686,6 @@ controls: - l1_workstation rules: - sshd_limit_user_access - - var_sshd_allow_groups=users status: automated - id: 5.1.5 diff --git a/linux_os/guide/services/ssh/ssh_server/sshd_limit_user_access/rule.yml b/linux_os/guide/services/ssh/ssh_server/sshd_limit_user_access/rule.yml index 2bafe99b91c6..45268c1823fc 100644 --- a/linux_os/guide/services/ssh/ssh_server/sshd_limit_user_access/rule.yml +++ b/linux_os/guide/services/ssh/ssh_server/sshd_limit_user_access/rule.yml @@ -65,3 +65,8 @@ references: nist: AC-3,CM-6(a) nist-csf: PR.AC-4,PR.AC-6,PR.PT-3 pcidss: Req-2.2.4 + +warnings: + - general: |- + Automated remediation is not available for this configuration check + because each system has unique user names and group names. diff --git a/linux_os/guide/services/ssh/ssh_server/sshd_set_allow_groups/rule.yml b/linux_os/guide/services/ssh/ssh_server/sshd_set_allow_groups/rule.yml new file mode 100644 index 000000000000..31bd04d911fa --- /dev/null +++ b/linux_os/guide/services/ssh/ssh_server/sshd_set_allow_groups/rule.yml @@ -0,0 +1,31 @@ +documentation_complete: true + +title: 'Set SSH AllowGroups' + +description: |- + The AllowGroups parameter restricts which groups of users + can log in via SSH. To configure it, edit /etc/ssh/sshd_config: +
    AllowGroups {{{ xccdf_value("var_sshd_allow_groups") }}}
    + +rationale: |- + Restricting SSH access to specific groups reduces the attack surface by + ensuring only authorized users can connect remotely. + +severity: medium + +ocil_clause: 'AllowGroups is not set to the required group' + +ocil: |- + Run the following command to verify the AllowGroups setting: +
    $ sudo grep -i AllowGroups /etc/ssh/sshd_config
    + The output should contain: +
    AllowGroups {{{ xccdf_value("var_sshd_allow_groups") }}}
    + +platform: package[openssh-server] + +template: + name: sshd_lineinfile + vars: + parameter: AllowGroups + xccdf_variable: var_sshd_allow_groups + datatype: string diff --git a/products/debian13/profiles/cis_level1_server_ulpgc.profile b/products/debian13/profiles/cis_level1_server_ulpgc.profile index e3f46f5bbb89..2007007d2479 100644 --- a/products/debian13/profiles/cis_level1_server_ulpgc.profile +++ b/products/debian13/profiles/cis_level1_server_ulpgc.profile @@ -35,3 +35,6 @@ selections: - service_syslogng_enabled - syslogng_filecreatemode - syslogng_nolisten + # 5.1.4: remediación específica ULPGC — configurar AllowGroups + - sshd_set_allow_groups + - var_sshd_allow_groups=users From 2afa1e6ee763deb6329a171fdf8fed23244320e7 Mon Sep 17 00:00:00 2001 From: Israel Villar Boillos Date: Thu, 4 Jun 2026 06:57:13 +0100 Subject: [PATCH 51/61] Add sysctl_apply_after_network rule for CIS 3.3.1.16 and 3.3.1.17 on Debian 13 On Debian 13, the network stack resets net.ipv4.conf.*.log_martians to 0 after systemd-sysctl.service has applied the hardened values at boot. Creating a systemd drop-in that adds After=network.target ensures the sysctl settings are applied in their final state. New rule sysctl_apply_after_network: - OVAL: checks for After=network.target in any .conf under /etc/systemd/system/systemd-sysctl.service.d/ - Bash: creates cac_hardening.conf with [Unit]\nAfter=network.target and runs systemctl daemon-reload - Added to CIS Debian 13 controls 3.3.1.16 and 3.3.1.17 Co-Authored-By: Claude Sonnet 4.6 --- controls/cis_debian13.yml | 2 + .../sysctl_apply_after_network/bash/shared.sh | 20 ++++++++ .../oval/shared.xml | 22 +++++++++ .../sysctl_apply_after_network/rule.yml | 46 +++++++++++++++++++ 4 files changed, 90 insertions(+) create mode 100644 linux_os/guide/system/network/network-kernel/network_host_and_router_parameters/sysctl_apply_after_network/bash/shared.sh create mode 100644 linux_os/guide/system/network/network-kernel/network_host_and_router_parameters/sysctl_apply_after_network/oval/shared.xml create mode 100644 linux_os/guide/system/network/network-kernel/network_host_and_router_parameters/sysctl_apply_after_network/rule.yml diff --git a/controls/cis_debian13.yml b/controls/cis_debian13.yml index acfd391b11ca..a5bbed629efc 100644 --- a/controls/cis_debian13.yml +++ b/controls/cis_debian13.yml @@ -1512,6 +1512,7 @@ controls: - l1_workstation rules: - sysctl_net_ipv4_conf_all_log_martians + - sysctl_apply_after_network status: automated - id: 3.3.1.17 @@ -1521,6 +1522,7 @@ controls: - l1_workstation rules: - sysctl_net_ipv4_conf_default_log_martians + - sysctl_apply_after_network status: automated - id: 3.3.1.18 diff --git a/linux_os/guide/system/network/network-kernel/network_host_and_router_parameters/sysctl_apply_after_network/bash/shared.sh b/linux_os/guide/system/network/network-kernel/network_host_and_router_parameters/sysctl_apply_after_network/bash/shared.sh new file mode 100644 index 000000000000..5b4d5f21e7ab --- /dev/null +++ b/linux_os/guide/system/network/network-kernel/network_host_and_router_parameters/sysctl_apply_after_network/bash/shared.sh @@ -0,0 +1,20 @@ +# platform = multi_platform_debian +# reboot = false +# strategy = configure +# complexity = low +# disruption = low + +DROPIN_DIR="/etc/systemd/system/systemd-sysctl.service.d" +DROPIN_FILE="${DROPIN_DIR}/cac_hardening.conf" + +mkdir -p "${DROPIN_DIR}" + +if ! grep -qrP "^After=.*network\.target" "${DROPIN_DIR}/" 2>/dev/null; then + if grep -q "^\[Unit\]" "${DROPIN_FILE}" 2>/dev/null; then + sed -i '/^\[Unit\]/a After=network.target' "${DROPIN_FILE}" + else + printf '[Unit]\nAfter=network.target\n' >> "${DROPIN_FILE}" + fi +fi + +systemctl daemon-reload diff --git a/linux_os/guide/system/network/network-kernel/network_host_and_router_parameters/sysctl_apply_after_network/oval/shared.xml b/linux_os/guide/system/network/network-kernel/network_host_and_router_parameters/sysctl_apply_after_network/oval/shared.xml new file mode 100644 index 000000000000..fab88d075053 --- /dev/null +++ b/linux_os/guide/system/network/network-kernel/network_host_and_router_parameters/sysctl_apply_after_network/oval/shared.xml @@ -0,0 +1,22 @@ + + + {{{ oval_metadata("Ensure systemd-sysctl.service has a drop-in override that adds network.target to its After= ordering.", rule_title=rule_title) }}} + + + + + + + + + + + /etc/systemd/system/systemd-sysctl.service.d + ^.*\.conf$ + ^After=.*network\.target + 1 + + diff --git a/linux_os/guide/system/network/network-kernel/network_host_and_router_parameters/sysctl_apply_after_network/rule.yml b/linux_os/guide/system/network/network-kernel/network_host_and_router_parameters/sysctl_apply_after_network/rule.yml new file mode 100644 index 000000000000..004e6a22cd4e --- /dev/null +++ b/linux_os/guide/system/network/network-kernel/network_host_and_router_parameters/sysctl_apply_after_network/rule.yml @@ -0,0 +1,46 @@ +documentation_complete: true + +title: 'Ensure systemd-sysctl Service Starts After Network Initialization' + +description: |- + On Debian 13, the network initialization resets kernel parameters that were + previously applied by systemd-sysctl.service during early boot. + To ensure sysctl values such as net.ipv4.conf.all.log_martians take + effect in their final state, systemd-sysctl.service must start after + network.target. +

    + Create a systemd drop-in override file + /etc/systemd/system/systemd-sysctl.service.d/cac_hardening.conf + with the following content: +
    [Unit]
    +    After=network.target
    + Then reload the systemd daemon: +
    $ sudo systemctl daemon-reload
    + +rationale: |- + systemd-sysctl.service runs early at boot and applies kernel parameters + from /etc/sysctl.conf and /etc/sysctl.d/. On systems where + the network stack initializes after this service, the kernel resets certain + network-related sysctl parameters to their defaults when interfaces are brought + up. This renders network sysctl hardening ineffective at runtime even when the + static configuration is correct. Ensuring the service runs after + network.target guarantees that hardened values persist. + +severity: medium + +platform: machine + +ocil_clause: 'no drop-in file configures After=network.target for systemd-sysctl.service' + +ocil: |- + Verify that a drop-in override for systemd-sysctl.service exists + and adds network.target to the ordering: +
    $ grep -r "After=.*network\.target" /etc/systemd/system/systemd-sysctl.service.d/
    + The output should contain a line matching After=network.target. + +fixtext: |- + Create the drop-in directory and override file: +
    $ sudo mkdir -p /etc/systemd/system/systemd-sysctl.service.d/
    +    $ sudo printf '[Unit]\nAfter=network.target\n' > \
    +        /etc/systemd/system/systemd-sysctl.service.d/cac_hardening.conf
    +    $ sudo systemctl daemon-reload
    From e2890c62be223bca53d94fcb3cd2072cf52c1026 Mon Sep 17 00:00:00 2001 From: Israel Villar Boillos Date: Thu, 4 Jun 2026 07:20:20 +0100 Subject: [PATCH 52/61] Fix sysctl_apply_after_network: use network-online.target instead of network.target network.target is reached before networking backends (systemd-networkd, NetworkManager via Netplan, ifupdown) finish bringing up interfaces. The kernel resets net.ipv4.conf.all.log_martians to 0 when interfaces are initialized, which happens after network.target but before network-online.target. Switching to After=network-online.target + Wants=network-online.target ensures systemd-sysctl runs after all managed interfaces are fully online, regardless of the networking backend (ifupdown, systemd-networkd, Netplan). Co-Authored-By: Claude Sonnet 4.6 --- .../sysctl_apply_after_network/bash/shared.sh | 6 +-- .../oval/shared.xml | 10 ++-- .../sysctl_apply_after_network/rule.yml | 51 +++++++++++-------- 3 files changed, 39 insertions(+), 28 deletions(-) diff --git a/linux_os/guide/system/network/network-kernel/network_host_and_router_parameters/sysctl_apply_after_network/bash/shared.sh b/linux_os/guide/system/network/network-kernel/network_host_and_router_parameters/sysctl_apply_after_network/bash/shared.sh index 5b4d5f21e7ab..dcc0342dc595 100644 --- a/linux_os/guide/system/network/network-kernel/network_host_and_router_parameters/sysctl_apply_after_network/bash/shared.sh +++ b/linux_os/guide/system/network/network-kernel/network_host_and_router_parameters/sysctl_apply_after_network/bash/shared.sh @@ -9,11 +9,11 @@ DROPIN_FILE="${DROPIN_DIR}/cac_hardening.conf" mkdir -p "${DROPIN_DIR}" -if ! grep -qrP "^After=.*network\.target" "${DROPIN_DIR}/" 2>/dev/null; then +if ! grep -qrP "^After=.*network-online\.target" "${DROPIN_DIR}/" 2>/dev/null; then if grep -q "^\[Unit\]" "${DROPIN_FILE}" 2>/dev/null; then - sed -i '/^\[Unit\]/a After=network.target' "${DROPIN_FILE}" + sed -i '/^\[Unit\]/a Wants=network-online.target\nAfter=network-online.target' "${DROPIN_FILE}" else - printf '[Unit]\nAfter=network.target\n' >> "${DROPIN_FILE}" + printf '[Unit]\nAfter=network-online.target\nWants=network-online.target\n' >> "${DROPIN_FILE}" fi fi diff --git a/linux_os/guide/system/network/network-kernel/network_host_and_router_parameters/sysctl_apply_after_network/oval/shared.xml b/linux_os/guide/system/network/network-kernel/network_host_and_router_parameters/sysctl_apply_after_network/oval/shared.xml index fab88d075053..7e6da2e03dbb 100644 --- a/linux_os/guide/system/network/network-kernel/network_host_and_router_parameters/sysctl_apply_after_network/oval/shared.xml +++ b/linux_os/guide/system/network/network-kernel/network_host_and_router_parameters/sysctl_apply_after_network/oval/shared.xml @@ -1,22 +1,22 @@ - - {{{ oval_metadata("Ensure systemd-sysctl.service has a drop-in override that adds network.target to its After= ordering.", rule_title=rule_title) }}} + + {{{ oval_metadata("Ensure systemd-sysctl.service has a drop-in override ordering it after network-online.target.", rule_title=rule_title) }}} - + comment="Check that a drop-in file orders systemd-sysctl.service after network-online.target"> /etc/systemd/system/systemd-sysctl.service.d ^.*\.conf$ - ^After=.*network\.target + ^After=.*network-online\.target 1 diff --git a/linux_os/guide/system/network/network-kernel/network_host_and_router_parameters/sysctl_apply_after_network/rule.yml b/linux_os/guide/system/network/network-kernel/network_host_and_router_parameters/sysctl_apply_after_network/rule.yml index 004e6a22cd4e..e855b89cd1d9 100644 --- a/linux_os/guide/system/network/network-kernel/network_host_and_router_parameters/sysctl_apply_after_network/rule.yml +++ b/linux_os/guide/system/network/network-kernel/network_host_and_router_parameters/sysctl_apply_after_network/rule.yml @@ -1,46 +1,57 @@ documentation_complete: true -title: 'Ensure systemd-sysctl Service Starts After Network Initialization' +title: 'Ensure systemd-sysctl Service Starts After Network Is Online' description: |- - On Debian 13, the network initialization resets kernel parameters that were - previously applied by systemd-sysctl.service during early boot. - To ensure sysctl values such as net.ipv4.conf.all.log_martians take - effect in their final state, systemd-sysctl.service must start after - network.target. + On Debian 13, the network stack (whether managed by ifupdown, + systemd-networkd, or NetworkManager via Netplan) may + initialize network interfaces after systemd-sysctl.service has + already applied kernel parameters at early boot. When interfaces are brought + up, the kernel resets certain network sysctl values to their defaults, + overriding the hardened configuration.

    - Create a systemd drop-in override file + To ensure the hardened sysctl values persist, create a systemd drop-in + override file /etc/systemd/system/systemd-sysctl.service.d/cac_hardening.conf with the following content:
    [Unit]
    -    After=network.target
    + After=network-online.target + Wants=network-online.target
Then reload the systemd daemon:
$ sudo systemctl daemon-reload
+ network-online.target is reached only when all managed network + interfaces are fully configured and online, regardless of the networking + backend in use. rationale: |- - systemd-sysctl.service runs early at boot and applies kernel parameters - from /etc/sysctl.conf and /etc/sysctl.d/. On systems where - the network stack initializes after this service, the kernel resets certain - network-related sysctl parameters to their defaults when interfaces are brought - up. This renders network sysctl hardening ineffective at runtime even when the - static configuration is correct. Ensuring the service runs after - network.target guarantees that hardened values persist. + systemd-sysctl.service runs early at boot and applies kernel + parameters from /etc/sysctl.conf and /etc/sysctl.d/. + When a networking subsystem (systemd-networkd, NetworkManager, + or ifupdown) initializes interfaces after this service has run, + the kernel resets network-related sysctl values such as + net.ipv4.conf.all.log_martians to their defaults. This renders + network sysctl hardening ineffective at runtime even when the static + configuration is correct. +

+ Ordering systemd-sysctl.service after network-online.target + ensures that all interfaces are fully up before sysctl values are applied, + so the hardened values are the final ones in effect. severity: medium platform: machine -ocil_clause: 'no drop-in file configures After=network.target for systemd-sysctl.service' +ocil_clause: 'no drop-in file orders systemd-sysctl.service after network-online.target' ocil: |- Verify that a drop-in override for systemd-sysctl.service exists - and adds network.target to the ordering: -
$ grep -r "After=.*network\.target" /etc/systemd/system/systemd-sysctl.service.d/
- The output should contain a line matching After=network.target. + and orders it after network-online.target: +
$ grep -r "After=.*network-online\.target" /etc/systemd/system/systemd-sysctl.service.d/
+ The output should contain a line matching After=network-online.target. fixtext: |- Create the drop-in directory and override file:
$ sudo mkdir -p /etc/systemd/system/systemd-sysctl.service.d/
-    $ sudo printf '[Unit]\nAfter=network.target\n' > \
+    $ sudo printf '[Unit]\nAfter=network-online.target\nWants=network-online.target\n' > \
         /etc/systemd/system/systemd-sysctl.service.d/cac_hardening.conf
     $ sudo systemctl daemon-reload
From c73f176e77115c42bc642aa5038d5a1ed94813a8 Mon Sep 17 00:00:00 2001 From: Israel Villar Boillos Date: Thu, 4 Jun 2026 18:29:38 +0100 Subject: [PATCH 53/61] Remove leftover bash/shared.sh from sshd_limit_user_access The file was added in c9af594273 but the approach was reverted in 5c0f5189b0 (site-specific AllowGroups moved to sshd_set_allow_groups). The deletion was not committed at the time. Co-Authored-By: Claude Sonnet 4.6 --- .../ssh/ssh_server/sshd_limit_user_access/bash/shared.sh | 9 --------- 1 file changed, 9 deletions(-) delete mode 100644 linux_os/guide/services/ssh/ssh_server/sshd_limit_user_access/bash/shared.sh diff --git a/linux_os/guide/services/ssh/ssh_server/sshd_limit_user_access/bash/shared.sh b/linux_os/guide/services/ssh/ssh_server/sshd_limit_user_access/bash/shared.sh deleted file mode 100644 index 314ab5ec1f18..000000000000 --- a/linux_os/guide/services/ssh/ssh_server/sshd_limit_user_access/bash/shared.sh +++ /dev/null @@ -1,9 +0,0 @@ -# platform = multi_platform_all -# reboot = false -# strategy = configure -# complexity = low -# disruption = low - -{{{ bash_instantiate_variables("var_sshd_allow_groups") }}} - -{{{ bash_sshd_remediation(parameter="AllowGroups", value="$var_sshd_allow_groups", config_is_distributed=sshd_distributed_config, rule_id=rule_id) }}} From 14a92283a931d6b82635998f05439c50ecc9908d Mon Sep 17 00:00:00 2001 From: Israel Villar Boillos Date: Thu, 4 Jun 2026 18:42:47 +0100 Subject: [PATCH 54/61] Add upstream note to AppArmor 1.3.1.3 control Incorporate note from ComplianceAsCode upstream explaining that the CIS recommendation for enforcing AppArmor profiles does not adequately address force-complain/unconfined profiles and may break applications. References upstream CIS Workbench ticket for context. Co-Authored-By: Claude Sonnet 4.6 --- controls/cis_debian13.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/controls/cis_debian13.yml b/controls/cis_debian13.yml index a5bbed629efc..e318bbab1c79 100644 --- a/controls/cis_debian13.yml +++ b/controls/cis_debian13.yml @@ -475,6 +475,12 @@ controls: rules: - all_apparmor_profiles_enforced status: automated + notes: | + CIS recommendation does not adequately address the nuances + of various profiles, including disabled, force-complain, + and unconfined. Currently, the control changes the default apparmor + mode for all profiles in /etc/apparmor.d which can + break certain applications. See https://workbench.cisecurity.org/benchmarks/18959/tickets/23987 - id: 1.3.1.4 title: Ensure apparmor_restrict_unprivileged_unconfined is enabled (Automated) From 0def0941eafdbace11d3aaaa28ab10a119d8f1d1 Mon Sep 17 00:00:00 2001 From: Israel Villar Boillos Date: Thu, 4 Jun 2026 18:49:16 +0100 Subject: [PATCH 55/61] Fix product.yml: add components_root, remove duplicate reference_uris - Add components_root: "../../components" consistent with upstream and other Debian-family products - Remove duplicate reference_uris block with the generic CIS URL, keeping only the Debian-specific benchmark URL Co-Authored-By: Claude Sonnet 4.6 --- products/debian13/product.yml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/products/debian13/product.yml b/products/debian13/product.yml index 774ea0641c72..115c0f8478fa 100644 --- a/products/debian13/product.yml +++ b/products/debian13/product.yml @@ -10,6 +10,7 @@ major_version_ordinal: 13 benchmark_id: DEBIAN-13 benchmark_root: "../../linux_os/guide" +components_root: "../../components" profiles_root: "./profiles" @@ -32,9 +33,6 @@ cpes: title: "Debian Linux 13" check_id: installed_OS_is_debian13 -reference_uris: - cis: 'https://www.cisecurity.org/cis-benchmarks/' - # Mapping of CPE platform to package platform_package_overrides: gdm: gdm3 From 571241ff4be0a3998557513776906b25ec9bb310 Mon Sep 17 00:00:00 2001 From: Israel Villar Boillos Date: Thu, 4 Jun 2026 18:55:47 +0100 Subject: [PATCH 56/61] Remove sysctl_apply_after_network rule: causes systemd boot cycle MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Making systemd-sysctl.service depend on network-online.target via After=/Wants= creates an ordering cycle on Debian 13: network-online.target → networking.service → sysinit.target → systemd-sysctl.service → network-online.target systemd breaks the cycle by dropping networking.service and systemd-sysctl.service from the boot transaction, so sysctl parameters are never applied at boot — worse than the original problem. Remove the rule and its mappings in CIS controls 3.3.1.16/3.3.1.17. The standard sysctl rules plus sysctl_conf_symlink_etc_sysctl_d are sufficient; the log_martians all/default values are not reset by interface bring-up in the way per-interface values can be. Co-Authored-By: Claude Sonnet 4.6 --- controls/cis_debian13.yml | 2 - .../sysctl_apply_after_network/bash/shared.sh | 20 ------- .../oval/shared.xml | 22 ------- .../sysctl_apply_after_network/rule.yml | 57 ------------------- 4 files changed, 101 deletions(-) delete mode 100644 linux_os/guide/system/network/network-kernel/network_host_and_router_parameters/sysctl_apply_after_network/bash/shared.sh delete mode 100644 linux_os/guide/system/network/network-kernel/network_host_and_router_parameters/sysctl_apply_after_network/oval/shared.xml delete mode 100644 linux_os/guide/system/network/network-kernel/network_host_and_router_parameters/sysctl_apply_after_network/rule.yml diff --git a/controls/cis_debian13.yml b/controls/cis_debian13.yml index e318bbab1c79..f632264e8a35 100644 --- a/controls/cis_debian13.yml +++ b/controls/cis_debian13.yml @@ -1518,7 +1518,6 @@ controls: - l1_workstation rules: - sysctl_net_ipv4_conf_all_log_martians - - sysctl_apply_after_network status: automated - id: 3.3.1.17 @@ -1528,7 +1527,6 @@ controls: - l1_workstation rules: - sysctl_net_ipv4_conf_default_log_martians - - sysctl_apply_after_network status: automated - id: 3.3.1.18 diff --git a/linux_os/guide/system/network/network-kernel/network_host_and_router_parameters/sysctl_apply_after_network/bash/shared.sh b/linux_os/guide/system/network/network-kernel/network_host_and_router_parameters/sysctl_apply_after_network/bash/shared.sh deleted file mode 100644 index dcc0342dc595..000000000000 --- a/linux_os/guide/system/network/network-kernel/network_host_and_router_parameters/sysctl_apply_after_network/bash/shared.sh +++ /dev/null @@ -1,20 +0,0 @@ -# platform = multi_platform_debian -# reboot = false -# strategy = configure -# complexity = low -# disruption = low - -DROPIN_DIR="/etc/systemd/system/systemd-sysctl.service.d" -DROPIN_FILE="${DROPIN_DIR}/cac_hardening.conf" - -mkdir -p "${DROPIN_DIR}" - -if ! grep -qrP "^After=.*network-online\.target" "${DROPIN_DIR}/" 2>/dev/null; then - if grep -q "^\[Unit\]" "${DROPIN_FILE}" 2>/dev/null; then - sed -i '/^\[Unit\]/a Wants=network-online.target\nAfter=network-online.target' "${DROPIN_FILE}" - else - printf '[Unit]\nAfter=network-online.target\nWants=network-online.target\n' >> "${DROPIN_FILE}" - fi -fi - -systemctl daemon-reload diff --git a/linux_os/guide/system/network/network-kernel/network_host_and_router_parameters/sysctl_apply_after_network/oval/shared.xml b/linux_os/guide/system/network/network-kernel/network_host_and_router_parameters/sysctl_apply_after_network/oval/shared.xml deleted file mode 100644 index 7e6da2e03dbb..000000000000 --- a/linux_os/guide/system/network/network-kernel/network_host_and_router_parameters/sysctl_apply_after_network/oval/shared.xml +++ /dev/null @@ -1,22 +0,0 @@ - - - {{{ oval_metadata("Ensure systemd-sysctl.service has a drop-in override ordering it after network-online.target.", rule_title=rule_title) }}} - - - - - - - - - - - /etc/systemd/system/systemd-sysctl.service.d - ^.*\.conf$ - ^After=.*network-online\.target - 1 - - diff --git a/linux_os/guide/system/network/network-kernel/network_host_and_router_parameters/sysctl_apply_after_network/rule.yml b/linux_os/guide/system/network/network-kernel/network_host_and_router_parameters/sysctl_apply_after_network/rule.yml deleted file mode 100644 index e855b89cd1d9..000000000000 --- a/linux_os/guide/system/network/network-kernel/network_host_and_router_parameters/sysctl_apply_after_network/rule.yml +++ /dev/null @@ -1,57 +0,0 @@ -documentation_complete: true - -title: 'Ensure systemd-sysctl Service Starts After Network Is Online' - -description: |- - On Debian 13, the network stack (whether managed by ifupdown, - systemd-networkd, or NetworkManager via Netplan) may - initialize network interfaces after systemd-sysctl.service has - already applied kernel parameters at early boot. When interfaces are brought - up, the kernel resets certain network sysctl values to their defaults, - overriding the hardened configuration. -

- To ensure the hardened sysctl values persist, create a systemd drop-in - override file - /etc/systemd/system/systemd-sysctl.service.d/cac_hardening.conf - with the following content: -
[Unit]
-    After=network-online.target
-    Wants=network-online.target
- Then reload the systemd daemon: -
$ sudo systemctl daemon-reload
- network-online.target is reached only when all managed network - interfaces are fully configured and online, regardless of the networking - backend in use. - -rationale: |- - systemd-sysctl.service runs early at boot and applies kernel - parameters from /etc/sysctl.conf and /etc/sysctl.d/. - When a networking subsystem (systemd-networkd, NetworkManager, - or ifupdown) initializes interfaces after this service has run, - the kernel resets network-related sysctl values such as - net.ipv4.conf.all.log_martians to their defaults. This renders - network sysctl hardening ineffective at runtime even when the static - configuration is correct. -

- Ordering systemd-sysctl.service after network-online.target - ensures that all interfaces are fully up before sysctl values are applied, - so the hardened values are the final ones in effect. - -severity: medium - -platform: machine - -ocil_clause: 'no drop-in file orders systemd-sysctl.service after network-online.target' - -ocil: |- - Verify that a drop-in override for systemd-sysctl.service exists - and orders it after network-online.target: -
$ grep -r "After=.*network-online\.target" /etc/systemd/system/systemd-sysctl.service.d/
- The output should contain a line matching After=network-online.target. - -fixtext: |- - Create the drop-in directory and override file: -
$ sudo mkdir -p /etc/systemd/system/systemd-sysctl.service.d/
-    $ sudo printf '[Unit]\nAfter=network-online.target\nWants=network-online.target\n' > \
-        /etc/systemd/system/systemd-sysctl.service.d/cac_hardening.conf
-    $ sudo systemctl daemon-reload
From afe93ce035670d44ffb557aae8140b41918f4902 Mon Sep 17 00:00:00 2001 From: Israel Villar Boillos Date: Thu, 4 Jun 2026 19:38:25 +0100 Subject: [PATCH 57/61] Add sysctl_reapply_after_network rule for Debian 13 On Debian 13, the kernel resets network sysctl values when interfaces come up, overriding the early-boot configuration applied by systemd-sysctl.service. This causes hardened values such as net.ipv4.conf.all.log_martians to revert to 0 at runtime. Add a rule that creates and enables a systemd oneshot service (sysctl-reapply-network.service) with DefaultDependencies=no and After=networking.service. The service runs sysctl --system after network interfaces are up, ensuring hardened values persist. Using DefaultDependencies=no avoids the ordering cycle that broke boot when systemd-sysctl.service itself was made to depend on network-online.target. Map the rule to CIS controls 3.3.1.16 and 3.3.1.17 alongside the corresponding sysctl value rules, with notes explaining the rationale. Co-Authored-By: Claude Sonnet 4.6 --- controls/cis_debian13.yml | 10 ++++ .../bash/shared.sh | 32 +++++++++++++ .../oval/shared.xml | 37 +++++++++++++++ .../sysctl_reapply_after_network/rule.yml | 47 +++++++++++++++++++ 4 files changed, 126 insertions(+) create mode 100644 linux_os/guide/system/permissions/restrictions/sysctl_reapply_after_network/bash/shared.sh create mode 100644 linux_os/guide/system/permissions/restrictions/sysctl_reapply_after_network/oval/shared.xml create mode 100644 linux_os/guide/system/permissions/restrictions/sysctl_reapply_after_network/rule.yml diff --git a/controls/cis_debian13.yml b/controls/cis_debian13.yml index f632264e8a35..e0c6db034727 100644 --- a/controls/cis_debian13.yml +++ b/controls/cis_debian13.yml @@ -1518,7 +1518,14 @@ controls: - l1_workstation rules: - sysctl_net_ipv4_conf_all_log_martians + - sysctl_reapply_after_network status: automated + notes: |- + On Debian 13, the kernel resets network sysctl values when interfaces + come up, overriding the early-boot configuration applied by + systemd-sysctl.service. sysctl_reapply_after_network creates a oneshot + service that re-applies all sysctl settings after networking is up, + ensuring the hardened values persist at runtime. - id: 3.3.1.17 title: Ensure net.ipv4.conf.default.log_martians is configured (Automated) @@ -1527,7 +1534,10 @@ controls: - l1_workstation rules: - sysctl_net_ipv4_conf_default_log_martians + - sysctl_reapply_after_network status: automated + notes: |- + See notes for 3.3.1.16. - id: 3.3.1.18 title: Ensure net.ipv4.tcp_syncookies is configured (Automated) diff --git a/linux_os/guide/system/permissions/restrictions/sysctl_reapply_after_network/bash/shared.sh b/linux_os/guide/system/permissions/restrictions/sysctl_reapply_after_network/bash/shared.sh new file mode 100644 index 000000000000..c5853b07e720 --- /dev/null +++ b/linux_os/guide/system/permissions/restrictions/sysctl_reapply_after_network/bash/shared.sh @@ -0,0 +1,32 @@ +# platform = multi_platform_debian +# reboot = false +# strategy = configure +# complexity = low +# disruption = low + +SERVICE_FILE="/etc/systemd/system/sysctl-reapply-network.service" + +cat > "${SERVICE_FILE}" << 'EOF' +[Unit] +Description=Re-apply sysctl hardening after network interfaces come up +After=networking.service systemd-networkd.service +DefaultDependencies=no + +[Service] +Type=oneshot +ExecStart=/sbin/sysctl --system +RemainAfterExit=yes + +[Install] +WantedBy=multi-user.target +EOF + +chown root:root "${SERVICE_FILE}" +chmod 0644 "${SERVICE_FILE}" + +systemctl daemon-reload +systemctl enable sysctl-reapply-network.service + +if [[ $(systemctl is-system-running) != "offline" ]]; then + systemctl start sysctl-reapply-network.service +fi diff --git a/linux_os/guide/system/permissions/restrictions/sysctl_reapply_after_network/oval/shared.xml b/linux_os/guide/system/permissions/restrictions/sysctl_reapply_after_network/oval/shared.xml new file mode 100644 index 000000000000..7853ffdb8796 --- /dev/null +++ b/linux_os/guide/system/permissions/restrictions/sysctl_reapply_after_network/oval/shared.xml @@ -0,0 +1,37 @@ + + + {{{ oval_metadata("Ensure sysctl-reapply-network.service exists and is enabled.", rule_title=rule_title) }}} + + + + + + + + + + + + /etc/systemd/system/sysctl-reapply-network.service + + + + + + + + + sysctl-reapply-network.service + UnitFileState + + + + enabled + + diff --git a/linux_os/guide/system/permissions/restrictions/sysctl_reapply_after_network/rule.yml b/linux_os/guide/system/permissions/restrictions/sysctl_reapply_after_network/rule.yml new file mode 100644 index 000000000000..466bf7fcea48 --- /dev/null +++ b/linux_os/guide/system/permissions/restrictions/sysctl_reapply_after_network/rule.yml @@ -0,0 +1,47 @@ +documentation_complete: true + +title: 'Ensure sysctl network settings are re-applied after network interfaces come up' + +description: |- + On Debian systems, the kernel resets certain network sysctl values when a + network interface is brought up, overriding hardened settings applied at + early boot by systemd-sysctl.service. +

+ Create a systemd oneshot service + /etc/systemd/system/sysctl-reapply-network.service: +
[Unit]
+    Description=Re-apply sysctl hardening after network interfaces come up
+    After=networking.service systemd-networkd.service
+    DefaultDependencies=no
+
+    [Service]
+    Type=oneshot
+    ExecStart=/sbin/sysctl --system
+    RemainAfterExit=yes
+
+    [Install]
+    WantedBy=multi-user.target
+ Then reload the systemd daemon and enable the service: +
$ sudo systemctl daemon-reload
+    $ sudo systemctl enable sysctl-reapply-network.service
+ +rationale: |- + When a network interface is initialized, the Linux kernel may reset interface-level + and global sysctl values to their defaults. Running sysctl --system after + network interfaces are up ensures the hardened values from /etc/sysctl.conf + and /etc/sysctl.d/ are the final values in effect at runtime. +

+ Using DefaultDependencies=no prevents the ordering cycle that would arise + from modifying systemd-sysctl.service itself to depend on + network-online.target. + +severity: medium + +platform: machine + +ocil_clause: 'the sysctl-reapply-network service does not exist or is not enabled' + +ocil: |- + Verify that the sysctl-reapply-network.service unit is enabled: +
$ systemctl is-enabled sysctl-reapply-network.service
+ The output should be enabled. From 2b85cda8d94e6eadc3945682dbe8c00282f17de5 Mon Sep 17 00:00:00 2001 From: Israel Villar Boillos Date: Thu, 4 Jun 2026 20:03:27 +0100 Subject: [PATCH 58/61] Map Debian 13 CIS rules to component files Add missing rule-to-component mappings required by components_root in products/debian13/product.yml. Without these mappings the build fails with "isn't mapped to any component" errors. - apt.yml: apt_disable_weak_dependencies, directory/file owner/group/ permissions rules for apt GPG keys, sources.list.d, trusted.gpg.d, auth.conf.d, and usr/share/keyrings - apparmor.yml: sysctl_kernel_apparmor_restrict_unprivileged_unconfined - kea.yml: service_kea_dhcp{4,6,_ddns}_server_disabled - kernel.yml: sysctl_conf_symlink_etc_sysctl_d, sysctl_reapply_after_network - openssh.yml: sshd_set_allow_groups - syslog-ng.yml: syslogng_filecreatemode, syslogng_nolisten - ufw.yml: ufw_default_incoming_rule, ufw_default_outgoing_rule, ufw_disabled_routed Co-Authored-By: Claude Sonnet 4.6 --- components/apparmor.yml | 1 + components/apt.yml | 22 ++++++++++++++++++++++ components/kea.yml | 3 +++ components/kernel.yml | 2 ++ components/openssh.yml | 1 + components/syslog-ng.yml | 2 ++ components/ufw.yml | 3 +++ 7 files changed, 34 insertions(+) diff --git a/components/apparmor.yml b/components/apparmor.yml index 9f2e000260e9..770f9d537214 100644 --- a/components/apparmor.yml +++ b/components/apparmor.yml @@ -12,3 +12,4 @@ rules: - package_apparmor_installed - package_apparmor-utils_installed - package_pam_apparmor_installed +- sysctl_kernel_apparmor_restrict_unprivileged_unconfined diff --git a/components/apt.yml b/components/apt.yml index cb1cbd476842..8148a2d7df81 100644 --- a/components/apt.yml +++ b/components/apt.yml @@ -5,4 +5,26 @@ packages: - apt rules: - apt_conf_disallow_unauthenticated +- apt_disable_weak_dependencies - apt_sources_list_official +- directory_groupowner_apt_auth_conf_d +- directory_groupowner_apt_sources_list_d +- directory_groupowner_apt_trusted_gpg_d +- directory_groupowner_usr_share_keyrings +- directory_owner_apt_auth_conf_d +- directory_owner_apt_sources_list_d +- directory_owner_apt_trusted_gpg_d +- directory_owner_usr_share_keyrings +- directory_permissions_apt_auth_conf_d +- directory_permissions_apt_sources_list_d +- directory_permissions_apt_trusted_gpg_d +- directory_permissions_usr_share_keyrings +- file_groupowner_apt_auth_conf_d +- file_groupowner_apt_gpg_keys +- file_groupowner_apt_sources_list_d +- file_owner_apt_auth_conf_d +- file_owner_apt_gpg_keys +- file_owner_apt_sources_list_d +- file_permissions_apt_auth_conf_d +- file_permissions_apt_gpg_keys +- file_permissions_apt_sources_list_d diff --git a/components/kea.yml b/components/kea.yml index b4db421edd9d..c80631898db3 100644 --- a/components/kea.yml +++ b/components/kea.yml @@ -3,3 +3,6 @@ packages: - kea rules: - package_kea_removed +- service_kea_dhcp4_server_disabled +- service_kea_dhcp6_server_disabled +- service_kea_dhcp_ddns_server_disabled diff --git a/components/kernel.yml b/components/kernel.yml index ef50ac95e91e..eee782928c69 100644 --- a/components/kernel.yml +++ b/components/kernel.yml @@ -201,6 +201,8 @@ rules: - sysctl_net_ipv6_conf_default_forwarding - sysctl_net_ipv6_conf_default_max_addresses - sysctl_net_ipv6_conf_default_router_solicitations +- sysctl_conf_symlink_etc_sysctl_d +- sysctl_reapply_after_network - sysctl_user_max_user_namespaces - sysctl_user_max_user_namespaces_no_remediation - sysctl_vm_mmap_min_addr diff --git a/components/openssh.yml b/components/openssh.yml index 63c1017aecf8..06dac05cba3a 100644 --- a/components/openssh.yml +++ b/components/openssh.yml @@ -71,6 +71,7 @@ rules: - sshd_enable_x11_forwarding - sshd_limit_user_access - sshd_print_last_log +- sshd_set_allow_groups - sshd_rekey_limit - sshd_set_idle_timeout - sshd_set_keepalive diff --git a/components/syslog-ng.yml b/components/syslog-ng.yml index 88b09f225e35..9862dda16258 100644 --- a/components/syslog-ng.yml +++ b/components/syslog-ng.yml @@ -4,3 +4,5 @@ packages: rules: - package_syslogng_installed - service_syslogng_enabled +- syslogng_filecreatemode +- syslogng_nolisten diff --git a/components/ufw.yml b/components/ufw.yml index 3ceaeeed9064..b79ffaafd565 100644 --- a/components/ufw.yml +++ b/components/ufw.yml @@ -10,6 +10,9 @@ rules: - service_ufw_enabled - set_ufw_default_rule - set_ufw_loopback_traffic +- ufw_default_incoming_rule +- ufw_default_outgoing_rule +- ufw_disabled_routed - ufw_only_required_services - ufw_rate_limit - ufw_rules_for_open_ports From 1d47c1dc35f208371676105f8f6c4e2ff82c1884 Mon Sep 17 00:00:00 2001 From: Israel Villar Boillos Date: Thu, 4 Jun 2026 21:48:48 +0100 Subject: [PATCH 59/61] Fix accounts_password bash template: skip pam-auth-update on Debian 13 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit On Debian 13 (like Debian 12), libpam-pwquality is installed by default and pam_pwquality.so is already active in /etc/pam.d/common-password. Calling pam-auth-update is unnecessary and causes the first remediation pass to fail: pam-auth-update resolves the conflict between cac_pwquality and the standard pwquality pam-config by removing pam_pwquality.so from common-password, causing the pwquality OVAL checks to return notapplicable and preventing the parameter values from being written to pwquality.conf. Remove debian13 from the ubuntu2404 condition so Debian 13 is treated like Debian 12 — write values directly to pwquality.conf without calling pam-auth-update. Co-Authored-By: Claude Sonnet 4.6 --- shared/templates/accounts_password/bash.template | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/shared/templates/accounts_password/bash.template b/shared/templates/accounts_password/bash.template index 4eb0abaaa98e..e61ead0a6be0 100644 --- a/shared/templates/accounts_password/bash.template +++ b/shared/templates/accounts_password/bash.template @@ -27,7 +27,7 @@ fi }}} {{% endif %}} -{{% if product == "ubuntu2404" or product == "debian13" %}} +{{% if product == "ubuntu2404" %}} {{{ bash_pam_pwquality_enable() }}} {{% endif %}} From fb093610bc62955605e0ae7a2de79641fbd7ac76 Mon Sep 17 00:00:00 2001 From: Israel Villar Boillos Date: Fri, 5 Jun 2026 06:09:53 +0100 Subject: [PATCH 60/61] Fix accounts_password_pam_pwquality_enabled bash: skip pam-auth-update on Debian On Debian (12 and 13), libpam-pwquality is installed by default and pam_pwquality.so is already active in /etc/pam.d/common-password. Calling pam-auth-update via bash_pam_pwquality_enable() creates a cac_pwquality pam-config that conflicts with the standard pwquality config, causing pam-auth-update to remove pam_pwquality.so from common-password. This makes all accounts_password_pam_* OVAL checks fail because they extend the accounts_password_pam_pwquality definition which checks for pam_pwquality.so in common-password. Extend the condition that uses bash_ensure_pam_module_configuration (direct PAM file edit, no pam-auth-update) to include all Debian products, consistent with the fix applied to the accounts_password bash template in the previous commit. Co-Authored-By: Claude Sonnet 4.6 --- .../accounts_password_pam_pwquality_enabled/bash/shared.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/linux_os/guide/system/accounts/accounts-pam/password_quality/password_quality_pwquality/accounts_password_pam_pwquality_enabled/bash/shared.sh b/linux_os/guide/system/accounts/accounts-pam/password_quality/password_quality_pwquality/accounts_password_pam_pwquality_enabled/bash/shared.sh index aff806f7f3be..587deb246ad0 100644 --- a/linux_os/guide/system/accounts/accounts-pam/password_quality/password_quality_pwquality/accounts_password_pam_pwquality_enabled/bash/shared.sh +++ b/linux_os/guide/system/accounts/accounts-pam/password_quality/password_quality_pwquality/accounts_password_pam_pwquality_enabled/bash/shared.sh @@ -1,6 +1,6 @@ # platform = multi_platform_sle,multi_platform_ubuntu,multi_platform_debian -{{% if product in ['sle15', 'sle16'] %}} +{{% if product in ['sle15', 'sle16'] or 'debian' in product %}} {{{ bash_ensure_pam_module_configuration('/etc/pam.d/common-password', 'password', 'requisite', 'pam_pwquality.so', '', '', 'BOF') }}} {{% else %}} {{{ bash_pam_pwquality_enable() }}} From 9a4d724f7d9e2f20af5fcbec7fb9a4887ca7f5c8 Mon Sep 17 00:00:00 2001 From: Israel Villar Boillos Date: Fri, 5 Jun 2026 06:39:36 +0100 Subject: [PATCH 61/61] Fix log file permission rules for Debian: align with CIS Debian 13 6.1.3.1 CIS Debian 13 benchmark (6.1.3.1) requires: - /var/log/messages: group root|adm, max permissions 0640 - /var/log/apt/ files: max permissions 0644 (perm_mask 0133) - Other log files: max permissions 0640 Three rules were too strict for Debian: - file_groupowner_var_log_messages: extend ubuntu2404 condition to include 'debian' in product so the rule accepts group adm|root instead of requiring GID 0 (root only). - file_permissions_var_log_messages: extend condition to include 'debian' in product so the rule checks for 0640 instead of 0600. - permissions_local_var_log: add excluded_files@debian13 to skip history.log*, eipp.log.xz* (apt files, CIS allows 0644) and [bw]tmp/lastlog (different ownership rules); add recursive@debian13 to check subdirectories including /var/log/apt/. Co-Authored-By: Claude Sonnet 4.6 --- .../permissions/files/permissions_local_var_log/rule.yml | 2 ++ .../file_groupowner_var_log_messages/rule.yml | 4 ++-- .../file_permissions_var_log_messages/rule.yml | 2 +- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/linux_os/guide/system/permissions/files/permissions_local_var_log/rule.yml b/linux_os/guide/system/permissions/files/permissions_local_var_log/rule.yml index 1be0bd45ad28..192383d53e40 100644 --- a/linux_os/guide/system/permissions/files/permissions_local_var_log/rule.yml +++ b/linux_os/guide/system/permissions/files/permissions_local_var_log/rule.yml @@ -57,10 +57,12 @@ template: excluded_files@slmicro5: ['*[bw]tmp', '*lastlog'] excluded_files@slmicro6: ['*[bw]tmp', '*lastlog'] excluded_files@ubuntu2204: ['history.log*', 'eipp.log.xz*', '[bw]tmp', '[bw]tmp.*', '[bw]tmp-*', 'lastlog', 'lastlog.*'] + excluded_files@debian13: ['history.log*', 'eipp.log.xz*', '[bw]tmp', '[bw]tmp.*', '[bw]tmp-*', 'lastlog', 'lastlog.*'] excluded_files@ubuntu2404: ['history.log*', 'eipp.log.xz*', '[bw]tmp', '[bw]tmp.*', '[bw]tmp-*', 'lastlog', 'lastlog.*', 'cloud-init.log*', 'localmessages*', 'waagent.log*'] file_regex: '.*' filemode: '0640' filepath: /var/log/ + recursive@debian13: 'true' recursive@sle12: 'true' recursive@sle15: 'true' recursive@sle16: 'true' diff --git a/linux_os/guide/system/permissions/files/permissions_var_log_dir/file_groupowner_var_log_messages/rule.yml b/linux_os/guide/system/permissions/files/permissions_var_log_dir/file_groupowner_var_log_messages/rule.yml index db4e868bc414..68efa233a2dc 100644 --- a/linux_os/guide/system/permissions/files/permissions_var_log_dir/file_groupowner_var_log_messages/rule.yml +++ b/linux_os/guide/system/permissions/files/permissions_var_log_dir/file_groupowner_var_log_messages/rule.yml @@ -2,7 +2,7 @@ documentation_complete: true title: 'Verify Group Who Owns /var/log/messages File' -{{%- if product in ['ubuntu2404'] %}} +{{%- if product in ['ubuntu2404'] or 'debian' in product %}} description: '{{{ describe_file_group_owner(file="/var/log/messages", group="adm|root") }}}' {{%- else %}} description: '{{{ describe_file_group_owner(file="/var/log/messages", group="root") }}}' @@ -23,7 +23,7 @@ references: srg: SRG-OS-000206-GPOS-00084 stigid@ol8: OL08-00-010230 -{{%- if product in ['ubuntu2404'] %}} +{{%- if product in ['ubuntu2404'] or 'debian' in product %}} ocil_clause: '{{{ ocil_clause_file_group_owner(file="/var/log/messages", group="adm|root") }}}' ocil: |- diff --git a/linux_os/guide/system/permissions/files/permissions_var_log_dir/file_permissions_var_log_messages/rule.yml b/linux_os/guide/system/permissions/files/permissions_var_log_dir/file_permissions_var_log_messages/rule.yml index 1eee00ea1d2e..845a23865cfe 100644 --- a/linux_os/guide/system/permissions/files/permissions_var_log_dir/file_permissions_var_log_messages/rule.yml +++ b/linux_os/guide/system/permissions/files/permissions_var_log_dir/file_permissions_var_log_messages/rule.yml @@ -2,7 +2,7 @@ documentation_complete: true title: 'Verify Permissions on /var/log/messages File' -{{% if product in ['ubuntu2404','ol9','ol8'] %}} +{{% if product in ['ubuntu2404','ol9','ol8'] or 'debian' in product %}} {{% set target_perms_octal="0640" %}} {{% set target_perms="-rw-r-----" %}} {{% else %}}