diff --git a/.config/.secrets.baseline b/.config/.secrets.baseline deleted file mode 100644 index 65908eb9..00000000 --- a/.config/.secrets.baseline +++ /dev/null @@ -1,119 +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_password.yml" - ] - } - ], - "results": {}, - "generated_at": "2023-09-25T16:05:28Z" -} diff --git a/.github/workflows/devel_pipeline_validation.yml b/.github/workflows/devel_pipeline_validation.yml index e02fe1f0..9a80bdc1 100644 --- a/.github/workflows/devel_pipeline_validation.yml +++ b/.github/workflows/devel_pipeline_validation.yml @@ -27,7 +27,7 @@ jobs: # This will create messages for first time contributers and direct them to the Discord server welcome: - runs-on: self-hosted + runs-on: ubuntu-latest steps: - uses: actions/first-interaction@main @@ -55,7 +55,7 @@ steps: - - name: Git clone the lockdown repository to test + - name: Git Clone the Lockdown Repository to test uses: actions/checkout@v4 with: ref: ${{ github.event.pull_request.head.sha }} @@ -81,7 +81,7 @@ # Uses dedicated restricted role and policy to enable this only for this task # No credentials are part of github for AWS auth - - name: configure aws credentials + - name: Configure AWS Credentials uses: aws-actions/configure-aws-credentials@main with: role-to-assume: ${{ secrets.AWS_ASSUME_ROLE }} @@ -104,7 +104,7 @@ PRIVSUBNET_ID: ${{ secrets.AWS_PRIVSUBNET_ID }} VPC_ID: ${{ secrets.AWS_VPC_SECGRP_ID }} - - name: Tofu init + - name: Tofu Init id: init run: tofu init env: @@ -112,7 +112,7 @@ OSVAR: ${{ vars.OSVAR }} TF_VAR_benchmark_type: ${{ vars.BENCHMARK_TYPE }} - - name: Tofu validate + - name: Tofu Validate id: validate run: tofu validate env: @@ -120,7 +120,7 @@ OSVAR: ${{ vars.OSVAR }} TF_VAR_benchmark_type: ${{ vars.BENCHMARK_TYPE }} - - name: Tofu apply + - name: Tofu Apply id: apply env: OSVAR: ${{ vars.OSVAR }} @@ -136,11 +136,11 @@ # Aws deployments taking a while to come up insert sleep or playbook fails - - name: Sleep to allow system to come up + - name: Sleep - Allow system to come up run: sleep ${{ vars.BUILD_SLEEPTIME }} # Run the Ansible playbook - - name: Run_Ansible_Playbook + - name: Run Ansible Playbook env: ANSIBLE_HOST_KEY_CHECKING: "false" ANSIBLE_DEPRECATION_WARNINGS: "false" diff --git a/.github/workflows/main_pipeline_validation.yml b/.github/workflows/main_pipeline_validation.yml index 4a5adc9c..9d7ea079 100644 --- a/.github/workflows/main_pipeline_validation.yml +++ b/.github/workflows/main_pipeline_validation.yml @@ -23,18 +23,6 @@ # A workflow run is made up of one or more jobs # that can run sequentially or in parallel jobs: - # This will create messages for first time contributers and direct them to the Discord server - welcome: - runs-on: self-hosted - - steps: - - uses: actions/first-interaction@main - with: - repo-token: ${{ secrets.GITHUB_TOKEN }} - pr-message: |- - Congrats on opening your first pull request and thank you for taking the time to help improve Ansible-Lockdown! - Please join in the conversation happening on the [Discord Server](https://www.lockdownenterprise.com/discord) as well. - # This workflow contains a single job that tests the playbook playbook-test: # The type of runner that the job will run on @@ -53,7 +41,7 @@ steps: - - name: Git clone the lockdown repository to test + - name: Git Clone the Lockdown Repository to test uses: actions/checkout@v4 with: ref: ${{ github.event.pull_request.head.sha }} @@ -78,7 +66,7 @@ # Uses dedicated restricted role and policy to enable this only for this task # No credentials are part of github for AWS auth - - name: configure aws credentials + - name: Configure AWS Credentials uses: aws-actions/configure-aws-credentials@main with: role-to-assume: ${{ secrets.AWS_ASSUME_ROLE }} @@ -101,7 +89,7 @@ PRIVSUBNET_ID: ${{ secrets.AWS_PRIVSUBNET_ID }} VPC_ID: ${{ secrets.AWS_VPC_SECGRP_ID }} - - name: Tofu init + - name: Tofu Init id: init run: tofu init env: @@ -109,7 +97,7 @@ OSVAR: ${{ vars.OSVAR }} TF_VAR_benchmark_type: ${{ vars.BENCHMARK_TYPE }} - - name: Tofu validate + - name: Tofu Validate id: validate run: tofu validate env: @@ -117,7 +105,7 @@ OSVAR: ${{ vars.OSVAR }} TF_VAR_benchmark_type: ${{ vars.BENCHMARK_TYPE }} - - name: Tofu apply + - name: Tofu Apply id: apply env: OSVAR: ${{ vars.OSVAR }} @@ -133,11 +121,11 @@ # Aws deployments taking a while to come up insert sleep or playbook fails - - name: Sleep to allow system to come up + - name: Sleep - Allow system to come up run: sleep ${{ vars.BUILD_SLEEPTIME }} # Run the Ansible playbook - - name: Run_Ansible_Playbook + - name: Run Ansible Playbook env: ANSIBLE_HOST_KEY_CHECKING: "false" ANSIBLE_DEPRECATION_WARNINGS: "false" diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 1e9eee39..e890b356 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.6.0 + rev: v5.0.0 hooks: # Safety - id: detect-aws-credentials @@ -33,18 +33,14 @@ repos: rev: v1.5.0 hooks: - id: detect-secrets - args: ['--baseline', '.config/.secrets.baseline'] - exclude: package.lock.json - repo: https://github.com/gitleaks/gitleaks - rev: v8.18.4 + rev: v8.20.1 hooks: - id: gitleaks - args: ['--baseline-path', '.config/.gitleaks-report.json'] - exclude: .config/.secrets.baseline - repo: https://github.com/ansible-community/ansible-lint - rev: v24.6.0 + rev: v24.9.2 hooks: - id: ansible-lint name: Ansible-lint diff --git a/Changelog.md b/Changelog.md index b1e5a0c9..e089b3d4 100644 --- a/Changelog.md +++ b/Changelog.md @@ -1,5 +1,16 @@ # Changes to rhel8CIS +## Benchmark v3.0.0 + +### 2.1 updates August 2024 + +new workflow +audit updates +authselect rewrite +thanks to @msachikanta, @fgierlinger, @bantify, @txdavec, @csabapatyi @dirkvdplas, @karlg100 and @devallan for issues and fixes +now able to run audit on ARM64 although not officially supported by CIS feedback needed +audit binary update to 0.4.8 + ## 2.0 based on CIS 3.0.0 ### This is not an upgrade for CIS v2.0.0 due to the number of changes treat as a new baseline diff --git a/defaults/main.yml b/defaults/main.yml index fc91ae17..66d8ba6c 100644 --- a/defaults/main.yml +++ b/defaults/main.yml @@ -37,6 +37,9 @@ benchmark_version: v3.0.0 # Whether to skip the reboot skip_reboot: true +# Modify behavior of changed_when if reboot is pending and skipped to allow idempotency to succeed +reboot_warning_changed_when: true + ### ### Settings for associated Audit role using Goss ### @@ -560,7 +563,7 @@ rhel8cis_ntp_server_options: "iburst" # mask - if a dependancy for product so cannot be removed # Server Services rhel8cis_autofs_services: false -rhel8cis_autofs_mask: true +rhel8cis_autofs_mask: false rhel8cis_avahi_server: false rhel8cis_avahi_mask: false rhel8cis_dhcp_server: false @@ -683,21 +686,34 @@ rhel8cis_sudolog_location: "/var/log/sudo.log" rhel8cis_sudo_timestamp_timeout: 15 ## PAM -# 4.4.2.x +## 4.4.2.x PAM and Authselect # Do not use authselect if: # Your host is part of Linux Identity Management. # Joining your host to an IdM domain with the ipa-client-install command automatically configures SSSD authentication on your host. # Your host is part of Active Directory via SSSD. # Calling the realm join command to join your host to an Active Directory domain automatically configures SSSD authentication on your host. -rhel8cis_allow_authselect_updates: false +rhel8cis_allow_authselect_updates: true ## rhel8cis_authselect_pkg_update: false # NOTE the risks if system is using SSSD or using ipa-client-install -rhel8cis_authselect_custom_profile_create: false -rhel8cis_authselect_custom_profile_select: false -rhel8cis_authselect: - custom_profile_name: 'cis_example_profile' - default_file_to_copy: "sssd --symlink-meta" - options: with-sudo with-faillock without-nullok with-pwhistory + +## PAM AND Authselect + +# To create a new profile (best for greenfield fresh sites not configured) +# This allows creation of a custom profile using an existing one to build from +# will only create if profiel does not already exist +## options true or false +rhel8cis_authselect_custom_profile_create: true +## Controls: +# - 4.4.2.1 - Ensure custom authselect profile is used +# Settings in place now will fail, they are placeholders from the control example. Due to the way many multiple +# options and ways to configure this control needs to be enabled and settings adjusted to minimise risk. + +# This variable configures the name of the custom profile to be created and selected. +# To be changed from default - cis_example_profile +rhel8cis_authselect_custom_profile_name: cis_example_profile +# Name of the existing authselect profile to copy - options can be found with +# ```authselect list``` on the host to be configured +rhel8cis_authselect_default_profile_to_copy: "sssd --symlink-meta" rhel8cis_pam_faillock: attempts: 5 @@ -784,7 +800,7 @@ rhel8cis_auditd: disk_full_action: halt action_mail_acct: root space_left_action: email - admin_space_left_action: email + admin_space_left_action: single max_log_file_action: keep_logs # This can be used to configure other keys in auditd.conf diff --git a/tasks/LE_audit_setup.yml b/tasks/LE_audit_setup.yml index 70674142..1b5ba8a9 100644 --- a/tasks/LE_audit_setup.yml +++ b/tasks/LE_audit_setup.yml @@ -8,7 +8,7 @@ audit_pkg_arch_name: AMD64 - name: Pre Audit Setup | Set audit package name | ARM64 - when: ansible_facts.machine == "arm64" + when: ansible_facts.machine == "aarch64" ansible.builtin.set_fact: audit_pkg_arch_name: ARM64 diff --git a/tasks/main.yml b/tasks/main.yml index c47d8485..92aa293d 100644 --- a/tasks/main.yml +++ b/tasks/main.yml @@ -108,6 +108,29 @@ vars: sudo_password_rule: rhel8cis_rule_4_3_4 # pragma: allowlist secret +- name: "PRELIM | AUDIT | Check authselect profile is selected" + when: + - rhel8cis_allow_authselect_updates + tags: + - always + block: + - name: "PRELIM | AUDIT | Check authselect profile name has been updated" + ansible.builtin.assert: + that: rhel8cis_authselect_custom_profile_name != 'cis_example_profile' + fail_msg: "You still have the default name for your authselect profile" + + - name: "PRELIM | AUDIT | Check authselect profile is selected" + ansible.builtin.shell: authselect current | head -1 | awk '{print $NF}' + changed_when: false + failed_when: prelim_authselect_current_profile.rc not in [ 0, 1 ] + register: prelim_authselect_current_profile + + - name: "PRELIM | AUDIT | Check authselect profile is selected" + ansible.builtin.assert: + that: prelim_authselect_current_profile is defined + success_msg: "Authselect is running and profile is selected" + fail_msg: Authselect updates have been selected there are issues with profile selection" + - name: Include prelim tasks tags: - prelim_tasks @@ -139,48 +162,36 @@ - name: Run Section 1 tasks when: - rhel8cis_section1 - tags: - - rhel8cis_section1 ansible.builtin.import_tasks: file: section_1/main.yml - name: Run Section 2 tasks when: - rhel8cis_section2 - tags: - - rhel8cis_section2 ansible.builtin.import_tasks: file: section_2/main.yml - name: Run Section 3 tasks when: - rhel8cis_section3 - tags: - - rhel8cis_section3 ansible.builtin.import_tasks: file: section_3/main.yml - name: Run Section 4 tasks when: - rhel8cis_section4 - tags: - - rhel8cis_section4 ansible.builtin.import_tasks: file: section_4/main.yml - name: run Section 5 tasks when: - rhel8cis_section5 - tags: - - rhel8cis_section5 ansible.builtin.import_tasks: file: section_5/main.yml - name: Run Section 6 tasks when: - rhel8cis_section6 - tags: - - rhel8cis_section6 ansible.builtin.import_tasks: file: section_6/main.yml diff --git a/tasks/post.yml b/tasks/post.yml index d981fcf8..88618abd 100644 --- a/tasks/post.yml +++ b/tasks/post.yml @@ -23,7 +23,7 @@ - skip_reboot ansible.builtin.debug: msg: "Warning!! changes have been made that require a reboot to be implemented but skip reboot was set - Can affect compliance check results" - changed_when: true + changed_when: reboot_warning_changed_when - name: "POST | Warning a reboot required but skip option set | warning count" when: diff --git a/tasks/post_remediation_audit.yml b/tasks/post_remediation_audit.yml index 19dff268..b3c18234 100644 --- a/tasks/post_remediation_audit.yml +++ b/tasks/post_remediation_audit.yml @@ -21,26 +21,24 @@ when: - audit_format == "json" block: - - name: Post Audit | Capture data {{ post_audit_outfile }} - ansible.builtin.shell: "cat {{ post_audit_outfile }}" - register: discovered_post_audit + - name: Post Audit | Capture audit data if json format + ansible.builtin.shell: grep -E '"summary-line.*Count:.*Failed' "{{ post_audit_outfile }}" | cut -d'"' -f4 + register: post_audit_summary changed_when: false - - name: Post Audit | Capture post-audit result + - name: Post Audit | Set Fact for audit summary ansible.builtin.set_fact: - post_audit_summary: "{{ discovered_post_audit.stdout | from_json | json_query(summary) }}" - vars: - summary: summary."summary-line" + post_audit_results: "{{ post_audit_summary.stdout }}" - name: Post Audit | Capture audit data if documentation format when: - audit_format == "documentation" block: - - name: Post Audit | Capture data {{ post_audit_outfile }} + - name: Post Audit | Capture audit data if documentation format ansible.builtin.shell: "tail -2 {{ post_audit_outfile }}" - register: discovered_post_audit + register: post_audit_summary changed_when: false - - name: Post Audit | Capture post-audit result + - name: Post Audit | Set Fact for audit summary ansible.builtin.set_fact: - post_audit_summary: "{{ discovered_post_audit.stdout_lines }}" + post_audit_results: "{{ post_audit_summary.stdout }}" diff --git a/tasks/pre_remediation_audit.yml b/tasks/pre_remediation_audit.yml index fb6d709f..acba130f 100644 --- a/tasks/pre_remediation_audit.yml +++ b/tasks/pre_remediation_audit.yml @@ -90,29 +90,27 @@ when: - audit_format == "json" block: - - name: Pre Audit | Capture data {{ pre_audit_outfile }} - ansible.builtin.shell: "cat {{ pre_audit_outfile }}" - register: discovered_pre_audit + - name: Pre Audit | Capture audit data if json format + ansible.builtin.shell: grep -E '\"summary-line.*Count:.*Failed' "{{ pre_audit_outfile }}" | cut -d'"' -f4 + register: pre_audit_summary changed_when: false - - name: Pre Audit | Capture pre-audit result + - name: Pre Audit | Set Fact for audit summary ansible.builtin.set_fact: - pre_audit_summary: "{{ discovered_pre_audit.stdout | from_json | json_query(summary) }}" - vars: - summary: summary."summary-line" + pre_audit_results: "{{ pre_audit_summary.stdout }}" - name: Pre Audit | Capture audit data if documentation format when: - audit_format == "documentation" block: - - name: Pre Audit | Capture data {{ pre_audit_outfile }} | documentation format - ansible.builtin.shell: "tail -2 {{ pre_audit_outfile }}" - register: discovered_pre_audit + - name: Pre Audit | Capture audit data if documentation format + ansible.builtin.shell: tail -2 "{{ pre_audit_outfile }}" | tac | tr '\n' ' ' + register: pre_audit_summary changed_when: false - - name: Pre Audit | Capture pre-audit result | documentation format + - name: Pre Audit | Set Fact for audit summary ansible.builtin.set_fact: - pre_audit_summary: "{{ discovered_pre_audit.stdout_lines }}" + pre_audit_results: "{{ pre_audit_summary.stdout }}" - name: Audit_Only | Run Audit Only when: diff --git a/tasks/prelim.yml b/tasks/prelim.yml index d35cf848..df3b5e64 100644 --- a/tasks/prelim.yml +++ b/tasks/prelim.yml @@ -228,50 +228,6 @@ ansible.builtin.import_tasks: file: warning_facts.yml -- name: "PRELIM | AUDIT | Check authselect profile is selected" - when: - - rhel8cis_allow_authselect_updates - - rhel8cis_rule_4_4_2_1 or - rhel8cis_rule_4_4_2_2 or - rhel8cis_rule_4_4_2_3 or - rhel8cis_rule_4_4_2_4 or - rhel8cis_rule_4_4_2_5 or - rhel8cis_rule_4_4_3_1_1 or - rhel8cis_rule_4_4_3_1_2 or - rhel8cis_rule_4_4_3_1_3 - tags: - - always - block: - - name: "PRELIM | AUDIT | Check authselect profile name has been updated" - ansible.builtin.assert: - that: rhel8cis_authselect['custom_profile_name'] != 'cis_example_profile' - fail_msg: "You still have the default name for your authselect profile" - - - name: "PRELIM | AUDIT | Check authselect profile is selected" - when: not rhel8cis_authselect_custom_profile_create - ansible.builtin.shell: authselect current - changed_when: false - failed_when: discovered_authselect_running_config.rc not in [ 0, 1 ] - register: discovered_authselect_running_config - - - name: "PRELIM | AUDIT | Check authselect profile is selected" - ansible.builtin.assert: - that: not rhel8cis_authselect_custom_profile_create and "'example' not in rhel8cis_authselect['custom_profile_name']" or discovered_authselect_running_config is defined - success_msg: "Authselect is running and profile is selected" - fail_msg: Authselect updates have been selected there are issues with profile selection" - - - name: "PRELIM | AUDIT | Check profile exists if not created" - ansible.builtin.stat: - path: "/etc/authselect/custom/{{ rhel8cis_authselect['custom_profile_name'] }}" - register: discovered_authselect_profile - - - name: "PRELIM | AUDIT | Check authselect profile exists if not created" - when: discovered_authselect_profile.stat.exists - ansible.builtin.assert: - that: not rhel8cis_authselect_custom_profile_create - success_msg: "Authselect is running and profile is selected" - fail_msg: Authselect updates have been selected but you have stated create and profile already exists" - - name: "PRELIM | AUDIT | Interactive User accounts home directories" tags: - always @@ -332,10 +288,11 @@ - name: "PRELIM | AUDIT | Gather UID 0 accounts other than root" when: - - rhel8cis_rule_6_2_8 + - rhel8cis_rule_6_2_9 tags: - always - ansible.builtin.shell: "cat /etc/passwd | awk -F: '($3 == 0 && $1 != \"root\") {i++;print $1 } END {exit i}'" + ansible.builtin.shell: "cat /etc/passwd | awk -F: '($3 == 0 && $1 != \"root\") {i++;print $1 } END {exit 1}'" + failed_when: discovered_uid_zero_accounts_except_root.rc not in [ 0, 1 ] changed_when: false check_mode: false register: discovered_uid_zero_accounts_except_root diff --git a/tasks/section_1/cis_1.6.x.yml b/tasks/section_1/cis_1.6.x.yml index 41712b29..4e619c49 100644 --- a/tasks/section_1/cis_1.6.x.yml +++ b/tasks/section_1/cis_1.6.x.yml @@ -18,7 +18,7 @@ - name: "1.6.1 | PATCH | Ensure system-wide crypto policy is not legacy" when: - - discovered_system_wide_crypto_policy.stdout not in rhel8cis_crypto_policy + - rhel8cis_full_crypto_policy not in discovered_system_wide_crypto_policy.stdout ansible.builtin.shell: | update-crypto-policies --set "{{ rhel8cis_full_crypto_policy }}" update-crypto-policies diff --git a/tasks/section_1/cis_1.7.x.yml b/tasks/section_1/cis_1.7.x.yml index 9c240b4e..21714e09 100644 --- a/tasks/section_1/cis_1.7.x.yml +++ b/tasks/section_1/cis_1.7.x.yml @@ -18,7 +18,7 @@ dest: /etc/motd owner: root group: root - mode: go-rx + mode: 'go-rx' - name: "1.7.2 | PATCH | Ensure local login warning banner is configured properly" when: @@ -37,7 +37,7 @@ dest: /etc/issue owner: root group: root - mode: go-rx + mode: 'go-rx' - name: "1.7.3 | PATCH | Ensure remote login warning banner is configured properly" when: @@ -57,7 +57,7 @@ dest: /etc/issue.net owner: root group: root - mode: go-wx + mode: 'go-wx' - name: "1.7.4 | PATCH | Ensure access to /etc/motd is configured" when: @@ -76,7 +76,7 @@ state: file owner: root group: root - mode: go-wx + mode: 'go-wx' - name: "1.7.5 | PATCH | Ensure access to /etc/issue is configured" when: @@ -95,7 +95,7 @@ state: file owner: root group: root - mode: go-wx + mode: 'go-wx' - name: "1.7.6 | PATCH | Ensure access to /etc/issue.net is configured" when: @@ -114,4 +114,4 @@ state: file owner: root group: root - mode: go-wx + mode: 'go-wx' diff --git a/tasks/section_2/cis_2.2.x.yml b/tasks/section_2/cis_2.2.x.yml index 7d559a1f..208f5268 100644 --- a/tasks/section_2/cis_2.2.x.yml +++ b/tasks/section_2/cis_2.2.x.yml @@ -393,7 +393,7 @@ - not rhel8cis_rpc_server - not rhel8cis_rpc_mask ansible.builtin.package: - name: cups + name: rpcbind state: absent - name: "2.2.12 | PATCH | Ensure rpcbind services are not in use | Mask service" @@ -464,7 +464,7 @@ - not rhel8cis_net_snmp_server - not rhel8cis_net_snmp_mask ansible.builtin.package: - name: rsync-daemon + name: net-snmp state: absent - name: "2.2.14 | PATCH | Ensure snmp services are not in use | Mask service" @@ -549,7 +549,7 @@ - name: "2.2.17 | PATCH | Ensure web proxy server services are not in use" when: - "'squid' in ansible_facts.packages" - - rhel8cis_rule_2_217 + - rhel8cis_rule_2_2_17 tags: - level1-server - level1-workstation @@ -565,7 +565,7 @@ - not rhel8cis_squid_server - not rhel8cis_squid_mask ansible.builtin.package: - name: tftp-server + name: squid state: absent - name: "2.2.17 | PATCH | Ensure web proxy server services are not in use | Mask service" @@ -653,7 +653,7 @@ - not rhel8cis_xinetd_server - not rhel8cis_xinetd_mask ansible.builtin.package: - name: tftp-server + name: xinetd state: absent - name: "2.2.19 | PATCH | Ensure xinetd services are not in use | Mask service" diff --git a/tasks/section_4/cis_4.1.1.x.yml b/tasks/section_4/cis_4.1.1.x.yml index b70ee61f..6e2d2464 100644 --- a/tasks/section_4/cis_4.1.1.x.yml +++ b/tasks/section_4/cis_4.1.1.x.yml @@ -161,4 +161,4 @@ state: '{{ "file" if discovered_cron_allow_state.stat.exists else "touch" }}' owner: root group: root - mode: g-wx,o-rwx + mode: 'g-wx,o-rwx' diff --git a/tasks/section_4/cis_4.4.2.x.yml b/tasks/section_4/cis_4.4.2.x.yml index 08ef1284..423e410e 100644 --- a/tasks/section_4/cis_4.4.2.x.yml +++ b/tasks/section_4/cis_4.4.2.x.yml @@ -3,9 +3,8 @@ - name: "4.4.2.1 | PATCH | Ensure custom authselect profile is used" when: - rhel8cis_rule_4_4_2_1 - - authselect_version == "OK" - - pam_version == "OK" - rhel8cis_disruption_high + - rhel8cis_allow_authselect_updates tags: - level1-server - level1-workstation @@ -16,22 +15,35 @@ block: - name: "4.4.2.1 | PATCH | Ensure custom authselect profile is used | Create custom profiles" when: - - rhel8cis_authselect_custom_profile_create - - discovered_authselect_running_config.stdout is not defined - - not discovered_authselect_profile.stat.exists - ansible.builtin.shell: "/usr/bin/authselect create-profile {{ rhel8cis_authselect['custom_profile_name'] }} -b {{ rhel8cis_authselect['default_file_to_copy'] }}" + - rhel8cis_authselect_custom_profile_name not in prelim_authselect_current_profile.stdout or + prelim_authselect_current_profile.stdout is not defined + ansible.builtin.shell: "/usr/bin/authselect create-profile {{ rhel8cis_authselect_custom_profile_name }} -b {{ rhel8cis_authselect_default_profile_to_copy }}" args: - creates: "/etc/authselect/custom/{{ rhel8cis_authselect['custom_profile_name'] }}" + creates: "/etc/authselect/custom/{{ rhel8cis_authselect_custom_profile_name }}" - - name: "4.4.2.1 | PATCH | Ensure custom authselect profile is used | Select profiles" - when: - - rhel8cis_authselect_custom_profile_select - - (discovered_authselect_running_config.stdout is defined and "rhel8cis_authselect['custom_profile_name'] not in discovered_authselect_running_config.stdout") - ansible.builtin.shell: "/usr/bin/authselect select custom/{{ rhel8cis_authselect['custom_profile_name'] }}{% if rhel8cis_rule_4_4_2_2 %} with-faillock{% endif %}{% if rhel8cis_rule_4_4_2_4 %} with-pwhistory{% endif %}{% if rhel8cis_rule_4_4_3_4_1 %} without-nullok{% endif %} --force" + - name: "4.4.2.1 | AUDIT | Ensure custom authselect profile is used | get profile features" + ansible.builtin.shell: "/usr/bin/authselect list-features custom/{{ rhel8cis_authselect_custom_profile_name }}" + changed_when: false + register: discovered_authselect_profile_features + + - name: "4.4.2.1 | PATCH | Ensure custom authselect profile is used | Add missing pam modules to config | pwquality" + when: "'with-pwquality' not in discovered_authselect_profile_features.stdout_lines" + ansible.builtin.lineinfile: + path: "/etc/authselect/custom/{{ rhel8cis_authselect_custom_profile_name }}/{{ item }}-auth" + regexp: ^password\s*requisite\s*pam_pwquality.so.* + line: password requisite pam_pwquality.so local_users_only {include if "with-pwquality"} + loop: + - system + - password + + - name: "4.4.2.1 | PATCH | Ensure custom authselect profile is used | Backup and Add pam modules" + ansible.builtin.shell: "/usr/bin/authselect select custom/{{ rhel8cis_authselect_custom_profile_name }}{% if rhel8cis_rule_4_4_2_2 %} with-faillock{% endif %}{% if rhel8cis_rule_4_4_2_3 %} with-pwquality{% endif %}{% if rhel8cis_rule_4_4_2_4 %} with-pwhistory{% endif %}{% if rhel8cis_rule_4_4_3_4_1 %} without-nullok{% endif %} --force --backup=rhel8cis-preremediate-{{ lookup('pipe', 'date +%Y-%m-%d-%H%M') }}" - name: "4.4.2.2 | PATCH | Ensure pam_faillock module is enabled" when: - rhel8cis_rule_4_4_2_2 + - rhel8cis_disruption_high + - rhel8cis_allow_authselect_updates tags: - level1-server - level1-workstation @@ -44,21 +56,23 @@ - NIST800-53R5_IA-5 - authselect - rule_4.4.2.2 - notify: Update_authselect + notify: Authselect update block: - name: "4.4.2.2 | AUDIT | Ensure pam_faillock module is enabled | Get current config" ansible.builtin.shell: authselect current | grep faillock changed_when: false - failed_when: discovered_authselect_current.rc not in [ 0, 1 ] - register: discovered_authselect_current + failed_when: discovered_authselect_current_faillock.rc not in [ 0, 1 ] + register: discovered_authselect_current_faillock - name: "4.4.2.2 | AUDIT | Ensure pam_faillock module is enabled | Add feature if missing" - when: discovered_authselect_current.rc != 0 - ansible.builtin.shell: "authselect enable-feature with-faillock" + when: discovered_authselect_current_faillock.rc != 0 + ansible.builtin.shell: "/usr/bin/authselect select custom/{{ rhel8cis_authselect_custom_profile_name }}{% if rhel8cis_rule_4_4_2_2 %} with-faillock{% endif %}{% if rhel8cis_rule_4_4_2_3 %} with-pwquality{% endif %}{% if rhel8cis_rule_4_4_2_4 %} with-pwhistory{% endif %}{% if rhel8cis_rule_4_4_3_4_1 %} without-nullok{% endif %}" - name: "4.4.2.3 | PATCH | Ensure pam_pwquality module is enabled" when: - rhel8cis_rule_4_4_2_3 + - rhel8cis_disruption_high + - rhel8cis_allow_authselect_updates tags: - level1-server - level1-workstation @@ -67,41 +81,23 @@ - NIST800-53R5_IA-5 - authselect - rule_4.4.2.3 - notify: Update_authselect block: - - name: "4.4.2.3 | AUDIT | Ensure pam_pwquality module is enabled | Capture current state" - ansible.builtin.shell: | - grep -P -- '\bpam_pwquality\.so\b' /etc/pam.d/{password,system}-auth + - name: "4.4.2.3 | AUDIT | Ensure pam_pwquality module is enabled | Get current config" + ansible.builtin.shell: authselect current | grep quality changed_when: false - failed_when: rhel8cis_pwquality_enabled.rc not in [ 0, 1 ] - register: discovered_pwquality_enabled + failed_when: discovered_authselect_current_quality.rc not in [ 0, 1 ] + register: discovered_authselect_current_quality - - name: "4.4.2.3 | PATCH | Ensure pam_pwquality module is enabled | system-auth" - when: "'system-auth:password' not in discovered_pwquality_enabled.stdout" - ansible.builtin.lineinfile: - backrefs: true - insertbefore: "{{ item.before | default (omit) }}" - line: "{{ item.line }}" - path: /etc/authselect/custom/{{ rhel8cis_authselect['custom_profile_name'] }}/system-auth - regexp: "{{ item.regexp }}" - loop: - - { regexp: '^(password\s+)(required|requisite|sufficient)(\s+pam_pwquality.so.*)(.*)', line: '\1requisite\3\4', before: '^password\s+[default=1 ignore=ignore success=ok]' } - - - name: "4.4.2.3 | PATCH | Ensure pam_pwquality module is enabled | password-auth" - when: "'password-auth:password' not in discovered_pwquality_enabled.stdout" - ansible.builtin.lineinfile: - backrefs: true - insertafter: "{{ item.after | default (omit) }}" - insertbefore: "{{ item.before | default (omit) }}" - line: "{{ item.line }}" - path: /etc/authselect/custom/{{ rhel8cis_authselect['custom_profile_name'] }}/password-auth - regexp: "{{ item.regexp }}" - loop: - - { regexp: '^(password\s+)(required|requisite|sufficient)(\s+pam_pwquality.so.*)(.*)', line: '\1requisite\3\4', before: '^password\s+[default=1 ignore=ignore success=ok]' } + - name: "4.4.2.3 | AUDIT | Ensure pam_pwquality module is enabled | Add feature if missing" + when: discovered_authselect_current_quality.rc != 0 + ansible.builtin.shell: "/usr/bin/authselect select custom/{{ rhel8cis_authselect_custom_profile_name }}{% if rhel8cis_rule_4_4_2_2 %} with-faillock{% endif %}{% if rhel8cis_rule_4_4_2_3 %} with-pwquality{% endif %}{% if rhel8cis_rule_4_4_2_4 %} with-pwhistory{% endif %}{% if rhel8cis_rule_4_4_3_4_1 %} without-nullok{% endif %}" + notify: Authselect update - name: "4.4.2.4 | PATCH | Ensure pam_pwhistory module is enabled" when: - rhel8cis_rule_4_4_2_4 + - rhel8cis_disruption_high + - rhel8cis_allow_authselect_updates tags: - level1-server - level1-workstation @@ -110,21 +106,23 @@ - NIST800-53R5_IA-5 - authselect - rule_4.4.2.4 - notify: Update_authselect block: - name: "4.4.2.4 | AUDIT | Ensure pam_pwhistory module is enabled | Get current config" ansible.builtin.shell: authselect current | grep pwhistory changed_when: false - failed_when: discovered_authselect_current.rc not in [ 0, 1 ] - register: discovered_authselect_current + failed_when: discovered_authselect_current_history.rc not in [ 0, 1 ] + register: discovered_authselect_current_history - name: "4.4.2.4 | PATCH | Ensure pam_pwhistory module is enabled | enable feature" - when: discovered_authselect_current.rc != 0 - ansible.builtin.shell: "authselect enable-feature with-pwhistory" + when: discovered_authselect_current_history.rc != 0 + ansible.builtin.shell: "/usr/bin/authselect select custom/{{ rhel8cis_authselect_custom_profile_name }}{% if rhel8cis_rule_4_4_2_2 %} with-faillock{% endif %}{% if rhel8cis_rule_4_4_2_3 %} with-pwquality{% endif %}{% if rhel8cis_rule_4_4_2_4 %} with-pwhistory{% endif %}{% if rhel8cis_rule_4_4_3_4_1 %} without-nullok{% endif %}" + notify: Authselect update - name: "4.4.2.5 | PATCH | Ensure pam_unix module is enabled" when: - rhel8cis_rule_4_4_2_5 + - rhel8cis_disruption_high + - rhel8cis_allow_authselect_updates tags: - level1-server - level1-workstation @@ -138,31 +136,33 @@ ansible.builtin.shell: | grep -P -- '\b(pam_unix\.so)\b' /etc/authselect/"$(head -1 /etc/authselect/authselect.conf)"/{system,password}-auth changed_when: false - failed_when: rhel8cis_authselect_pam_unix.rc not in [ 0, 1 ] + failed_when: discovered_authselect_pam_unix.rc not in [ 0, 1 ] register: discovered_authselect_pam_unix - name: "4.4.2.5 | PATCH | Ensure pam_unix module is enabled | system-auth" when: "'system-auth:password' not in discovered_authselect_pam_unix.stdout" ansible.builtin.lineinfile: + path: /etc/authselect/custom/{{ rhel8cis_authselect_custom_profile_name }}/system-auth + regexp: "{{ item.regexp }}" + line: "{{ item.line }}" backrefs: true insertafter: "{{ item.after | default (omit) }}" insertbefore: "{{ item.before | default (omit) }}" - line: "{{ item.line }}" - path: /etc/authselect/custom/{{ rhel8cis_authselect['custom_profile_name'] }}/system-auth - regexp: "{{ item.regexp }}" - loop: - - { regexp: '^(auth\s+)sufficient(\s+pam_unix.so.*)(.*)', line: '\1sufficient\2\3', after: '^auth.*pam_faillock.*preauth' } - - { regexp: '^(password\s+)sufficient(\s+pam_unix.so.*)(.*)', line: '\1sufficient\2\3', before: '^password.*pam_deny.so' } + loop: + - { regexp: '^(auth\s+)sufficient(\s+pam_unix.so.*)(.*)', line: '\1sufficient\2\3', after: '^auth.*pam_faillock.*preauth' } + - { regexp: '^(password\s+)sufficient(\s+pam_unix.so.*)(.*)', line: '\1sufficient\2\3', before: '^password.*pam_deny.so' } + notify: Authselect update - name: "4.4.2.5 | PATCH | Ensure pam_unix module is enabled | password-auth" when: "'password-auth:password' not in discovered_authselect_pam_unix.stdout" ansible.builtin.lineinfile: + path: /etc/authselect/custom/{{ rhel8cis_authselect_custom_profile_name }}/password-auth + line: "{{ item.line }}" + regexp: "{{ item.regexp }}" backrefs: true insertafter: "{{ item.after | default (omit) }}" insertbefore: "{{ item.before | default (omit) }}" - line: "{{ item.line }}" - path: /etc/authselect/custom/{{ rhel8cis_authselect['custom_profile_name'] }}/password-auth - regexp: "{{ item.regexp }}" - loop: - - { regexp: '^(auth\s+)sufficient(\s+pam_unix.so.*)(.*)', line: '\1sufficient\2\2', after: '^auth.*pam_faillock.*preauth' } - - { regexp: '^(password\s+)sufficient(\s+pam_unix.so.*)(.*)', line: '\1sufficient\2\3', before: '^password.*pam_deny.so' } + loop: + - { regexp: '^(auth\s+)sufficient(\s+pam_unix.so.*)(.*)', line: '\1sufficient\2\2', after: '^auth.*pam_faillock.*preauth' } + - { regexp: '^(password\s+)sufficient(\s+pam_unix.so.*)(.*)', line: '\1sufficient\2\3', before: '^password.*pam_deny.so' } + notify: Authselect update diff --git a/tasks/section_4/cis_4.4.3.1.x.yml b/tasks/section_4/cis_4.4.3.1.x.yml index 062efcee..13d39acd 100644 --- a/tasks/section_4/cis_4.4.3.1.x.yml +++ b/tasks/section_4/cis_4.4.3.1.x.yml @@ -41,7 +41,7 @@ - rhel8cis_allow_authselect_updates - discovered_authselect_current.rc != 0 ansible.builtin.replace: - path: "/etc/authselect/custom/{{ rhel8cis_authselect['custom_profile_name'] }}/{{ item }}-auth" + path: "/etc/authselect/custom/{{ rhel8cis_authselect_custom_profile_name }}/{{ item }}-auth" regexp: ^(\s*auth\s+(requisite|required|sufficient)\s+pam_faillock\.so)(.*)\s+deny\s*=\s*\S+(.*$) replace: \1\2\3 loop: @@ -79,10 +79,10 @@ - name: "4.4.3.1.2 | PATCH | Ensure password unlock time is configured | authselect_files" when: - rhel8cis_allow_authselect_updates - - "'example' not in rhel8cis_authselect['custom_profile_name']" + - "'example' not in rhel8cis_authselect_custom_profile_name" notify: Update_authselect ansible.builtin.replace: - path: "/etc/authselect/custom/{{ rhel8cis_authselect['custom_profile_name'] }}/{{ item }}-auth" + path: "/etc/authselect/custom/{{ rhel8cis_authselect_custom_profile_name }}/{{ item }}-auth" regexp: ^(\s*auth\s+(requisite|required|sufficient)\s+pam_faillock\.so)(.*)\s+unlock_time\s*=\s*\S+(.*$) replace: \1\2\3 loop: @@ -120,10 +120,10 @@ - name: "4.4.3.1.3 | PATCH | Ensure password failed attempts lockout includes root account | authselect_files" when: - rhel8cis_allow_authselect_updates - - "'example' not in rhel8cis_authselect['custom_profile_name']" + - "'example' not in rhel8cis_authselect_custom_profile_name" notify: Update_authselect ansible.builtin.replace: - path: "/etc/authselect/custom/{{ rhel8cis_authselect['custom_profile_name'] }}/{{ item }}-auth" + path: "/etc/authselect/custom/{{ rhel8cis_authselect_custom_profile_name }}/{{ item }}-auth" regexp: ^(\s*auth\s+(requisite|required|sufficient)\s+pam_faillock\.so)(.*)\s"{{ rhel8cis_pam_faillock['root_option'] }}"(\s*=\s*\d|.*)\S+(.*$) replace: \1\2\3\4 loop: diff --git a/tasks/section_4/cis_4.4.3.2.x.yml b/tasks/section_4/cis_4.4.3.2.x.yml index c3f8e1fd..8538d1f3 100644 --- a/tasks/section_4/cis_4.4.3.2.x.yml +++ b/tasks/section_4/cis_4.4.3.2.x.yml @@ -32,10 +32,10 @@ - name: "4.4.3.2.1 | PATCH | Ensure password number of changed characters is configured | authselect_files" when: - rhel8cis_allow_authselect_updates - - "'example' not in rhel8cis_authselect['custom_profile_name']" + - "'example' not in rhel8cis_authselect_custom_profile_name" notify: Update_authselect ansible.builtin.replace: - path: "/etc/authselect/custom/{{ rhel8cis_authselect['custom_profile_name'] }}/{{ item }}-auth" + path: "/etc/authselect/custom/{{ rhel8cis_authselect_custom_profile_name }}/{{ item }}-auth" regexp: ^(\s*password\s+(requisite|required|sufficient)\s+pam_pwquality\.so)(.*)\s+difok\s*=\s*\S+(.*$) replace: \1\2\3 loop: @@ -74,10 +74,10 @@ - name: "4.4.3.2.2 | PATCH | Ensure password length is configured | authselect_files" when: - rhel8cis_allow_authselect_updates - - "'example' not in rhel8cis_authselect['custom_profile_name']" + - "'example' not in rhel8cis_authselect_custom_profile_name" notify: Update_authselect ansible.builtin.replace: - path: "/etc/authselect/custom/{{ rhel8cis_authselect['custom_profile_name'] }}/{{ item }}-auth" + path: "/etc/authselect/custom/{{ rhel8cis_authselect_custom_profile_name }}/{{ item }}-auth" regexp: ^(\s*password\s+(requisite|required|sufficient)\s+pam_pwquality\.so)(.*)\s+minlen\s*=\s*\S+(.*$) replace: \1\2\3 loop: @@ -116,10 +116,10 @@ - name: "4.4.3.2.3 | PATCH | Ensure password complexity is configured | authselect_files" when: - rhel8cis_allow_authselect_updates - - "'example' not in rhel8cis_authselect['custom_profile_name']" + - "'example' not in rhel8cis_authselect_custom_profile_name" notify: Update_authselect ansible.builtin.replace: - path: "/etc/authselect/custom/{{ rhel8cis_authselect['custom_profile_name'] }}/{{ item }}-auth" + path: "/etc/authselect/custom/{{ rhel8cis_authselect_custom_profile_name }}/{{ item }}-auth" regexp: ^(\s*password\s+(requisite|required|sufficient)\s+pam_pwquality\.so)(.*)\s+minclass\s*=\s*\S+(.*$) replace: \1\2\3 loop: @@ -158,10 +158,10 @@ - name: "4.4.3.2.4 | PATCH | Ensure password same consecutive characters is configured | authselect_files" when: - rhel8cis_allow_authselect_updates - - "'example' not in rhel8cis_authselect['custom_profile_name']" + - "'example' not in rhel8cis_authselect_custom_profile_name" notify: Update_authselect ansible.builtin.replace: - path: "/etc/authselect/custom/{{ rhel8cis_authselect['custom_profile_name'] }}/{{ item }}-auth" + path: "/etc/authselect/custom/{{ rhel8cis_authselect_custom_profile_name }}/{{ item }}-auth" regexp: ^(\s*password\s+(requisite|required|sufficient)\s+pam_pwquality\.so)(.*)\s+maxrepeat\s*=\s*\S+(.*$) replace: \1\2\3 loop: @@ -184,14 +184,14 @@ ansible.builtin.lineinfile: path: /etc/security/pwquality.conf state: present - regexp: '^(#|)\s*maxseq\s*=\s*\d' - line: "maxseq = {{ rhel8cis_pam_pwquality['maxseq'] }}" + regexp: '^(#|)\s*maxsequence\s*=\s*\d' + line: "maxsequence = {{ rhel8cis_pam_pwquality['maxseq'] }}" - name: "4.4.3.2.5 | PATCH | Ensure password maximum sequential characters is configured | pam_files" when: not rhel8cis_allow_authselect_updates ansible.builtin.replace: path: "/etc/pam.d/{{ item }}-auth" - regexp: ^(\s*password\s+(requisite|required|sufficient)\s+pam_pwquality\.so)(.*)\s+maxseq\s*=\s*\S+(.*$) + regexp: ^(\s*password\s+(requisite|required|sufficient)\s+pam_pwquality\.so)(.*)\s+maxsequence\s*=\s*\S+(.*$) replace: \1\2\3 loop: - password @@ -200,11 +200,11 @@ - name: "4.4.3.2.5 | PATCH | Ensure password same consecutive characters is configured | authselect_files" when: - rhel8cis_allow_authselect_updates - - "'example' not in rhel8cis_authselect['custom_profile_name']" + - "'example' not in rhel8cis_authselect_custom_profile_name" notify: Update_authselect ansible.builtin.replace: - path: "/etc/authselect/custom/{{ rhel8cis_authselect['custom_profile_name'] }}/{{ item }}-auth" - regexp: ^(\s*password\s+(requisite|required|sufficient)\s+pam_pwquality\.so)(.*)\s+maxseq\s*=\s*\S+(.*$) + path: "/etc/authselect/custom/{{ rhel8cis_authselect_custom_profile_name }}/{{ item }}-auth" + regexp: ^(\s*password\s+(requisite|required|sufficient)\s+pam_pwquality\.so)(.*)\s+maxsequence\s*=\s*\S+(.*$) replace: \1\2\3 loop: - password @@ -242,10 +242,10 @@ - name: "4.4.3.2.6 | PATCH | Ensure password dictionary check is enabled | authselect_files" when: - rhel8cis_allow_authselect_updates - - "'example' not in rhel8cis_authselect['custom_profile_name']" + - "'example' not in rhel8cis_authselect_custom_profile_name" notify: Update_authselect ansible.builtin.replace: - path: "/etc/authselect/custom/{{ rhel8cis_authselect['custom_profile_name'] }}/{{ item }}-auth" + path: "/etc/authselect/custom/{{ rhel8cis_authselect_custom_profile_name }}/{{ item }}-auth" regexp: ^(\s*password\s+(requisite|required|sufficient)\s+pam_pwquality\.so)(.*)\s+dictcheck\s*=\s*\S+(.*$) replace: \1\2\3 loop: @@ -284,10 +284,10 @@ - name: "4.4.3.2.7 | PATCH | Ensure password dictionary check is enabled | authselect_files" when: - rhel8cis_allow_authselect_updates - - "'example' not in rhel8cis_authselect['custom_profile_name']" + - "'example' not in rhel8cis_authselect_custom_profile_name" notify: Update_authselect ansible.builtin.replace: - path: "/etc/authselect/custom/{{ rhel8cis_authselect['custom_profile_name'] }}/{{ item }}-auth" + path: "/etc/authselect/custom/{{ rhel8cis_authselect_custom_profile_name }}/{{ item }}-auth" regexp: ^(\s*password\s+(requisite|required|sufficient)\s+pam_pwquality\.so)(.*)\s+enforce_for_root(.*$) replace: \1\2\3 loop: diff --git a/tasks/section_4/cis_4.4.3.3.x.yml b/tasks/section_4/cis_4.4.3.3.x.yml index b321e3e1..183d36d6 100644 --- a/tasks/section_4/cis_4.4.3.3.x.yml +++ b/tasks/section_4/cis_4.4.3.3.x.yml @@ -22,10 +22,10 @@ - name: "4.4.3.3.1 | PATCH | Ensure password number of changed characters is configured | authselect_files" when: - rhel8cis_allow_authselect_updates - - "'example' not in rhel8cis_authselect['custom_profile_name']" + - "'example' not in rhel8cis_authselect_custom_profile_name" notify: Update_authselect ansible.builtin.replace: - path: "/etc/authselect/custom/{{ rhel8cis_authselect['custom_profile_name'] }}/{{ item }}-auth" + path: "/etc/authselect/custom/{{ rhel8cis_authselect_custom_profile_name }}/{{ item }}-auth" regexp: ^(\s*password\s+(requisite|required|sufficient)\s+pam_pwhistory\.so)(.*)\s+remember\s*=\s*\S+(.*$) replace: \1\2\3 loop: @@ -64,10 +64,10 @@ - name: "4.4.3.3.2 | PATCH | Ensure password history is enforced for the root user | authselect_files" when: - rhel8cis_allow_authselect_updates - - "'example' not in rhel8cis_authselect['custom_profile_name']" + - "'example' not in rhel8cis_authselect_custom_profile_name" notify: Update_authselect ansible.builtin.replace: - path: "/etc/authselect/custom/{{ rhel8cis_authselect['custom_profile_name'] }}/{{ item }}-auth" + path: "/etc/authselect/custom/{{ rhel8cis_authselect_custom_profile_name }}/{{ item }}-auth" regexp: ^(\s*password\s+(requisite|required|sufficient)\s+pam_pwhistory\.so)(.*)\s+enforce_for_root(.*$) replace: \1\2\3 loop: @@ -104,15 +104,12 @@ when: - rhel8cis_allow_authselect_updates - discovered_pwhistory_authtok.rc != 0 - notify: Update_authselect - community.general.pamd: - name: "{{ item }}-auth" - path: "/etc/authselect/custom/{{ rhel8cis_authselect['custom_profile_name'] }}" - type: password - control: requisite - module_path: pam_pwhistory.so - module_arguments: 'use_authtok' - state: updated + ansible.builtin.lineinfile: + path: "/etc/authselect/custom/{{ rhel8cis_authselect_custom_profile_name }}/{{ item }}-auth" + regexp: ^(\s*password\s+)(requisite|required|sufficient)(\s+pam_unix.so\s)(.*)use_authtok(.*$) + line: \1\2\3\4use_authtok\5 + backrefs: true loop: - password - system + notify: Update_authselect diff --git a/tasks/section_4/cis_4.4.3.4.x.yml b/tasks/section_4/cis_4.4.3.4.x.yml index 87dbcc0e..9c5cecf7 100644 --- a/tasks/section_4/cis_4.4.3.4.x.yml +++ b/tasks/section_4/cis_4.4.3.4.x.yml @@ -63,7 +63,7 @@ ansible.builtin.replace: path: "/etc/pam.d/{{ item }}-auth" regexp: ^(\s*password\s+(requisite|required|sufficient)\s+pam_unix\.so)(.*)remember\s*=\s*\d+(.*$) - replace: \1\2\3 + replace: \1\3\4 loop: - password - system @@ -73,12 +73,12 @@ - discovered_pam_remember is defined - discovered_pam_remember | length > 0 - rhel8cis_allow_authselect_updates - - "'example' not in rhel8cis_authselect['custom_profile_name']" + - "'example' not in rhel8cis_authselect_custom_profile_name" notify: Update_authselect ansible.builtin.replace: - path: "/etc/authselect/custom/{{ rhel8cis_authselect['custom_profile_name'] }}/{{ item }}-auth" + path: "/etc/authselect/custom/{{ rhel8cis_authselect_custom_profile_name }}/{{ item }}-auth" regexp: ^(\s*password\s+(requisite|required|sufficient)\s+pam_unix\.so)(.*)remember\s*=\s*\d+(.*$) - replace: \1\2\3 + replace: \1\3\4 loop: - password - system @@ -108,7 +108,7 @@ ansible.builtin.replace: path: "/etc/pam.d/{{ item }}-auth" regexp: ^(\s*password\s+(requisite|required|sufficient)\s+pam_unix\.so)(.*)(sha512|yescrypt)(.*$) - replace: \1\2\4 {{ rhel8cis_pam_pwhash }} + replace: \1\3\5 {{ rhel8cis_pam_pwhash }} loop: - password - system @@ -118,12 +118,12 @@ - discovered_hash_state is defined - discovered_hash_state | length > 0 - rhel8cis_allow_authselect_updates - - "'example' not in rhel8cis_authselect['custom_profile_name']" + - "'example' not in rhel8cis_authselect_custom_profile_name" notify: Update_authselect ansible.builtin.replace: - path: "/etc/authselect/custom/{{ rhel8cis_authselect['custom_profile_name'] }}/{{ item }}-auth" + path: "/etc/authselect/custom/{{ rhel8cis_authselect_custom_profile_name }}/{{ item }}-auth" regexp: ^(\s*password\s+(requisite|required|sufficient)\s+pam_unix\.so)(.*)(sha512|yescrypt)\s*=\s*\d+(.*$) - replace: \1\2\4 {{ rhel8cis_pam_pwhash }} + replace: \1\3\5 {{ rhel8cis_pam_pwhash }} loop: - password - system @@ -163,10 +163,10 @@ - discovered_pam_authtok is defined - discovered_pam_authtok | length > 0 - rhel8cis_allow_authselect_updates - - "'example' not in rhel8cis_authselect['custom_profile_name']" + - "'example' not in rhel8cis_authselect_custom_profile_name" notify: Update_authselect ansible.builtin.replace: - path: "/etc/authselect/custom/{{ rhel8cis_authselect['custom_profile_name'] }}/{{ item }}-auth" + path: "/etc/authselect/custom/{{ rhel8cis_authselect_custom_profile_name }}/{{ item }}-auth" regexp: ^(\s*password\s+(requisite|required|sufficient)\s+pam_unix\.so)(.*)\s+use_authtok(.*$) replace: \1\3\4 use_authtok loop: diff --git a/tasks/section_5/cis_5.1.4.yml b/tasks/section_5/cis_5.1.4.yml index bd20b407..27fbba29 100644 --- a/tasks/section_5/cis_5.1.4.yml +++ b/tasks/section_5/cis_5.1.4.yml @@ -13,25 +13,32 @@ - rule_5.1.4 block: - name: "5.1.4 | AUDIT | Ensure permissions on all logfiles are configured | find files" - ansible.builtin.shell: find /var/log/ -type f -perm /g+wx,o+rwx -exec ls {} \; + ansible.builtin.shell: find -L /var/log/ -type f -perm /g+wx,o+rwx -exec ls {} \; changed_when: false failed_when: false register: discovered_logfiles - - name: "5.1.4 | AUDIT | Ensure permissions on all logfiles are configured | set_fact" - ansible.builtin.set_fact: - discovered_logfiles_flattened: "{{ discovered_logfiles | json_query('stdout_lines[*]') | flatten }}" # noqa: jinja[invalid] - when: - - discovered_logfiles.stdout_lines | length > 0 - - discovered_logfiles is defined - - name: "5.1.4 | PATCH | Ensure permissions on all logfiles are configured | change permissions" - ansible.builtin.file: - path: "{{ item }}" - mode: '0640' - loop: "{{ discovered_logfiles_flattened }}" when: - - rhel8cis_5_1_4_logfiles_flattened is defined - item != "/var/log/btmp" - item != "/var/log/utmp" - item != "/var/log/wtmp" + - item != "/var/log/lastlog" + ansible.builtin.file: + path: "{{ item }}" + mode: 'u-x,g-wx,o-rwx' + failed_when: discovered_logfile_list.state not in '[ file, absent ]' + register: discovered_logfile_list + loop: "{{ discovered_logfiles.stdout_lines }}" + + - name: "5.1.4 | PATCH | Ensure permissions on all logfiles are configured | change permissions" + ansible.builtin.file: + path: "{{ item.name }}" + mode: 'ug-x,o-wx' + failed_when: discovered_logfile_list.state not in '[ file, absent ]' + register: discovered_logfile_list + with_fileglob: + - /var/log/*tmp.*" + - /var/log/lastlog" + - /var/log/ssd*" + - /var/log/SSD*" diff --git a/tasks/section_5/cis_5.2.4.x.yml b/tasks/section_5/cis_5.2.4.x.yml index e78a7ff1..2914005e 100644 --- a/tasks/section_5/cis_5.2.4.x.yml +++ b/tasks/section_5/cis_5.2.4.x.yml @@ -12,7 +12,7 @@ ansible.builtin.file: path: "{{ discovered_audit_logfile.stdout | dirname }}" state: directory - mode: g-w,o-rwx + mode: 'g-w,o-rwx' - name: | "5.2.4.2 | PATCH | Ensure audit log files are mode 0640 or less permissive" @@ -43,7 +43,7 @@ "5.2.4.4 | PATCH | Ensure only authorized groups are assigned ownership of audit log files" ansible.builtin.file: path: "{{ discovered_audit_logfile.stdout }}" - mode: "{% if discovered_auditlog_info.stat.mode != '0600' %}0640{% endif %}" + mode: 'o-x,g-wx,o-rwx' owner: root group: root @@ -58,7 +58,7 @@ - rule_5.2.4.5 ansible.builtin.file: path: "{{ item.path }}" - mode: g-wx,o-rwx + mode: 'g-wx,o-rwx' loop: "{{ discovered_auditd_conf_files.files }}" loop_control: label: "{{ item.path }}" @@ -120,7 +120,7 @@ - name: "5.2.4.8 | PATCH | Ensure audit tools are 755 or more restrictive | set if required" ansible.builtin.file: path: "{{ item.item }}" - mode: g-w,o-w + mode: 'g-w,o-w' loop: "{{ discovered_audit_bins_mode.results }}" loop_control: label: "{{ item.item }}" diff --git a/tasks/section_5/cis_5.3.x.yml b/tasks/section_5/cis_5.3.x.yml index bb955a9e..754f57b4 100644 --- a/tasks/section_5/cis_5.3.x.yml +++ b/tasks/section_5/cis_5.3.x.yml @@ -85,10 +85,10 @@ path: /etc/aide.conf marker: "# {mark} Audit tools - CIS benchmark - Ansible-lockdown" block: | - /usr/sbin/auditctl p+i+n+u+g+s+b+acl+xattrs+sha512 - /usr/sbin/auditd p+i+n+u+g+s+b+acl+xattrs+sha512 - /usr/sbin/ausearch p+i+n+u+g+s+b+acl+xattrs+sha512 - /usr/sbin/aureport p+i+n+u+g+s+b+acl+xattrs+sha512 - /usr/sbin/autrace p+i+n+u+g+s+b+acl+xattrs+sha512 - /usr/sbin/augenrules p+i+n+u+g+s+b+acl+xattrs+sha512 + /sbin/auditctl p+i+n+u+g+s+b+acl+xattrs+sha512 + /sbin/auditd p+i+n+u+g+s+b+acl+xattrs+sha512 + /sbin/ausearch p+i+n+u+g+s+b+acl+xattrs+sha512 + /sbin/aureport p+i+n+u+g+s+b+acl+xattrs+sha512 + /sbin/autrace p+i+n+u+g+s+b+acl+xattrs+sha512 + /sbin/augenrules p+i+n+u+g+s+b+acl+xattrs+sha512 validate: aide -D --config %s diff --git a/tasks/section_6/cis_6.1.x.yml b/tasks/section_6/cis_6.1.x.yml index 0c16bd2f..a0bddda0 100644 --- a/tasks/section_6/cis_6.1.x.yml +++ b/tasks/section_6/cis_6.1.x.yml @@ -16,7 +16,7 @@ path: /etc/passwd owner: root group: root - mode: u-x,go-wx + mode: 'u-x,go-wx' - name: "6.1.2 | PATCH | Ensure permissions on /etc/passwd- are configured" when: @@ -34,7 +34,7 @@ path: /etc/passwd- owner: root group: root - mode: u-x,go-wx + mode: 'u-x,go-wx' - name: "6.1.3 | PATCH | Ensure permissions on /etc/security/opasswd are configured" when: @@ -70,7 +70,7 @@ path: /etc/group owner: root group: root - mode: u-x,go-wx + mode: 'u-x,go-wx' - name: "6.1.5 | PATCH | Ensure permissions on /etc/group- are configured" when: @@ -88,7 +88,7 @@ path: /etc/group- owner: root group: root - mode: u-x,go-wx + mode: 'u-x,go-wx' - name: "6.1.6 | PATCH | Ensure permissions on /etc/shadow are configured" when: @@ -178,7 +178,7 @@ path: /etc/shells owner: root group: root - mode: u-x,go-wx + mode: 'u-x,go-wx' - name: "6.1.11 | PATCH | Ensure world writable files and directories are secured" when: @@ -209,7 +209,7 @@ - rhel8cis_no_world_write_adjust ansible.builtin.file: path: '{{ item }}' - mode: o-w + mode: 'o-w' state: touch with_items: "{{ discovered_perms_results.stdout_lines }}" diff --git a/tasks/section_6/cis_6.2.x.yml b/tasks/section_6/cis_6.2.x.yml index 24fe621b..e1fc4d90 100644 --- a/tasks/section_6/cis_6.2.x.yml +++ b/tasks/section_6/cis_6.2.x.yml @@ -341,7 +341,6 @@ path: "{{ item.dir }}" state: directory owner: "{{ item.id }}" - group: "{{ item.gid }}" loop: "{{ rhel8cis_passwd | selectattr('uid', '>=', rhel8uid_uid_start | int ) | selectattr('uid', '<=', rhel8uid_uid_stop | int ) | list }}" loop_control: label: "{{ item.id }}" @@ -417,5 +416,5 @@ ansible.builtin.file: path: '{{ item }}' - mode: go-w + mode: 'go-w' with_items: "{{ discovered_dot_files.stdout_lines }}" diff --git a/templates/ansible_vars_goss.yml.j2 b/templates/ansible_vars_goss.yml.j2 index 04a487bc..9284799b 100644 --- a/templates/ansible_vars_goss.yml.j2 +++ b/templates/ansible_vars_goss.yml.j2 @@ -616,14 +616,8 @@ rhel8cis_sudo_timestamp_timeout: {{ rhel8cis_sudo_timestamp_timeout }} ## PAM # 4.4.2.x -rhel8cis_authselect_pkg_update: {{ rhel8cis_authselect_pkg_update }} # NOTE the risks if system is using SSSD or using ipa-client-install rhel8cis_allow_authselect_updates: {{ rhel8cis_allow_authselect_updates }} -rhel8cis_authselect_custom_profile_create: {{ rhel8cis_authselect_custom_profile_create }} -rhel8cis_authselect_custom_profile_select: {{ rhel8cis_authselect_custom_profile_select }} -rhel8cis_authselect: - custom_profile_name: '{{ rhel8cis_authselect.custom_profile_name }}' - default_file_to_copy: "{{ rhel8cis_authselect.default_file_to_copy }}" - options: {{ rhel8cis_authselect }} +rhel8cis_authselect_custom_profile_name: '{{ rhel8cis_authselect_custom_profile_name }}' rhel8cis_pam_faillock: attempts: {{ rhel8cis_pam_faillock.attempts }} @@ -642,7 +636,7 @@ rhel8cis_pam_pwquality: minclass: {{ rhel8cis_pam_pwquality.minclass }} rhel8cis_pam_pwhistory: - remember: {{ rhel8cis_pam_pwhistory }} + remember: {{ rhel8cis_pam_pwhistory.remember }} rhel8cis_pam_pwhash: {{ rhel8cis_pam_pwhash }} diff --git a/vars/audit.yml b/vars/audit.yml index bb50f6d3..7a2e9ec8 100644 --- a/vars/audit.yml +++ b/vars/audit.yml @@ -26,15 +26,16 @@ post_audit_outfile: "{{ audit_log_dir }}/{{ ansible_facts.hostname }}-{{ benchma ### Audit binary settings ### audit_bin_version: - release: v0.4.4 - AMD64_checksum: 'sha256:1c4f54b22fde9d4d5687939abc2606b0660a5d14a98afcd09b04b793d69acdc5' + release: v0.4.8 + AMD64_checksum: 'sha256:85d00b7bba5f175bec95de7dfe1f71f8f25204914aad4c6f03c8457868eb6e2f' + ARM64_checksum: 'sha256:bca8c898bfd35b94c51455ece6193c95e2cd7b2b183ac2047b2d76291e73e47d' 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 audit results are: {{ pre_audit_summary }} - {% if not audit_only %}The post remediation audit results are: {{ post_audit_summary }}{% endif %} + The{% if not audit_only %} pre remediation{% endif %} audit results are: {{ pre_audit_results }} + {% if not audit_only %}The post remediation audit results are: {{ post_audit_results }}{% endif %} Full breakdown can be found in {{ audit_log_dir }}