From 26e9ed2b58b28c93b3956c2bca38e1bbbfe4a596 Mon Sep 17 00:00:00 2001 From: uk-bolly Date: Tue, 30 Apr 2024 08:19:35 +0100 Subject: [PATCH] Release of v1r12 (#275) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * ruleid updates for v1r12 refer changelog Signed-off-by: Mark Bolwell * updated Signed-off-by: Mark Bolwell * updated PRELIM in title Signed-off-by: Mark Bolwell * updated the workflow version and galaxy setup Signed-off-by: Mark Bolwell * fix typo Signed-off-by: Mark Bolwell * Oraclelinux updated thanks to @BillSkiCO Signed-off-by: Mark Bolwell * updated task 20030 thanks to @BillSkiCO Signed-off-by: Mark Bolwell * updated 40321 thanks to @whitehat237 Signed-off-by: Mark Bolwell * updated after feedback from #245 Signed-off-by: Mark Bolwell * added issue #248 fix Signed-off-by: Mark Bolwell * Added fix for #254 Signed-off-by: Mark Bolwell * fix syntax Signed-off-by: Mark Bolwell * Squashed commit of the following: commit 14d7da6a3335dea85d73044cac45f851d45e721f Author: Mark Bolwell Date: Wed Feb 21 15:52:45 2024 +0000 updated Signed-off-by: Mark Bolwell commit e6b8a7c2008da9cf11075265801723c597284d6e Author: Mark Bolwell Date: Wed Feb 21 15:52:05 2024 +0000 lint and variable improvements Signed-off-by: Mark Bolwell commit 79948fb314df745bc37f94dffcdf6ec818d945bc Author: Mark Bolwell Date: Wed Feb 21 15:51:32 2024 +0000 ssh validation added Signed-off-by: Mark Bolwell commit 4742d58286387ffdbf569c2094d34290c8f2f90a Author: Mark Bolwell Date: Wed Feb 21 15:50:46 2024 +0000 ssh validation added Signed-off-by: Mark Bolwell commit 33348bc1d3a0537d0cdbcfc70c10286875d97261 Author: Mark Bolwell Date: Wed Feb 21 15:50:25 2024 +0000 changed ordering and added logic Signed-off-by: Mark Bolwell commit 6c2d07987d379575c6ecf766e528da19ba5ffae0 Author: Mark Bolwell Date: Wed Feb 21 15:50:12 2024 +0000 removed as mnot required Signed-off-by: Mark Bolwell commit 1d775c698c9270f707dddbd955d096bfaa978dae Author: Mark Bolwell Date: Wed Feb 21 15:50:04 2024 +0000 updated Signed-off-by: Mark Bolwell commit 562d7604e5263ed4d5cd97cdd2a46ea4a1c3f58f Author: Mark Bolwell Date: Wed Feb 21 15:49:57 2024 +0000 updated precommit Signed-off-by: Mark Bolwell commit bb46131304f00cfe9c9b7b62dda9150ab5d19643 Author: Mark Bolwell Date: Wed Feb 21 12:04:15 2024 +0000 Added ability for audit_only Signed-off-by: Mark Bolwell Signed-off-by: Mark Bolwell * fix typo line 020030 Signed-off-by: Mark Bolwell * updated due to galaxy_ng changes Signed-off-by: Mark Bolwell * Revert "fixed gnutls as per issue 196 thansk to @jmalpede" This reverts commit 63c4c8406e7f6b49eeb94d787f258917e8716b0b. Signed-off-by: William Panlener * Update main.yml Removing stale var rhel8stig_sshd_compression Signed-off-by: William Golembieski * [pre-commit.ci] pre-commit autoupdate updates: - [github.com/pre-commit/pre-commit-hooks: v4.4.0 → v4.5.0](https://github.com/pre-commit/pre-commit-hooks/compare/v4.4.0...v4.5.0) - [github.com/gitleaks/gitleaks: v8.18.0 → v8.18.1](https://github.com/gitleaks/gitleaks/compare/v8.18.0...v8.18.1) - [github.com/ansible-community/ansible-lint: v6.20.2 → v6.22.1](https://github.com/ansible-community/ansible-lint/compare/v6.20.2...v6.22.1) - [github.com/adrienverge/yamllint.git: v1.32.0 → v1.33.0](https://github.com/adrienverge/yamllint.git/compare/v1.32.0...v1.33.0) * [pre-commit.ci] pre-commit autoupdate updates: - [github.com/gitleaks/gitleaks: v8.18.1 → v8.18.2](https://github.com/gitleaks/gitleaks/compare/v8.18.1...v8.18.2) - [github.com/ansible-community/ansible-lint: v6.22.1 → v24.2.0](https://github.com/ansible-community/ansible-lint/compare/v6.22.1...v24.2.0) - [github.com/adrienverge/yamllint.git: v1.33.0 → v1.35.1](https://github.com/adrienverge/yamllint.git/compare/v1.33.0...v1.35.1) * updated Readme credits Signed-off-by: Mark Bolwell * updated credits Signed-off-by: Mark Bolwell * [pre-commit.ci] pre-commit autoupdate updates: - [github.com/ansible-community/ansible-lint: v24.2.0 → v24.2.1](https://github.com/ansible-community/ansible-lint/compare/v24.2.0...v24.2.1) * Updated RHEL-08-020050 to loop over stdout_lines. Fixes issue #261. Signed-off-by: Phenix66 <34311559+Phenix66@users.noreply.github.com> * [pre-commit.ci] pre-commit autoupdate updates: - [github.com/pre-commit/pre-commit-hooks: v4.5.0 → v4.6.0](https://github.com/pre-commit/pre-commit-hooks/compare/v4.5.0...v4.6.0) * addressing #251 Signed-off-by: Mark Bolwell * fix issue #263 Signed-off-by: Mark Bolwell * Address issues #242 Signed-off-by: Mark Bolwell * housekeeping lint Signed-off-by: Mark Bolwell * Meet fix text of V-244546 Signed-off-by: Eric Lehmann * issue #267 Signed-off-by: Mark Bolwell * [pre-commit.ci] pre-commit autoupdate updates: - [github.com/ansible-community/ansible-lint: v24.2.1 → v24.2.2](https://github.com/ansible-community/ansible-lint/compare/v24.2.1...v24.2.2) * fixed error in conditional rhel-08-020022 Signed-off-by: Mark Bolwell --------- Signed-off-by: Mark Bolwell Signed-off-by: William Panlener Signed-off-by: William Golembieski Signed-off-by: uk-bolly Signed-off-by: Phenix66 <34311559+Phenix66@users.noreply.github.com> Signed-off-by: Eric Lehmann Co-authored-by: William Panlener Co-authored-by: William Golembieski Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: Phenix66 <34311559+Phenix66@users.noreply.github.com> Co-authored-by: Eric Lehmann --- .config/.gitleaks-report.json | 1 - .config/.secrets.baseline | 120 -------------- .pre-commit-config.yaml | 7 +- Changelog.md | 20 ++- README.md | 2 +- defaults/main.yml | 98 +++++------- handlers/main.yml | 13 +- tasks/LE_audit_setup.yml | 20 ++- tasks/audit_only.yml | 30 ++++ tasks/fix-cat1.yml | 15 +- tasks/fix-cat2.yml | 242 ++++++++++++++++------------ tasks/fix-cat3.yml | 6 +- tasks/main.yml | 37 +++-- tasks/parse_etc_passwd.yml | 2 +- tasks/post_remediation_audit.yml | 62 +++---- tasks/pre_remediation_audit.yml | 94 ++++++----- tasks/prelim.yml | 62 ++++--- templates/ansible_vars_goss.yml.j2 | 19 +-- templates/pam_pkcs11.conf.j2 | 249 ----------------------------- vars/audit.yml | 41 +++++ 20 files changed, 456 insertions(+), 684 deletions(-) delete mode 100644 .config/.gitleaks-report.json delete mode 100644 .config/.secrets.baseline create mode 100644 tasks/audit_only.yml delete mode 100644 templates/pam_pkcs11.conf.j2 create mode 100644 vars/audit.yml diff --git a/.config/.gitleaks-report.json b/.config/.gitleaks-report.json deleted file mode 100644 index fe51488c..00000000 --- a/.config/.gitleaks-report.json +++ /dev/null @@ -1 +0,0 @@ -[] diff --git a/.config/.secrets.baseline b/.config/.secrets.baseline deleted file mode 100644 index 2ad77429..00000000 --- a/.config/.secrets.baseline +++ /dev/null @@ -1,120 +0,0 @@ -{ - "version": "1.4.0", - "plugins_used": [ - { - "name": "ArtifactoryDetector" - }, - { - "name": "AWSKeyDetector" - }, - { - "name": "AzureStorageKeyDetector" - }, - { - "name": "Base64HighEntropyString", - "limit": 4.5 - }, - { - "name": "BasicAuthDetector" - }, - { - "name": "CloudantDetector" - }, - { - "name": "DiscordBotTokenDetector" - }, - { - "name": "GitHubTokenDetector" - }, - { - "name": "HexHighEntropyString", - "limit": 3.0 - }, - { - "name": "IbmCloudIamDetector" - }, - { - "name": "IbmCosHmacDetector" - }, - { - "name": "JwtTokenDetector" - }, - { - "name": "KeywordDetector", - "keyword_exclude": "" - }, - { - "name": "MailchimpDetector" - }, - { - "name": "NpmDetector" - }, - { - "name": "PrivateKeyDetector" - }, - { - "name": "SendGridDetector" - }, - { - "name": "SlackDetector" - }, - { - "name": "SoftlayerDetector" - }, - { - "name": "SquareOAuthDetector" - }, - { - "name": "StripeDetector" - }, - { - "name": "TwilioKeyDetector" - } - ], - "filters_used": [ - { - "path": "detect_secrets.filters.allowlist.is_line_allowlisted" - }, - { - "path": "detect_secrets.filters.common.is_ignored_due_to_verification_policies", - "min_level": 2 - }, - { - "path": "detect_secrets.filters.heuristic.is_indirect_reference" - }, - { - "path": "detect_secrets.filters.heuristic.is_likely_id_string" - }, - { - "path": "detect_secrets.filters.heuristic.is_lock_file" - }, - { - "path": "detect_secrets.filters.heuristic.is_not_alphanumeric_string" - }, - { - "path": "detect_secrets.filters.heuristic.is_potential_uuid" - }, - { - "path": "detect_secrets.filters.heuristic.is_prefixed_with_dollar_sign" - }, - { - "path": "detect_secrets.filters.heuristic.is_sequential_string" - }, - { - "path": "detect_secrets.filters.heuristic.is_swagger_file" - }, - { - "path": "detect_secrets.filters.heuristic.is_templated_secret" - }, - { - "path": "detect_secrets.filters.regex.should_exclude_file", - "pattern": [ - ".config/.gitleaks-report.json", - "tasks/parse_etc_passwd.yml", - "templates/pam_pkcs11.conf.j2" - ] - } - ], - "results": {}, - "generated_at": "2023-09-25T15:48:01Z" -} diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 873f2757..71a7e81a 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -7,7 +7,7 @@ ci: repos: - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v4.5.0 + rev: v4.6.0 hooks: # Safety - id: detect-aws-credentials @@ -33,17 +33,14 @@ repos: rev: v1.4.0 hooks: - id: detect-secrets - args: [ '--baseline', '.config/.secrets.baseline' ] - exclude: .config/.gitleaks-report.json - repo: https://github.com/gitleaks/gitleaks rev: v8.18.2 hooks: - id: gitleaks - args: ['--baseline-path', '.config/.gitleaks-report.json'] - repo: https://github.com/ansible-community/ansible-lint - rev: v24.2.0 + rev: v24.2.2 hooks: - id: ansible-lint name: Ansible-lint diff --git a/Changelog.md b/Changelog.md index 9dd2c8df..c0bcafc1 100644 --- a/Changelog.md +++ b/Changelog.md @@ -1,7 +1,25 @@ # Changes to RHEL8STIG +## 3.1 - STIG V1R12 - 25th Oct 2023 + +ruleid updated + +- 010020 +- 010471 +- 030741 +- 030742 +- 040400 + +- added SSH validation +- added ansible_facts for variable usage + +- AUDIT + - Audit_only ability now added to run standalone audit + - audit_only: true + - Related Audit repo updated to improve tests audit binary(goss updated to latest version) + ## 3.0.3 - Stig V1R11 - 26th July 2023 -q + - updates to collections since galaxy updated - updates to audit diff --git a/README.md b/README.md index 8d27ce4a..9ed50479 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ ## Configure a RHEL8 based system to be complaint with Disa STIG -This role is based on RHEL 8 DISA STIG: [Version 1, Rel 11 released on July 26, 2023](https://dl.dod.cyber.mil/wp-content/uploads/stigs/zip/U_RHEL_8_V1R11_STIG.zip). +This role is based on RHEL 8 DISA STIG: [Version 1, Rel 12 released on Oct 25, 2023](https://dl.dod.cyber.mil/wp-content/uploads/stigs/zip/U_RHEL_8_V1R12_STIG.zip). --- diff --git a/defaults/main.yml b/defaults/main.yml index e3c36861..acc87c40 100644 --- a/defaults/main.yml +++ b/defaults/main.yml @@ -1,6 +1,6 @@ --- ## metadata for Audit benchmark -benchmark_version: 'v1r11' +benchmark_version: 'v1r12' ## Benchmark name used by audting control role # The audit variable found at the base @@ -56,24 +56,46 @@ rhel8stig_skip_reboot: true # Defined will change if control requires change_requires_reboot: false -### Goss is required on the remote host +########################################## +### Goss is required on the remote host ### +## Refer to vars/auditd.yml for any other settings ## + +# Allow audit to setup the requirements including installing git (if option chosen and downloading and adding goss binary to system) setup_audit: false + +# enable audits to run - this runs the audit and get the latest content +run_audit: false + +# Only run Audit do not remediate +audit_only: false +# As part of audit_only +# This will enable files to be copied back to control node +fetch_audit_files: false +# Path to copy the files to will create dir structure +audit_capture_files_dir: /some/location to copy to on control node + # How to retrieve audit binary # Options are copy or download - detailed settings at the bottom of this file # you will need to access to either github or the file already dowmloaded get_audit_binary_method: download +## if get_audit_binary_method - copy the following needs to be updated for your environment +## it is expected that it will be copied from somewhere accessible to the control node +## e.g copy from ansible control node to remote host +audit_bin_copy_location: /some/accessible/path + # how to get audit files onto host options # options are git/copy/get_url other e.g. if you wish to run from already downloaded conf audit_content: git -# enable audits to run - this runs the audit and get the latest content -run_audit: false +# archive or copy: +audit_conf_copy: "some path to copy from" + +# get_url: +audit_files_url: "some url maybe s3?" # Run heavy tests - some tests can have more impact on a system enabling these can have greater impact on a system audit_run_heavy_tests: true -# Timeout for those cmds that take longer to run where timeout set -audit_cmd_timeout: 60000 ### End Goss enablements #### #### Detailed settings found at the end of this document #### @@ -856,20 +878,26 @@ rhel8stig_ntp_server_name: 0.us.pool.ntp.mil # rhel8stig_fapolicy_white_list is the whitelist for fapolicyd, the last item in the list must be dyny all all rhel8stig_fapolicy_white_list: - 'deny_audit perm=any pattern=ld_so : all' - - deny all all + - 'deny perm=any all : all' # RHEL-08-040090 # rhel8stig_custom_firewall_zone is the desired name for the new customer firewall zone rhel8stig_custom_firewall_zone: "new_fw_zone" +# rhel8stig_copy_existing_zone - if you wish to copy an existing zones rules to the new zone +rhel8stig_copy_existing_zone: true +# rhel8stig_existing_zone_to_copy - name of the zone that you wish to copy from +rhel8stig_existing_zone_to_copy: public + # RHEL-08-040090 -# rhel8stig_white_list_services is the services that you want to allow through initially for teh new firewall zone +# This designed not work with rhel8stig_existing_zone_to_copy and when deploy new rules +# rhel8stig_white_list_services is the services that you want to allow through initially for the new firewall zone # http and ssh need to be enabled for the role to run. # This can also be a port number if no service exists rhel8stig_white_list_services: + - ssh - http - https - - ssh # RHEL-08-010290 # RHEL-08-010290 @@ -900,55 +928,3 @@ rhel8stig_tmux_lock_after_time: 900 # The value given to Defaults timestamp timeout= in the sudo file. # Value must be greater than 0 to conform to STIG standards rhel8stig_sudo_timestamp_timeout: 1 - -#### Goss Configuration Settings #### -# Set correct env for the run_audit.sh script from https://github.com/ansible-lockdown/{{ benchmark }}-Audit.git" -audit_run_script_environment: - AUDIT_BIN: "{{ audit_bin }}" - AUDIT_FILE: 'goss.yml' - AUDIT_CONTENT_LOCATION: "{{ audit_out_dir }}" - -### Goss binary settings ### -audit_bin_version: - release: v0.3.23 - checksum: 'sha256:9e9f24e25f86d6adf2e669a9ffbe8c3d7b9b439f5f877500dea02ba837e10e4d' -audit_bin_path: /usr/local/bin/ -audit_bin: "{{ audit_bin_path }}goss" -audit_format: json - -# if get_audit_binary_method == download change accordingly -audit_bin_url: "https://github.com/goss-org/goss/releases/download/{{ audit_bin_version.release }}/goss-linux-amd64" - -## if get_audit_binary_method - copy the following needs to be updated for your environment -## it is expected that it will be copied from somewhere accessible to the control node -## e.g copy from ansible control node to remote host -audit_bin_copy_location: /some/accessible/path - -#### Goss Audit Benchmark file ### -## managed by the control audit_content -# git -audit_file_git: "https://github.com/ansible-lockdown/{{ benchmark }}-Audit.git" -audit_git_version: "benchmark_{{ benchmark_version }}_rh8" - -# archive or copy: -audit_conf_copy: "some path to copy from" - -# get_url: -audit_files_url: "some url maybe s3?" - -## Goss configuration information -# Where the goss configs and outputs are stored -audit_out_dir: '/opt' -# Where the goss audit configuration will be stored -audit_conf_dir: "{{ audit_out_dir }}/{{ benchmark }}-Audit" - -# If changed these can affect other products -pre_audit_outfile: "{{ audit_out_dir }}/{{ ansible_hostname }}-{{ benchmark }}-{{ benchmark_version }}_pre_scan_{{ ansible_date_time.epoch }}.{{ audit_format }}" -post_audit_outfile: "{{ audit_out_dir }}/{{ ansible_hostname }}-{{ benchmark }}-{{ benchmark_version }}_post_scan_{{ ansible_date_time.epoch }}.{{ audit_format }}" - -## The following should not need changing -audit_vars_path: "{{ audit_conf_dir }}/vars/{{ ansible_hostname }}.yml" -audit_results: | - The pre remediation results are: {{ pre_audit_summary }}. - The post remediation results are: {{ post_audit_summary }}. - Full breakdown can be found in {{ audit_out_dir }} diff --git a/handlers/main.yml b/handlers/main.yml index 3e6ff61d..c210d6f1 100644 --- a/handlers/main.yml +++ b/handlers/main.yml @@ -1,4 +1,9 @@ --- + +- name: change_requires_reboot + ansible.builtin.set_fact: + change_requires_reboot: true + - name: systemctl daemon-reload ansible.builtin.systemd: daemon_reload: true @@ -16,6 +21,7 @@ when: - not rhel8stig_system_is_chroot - "'openssh-server' in ansible_facts.packages" + - not change_requires_reboot - name: restart sssd ansible.builtin.service: @@ -30,6 +36,7 @@ state: restarted when: - not rhel8stig_system_is_chroot + - not change_requires_reboot - name: restart rsyslog ansible.builtin.service: @@ -82,6 +89,7 @@ - not rhel8stig_skip_for_travis - not rhel8stig_system_is_chroot - not system_is_container + - not change_requires_reboot - name: update auditd ansible.builtin.template: @@ -98,6 +106,7 @@ - not rhel8stig_skip_for_travis - not rhel8stig_system_is_chroot - not system_is_container + - not change_requires_reboot - name: rebuild initramfs ansible.builtin.shell: dracut -f @@ -146,7 +155,3 @@ ansible.builtin.debug: msg: "Post-run OpenSCAP score is {{ rhel8stig_postscanresults.Benchmark.TestResult.score['#text'] }}" when: rhel8stig_oscap_scan - -- name: change_requires_reboot - ansible.builtin.set_fact: - change_requires_reboot: true diff --git a/tasks/LE_audit_setup.yml b/tasks/LE_audit_setup.yml index c8222b8e..7ef94b4a 100644 --- a/tasks/LE_audit_setup.yml +++ b/tasks/LE_audit_setup.yml @@ -1,22 +1,34 @@ --- +- name: Pre Audit Setup | Set audit package name + block: + - name: Pre Audit Setup | Set audit package name | 64bit + ansible.builtin.set_fact: + audit_pkg_arch_name: AMD64 + when: ansible_facts.machine == "x86_64" + + - name: Pre Audit Setup | Set audit package name | ARM64 + ansible.builtin.set_fact: + audit_pkg_arch_name: ARM64 + when: ansible_facts.machine == "arm64" + - name: Pre Audit Setup | Download audit binary ansible.builtin.get_url: - url: "{{ audit_bin_url }}" + url: "{{ audit_bin_url }}{{ audit_pkg_arch_name }}" dest: "{{ audit_bin }}" owner: root group: root - checksum: "{{ audit_bin_version.checksum }}" + checksum: "{{ audit_bin_version[audit_pkg_arch_name + '_checksum'] }}" mode: '0555' when: - get_audit_binary_method == 'download' -- name: Pre Audit Setup | copy audit binary +- name: Pre Audit Setup | Copy audit binary ansible.builtin.copy: src: "{{ audit_bin_copy_location }}" dest: "{{ audit_bin }}" + mode: '0555' owner: root group: root - mode: '0555' when: - get_audit_binary_method == 'copy' diff --git a/tasks/audit_only.yml b/tasks/audit_only.yml new file mode 100644 index 00000000..864f5bbe --- /dev/null +++ b/tasks/audit_only.yml @@ -0,0 +1,30 @@ +--- + +- name: Audit_Only | Create local Directories for hosts + ansible.builtin.file: + mode: '0755' + path: "{{ audit_capture_files_dir }}/{{ inventory_hostname }}" + recurse: true + state: directory + when: fetch_audit_files + delegate_to: localhost + become: false + +- name: Audit_only | Get audits from systems and put in group dir + ansible.builtin.fetch: + dest: "{{ audit_capture_files_dir }}/{{ inventory_hostname }}/" + flat: true + mode: '0644' + src: "{{ pre_audit_outfile }}" + when: fetch_audit_files + +- name: Audit_only | Show Audit Summary + when: + - audit_only + ansible.builtin.debug: + msg: "The Audit results are: {{ pre_audit_summary }}." + +- name: Audit_only | Stop Playbook Audit Only selected + when: + - audit_only + ansible.builtin.meta: end_play diff --git a/tasks/fix-cat1.yml b/tasks/fix-cat1.yml index a215e10c..f89014d5 100644 --- a/tasks/fix-cat1.yml +++ b/tasks/fix-cat1.yml @@ -133,7 +133,7 @@ - CAT1 - CCI-000068 - SRG-OS-000033-GPOS-00014 - - SV-230223r792855_rule + - SV-230223r928585_rule - V-230223 - name: "HIGH | RHEL-08-010121 | PATCH | The RHEL 8 operating system must not have accounts configured with blank or null passwords." @@ -276,18 +276,18 @@ - name: "HIGH | RHEL-08-010470 | PATCH | There must be no .shosts files on the RHEL 8 operating system." block: - name: "HIGH | RHEL-08-010470 | PATCH | There must be no .shosts files on the RHEL 8 operating system. | Find .shosts files" - ansible.builtin.find: - path: '/' - recurse: true - patterns: '*.shosts' + ansible.builtin.shell: find / -name "*.shosts" + changed_when: false + failed_when: rhel_08_010470_shost_files.rc not in [ 0, 1 ] register: rhel_08_010470_shost_files - name: "HIGH | RHEL-08-010470 | PATCH | There must be no .shosts files on the RHEL 8 operating system. | Remove .shosts files" ansible.builtin.file: - path: "{{ item.path }}" + path: "{{ item }}" state: absent with_items: - - "{{ rhel_08_010470_shost_files.files }}" + - "{{ rhel_08_010470_shost_files.stdout_lines }}" + when: rhel_08_010470_shost_files.stdout | length > 0 when: - rhel_08_010470 tags: @@ -321,6 +321,7 @@ path: /etc/ssh/sshd_config regexp: '(?i)^#?PermitEmptyPasswords' line: 'PermitEmptyPasswords no' + validate: '/usr/sbin/sshd -T -f %s' notify: restart sshd when: - rhel_08_020330 diff --git a/tasks/fix-cat2.yml b/tasks/fix-cat2.yml index 035503f3..8e50668b 100644 --- a/tasks/fix-cat2.yml +++ b/tasks/fix-cat2.yml @@ -112,6 +112,7 @@ path: /etc/ssh/sshd_config regexp: '(?i)^#?Banner' line: 'Banner /etc/issue' + validate: '/usr/sbin/sshd -T -f %s' when: - rhel8stig_ssh_required @@ -191,11 +192,42 @@ - V-230226 - name: "MEDIUM | RHEL-08-010070 | PATCH | All RHEL 8 remote access methods must be monitored." - ansible.builtin.lineinfile: - path: /etc/rsyslog.conf - line: "auth.*;authpriv.*;daemon.* /var/log/secure" - create: true - mode: '0644' + block: + - name: "MEDIUM | RHEL-08-010070 | AUDIT | All RHEL 8 remote access methods must be monitored. | check settings info" + ansible.builtin.shell: grep '*.info' /etc/rsyslog.conf + changed_when: false + failed_when: false + register: rhel_08_010070_info_set_rsyslog + + - name: "MEDIUM | RHEL-08-010070 | AUDIT | All RHEL 8 remote access methods must be monitored. | check settings authpriv" + ansible.builtin.shell: grep 'authpriv.* /var/log/secure' /etc/rsyslog.conf + changed_when: false + failed_when: false + register: rhel_08_010070_authpriv_set_rsyslog + + - name: "MEDIUM | RHEL-08-010070 | PATCH | All RHEL 8 remote access methods must be monitored. | Adjust settings no info" + ansible.builtin.lineinfile: + path: /etc/rsyslog.conf + regexp: ^(?!#).*\/var\/log\/secure + line: 'auth.*;authpriv.*;daemon.* /var/log/secure' + create: true + mode: '0644' + when: + - rhel_08_010070_info_set_rsyslog.stdout == 0 + - rhel_08_010070_authpriv_set_rsyslog.stdout > 0 + + - name: "MEDIUM | RHEL-08-010070 | PATCH | All RHEL 8 remote access methods must be monitored. | Adjust settings if info set" + ansible.builtin.lineinfile: + path: /etc/rsyslog.conf + backrefs: true + regexp: ^(?!#)(.*)(authpriv\.\*)(.*\/var\/log\/secure) + line: \1authpriv.*\2/var/log/secure + create: true + mode: '0644' + when: + - rhel_08_010070_info_set_rsyslog.stdout | length > 0 + - rhel_08_010070_authpriv_set_rsyslog.stdout == 0 + notify: restart rsyslog when: - rhel_08_010070 @@ -429,19 +461,18 @@ - name: "MEDIUM | RHEL-08-010161 | PATCH | RHEL 8 must prevent system daemons from using Kerberos for authentication." block: - name: "MEDIUM | RHEL-08-010161 | AUDIT | RHEL 8 must prevent system daemons from using Kerberos for authentication. | Find .keytab files" - ansible.builtin.find: - path: / - patterns: '*.keytab' - recurse: true + ansible.builtin.shell: find / -name *.keytab + changed_when: false + failed_when: rhel8stig_010161_keytab_files.rc not in [ 0, 1 ] register: rhel8stig_010161_keytab_files - name: "MEDIUM | RHEL-08-010161 | PATCH | RHEL 8 must prevent system daemons from using Kerberos for authentication. | Remove .keytab files" ansible.builtin.file: - path: "{{ item.path }}" + path: "{{ item }}" state: absent with_items: - - "{{ rhel8stig_010161_keytab_files.files }}" - when: rhel8stig_010161_keytab_files.matched > 0 + - "{{ rhel8stig_010161_keytab_files.stdout_lines }}" + when: rhel8stig_010161_keytab_files.stdout | length > 0 when: - rhel_08_010161 tags: @@ -524,6 +555,7 @@ path: /etc/ssh/sshd_config regexp: '(?i)^#?ClientAliveCountMax.*' line: ClientAliveCountMax 1 + validate: '/usr/sbin/sshd -T -f %s' notify: restart sshd when: - rhel_08_010200 @@ -542,6 +574,7 @@ path: /etc/ssh/sshd_config regexp: '(?i)^#?ClientAliveInterval.*' line: "ClientAliveInterval {{ rhel8stig_ssh_session_timeout }}" + validate: '/usr/sbin/sshd -T -f %s' notify: restart sshd when: - rhel_08_010201 @@ -1596,25 +1629,19 @@ - name: "MEDIUM | RHEL-08-010480 | PATCH | The RHEL 8 SSH public host key files must have mode 0644 or less permissive." block: - name: "MEDIUM | RHEL-08-010480 | AUDIT | The RHEL 8 SSH public host key files must have mode 0644 or less permissive. | Find files" - ansible.builtin.find: - paths: /etc/ssh - recurse: true - file_type: file - patterns: 'ssh_host*_key.pub' - hidden: true + ansible.builtin.shell: find /etc/ssh -name ssh_host*_key.pub changed_when: false - failed_when: false + failed_when: rhel_08_010480_public_files.rc not in [ 0, 1 ] register: rhel_08_010480_public_files - name: "MEDIUM | RHEL-08-010480 | PATCH | The RHEL 8 SSH public host key files must have mode 0644 or less permissive. | Set permissions" ansible.builtin.file: - path: "{{ item.path }}" + path: "{{ item }}" mode: "{{ rhel8stig_ssh_pub_key_perm }}" with_items: - - "{{ rhel_08_010480_public_files.files }}" - loop_control: - label: "{{ item.path }}" + - "{{ rhel_08_010480_public_files.stdout_lines }}" notify: restart sshd + when: rhel_08_010480_public_files.stdout | length > 0 when: - rhel_08_010480 - rhel8stig_ssh_required @@ -1630,25 +1657,19 @@ - name: "MEDIUM | RHEL-08-010490 | PATCH | The RHEL 8 SSH private host key files must have mode 0640 or less permissive." block: - name: "MEDIUM | RHEL-08-010490 | AUDIT | The RHEL 8 SSH private host key files must have mode 0640 or less permissive. | Find files" - ansible.builtin.find: - paths: /etc/ssh - recurse: true - file_type: file - patterns: 'ssh_host*key' - hidden: true + ansible.builtin.shell: find /etc/ssh -name ssh_host*_key changed_when: false - failed_when: false + failed_when: rhel_08_010490_private_host_key_files.rc not in [ 0, 1 ] register: rhel_08_010490_private_host_key_files - name: "MEDIUM | RHEL-08-010490 | PATCH | The RHEL 8 SSH private host key files must have mode 0640 or less permissive. | Set permissions" ansible.builtin.file: - path: "{{ item.path }}" + path: "{{ item }}" mode: "{{ rhel8stig_ssh_priv_key_perm }}" with_items: - - "{{ rhel_08_010490_private_host_key_files.files }}" - loop_control: - label: "{{ item.path }}" + - "{{ rhel_08_010490_private_host_key_files.stdout_lines }}" notify: restart sshd + when: rhel_08_010490_private_host_key_files.stdout | length > 0 when: - rhel_08_010490 - rhel8stig_ssh_required @@ -1666,6 +1687,7 @@ path: /etc/ssh/sshd_config regexp: '(?i)^#?StrictModes' line: 'StrictModes yes' + validate: '/usr/sbin/sshd -T -f %s' notify: restart sshd when: - rhel_08_010500 @@ -1684,6 +1706,7 @@ path: /etc/ssh/sshd_config regexp: '(?i)^#?IgnoreUserKnownHosts' line: 'IgnoreUserKnownHosts yes' + validate: '/usr/sbin/sshd -T -f %s' notify: restart sshd when: - rhel_08_010520 @@ -1702,6 +1725,7 @@ path: /etc/ssh/sshd_config regexp: '(?i)^#?KerberosAuthentication' line: "KerberosAuthentication no" + validate: '/usr/sbin/sshd -T -f %s' notify: restart sshd when: - rhel_08_010521 @@ -1720,6 +1744,7 @@ path: /etc/ssh/sshd_config regexp: '(?i)^#?GSSAPIAuthentication' line: "GSSAPIAuthentication no" + validate: '/usr/sbin/sshd -T -f %s' when: - rhel_08_010522 - rhel8stig_ssh_required @@ -1776,6 +1801,7 @@ path: /etc/ssh/sshd_config regexp: '(?i)^#?PermitRootLogin' line: 'PermitRootLogin no' + validate: '/usr/sbin/sshd -T -f %s' notify: restart sshd when: - rhel_08_010550 @@ -2191,7 +2217,6 @@ when: - rhel_08_010660 - rhel8stig_disruption_high - # - rhel_08_stig_interactive_homedir_inifiles is defined tags: - RHEL-08-010660 - CAT2 @@ -2402,7 +2427,7 @@ block: - name: "MEDIUM | RHEL-08-010690 | AUDIT | Executable search paths within the initialization files of all local interactive RHEL 8 users must only contain paths that resolve to the system default or the users home directory. | Find path files" ansible.builtin.shell: find "{{ item }}" -maxdepth 1 -type f | xargs grep "PATH=" | cut -d':' -f1 | xargs realpath - with_items: "{{ rhel_08_stig_interactive_homedir_results }}" + with_items: "{{ discovered_interactive_users_home.stdout_list }}" register: rhel_08_010690_ini_path_grep_list changed_when: false failed_when: false @@ -2519,15 +2544,31 @@ - SV-230320r627750_rule - V-230320 +# Required for RHEL-08-010730 +- name: "MEDIUM | RHEL-08-010750 | PATCH | All RHEL 8 local interactive user home directories defined in the /etc/passwd file must exist." + ansible.builtin.file: + path: "{{ item }}" + state: directory + with_items: "{{ discovered_interactive_users_home.stdout_lines }}" + when: + - rhel_08_010750 + tags: + - RHEL-08-010750 + - CAT2 + - CCI-000366 + - SRG-OS-000480-GPOS-00227 + - SV-230323r627750_rule + - V-230323 + - permissions + - name: "MEDIUM | RHEL-08-010730 | PATCH | All RHEL 8 local interactive user home directories must have mode 0750 or less permissive." ansible.builtin.file: path: "{{ item }}" mode: "{{ rhel8stig_local_int_home_perms }}" with_items: - - "{{ local_home_directories.stdout_lines }}" + - "{{ discovered_interactive_users_home.stdout_lines }}" when: - rhel_08_010730 - - local_home_directories.stdout | length > 0 tags: - RHEL-08-010730 - CAT2 @@ -2539,20 +2580,12 @@ - name: "MEDIUM | RHEL-08-010731 | PATCH | All RHEL 8 local interactive user home directory files must have mode 0750 or less permissive." block: - - name: "MEDIUM | RHEL-08-010731 | AUDIT | All RHEL 8 local interactive user home directory files must have mode 0750 or less permissive. | Find out of compliance files" - ansible.builtin.shell: "find {{ item }} -perm -750 ! -perm 750" - changed_when: false - failed_when: false - register: rhel_08_010731_files - with_items: - - "{{ rhel8stig_passwd | selectattr('uid', '>=', rhel8stig_interactive_uid_start | int) | selectattr('uid', '!=', 65534) | map(attribute='dir') | list }}" - - name: "MEDIUM | RHEL-08-010731 | PATCH | All RHEL 8 local interactive user home directory files must have mode 0750 or less permissive. | Bring files into compliance" ansible.builtin.file: path: "{{ item }}" mode: "{{ rhel8stig_local_int_home_file_perms }}" with_items: - - "{{ rhel_08_010731_files.results | map(attribute='stdout_lines') | flatten }}" + - "{{ discovered_interactive_users_home.stdout_lines }}" when: rhel8stig_disruption_high - name: "MEDIUM | RHEL-08-010731 | AUDIT | All RHEL 8 local interactive user home directory files must have mode 0750 or less permissive. | Alert on out of compliance files" @@ -2560,7 +2593,7 @@ msg: - "Alert! Below are the files that are in interactive user folders but permissiosn less restrictiv than 0750." - "Please review the files to bring into STIG compliance" - - "{{ rhel_08_010731_files.results | map(attribute='stdout_lines') | flatten }}" + - "{{ discovered_interactive_users_home.stdout_lines }}" when: not rhel8stig_disruption_high when: - rhel_08_010731 @@ -2583,10 +2616,8 @@ label: "{{ rhel8stig_passwd_label }}" when: - rhel_08_010740 - - (item.uid >= rhel8stig_interactive_uid_start | int) - - (item.uid >= rhel8stig_interactive_uid_stop | int) + - item.uid is search(discovered_interactive_uids.stdout) tags: - - skip_ansible_lint - RHEL-08-010740 - CAT2 - CCI-000366 @@ -2606,8 +2637,7 @@ label: "{{ rhel8stig_passwd_label }}" when: - rhel_08_010741 - - (item.uid >= rhel8stig_interactive_uid_start | int) - - item.uid != 65534 + - item.uid is search(discovered_interactive_uids.stdout) tags: - RHEL-08-010741 - CAT2 @@ -2617,26 +2647,6 @@ - V-244532 - permissions -- name: "MEDIUM | RHEL-08-010750 | PATCH | All RHEL 8 local interactive user home directories defined in the /etc/passwd file must exist." - ansible.builtin.file: - path: "{{ item.dir }}" - state: directory - with_items: "{{ rhel8stig_passwd }}" - loop_control: - label: "{{ rhel8stig_passwd_label }}" - when: - - rhel_08_010750 - - (item.uid >= rhel8stig_interactive_uid_start | int) - tags: - - skip_ansible_lint - - RHEL-08-010750 - - CAT2 - - CCI-000366 - - SRG-OS-000480-GPOS-00227 - - SV-230323r627750_rule - - V-230323 - - permissions - - name: "MEDIUM | RHEL-08-010760 | PATCH | All RHEL 8 local interactive user accounts must be assigned a home directory upon creation." ansible.builtin.lineinfile: path: /etc/login.defs @@ -2747,6 +2757,7 @@ path: /etc/ssh/sshd_config regexp: '(?i)^#?PermitUserEnvironment' line: 'PermitUserEnvironment no' + validate: '/usr/sbin/sshd -T -f %s' notify: restart sshd when: - rhel_08_010830 @@ -3195,7 +3206,7 @@ - password-auth when: - rhel_08_020022 - - ansible_distribution_version is version('8.2', '>=') + - ansible_distribution_version is version('8.1', '<=') tags: - RHEL-08-020022 - CAT2 @@ -3260,16 +3271,17 @@ - name: "MEDIUM | RHEL-08-020030 | PATCH | RHEL 8 must enable a user session lock until that user re-establishes access using established identification and authentication procedures for graphical user sessions." block: - name: "MEDIUM | RHEL-08-020030 | AUDIT | RHEL 8 must enable a user session lock until that user re-establishes access using established identification and authentication procedures for graphical user sessions. | Check for lock-enabled" - ansible.builtin.shell: "grep lock-enabled /etc/dconf/db/* -rI | sort -u | tail -n 1 | cut -f1 -d:" + ansible.builtin.shell: "grep -IlR ^lock-enabled /etc/dconf/db/*" changed_when: false failed_when: false register: rhel_08_020030_lock_enabled - name: "MEDIUM | RHEL-08-020030 | PATCH | RHEL 8 must enable a user session lock until that user re-establishes access using established identification and authentication procedures for graphical user sessions. | Set if exists" ansible.builtin.lineinfile: - path: "{{ rhel_08_020030_lock_enabled.stdout }}" - regexp: '^lock-enabled' + path: "{{ item }}" + regexp: ^lock-enabled line: lock-enabled=true + loop: "{{ rhel_08_020030_lock_enabled.stdout_lines }}" when: rhel_08_020030_lock_enabled.stdout | length > 0 notify: dconf update @@ -3372,13 +3384,13 @@ - name: "MEDIUM | RHEL-08-020050 | PATCH | RHEL 8 must be able to initiate directly a session lock for all connection types using smartcard when the smartcard is removed." block: - name: "MEDIUM | RHEL-08-020050 | AUDIT | RHEL 8 must be able to initiate directly a session lock for all connection types using smartcard when the smartcard is removed. | Find removal-action param" - ansible.builtin.shell: 'grep "removal-action=" /etc/dconf/db/* -R | cut -f1 -d:' + ansible.builtin.shell: "grep -IlR removal-action= /etc/dconf/db/*" changed_when: false failed_when: false register: rhel_08_020050_removal_action - name: "MEDIUM | RHEL-08-020050 | AUDIT | RHEL 8 must be able to initiate directly a session lock for all connection types using smartcard when the smartcard is removed. | Find removal-action param" - ansible.builtin.shell: "grep removal-action= /etc/dconf/db/* -R | cut -f1 -d: | sed 's:.*/::'" + ansible.builtin.shell: "grep -IlR removal-action= /etc/dconf/db/* | sed 's:.*/::'" changed_when: false failed_when: false register: rhel_08_020050_removal_action_file @@ -3393,22 +3405,24 @@ line: | [org/gnome/settings-daemon/peripherals/smartcard] removal-action='lock-screen' - when: rhel_08_020050_removal_action.stdout | length == 0 + when: rhel_08_020050_removal_action.stdout_lines | length == 0 notify: dconf update - name: "MEDIUM | RHEL-08-020050 | PATCH | RHEL 8 must be able to initiate directly a session lock for all connection types using smartcard when the smartcard is removed. | Update removal-action if exists" ansible.builtin.lineinfile: - path: "{{ rhel_08_020050_removal_action.stdout }}" + path: "{{ item }}" regexp: ^removal-action= line: removal-action='lock-screen' - when: rhel_08_020050_removal_action.stdout | length > 0 + loop: "{{ rhel_08_020050_removal_action.stdout_lines }}" + when: rhel_08_020050_removal_action.stdout_lines | length > 0 notify: dconf update - name: "MEDIUM | RHEL-08-020050 | PATCH | RHEL 8 must be able to initiate directly a session lock for all connection types using smartcard when the smartcard is removed. | Set smartcard section of db" ansible.builtin.lineinfile: - path: '/etc/dconf/db/distro.d/locks/{{ rhel_08_020050_removal_action_file.stdout }}' + path: '/etc/dconf/db/distro.d/locks/{{ item }}' line: /org/gnome/settings-daemon/peripherals/smartcard/removal-action - when: rhel_08_020050_removal_action_file.stdout | length > 0 + loop: "{{ rhel_08_020050_removal_action_file.stdout_lines }}" + when: rhel_08_020050_removal_action_file.stdout_lines | length > 0 notify: dconf update - name: "MEDIUM | RHEL-08-020050 | PATCH | RHEL 8 must be able to initiate directly a session lock for all connection types using smartcard when the smartcard is removed. | Set smartcard section of db" @@ -3419,7 +3433,7 @@ owner: root group: root mode: 0640 - when: rhel_08_020050_removal_action_file.stdout | length == 0 + when: rhel_08_020050_removal_action_file.stdout_lines | length == 0 notify: dconf update when: - rhel_08_020050 @@ -3436,7 +3450,7 @@ - name: "MEDIUM | RHEL-08-020060 | PATCH | RHEL 8 must automatically log out graphical user sessions after 15 minutes of inactivity." block: - name: "MEDIUM | RHEL-08-020060 | AUDIT | RHEL 8 must automatically log out graphical user sessions after 15 minutes of inactivity. | Find idle-delay parameter" - ansible.builtin.shell: 'grep idle-delay= /etc/dconf/db/* -R | cut -f1 -d:' + ansible.builtin.shell: 'grep -IlR idle-delay= /etc/dconf/db/*' changed_when: false failed_when: false register: rhel_08_020060_idle_delay_param @@ -3458,14 +3472,15 @@ - name: "MEDIUM | RHEL-08-020060 | PATCH | RHEL 8 must automatically log out graphical user sessions after 15 minutes of inactivity. | Set idle-delay if exists" ansible.builtin.lineinfile: - path: "{{ rhel_08_020060_idle_delay_param.stdout }}" + path: "{{ item }}" regexp: '^idle-delay=' line: idle-delay=uint32 900 owner: root group: root mode: 0640 - notify: dconf update + loop: "{{ rhel_08_020060_idle_delay_param.stdout }}" when: rhel_08_020060_idle_delay_param.stdout | length > 0 + notify: dconf update when: - rhel_08_020060 - "'dconf' in ansible_facts.packages" @@ -4352,7 +4367,7 @@ hidden: true use_regex: true register: rhel8stig_020352_file - loop: "{{ local_home_directories.stdout_lines }}" + loop: "{{ discovered_interactive_users_home.stdout_lines }}" - name: "MEDIUM | RHEL-08-020352 | PATCH | RHEL 8 must set the umask value to 077 for all local interactive user accounts. | Remove umask param" ansible.builtin.lineinfile: @@ -6037,15 +6052,38 @@ permanent: true state: present + - name: "MEDIUM | RHEL-08-040090 | PATCH | A RHEL 8 firewall must employ a deny-all, allow-by-exception policy for allowing connections to other systems. | Copy existing rules to new zone" + ansible.builtin.copy: + src: "/etc/firewalld/zones/{{ rhel8stig_existing_zone_to_copy }}.xml" + dest: "/etc/firewalld/zones/{{ rhel8stig_custom_firewall_zone }}.xml" + remote_src: true + when: + - rhel8stig_copy_existing_zone + - rhel8stig_existing_zone_to_copy | length > 0 + + - name: "MEDIUM | RHEL-08-040090 | PATCH | A RHEL 8 firewall must employ a deny-all, allow-by-exception policy for allowing connections to other systems. | Amend copied file" + ansible.builtin.replace: + path: "/etc/firewalld/zones/{{ rhel8stig_custom_firewall_zone }}.xml" + regexp: "{{ item.regexp }}" + replace: \1{{ item.replace }}\2 + loop: + - { regexp: (\s*(\s*$), replace: ' target="DROP">' } + - { regexp: (\s*).*(<\/short>), replace: "{{ rhel8stig_custom_firewall_zone }}" } + when: + - rhel8stig_copy_existing_zone + - rhel8stig_existing_zone_to_copy | length > 0 + - name: "MEDIUM | RHEL-08-040090 | PATCH | A RHEL 8 firewall must employ a deny-all, allow-by-exception policy for allowing connections to other systems. | Allow internet and ssh" ansible.posix.firewalld: zone: "{{ rhel8stig_custom_firewall_zone }}" permanent: true state: enabled - service: "{{ (item == (item | regex_search('^[a-z]+$'))) | bool | ternary(item, omit) }}" - port: "{{ (item == (item | regex_search('^[0-9]+/[a-z]+$'))) | bool | ternary(item, omit) }}" + service: "{{ (item == (item | regex_search('^[a-z]+$'))) | ternary(item, omit) }}" + port: "{{ (item == (item | regex_search('^[0-9]+/[a-z]+$'))) | ternary(item, omit) }}" with_items: - "{{ rhel8stig_white_list_services }}" + when: + - not rhel8stig_copy_existing_zone - name: "MEDIUM | RHEL-08-040090 | PATCH | A RHEL 8 firewall must employ a deny-all, allow-by-exception policy for allowing connections to other systems. | Target Drop | 2.10+" ansible.posix.firewalld: @@ -6053,7 +6091,9 @@ permanent: true state: enabled target: DROP - when: ansible_version.full is version_compare('2.10.0 | int', '>=') + when: + - ansible_version.full is version_compare('2.10.0 | int', '>=') + - not rhel8stig_copy_existing_zone - name: "MEDIUM | RHEL-08-040090 | PATCH | A RHEL 8 firewall must employ a deny-all, allow-by-exception policy for allowing connections to other systems. | Target Drop | 2.9" block: @@ -6067,7 +6107,9 @@ ansible.builtin.shell: firewall-cmd --permanent --zone={{ rhel8stig_custom_firewall_zone }} --set-target=DROP when: - rhel8stig_target_drop_set.rc != 0 - when: ansible_version.full is version_compare('2.10 | int', '<') + when: + - ansible_version.full is version_compare('2.10 | int', '<') + - not rhel8stig_copy_existing_zone - name: "MEDIUM | RHEL-08-040090 | PATCH | A RHEL 8 firewall must employ a deny-all, allow-by-exception policy for allowing connections to other systems. | Reload zones" ansible.builtin.shell: firewall-cmd --reload @@ -6119,7 +6161,7 @@ - CCI-001444 - SRG-OS-000299-GPOS-00117 - SV-230506r627750_rule - - V-23050 + - V-230506 - wifi - name: "MEDIUM | RHEL-08-040111 | PATCH | RHEL 8 Bluetooth must be disabled." @@ -6581,6 +6623,7 @@ path: /etc/ssh/sshd_config regexp: '(?i)^#?RekeyLimit' line: 'RekeyLimit 1G 1h' + validate: '/usr/sbin/sshd -T -f %s' notify: restart sshd when: - rhel_08_040161 @@ -7096,7 +7139,7 @@ - name: "MEDIUM | RHEL-08-040279 | PATCH | RHEL 8 must ignore IPv4 Internet Control Message Protocol (ICMP) redirect messages. | Use template to create file" ansible.posix.sysctl: - name: net.ipv4.conf.all.send_redirects + name: net.ipv4.conf.all.accept_redirects value: 0 state: present reload: "{{ rhel8stig_sysctl_reload }}" @@ -7441,6 +7484,7 @@ path: /etc/ssh/sshd_config regexp: '(?i)^#?X11Forwarding' line: 'X11Forwarding no' + validate: '/usr/sbin/sshd -T -f %s' notify: restart sshd when: - rhel_08_040340 @@ -7459,6 +7503,7 @@ path: /etc/ssh/sshd_config regexp: '(?i)^#?X11UseLocalhost' line: 'X11UseLocalhost yes' + validate: '/usr/sbin/sshd -T -f %s' when: - rhel_08_040341 - rhel8stig_ssh_required @@ -7473,11 +7518,12 @@ - name: "MEDIUM | RHEL-08-040342 | PATCH | RHEL 8 SSH server must be configured to use only FIPS-validated key exchange algorithms. | Add KEXs" block: - name: "MEDIUM | RHEL-08-040342 | AUDIT | RHEL 8 SSH server must be configured to use only FIPS-validated key exchange algorithms. | get KEXs" - ansible.builtin.shell: grep "^CRYPTO_POLICY" /etc/crypto-policies/back-ends/opensshserver.config | cut -d "'" -f2 | sed s'/ /\n/g' | grep -i okexa | sed s'/-o//g' + ansible.builtin.shell: grep -E "^CRYPTO_POLICY" /etc/crypto-policies/back-ends/opensshserver.config | cut -d "'" -f2 | sed s'/ /\n/g' | grep -i okexa | sed s'/-o//g' changed_when: false + failed_when: false register: rhel8stig_current_kex - - name: MEDIUM | RHEL-08-040342 | PATCH | RHEL 8 SSH server must be configured to use only FIPS-validated key exchange algorithms. | get KEXs" + - name: MEDIUM | RHEL-08-040342 | PATCH | RHEL 8 SSH server must be configured to use only FIPS-validated key exchange algorithms. | update KEXs" ansible.builtin.lineinfile: path: /etc/crypto-policies/back-ends/opensshserver.config regexp: '(^CRYPTO_POLICY=.*)-o{{ rhel8stig_current_kex.stdout }}(.*$)' @@ -7586,7 +7632,7 @@ - CAT2 - CCI-002265 - SRG-OS-000324-GPOS-00125 - - SV-254520r858835_rule + - SV-254520r928805_rule - V-254520 - selinux diff --git a/tasks/fix-cat3.yml b/tasks/fix-cat3.yml index 66c817ca..31c8abb7 100644 --- a/tasks/fix-cat3.yml +++ b/tasks/fix-cat3.yml @@ -163,7 +163,7 @@ - CAT3 - CCI-000366 - SRG-OS-000480-GPOS-00227 - - SV-230285r917876_rule + - SV-230285r928587_rule - SV-244527r743830_rule - V-230285 - V-244527 @@ -406,7 +406,7 @@ - CAT3 - CCI-000381 - SRG-OS-000095-GPOS-00049 - - SV-230485r627750_rule + - SV-230485r928590_rule - V-230485 - chrony @@ -422,7 +422,7 @@ - CAT3 - CCI-000381 - SRG-OS-000095-GPOS-00049 - - SV-230486r627750_rule + - SV-230486r928593_rule - V-230486 - chrony diff --git a/tasks/main.yml b/tasks/main.yml index c516e703..14a40c90 100644 --- a/tasks/main.yml +++ b/tasks/main.yml @@ -4,15 +4,15 @@ ansible.builtin.setup: gather_subset: distribution,!all,!min when: - - ansible_distribution is not defined + - ansible_facts.distribution is not defined tags: - always - name: Check OS version and family ansible.builtin.assert: - that: (ansible_distribution != 'CentOS' and ansible_os_family == 'RedHat' or ansible_os_family == "Rocky") and ansible_distribution_major_version is version_compare('8', '==') - fail_msg: "This role can only be run against RHEL/Rocky 8. {{ ansible_distribution }} {{ ansible_distribution_major_version }} is not supported." - success_msg: "This role is running against a supported OS {{ ansible_distribution }} {{ ansible_distribution_major_version }}" + that: (ansible_facts.distribution != 'CentOS' and ansible_facts.os_family == 'RedHat' or ansible_facts.os_family == "Rocky") and ansible_facts.distribution_major_version is version_compare('8', '==') + fail_msg: "This role can only be run against RHEL/Rocky 8. {{ ansible_facts.distribution }} {{ ansible_facts.distribution_major_version }} is not supported." + success_msg: "This role is running against a supported OS {{ ansible_facts.distribution }} {{ ansible_facts.distribution_major_version }}" when: - not skip_os_check tags: @@ -36,14 +36,14 @@ ansible.builtin.include_vars: file: "{{ container_vars_file }}" - - name: output if discovered is a container + - name: Output if discovered is a container ansible.builtin.debug: msg: system has been discovered as a container when: - system_is_container when: - ansible_connection == 'docker' or - ansible_virtualization_type in ["docker", "lxc", "openvz", "podman", "container"] + ansible_facts.virtualization_type in ["docker", "lxc", "openvz", "podman", "container"] tags: - container_discovery - always @@ -92,7 +92,7 @@ - RHEL-08-010149 - name: Include OS specific variables - ansible.builtin.include_vars: "{{ ansible_distribution }}.yml" + ansible.builtin.include_vars: "{{ ansible_facts.distribution }}.yml" tags: - always @@ -134,10 +134,19 @@ - prelim_tasks - run_audit -- name: Include pre-remediation tasks - ansible.builtin.import_tasks: pre_remediation_audit.yml +- name: Include audit specific variables + ansible.builtin.include_vars: audit.yml when: + - run_audit or audit_only + - setup_audit + tags: + - setup_audit - run_audit + +- name: Include pre-remediation audit tasks + ansible.builtin.import_tasks: pre_remediation_audit.yml + when: + - run_audit or audit_only - setup_audit tags: - run_audit @@ -158,17 +167,17 @@ - name: Include CAT III patches ansible.builtin.import_tasks: fix-cat3.yml - when: rhel8stig_cat3_patch | bool + when: rhel8stig_cat3_patch tags: - CAT3 - low -- name: flush handlers +- name: Flush handlers ansible.builtin.meta: flush_handlers -- name: reboot system +- name: Reboot system block: - - name: reboot system if not skipped + - name: Reboot system if not skipped ansible.builtin.reboot: when: - change_requires_reboot @@ -182,7 +191,7 @@ - change_requires_reboot - rhel8stig_skip_reboot -- name: run post remediation audit +- name: Run post remediation audit ansible.builtin.import_tasks: post_remediation_audit.yml when: - run_audit diff --git a/tasks/parse_etc_passwd.yml b/tasks/parse_etc_passwd.yml index ef4fbf6a..aada90e2 100644 --- a/tasks/parse_etc_passwd.yml +++ b/tasks/parse_etc_passwd.yml @@ -15,7 +15,7 @@ vars: ld_passwd_regex: >- ^(?P[^:]*):(?P[^:]*):(?P[^:]*):(?P[^:]*):(?P[^:]*):(?P[^:]*):(?P[^:]*) - ld_passwd_yaml: | + ld_passwd_yaml: | # pragma: allowlist secret id: >-4 \g password: >-4 diff --git a/tasks/post_remediation_audit.yml b/tasks/post_remediation_audit.yml index fa9614b6..2c51bbb0 100644 --- a/tasks/post_remediation_audit.yml +++ b/tasks/post_remediation_audit.yml @@ -1,18 +1,28 @@ --- -- name: Post Audit | Capture audit data if json format - block: +- name: Post Audit | Run post_remediation {{ benchmark }} audit + ansible.builtin.shell: "{{ audit_conf_dir }}/run_audit.sh -v {{ audit_vars_path }} -o {{ post_audit_outfile }} -g \"{{ group_names }}\"" + changed_when: true + environment: + AUDIT_BIN: "{{ audit_bin }}" + AUDIT_CONTENT_LOCATION: "{{ audit_out_dir }}" + AUDIT_FILE: goss.yml - - name: "Post Audit | Run post_remediation {{ benchmark }} audit" - ansible.builtin.shell: "{{ audit_conf_dir }}/run_audit.sh -v {{ audit_vars_path }} -o {{ post_audit_outfile }} -g {{ group_names }}" - changed_when: true - environment: - AUDIT_BIN: "{{ audit_bin }}" - AUDIT_CONTENT_LOCATION: "{{ audit_out_dir }}" - AUDIT_FILE: "goss.yml" +- name: Post Audit | ensure audit files readable by users + ansible.builtin.file: + path: "{{ item }}" + mode: '0644' + state: file + loop: + - "{{ post_audit_outfile }}" + - "{{ pre_audit_outfile }}" - - name: "capture data {{ post_audit_outfile }}" - ansible.builtin.shell: "cat {{ post_audit_outfile }}" +- name: Post Audit | Capture audit data if json format + when: + - audit_format == "json" + block: + - name: capture data {{ post_audit_outfile }} + ansible.builtin.shell: cat {{ post_audit_outfile }} register: post_audit changed_when: false @@ -20,37 +30,17 @@ ansible.builtin.set_fact: post_audit_summary: "{{ post_audit.stdout | from_json | json_query(summary) }}" vars: - summary: 'summary."summary-line"' - when: - - audit_format == "json" + summary: summary."summary-line" - name: Post Audit | Capture audit data if documentation format + when: + - audit_format == "documentation" block: - - - name: "Post Audit | Run post_remediation {{ benchmark }} audit" - ansible.builtin.shell: "{{ audit_conf_dir }}/run_audit.sh -v {{ audit_vars_path }} -o {{ post_audit_outfile }} -g {{ group_names }} -f documentation" - changed_when: true - environment: - AUDIT_BIN: "{{ audit_bin }}" - AUDIT_CONTENT_LOCATION: "{{ audit_out_dir }}" - AUDIT_FILE: "goss.yml" - - - name: "Post Audit | capture data {{ post_audit_outfile }}" - ansible.builtin.shell: "tail -2 {{ post_audit_outfile }}" + - name: Post Audit | capture data {{ post_audit_outfile }} + ansible.builtin.shell: tail -2 {{ post_audit_outfile }} register: post_audit changed_when: false - name: Post Audit | Capture post-audit result ansible.builtin.set_fact: post_audit_summary: "{{ post_audit.stdout_lines }}" - when: - - audit_format == "documentation" - -- name: Post Audit | ensure audit files readable by users - ansible.builtin.file: - path: "{{ item }}" - mode: '0644' - state: file - loop: - - "{{ post_audit_outfile }}" - - "{{ pre_audit_outfile }}" diff --git a/tasks/pre_remediation_audit.yml b/tasks/pre_remediation_audit.yml index 290170d6..e3a261e7 100644 --- a/tasks/pre_remediation_audit.yml +++ b/tasks/pre_remediation_audit.yml @@ -1,58 +1,58 @@ --- -- name: Audit Binary Setup | Setup the LE audit - ansible.builtin.include_tasks: - file: LE_audit_setup.yml +- name: Pre Audit Setup | Setup the LE audit when: - setup_audit tags: - setup_audit + ansible.builtin.include_tasks: LE_audit_setup.yml -- name: "Pre Audit Setup | Ensure {{ audit_conf_dir }} exists" +- name: Pre Audit Setup | Ensure {{ audit_conf_dir }} exists ansible.builtin.file: path: "{{ audit_conf_dir }}" state: directory mode: '0755' - name: Pre Audit Setup | If using git for content set up + when: + - audit_content == 'git' block: - name: Pre Audit Setup | Install git ansible.builtin.package: name: git state: present - when: "'git' not in ansible_facts.packages" - - name: Pre Audit Setup | retrieve audit content files from git + - name: Pre Audit Setup | Retrieve audit content files from git ansible.builtin.git: repo: "{{ audit_file_git }}" dest: "{{ audit_conf_dir }}" version: "{{ audit_git_version }}" - when: - - audit_content == 'git' -- name: Pre Audit Setup | copy to audit content files to server +- name: Pre Audit Setup | Copy to audit content files to server + when: + - audit_content == 'copy' ansible.builtin.copy: src: "{{ audit_local_copy }}" dest: "{{ audit_conf_dest }}" mode: preserve - when: - - audit_content == 'copy' -- name: Pre Audit Setup | unarchive audit content files on server +- name: Pre Audit Setup | Unarchive audit content files on server + when: + - audit_content == 'archived' ansible.builtin.unarchive: src: "{{ audit_conf_copy }}" dest: "{{ audit_conf_dir }}" - when: - - audit_content == 'archived' -- name: Pre Audit Setup | get audit content from url +- name: Pre Audit Setup | Get audit content from url + when: + - audit_content == 'get_url' ansible.builtin.get_url: url: "{{ audit_files_url }}" dest: "{{ audit_conf_dir }}" - when: - - audit_content == 'get_url' - name: Pre Audit Setup | Check Goss is available + when: + - run_audit block: - name: Pre Audit Setup | Check for goss file ansible.builtin.stat: @@ -60,34 +60,36 @@ register: goss_available - name: Pre Audit Setup | If audit ensure goss is available + when: + - not goss_available.stat.exists ansible.builtin.assert: - that: goss_available.stat.exists msg: "Audit has been selected: unable to find goss binary at {{ audit_bin }}" - when: - - run_audit - name: Pre Audit Setup | Copy ansible default vars values to test audit + tags: + - goss_template + - run_audit + when: + - run_audit ansible.builtin.template: src: ansible_vars_goss.yml.j2 dest: "{{ audit_vars_path }}" mode: '0600' - when: - - run_audit - tags: - - goss_template + +- name: Pre Audit | Run pre_remediation {{ benchmark }} audit + ansible.builtin.shell: "{{ audit_conf_dir }}/run_audit.sh -v {{ audit_vars_path }} -o {{ pre_audit_outfile }} -g \"{{ group_names }}\"" + changed_when: true + environment: + AUDIT_BIN: "{{ audit_bin }}" + AUDIT_CONTENT_LOCATION: "{{ audit_out_dir }}" + AUDIT_FILE: goss.yml - name: Pre Audit | Capture audit data if json format + when: + - audit_format == "json" block: - - name: "Pre Audit | Run pre_remediation {{ benchmark }} audit" - ansible.builtin.shell: "{{ audit_conf_dir }}/run_audit.sh -v {{ audit_vars_path }} -o {{ pre_audit_outfile }} -g {{ group_names }}" - changed_when: true - environment: - AUDIT_BIN: "{{ audit_bin }}" - AUDIT_CONTENT_LOCATION: "{{ audit_out_dir }}" - AUDIT_FILE: "goss.yml" - - - name: "capture data {{ pre_audit_outfile }}" - ansible.builtin.shell: "cat {{ pre_audit_outfile }}" + - name: capture data {{ pre_audit_outfile }} + ansible.builtin.shell: cat {{ pre_audit_outfile }} register: pre_audit changed_when: false @@ -95,28 +97,22 @@ ansible.builtin.set_fact: pre_audit_summary: "{{ pre_audit.stdout | from_json | json_query(summary) }}" vars: - summary: 'summary."summary-line"' - when: - - audit_format == "json" + summary: summary."summary-line" - name: Pre Audit | Capture audit data if documentation format + when: + - audit_format == "documentation" block: - - - name: "Pre Audit | Run pre_remediation {{ benchmark }} audit" - ansible.builtin.shell: "{{ audit_conf_dir }}/run_audit.sh -v {{ audit_vars_path }} -o {{ pre_audit_outfile }} -g {{ group_names }} -f documentation" - changed_when: true - environment: - AUDIT_BIN: "{{ audit_bin }}" - AUDIT_CONTENT_LOCATION: "{{ audit_out_dir }}" - AUDIT_FILE: "goss.yml" - - - name: "Pre Audit | capture data {{ pre_audit_outfile }} | documentation format" - ansible.builtin.shell: "tail -2 {{ pre_audit_outfile }}" + - name: Pre Audit | capture data {{ pre_audit_outfile }} | documentation format + ansible.builtin.shell: tail -2 {{ pre_audit_outfile }} register: pre_audit changed_when: false - name: Pre Audit | Capture pre-audit result | documentation format ansible.builtin.set_fact: pre_audit_summary: "{{ pre_audit.stdout_lines }}" + +- name: Audit_Only | Run Audit Only when: - - audit_format == "documentation" + - audit_only + ansible.builtin.import_tasks: audit_only.yml diff --git a/tasks/prelim.yml b/tasks/prelim.yml index 4a04d26d..9583a072 100644 --- a/tasks/prelim.yml +++ b/tasks/prelim.yml @@ -49,7 +49,7 @@ - "'dconf' not in ansible_facts.packages" - rhel8stig_gui - - name: dconf directory structure + - name: "PRELIM | dconf directory structure setup" ansible.builtin.file: path: /etc/dconf/db/local.d/locks state: directory @@ -106,7 +106,7 @@ tags: - always -- name: ensure cronie is available +- name: "PRELIM | ensure cronie is available" ansible.builtin.package: name: cronie when: @@ -139,15 +139,39 @@ - RHEL-08-010750 - RHEL-08-020320 -- name: "PRELIM | RHEL-08-010690 Ensure user enumeration command is modified when autofs remote home directories are in use" +- name: "PRELIM | AUDIT | Discover Interactive Users" + tags: + - always + ansible.builtin.shell: > + grep -E -v '^(root|halt|sync|shutdown)' /etc/passwd | awk -F: '(!index($7, "sbin/nologin") && $7 != "/bin/nologin" && $7 != "/bin/false") { print $1 }' + changed_when: false + register: discovered_interactive_usernames + +- name: "PRELIM | AUDIT | Discover Interactive User accounts home directories" + tags: + - always + ansible.builtin.shell: > + grep -E -v '^(root|halt|sync|shutdown)' /etc/passwd | awk -F: '(!index($7, "sbin/nologin") && $7 != "/bin/nologin" && $7 != "/bin/false") { print $6 }' + changed_when: false + register: discovered_interactive_users_home + +- name: "PRELIM | AUDIT | Discover Interactive user UIDs" + tags: + - always + ansible.builtin.shell: > + grep -E -v '^(root|halt|sync|shutdown)' /etc/passwd | awk -F: '(!index($7, "sbin/nologin") && $7 != "/bin/nologin" && $7 != "/bin/false") { print $3 }' + changed_when: false + register: discovered_interactive_uids + +- name: "PRELIM | RHEL-08-010690 | Ensure user enumeration command is modified when autofs remote home directories are in use" block: - - name: Ensure that rhel8stig_auto_mount_home_dirs_local_mount_point is defined and not length zero + - name: PRELIM | RHEL-08-010690 | AUDIT | Ensure that rhel8stig_auto_mount_home_dirs_local_mount_point is defined and not length zero ansible.builtin.assert: that: - rhel8stig_auto_mount_home_dirs_local_mount_point is defined - rhel8stig_auto_mount_home_dirs_local_mount_point | length > 0 - - name: Modify local_interactive_user_dir_command to exclude remote automounted home directories + - name: PRELIM | RHEL-08-010690 | PATCH | Modify local_interactive_user_dir_command to exclude remote automounted home directories ansible.builtin.set_fact: local_interactive_user_dir_command: "{{ local_interactive_user_dir_command }} | grep -v '{{ rhel8stig_auto_mount_home_dirs_local_mount_point }}" @@ -188,16 +212,16 @@ - RHEL-08-010070 - RHEL-08-030010 -- name: "PRELIM | RHEL-08-010730 | RHEL-08-20352 | Get local interactive user home directories" - ansible.builtin.shell: ls -d $(awk -F':' '($3>=1000)&&($1!="nobody"){print $6}' /etc/passwd) - changed_when: false - failed_when: false - register: local_home_directories - when: - - rhel_08_010730 or - rhel_08_020352 - tags: - - always +# - name: "PRELIM | RHEL-08-010730 | RHEL-08-20352 | Get local interactive user home directories" +# ansible.builtin.shell: ls -d $(awk -F':' '($3>=1000)&&($1!="nobody"){print $6}' /etc/passwd) +# changed_when: false +# failed_when: false +# register: local_home_directories +# when: +# - rhel_08_010730 or +# rhel_08_020352 +# tags: +# - always - name: "PRELIM | RHEL-08-030620 | RHEL-08-030630 | RHEL-08-030640 | RHEL-08-030650 | Install audit remote plugin." ansible.builtin.package: @@ -274,12 +298,12 @@ state: "{{ rhel8stig_service_started }}" enabled: true - - name: PRELIM | check if ssh host key exists + - name: PRELIM | Check if ssh host key exists ansible.builtin.stat: path: /etc/ssh/ssh_host_rsa_key register: rhel8stig_ssh_host_rsa_key_stat - - name: PRELIM | create ssh host key to allow 'sshd -t -f %s' to succeed + - name: PRELIM | Create ssh host key to allow 'sshd -t -f %s' to succeed ansible.builtin.shell: ssh-keygen -N '' -f /etc/ssh/ssh_host_rsa_key -t rsa -b 4096 when: not rhel8stig_ssh_host_rsa_key_stat.stat.exists notify: clean up ssh host key @@ -302,7 +326,7 @@ - RHEL-08-010770 - complexity-high -- name: "MEDIUM | RHEL-08-010660 | RHEL-08-010770 | Set fact for home directory paths for interactive users" +- name: "PRELIM | RHEL-08-010660 | RHEL-08-010770 | Set fact for home directory paths for interactive users" ansible.builtin.set_fact: rhel_08_stig_interactive_homedir_inifiles: "{{ rhel_08_010770_ini_file_list.results | map(attribute='stdout_lines') | list }}" when: @@ -357,7 +381,7 @@ tags: - always -- name: Gather the package facts +- name: "PRELIM | Gather the package facts" ansible.builtin.package_facts: manager: auto tags: diff --git a/templates/ansible_vars_goss.yml.j2 b/templates/ansible_vars_goss.yml.j2 index 69484221..d9af9eae 100644 --- a/templates/ansible_vars_goss.yml.j2 +++ b/templates/ansible_vars_goss.yml.j2 @@ -1,6 +1,6 @@ ## metadata for Audit benchmark -benchmark_version: '1.11' +benchmark_version: {{ benchmark_version }} rhel8stig_os_distribution: {{ ansible_distribution | lower }} @@ -443,13 +443,13 @@ MAX_UID: {{ rhel8stig_interactive_uid_stop }} # RHEL_08_010040-010050-010060 rhel8stig_banner_file: /etc/issue rhel8stig_logon_banner: -- You are accessing a U.S. Government (USG) Information System (IS) that is provided for USG-authorized use only. -- By using this IS (which includes any device attached to this IS), you consent to the following conditions -- -The USG routinely intercepts and monitors communications on this IS for purposes including, but not limited to, penetration testing, COMSEC monitoring, network operations and defense, personnel misconduct (PM), law enforcement (LE), and counterintelligence (CI) investigations. -- -At any time, the USG may inspect and seize data stored on this IS. -- -Communications using, or data stored on, this IS are not private, are subject to routine monitoring, interception, and search, and may be disclosed or used for any USG-authorized purpose. -- -This IS includes security measures (e.g., authentication and access controls) to protect USG interests--not for your personal benefit or privacy. -- -Notwithstanding the above, using this IS does not constitute consent to PM, LE or CI investigative searching or monitoring of the content of privileged communications, or work product, related to personal representation or services by attorneys, psychotherapists, or clergy, and their assistants. Such communications and work product are private and confidential. See User Agreement for details. + You are accessing a U.S. Government (USG) Information System (IS) that is provided for USG-authorized use only. + By using this IS (which includes any device attached to this IS), you consent to the following conditions + -The USG routinely intercepts and monitors communications on this IS for purposes including, but not limited to, penetration testing, COMSEC monitoring, network operations and defense, personnel misconduct (PM), law enforcement (LE), and counterintelligence (CI) investigations. + -At any time, the USG may inspect and seize data stored on this IS. + -Communications using, or data stored on, this IS are not private, are subject to routine monitoring, interception, and search, and may be disclosed or used for any USG-authorized purpose. + -This IS includes security measures (e.g., authentication and access controls) to protect USG interests--not for your personal benefit or privacy. + -Notwithstanding the above, using this IS does not constitute consent to PM, LE or CI investigative searching or monitoring of the content of privileged communications, or work product, related to personal representation or services by attorneys, psychotherapists, or clergy, and their assistants. Such communications and work product are private and confidential. See User Agreement for details. # RHEL_08_010680 to change if using hostfile only - seperate checks rhel8stig_uses_dns: true @@ -479,6 +479,3 @@ rhel8stig_remotelog_protocol: '{{ rhel8stig_remotelog_server.protocol }}' # RHEL_08_040137 python_bin: {{ ansible_python.executable }} - -# RHEL_08_040260-62 -rhel8stig_system_is_router: {{ rhel8stig_system_is_router }} diff --git a/templates/pam_pkcs11.conf.j2 b/templates/pam_pkcs11.conf.j2 deleted file mode 100644 index 32c441b5..00000000 --- a/templates/pam_pkcs11.conf.j2 +++ /dev/null @@ -1,249 +0,0 @@ -# -# Configuration file for pam_pkcs11 module -# -# Version 0.4 -# Author: Juan Antonio Martinez -# -pam_pkcs11 { - # Allow empty passwords - nullok = true; - - # Enable debugging support. - debug = false; - - # If the smart card is inserted, only use it - card_only = true; - - # Do not prompt the user for the passwords but take them from the - # PAM_ items instead. - use_first_pass = false; - - # Do not prompt the user for the passwords unless PAM_(OLD)AUTHTOK - # is unset. - try_first_pass = false; - - # Like try_first_pass, but fail if the new PAM_AUTHTOK has not been - # previously set (intended for stacking password modules only). - use_authtok = false; - - # Filename of the PKCS #11 module. The default value is "default" - use_pkcs11_module = {{ rhel08stig_smartcarddriver }}; - - screen_savers = gnome-screensaver,xscreensaver,kscreensaver - - pkcs11_module {{ rhel08stig_smartcarddriver }} { - {% if rhel08stig_smartcarddriver == 'cackey' %}module = /usr/lib64/libcackey.so;{% elif rhel08stig_smartcarddriver == 'coolkey' %}module = libcoolkeypk11.so;{% endif %} - module = /usr/lib64/libcackey.so; - description = "{{ rhel08stig_smartcarddriver }}"; - slot_num = 0; - support_threads = false; - ca_dir = /etc/pam_pkcs11/cacerts; - crl_dir = /etc/pam_pkcs11/crls; - cert_policy = signature; - } - - pkcs11_module opensc { - module = opensc-pkcs11.so; - description = "OpenSC PKCS#11 module"; - # Slot-number to use. One for the first, two for the second and so - # on. The default value is zero which means to use the first slot - # with an available token. - slot_num = 0; - - # Path to the directory where the NSS CA certificate database is stored. - # you can mange the certs in this database with the certutil command in - # the package nss-tools - nss_dir = /etc/pki/nssdb; - - # Sets the Certificate Policy, (see above) - cert_policy = ca, signature; - } - - # Default pkcs11 module - pkcs11_module default { - module = /usr/$LIB/pam_pkcs11/pkcs11_module.so; - description = "Default pkcs#11 module"; - slot_num = 0; - #ca_dir = /etc/pam_pkcs11/cacerts; - #crl_dir = /etc/pam_pkcs11/crls; - nss_dir = /etc/pki/nssdb; - cert_policy = ca, signature; - } - - # Which mappers ( Cert to login ) to use? - # you can use several mappers: - # - # subject - Cert Subject to login file based mapper - # pwent - CN to getpwent() login or gecos fields mapper - # ldap - LDAP mapper - # opensc - Search certificate in ${HOME}/.eid/authorized_certificates - # openssh - Search certificate public key in ${HOME}/.ssh/authorized_keys - # mail - Compare email fields from certificate - # ms - Use Microsoft Universal Principal Name extension - # krb - Compare againts Kerberos Principal Name - # cn - Compare Common Name (CN) - # uid - Compare Unique Identifier - # digest - Certificate digest to login (mapfile based) mapper - # generic - User defined certificate contents mapped - # null - blind access/deny mapper - # - # You can select a comma-separated mapper list. - # If used null mapper should be the last in the list :-) - # Also you should select at least one mapper, otherwise - # certificate will not match :-) - use_mappers = cn, uid, pwent, null; - - # When no absolute path or module info is provided, use this - # value as module search path - # TODO: - # This is not still functional: use absolute pathnames or LD_LIBRARY_PATH - mapper_search_path = /usr/$LIB/pam_pkcs11; - - # - # Generic certificate contents mapper - mapper generic { - debug = true; - module = /usr/$LIB/pam_pkcs11/generic_mapper.so; - # ignore letter case on match/compare - ignorecase = false; - # Use one of "cn" , "subject" , "kpn" , "email" , "upn" or "uid" - cert_item = cn; - # Define mapfile if needed, else select "none" - mapfile = file:///etc/pam_pkcs11/generic_mapping - # Decide if use getpwent() to map login - use_getpwent = false; - } - - # Certificate Subject to login based mapper - # provided file stores one or more "Subject -> login" lines - mapper subject { - debug = false; - # module = /usr/$LIB/pam_pkcs11/subject_mapper.so; - module = internal; - ignorecase = false; - mapfile = file:///etc/pam_pkcs11/subject_mapping; - } - - # Search public keys from $HOME/.ssh/authorized_keys to match users - mapper openssh { - debug = false; - module = /usr/$LIB/pam_pkcs11/openssh_mapper.so; - } - - # Search certificates from $HOME/.eid/authorized_certificates to match users - mapper opensc { - debug = false; - module = /usr/$LIB/pam_pkcs11/opensc_mapper.so; - } - - # Certificate Common Name ( CN ) to getpwent() mapper - mapper pwent { - debug = false; - ignorecase = false; - module = internal; - # module = /usr/$LIB/pam_pkcs11/pwent_mapper.so; - } - - # Null ( no map ) mapper. when user as finder matchs to NULL or "nobody" - mapper null { - debug = false; - # module = /usr/$LIB/pam_pkcs11/null_mapper.so; - module = internal ; - # select behavior: always match, or always fail - default_match = false; - # on match, select returned user - default_user = nobody ; - } - - # Directory ( ldap style ) mapper - mapper ldap { - debug = false; - module = /usr/$LIB/pam_pkcs11/ldap_mapper.so; - # where base directory resides - basedir = /etc/pam_pkcs11/mapdir; - # hostname of ldap server - ldaphost = "localhost"; - # Port on ldap server to connect - ldapport = 389; - # Scope of search: 0 = x, 1 = y, 2 = z - scope = 2; - # DN to bind with. Must have read-access for user entries under "base" - binddn = "cn=pam,o=example,c=com"; - # Password for above DN - passwd = "test"; - # Searchbase for user entries - base = "ou=People,o=example,c=com"; - # Attribute of user entry which contains the certificate - attribute = "userCertificate"; - # Searchfilter for user entry. Must only let pass user entry for the login user. - filter = "(&(objectClass=posixAccount)(uid=%s))" - } - - # Assume common name (CN) to be the login - mapper cn { - debug = false; - module = internal; - # module = /usr/$LIB/pam_pkcs11/cn_mapper.so; - ignorecase = true; - mapfile = file:///etc/pam_pkcs11/cn_map; - } - - # mail - Compare email field from certificate - mapper mail { - debug = false; - module = internal; - # module = /usr/$LIB/pam_pkcs11/mail_mapper.so; - # Declare mapfile or - # leave empty "" or "none" to use no map - mapfile = file:///etc/pam_pkcs11/mail_mapping; - # Some certs store email in uppercase. take care on this - ignorecase = true; - # Also check that host matches mx domain - # when using mapfile this feature is ignored - ignoredomain = false; - } - - # ms - Use Microsoft Universal Principal Name extension - # UPN is in format login@ADS_Domain. No map is needed, just - # check domain name. - mapper ms { - debug = false; - module = internal; - # module = /usr/$LIB/pam_pkcs11/ms_mapper.so; - ignorecase = false; - ignoredomain = false; - domain = "domain.com"; - } - - # krb - Compare againts Kerberos Principal Name - mapper krb { - debug = false; - module = internal; - # module = /usr/$LIB/pam_pkcs11/krb_mapper.so; - ignorecase = false; - mapfile = "none"; - } - - # uid - Maps Subject Unique Identifier field (if exist) to login - mapper uid { - debug = false; - module = internal; - # module = /usr/$LIB/pam_pkcs11/uid_mapper.so; - ignorecase = false; - mapfile = "none"; - } - - # digest - elaborate certificate digest and map it into a file - mapper digest { - debug = false; - module = internal; - # module = /usr/$LIB/pam_pkcs11/digest_mapper.so; - # algorithm used to evaluate certificate digest - # Select one of: - # "null","md2","md4","md5","sha","sha1","dss","dss1","ripemd160" - algorithm = "sha1"; - mapfile = file:///etc/pam_pkcs11/digest_mapping; - # mapfile = "none"; - } - -} diff --git a/vars/audit.yml b/vars/audit.yml new file mode 100644 index 00000000..89e61a84 --- /dev/null +++ b/vars/audit.yml @@ -0,0 +1,41 @@ +--- + +#### Audit Configuration Settings #### + +# Timeout for those cmds that take longer to run where timeout set +audit_cmd_timeout: 120000 + +# if get_audit_binary_method == download change accordingly +audit_bin_url: "https://github.com/goss-org/goss/releases/download/{{ audit_bin_version.release }}/goss-linux-" + +### Goss Audit Benchmark file ### +## managed by the control audit_content +# git +audit_file_git: "https://github.com/ansible-lockdown/{{ benchmark }}-Audit.git" +audit_git_version: "benchmark_{{ benchmark_version }}_rh8" + +## Goss configuration information +# Where the goss configs and outputs are stored +audit_out_dir: '/opt' +# Where the goss audit configuration will be stored +audit_conf_dir: "{{ audit_out_dir }}/{{ benchmark }}-Audit" + +# If changed these can affect other products +pre_audit_outfile: "{{ audit_out_dir }}/{{ ansible_facts.hostname }}-{{ benchmark }}-{{ benchmark_version }}_pre_scan_{{ ansible_facts.date_time.epoch }}.{{ audit_format }}" +post_audit_outfile: "{{ audit_out_dir }}/{{ ansible_facts.hostname }}-{{ benchmark }}-{{ benchmark_version }}_post_scan_{{ ansible_facts.date_time.epoch }}.{{ audit_format }}" + +## The following should not need changing + +### Audit binary settings ### +audit_bin_version: + release: v0.4.4 + AMD64_checksum: 'sha256:1c4f54b22fde9d4d5687939abc2606b0660a5d14a98afcd09b04b793d69acdc5' +audit_bin_path: /usr/local/bin/ +audit_bin: "{{ audit_bin_path }}goss" +audit_format: json + +audit_vars_path: "{{ audit_conf_dir }}/vars/{{ ansible_facts.hostname }}.yml" +audit_results: | + The pre remediation results are: {{ pre_audit_summary }}. + The post remediation results are: {{ post_audit_summary }}. + Full breakdown can be found in {{ audit_out_dir }}