From a420bccf45a5c91f4669fc3e3de026f27650f8d8 Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Tue, 14 Jan 2025 09:00:11 +0000 Subject: [PATCH 1/9] address issue #63 thanks to @PrymalInstynct Signed-off-by: Mark Bolwell --- tasks/Cat2/RHEL-09-23xxxx.yml | 32 +++++++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/tasks/Cat2/RHEL-09-23xxxx.yml b/tasks/Cat2/RHEL-09-23xxxx.yml index 4da54f5..7d99e84 100644 --- a/tasks/Cat2/RHEL-09-23xxxx.yml +++ b/tasks/Cat2/RHEL-09-23xxxx.yml @@ -1133,6 +1133,8 @@ ansible.builtin.file: mode: 'u-x,go-wx' path: /etc/group- + failed_when: discovered_group_hyphen_exists.state not in '[ file, absent ]' + register: discovered_group_hyphen_exists - name: "MEDIUM | RHEL-09-232065 | PATCH | RHEL 9 /etc/gshadow file must have mode 0000 or less permissive to prevent unauthorized access." when: @@ -1148,6 +1150,8 @@ ansible.builtin.file: mode: 'ugo-rwx' path: /etc/gshadow + failed_when: discovered_gshadow_file_exists.state not in '[ file, absent ]' + register: discovered_gshadow_file_exists - name: "MEDIUM | RHEL-09-232070 | PATCH | RHEL 9 /etc/gshadow- file must have mode 0000 or less permissive to prevent unauthorized access." when: @@ -1163,6 +1167,8 @@ ansible.builtin.file: mode: 'ugo-rwx' path: /etc/gshadow- + failed_when: discovered_gshadow_hyphen_exists.state not in '[ file, absent ]' + register: discovered_gshadow_hyphen_exists - name: "MEDIUM | RHEL-09-232075 | PATCH | RHEL 9 /etc/passwd file must have mode 0644 or less permissive to prevent unauthorized access." when: @@ -1193,6 +1199,8 @@ ansible.builtin.file: mode: 'u-x,go-wx' path: /etc/passwd- + failed_when: discovered_passwd_hyphen_exists.state not in '[ file, absent ]' + register: discovered_passwd_hyphen_exists - name: "MEDIUM | RHEL-09-232085 | PATCH | RHEL 9 /etc/shadow- file must have mode 0000 or less permissive to prevent unauthorized access." when: @@ -1208,6 +1216,8 @@ ansible.builtin.file: mode: 'ugo-rwx' path: /etc/shadow- + failed_when: discovered_shadow_hyphen_exists.state not in '[ file, absent ]' + register: discovered_shadow_hyphen_exists - name: "MEDIUM | RHEL-09-232090 | PATCH | RHEL 9 /etc/group file must be owned by root." when: @@ -1253,6 +1263,8 @@ ansible.builtin.file: owner: root path: /etc/group- + failed_when: discovered_group_hyphen_exists.state not in '[ file, absent ]' + register: discovered_group_hyphen_exists - name: "MEDIUM | RHEL-09-232105 | PATCH | RHEL 9 /etc/group- file must be group-owned by root." when: @@ -1268,6 +1280,8 @@ ansible.builtin.file: group: root path: /etc/group- + failed_when: discovered_group_hyphen_exists.state not in '[ file, absent ]' + register: discovered_group_hyphen_exists - name: "MEDIUM | RHEL-09-232110 | PATCH | RHEL 9 /etc/gshadow file must be owned by root." when: @@ -1283,6 +1297,8 @@ ansible.builtin.file: owner: root path: /etc/gshadow + failed_when: discovered_gshadow_file_exists.state not in '[ file, absent ]' + register: discovered_gshadow_file_exists - name: "MEDIUM | RHEL-09-232115 | PATCH | RHEL 9 /etc/gshadow file must be group-owned by root." when: @@ -1298,6 +1314,8 @@ ansible.builtin.file: group: root path: /etc/gshadow + failed_when: discovered_gshadow_file_exists.state not in '[ file, absent ]' + register: discovered_gshadow_file_exists - name: "MEDIUM | RHEL-09-232120 | PATCH | RHEL 9 /etc/gshadow- file must be owned by root." when: @@ -1313,6 +1331,8 @@ ansible.builtin.file: owner: root path: /etc/gshadow- + failed_when: discovered_gshadow_hyphen_exists.state not in '[ file, absent ]' + register: discovered_gshadow_hyphen_exists - name: "MEDIUM | RHEL-09-232125 | PATCH | RHEL 9 /etc/gshadow- file must be group-owned by root." when: @@ -1328,6 +1348,8 @@ ansible.builtin.file: group: root path: /etc/gshadow- + failed_when: discovered_gshadow_hyphen_exists.state not in '[ file, absent ]' + register: discovered_gshadow_hyphen_exists - name: "MEDIUM | RHEL-09-232130 | PATCH | RHEL 9 /etc/passwd file must be owned by root." when: @@ -1373,6 +1395,8 @@ ansible.builtin.file: owner: root path: /etc/passwd- + failed_when: discovered_passwd_hyphen_exists.state not in '[ file, absent ]' + register: discovered_passwd_hyphen_exists - name: "MEDIUM | RHEL-09-232145 | PATCH | RHEL 9 /etc/passwd- file must be group-owned by root." when: @@ -1388,6 +1412,8 @@ ansible.builtin.file: group: root path: /etc/passwd- + failed_when: discovered_passwd_hyphen_exists.state not in '[ file, absent ]' + register: discovered_passwd_hyphen_exists - name: "MEDIUM | RHEL-09-232150 | PATCH | RHEL 9 /etc/shadow file must be owned by root." when: @@ -1433,6 +1459,8 @@ ansible.builtin.file: owner: root path: /etc/shadow- + failed_when: discovered_shadow_hyphen_exists.state not in '[ file, absent ]' + register: discovered_shadow_hyphen_exists - name: "MEDIUM | RHEL-09-232165 | PATCH | RHEL 9 /etc/shadow- file must be group-owned by root." when: @@ -1447,7 +1475,9 @@ - NIST800-53R4_CM-6 ansible.builtin.file: group: root - path: /etc/shadow + path: /etc/shadow- + failed_when: discovered_shadow_hyphen_exists.state not in '[ file, absent ]' + register: discovered_shadow_hyphen_exists - name: "MEDIUM | RHEL-09-232170 | PATCH | RHEL 9 /var/log directory must be owned by root." when: From 176b98b0b45d4dc12403fd73a3305680d290bebc Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Tue, 14 Jan 2025 12:16:50 +0000 Subject: [PATCH 2/9] Addressed issue #65 gui logic Signed-off-by: Mark Bolwell --- defaults/main.yml | 5 ++++- tasks/Cat2/RHEL-09-21xxxx.yml | 13 ++++++++++++- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/defaults/main.yml b/defaults/main.yml index 1ec00d2..7ba3f34 100644 --- a/defaults/main.yml +++ b/defaults/main.yml @@ -596,7 +596,10 @@ rhel_09_653120: true ### CONTROLS -## Graphical/Gnome interface required +## Graphical/Gnome interface approved to be present +rhel9stig_gui_approved: false + +# If gui not installed rhel9stig_gui: "{{ rhel_09_gnome_present.stat.exists | default(false) }}" ## SSHD diff --git a/tasks/Cat2/RHEL-09-21xxxx.yml b/tasks/Cat2/RHEL-09-21xxxx.yml index 2b96bf3..7b60f38 100644 --- a/tasks/Cat2/RHEL-09-21xxxx.yml +++ b/tasks/Cat2/RHEL-09-21xxxx.yml @@ -84,6 +84,7 @@ - name: "MEDIUM | RHEL-09-211030 | PATCH | The graphical display manager must not be the default target on RHEL 9 unless approved." when: - rhel_09_211030 + - not rhel9stig_gui_approved tags: - RHEL-09-211030 - CAT2 @@ -1063,9 +1064,14 @@ name: quagga state: absent +# Note if groups installed via ansible previously https://bugzilla.redhat.com/show_bug.cgi?id=1620324. +# More efficient to remove as a list but conditional required a loop - name: "MEDIUM | RHEL-09-215070 | PATCH | A graphical display manager must not be installed on RHEL 9 unless approved." when: - rhel_09_215070 + - not rhel9stig_gui_approved + - rhel9stig_gui + - "item in ansible_facts.packages" tags: - RHEL-09-215070 - CAT2 @@ -1075,8 +1081,13 @@ - V-257837 - NIST800-53R4_CM-6 ansible.builtin.package: - name: "xorg*common" + name: "{{ item }}" state: absent + loop: + - "xorg*common" + - "workstation-product-environment" + - "graphical-server-environment" + - "gnome-desktop" - name: "MEDIUM | RHEL-09-215075 | PATCH | RHEL 9 must have the openssl-pkcs11 package installed." when: From 7eb794d94b523d923ce6896f08e0c9f96e233c99 Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Tue, 14 Jan 2025 12:31:07 +0000 Subject: [PATCH 3/9] Addressed issues #66 Signed-off-by: Mark Bolwell --- tasks/Cat2/RHEL-09-25xxxx.yml | 330 ++++++++++++++++++++++++---------- tasks/prelim.yml | 8 +- 2 files changed, 246 insertions(+), 92 deletions(-) diff --git a/tasks/Cat2/RHEL-09-25xxxx.yml b/tasks/Cat2/RHEL-09-25xxxx.yml index f4cc416..76c7651 100644 --- a/tasks/Cat2/RHEL-09-25xxxx.yml +++ b/tasks/Cat2/RHEL-09-25xxxx.yml @@ -1019,12 +1019,22 @@ - NIST800-53R4_AC-17 - ssh notify: Restart_sshd - ansible.builtin.lineinfile: - path: "{{ rhel9stig_sshd_config_file }}" - regexp: ^(?i)(#|)Include.* - line: "Include {{ rhel9stig_sshd_config.include_conf }}" - create: true - validate: sshd -t -f %s + block: + - name: "MEDIUM | RHEL-09-255055 | PATCH | RHEL 9 SSH daemon must be configured to use system-wide crypto policies. | Remove existing" + when: "rhel9stig_sshd_config_file not in item" + ansible.builtin.replace: + path: "{{ item }}" + regexp: (?i)^\s*Include.* + replace: '#\1' + loop: "{{ prelim_sshd_config_files.files }}" + + - name: "MEDIUM | RHEL-09-255055 | PATCH | RHEL 9 SSH daemon must be configured to use system-wide crypto policies. | Esnure exists" + ansible.builtin.lineinfile: + path: "{{ rhel9stig_sshd_config_file }}" + regexp: (?i)^(?#)\s*Include.* + line: "Include {{ rhel9stig_sshd_config.include_conf }}" + create: true + validate: sshd -t -f %s - name: "MEDIUM | RHEL-09-255060 | PATCH | RHEL 9 must implement DOD-approved encryption ciphers to protect the confidentiality of SSH client connections." when: @@ -1113,12 +1123,22 @@ - NIST800-53R4_CM-6 - ssh notify: Restart_ssh - ansible.builtin.lineinfile: - path: "{{ rhel9stig_sshd_config_file }}" - regexp: ^(?i)(#|)PermitUserEnvironments\s*(yes|no) - line: "PermitUserEnvironment {{ rhel9stig_sshd_config.userenv }}" - create: true - validate: sshd -t -f %s + block: + - name: "MEDIUM | RHEL-09-255085 | PATCH | RHEL 9 must not allow users to override SSH environment variables. | Remove" + when: "rhel9stig_sshd_config_file not in item" + ansible.builtin.replace: + path: "{{ item }}" + regexp: (?i)^\s*PermitUserEnvironment + replace: '#\1' + loop: "{{ prelim_sshd_config_files.files }}" + + - name: "MEDIUM | RHEL-09-255085 | PATCH | RHEL 9 must not allow users to override SSH environment variables. | Exists" + ansible.builtin.lineinfile: + path: "{{ rhel9stig_sshd_config_file }}" + regexp: (?i)^(?#)\s*PermitUserEnvironment\s*(yes|no) + line: "PermitUserEnvironment {{ rhel9stig_sshd_config.userenv }}" + create: true + validate: sshd -t -f %s - name: "MEDIUM | RHEL-09-255090 | PATCH | RHEL 9 must force a frequent session key renegotiation for SSH connections to the server." when: @@ -1138,12 +1158,22 @@ - NIST800-53R4_SC-8 - ssh notify: Restart_ssh - ansible.builtin.lineinfile: - path: "{{ rhel9stig_sshd_config_file }}" - regexp: ^(?i)(#|)RekeyLimit.* - line: "RekeyLimit {{ rhel9stig_sshd_config.rekeylimit }}" - create: true - validate: sshd -t -f %s + block: + - name: "MEDIUM | RHEL-09-255090 | PATCH | RHEL 9 must force a frequent session key renegotiation for SSH connections to the server. | Remove" + when: "rhel9stig_sshd_config_file not in item" + ansible.builtin.replace: + path: "{{ item }}" + regexp: (?i)^\s*RekeyLimit + replace: '#\1' + loop: "{{ prelim_sshd_config_files.files }}" + + - name: "MEDIUM | RHEL-09-255090 | PATCH | RHEL 9 must force a frequent session key renegotiation for SSH connections to the server. | Exists" + ansible.builtin.lineinfile: + path: "{{ rhel9stig_sshd_config_file }}" + regexp: (?i)^(?#)\s*RekeyLimit.* + line: "RekeyLimit {{ rhel9stig_sshd_config.rekeylimit }}" + create: true + validate: sshd -t -f %s - name: "MEDIUM | RHEL-09-255095 | PATCH | RHEL 9 must be configured so that all network connections associated with SSH traffic terminate after becoming unresponsive." when: @@ -1162,12 +1192,22 @@ - NIST800-53R4_AC-12 - ssh notify: Restart_ssh - ansible.builtin.lineinfile: - path: "{{ rhel9stig_sshd_config_file }}" - regexp: ^(?i)(#|)ClientAliveCountMax\s\d* - line: "ClientAliveCountMax {{ rhel9stig_sshd_config.clientalivecountmax }}" - create: true - validate: sshd -t -f %s + block: + - name: "MEDIUM | RHEL-09-255095 | PATCH | RHEL 9 must be configured so that all network connections associated with SSH traffic terminate after becoming unresponsive. | Remove" + when: "rhel9stig_sshd_config_file not in item" + ansible.builtin.replace: + path: "{{ item }}" + regexp: (?i)^\s*ClientAliveCountMax + replace: '#\1' + loop: "{{ prelim_sshd_config_files.files }}" + + - name: "MEDIUM | RHEL-09-255095 | PATCH | RHEL 9 must be configured so that all network connections associated with SSH traffic terminate after becoming unresponsive. | exists" + ansible.builtin.lineinfile: + path: "{{ rhel9stig_sshd_config_file }}" + regexp: ^(?i)(#|)ClientAliveCountMax\s\d* + line: "ClientAliveCountMax {{ rhel9stig_sshd_config.clientalivecountmax }}" + create: true + validate: sshd -t -f %s - name: "MEDIUM | RHEL-09-255100 | PATCH | RHEL 9 must be configured so that all network connections associated with SSH traffic are terminated after 10 minutes of becoming unresponsive." when: @@ -1190,12 +1230,22 @@ - NIST800-53R4_AC-12 - ssh notify: Restart_ssh - ansible.builtin.lineinfile: - path: "{{ rhel9stig_sshd_config_file }}" - regexp: ^(?i)(#|)ClientAliveInterval\s\d* - line: "ClientAliveInterval {{ rhel9stig_sshd_config.clientaliveinterval }}" - create: true - validate: sshd -t -f %s + block: + - name: "MEDIUM | RHEL-09-255100 | PATCH | RHEL 9 must be configured so that all network connections associated with SSH traffic are terminated after 10 minutes of becoming unresponsive. | Remove" + when: "rhel9stig_sshd_config_file not in item" + ansible.builtin.replace: + path: "{{ item }}" + regexp: (?i)^\s*ClientAliveInterval + replace: '#\1' + loop: "{{ prelim_sshd_config_files.files }}" + + - name: "MEDIUM | RHEL-09-255100 | PATCH | RHEL 9 must be configured so that all network connections associated with SSH traffic are terminated after 10 minutes of becoming unresponsive." + ansible.builtin.lineinfile: + path: "{{ rhel9stig_sshd_config_file }}" + regexp: (?i)^(?#)\s*ClientAliveInterval\s\d* + line: "ClientAliveInterval {{ rhel9stig_sshd_config.clientaliveinterval }}" + create: true + validate: sshd -t -f %s - name: "MEDIUM | RHEL-09-255105 | PATCH | RHEL 9 SSH server configuration file must be group-owned by root." when: @@ -1306,12 +1356,21 @@ - NIST800-53R4_CM-6 - ssh notify: Restart_ssh - ansible.builtin.lineinfile: - path: "{{ rhel9stig_sshd_config_file }}" - regexp: ^(?i)(#|)Compression\s*(yes|no) - line: "Compression {{ rhel9stig_sshd_config.compress }}" - create: true - validate: sshd -t -f %s + block: + - name: "MEDIUM | RHEL-09-255135 | PATCH | RHEL 9 SSH daemon must not allow compression or must only allow compression after successful authentication. | remove setting from incorrect files" + when: "rhel9stig_sshd_config_file not in item" + ansible.builtin.replace: + path: "{{ item }}" + regexp: (?i)^\s*Compression + replace: '#\1' + loop: "{{ prelim_sshd_config_files.files }}" + + - name: "MEDIUM | RHEL-09-255135 | PATCH | RHEL 9 SSH daemon must not allow compression or must only allow compression after successful authentication. | Exists in correct file" + ansible.builtin.lineinfile: + path: "{{ rhel9stig_sshd_config_file }}" + regexp: (?i)^(?#)\s*Compression\s*(yes|no) + line: "Compression {{ rhel9stig_sshd_config.compress }}" + validate: sshd -t -f %s - name: "MEDIUM | RHEL-09-255135 | PATCH | RHEL 9 SSH daemon must not allow GSSAPI authentication." when: @@ -1329,12 +1388,21 @@ - NIST800-53R4_CM-6 - ssh notify: Restart_ssh - ansible.builtin.lineinfile: - path: "{{ rhel9stig_sshd_config_file }}" - regexp: ^(?i)(#|)GSSAPIAuthentication\s*(yes|no) - line: "GSSAPIAuthentication {{ rhel9stig_sshd_config.gssapiauth }}" - create: true - validate: sshd -t -f %s + block: + - name: "MEDIUM | RHEL-09-255135 | PATCH | RHEL 9 SSH daemon must not allow GSSAPI authentication. | remove setting from incorrect files" + when: "rhel9stig_sshd_config_file not in item" + ansible.builtin.replace: + path: "{{ item }}" + regexp: (?i)^\s*GSSAPIAuthentication + replace: '#\1' + loop: "{{ prelim_sshd_config_files.files }}" + + - name: "MEDIUM | RHEL-09-255135 | PATCH | RHEL 9 SSH daemon must not allow GSSAPI authentication. | Ensure correct setting in file" + ansible.builtin.lineinfile: + path: "{{ rhel9stig_sshd_config_file }}" + regexp: (?i)^(?#)\s*GSSAPIAuthentication\s*(yes|no) + line: "GSSAPIAuthentication {{ rhel9stig_sshd_config.gssapiauth }}" + validate: sshd -t -f %s - name: "MEDIUM | RHEL-09-255140 | PATCH | RHEL 9 SSH daemon must not allow Kerberos authentication." when: @@ -1352,12 +1420,22 @@ - NIST800-53R4_CM-6 - ssh notify: Restart_ssh - ansible.builtin.lineinfile: - path: "{{ rhel9stig_sshd_config_file }}" - regexp: ^(?i)(#|)KerberosAuthentication\s*(yes|no) - line: "KerberosAuthentication {{ rhel9stig_sshd_config.kerbauth }}" - create: true - validate: sshd -t -f %s + block: + - name: "MEDIUM | RHEL-09-255140 | PATCH | RHEL 9 SSH daemon must not allow Kerberos authentication. | remove setting from incorrect files" + when: "rhel9stig_sshd_config_file not in item" + ansible.builtin.replace: + path: "{{ item }}" + regexp: (?i)^\s*KerberosAuthentication + replace: '#\1' + loop: "{{ prelim_sshd_config_files.files }}" + + - name: "MEDIUM | RHEL-09-255140 | PATCH | RHEL 9 SSH daemon must not allow Kerberos authentication. | Exists" + ansible.builtin.lineinfile: + path: "{{ rhel9stig_sshd_config_file }}" + regexp: (?i)^(?#)\s*KerberosAuthentication\s*(yes|no) + line: "KerberosAuthentication {{ rhel9stig_sshd_config.kerbauth }}" + create: true + validate: sshd -t -f %s - name: "MEDIUM | RHEL-09-255145 | PATCH | RHEL 9 SSH daemon must not allow rhosts authentication" when: @@ -1372,12 +1450,22 @@ - NIST800-53R4_CM-6 - ssh notify: Restart_ssh - ansible.builtin.lineinfile: - path: "{{ rhel9stig_sshd_config_file }}" - regexp: ^(?i)(#|)IgnoreRhosts\s*(yes|no) - line: "IgnoreRhosts {{ rhel9stig_sshd_config.ignorerhosts }}" - create: true - validate: sshd -t -f %s + block: + - name: "MEDIUM | RHEL-09-255145 | PATCH | RHEL 9 SSH daemon must not allow rhosts authentication | Remove" + when: "rhel9stig_sshd_config_file not in item" + ansible.builtin.replace: + path: "{{ item }}" + regexp: (?i)^\s*IgnoreRhosts + replace: '#\1' + loop: "{{ prelim_sshd_config_files.files }}" + + - name: "MEDIUM | RHEL-09-255145 | PATCH | RHEL 9 SSH daemon must not allow rhosts authentication | Exists" + ansible.builtin.lineinfile: + path: "{{ rhel9stig_sshd_config_file }}" + regexp: (?i)^(?#)\s*IgnoreRhosts\s*(yes|no) + line: "IgnoreRhosts {{ rhel9stig_sshd_config.ignorerhosts }}" + create: true + validate: sshd -t -f %s - name: "MEDIUM | RHEL-09-255150 | PATCH | RHEL 9 SSH daemon must not allow known hosts authentication." when: @@ -1392,12 +1480,22 @@ - NIST800-53R4_CM-6 - ssh notify: Restart_ssh - ansible.builtin.lineinfile: - path: /etc/ssh/sshd_config.d/50-redhat.conf - regexp: ^(?i)(#|)IgnoreUserKnownHosts\s*(yes|no) - line: "IgnoreUserKnownHosts {{ rhel9stig_sshd_config.ignoreknownhosts }}" - create: true - validate: sshd -t -f %s + block: + - name: "MEDIUM | RHEL-09-255150 | PATCH | RHEL 9 SSH daemon must not allow known hosts authentication. | Remove" + when: "rhel9stig_sshd_config_file not in item" + ansible.builtin.replace: + path: "{{ item }}" + regexp: (?i)^\s*IgnoreUserKnownHosts + replace: '#\1' + loop: "{{ prelim_sshd_config_files.files }}" + + - name: "MEDIUM | RHEL-09-255150 | PATCH | RHEL 9 SSH daemon must not allow known hosts authentication. | Exists " + ansible.builtin.lineinfile: + path: "{{ rhel9stig_sshd_config_file }}" + regexp: (?i)^(?#)\s*IgnoreUserKnownHosts\s*(yes|no) + line: "IgnoreUserKnownHosts {{ rhel9stig_sshd_config.ignoreknownhosts }}" + create: true + validate: sshd -t -f %s - name: "MEDIUM | RHEL-09-255155 | PATCH | RHEL 9 SSH daemon must disable remote X connections for interactive users." when: @@ -1412,14 +1510,24 @@ - NIST800-53R4_CM-6 - ssh notify: Restart_ssh - ansible.builtin.lineinfile: - path: "{{ rhel9stig_sshd_config_file }}" - regexp: ^(?i)(#|)X11forwarding\s*(yes|no) - line: "X11forwarding {{ rhel9stig_sshd_config.x11forward }}" - create: true - validate: sshd -t -f %s + block: + - name: "MEDIUM | RHEL-09-255155 | PATCH | RHEL 9 SSH daemon must disable remote X connections for interactive users. | remove setting from incorrect files" + when: "rhel9stig_sshd_config_file not in item" + ansible.builtin.replace: + path: "{{ item }}" + regexp: (?i)^\s*X11Forwarding + replace: '#\1' + loop: "{{ prelim_sshd_config_files.files }}" + + - name: "MEDIUM | RHEL-09-255155 | PATCH | RHEL 9 SSH daemon must disable remote X connections for interactive users. | Ensure setting in correct files" + ansible.builtin.lineinfile: + path: "{{ rhel9stig_sshd_config_file }}" + regexp: (?i)^(?#)\s*X11forwarding\s*(yes|no) + line: "X11forwarding {{ rhel9stig_sshd_config.x11forward }}" + create: true + validate: sshd -t -f %s -- name: "MEDIUM | RHEL-09-255160 | PATCH | RHEL 9 SSH daemon must perform strict mode checking of home directory configuration files." +- name: "MEDIUM | RHEL-09-255160 | PATCH | RHEL 9 SSH daemon must perform strict mode checking of home directory configuration files. | Exists" when: - rhel_09_255160 tags: @@ -1432,12 +1540,22 @@ - NIST800-53R4_CM-6 - ssh notify: Restart_ssh - ansible.builtin.lineinfile: - path: "{{ rhel9stig_sshd_config_file }}" - regexp: ^(?i)(#|)StrictModes\s*(yes|no) - line: "StrictModes {{ rhel9stig_sshd_config.strictmodes }}" - create: true - validate: sshd -t -f %s + block: + - name: "MEDIUM | RHEL-09-255160 | PATCH | RHEL 9 SSH daemon must perform strict mode checking of home directory configuration files. | Remove" + when: "rhel9stig_sshd_config_file not in item" + ansible.builtin.replace: + path: "{{ item }}" + regexp: (?i)^\s*StrictModes + replace: '#\1' + loop: "{{ prelim_sshd_config_files.files }}" + + - name: "MEDIUM | RHEL-09-255160 | PATCH | RHEL 9 SSH daemon must perform strict mode checking of home directory configuration files. | Exists" + ansible.builtin.lineinfile: + path: "{{ rhel9stig_sshd_config_file }}" + regexp: (?i)^(?#)\s*StrictModes\s*(yes|no) + line: "StrictModes {{ rhel9stig_sshd_config.strictmodes }}" + create: true + validate: sshd -t -f %s - name: "MEDIUM | RHEL-09-255165 | PATCH | RHEL 9 SSH daemon must display the date and time of the last successful account logon upon an SSH logon." when: @@ -1452,12 +1570,22 @@ - NIST800-53R4_CM-6 - ssh notify: Restart_ssh - ansible.builtin.lineinfile: - path: "{{ rhel9stig_sshd_config_file }}" - regexp: ^(?i)(#|)PrintLastLog\s*(yes|no) - line: "PrintLastLog {{ rhel9stig_sshd_config.lastlog }}" - create: true - validate: sshd -t -f %s + block: + - name: "MEDIUM | RHEL-09-255165 | PATCH | RHEL 9 SSH daemon must display the date and time of the last successful account logon upon an SSH logon. | Remove" + when: "rhel9stig_sshd_config_file not in item" + ansible.builtin.replace: + path: "{{ item }}" + regexp: (?i)^\s*PrintLastLog + replace: '#\1' + loop: "{{ prelim_sshd_config_files.files }}" + + - name: "MEDIUM | RHEL-09-255165 | PATCH | RHEL 9 SSH daemon must display the date and time of the last successful account logon upon an SSH logon. | Exists" + ansible.builtin.lineinfile: + path: "{{ rhel9stig_sshd_config_file }}" + regexp: (?i)^(?#)\s*PrintLastLog\s*(yes|no) + line: "PrintLastLog {{ rhel9stig_sshd_config.lastlog }}" + create: true + validate: sshd -t -f %s - name: "MEDIUM | RHEL-09-255170 | PATCH | RHEL 9 SSH daemon must display the date and time of the last successful account logon upon an SSH logon." when: @@ -1472,12 +1600,22 @@ - NIST800-53R4_CM-6 - ssh notify: Restart_ssh - ansible.builtin.lineinfile: - path: "{{ rhel9stig_sshd_config_file }}" - regexp: ^(?i)(#|)UsePrivilegeSeparation\s*(yes|no) - line: "UsePrivilegeSeparation {{ rhel9stig_sshd_config.privsep }}" - create: true - validate: sshd -t -f %s + block: + - name: "MEDIUM | RHEL-09-255170 | PATCH | RHEL 9 SSH daemon must display the date and time of the last successful account logon upon an SSH logon. | Remove" + when: "rhel9stig_sshd_config_file not in item" + ansible.builtin.replace: + path: "{{ item }}" + regexp: (?i)^\s*UsePrivilegeSeparation + replace: '#\1' + loop: "{{ prelim_sshd_config_files.files }}" + + - name: "MEDIUM | RHEL-09-255170 | PATCH | RHEL 9 SSH daemon must display the date and time of the last successful account logon upon an SSH logon. | Exists" + ansible.builtin.lineinfile: + path: "{{ rhel9stig_sshd_config_file }}" + regexp: (?i)^(?#)\s*UsePrivilegeSeparation\s*(yes|no) + line: "UsePrivilegeSeparation {{ rhel9stig_sshd_config.privsep }}" + create: true + validate: sshd -t -f %s - name: "MEDIUM | RHEL-09-255175 | PATCH | RHEL 9 SSH daemon must prevent remote hosts from connecting to the proxy display." when: @@ -1492,9 +1630,19 @@ - NIST800-53R4_CM-6 - ssh notify: Restart_ssh - ansible.builtin.lineinfile: - path: "{{ rhel9stig_sshd_config_file }}" - regexp: ^(?i)(#|)X11UseLocalhost\s*(yes|no) - line: "X11UseLocalhost {{ rhel9stig_sshd_config.x11uselocal }}" - create: true - validate: sshd -t -f %s + block: + - name: "MEDIUM | RHEL-09-255175 | PATCH | RHEL 9 SSH daemon must prevent remote hosts from connecting to the proxy display. | Remove" + when: "rhel9stig_sshd_config_file not in item" + ansible.builtin.replace: + path: "{{ item }}" + regexp: (?i)^\s*X11UseLocalhost + replace: '#\1' + loop: "{{ prelim_sshd_config_files.files }}" + + - name: "MEDIUM | RHEL-09-255175 | PATCH | RHEL 9 SSH daemon must prevent remote hosts from connecting to the proxy display. | Exists" + ansible.builtin.lineinfile: + path: "{{ rhel9stig_sshd_config_file }}" + regexp: (?i)^(?#)\s*X11UseLocalhost\s*(yes|no) + line: "X11UseLocalhost {{ rhel9stig_sshd_config.x11uselocal }}" + create: true + validate: sshd -t -f %s diff --git a/tasks/prelim.yml b/tasks/prelim.yml index c274dcf..ce70eba 100644 --- a/tasks/prelim.yml +++ b/tasks/prelim.yml @@ -179,7 +179,7 @@ register: discovered_auditd_logfile # Added to ensure ssh drop in file exists if not default /etc/ssh/sshd_config -- name: PRELIM | SSH +- name: PRELIM | SSH | create config file if absent ansible.builtin.file: path: "{{ rhel9stig_sshd_config_file }}" owner: root @@ -192,6 +192,12 @@ tags: - ssh +- name: PRELIM | SSH | existing ssh config files + ansible.builtin.find: + path: /etc/ssh + patterns: '*.conf' + register: prelim_sshd_config_files + - name: "PRELIM | Interactive User accounts" ansible.builtin.shell: 'cat /etc/passwd | grep -Ev "nologin|/sbin" | cut -d: -f6' changed_when: false From e49bc2cc885b5026dc543ac0236c79fc347fd9f6 Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Tue, 21 Jan 2025 19:01:31 +0000 Subject: [PATCH 4/9] Address issues #66 Signed-off-by: Mark Bolwell --- tasks/Cat2/RHEL-09-25xxxx.yml | 257 ++++++++++++++++++++++------------ 1 file changed, 169 insertions(+), 88 deletions(-) diff --git a/tasks/Cat2/RHEL-09-25xxxx.yml b/tasks/Cat2/RHEL-09-25xxxx.yml index 76c7651..c498be0 100644 --- a/tasks/Cat2/RHEL-09-25xxxx.yml +++ b/tasks/Cat2/RHEL-09-25xxxx.yml @@ -930,12 +930,23 @@ - NIST800-53R4_AC-8 - ssh notify: Restart_ssh - ansible.builtin.lineinfile: - path: "{{ rhel9stig_sshd_config_file }}" - regexp: ^(?i)(#|)banner \/.*\/.* - line: "banner {{ rhel9stig_sshd_config.banner_file }}" - create: true - validate: sshd -t -f %s + block: + - name: "MEDIUM | RHEL-09-255025 | PATCH | RHEL 9 must display the Standard Mandatory DOD Notice and Consent Banner before granting local or remote access to the system via a SSH logon. | Remove" + when: "item.path != rhel9stig_sshd_config_file" + ansible.builtin.replace: + path: "{{ item }}" + regexp: (?i)(^banner.*) + replace: '#\1' + failed_when: discovered_banner_exists.rc != 257 + register: discovered_banner_exists + loop: "{{ prelim_sshd_config_files.files }}" + + - name: "MEDIUM | RHEL-09-255025 | PATCH | RHEL 9 must display the Standard Mandatory DOD Notice and Consent Banner before granting local or remote access to the system via a SSH logon. | Remove" + ansible.builtin.lineinfile: + path: "{{ rhel9stig_sshd_config_file }}" + regexp: (?i)^(?#)banner .* + line: "banner {{ rhel9stig_sshd_config.banner_file }}" + validate: sshd -t -f %s - name: "MEDIUM | RHEL-09-255030 | PATCH | RHEL 9 must log SSH connection attempts and failures to the server." when: @@ -950,12 +961,23 @@ - NIST800-53R4_AC-17 - ssh notify: Restart_ssh - ansible.builtin.lineinfile: - path: "{{ rhel9stig_sshd_config_file }}" - regexp: ^(?i)(#|)LogLevel.* - line: "LogLevel {{ rhel9stig_sshd_config.loglevel }}" - create: true - validate: sshd -t -f %s + block: + - name: "MEDIUM | RHEL-09-255030 | PATCH | RHEL 9 must log SSH connection attempts and failures to the server. | Remove" + when: "item.path != rhel9stig_sshd_config_file" + ansible.builtin.replace: + path: "{{ item }}" + regexp: (?i)(^LogLevel.*) + replace: '#\1' + failed_when: discovered_loglevel_exists.rc != 257 + register: discovered_loglevel_exists + loop: "{{ prelim_sshd_config_files.files }}" + + - name: "MEDIUM | RHEL-09-255030 | PATCH | RHEL 9 must log SSH connection attempts and failures to the server. | Exists" + ansible.builtin.lineinfile: + path: "{{ rhel9stig_sshd_config_file }}" + regexp: (?i)^(#|)LogLevel.* + line: "LogLevel {{ rhel9stig_sshd_config.loglevel }}" + validate: sshd -t -f %s - name: "MEDIUM | RHEL-09-255035 | PATCH | RHEL 9 SSHD must accept public key authentication" when: @@ -976,12 +998,23 @@ - NIST800-53R4_IA-2 - ssh notify: Restart_ssh - ansible.builtin.lineinfile: - path: "{{ rhel9stig_sshd_config_file }}" - regexp: ^(?i)(#|)PubkeyAuthentication\s*(yes|no) - line: "PubkeyAuthentication {{ rhel9stig_sshd_config.pubkeyauth }}" - create: true - validate: sshd -t -f %s + block: + - name: "MEDIUM | RHEL-09-255035 | PATCH | RHEL 9 SSHD must accept public key authentication | Remove" + when: "item.path != rhel9stig_sshd_config_file" + ansible.builtin.replace: + path: "{{ item }}" + regexp: (?i)(^PubkeyAuthentication.*) + replace: '#\1' + failed_when: discovered_pubkey_exists.rc != 257 + register: discovered_pubkey_exists + loop: "{{ prelim_sshd_config_files.files }}" + + - name: "MEDIUM | RHEL-09-255035 | PATCH | RHEL 9 SSHD must accept public key authentication | Exists" + ansible.builtin.lineinfile: + path: "{{ rhel9stig_sshd_config_file }}" + regexp: (?i)^(#|)PubkeyAuthentication\s*(yes|no|true|false) + line: "PubkeyAuthentication {{ rhel9stig_sshd_config.pubkeyauth }}" + validate: sshd -t -f %s - name: "MEDIUM | RHEL-09-255045 | PATCH | RHEL 9 must not permit direct logons to the root account using remote access via SSH." when: @@ -999,12 +1032,23 @@ - NIST800-53R4_IA-2 - ssh notify: Restart_ssh - ansible.builtin.lineinfile: - path: "{{ rhel9stig_sshd_config_file }}" - regexp: ^(?i)(#|)PermitRootLogin\s*(yes|no) - line: "PermitRootLogin {{ rhel9stig_sshd_config.permitroot }}" - create: true - validate: sshd -t -f %s + block: + - name: "MEDIUM | RHEL-09-255045 | PATCH | RHEL 9 must not permit direct logons to the root account using remote access via SSH. | Remove existing" + when: "item.path != rhel9stig_sshd_config_file" + ansible.builtin.replace: + path: "{{ item }}" + regexp: (?i)(^PermitRootLogin.*) + replace: '#\1' + failed_when: discovered_rootlogin_exists.rc != 257 + register: discovered_rootlogin_exists + loop: "{{ prelim_sshd_config_files.files }}" + + - name: "MEDIUM | RHEL-09-255045 | PATCH | RHEL 9 must not permit direct logons to the root account using remote access via SSH. | Remove existing" + ansible.builtin.lineinfile: + path: "{{ rhel9stig_sshd_config_file }}" + regexp: (?i)^(#|)PermitRootLogin\s*(yes|no|true|false) + line: "PermitRootLogin {{ rhel9stig_sshd_config.permitroot }}" + validate: sshd -t -f %s - name: "MEDIUM | RHEL-09-255055 | PATCH | RHEL 9 SSH daemon must be configured to use system-wide crypto policies." when: @@ -1021,11 +1065,13 @@ notify: Restart_sshd block: - name: "MEDIUM | RHEL-09-255055 | PATCH | RHEL 9 SSH daemon must be configured to use system-wide crypto policies. | Remove existing" - when: "rhel9stig_sshd_config_file not in item" + when: "item.path != rhel9stig_sshd_config_file" ansible.builtin.replace: path: "{{ item }}" - regexp: (?i)^\s*Include.* + regexp: (?i)^Include.*(?!etc\/crypto-policies\/back-ends\/opensshserver\.config) replace: '#\1' + failed_when: discovered_sshinclude_exists.rc != 257 + register: discovered_sshinclude_exists loop: "{{ prelim_sshd_config_files.files }}" - name: "MEDIUM | RHEL-09-255055 | PATCH | RHEL 9 SSH daemon must be configured to use system-wide crypto policies. | Esnure exists" @@ -1033,7 +1079,6 @@ path: "{{ rhel9stig_sshd_config_file }}" regexp: (?i)^(?#)\s*Include.* line: "Include {{ rhel9stig_sshd_config.include_conf }}" - create: true validate: sshd -t -f %s - name: "MEDIUM | RHEL-09-255060 | PATCH | RHEL 9 must implement DOD-approved encryption ciphers to protect the confidentiality of SSH client connections." @@ -1051,7 +1096,7 @@ notify: Restart_sshd ansible.builtin.lineinfile: path: "{{ rhel9stig_sshd_config_file }}" - regexp: ^(?i)(#|)Include.* + regexp: ^(?i)(?#)Include.* line: "Include {{ rhel9stig_sshd_config.include_conf }}" create: true validate: sshd -t -f %s @@ -1103,12 +1148,24 @@ - NIST800-53R4_CM-6 - ssh notify: Restart_ssh - ansible.builtin.lineinfile: - path: "{{ rhel9stig_sshd_config_file }}" - regexp: ^(?i)(#|)HostbasedAuthentication\s*(yes|no) - line: "HostbasedAuthentication {{ rhel9stig_sshd_config.hostauth }}" - create: true - validate: sshd -t -f %s + block: + - name: "MEDIUM | RHEL-09-255080 | PATCH | RHEL 9 must not allow a noncertificate trusted host SSH logon to the system. | Remove" + when: "item.path != rhel9stig_sshd_config_file" + ansible.builtin.replace: + path: "{{ item }}" + regexp: (?i)^(HostbasedAuthentication.*) + replace: '#\1' + failed_when: discovered_hostbasedauth_exists.rc != 257 + register: discovered_hostbasedauth_exists + loop: "{{ prelim_sshd_config_files.files }}" + + - name: "MEDIUM | RHEL-09-255080 | PATCH | RHEL 9 must not allow a noncertificate trusted host SSH logon to the system. | Exists" + ansible.builtin.lineinfile: + path: "{{ rhel9stig_sshd_config_file }}" + regexp: (?i)^(?#)HostbasedAuthentication\s*(yes|no|true|false) + line: "HostbasedAuthentication {{ rhel9stig_sshd_config.hostauth }}" + create: true + validate: sshd -t -f %s - name: "MEDIUM | RHEL-09-255085 | PATCH | RHEL 9 must not allow users to override SSH environment variables." when: @@ -1125,11 +1182,13 @@ notify: Restart_ssh block: - name: "MEDIUM | RHEL-09-255085 | PATCH | RHEL 9 must not allow users to override SSH environment variables. | Remove" - when: "rhel9stig_sshd_config_file not in item" + when: "item.path != rhel9stig_sshd_config_file" ansible.builtin.replace: path: "{{ item }}" - regexp: (?i)^\s*PermitUserEnvironment + regexp: (?i)^(PermitUserEnvironment.*) replace: '#\1' + failed_when: discovered_userenv_exists.rc != 257 + register: discovered_userenv_exists loop: "{{ prelim_sshd_config_files.files }}" - name: "MEDIUM | RHEL-09-255085 | PATCH | RHEL 9 must not allow users to override SSH environment variables. | Exists" @@ -1160,11 +1219,13 @@ notify: Restart_ssh block: - name: "MEDIUM | RHEL-09-255090 | PATCH | RHEL 9 must force a frequent session key renegotiation for SSH connections to the server. | Remove" - when: "rhel9stig_sshd_config_file not in item" + when: "item.path != rhel9stig_sshd_config_file" ansible.builtin.replace: path: "{{ item }}" - regexp: (?i)^\s*RekeyLimit + regexp: (?i)(^RekeyLimit.*) replace: '#\1' + failed_when: discovered_rekey_exists.rc != 257 + register: discovered_rekey_exists loop: "{{ prelim_sshd_config_files.files }}" - name: "MEDIUM | RHEL-09-255090 | PATCH | RHEL 9 must force a frequent session key renegotiation for SSH connections to the server. | Exists" @@ -1194,17 +1255,19 @@ notify: Restart_ssh block: - name: "MEDIUM | RHEL-09-255095 | PATCH | RHEL 9 must be configured so that all network connections associated with SSH traffic terminate after becoming unresponsive. | Remove" - when: "rhel9stig_sshd_config_file not in item" + when: "item.path != rhel9stig_sshd_config_file" ansible.builtin.replace: path: "{{ item }}" - regexp: (?i)^\s*ClientAliveCountMax + regexp: (?i)^(ClientAliveCountMax .*) replace: '#\1' + failed_when: discovered_alivecount_exists.rc != 257 + register: discovered_alivecount_exists loop: "{{ prelim_sshd_config_files.files }}" - name: "MEDIUM | RHEL-09-255095 | PATCH | RHEL 9 must be configured so that all network connections associated with SSH traffic terminate after becoming unresponsive. | exists" ansible.builtin.lineinfile: path: "{{ rhel9stig_sshd_config_file }}" - regexp: ^(?i)(#|)ClientAliveCountMax\s\d* + regexp: (?i)^(?#)ClientAliveCountMax\s\d* line: "ClientAliveCountMax {{ rhel9stig_sshd_config.clientalivecountmax }}" create: true validate: sshd -t -f %s @@ -1232,17 +1295,19 @@ notify: Restart_ssh block: - name: "MEDIUM | RHEL-09-255100 | PATCH | RHEL 9 must be configured so that all network connections associated with SSH traffic are terminated after 10 minutes of becoming unresponsive. | Remove" - when: "rhel9stig_sshd_config_file not in item" + when: "item.path != rhel9stig_sshd_config_file" ansible.builtin.replace: path: "{{ item }}" - regexp: (?i)^\s*ClientAliveInterval + regexp: (?i)^(ClientAliveInterval.*) replace: '#\1' + failed_when: discovered_liveinterval_exists.rc != 257 + register: discovered_liveinterval_exists loop: "{{ prelim_sshd_config_files.files }}" - name: "MEDIUM | RHEL-09-255100 | PATCH | RHEL 9 must be configured so that all network connections associated with SSH traffic are terminated after 10 minutes of becoming unresponsive." ansible.builtin.lineinfile: path: "{{ rhel9stig_sshd_config_file }}" - regexp: (?i)^(?#)\s*ClientAliveInterval\s\d* + regexp: (?i)^(?#)ClientAliveInterval\s\d* line: "ClientAliveInterval {{ rhel9stig_sshd_config.clientaliveinterval }}" create: true validate: sshd -t -f %s @@ -1357,18 +1422,20 @@ - ssh notify: Restart_ssh block: - - name: "MEDIUM | RHEL-09-255135 | PATCH | RHEL 9 SSH daemon must not allow compression or must only allow compression after successful authentication. | remove setting from incorrect files" - when: "rhel9stig_sshd_config_file not in item" + - name: "MEDIUM | RHEL-09-255135 | PATCH | RHEL 9 SSH daemon must not allow compression or must only allow compression after successful authentication. | Remove" + when: "item.path != rhel9stig_sshd_config_file" ansible.builtin.replace: path: "{{ item }}" - regexp: (?i)^\s*Compression + regexp: (?i)^(compression .*) replace: '#\1' + failed_when: discovered_compression_exists.rc != 257 + register: discovered_compression_exists loop: "{{ prelim_sshd_config_files.files }}" - name: "MEDIUM | RHEL-09-255135 | PATCH | RHEL 9 SSH daemon must not allow compression or must only allow compression after successful authentication. | Exists in correct file" ansible.builtin.lineinfile: path: "{{ rhel9stig_sshd_config_file }}" - regexp: (?i)^(?#)\s*Compression\s*(yes|no) + regexp: (?i)^(?#)Compression\s*(yes|no|true|false) line: "Compression {{ rhel9stig_sshd_config.compress }}" validate: sshd -t -f %s @@ -1389,18 +1456,18 @@ - ssh notify: Restart_ssh block: - - name: "MEDIUM | RHEL-09-255135 | PATCH | RHEL 9 SSH daemon must not allow GSSAPI authentication. | remove setting from incorrect files" - when: "rhel9stig_sshd_config_file not in item" + - name: "MEDIUM | RHEL-09-255135 | PATCH | RHEL 9 SSH daemon must not allow GSSAPI authentication. | Remove" + when: "item.path != rhel9stig_sshd_config_file" ansible.builtin.replace: - path: "{{ item }}" - regexp: (?i)^\s*GSSAPIAuthentication + path: "{{ item.path }}" + regexp: (?i)^(GSSAPIAuthentication (yes|true)) replace: '#\1' loop: "{{ prelim_sshd_config_files.files }}" - - name: "MEDIUM | RHEL-09-255135 | PATCH | RHEL 9 SSH daemon must not allow GSSAPI authentication. | Ensure correct setting in file" + - name: "MEDIUM | RHEL-09-255135 | PATCH | RHEL 9 SSH daemon must not allow GSSAPI authentication. | Exists" ansible.builtin.lineinfile: path: "{{ rhel9stig_sshd_config_file }}" - regexp: (?i)^(?#)\s*GSSAPIAuthentication\s*(yes|no) + regexp: (?i)^(?#)GSSAPIAuthentication\s*(yes|no) line: "GSSAPIAuthentication {{ rhel9stig_sshd_config.gssapiauth }}" validate: sshd -t -f %s @@ -1421,20 +1488,21 @@ - ssh notify: Restart_ssh block: - - name: "MEDIUM | RHEL-09-255140 | PATCH | RHEL 9 SSH daemon must not allow Kerberos authentication. | remove setting from incorrect files" - when: "rhel9stig_sshd_config_file not in item" + - name: "MEDIUM | RHEL-09-255140 | PATCH | RHEL 9 SSH daemon must not allow Kerberos authentication. | Remove" + when: "item.path != rhel9stig_sshd_config_file" ansible.builtin.replace: path: "{{ item }}" - regexp: (?i)^\s*KerberosAuthentication + regexp: (?i)^(KerberosAuthentication (yes|true)) replace: '#\1' + failed_when: discovered_kerberosauth_exists.rc != 257 + register: discovered_kerberosauth_exists loop: "{{ prelim_sshd_config_files.files }}" - name: "MEDIUM | RHEL-09-255140 | PATCH | RHEL 9 SSH daemon must not allow Kerberos authentication. | Exists" ansible.builtin.lineinfile: path: "{{ rhel9stig_sshd_config_file }}" - regexp: (?i)^(?#)\s*KerberosAuthentication\s*(yes|no) + regexp: (?i)^(?#)KerberosAuthentication\s*(yes|no|true|false) line: "KerberosAuthentication {{ rhel9stig_sshd_config.kerbauth }}" - create: true validate: sshd -t -f %s - name: "MEDIUM | RHEL-09-255145 | PATCH | RHEL 9 SSH daemon must not allow rhosts authentication" @@ -1452,19 +1520,20 @@ notify: Restart_ssh block: - name: "MEDIUM | RHEL-09-255145 | PATCH | RHEL 9 SSH daemon must not allow rhosts authentication | Remove" - when: "rhel9stig_sshd_config_file not in item" + when: "item.path != rhel9stig_sshd_config_file" ansible.builtin.replace: path: "{{ item }}" - regexp: (?i)^\s*IgnoreRhosts + regexp: (?i)^(IgnoreRhosts (no|false)) replace: '#\1' + failed_when: discovered_ignorerhosts_exists.rc != 257 + register: discovered_ignorerhosts_exists loop: "{{ prelim_sshd_config_files.files }}" - name: "MEDIUM | RHEL-09-255145 | PATCH | RHEL 9 SSH daemon must not allow rhosts authentication | Exists" ansible.builtin.lineinfile: path: "{{ rhel9stig_sshd_config_file }}" - regexp: (?i)^(?#)\s*IgnoreRhosts\s*(yes|no) + regexp: (?i)^(?#)IgnoreRhosts\s*(yes|no|true|false) line: "IgnoreRhosts {{ rhel9stig_sshd_config.ignorerhosts }}" - create: true validate: sshd -t -f %s - name: "MEDIUM | RHEL-09-255150 | PATCH | RHEL 9 SSH daemon must not allow known hosts authentication." @@ -1482,17 +1551,19 @@ notify: Restart_ssh block: - name: "MEDIUM | RHEL-09-255150 | PATCH | RHEL 9 SSH daemon must not allow known hosts authentication. | Remove" - when: "rhel9stig_sshd_config_file not in item" + when: "item.path != rhel9stig_sshd_config_file" ansible.builtin.replace: path: "{{ item }}" - regexp: (?i)^\s*IgnoreUserKnownHosts + regexp: (?i)^(IgnoreUserKnownHosts (no|false)) replace: '#\1' + failed_when: discovered_knownhosts_exists.rc != 257 + register: discovered_knownhosts_exists loop: "{{ prelim_sshd_config_files.files }}" - - name: "MEDIUM | RHEL-09-255150 | PATCH | RHEL 9 SSH daemon must not allow known hosts authentication. | Exists " + - name: "MEDIUM | RHEL-09-255150 | PATCH | RHEL 9 SSH daemon must not allow known hosts authentication. | Exists" ansible.builtin.lineinfile: path: "{{ rhel9stig_sshd_config_file }}" - regexp: (?i)^(?#)\s*IgnoreUserKnownHosts\s*(yes|no) + regexp: (?i)^(?#)IgnoreUserKnownHosts\s*(yes|no|true|false) line: "IgnoreUserKnownHosts {{ rhel9stig_sshd_config.ignoreknownhosts }}" create: true validate: sshd -t -f %s @@ -1511,23 +1582,25 @@ - ssh notify: Restart_ssh block: - - name: "MEDIUM | RHEL-09-255155 | PATCH | RHEL 9 SSH daemon must disable remote X connections for interactive users. | remove setting from incorrect files" - when: "rhel9stig_sshd_config_file not in item" + - name: "MEDIUM | RHEL-09-255155 | PATCH | RHEL 9 SSH daemon must disable remote X connections for interactive users. | Remove" + when: "item.path != rhel9stig_sshd_config_file" ansible.builtin.replace: path: "{{ item }}" - regexp: (?i)^\s*X11Forwarding + regexp: (?i)(^X11Forwarding (yes|true)) replace: '#\1' + failed_when: discovered_x11forward_exists.rc != 257 + register: discovered_x11forward_exists loop: "{{ prelim_sshd_config_files.files }}" - - name: "MEDIUM | RHEL-09-255155 | PATCH | RHEL 9 SSH daemon must disable remote X connections for interactive users. | Ensure setting in correct files" + - name: "MEDIUM | RHEL-09-255155 | PATCH | RHEL 9 SSH daemon must disable remote X connections for interactive users. | Exists" ansible.builtin.lineinfile: path: "{{ rhel9stig_sshd_config_file }}" - regexp: (?i)^(?#)\s*X11forwarding\s*(yes|no) + regexp: (?i)^(?#)X11forwarding\s*(yes|no|true|false) line: "X11forwarding {{ rhel9stig_sshd_config.x11forward }}" create: true validate: sshd -t -f %s -- name: "MEDIUM | RHEL-09-255160 | PATCH | RHEL 9 SSH daemon must perform strict mode checking of home directory configuration files. | Exists" +- name: "MEDIUM | RHEL-09-255160 | PATCH | RHEL 9 SSH daemon must perform strict mode checking of home directory configuration files." when: - rhel_09_255160 tags: @@ -1542,17 +1615,19 @@ notify: Restart_ssh block: - name: "MEDIUM | RHEL-09-255160 | PATCH | RHEL 9 SSH daemon must perform strict mode checking of home directory configuration files. | Remove" - when: "rhel9stig_sshd_config_file not in item" + when: "item.path != rhel9stig_sshd_config_file" ansible.builtin.replace: path: "{{ item }}" - regexp: (?i)^\s*StrictModes + regexp: (?i)^(StrictModes (no|false)) replace: '#\1' + failed_when: discovered_strictmode_exists.rc != 257 + register: discovered_strictmode_exists loop: "{{ prelim_sshd_config_files.files }}" - name: "MEDIUM | RHEL-09-255160 | PATCH | RHEL 9 SSH daemon must perform strict mode checking of home directory configuration files. | Exists" ansible.builtin.lineinfile: path: "{{ rhel9stig_sshd_config_file }}" - regexp: (?i)^(?#)\s*StrictModes\s*(yes|no) + regexp: (?i)^(?#)StrictModes\s*(yes|no|true|false) line: "StrictModes {{ rhel9stig_sshd_config.strictmodes }}" create: true validate: sshd -t -f %s @@ -1572,22 +1647,24 @@ notify: Restart_ssh block: - name: "MEDIUM | RHEL-09-255165 | PATCH | RHEL 9 SSH daemon must display the date and time of the last successful account logon upon an SSH logon. | Remove" - when: "rhel9stig_sshd_config_file not in item" + when: "item.path != rhel9stig_sshd_config_file" ansible.builtin.replace: path: "{{ item }}" - regexp: (?i)^\s*PrintLastLog + regexp: (?i)^(PrintLastLog (no|false)) replace: '#\1' + failed_when: discovered_printlastlog_exists.rc != 257 + register: discovered_printlastlog_exists loop: "{{ prelim_sshd_config_files.files }}" - name: "MEDIUM | RHEL-09-255165 | PATCH | RHEL 9 SSH daemon must display the date and time of the last successful account logon upon an SSH logon. | Exists" ansible.builtin.lineinfile: path: "{{ rhel9stig_sshd_config_file }}" - regexp: (?i)^(?#)\s*PrintLastLog\s*(yes|no) + regexp: (?i)^(?#)PrintLastLog\s*(yes|no|true|false) line: "PrintLastLog {{ rhel9stig_sshd_config.lastlog }}" create: true validate: sshd -t -f %s -- name: "MEDIUM | RHEL-09-255170 | PATCH | RHEL 9 SSH daemon must display the date and time of the last successful account logon upon an SSH logon." +- name: "MEDIUM | RHEL-09-255170 | PATCH | RHEL 9 SSH daemon must be configured to use privilege separation." when: - rhel_09_255170 tags: @@ -1601,18 +1678,20 @@ - ssh notify: Restart_ssh block: - - name: "MEDIUM | RHEL-09-255170 | PATCH | RHEL 9 SSH daemon must display the date and time of the last successful account logon upon an SSH logon. | Remove" - when: "rhel9stig_sshd_config_file not in item" + - name: "MEDIUM | RHEL-09-255170 | PATCH | RHEL 9 SSH daemon must be configured to use privilege separation. | Remove" + when: "item.path != rhel9stig_sshd_config_file" ansible.builtin.replace: path: "{{ item }}" - regexp: (?i)^\s*UsePrivilegeSeparation + regexp: (?i)^(UsePrivilegeSeparation.*) replace: '#\1' + failed_when: discovered_privseperation_exists.rc != 257 + register: discovered_privseperation_exists loop: "{{ prelim_sshd_config_files.files }}" - - name: "MEDIUM | RHEL-09-255170 | PATCH | RHEL 9 SSH daemon must display the date and time of the last successful account logon upon an SSH logon. | Exists" + - name: "MEDIUM | RHEL-09-255170 | PATCH | RHEL 9 SSH daemon must be configured to use privilege separation. | Exists" ansible.builtin.lineinfile: path: "{{ rhel9stig_sshd_config_file }}" - regexp: (?i)^(?#)\s*UsePrivilegeSeparation\s*(yes|no) + regexp: (?i)^(?#)UsePrivilegeSeparation\s*(yes|no|sandbox) line: "UsePrivilegeSeparation {{ rhel9stig_sshd_config.privsep }}" create: true validate: sshd -t -f %s @@ -1632,17 +1711,19 @@ notify: Restart_ssh block: - name: "MEDIUM | RHEL-09-255175 | PATCH | RHEL 9 SSH daemon must prevent remote hosts from connecting to the proxy display. | Remove" - when: "rhel9stig_sshd_config_file not in item" + when: "item.path != rhel9stig_sshd_config_file" ansible.builtin.replace: path: "{{ item }}" - regexp: (?i)^\s*X11UseLocalhost + regexp: (?i)^(X11UseLocalhost.*) replace: '#\1' + failed_when: discovered_x11localhost_exists.rc != 257 + register: discovered_x11localhost_exists loop: "{{ prelim_sshd_config_files.files }}" - name: "MEDIUM | RHEL-09-255175 | PATCH | RHEL 9 SSH daemon must prevent remote hosts from connecting to the proxy display. | Exists" ansible.builtin.lineinfile: path: "{{ rhel9stig_sshd_config_file }}" - regexp: (?i)^(?#)\s*X11UseLocalhost\s*(yes|no) + regexp: (?i)^(?#)X11UseLocalhost\s*(yes|no|true|false) line: "X11UseLocalhost {{ rhel9stig_sshd_config.x11uselocal }}" create: true validate: sshd -t -f %s From 243e9c0333064569bc6918801ac5ea5618469a94 Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Tue, 21 Jan 2025 19:01:47 +0000 Subject: [PATCH 5/9] fix title typo Signed-off-by: Mark Bolwell --- tasks/Cat1/RHEL-09-4xxxxx.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tasks/Cat1/RHEL-09-4xxxxx.yml b/tasks/Cat1/RHEL-09-4xxxxx.yml index ff5da43..c5a91a7 100644 --- a/tasks/Cat1/RHEL-09-4xxxxx.yml +++ b/tasks/Cat1/RHEL-09-4xxxxx.yml @@ -1,6 +1,6 @@ --- -- name: HIGH | RHEL-09-0411100 | The root account must be the only account having unrestricted access to RHEL 9 system. +- name: HIGH | RHEL-09-411100 | The root account must be the only account having unrestricted access to RHEL 9 system. when: - rhel_09_411100 tags: @@ -15,13 +15,13 @@ vars: warn_control_id: "HIGH | RHEL-09-411100" block: - - name: HIGH | RHEL-09-0411100 | AUDIT | The root account must be the only account having unrestricted access to RHEL 9 system. + - name: HIGH | RHEL-09-411100 | AUDIT | The root account must be the only account having unrestricted access to RHEL 9 system. ansible.builtin.shell: "cat /etc/passwd | awk -F: '($3 == 0 && $1 != \"root\") {i++;print $1 } END {exit i}'" changed_when: false check_mode: false register: rhel9stig_uid_zero_accounts_except_root - - name: HIGH | RHEL-09-0411100 | WARN | The root account must be the only account having unrestricted access to RHEL 9 system. + - name: HIGH | RHEL-09-411100 | WARN | The root account must be the only account having unrestricted access to RHEL 9 system. when: - rhel9stig_uid_zero_accounts_except_root is defined - rhel9stig_uid_zero_accounts_except_root.stdout | length > 0 From c452caeddd8d7c6755b42f7321ecdd5e1f46c174 Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Tue, 21 Jan 2025 19:02:04 +0000 Subject: [PATCH 6/9] variabllise the audit binaries Signed-off-by: Mark Bolwell --- tasks/Cat2/RHEL-09-23xxxx.yml | 27 +++------------------------ vars/main.yml | 10 ++++++++++ 2 files changed, 13 insertions(+), 24 deletions(-) diff --git a/tasks/Cat2/RHEL-09-23xxxx.yml b/tasks/Cat2/RHEL-09-23xxxx.yml index 7d99e84..4bf8f69 100644 --- a/tasks/Cat2/RHEL-09-23xxxx.yml +++ b/tasks/Cat2/RHEL-09-23xxxx.yml @@ -981,14 +981,7 @@ modification_time: preserve owner: root path: "{{ item }}" - loop: - - /sbin/auditctl - - /sbin/aureport - - /sbin/ausearch - - /sbin/autrace - - /sbin/auditd - - /sbin/rsyslogd - - /sbin/augenrules + loop: "{{ audit_bins }}" - name: "MEDIUM | RHEL-09-232040 | PATCH | RHEL 9 cron configuration directories must have a mode of 0700 or less permissive." when: @@ -1723,14 +1716,7 @@ ansible.builtin.file: owner: root path: "{{ item }}" - loop: - - '/sbin/auditctl' - - '/sbin/aureport' - - '/sbin/ausearch' - - '/sbin/autrace' - - '/sbin/auditd' - - '/sbin/rsyslogd' - - '/sbin/augenrules' + loop: "{{ audit_bins}}" - name: "MEDIUM | RHEL-09-232225 | PATCH | RHEL 9 audit tools must be group-owned by root." when: @@ -1746,14 +1732,7 @@ ansible.builtin.file: group: root path: "{{ item }}" - loop: - - '/sbin/auditctl' - - '/sbin/aureport' - - '/sbin/ausearch' - - '/sbin/autrace' - - '/sbin/auditd' - - '/sbin/rsyslogd' - - '/sbin/augenrules' + loop: "{{ audit_bins }}" - name: "MEDIUM | RHEL-09-232230 | PATCH | RHEL 9 cron configuration files directory must be owned by root." when: diff --git a/vars/main.yml b/vars/main.yml index 490834c..1d5562a 100644 --- a/vars/main.yml +++ b/vars/main.yml @@ -50,3 +50,13 @@ rhel9stig_dod_kex: # Defaults added for searches rhel9stig_ungrouped_files_found: false rhel9stig_unowned_files_found: false + +# Audit binaries +audit_bins: +- '/usr/sbin/auditctl' +- '/usr/sbin/aureport' +- '/usr/sbin/ausearch' +- '/usr/sbin/autrace' +- '/usr/sbin/auditd' +- '/usr/sbin/rsyslogd' +- '/usr/sbin/augenrules' From b496611da81e9bd3521d73d2f7041fe874494808 Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Tue, 21 Jan 2025 19:02:21 +0000 Subject: [PATCH 7/9] capture ssh_config file #66 Signed-off-by: Mark Bolwell --- tasks/prelim.yml | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/tasks/prelim.yml b/tasks/prelim.yml index ce70eba..beb4ba1 100644 --- a/tasks/prelim.yml +++ b/tasks/prelim.yml @@ -192,11 +192,21 @@ tags: - ssh -- name: PRELIM | SSH | existing ssh config files +- name: PRELIM | SSH | find existing ssh config files ansible.builtin.find: - path: /etc/ssh - patterns: '*.conf' + paths: + - /etc/ssh/ + - /etc/ssh/sshd_config.d + patterns: 'sshd_config,*.conf' + recurse: false register: prelim_sshd_config_files + tags: + - always + +- name: Debug + ansible.builtin.debug: + msg: "{{ prelim_sshd_config_files }}" + tags: always - name: "PRELIM | Interactive User accounts" ansible.builtin.shell: 'cat /etc/passwd | grep -Ev "nologin|/sbin" | cut -d: -f6' From e591b19c060efef77d2b508fe84d232bdbf659aa Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Tue, 21 Jan 2025 19:05:47 +0000 Subject: [PATCH 8/9] Address issues #72 maxlogins made variable Signed-off-by: Mark Bolwell --- defaults/main.yml | 1 + tasks/Cat3/RHEL-09-4xxxxx.yml | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/defaults/main.yml b/defaults/main.yml index 7ba3f34..315149c 100644 --- a/defaults/main.yml +++ b/defaults/main.yml @@ -605,6 +605,7 @@ rhel9stig_gui: "{{ rhel_09_gnome_present.stat.exists | default(false) }}" ## SSHD rhel9stig_sshd_config_file: /etc/ssh/sshd_config rhel9stig_ssh_required: true +rhel9stig_sshd_config_maxlogins: 10 rhel9stig_sshd_config: banner_file: /etc/issue ciphers: "{{ rhel9stig_dod_ciphers }}" diff --git a/tasks/Cat3/RHEL-09-4xxxxx.yml b/tasks/Cat3/RHEL-09-4xxxxx.yml index 79a2c64..df83263 100644 --- a/tasks/Cat3/RHEL-09-4xxxxx.yml +++ b/tasks/Cat3/RHEL-09-4xxxxx.yml @@ -36,7 +36,7 @@ ansible.builtin.lineinfile: path: /etc/security/limits.conf regexp: '^\s*\*\s+hard\s+maxlogins\s+\d{1,}' - line: "* hard maxlogins 10" + line: "* hard maxlogins {{ rhel9stig_sshd_config_maxlogins }}" - name: "LOW | RHEL-09-412075 | PATCH | RHEL 9 must display the date and time of the last successful account logon upon logon." when: From ff36a7c239cd5259b857d1ee0c36610852c1289f Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Tue, 21 Jan 2025 19:23:26 +0000 Subject: [PATCH 9/9] Updated 611080 issue #67 Signed-off-by: Mark Bolwell --- tasks/Cat2/RHEL-09-61xxxx.yml | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/tasks/Cat2/RHEL-09-61xxxx.yml b/tasks/Cat2/RHEL-09-61xxxx.yml index 54cd3ea..7a7a5f4 100644 --- a/tasks/Cat2/RHEL-09-61xxxx.yml +++ b/tasks/Cat2/RHEL-09-61xxxx.yml @@ -446,8 +446,7 @@ - rhel9stig_24hr_passwd_restrict.stdout | length > 0 - not rhel9stig_disruption_high ansible.builtin.debug: - msg: | - "Warning!! Accounts have been found to have an incorrect password lifetime" + msg: "Warning!! Accounts have been found to have an incorrect password lifetime" - name: "MEDIUM | RHEL-09-611080 | WARN | RHEL 9 passwords must have a 24 hours minimum password lifetime restriction in /etc/shadow. | Warning" when: @@ -460,7 +459,7 @@ when: - rhel9stig_24hr_passwd_restrict.stdout | length > 0 - rhel9stig_disruption_high - - item in rhel9stig_interactive_users + - item in rhel9stig_interactive_users.stdout_lines ansible.builtin.shell: "passwd -n 1 {{ item }}" loop: "{{ rhel9stig_24hr_passwd_restrict.stdout_lines }}"