From 95cf8b94925ce868dd2ad6a96fd1c4f3883a223f Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Tue, 10 Dec 2024 10:09:46 +0000 Subject: [PATCH 01/22] updated auditd handlers for restart Signed-off-by: Mark Bolwell --- handlers/main.yml | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/handlers/main.yml b/handlers/main.yml index 27e4a56..d7f49d9 100644 --- a/handlers/main.yml +++ b/handlers/main.yml @@ -107,8 +107,15 @@ msg: "Reboot required for auditd to apply new rules as immutable set" notify: Change_requires_reboot -- name: Restart auditd - ansible.builtin.shell: service auditd restart +- name: Stop auditd process + ansible.builtin.shell: systemctl kill auditd + listen: Restart auditd + +- name: Start auditd process + ansible.builtin.systemd_service: + name: auditd + state: started + listen: Restart auditd - name: Change_requires_reboot ansible.builtin.set_fact: From 0a8d8abf1e8a041cfa47501f1dff3d4490f86279 Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Tue, 10 Dec 2024 10:10:09 +0000 Subject: [PATCH 02/22] Changed warning if auditd template updated Signed-off-by: Mark Bolwell --- tasks/auditd.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tasks/auditd.yml b/tasks/auditd.yml index 502497c..7022e2c 100644 --- a/tasks/auditd.yml +++ b/tasks/auditd.yml @@ -26,7 +26,7 @@ ansible.builtin.import_tasks: file: warning_facts.yml vars: - warn_control_id: 'Auditd template updated, see diff output for details' + warn_control_id: 'Auditd template updated, validate as expected' - name: POST | AUDITD | Apply auditd template will for section 4.1.3 - only required rules will be added | stat file ansible.builtin.stat: From f3ef69d54c397a72960161b85481eb176008135b Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Tue, 10 Dec 2024 16:43:27 +0000 Subject: [PATCH 03/22] updated lint files Signed-off-by: Mark Bolwell --- .ansible-lint | 17 ++--------------- .pre-commit-config.yaml | 18 ++++++++++++------ .yamllint | 21 +++++++++++++-------- 3 files changed, 27 insertions(+), 29 deletions(-) diff --git a/.ansible-lint b/.ansible-lint index 3090307..3b7c373 100644 --- a/.ansible-lint +++ b/.ansible-lint @@ -3,20 +3,7 @@ parseable: true quiet: true skip_list: - - 'schema' - - 'no-changed-when' - - 'var-spacing' - - 'experimental' - - 'name[play]' - - 'name[casing]' - - 'name[template]' - - 'key-order[task]' - - '204' - - '305' - - '303' - - '403' - - '306' - - '602' - - '208' + - 'package-latest' + - 'risky-shell-pipe' use_default_rules: true verbosity: 0 diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index e53f665..acdd896 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -7,16 +7,21 @@ 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 + name: Detect AWS Credentials - id: detect-private-key + name: Detect Private Keys # git checks - id: check-merge-conflict + name: Check for merge conflicts - id: check-added-large-files + name: Check for Large files - id: check-case-conflict + name: Check case conflict # General checks - id: trailing-whitespace @@ -27,21 +32,21 @@ repos: types: [text] args: [--markdown-linebreak-ext=md] - id: end-of-file-fixer + name: Ensure line at end of file # Scan for passwords - repo: https://github.com/Yelp/detect-secrets rev: v1.5.0 hooks: - id: detect-secrets - exclude: templates/etc/security/pwquality.conf.d/50-pwcomplexity.conf.j2 - repo: https://github.com/gitleaks/gitleaks - rev: v8.18.4 + rev: v8.21.2 hooks: - id: gitleaks - repo: https://github.com/ansible-community/ansible-lint - rev: v24.7.0 + rev: v24.10.0 hooks: - id: ansible-lint name: Ansible-lint @@ -52,14 +57,15 @@ repos: # https://github.com/ansible/ansible-lint/issues/611 pass_filenames: false always_run: true - additional_dependencies: + # additional_dependencies: # https://github.com/pre-commit/pre-commit/issues/1526 # If you want to use specific version of ansible-core or ansible, feel # free to override `additional_dependencies` in your own hook config # file. - - ansible-core>=2.10.1 + # - ansible-core>=2.10.1 - repo: https://github.com/adrienverge/yamllint.git rev: v1.35.1 # or higher tag hooks: - id: yamllint + name: Check YAML Lint diff --git a/.yamllint b/.yamllint index ec2d1cd..fa7b697 100644 --- a/.yamllint +++ b/.yamllint @@ -1,32 +1,37 @@ --- extends: default - ignore: | tests/ molecule/ .github/ .gitlab-ci.yml *molecule.yml - rules: - indentation: - # Requiring 4 space indentation - spaces: 2 - # Requiring consistent indentation within a file, either indented or not - indent-sequences: consistent braces: max-spaces-inside: 1 level: error brackets: max-spaces-inside: 1 level: error + comments: + ignore-shebangs: true + min-spaces-from-content: 1 # prettier compatibility + comments-indentation: enable empty-lines: max: 1 - line-length: disable + indentation: + # Requiring 2 space indentation + spaces: 2 + # Requiring consistent indentation within a file, either indented or not + indent-sequences: consistent key-duplicates: enable + line-length: disable new-line-at-end-of-file: enable new-lines: type: unix + octal-values: + forbid-implicit-octal: true # yamllint defaults to false + forbid-explicit-octal: true trailing-spaces: enable truthy: allowed-values: ['true', 'false'] From b4afeab63878df54cc1447f9898d3ddc9e75252a Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Tue, 10 Dec 2024 16:44:14 +0000 Subject: [PATCH 04/22] updated title Signed-off-by: Mark Bolwell --- LICENSE | 2 +- templates/audit/98_auditd_exception.rules.j2 | 2 +- templates/audit/99_auditd.rules.j2 | 2 +- templates/etc/cron.d/aide.cron.j2 | 2 +- templates/etc/dconf/db/00-automount_lock.j2 | 2 +- templates/etc/dconf/db/00-autorun_lock.j2 | 2 +- templates/etc/dconf/db/00-media-automount.j2 | 2 +- templates/etc/dconf/db/00-media-autorun.j2 | 2 +- templates/etc/dconf/db/00-screensaver.j2 | 2 +- templates/etc/dconf/db/00-screensaver_lock.j2 | 2 +- templates/etc/dconf/db/gdm.d/01-banner-message.j2 | 2 +- 11 files changed, 11 insertions(+), 11 deletions(-) diff --git a/LICENSE b/LICENSE index f6d2b57..bb487ce 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2023 Mindpoint Group / Lockdown Enterprise / Lockdown Enterprise Releases +2025 Mindpoint Group - A Tyto Athene Company / Ansible Lockdown Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/templates/audit/98_auditd_exception.rules.j2 b/templates/audit/98_auditd_exception.rules.j2 index 0f4a4f9..82f6555 100644 --- a/templates/audit/98_auditd_exception.rules.j2 +++ b/templates/audit/98_auditd_exception.rules.j2 @@ -1,6 +1,6 @@ ## Ansible controlled file # Added as part of ansible-lockdown CIS baseline -# provided by MindPointGroup LLC +# provided by Mindpoint Group - A Tyto Athene Company / Ansible Lockdown ### YOUR CHANGES WILL BE LOST! # This file contains users whose actions are not logged by auditd diff --git a/templates/audit/99_auditd.rules.j2 b/templates/audit/99_auditd.rules.j2 index bf2d191..6d69976 100644 --- a/templates/audit/99_auditd.rules.j2 +++ b/templates/audit/99_auditd.rules.j2 @@ -1,6 +1,6 @@ ## Ansible controlled file # Added as part of ansible-lockdown CIS baseline -# provided by MindPointGroup LLC +# provided by Mindpoint Group - A Tyto Athene Company / Ansible Lockdown ### YOUR CHANGES WILL BE LOST! # This template will set all of the auditd configurations via a handler in the role in one task instead of individually diff --git a/templates/etc/cron.d/aide.cron.j2 b/templates/etc/cron.d/aide.cron.j2 index db93323..f9324da 100644 --- a/templates/etc/cron.d/aide.cron.j2 +++ b/templates/etc/cron.d/aide.cron.j2 @@ -1,7 +1,7 @@ # Run AIDE integrity check ## Ansible controlled file # Added as part of ansible-lockdown CIS baseline -# provided by MindPointGroup LLC +# provided by Mindpoint Group - A Tyto Athene Company / Ansible Lockdown ### YOUR CHANGES WILL BE LOST! # CIS 1.3.2 diff --git a/templates/etc/dconf/db/00-automount_lock.j2 b/templates/etc/dconf/db/00-automount_lock.j2 index efebeac..45989d0 100644 --- a/templates/etc/dconf/db/00-automount_lock.j2 +++ b/templates/etc/dconf/db/00-automount_lock.j2 @@ -1,6 +1,6 @@ ## Ansible controlled file # Added as part of ansible-lockdown CIS baseline -# provided by MindPointGroup LLC +# provided by Mindpoint Group - A Tyto Athene Company / Ansible Lockdown # Lock desktop media-handling automount setting /org/gnome/desktop/media-handling/automount diff --git a/templates/etc/dconf/db/00-autorun_lock.j2 b/templates/etc/dconf/db/00-autorun_lock.j2 index 4506f4f..60265c4 100644 --- a/templates/etc/dconf/db/00-autorun_lock.j2 +++ b/templates/etc/dconf/db/00-autorun_lock.j2 @@ -1,6 +1,6 @@ ## Ansible controlled file # Added as part of ansible-lockdown CIS baseline -# provided by MindPointGroup LLC +# provided by Mindpoint Group - A Tyto Athene Company / Ansible Lockdown # Lock desktop media-handling settings /org/gnome/desktop/media-handling/autorun-never diff --git a/templates/etc/dconf/db/00-media-automount.j2 b/templates/etc/dconf/db/00-media-automount.j2 index 78ad883..96c122f 100644 --- a/templates/etc/dconf/db/00-media-automount.j2 +++ b/templates/etc/dconf/db/00-media-automount.j2 @@ -1,6 +1,6 @@ ## Ansible controlled file # Added as part of ansible-lockdown CIS baseline -# provided by MindPointGroup LLC +# provided by Mindpoint Group - A Tyto Athene Company / Ansible Lockdown [org/gnome/desktop/media-handling] automount=false diff --git a/templates/etc/dconf/db/00-media-autorun.j2 b/templates/etc/dconf/db/00-media-autorun.j2 index 81bdfea..0e371af 100644 --- a/templates/etc/dconf/db/00-media-autorun.j2 +++ b/templates/etc/dconf/db/00-media-autorun.j2 @@ -1,6 +1,6 @@ ## Ansible controlled file # Added as part of ansible-lockdown CIS baseline -# provided by MindPointGroup LLC +# provided by Mindpoint Group - A Tyto Athene Company / Ansible Lockdown [org/gnome/desktop/media-handling] autorun-never=true diff --git a/templates/etc/dconf/db/00-screensaver.j2 b/templates/etc/dconf/db/00-screensaver.j2 index acfeaee..95237fb 100644 --- a/templates/etc/dconf/db/00-screensaver.j2 +++ b/templates/etc/dconf/db/00-screensaver.j2 @@ -1,6 +1,6 @@ ## Ansible controlled file # Added as part of ansible-lockdown CIS baseline -# provided by MindPointGroup LLC +# provided by Mindpoint Group - A Tyto Athene Company / Ansible Lockdown # Specify the dconf path [org/gnome/desktop/session] diff --git a/templates/etc/dconf/db/00-screensaver_lock.j2 b/templates/etc/dconf/db/00-screensaver_lock.j2 index d6c5d70..1b99027 100644 --- a/templates/etc/dconf/db/00-screensaver_lock.j2 +++ b/templates/etc/dconf/db/00-screensaver_lock.j2 @@ -1,6 +1,6 @@ ## Ansible controlled file # Added as part of ansible-lockdown CIS baseline -# provided by MindPointGroup LLC +# provided by Mindpoint Group - A Tyto Athene Company / Ansible Lockdown # Lock desktop screensaver idle-delay setting /org/gnome/desktop/session/idle-delay diff --git a/templates/etc/dconf/db/gdm.d/01-banner-message.j2 b/templates/etc/dconf/db/gdm.d/01-banner-message.j2 index c7ae76e..da31670 100644 --- a/templates/etc/dconf/db/gdm.d/01-banner-message.j2 +++ b/templates/etc/dconf/db/gdm.d/01-banner-message.j2 @@ -1,6 +1,6 @@ ## Ansible controlled file # Added as part of ansible-lockdown CIS baseline -# provided by MindPointGroup LLC +# provided by Mindpoint Group - A Tyto Athene Company / Ansible Lockdown [org/gnome/login-screen] banner-message-enable=true From 2827c752ac821b01eab3836caeed00be839c85ac Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Tue, 10 Dec 2024 16:45:49 +0000 Subject: [PATCH 05/22] aide variablizing Signed-off-by: Mark Bolwell --- defaults/main.yml | 13 ++++++++++-- tasks/section_6/cis_6.1.x.yml | 37 ++++++++++++++++++++++++++++++----- vars/main.yml | 12 ++++++++++++ 3 files changed, 55 insertions(+), 7 deletions(-) diff --git a/defaults/main.yml b/defaults/main.yml index e210596..32bb5af 100644 --- a/defaults/main.yml +++ b/defaults/main.yml @@ -1034,8 +1034,7 @@ min_int_uid: 1000 max_int_uid: 65533 ## Section6 vars - -## Control 6.1.1 - allow aide to be configured +## Control 6.1.x - allow aide to be configured # AIDE is a file integrity checking tool, similar in nature to Tripwire. # While it cannot prevent intrusions, it can detect unauthorized changes # to configuration files by alerting when the files are changed. Review @@ -1043,6 +1042,16 @@ max_int_uid: 65533 # By setting this variable to `true`, all of the settings related to AIDE will be applied! rhel9cis_config_aide: true +# If DB file older than below will automatically rebuild DB +# e.g. options:1w = 1 week, 1d = 1day 1h = 1 hour +rhel9cis_aide_db_file_age: 1w + +# If aide already setup this forces a new DB to be created +rhel9cis_aide_db_recreate: false + +# allows to change db file, not config need to be adjusted too +rhel9cis_aide_db_file: /var/lib/aide/aide.db + ## Control 6.1.2 AIDE cron settings ## How the aide schedule is run either cron or timer diff --git a/tasks/section_6/cis_6.1.x.yml b/tasks/section_6/cis_6.1.x.yml index 898444f..950ca5e 100644 --- a/tasks/section_6/cis_6.1.x.yml +++ b/tasks/section_6/cis_6.1.x.yml @@ -12,17 +12,44 @@ - rule_6.1.1 - NIST800-53R5_AU-2 block: + block: - name: "6.1.1 | PATCH | Ensure AIDE is installed" + when: + - "'aide' not in ansible_facts.packages or + 'aide-common' not in ansible_facts.packages" ansible.builtin.package: - name: aide + name: ['aide', 'aide-common'] state: present - register: discovered_aide_installed + update_cache: true + register: discovered_aide_pkg_added - - name: "6.1.1 | PATCH | Ensure AIDE is installed| Build AIDE DB" - when: discovered_aide_installed.changed # noqa: no-handler + - name: "6.1.1 | PATCH | Ensure AIDE is installed | Recapture packages" + when: discovered_aide_pkg_added.skipped is not defined + ansible.builtin.package_facts: + manager: auto + + - name: "6.1.1 | AUDIT | Ensure AIDE is installed | Check file exists" + ansible.builtin.stat: + path: "{{ rhel9cis_aide_db_file }}" + register: discovered_aide_db_file + + - name: "6.1.1 | AUDIT | Ensure AIDE is installed | Check current db file age" + when: discovered_aide_db_file.stat.exists + ansible.builtin.find: + path: "{{ rhel9cis_aide_db_file | dirname }}" + pattern: "{{ rhel9cis_aide_db_file | basename }}" + age: "{{ rhel9cis_aide_db_file_age }}" + register: discovered_aide_db_age + + - name: "6.1.1 | PATCH | Ensure AIDE is installed | Configure AIDE" + when: + - not ansible_check_mode + - not discovered_aide_db_file.stat.exists or + (discovered_aide_db_age.files | length > 0) or + rhel9cis_aide_db_recreate block: - name: "6.1.1 | PATCH | Ensure AIDE is installed| Build AIDE DB" - ansible.builtin.shell: /usr/sbin/aide --init + ansible.builtin.shell: "{{ aide_initiate_command }}" - name: "6.1.1 | PATCH | Ensure AIDE is installed| Build AIDE DB | Wait for file before continuing" ansible.builtin.wait_for: diff --git a/vars/main.yml b/vars/main.yml index ec72d0b..679c5b9 100644 --- a/vars/main.yml +++ b/vars/main.yml @@ -44,3 +44,15 @@ container_vars_file: is_container.yml # rhel9cis is left off the front of this var for consistency in testing pipeline # system_is_ec2 toggle will disable tasks that fail on Amazon EC2 instances. Set true to skip and false to run tasks system_is_ec2: false + +# Aide initiate command for new DB creation +aide_initiate_command: aideinit -y -f + +# Audit vars +audit_bins: + - /sbin/auditctl + - /sbin/aureport + - /sbin/ausearch + - /sbin/autrace + - /sbin/auditd + - /sbin/augenrules From c5278da4e5a382438bd94575c94332c3e1e0c593 Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Tue, 10 Dec 2024 16:46:08 +0000 Subject: [PATCH 06/22] audit binaries variables Signed-off-by: Mark Bolwell --- tasks/section_6/cis_6.3.4.x.yml | 24 +++--------------------- 1 file changed, 3 insertions(+), 21 deletions(-) diff --git a/tasks/section_6/cis_6.3.4.x.yml b/tasks/section_6/cis_6.3.4.x.yml index c89af87..d55b4e8 100644 --- a/tasks/section_6/cis_6.3.4.x.yml +++ b/tasks/section_6/cis_6.3.4.x.yml @@ -105,13 +105,7 @@ ansible.builtin.file: path: "{{ item }}" mode: 'go-w' - loop: - - /sbin/auditctl - - /sbin/aureport - - /sbin/ausearch - - /sbin/autrace - - /sbin/auditd - - /sbin/augenrules + loop: "{{ audit_bins }}" - name: "6.3.4.9 | PATCH | Ensure audit tools owner is configured" when: @@ -126,13 +120,7 @@ path: "{{ item }}" owner: root group: root - loop: - - /sbin/auditctl - - /sbin/aureport - - /sbin/ausearch - - /sbin/autrace - - /sbin/auditd - - /sbin/augenrules + loop: "{{ audit_bins }}" - name: "6.3.4.10 | PATCH | Ensure audit tools group owner is configured" when: @@ -147,10 +135,4 @@ ansible.builtin.file: path: "{{ item }}" group: root - loop: - - /sbin/auditctl - - /sbin/aureport - - /sbin/ausearch - - /sbin/autrace - - /sbin/auditd - - /sbin/augenrules + loop: "{{ audit_bins }}" From a3f8d4fe1fc4276735d967b8526e36efb3eee7f2 Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Tue, 10 Dec 2024 16:46:17 +0000 Subject: [PATCH 07/22] layout update Signed-off-by: Mark Bolwell --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 985dec7..7551cc9 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ ## Configure a RHEL 9 machine to be [CIS](https://www.cisecurity.org/cis-benchmarks/) compliant -### Based on [ CIS RedHat Enterprise Linux 9 Benchmark v2.0.0 ](https://www.cisecurity.org/cis-benchmarks/) +### Based on [CIS RedHat Enterprise Linux 9 Benchmark v2.0.0](https://www.cisecurity.org/cis-benchmarks/) --- From bab28dda4518be1d8bcfdec8d49e26e1a312eacf Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Tue, 10 Dec 2024 17:28:49 +0000 Subject: [PATCH 08/22] Added further aide variable Signed-off-by: Mark Bolwell --- tasks/section_6/cis_6.1.x.yml | 10 +++------- vars/main.yml | 6 +++++- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/tasks/section_6/cis_6.1.x.yml b/tasks/section_6/cis_6.1.x.yml index 950ca5e..f889cd4 100644 --- a/tasks/section_6/cis_6.1.x.yml +++ b/tasks/section_6/cis_6.1.x.yml @@ -12,13 +12,9 @@ - rule_6.1.1 - NIST800-53R5_AU-2 block: - block: - name: "6.1.1 | PATCH | Ensure AIDE is installed" - when: - - "'aide' not in ansible_facts.packages or - 'aide-common' not in ansible_facts.packages" ansible.builtin.package: - name: ['aide', 'aide-common'] + name: "{{ aide_packages }}" state: present update_cache: true register: discovered_aide_pkg_added @@ -48,10 +44,10 @@ (discovered_aide_db_age.files | length > 0) or rhel9cis_aide_db_recreate block: - - name: "6.1.1 | PATCH | Ensure AIDE is installed| Build AIDE DB" + - name: "6.1.1 | PATCH | Ensure AIDE is installed | Build AIDE DB" ansible.builtin.shell: "{{ aide_initiate_command }}" - - name: "6.1.1 | PATCH | Ensure AIDE is installed| Build AIDE DB | Wait for file before continuing" + - name: "6.1.1 | PATCH | Ensure AIDE is installed | Build AIDE DB | Wait for file before continuing" ansible.builtin.wait_for: path: /var/lib/aide/aide.db.new.gz diff --git a/vars/main.yml b/vars/main.yml index 679c5b9..93439ad 100644 --- a/vars/main.yml +++ b/vars/main.yml @@ -45,8 +45,12 @@ container_vars_file: is_container.yml # system_is_ec2 toggle will disable tasks that fail on Amazon EC2 instances. Set true to skip and false to run tasks system_is_ec2: false +# Aide Packages + +aide_packages: + - aide # Aide initiate command for new DB creation -aide_initiate_command: aideinit -y -f +aide_initiate_command: /usr/sbin/aide --init # Audit vars audit_bins: From fd97459b6a7b9c194406880e6b07af5065fad464 Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Tue, 10 Dec 2024 17:29:27 +0000 Subject: [PATCH 09/22] Updated mountpoints controls Signed-off-by: Mark Bolwell --- defaults/main.yml | 5 + handlers/main.yml | 148 +++++++++++++++++++++++++++++- tasks/prelim.yml | 29 +++++- tasks/section_1/cis_1.1.2.1.x.yml | 118 ++++++++++++++++-------- tasks/section_1/cis_1.1.2.2.x.yml | 96 +++++++++++++------ tasks/section_1/cis_1.1.2.3.x.yml | 82 +++++++++++------ tasks/section_1/cis_1.1.2.4.x.yml | 77 ++++++++++------ tasks/section_1/cis_1.1.2.5.x.yml | 97 ++++++++++++++------ tasks/section_1/cis_1.1.2.6.x.yml | 95 +++++++++++++------ tasks/section_1/cis_1.1.2.7.x.yml | 95 +++++++++++++------ 10 files changed, 628 insertions(+), 214 deletions(-) diff --git a/defaults/main.yml b/defaults/main.yml index 32bb5af..816eb11 100644 --- a/defaults/main.yml +++ b/defaults/main.yml @@ -495,6 +495,11 @@ rhel9cis_rule_7_2_9: true ## Section 1 vars +## Ability to enabe debug on mounts to assist in troubleshooting +# Mount point changes are set based upon facts created in Prelim +# these then build the variable and options that is passed to the handler to set the mount point for the controls in section1. +rhel9cis_debug_mount_data: false + ## Control 1.1.2 # If set to `true`, rule will be implemented using the `tmp.mount` systemd-service, # otherwise fstab configuration will be used. diff --git a/handlers/main.yml b/handlers/main.yml index d7f49d9..96cc86e 100644 --- a/handlers/main.yml +++ b/handlers/main.yml @@ -1,6 +1,149 @@ --- # handlers file for RHEL9-CIS +- name: "Adding options for /tmp" + when: not rhel9cis_tmp_svc + vars: + mount_point: '/tmp' + ansible.posix.mount: + path: "{{ mount_point }}" + src: "{{ mount_point_fs_and_options[mount_point]['src'] }}" + state: present + fstype: "{{ mount_point_fs_and_options[mount_point]['fs_type'] }}" + opts: "{{ mount_point_fs_and_options[mount_point]['options'] | unique | join(',') }}" + listen: "Remount /tmp" + +- name: "Remounting /tmp" + vars: + mount_point: '/tmp' + ansible.posix.mount: + path: "{{ mount_point }}" + state: remounted + listen: "Remount /tmp" + +- name: "Remounting /tmp systemd" + vars: + mount_point: '/tmp' + ansible.builtin.systemd: + name: tmp.mount + state: restarted + daemon_reload: true + listen: "Remount /tmp" + +- name: "Adding options for /dev/shm" + vars: + mount_point: '/dev/shm' + ansible.posix.mount: + path: "{{ mount_point }}" + src: "{{ mount_point_fs_and_options[mount_point]['src'] }}" + state: present + fstype: "{{ mount_point_fs_and_options[mount_point]['fs_type'] }}" + opts: "{{ mount_point_fs_and_options[mount_point]['options'] | unique | join(',') }}" + listen: "Remount /dev/shm" + +- name: "Remounting /dev/shm" + vars: + mount_point: '/dev/shm' + ansible.posix.mount: + path: "{{ mount_point }}" + state: remounted + listen: "Remount /dev/shm" + +- name: "Adding options for /home" + vars: + mount_point: '/home' + ansible.posix.mount: + path: "{{ mount_point }}" + src: "{{ mount_point_fs_and_options[mount_point]['src'] }}" + state: present + fstype: "{{ mount_point_fs_and_options[mount_point]['fs_type'] }}" + opts: "{{ mount_point_fs_and_options[mount_point]['options'] | unique | join(',') }}" + listen: "Remount /home" + +- name: "Remounting /home" + vars: + mount_point: '/home' + ansible.posix.mount: + path: "{{ mount_point }}" + state: remounted + listen: "Remount /home" + +- name: "Adding options for /var" + vars: + mount_point: '/var' + ansible.posix.mount: + path: "{{ mount_point }}" + src: "{{ mount_point_fs_and_options[mount_point]['src'] }}" + state: present + fstype: "{{ mount_point_fs_and_options[mount_point]['fs_type'] }}" + opts: "{{ mount_point_fs_and_options[mount_point]['options'] | unique | join(',') }}" + listen: "Remount /var" + +- name: "Remounting /var" + vars: + mount_point: '/var' + ansible.posix.mount: + path: "{{ mount_point }}" + state: remounted + listen: "Remount /var" + +- name: "Adding options for /var/tmp" + vars: + mount_point: '/var/tmp' + ansible.posix.mount: + path: "{{ mount_point }}" + src: "{{ mount_point_fs_and_options[mount_point]['src'] }}" + state: present + fstype: "{{ mount_point_fs_and_options[mount_point]['fs_type'] }}" + opts: "{{ mount_point_fs_and_options[mount_point]['options'] | unique | join(',') }}" + listen: "Remount /var/tmp" + +- name: "Remounting /var/tmp" + vars: + mount_point: '/var/tmp' + ansible.posix.mount: + path: "{{ mount_point }}" + state: remounted + listen: "Remount /var/tmp" + +- name: "Adding options for /var/log" + vars: + mount_point: '/var/log' + ansible.posix.mount: + path: "{{ mount_point }}" + src: "{{ mount_point_fs_and_options[mount_point]['src'] }}" + state: present + fstype: "{{ mount_point_fs_and_options[mount_point]['fs_type'] }}" + opts: "{{ mount_point_fs_and_options[mount_point]['options'] | unique | join(',') }}" + listen: "Remount /var/log" + +- name: "Remounting /var/log" + vars: + mount_point: '/var/log' + ansible.posix.mount: + path: "{{ mount_point }}" + state: remounted + listen: "Remount /var/log" + +- name: "Adding options for /var/log/audit" + vars: + mount_point: '/var/log/audit' + ansible.posix.mount: + path: "{{ mount_point }}" + src: "{{ mount_point_fs_and_options[mount_point]['src'] }}" + state: present + fstype: "{{ mount_point_fs_and_options[mount_point]['fs_type'] }}" + opts: "{{ mount_point_fs_and_options[mount_point]['options'] | unique | join(',') }}" + listen: "Remount /var/log/audit" + +- name: "Remounting /var/log/audit" + vars: + mount_point: '/var/log/audit' + ansible.posix.mount: + path: "{{ mount_point }}" + state: remounted + listen: "Remount /var/log/audit" + - name: Reload sysctl ansible.builtin.shell: sysctl --system @@ -31,11 +174,6 @@ masked: false state: reloaded -- name: Remount tmp - ansible.posix.mount: - path: /tmp - state: remounted - - name: Update Crypto Policy ansible.builtin.set_fact: rhel9cis_full_crypto_policy: "{{ rhel9cis_crypto_policy }}{% if rhel9cis_crypto_policy_module | length > 0 %}{{ rhel9cis_crypto_policy_module }}{% endif %}" diff --git a/tasks/prelim.yml b/tasks/prelim.yml index 28292fb..36c70c8 100644 --- a/tasks/prelim.yml +++ b/tasks/prelim.yml @@ -58,12 +58,35 @@ name: python3-libselinux state: present -- name: "PRELIM | AUDIT | Section 1.1 | Create list of mount points" - tags: - - Always +- name: PRELIM | AUDIT | Section 1.1 | Create list of mount points + tags: always ansible.builtin.set_fact: mount_names: "{{ ansible_facts.mounts | map(attribute='mount') | list }}" +- name: PRELIM | AUDIT | Section 1.1 | Retrieve mount options + tags: always + block: + - name: PRELIM | AUDIT | Section 1.1 | Retrieve mount options - call mount # noqa command-instead-of-module + ansible.builtin.shell: | + mount | awk '{print $1, $3, $5, $6}' + changed_when: false + register: mount_output + + - name: PRELIM | AUDIT | Section 1.1 | Retrieve mount options - build fact + ansible.builtin.set_fact: + mount_point_fs_and_options: >- + {%- set mount_point_fs_and_options = {} -%} + {%- for line in mount_output.stdout_lines -%} + {%- set fields = line.split() -%} + {%- set _ = mount_point_fs_and_options.update({fields[1]: {'src': fields[0], 'fs_type': fields[2], 'original_options': fields[3][1:-1].split(','), 'options': fields[3][1:-1].split(',')}}) -%} + {%- endfor -%} + {{ mount_point_fs_and_options }} + + - name: "PRELIM | AUDIT | Debug of mount variables to assist in troubleshooting" + when: rhel9cis_debug_mount_data + ansible.builtin.debug: + msg: "{{ mount_point_fs_and_options }}" + - name: "PRELIM | PATCH | Update to latest gpg keys" when: - rhel9cis_rule_1_2_1_1 diff --git a/tasks/section_1/cis_1.1.2.1.x.yml b/tasks/section_1/cis_1.1.2.1.x.yml index 5683cde..a2adce0 100644 --- a/tasks/section_1/cis_1.1.2.1.x.yml +++ b/tasks/section_1/cis_1.1.2.1.x.yml @@ -12,62 +12,104 @@ - rule_1.1.2.1.1 - NIST800-53R5_CM-7 vars: - warn_control_id: '1.1.2.1.1' - required_mount: '/tmp' + warn_control_id: "1.1.2.1.1" + required_mount: "/tmp" block: - - name: "1.1.2.1.1 | PATCH | Ensure /tmp is a separate partition | Absent" - ansible.builtin.debug: - msg: "Warning!! {{ required_mount }} doesn't exist. This is a manual task" + - name: "1.1.2.1.1 | AUDIT | Ensure /tmp is a separate partition | check for mount" + ansible.builtin.command: findmnt -kn "{{ required_mount }}" + changed_when: false + failed_when: discovered_tmp_mount.rc not in [ 0, 1 ] + register: discovered_tmp_mount - - name: "1.1.2.1.1 | PATCH | Ensure /tmp is a separate partition | Present" + - name: "1.1.2.1.1 | AUDIT | Ensure /tmp is a separate partition | Absent" + when: discovered_tmp_mount is undefined + ansible.builtin.debug: + msg: "Warning!! {{ required_mount }} is not mounted on a separate partition" + + - name: "1.1.2.1.1 | AUDIT | Ensure /tmp is a separate partition | Present" + when: discovered_tmp_mount is undefined ansible.builtin.import_tasks: file: warning_facts.yml # via fstab -- name: | - "1.1.2.1.2 | PATCH | Ensure nodev option set on /tmp partition" - "1.1.2.1.3 | PATCH | Ensure nosuid option set on /tmp partition" - "1.1.2.1.4 | PATCH | Ensure noexec option set on /tmp partition" - ansible.posix.mount: - name: /tmp - src: "{{ item.device }}" - fstype: "{{ item.fstype }}" - state: present - opts: "{{ item.options }}{% if ('nodev' not in item.options and rhel9cis_rule_1_1_2_1_2) %},nodev{% endif %}{% if ('nosuid' not in item.options and rhel9cis_rule_1_1_2_1_3) %},nosuid{% endif %}{% if ('noexec' not in item.options and rhel9cis_rule_1_1_2_1_4) %},noexec{% endif %}" - notify: Remount tmp - loop: "{{ ansible_facts.mounts }}" - loop_control: - label: "{{ item.device }}" +- name: "1.1.2.1.2 | PATCH | Ensure nodev option set on /tmp partition" when: - - item.mount == "/tmp" + - mount_point_fs_and_options[mount_point] is defined + - not mount_point_fs_and_options[mount_point]['src'] == "tmpfs" + - rhel9cis_rule_1_1_2_1_2 - not rhel9cis_tmp_svc - - rhel9cis_rule_1_1_2_1_2 or - rhel9cis_rule_1_1_2_1_3 or - rhel9cis_rule_1_1_2_1_4 tags: - level1-server - level1-workstation - patch - mounts - rule_1.1.2.1.2 - - rule_1.1.2.1.3 - - rule_1.1.2.1.4 - - NIST800-53R5_CM-7 - NIST800-53R5_AC-3 - NIST800-53R5_MP-2 + vars: + mount_point: "/tmp" + required_option: nodev + notify: &mount_option_notify + - "Remount {{ mount_point }}" + ansible.builtin.set_fact: &mount_option_set_fact + mount_point_fs_and_options: | + {{ mount_point_fs_and_options | combine({mount_point: {'options': (mount_point_fs_and_options[mount_point]['options'] + [required_option])}}, recursive=True) }} + changed_when: &mount_option_changed_when + - required_option not in mount_point_fs_and_options[mount_point]['original_options'] + +- name: "1.1.2.1.3 | PATCH | Ensure nosuid option set on /tmp partition" + when: + - mount_point_fs_and_options[mount_point] is defined + - not mount_point_fs_and_options[mount_point]['src'] == "tmpfs" + - rhel9cis_rule_1_1_2_1_3 + - not rhel9cis_tmp_svc + tags: + - level1-server + - level1-workstation + - patch + - mounts + - rule_1.1.2.1.3 + - NIST800-53R5_AC-3 + - NIST800-53R5_MP-2 + vars: + mount_point: "/tmp" + required_option: nosuid + notify: *mount_option_notify + ansible.builtin.set_fact: + <<: *mount_option_set_fact + changed_when: *mount_option_changed_when + +- name: "1.1.2.1.4 | PATCH | Ensure noexec option set on /tmp partition" + when: + - mount_point_fs_and_options[mount_point] is defined + - not mount_point_fs_and_options[mount_point]['src'] == "tmpfs" + - rhel9cis_rule_1_1_2_1_4 + - not rhel9cis_tmp_svc + tags: + - level1-server + - level1-workstation + - patch + - mounts + - rule_1.1.2.1.4 + - NIST800-53R5_AC-3 + - NIST800-53R5_MP-2 + vars: + mount_point: "/tmp" + required_option: noexec + notify: *mount_option_notify + ansible.builtin.set_fact: + <<: *mount_option_set_fact + changed_when: *mount_option_changed_when # via systemd - name: | - "1.1.2.1.1 | PATCH | Ensure /tmp is configured" - "1.1.2.1.2 | PATCH | Ensure nodev option set on /tmp partition" - "1.1.2.1.3 | PATCH | Ensure noexec option set on /tmp partition" - "1.1.2.1.4 | PATCH | Ensure nosuid option set on /tmp partition" + "1.1.2.1.1 | PATCH | Ensure /tmp is configured + 1.1.2.1.2 | PATCH | Ensure nodev option set on /tmp partition + 1.1.2.1.3 | PATCH | Ensure noexec option set on /tmp partition + 1.1.2.1.4 | PATCH | Ensure nosuid option set on /tmp partition" when: - rhel9cis_tmp_svc - - rhel9cis_rule_1_1_2_1_1 or - rhel9cis_rule_1_1_2_1_2 or - rhel9cis_rule_1_1_2_1_3 or - rhel9cis_rule_1_1_2_1_4 + - rhel9cis_rule_1_1_2_1_1 or rhel9cis_rule_1_1_2_1_2 or rhel9cis_rule_1_1_2_1_3 or rhel9cis_rule_1_1_2_1_4 tags: - level1-server - level1-workstation @@ -79,10 +121,12 @@ - rule_1.1.2.1.4 - NIST800-53R5_AC-3 - NIST800-53R5_MP-2 + vars: + mount_point: "/tmp" ansible.builtin.template: src: etc/systemd/system/tmp.mount.j2 dest: /etc/systemd/system/tmp.mount owner: root group: root - mode: '0644' - notify: Systemd restart tmp.mount + mode: "go-wx" + notify: *mount_option_notify diff --git a/tasks/section_1/cis_1.1.2.2.x.yml b/tasks/section_1/cis_1.1.2.2.x.yml index eb82773..a2af00d 100644 --- a/tasks/section_1/cis_1.1.2.2.x.yml +++ b/tasks/section_1/cis_1.1.2.2.x.yml @@ -1,9 +1,9 @@ --- -# Skips if mount is absent -- name: "1.1.2.2.1 | AUDIT | Ensure /dev/shm is a separate partition" +- name: "1.1.2.2.1 | PATCH | Ensure /dev/shm is a separate partition" when: - rhel9cis_rule_1_1_2_2_1 + - required_mount not in mount_names tags: - level1-server - level1-workstation @@ -12,46 +12,84 @@ - rule_1.1.2.2.1 - NIST800-53R5_CM-7 vars: - warn_control_id: '1.1.2.2.1' + warn_control_id: "1.1.2.2.1" + required_mount: "/dev/shm" block: - - name: "1.1.2.2.1 | AUDIT | Ensure /dev/shm is a separate partition | check exists" - ansible.builtin.shell: mount -l | grep -w /dev/shm + - name: "1.1.2.2.1 | AUDIT | Ensure /dev/shm is a separate partition | check for mount" + ansible.builtin.command: findmnt -kn "{{ required_mount }}" changed_when: false - register: discovered_dev_shm_mount_check + failed_when: discovered_dev_shm_mount.rc not in [ 0, 1 ] + register: discovered_dev_shm_mount - - name: "1.1.2.2.1 | AUDIT | Ensure /dev/shm is a separate partition" - when: discovered_dev_shm_mount_check.rc == 1 - block: - - name: "1.1.2.2.1 | AUDIT | Ensure /dev/shm is a separate partition | Absent" - ansible.builtin.debug: - msg: "Warning!! {{ required_mount }} doesn't exist. This is a manual task" + - name: "1.1.2.2.1 | AUDIT | Ensure /dev/shm is a separate partition | Absent" + when: discovered_dev_shm_mount is undefined + ansible.builtin.debug: + msg: "Warning!! {{ required_mount }} is not mounted on a separate partition" - - name: "1.1.2.2.1 | AUDIT | Ensure separate partition exists for /home | Present" - ansible.builtin.import_tasks: - file: warning_facts.yml + - name: "1.1.2.2.1 | AUDIT | Ensure /dev/shm is a separate partition | Present" + when: discovered_dev_shm_mount is undefined + ansible.builtin.import_tasks: + file: warning_facts.yml -- name: | - "1.1.2.2.2 | PATCH | Ensure nodev option set on /dev/shm partition - 1.1.2.2.3 | PATCH | Ensure nosuid option set on /dev/shm partition - 1.1.2.2.4 | PATCH | Ensure noexec option set on /dev/shm partition" +- name: "1.1.2.2.2 | PATCH | Ensure nodev option set on /dev/shm partition" when: - - rhel9cis_rule_1_1_2_2_2 or - rhel9cis_rule_1_1_2_2_3 or - rhel9cis_rule_1_1_2_2_4 + - mount_point_fs_and_options[mount_point] is defined + - rhel9cis_rule_1_1_2_2_2 tags: - level1-server - level1-workstation - patch - mounts - rule_1.1.2.2.2 + - NIST800-53R5_AC-3 + - NIST800-53R5_MP-2 + vars: + mount_point: "/dev/shm" + required_option: nodev + notify: &mount_option_notify + - "Remount {{ mount_point }}" + ansible.builtin.set_fact: &mount_option_set_fact + mount_point_fs_and_options: | + {{ mount_point_fs_and_options | combine({mount_point: {'options': (mount_point_fs_and_options[mount_point]['options'] + [required_option])}}, recursive=True) }} + changed_when: &mount_option_changed_when + - required_option not in mount_point_fs_and_options[mount_point]['original_options'] + +- name: "1.1.2.2.3 | PATCH | Ensure nosuid option set on /dev/shm partition" + when: + - mount_point_fs_and_options[mount_point] is defined + - rhel9cis_rule_1_1_2_2_3 + tags: + - level1-server + - level1-workstation + - patch + - mounts - rule_1.1.2.2.3 + - NIST800-53R5_AC-3 + - NIST800-53R5_MP-2 + vars: + mount_point: "/dev/shm" + required_option: nosuid + notify: *mount_option_notify + ansible.builtin.set_fact: + <<: *mount_option_set_fact + changed_when: *mount_option_changed_when + +- name: "1.1.2.2.4 | PATCH | Ensure noexec option set on /dev/shm partition" + when: + - mount_point_fs_and_options[mount_point] is defined + - rhel9cis_rule_1_1_2_2_4 + tags: + - level1-server + - level1-workstation + - patch + - mounts - rule_1.1.2.2.4 - NIST800-53R5_AC-3 - NIST800-53R5_MP-2 - ansible.posix.mount: - name: /dev/shm - src: tmpfs - fstype: tmpfs - state: mounted - opts: defaults,{% if rhel9cis_rule_1_1_2_2_2 %}nodev,{% endif %}{% if rhel9cis_rule_1_1_2_2_3 %}nosuid,{% endif %}{% if rhel9cis_rule_1_1_2_2_4 %}noexec{% endif %} - notify: Change_requires_reboot + vars: + mount_point: "/dev/shm" + required_option: noexec + notify: *mount_option_notify + ansible.builtin.set_fact: + <<: *mount_option_set_fact + changed_when: *mount_option_changed_when diff --git a/tasks/section_1/cis_1.1.2.3.x.yml b/tasks/section_1/cis_1.1.2.3.x.yml index c7920cd..224bf38 100644 --- a/tasks/section_1/cis_1.1.2.3.x.yml +++ b/tasks/section_1/cis_1.1.2.3.x.yml @@ -1,52 +1,74 @@ --- - -- name: "1.1.2.3.1 | AUDIT | Ensure separate partition exists for /home" +- name: "1.1.2.3.1 | PATCH | Ensure /home is a separate partition" when: - - required_mount not in mount_names - rhel9cis_rule_1_1_2_3_1 + - required_mount not in mount_names tags: - - level2-server - - level2-workstation + - level1-server + - level1-workstation - audit - mounts - - rule_1_1_2.3.1 + - rule_1.1.2.3.1 - NIST800-53R5_CM-7 vars: - warn_control_id: '1.1.2.3.1' - required_mount: '/home' + warn_control_id: "1.1.2.3.1" + required_mount: "/home" block: - - name: "1.1.2.3.1 | AUDIT | Ensure separate partition exists for /home | Absent" - ansible.builtin.debug: - msg: "Warning!! {{ required_mount }} doesn't exist. This is a manual task" + - name: "1.1.2.3.1 | AUDIT | Ensure /home is a separate partition | check for mount" + ansible.builtin.command: findmnt -kn "{{ required_mount }}" + changed_when: false + failed_when: discovered_home_mount.rc not in [ 0, 1 ] + register: discovered_home_mount - - name: "1.1.2.3.1 | AUDIT | Ensure separate partition exists for /home | Present" + - name: "1.1.2.3.1 | AUDIT | Ensure /home is a separate partition | Absent" + when: discovered_dev_shm_mount is undefined + ansible.builtin.debug: + msg: "Warning!! {{ required_mount }} is not mounted on a separate partition" + + - name: "1.1.2.3.1 | AUDIT | Ensure /home is a separate partition | Present" + when: discovered_dev_shm_mount is undefined ansible.builtin.import_tasks: file: warning_facts.yml -- name: | - "1.1.2.3.2 | PATCH | Ensure nodev option set on /home partition - 1.1.2.3.3 | PATCH | Ensure nosuid option set on /home partition" +- name: "1.1.2.3.2 | PATCH | Ensure nodev option set on /home partition" when: - - item.mount == "/home" - - rhel9cis_rule_1_1_2_3_2 or - rhel9cis_rule_1_1_2_3_3 + - mount_point_fs_and_options[mount_point] is defined + - rhel9cis_rule_1_1_2_3_2 tags: - level1-server - level1-workstation - patch - mounts - rule_1.1.2.3.2 - - rule_1.1.2.3.3 - - NIST800-53R5_CM-7 - NIST800-53R5_AC-3 - NIST800-53R5_MP-2 - ansible.posix.mount: - name: /home - src: "{{ item.device }}" - fstype: "{{ item.fstype }}" - state: present - opts: "{{ item.options }}{% if ('nodev' not in item.options and rhel9cis_rule_1_1_2_3_2) %},nodev{% endif %}{% if ('nosuid' not in item.options and rhel9cis_rule_1_1_2_3_3) %},nosuid{% endif %}" - loop: "{{ ansible_facts.mounts }}" - loop_control: - label: "{{ item.device }}" - notify: Change_requires_reboot + vars: + mount_point: "/home" + required_option: nodev + notify: &mount_option_notify + - "Remount {{ mount_point }}" + ansible.builtin.set_fact: &mount_option_set_fact + mount_point_fs_and_options: | + {{ mount_point_fs_and_options | combine({mount_point: {'options': (mount_point_fs_and_options[mount_point]['options'] + [required_option])}}, recursive=True) }} + changed_when: &mount_option_changed_when + - required_option not in mount_point_fs_and_options[mount_point]['original_options'] + +- name: "1.1.2.3.3 | PATCH | Ensure nosuid option set on /home partition" + when: + - mount_point_fs_and_options[mount_point] is defined + - rhel9cis_rule_1_1_2_3_3 + tags: + - level1-server + - level1-workstation + - patch + - mounts + - rule_1.1.2.3.3 + - NIST800-53R5_AC-3 + - NIST800-53R5_MP-2 + vars: + mount_point: "/home" + required_option: nosuid + notify: *mount_option_notify + ansible.builtin.set_fact: + <<: *mount_option_set_fact + changed_when: *mount_option_changed_when diff --git a/tasks/section_1/cis_1.1.2.4.x.yml b/tasks/section_1/cis_1.1.2.4.x.yml index 0aa4fa2..3a3aabf 100644 --- a/tasks/section_1/cis_1.1.2.4.x.yml +++ b/tasks/section_1/cis_1.1.2.4.x.yml @@ -1,52 +1,75 @@ --- -- name: "1.1.2.4.1 | AUDIT | Ensure separate partition exists for /var" +- name: "1.1.2.4.1 | PATCH | Ensure /var is a separate partition" when: - - required_mount not in mount_names - rhel9cis_rule_1_1_2_4_1 + - required_mount not in mount_names tags: - - level2-server - - level2-workstation - - patch + - level1-server + - level1-workstation + - audit - mounts - - rule_1_1_2.4.1 + - rule_1.1.2.4.1 - NIST800-53R5_CM-7 vars: warn_control_id: '1.1.2.4.1' required_mount: '/var' block: - - name: "1.1.2.4.1 | AUDIT | Ensure separate partition exists for /var | Absent" - ansible.builtin.debug: - msg: "Warning!! {{ required_mount }} doesn't exist. This is a manual task" + - name: "1.1.2.4.1 | AUDIT | Ensure /var is a separate partition | check for mount" + ansible.builtin.command: findmnt -kn "{{ required_mount }}" + changed_when: false + failed_when: discovered_var_mount.rc not in [ 0, 1 ] + register: discovered_var_mount - - name: "1.1.2.4.1 | AUDIT | Ensure separate partition exists for /var | Present" + - name: "1.1.2.4.1 | AUDIT | Ensure /var is a separate partition | Absent" + when: discovered_dev_shm_mount is undefined + ansible.builtin.debug: + msg: "Warning!! {{ required_mount }} is not mounted on a separate partition" + + - name: "1.1.2.4.1 | AUDIT | Ensure /var is a separate partition | Present" + when: discovered_dev_shm_mount is undefined ansible.builtin.import_tasks: file: warning_facts.yml -# skips if mount is absent -- name: | - "1.1.2.4.2 | PATCH | Ensure nodev option set on /var partition - 1.1.2.4.3 | PATCH | Ensure nosuid option set on /var partition" +- name: "1.1.2.4.2 | PATCH | Ensure nodev option set on /var partition" when: - - item.mount == "/var" - - rhel9cis_rule_1_1_2_4_2 or - rhel9cis_rule_1_1_2_4_3 + - mount_point_fs_and_options[mount_point] is defined + - rhel9cis_rule_1_1_2_4_2 tags: - level1-server - level1-workstation - patch - mounts - rule_1.1.2.4.2 + - NIST800-53R5_AC-3 + - NIST800-53R5_MP-2 + vars: + mount_point: "/var" + required_option: nodev + notify: &mount_option_notify + - "Remount {{ mount_point }}" + ansible.builtin.set_fact: &mount_option_set_fact + mount_point_fs_and_options: | + {{ mount_point_fs_and_options | combine({mount_point: {'options': (mount_point_fs_and_options[mount_point]['options'] + [required_option])}}, recursive=True) }} + changed_when: &mount_option_changed_when + - required_option not in mount_point_fs_and_options[mount_point]['original_options'] + +- name: "1.1.2.4.3 | PATCH | Ensure nosuid option set on /var partition" + when: + - mount_point_fs_and_options[mount_point] is defined + - rhel9cis_rule_1_1_2_4_3 + tags: + - level1-server + - level1-workstation + - patch + - mounts - rule_1.1.2.4.3 - NIST800-53R5_AC-3 - NIST800-53R5_MP-2 - ansible.posix.mount: - name: /var - src: "{{ item.device }}" - fstype: "{{ item.fstype }}" - state: present - opts: "{{ item.options }}{% if ('nodev' not in item.options and rhel9cis_rule_1_1_2_4_2) %},nodev{% endif %}{% if ('nosuid' not in item.options and rhel9cis_rule_1_1_2_4_2) %},nosuid{% endif %}" - loop: "{{ ansible_facts.mounts }}" - loop_control: - label: "{{ item.device }}" - notify: Change_requires_reboot + vars: + mount_point: "/var" + required_option: nosuid + notify: *mount_option_notify + ansible.builtin.set_fact: + <<: *mount_option_set_fact + changed_when: *mount_option_changed_when diff --git a/tasks/section_1/cis_1.1.2.5.x.yml b/tasks/section_1/cis_1.1.2.5.x.yml index 449bc8b..2706d4b 100644 --- a/tasks/section_1/cis_1.1.2.5.x.yml +++ b/tasks/section_1/cis_1.1.2.5.x.yml @@ -1,56 +1,95 @@ --- -# Skips if mount is absent -- name: "1.1.2.5.1 | AUDIT | Ensure separate partition exists for /var/tmp" +- name: "1.1.2.5.1 | PATCH | Ensure /var/tmp is a separate partition" when: - - required_mount not in mount_names - rhel9cis_rule_1_1_2_5_1 + - required_mount not in mount_names tags: - - level2-server - - level2-workstation + - level1-server + - level1-workstation - audit - mounts - - rule_1_1_2.5.1 + - rule_1.1.2.5.1 - NIST800-53R5_CM-7 vars: warn_control_id: '1.1.2.5.1' required_mount: '/var/tmp' block: - - name: "1.1.2.5.1 | AUDIT | Ensure separate partition exists for /var/tmp | Absent" - ansible.builtin.debug: - msg: "Warning!! {{ required_mount }} doesn't exist. This is a manual task" + - name: "1.1.2.5.1 | AUDIT | Ensure /var/tmp is a separate partition | check for mount" + ansible.builtin.command: findmnt -kn "{{ required_mount }}" + changed_when: false + failed_when: discovered_var_tmp_mount.rc not in [ 0, 1 ] + register: discovered_var_tmp_mount - - name: "1.1.2.5.1 | AUDIT | Ensure separate partition exists for /var/tmp | Present" + - name: "1.1.2.5.1 | AUDIT | Ensure /var/tmp is a separate partition | Absent" + when: discovered_var_tmp_mount is undefined + ansible.builtin.debug: + msg: "Warning!! {{ required_mount }} is not mounted on a separate partition" + + - name: "1.1.2.5.1 | AUDIT | Ensure /var/tmp is a separate partition | Present" + when: discovered_var_tmp_mount is undefined ansible.builtin.import_tasks: file: warning_facts.yml -# skips if mount is absent -- name: | - "1.1.2.5.2 | PATCH | Ensure nodev option set on /var/tmp partition - 1.1.2.5.3 | PATCH | Ensure nosuid option set on /var/tmp partition - 1.1.2.5.4 | PATCH | Ensure noexec option set on /var/tmp partition" +- name: "1.1.2.5.2 | PATCH | Ensure nodev option set on /var/tmp partition" when: - - item.mount == "/var/tmp" - - rhel9cis_rule_1_1_2_5_2 or - rhel9cis_rule_1_1_2_5_3 or - rhel9cis_rule_1_1_2_5_4 + - mount_point_fs_and_options[mount_point] is defined + - rhel9cis_rule_1_1_2_5_2 tags: - level1-server - level1-workstation - patch - mounts - rule_1.1.2.5.2 + - NIST800-53R5_AC-3 + - NIST800-53R5_MP-2 + vars: + mount_point: "/var/tmp" + required_option: nodev + notify: &mount_option_notify + - "Remount {{ mount_point }}" + ansible.builtin.set_fact: &mount_option_set_fact + mount_point_fs_and_options: | + {{ mount_point_fs_and_options | combine({mount_point: {'options': (mount_point_fs_and_options[mount_point]['options'] + [required_option])}}, recursive=True) }} + changed_when: &mount_option_changed_when + - required_option not in mount_point_fs_and_options[mount_point]['original_options'] + +- name: "1.1.2.5.3 | PATCH | Ensure nosuid option set on /var/tmp partition" + when: + - mount_point_fs_and_options[mount_point] is defined + - rhel9cis_rule_1_1_2_5_3 + tags: + - level1-server + - level1-workstation + - patch + - mounts - rule_1.1.2.5.3 + - NIST800-53R5_AC-3 + - NIST800-53R5_MP-2 + vars: + mount_point: "/var/tmp" + required_option: nosuid + notify: *mount_option_notify + ansible.builtin.set_fact: + <<: *mount_option_set_fact + changed_when: *mount_option_changed_when + +- name: "1.1.2.5.4 | PATCH | Ensure noexec option set on /var/tmp partition" + when: + - mount_point_fs_and_options[mount_point] is defined + - rhel9cis_rule_1_1_2_5_4 + tags: + - level1-server + - level1-workstation + - patch + - mounts - rule_1.1.2.5.4 - NIST800-53R5_AC-3 - NIST800-53R5_MP-2 - ansible.posix.mount: - name: /var/tmp - src: "{{ item.device }}" - fstype: "{{ item.fstype }}" - state: present - opts: "{{ item.options }}{% if ('nodev' not in item.options and rhel9cis_rule_1_1_2_5_2) %},nodev{% endif %}{% if ('nosuid' not in item.options and rhel9cis_rule_1_1_2_5_3) %},nosuid{% endif %}{% if ('noexec' not in item.options and rhel9cis_rule_1_1_2_5_4) %},noexec{% endif %}" - loop: "{{ ansible_facts.mounts }}" - loop_control: - label: "{{ item.device }}" - notify: Change_requires_reboot + vars: + mount_point: "/var/tmp" + required_option: noexec + notify: *mount_option_notify + ansible.builtin.set_fact: + <<: *mount_option_set_fact + changed_when: *mount_option_changed_when diff --git a/tasks/section_1/cis_1.1.2.6.x.yml b/tasks/section_1/cis_1.1.2.6.x.yml index c45da55..77da285 100644 --- a/tasks/section_1/cis_1.1.2.6.x.yml +++ b/tasks/section_1/cis_1.1.2.6.x.yml @@ -1,54 +1,95 @@ --- -- name: "1.1.2.6.1 | AUDIT | Ensure separate partition exists for /var/log" +- name: "1/.1 | PATCH | Ensure /var/log is a separate partition" when: - - required_mount not in mount_names - rhel9cis_rule_1_1_2_6_1 + - required_mount not in mount_names tags: - - level2-server - - level2-workstation + - level1-server + - level1-workstation - audit - mounts - - rule_1_1_2.6.1 + - rule_1.1.2.6.1 - NIST800-53R5_CM-7 vars: warn_control_id: '1.1.2.6.1' required_mount: '/var/log' block: - - name: "1.1.2.6.1 | AUDIT | Ensure separate partition exists for /var/log | Absent" - ansible.builtin.debug: - msg: "Warning!! {{ required_mount }} doesn't exist. This is a manual task" + - name: "1.1.2.6.1 | AUDIT | Ensure /var/log is a separate partition | check for mount" + ansible.builtin.command: findmnt -kn "{{ required_mount }}" + changed_when: false + failed_when: discovered_var_log_mount.rc not in [ 0, 1 ] + register: discovered_var_log_mount - - name: "1.1.2.6.1 | AUDIT | Ensure separate partition exists for /var/log | Present" + - name: "1.1.2.6.1 | AUDIT | Ensure /var/log is a separate partition | Absent" + when: discovered_var_log_mount is undefined + ansible.builtin.debug: + msg: "Warning!! {{ required_mount }} is not mounted on a separate partition" + + - name: "1.1.2.6.1 | AUDIT | Ensure /var/log is a separate partition | Present" + when: discovered_var_log_mount is undefined ansible.builtin.import_tasks: file: warning_facts.yml -- name: | - "1.1.2.6.2 | PATCH | Ensure nodev option set on /var/log partition - 1.1.2.6.3 | PATCH | Ensure nosuid option set on /var/log partition - 1.1.2.6.4 | PATCH | Ensure noexec option set on /var/log partition" +- name: "1.1.2.6.2 | PATCH | Ensure nodev option set on /var/log partition" when: - - item.mount == "/var/log" - - rhel9cis_rule_1_1_2_6_2 or - rhel9cis_rule_1_1_2_6_3 or - rhel9cis_rule_1_1_2_6_4 + - mount_point_fs_and_options[mount_point] is defined + - rhel9cis_rule_1_1_2_6_2 tags: - level1-server - level1-workstation - patch - mounts - rule_1.1.2.6.2 + - NIST800-53R5_AC-3 + - NIST800-53R5_MP-2 + vars: + mount_point: "/var/log" + required_option: nodev + notify: &mount_option_notify + - "Remount {{ mount_point }}" + ansible.builtin.set_fact: &mount_option_set_fact + mount_point_fs_and_options: | + {{ mount_point_fs_and_options | combine({mount_point: {'options': (mount_point_fs_and_options[mount_point]['options'] + [required_option])}}, recursive=True) }} + changed_when: &mount_option_changed_when + - required_option not in mount_point_fs_and_options[mount_point]['original_options'] + +- name: "1.1.2.6.3 | PATCH | Ensure nosuid option set on /var/log partition" + when: + - mount_point_fs_and_options[mount_point] is defined + - rhel9cis_rule_1_1_2_6_3 + tags: + - level1-server + - level1-workstation + - patch + - mounts - rule_1.1.2.6.3 + - NIST800-53R5_AC-3 + - NIST800-53R5_MP-2 + vars: + mount_point: "/var/log" + required_option: nosuid + notify: *mount_option_notify + ansible.builtin.set_fact: + <<: *mount_option_set_fact + changed_when: *mount_option_changed_when + +- name: "1.1.2.6.4 | PATCH | Ensure noexec option set on /var/log partition" + when: + - mount_point_fs_and_options[mount_point] is defined + - rhel9cis_rule_1_1_2_6_4 + tags: + - level1-server + - level1-workstation + - patch + - mounts - rule_1.1.2.6.4 - NIST800-53R5_AC-3 - NIST800-53R5_MP-2 - ansible.posix.mount: - name: /var/log - src: "{{ item.device }}" - fstype: "{{ item.fstype }}" - state: present - opts: "{{ item.options }}{% if ('nodev' not in item.options and rhel9cis_rule_1_1_2_6_2) %},nodev{% endif %}{% if ('nosuid' not in item.options and rhel9cis_rule_1_1_2_6_3) %},nosuid{% endif %}{% if ('noexec' not in item.options and rhel9cis_rule_1_1_2_6_4) %},noexec{% endif %}" - loop: "{{ ansible_facts.mounts }}" - loop_control: - label: "{{ item.device }}" - notify: Change_requires_reboot + vars: + mount_point: "/var/log" + required_option: noexec + notify: *mount_option_notify + ansible.builtin.set_fact: + <<: *mount_option_set_fact + changed_when: *mount_option_changed_when diff --git a/tasks/section_1/cis_1.1.2.7.x.yml b/tasks/section_1/cis_1.1.2.7.x.yml index 4a8f67c..93bcb23 100644 --- a/tasks/section_1/cis_1.1.2.7.x.yml +++ b/tasks/section_1/cis_1.1.2.7.x.yml @@ -1,54 +1,95 @@ --- -- name: "1.1.2.7.1 | AUDIT | Ensure separate partition exists for /var/log/audit" +- name: "1/.1 | PATCH | Ensure /var/log/audit is a separate partition" when: - - required_mount not in mount_names - rhel9cis_rule_1_1_2_7_1 + - required_mount not in mount_names tags: - - level2-server - - level2-workstation + - level1-server + - level1-workstation - audit - mounts - - rule_1_1_2.7.1 + - rule_1.1.2.7.1 - NIST800-53R5_CM-7 vars: warn_control_id: '1.1.2.7.1' required_mount: '/var/log/audit' block: - - name: "1.1.2.7.1 | AUDIT | Ensure separate partition exists for /var/log/audit | Absent" - ansible.builtin.debug: - msg: "Warning!! {{ required_mount }} doesn't exist. This is a manual task" + - name: "1.1.2.7.1 | AUDIT | Ensure /var/log/audit is a separate partition | check for mount" + ansible.builtin.command: findmnt -kn "{{ required_mount }}" + changed_when: false + failed_when: discovered_var_log_audit_mount.rc not in [ 0, 1 ] + register: discovered_var_log_audit_mount - - name: "1.1.2.7.1 | AUDIT | Ensure separate partition exists for /var/log/audit | Present" + - name: "1.1.2.7.1 | AUDIT | Ensure /var/log/audit is a separate partition | Absent" + when: discovered_var_log_audit_mount is undefined + ansible.builtin.debug: + msg: "Warning!! {{ required_mount }} is not mounted on a separate partition" + + - name: "1.1.2.7.1 | AUDIT | Ensure /var/log/audit is a separate partition | Present" + when: discovered_var_log_audit_mount is undefined ansible.builtin.import_tasks: file: warning_facts.yml -- name: | - "1.1.2.7.2 | PATCH | Ensure nodev option set on /var/log/audit partition - 1.1.2.7.3 | PATCH | Ensure nosuid option set on /var/log/audit partition - 1.1.2.7.4 | PATCH | Ensure noexec option set on /var/log/audit partition" +- name: "1.1.2.7.2 | PATCH | Ensure nodev option set on /var/log/audit partition" when: - - item.mount == "/var/log/audit" - - rhel9cis_rule_1_1_2_7_2 or - rhel9cis_rule_1_1_2_7_3 or - rhel9cis_rule_1_1_2_7_4 + - mount_point_fs_and_options[mount_point] is defined + - rhel9cis_rule_1_1_2_7_2 tags: - level1-server - level1-workstation - patch - mounts - rule_1.1.2.7.2 + - NIST800-53R5_AC-3 + - NIST800-53R5_MP-2 + vars: + mount_point: "/var/log/audit" + required_option: nodev + notify: &mount_option_notify + - "Remount {{ mount_point }}" + ansible.builtin.set_fact: &mount_option_set_fact + mount_point_fs_and_options: | + {{ mount_point_fs_and_options | combine({mount_point: {'options': (mount_point_fs_and_options[mount_point]['options'] + [required_option])}}, recursive=True) }} + changed_when: &mount_option_changed_when + - required_option not in mount_point_fs_and_options[mount_point]['original_options'] + +- name: "1.1.2.7.3 | PATCH | Ensure nosuid option set on /var/log/audit partition" + when: + - mount_point_fs_and_options[mount_point] is defined + - rhel9cis_rule_1_1_2_7_3 + tags: + - level1-server + - level1-workstation + - patch + - mounts - rule_1.1.2.7.3 + - NIST800-53R5_AC-3 + - NIST800-53R5_MP-2 + vars: + mount_point: "/var/log/audit" + required_option: nosuid + notify: *mount_option_notify + ansible.builtin.set_fact: + <<: *mount_option_set_fact + changed_when: *mount_option_changed_when + +- name: "1.1.2.7.4 | PATCH | Ensure noexec option set on /var/log/audit partition" + when: + - mount_point_fs_and_options[mount_point] is defined + - rhel9cis_rule_1_1_2_7_4 + tags: + - level1-server + - level1-workstation + - patch + - mounts - rule_1.1.2.7.4 - NIST800-53R5_AC-3 - NIST800-53R5_MP-2 - ansible.posix.mount: - name: /var/log/audit - src: "{{ item.device }}" - fstype: "{{ item.fstype }}" - state: present - opts: "{{ item.options }}{% if ('nodev' not in item.options and rhel9cis_rule_1_1_2_7_2) %},nodev{% endif %}{% if ('nosuid' not in item.options and rhel9cis_rule_1_1_2_7_3) %},nosuid{% endif %}{% if ('noexec' not in item.options and rhel9cis_rule_1_1_2_7_4) %},noexec{% endif %}" - loop: "{{ ansible_facts.mounts }}" - loop_control: - label: "{{ item.device }}" - notify: Change_requires_reboot + vars: + mount_point: "/var/log/audit" + required_option: noexec + notify: *mount_option_notify + ansible.builtin.set_fact: + <<: *mount_option_set_fact + changed_when: *mount_option_changed_when From 7875e1f6b50199d068d1b81ac58291e0344da4eb Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Tue, 10 Dec 2024 17:29:40 +0000 Subject: [PATCH 10/22] udpated output 1.1.1.9 Signed-off-by: Mark Bolwell --- tasks/section_1/cis_1.1.1.x.yml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/tasks/section_1/cis_1.1.1.x.yml b/tasks/section_1/cis_1.1.1.x.yml index fb0f119..bd56bde 100644 --- a/tasks/section_1/cis_1.1.1.x.yml +++ b/tasks/section_1/cis_1.1.1.x.yml @@ -300,9 +300,7 @@ - name: "1.1.1.9 | AUDIT | Ensure unused filesystems kernel modules are not available | Output Warning" when: discovered_fs_modules_loaded.stdout | length > 0 ansible.builtin.debug: - msg: | - "Warning!! Discovered loaded Filesystem modules that need attention. This is a manual task - {{ discovered_fs_modules_loaded.stdout_lines}}" + msg: "{{ ['Warning!! Discovered loaded Filesystem modules that need attention. This is a manual task'] + discovered_fs_modules_loaded.stdout_lines }}" - name: "1.1.1.9 | AUDIT | Ensure unused filesystems kernel modules are not available | Capture Warning" when: discovered_fs_modules_loaded.stdout | length > 0 From d850fc58750627349736d911132eb42856731b1b Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Wed, 11 Dec 2024 10:09:31 +0000 Subject: [PATCH 11/22] Updated mountpoint vars correctly Signed-off-by: Mark Bolwell --- tasks/prelim.yml | 16 ++++++++-------- tasks/section_1/cis_1.1.2.1.x.yml | 20 ++++++++++---------- tasks/section_1/cis_1.1.2.2.x.yml | 14 +++++++------- tasks/section_1/cis_1.1.2.3.x.yml | 12 ++++++------ tasks/section_1/cis_1.1.2.4.x.yml | 12 ++++++------ tasks/section_1/cis_1.1.2.5.x.yml | 14 +++++++------- tasks/section_1/cis_1.1.2.6.x.yml | 14 +++++++------- tasks/section_1/cis_1.1.2.7.x.yml | 14 +++++++------- 8 files changed, 58 insertions(+), 58 deletions(-) diff --git a/tasks/prelim.yml b/tasks/prelim.yml index 36c70c8..7896d58 100644 --- a/tasks/prelim.yml +++ b/tasks/prelim.yml @@ -61,7 +61,7 @@ - name: PRELIM | AUDIT | Section 1.1 | Create list of mount points tags: always ansible.builtin.set_fact: - mount_names: "{{ ansible_facts.mounts | map(attribute='mount') | list }}" + prelim_mount_names: "{{ ansible_facts.mounts | map(attribute='mount') | list }}" - name: PRELIM | AUDIT | Section 1.1 | Retrieve mount options tags: always @@ -70,22 +70,22 @@ ansible.builtin.shell: | mount | awk '{print $1, $3, $5, $6}' changed_when: false - register: mount_output + register: prelim_mount_output - name: PRELIM | AUDIT | Section 1.1 | Retrieve mount options - build fact ansible.builtin.set_fact: - mount_point_fs_and_options: >- - {%- set mount_point_fs_and_options = {} -%} - {%- for line in mount_output.stdout_lines -%} + prelim_mount_point_fs_and_options: >- + {%- set prelim_mount_point_fs_and_options = {} -%} + {%- for line in prelim_mount_output.stdout_lines -%} {%- set fields = line.split() -%} - {%- set _ = mount_point_fs_and_options.update({fields[1]: {'src': fields[0], 'fs_type': fields[2], 'original_options': fields[3][1:-1].split(','), 'options': fields[3][1:-1].split(',')}}) -%} + {%- set _ = prelim_mount_point_fs_and_options.update({fields[1]: {'src': fields[0], 'fs_type': fields[2], 'original_options': fields[3][1:-1].split(','), 'options': fields[3][1:-1].split(',')}}) -%} {%- endfor -%} - {{ mount_point_fs_and_options }} + {{ prelim_mount_point_fs_and_options }} - name: "PRELIM | AUDIT | Debug of mount variables to assist in troubleshooting" when: rhel9cis_debug_mount_data ansible.builtin.debug: - msg: "{{ mount_point_fs_and_options }}" + msg: "{{ prelim_mount_point_fs_and_options }}" - name: "PRELIM | PATCH | Update to latest gpg keys" when: diff --git a/tasks/section_1/cis_1.1.2.1.x.yml b/tasks/section_1/cis_1.1.2.1.x.yml index a2adce0..355c32b 100644 --- a/tasks/section_1/cis_1.1.2.1.x.yml +++ b/tasks/section_1/cis_1.1.2.1.x.yml @@ -2,7 +2,7 @@ - name: "1.1.2.1.1 | PATCH | Ensure /tmp is a separate partition" when: - - required_mount not in mount_names + - required_mount not in prelim_mount_names - rhel9cis_rule_1_1_2_1_1 tags: - level1-server @@ -34,8 +34,8 @@ # via fstab - name: "1.1.2.1.2 | PATCH | Ensure nodev option set on /tmp partition" when: - - mount_point_fs_and_options[mount_point] is defined - - not mount_point_fs_and_options[mount_point]['src'] == "tmpfs" + - prelim_mount_point_fs_and_options[mount_point] is defined + - not prelim_mount_point_fs_and_options[mount_point]['src'] == "tmpfs" - rhel9cis_rule_1_1_2_1_2 - not rhel9cis_tmp_svc tags: @@ -52,15 +52,15 @@ notify: &mount_option_notify - "Remount {{ mount_point }}" ansible.builtin.set_fact: &mount_option_set_fact - mount_point_fs_and_options: | - {{ mount_point_fs_and_options | combine({mount_point: {'options': (mount_point_fs_and_options[mount_point]['options'] + [required_option])}}, recursive=True) }} + prelim_mount_point_fs_and_options: | + {{ prelim_mount_point_fs_and_options | combine({mount_point: {'options': (prelim_mount_point_fs_and_options[mount_point]['options'] + [required_option])}}, recursive=True) }} changed_when: &mount_option_changed_when - - required_option not in mount_point_fs_and_options[mount_point]['original_options'] + - required_option not in prelim_mount_point_fs_and_options[mount_point]['original_options'] - name: "1.1.2.1.3 | PATCH | Ensure nosuid option set on /tmp partition" when: - - mount_point_fs_and_options[mount_point] is defined - - not mount_point_fs_and_options[mount_point]['src'] == "tmpfs" + - prelim_mount_point_fs_and_options[mount_point] is defined + - not prelim_mount_point_fs_and_options[mount_point]['src'] == "tmpfs" - rhel9cis_rule_1_1_2_1_3 - not rhel9cis_tmp_svc tags: @@ -81,8 +81,8 @@ - name: "1.1.2.1.4 | PATCH | Ensure noexec option set on /tmp partition" when: - - mount_point_fs_and_options[mount_point] is defined - - not mount_point_fs_and_options[mount_point]['src'] == "tmpfs" + - prelim_mount_point_fs_and_options[mount_point] is defined + - not prelim_mount_point_fs_and_options[mount_point]['src'] == "tmpfs" - rhel9cis_rule_1_1_2_1_4 - not rhel9cis_tmp_svc tags: diff --git a/tasks/section_1/cis_1.1.2.2.x.yml b/tasks/section_1/cis_1.1.2.2.x.yml index a2af00d..57e92eb 100644 --- a/tasks/section_1/cis_1.1.2.2.x.yml +++ b/tasks/section_1/cis_1.1.2.2.x.yml @@ -3,7 +3,7 @@ - name: "1.1.2.2.1 | PATCH | Ensure /dev/shm is a separate partition" when: - rhel9cis_rule_1_1_2_2_1 - - required_mount not in mount_names + - required_mount not in prelim_mount_names tags: - level1-server - level1-workstation @@ -33,7 +33,7 @@ - name: "1.1.2.2.2 | PATCH | Ensure nodev option set on /dev/shm partition" when: - - mount_point_fs_and_options[mount_point] is defined + - prelim_mount_point_fs_and_options[mount_point] is defined - rhel9cis_rule_1_1_2_2_2 tags: - level1-server @@ -49,14 +49,14 @@ notify: &mount_option_notify - "Remount {{ mount_point }}" ansible.builtin.set_fact: &mount_option_set_fact - mount_point_fs_and_options: | - {{ mount_point_fs_and_options | combine({mount_point: {'options': (mount_point_fs_and_options[mount_point]['options'] + [required_option])}}, recursive=True) }} + prelim_mount_point_fs_and_options: | + {{ prelim_mount_point_fs_and_options | combine({mount_point: {'options': (prelim_mount_point_fs_and_options[mount_point]['options'] + [required_option])}}, recursive=True) }} changed_when: &mount_option_changed_when - - required_option not in mount_point_fs_and_options[mount_point]['original_options'] + - required_option not in prelim_mount_point_fs_and_options[mount_point]['original_options'] - name: "1.1.2.2.3 | PATCH | Ensure nosuid option set on /dev/shm partition" when: - - mount_point_fs_and_options[mount_point] is defined + - prelim_mount_point_fs_and_options[mount_point] is defined - rhel9cis_rule_1_1_2_2_3 tags: - level1-server @@ -76,7 +76,7 @@ - name: "1.1.2.2.4 | PATCH | Ensure noexec option set on /dev/shm partition" when: - - mount_point_fs_and_options[mount_point] is defined + - prelim_mount_point_fs_and_options[mount_point] is defined - rhel9cis_rule_1_1_2_2_4 tags: - level1-server diff --git a/tasks/section_1/cis_1.1.2.3.x.yml b/tasks/section_1/cis_1.1.2.3.x.yml index 224bf38..998d1ba 100644 --- a/tasks/section_1/cis_1.1.2.3.x.yml +++ b/tasks/section_1/cis_1.1.2.3.x.yml @@ -2,7 +2,7 @@ - name: "1.1.2.3.1 | PATCH | Ensure /home is a separate partition" when: - rhel9cis_rule_1_1_2_3_1 - - required_mount not in mount_names + - required_mount not in prelim_mount_names tags: - level1-server - level1-workstation @@ -32,7 +32,7 @@ - name: "1.1.2.3.2 | PATCH | Ensure nodev option set on /home partition" when: - - mount_point_fs_and_options[mount_point] is defined + - prelim_mount_point_fs_and_options[mount_point] is defined - rhel9cis_rule_1_1_2_3_2 tags: - level1-server @@ -48,14 +48,14 @@ notify: &mount_option_notify - "Remount {{ mount_point }}" ansible.builtin.set_fact: &mount_option_set_fact - mount_point_fs_and_options: | - {{ mount_point_fs_and_options | combine({mount_point: {'options': (mount_point_fs_and_options[mount_point]['options'] + [required_option])}}, recursive=True) }} + prelim_mount_point_fs_and_options: | + {{ prelim_mount_point_fs_and_options | combine({mount_point: {'options': (prelim_mount_point_fs_and_options[mount_point]['options'] + [required_option])}}, recursive=True) }} changed_when: &mount_option_changed_when - - required_option not in mount_point_fs_and_options[mount_point]['original_options'] + - required_option not in prelim_mount_point_fs_and_options[mount_point]['original_options'] - name: "1.1.2.3.3 | PATCH | Ensure nosuid option set on /home partition" when: - - mount_point_fs_and_options[mount_point] is defined + - prelim_mount_point_fs_and_options[mount_point] is defined - rhel9cis_rule_1_1_2_3_3 tags: - level1-server diff --git a/tasks/section_1/cis_1.1.2.4.x.yml b/tasks/section_1/cis_1.1.2.4.x.yml index 3a3aabf..e0afd4e 100644 --- a/tasks/section_1/cis_1.1.2.4.x.yml +++ b/tasks/section_1/cis_1.1.2.4.x.yml @@ -3,7 +3,7 @@ - name: "1.1.2.4.1 | PATCH | Ensure /var is a separate partition" when: - rhel9cis_rule_1_1_2_4_1 - - required_mount not in mount_names + - required_mount not in prelim_mount_names tags: - level1-server - level1-workstation @@ -33,7 +33,7 @@ - name: "1.1.2.4.2 | PATCH | Ensure nodev option set on /var partition" when: - - mount_point_fs_and_options[mount_point] is defined + - prelim_mount_point_fs_and_options[mount_point] is defined - rhel9cis_rule_1_1_2_4_2 tags: - level1-server @@ -49,14 +49,14 @@ notify: &mount_option_notify - "Remount {{ mount_point }}" ansible.builtin.set_fact: &mount_option_set_fact - mount_point_fs_and_options: | - {{ mount_point_fs_and_options | combine({mount_point: {'options': (mount_point_fs_and_options[mount_point]['options'] + [required_option])}}, recursive=True) }} + prelim_mount_point_fs_and_options: | + {{ prelim_mount_point_fs_and_options | combine({mount_point: {'options': (prelim_mount_point_fs_and_options[mount_point]['options'] + [required_option])}}, recursive=True) }} changed_when: &mount_option_changed_when - - required_option not in mount_point_fs_and_options[mount_point]['original_options'] + - required_option not in prelim_mount_point_fs_and_options[mount_point]['original_options'] - name: "1.1.2.4.3 | PATCH | Ensure nosuid option set on /var partition" when: - - mount_point_fs_and_options[mount_point] is defined + - prelim_mount_point_fs_and_options[mount_point] is defined - rhel9cis_rule_1_1_2_4_3 tags: - level1-server diff --git a/tasks/section_1/cis_1.1.2.5.x.yml b/tasks/section_1/cis_1.1.2.5.x.yml index 2706d4b..180d016 100644 --- a/tasks/section_1/cis_1.1.2.5.x.yml +++ b/tasks/section_1/cis_1.1.2.5.x.yml @@ -3,7 +3,7 @@ - name: "1.1.2.5.1 | PATCH | Ensure /var/tmp is a separate partition" when: - rhel9cis_rule_1_1_2_5_1 - - required_mount not in mount_names + - required_mount not in prelim_mount_names tags: - level1-server - level1-workstation @@ -33,7 +33,7 @@ - name: "1.1.2.5.2 | PATCH | Ensure nodev option set on /var/tmp partition" when: - - mount_point_fs_and_options[mount_point] is defined + - prelim_mount_point_fs_and_options[mount_point] is defined - rhel9cis_rule_1_1_2_5_2 tags: - level1-server @@ -49,14 +49,14 @@ notify: &mount_option_notify - "Remount {{ mount_point }}" ansible.builtin.set_fact: &mount_option_set_fact - mount_point_fs_and_options: | - {{ mount_point_fs_and_options | combine({mount_point: {'options': (mount_point_fs_and_options[mount_point]['options'] + [required_option])}}, recursive=True) }} + prelim_mount_point_fs_and_options: | + {{ prelim_mount_point_fs_and_options | combine({mount_point: {'options': (prelim_mount_point_fs_and_options[mount_point]['options'] + [required_option])}}, recursive=True) }} changed_when: &mount_option_changed_when - - required_option not in mount_point_fs_and_options[mount_point]['original_options'] + - required_option not in prelim_mount_point_fs_and_options[mount_point]['original_options'] - name: "1.1.2.5.3 | PATCH | Ensure nosuid option set on /var/tmp partition" when: - - mount_point_fs_and_options[mount_point] is defined + - prelim_mount_point_fs_and_options[mount_point] is defined - rhel9cis_rule_1_1_2_5_3 tags: - level1-server @@ -76,7 +76,7 @@ - name: "1.1.2.5.4 | PATCH | Ensure noexec option set on /var/tmp partition" when: - - mount_point_fs_and_options[mount_point] is defined + - prelim_mount_point_fs_and_options[mount_point] is defined - rhel9cis_rule_1_1_2_5_4 tags: - level1-server diff --git a/tasks/section_1/cis_1.1.2.6.x.yml b/tasks/section_1/cis_1.1.2.6.x.yml index 77da285..765de3d 100644 --- a/tasks/section_1/cis_1.1.2.6.x.yml +++ b/tasks/section_1/cis_1.1.2.6.x.yml @@ -3,7 +3,7 @@ - name: "1/.1 | PATCH | Ensure /var/log is a separate partition" when: - rhel9cis_rule_1_1_2_6_1 - - required_mount not in mount_names + - required_mount not in prelim_mount_names tags: - level1-server - level1-workstation @@ -33,7 +33,7 @@ - name: "1.1.2.6.2 | PATCH | Ensure nodev option set on /var/log partition" when: - - mount_point_fs_and_options[mount_point] is defined + - prelim_mount_point_fs_and_options[mount_point] is defined - rhel9cis_rule_1_1_2_6_2 tags: - level1-server @@ -49,14 +49,14 @@ notify: &mount_option_notify - "Remount {{ mount_point }}" ansible.builtin.set_fact: &mount_option_set_fact - mount_point_fs_and_options: | - {{ mount_point_fs_and_options | combine({mount_point: {'options': (mount_point_fs_and_options[mount_point]['options'] + [required_option])}}, recursive=True) }} + prelim_mount_point_fs_and_options: | + {{ prelim_mount_point_fs_and_options | combine({mount_point: {'options': (prelim_mount_point_fs_and_options[mount_point]['options'] + [required_option])}}, recursive=True) }} changed_when: &mount_option_changed_when - - required_option not in mount_point_fs_and_options[mount_point]['original_options'] + - required_option not in prelim_mount_point_fs_and_options[mount_point]['original_options'] - name: "1.1.2.6.3 | PATCH | Ensure nosuid option set on /var/log partition" when: - - mount_point_fs_and_options[mount_point] is defined + - prelim_mount_point_fs_and_options[mount_point] is defined - rhel9cis_rule_1_1_2_6_3 tags: - level1-server @@ -76,7 +76,7 @@ - name: "1.1.2.6.4 | PATCH | Ensure noexec option set on /var/log partition" when: - - mount_point_fs_and_options[mount_point] is defined + - prelim_mount_point_fs_and_options[mount_point] is defined - rhel9cis_rule_1_1_2_6_4 tags: - level1-server diff --git a/tasks/section_1/cis_1.1.2.7.x.yml b/tasks/section_1/cis_1.1.2.7.x.yml index 93bcb23..2dc5939 100644 --- a/tasks/section_1/cis_1.1.2.7.x.yml +++ b/tasks/section_1/cis_1.1.2.7.x.yml @@ -3,7 +3,7 @@ - name: "1/.1 | PATCH | Ensure /var/log/audit is a separate partition" when: - rhel9cis_rule_1_1_2_7_1 - - required_mount not in mount_names + - required_mount not in prelim_mount_names tags: - level1-server - level1-workstation @@ -33,7 +33,7 @@ - name: "1.1.2.7.2 | PATCH | Ensure nodev option set on /var/log/audit partition" when: - - mount_point_fs_and_options[mount_point] is defined + - prelim_mount_point_fs_and_options[mount_point] is defined - rhel9cis_rule_1_1_2_7_2 tags: - level1-server @@ -49,14 +49,14 @@ notify: &mount_option_notify - "Remount {{ mount_point }}" ansible.builtin.set_fact: &mount_option_set_fact - mount_point_fs_and_options: | - {{ mount_point_fs_and_options | combine({mount_point: {'options': (mount_point_fs_and_options[mount_point]['options'] + [required_option])}}, recursive=True) }} + prelim_mount_point_fs_and_options: | + {{ prelim_mount_point_fs_and_options | combine({mount_point: {'options': (prelim_mount_point_fs_and_options[mount_point]['options'] + [required_option])}}, recursive=True) }} changed_when: &mount_option_changed_when - - required_option not in mount_point_fs_and_options[mount_point]['original_options'] + - required_option not in prelim_mount_point_fs_and_options[mount_point]['original_options'] - name: "1.1.2.7.3 | PATCH | Ensure nosuid option set on /var/log/audit partition" when: - - mount_point_fs_and_options[mount_point] is defined + - prelim_mount_point_fs_and_options[mount_point] is defined - rhel9cis_rule_1_1_2_7_3 tags: - level1-server @@ -76,7 +76,7 @@ - name: "1.1.2.7.4 | PATCH | Ensure noexec option set on /var/log/audit partition" when: - - mount_point_fs_and_options[mount_point] is defined + - prelim_mount_point_fs_and_options[mount_point] is defined - rhel9cis_rule_1_1_2_7_4 tags: - level1-server From 834fa7a5eeeb9a815e9693b7c0bfac2ef36fe3f9 Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Wed, 11 Dec 2024 10:22:33 +0000 Subject: [PATCH 12/22] Added comment on set_fact for mountpoints Signed-off-by: Mark Bolwell --- handlers/main.yml | 42 +++++++++++++++++++++--------------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/handlers/main.yml b/handlers/main.yml index 96cc86e..c122eaa 100644 --- a/handlers/main.yml +++ b/handlers/main.yml @@ -7,10 +7,10 @@ mount_point: '/tmp' ansible.posix.mount: path: "{{ mount_point }}" - src: "{{ mount_point_fs_and_options[mount_point]['src'] }}" + src: "{{ prelim_mount_point_fs_and_options[mount_point]['src'] }}" state: present - fstype: "{{ mount_point_fs_and_options[mount_point]['fs_type'] }}" - opts: "{{ mount_point_fs_and_options[mount_point]['options'] | unique | join(',') }}" + fstype: "{{ prelim_mount_point_fs_and_options[mount_point]['fs_type'] }}" + opts: "{{ prelim_mount_point_fs_and_options[mount_point]['options'] | unique | join(',') }}" listen: "Remount /tmp" - name: "Remounting /tmp" @@ -35,10 +35,10 @@ mount_point: '/dev/shm' ansible.posix.mount: path: "{{ mount_point }}" - src: "{{ mount_point_fs_and_options[mount_point]['src'] }}" + src: "{{ prelim_mount_point_fs_and_options[mount_point]['src'] }}" state: present - fstype: "{{ mount_point_fs_and_options[mount_point]['fs_type'] }}" - opts: "{{ mount_point_fs_and_options[mount_point]['options'] | unique | join(',') }}" + fstype: "{{ prelim_mount_point_fs_and_options[mount_point]['fs_type'] }}" + opts: "{{ prelim_mount_point_fs_and_options[mount_point]['options'] | unique | join(',') }}" listen: "Remount /dev/shm" - name: "Remounting /dev/shm" @@ -54,10 +54,10 @@ mount_point: '/home' ansible.posix.mount: path: "{{ mount_point }}" - src: "{{ mount_point_fs_and_options[mount_point]['src'] }}" + src: "{{ prelim_mount_point_fs_and_options[mount_point]['src'] }}" state: present - fstype: "{{ mount_point_fs_and_options[mount_point]['fs_type'] }}" - opts: "{{ mount_point_fs_and_options[mount_point]['options'] | unique | join(',') }}" + fstype: "{{ prelim_mount_point_fs_and_options[mount_point]['fs_type'] }}" + opts: "{{ prelim_mount_point_fs_and_options[mount_point]['options'] | unique | join(',') }}" listen: "Remount /home" - name: "Remounting /home" @@ -73,10 +73,10 @@ mount_point: '/var' ansible.posix.mount: path: "{{ mount_point }}" - src: "{{ mount_point_fs_and_options[mount_point]['src'] }}" + src: "{{ prelim_mount_point_fs_and_options[mount_point]['src'] }}" state: present - fstype: "{{ mount_point_fs_and_options[mount_point]['fs_type'] }}" - opts: "{{ mount_point_fs_and_options[mount_point]['options'] | unique | join(',') }}" + fstype: "{{ prelim_mount_point_fs_and_options[mount_point]['fs_type'] }}" + opts: "{{ prelim_mount_point_fs_and_options[mount_point]['options'] | unique | join(',') }}" listen: "Remount /var" - name: "Remounting /var" @@ -92,10 +92,10 @@ mount_point: '/var/tmp' ansible.posix.mount: path: "{{ mount_point }}" - src: "{{ mount_point_fs_and_options[mount_point]['src'] }}" + src: "{{ prelim_mount_point_fs_and_options[mount_point]['src'] }}" state: present - fstype: "{{ mount_point_fs_and_options[mount_point]['fs_type'] }}" - opts: "{{ mount_point_fs_and_options[mount_point]['options'] | unique | join(',') }}" + fstype: "{{ prelim_mount_point_fs_and_options[mount_point]['fs_type'] }}" + opts: "{{ prelim_mount_point_fs_and_options[mount_point]['options'] | unique | join(',') }}" listen: "Remount /var/tmp" - name: "Remounting /var/tmp" @@ -111,10 +111,10 @@ mount_point: '/var/log' ansible.posix.mount: path: "{{ mount_point }}" - src: "{{ mount_point_fs_and_options[mount_point]['src'] }}" + src: "{{ prelim_mount_point_fs_and_options[mount_point]['src'] }}" state: present - fstype: "{{ mount_point_fs_and_options[mount_point]['fs_type'] }}" - opts: "{{ mount_point_fs_and_options[mount_point]['options'] | unique | join(',') }}" + fstype: "{{ prelim_mount_point_fs_and_options[mount_point]['fs_type'] }}" + opts: "{{ prelim_mount_point_fs_and_options[mount_point]['options'] | unique | join(',') }}" listen: "Remount /var/log" - name: "Remounting /var/log" @@ -130,10 +130,10 @@ mount_point: '/var/log/audit' ansible.posix.mount: path: "{{ mount_point }}" - src: "{{ mount_point_fs_and_options[mount_point]['src'] }}" + src: "{{ prelim_mount_point_fs_and_options[mount_point]['src'] }}" state: present - fstype: "{{ mount_point_fs_and_options[mount_point]['fs_type'] }}" - opts: "{{ mount_point_fs_and_options[mount_point]['options'] | unique | join(',') }}" + fstype: "{{ prelim_mount_point_fs_and_options[mount_point]['fs_type'] }}" + opts: "{{ prelim_mount_point_fs_and_options[mount_point]['options'] | unique | join(',') }}" listen: "Remount /var/log/audit" - name: "Remounting /var/log/audit" From 3545620db8afe57bdc0ef85ccf746292a94a8f2a Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Wed, 11 Dec 2024 10:22:44 +0000 Subject: [PATCH 13/22] udpated variable Signed-off-by: Mark Bolwell --- tasks/prelim.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tasks/prelim.yml b/tasks/prelim.yml index 7896d58..4664879 100644 --- a/tasks/prelim.yml +++ b/tasks/prelim.yml @@ -72,7 +72,7 @@ changed_when: false register: prelim_mount_output - - name: PRELIM | AUDIT | Section 1.1 | Retrieve mount options - build fact + - name: PRELIM | AUDIT | Section 1.1 | Retrieve mount options - build fact # This is inherited and used in mountpoints tasks ansible.builtin.set_fact: prelim_mount_point_fs_and_options: >- {%- set prelim_mount_point_fs_and_options = {} -%} From 69e01b84f3fed923138b512654ceed7251a68250 Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Wed, 11 Dec 2024 11:20:00 +0000 Subject: [PATCH 14/22] Updated files to std Signed-off-by: Mark Bolwell --- tasks/LE_audit_setup.yml | 6 ++-- tasks/audit_only.yml | 10 +++--- tasks/post_remediation_audit.yml | 18 +++++----- tasks/pre_remediation_audit.yml | 58 +++++++++++++------------------- 4 files changed, 38 insertions(+), 54 deletions(-) diff --git a/tasks/LE_audit_setup.yml b/tasks/LE_audit_setup.yml index 4b407eb..52fc8bd 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 == "aarch64" + when: ansible_facts.machine == "arm64" ansible.builtin.set_fact: audit_pkg_arch_name: ARM64 @@ -20,13 +20,13 @@ owner: root group: root checksum: "{{ audit_bin_version[audit_pkg_arch_name + '_checksum'] }}" - mode: '0555' + mode: 'u+x,go-w' - name: Pre Audit Setup | Copy audit binary when: get_audit_binary_method == 'copy' ansible.builtin.copy: src: "{{ audit_bin_copy_location }}" dest: "{{ audit_bin }}" - mode: '0555' owner: root group: root + mode: 'u+x,go-w' diff --git a/tasks/audit_only.yml b/tasks/audit_only.yml index b7dad08..008d358 100644 --- a/tasks/audit_only.yml +++ b/tasks/audit_only.yml @@ -3,7 +3,7 @@ - name: Audit_Only | Create local Directories for hosts when: fetch_audit_files ansible.builtin.file: - mode: '0755' + mode: 'u+x,go-w' path: "{{ audit_capture_files_dir }}/{{ inventory_hostname }}" recurse: true state: directory @@ -15,16 +15,14 @@ ansible.builtin.fetch: dest: "{{ audit_capture_files_dir }}/{{ inventory_hostname }}/" flat: true - mode: '0644' + mode: 'go-wx' src: "{{ pre_audit_outfile }}" - name: Audit_only | Show Audit Summary - when: - - audit_only + when: audit_only ansible.builtin.debug: msg: "{{ audit_results.split('\n') }}" - name: Audit_only | Stop Playbook Audit Only selected - when: - - audit_only + when: audit_only ansible.builtin.meta: end_play diff --git a/tasks/post_remediation_audit.yml b/tasks/post_remediation_audit.yml index 8004ed3..54d5785 100644 --- a/tasks/post_remediation_audit.yml +++ b/tasks/post_remediation_audit.yml @@ -1,14 +1,14 @@ --- -- name: Post Audit | Run post_remediation {{ benchmark }} audit - ansible.builtin.shell: "{{ audit_conf_dir }}/run_audit.sh -v {{ audit_vars_path }} -f {{ audit_format }} -o {{ post_audit_outfile }} -g \"{{ group_names }}\"" +- name: Post Audit | Run post_remediation {{ benchmark }} audit # noqa name[template] + ansible.builtin.command: "{{ audit_conf_dir }}/run_audit.sh -v {{ audit_vars_path }} -f {{ audit_format }} -o {{ post_audit_outfile }} -g \"{{ group_names }}\"" changed_when: true environment: AUDIT_BIN: "{{ audit_bin }}" AUDIT_CONTENT_LOCATION: "{{ audit_conf_dest | default('/opt') }}" AUDIT_FILE: goss.yml -- name: Post Audit | Ensure audit files readable by users +- name: Post Audit | ensure audit files readable by users ansible.builtin.file: path: "{{ item }}" mode: '0644' @@ -18,26 +18,24 @@ - "{{ pre_audit_outfile }}" - name: Post Audit | Capture audit data if json format - when: - - audit_format == "json" + when: audit_format == "json" block: - 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 + register: post_audit_summary - name: Post Audit | Set Fact for audit summary ansible.builtin.set_fact: post_audit_results: "{{ post_audit_summary.stdout }}" - name: Post Audit | Capture audit data if documentation format - when: - - audit_format == "documentation" + when: audit_format == "documentation" block: - name: Post Audit | Capture audit data if documentation format - ansible.builtin.shell: tail -2 "{{ post_audit_outfile }}" | tac | tr '\n' ' ' - register: post_audit_summary + ansible.builtin.shell: tail -2 "{{ pre_audit_outfile }}" | tac | tr '\n' ' ' changed_when: false + register: post_audit_summary - name: Post Audit | Set Fact for audit summary ansible.builtin.set_fact: diff --git a/tasks/pre_remediation_audit.yml b/tasks/pre_remediation_audit.yml index 3a3304c..91cc9b7 100644 --- a/tasks/pre_remediation_audit.yml +++ b/tasks/pre_remediation_audit.yml @@ -1,22 +1,19 @@ --- - name: Pre Audit Setup | Setup the LE audit - when: - - setup_audit - tags: - - setup_audit + when: setup_audit + tags: setup_audit ansible.builtin.include_tasks: file: LE_audit_setup.yml -- name: Pre Audit Setup | Ensure {{ audit_conf_dir }} exists +- name: Pre Audit Setup | Ensure existence of {{ audit_conf_dir }} # noqa name[template] ansible.builtin.file: path: "{{ audit_conf_dir }}" + mode: 'go-w' state: directory - mode: '0755' - name: Pre Audit Setup | If using git for content set up - when: - - audit_content == 'git' + when: audit_content == 'git' block: - name: Pre Audit Setup | Install git ansible.builtin.package: @@ -30,57 +27,51 @@ version: "{{ audit_git_version }}" - name: Pre Audit Setup | Copy to audit content files to server - when: - - audit_content == 'copy' + when: audit_content == 'copy' ansible.builtin.copy: src: "{{ audit_conf_source }}" dest: "{{ audit_conf_dest }}" mode: preserve - name: Pre Audit Setup | Unarchive audit content files on server - when: - - audit_content == 'archive' + when: audit_content == 'archive' ansible.builtin.unarchive: src: "{{ audit_conf_source }}" dest: "{{ audit_conf_dest }}" - name: Pre Audit Setup | Get audit content from url - when: - - audit_content == 'get_url' + when: audit_content == 'get_url' ansible.builtin.unarchive: src: "{{ audit_conf_source }}" dest: "{{ audit_conf_dest }}/{{ benchmark }}-Audit" - remote_src: "{{ ( audit_conf_source is contains ('http'))| ternary(true, false ) }}" - extra_opts: "{{ (audit_conf_source is contains ('github')) | ternary('--strip-components=1', [] ) }}" + remote_src: "{{ (audit_conf_source is contains('http')) | ternary(true, false) }}" + extra_opts: "{{ (audit_conf_source is contains('github')) | ternary('--strip-components=1', []) }}" - name: Pre Audit Setup | Check Goss is available - when: - - run_audit + when: run_audit block: - name: Pre Audit Setup | Check for goss file ansible.builtin.stat: path: "{{ audit_bin }}" - register: discovered_goss_available + register: prelim_goss_available - name: Pre Audit Setup | If audit ensure goss is available - when: - - not discovered_goss_available.stat.exists + when: not prelim_goss_available.stat.exists ansible.builtin.assert: msg: "Audit has been selected: unable to find goss binary at {{ audit_bin }}" - name: Pre Audit Setup | Copy ansible default vars values to test audit - when: - - run_audit + when: run_audit tags: - goss_template - run_audit ansible.builtin.template: src: ansible_vars_goss.yml.j2 dest: "{{ audit_vars_path }}" - mode: '0600' + mode: 'go-rwx' -- name: Pre Audit | Run pre_remediation {{ benchmark }} audit - ansible.builtin.shell: "{{ audit_conf_dir }}/run_audit.sh -v {{ audit_vars_path }} -f {{ audit_format }} -o {{ pre_audit_outfile }} -g \"{{ group_names }}\"" +- name: Pre Audit | Run pre_remediation audit {{ benchmark }} # noqa name[template] + ansible.builtin.command: "{{ audit_conf_dir }}/run_audit.sh -v {{ audit_vars_path }} -f {{ audit_format }} -o {{ pre_audit_outfile }} -g \"{{ group_names }}\"" # noqa yaml[line-length] changed_when: true environment: AUDIT_BIN: "{{ audit_bin }}" @@ -88,33 +79,30 @@ AUDIT_FILE: goss.yml - name: Pre Audit | Capture audit data if json format - when: - - audit_format == "json" + when: audit_format == "json" block: - 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 + register: pre_audit_summary - name: Pre Audit | Set Fact for audit summary ansible.builtin.set_fact: pre_audit_results: "{{ pre_audit_summary.stdout }}" - name: Pre Audit | Capture audit data if documentation format - when: - - audit_format == "documentation" + when: audit_format == "documentation" block: - name: Pre Audit | Capture audit data if documentation format - ansible.builtin.shell: tail -2 "{{ pre_audit_outfile }}" | tac | tr '\n' ' ' - register: pre_audit_summary + ansible.builtin.shell: tail -2 "{{ pre_audit_outfile }}" | tac | tr '\n' ' ' changed_when: false + register: pre_audit_summary - name: Pre Audit | Set Fact for audit summary ansible.builtin.set_fact: pre_audit_results: "{{ pre_audit_summary.stdout }}" - name: Audit_Only | Run Audit Only - when: - - audit_only + when: audit_only ansible.builtin.import_tasks: file: audit_only.yml From fcf9eb674f5c1908e0373264709db1643408d4ea Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Wed, 11 Dec 2024 11:20:19 +0000 Subject: [PATCH 15/22] lint and best practise Signed-off-by: Mark Bolwell --- handlers/main.yml | 21 ++++++++++++------- tasks/main.yml | 8 +++---- tasks/parse_etc_password.yml | 2 +- tasks/post.yml | 17 ++++++--------- tasks/prelim.yml | 11 ++++++---- .../pwquality.conf.d/50-pwcomplexity.conf.j2 | 4 ++-- 6 files changed, 33 insertions(+), 30 deletions(-) diff --git a/handlers/main.yml b/handlers/main.yml index c122eaa..91181a1 100644 --- a/handlers/main.yml +++ b/handlers/main.yml @@ -145,7 +145,8 @@ listen: "Remount /var/log/audit" - name: Reload sysctl - ansible.builtin.shell: sysctl --system + ansible.builtin.command: sysctl --system + changed_when: true - name: Sysctl flush ipv4 route table when: @@ -181,8 +182,8 @@ - name: Set Crypto Policy when: prelim_system_wide_crypto_policy.stdout != rhel9cis_full_crypto_policy - ansible.builtin.shell: | - update-crypto-policies --set "{{ rhel9cis_full_crypto_policy }}" + ansible.builtin.command: update-crypto-policies --set "{{ rhel9cis_full_crypto_policy }}" + changed_when: true notify: - Change_requires_reboot - Restart sshd @@ -203,10 +204,12 @@ state: restarted - name: Reload dconf - ansible.builtin.shell: dconf update + ansible.builtin.command: dconf update + changed_when: true - name: Grub2cfg - ansible.builtin.shell: "grub2-mkconfig -o /boot/grub2/grub.cfg" + ansible.builtin.command: "grub2-mkconfig -o /boot/grub2/grub.cfg" + changed_when: true ignore_errors: true # noqa ignore-errors - name: Restart rsyslog @@ -229,12 +232,13 @@ daemon-reload: true - name: Authselect update - ansible.builtin.shell: authselect apply-changes + ansible.builtin.command: authselect apply-changes + changed_when: true ## Auditd tasks note order for handlers to run - name: Auditd immutable check - ansible.builtin.shell: grep -c "^-e 2" /etc/audit/rules.d/99_auditd.rules + ansible.builtin.command: grep -c "^-e 2" /etc/audit/rules.d/99_auditd.rules changed_when: false register: discovered_auditd_immutable_check @@ -246,7 +250,8 @@ notify: Change_requires_reboot - name: Stop auditd process - ansible.builtin.shell: systemctl kill auditd + ansible.builtin.command: systemctl kill auditd + changed_when: true listen: Restart auditd - name: Start auditd process diff --git a/tasks/main.yml b/tasks/main.yml index 4598f85..4cb6869 100644 --- a/tasks/main.yml +++ b/tasks/main.yml @@ -81,14 +81,14 @@ vars: sudo_password_rule: rhel9cis_rule_5_2_4 # pragma: allowlist secret block: - - name: "Check password set for {{ ansible_env.SUDO_USER }} | password state" + - name: "Check password set for {{ ansible_env.SUDO_USER }} | password state" # noqa name[template] ansible.builtin.shell: "(grep {{ ansible_env.SUDO_USER }} /etc/shadow || echo 'not found:not found') | awk -F: '{print $2}'" changed_when: false failed_when: false check_mode: false register: prelim_ansible_user_password_set - - name: "Check for local account {{ ansible_env.SUDO_USER }} | Check for local account" + - name: "Check for local account {{ ansible_env.SUDO_USER }} | Check for local account" # noqa name[template] when: prelim_ansible_user_password_set.stdout == "not found" ansible.builtin.debug: msg: "No local account found for {{ ansible_env.SUDO_USER }} user. Skipping local account checks." @@ -97,7 +97,7 @@ when: - prelim_ansible_user_password_set.stdout != "not found" block: - - name: "Check password set for {{ ansible_env.SUDO_USER }} | Assert local password set" + - name: "Check password set for {{ ansible_env.SUDO_USER }} | Assert local password set" # noqa name[template] ansible.builtin.assert: that: - prelim_ansible_user_password_set.stdout | length != 0 @@ -105,7 +105,7 @@ fail_msg: "You have {{ sudo_password_rule }} enabled but the user = {{ ansible_env.SUDO_USER }} has no password set - It can break access" success_msg: "You have a password set for the {{ ansible_env.SUDO_USER }} user" - - name: "Check account is not locked for {{ ansible_env.SUDO_USER }} | Assert local account not locked" + - name: "Check account is not locked for {{ ansible_env.SUDO_USER }} | Assert local account not locked" # noqa name[template] ansible.builtin.assert: that: - not prelim_ansible_user_password_set.stdout.startswith("!") diff --git a/tasks/parse_etc_password.yml b/tasks/parse_etc_password.yml index 8270b5a..49941bf 100644 --- a/tasks/parse_etc_password.yml +++ b/tasks/parse_etc_password.yml @@ -5,7 +5,7 @@ - always block: - name: "PRELIM | 5.5.2 | 6.2.7 | 6.2.8 | 6.2.20 | Parse /etc/passwd" - ansible.builtin.shell: cat /etc/passwd + ansible.builtin.command: cat /etc/passwd changed_when: false check_mode: false register: rhel9cis_passwd_file_audit diff --git a/tasks/post.yml b/tasks/post.yml index 198d9c0..4308727 100644 --- a/tasks/post.yml +++ b/tasks/post.yml @@ -29,28 +29,23 @@ ansible.builtin.meta: flush_handlers - name: POST | reboot system if changes require it and not skipped + when: change_requires_reboot tags: - always + vars: + warn_control_id: Reboot_required block: - name: POST | Reboot system if changes require it and not skipped + when: not skip_reboot ansible.builtin.reboot: - when: - - change_requires_reboot - - not skip_reboot - name: POST | Warning a reboot required but skip option set + when: 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 - when: - - change_requires_reboot - - skip_reboot - name: "POST | Warning a reboot required but skip option set | warning count" + when: skip_reboot ansible.builtin.import_tasks: file: warning_facts.yml - when: - - change_requires_reboot - - skip_reboot - vars: - warn_control_id: Reboot_required diff --git a/tasks/prelim.yml b/tasks/prelim.yml index 4664879..efa13d5 100644 --- a/tasks/prelim.yml +++ b/tasks/prelim.yml @@ -103,14 +103,14 @@ - ansible_facts.distribution == 'RedHat' block: - name: "PRELIM | AUDIT | Import gpg keys | get data" - ansible.builtin.shell: rpm -q gpg-pubkey --qf '%{NAME}-%{VERSION}-%{RELEASE}\t%{SUMMARY}\n' + ansible.builtin.command: rpm -q gpg-pubkey --qf '%{NAME}-%{VERSION}-%{RELEASE}\t%{SUMMARY}\n' # noqa command-instead-of-module changed_when: false failed_when: false register: prelim_check_gpg_imported - name: "PRELIM | AUDIT | Import gpg keys | Check Package" when: "'not installed' in prelim_check_gpg_imported.stdout" - ansible.builtin.shell: rpm -qi redhat-release | grep Signature + ansible.builtin.shell: rpm -qi redhat-release | grep Signature # noqa command-instead-of-module changed_when: false failed_when: false register: prelim_os_gpg_package_valid @@ -119,7 +119,9 @@ when: - "'not installed' in prelim_check_gpg_imported.stdout" - "'Key ID 199e2f91fd431d51' in prelim_os_gpg_package_valid.stdout" - ansible.builtin.shell: rpm --import /etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-release + ansible.builtin.rpm_key: + key: /etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-release + state: present - name: "PRELIM | AUDIT | Check systemd coredump" when: @@ -150,7 +152,7 @@ state: present - name: "PRELIM | AUDIT | Gather system-wide crypto-policy" - ansible.builtin.shell: 'update-crypto-policies --show' + ansible.builtin.command: 'update-crypto-policies --show' changed_when: false check_mode: false register: prelim_system_wide_crypto_policy @@ -269,6 +271,7 @@ ansible.builtin.file: path: /etc/systemd/journald.conf.d state: directory + mode: 'u+x,g-w,o-rwx' - name: "PRELIM | PATCH | Configure System Accounting (auditd)" when: diff --git a/templates/etc/security/pwquality.conf.d/50-pwcomplexity.conf.j2 b/templates/etc/security/pwquality.conf.d/50-pwcomplexity.conf.j2 index 6a9855a..c223c84 100644 --- a/templates/etc/security/pwquality.conf.d/50-pwcomplexity.conf.j2 +++ b/templates/etc/security/pwquality.conf.d/50-pwcomplexity.conf.j2 @@ -1,9 +1,9 @@ # CIS Configurations # 5.3.3.2.3 Ensure password complexity is configured -{% if rhel9cis_passwd_complex_option == 'minclass' %} +{% if rhel9cis_passwd_complex_option == 'minclass' %} # pragma: allowlist secret minclass = {{ rhel9cis_passwd_minclass }} {% endif %} -{% if rhel9cis_passwd_complex_option == 'credits' %} +{% if rhel9cis_passwd_complex_option == 'credits' %} # pragma: allowlist secret dcredit = {{rhel9cis_passwd_dcredit }} ucredit = {{ rhel9cis_passwd_ucredit }} ocredit = {{ rhel9cis_passwd_ocredit }} From 88ac5c3d65f0481b8fe1c266c57525e3c1a3c3ff Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Wed, 11 Dec 2024 11:49:02 +0000 Subject: [PATCH 16/22] Lint updates Signed-off-by: Mark Bolwell --- {templates => files}/fs_with_cves.sh | 5 +-- tasks/section_1/cis_1.1.1.x.yml | 6 +-- tasks/section_1/cis_1.2.1.x.yml | 8 ++-- tasks/section_2/cis_2.1.x.yml | 2 +- tasks/section_2/cis_2.4.x.yml | 2 +- tasks/section_3/cis_3.1.x.yml | 4 +- tasks/section_3/cis_3.2.x.yml | 12 ++++-- tasks/section_4/cis_4.1.x.yml | 2 +- tasks/section_4/cis_4.3.x.yml | 62 +++++++++++++++++++--------- tasks/section_5/cis_5.3.2.x.yml | 36 +++++++++------- tasks/section_5/cis_5.3.3.1.x.yml | 1 + tasks/section_5/cis_5.4.1.x.yml | 28 ++++++++----- tasks/section_5/cis_5.4.2.x.yml | 3 +- tasks/section_6/cis_6.1.x.yml | 10 +++-- tasks/section_6/cis_6.3.1.x.yml | 18 ++++---- tasks/section_7/cis_7.1.x.yml | 4 +- tasks/section_7/cis_7.2.x.yml | 4 +- tasks/warning_facts.yml | 2 +- vars/audit.yml | 2 +- 19 files changed, 127 insertions(+), 84 deletions(-) rename {templates => files}/fs_with_cves.sh (98%) diff --git a/templates/fs_with_cves.sh b/files/fs_with_cves.sh similarity index 98% rename from templates/fs_with_cves.sh rename to files/fs_with_cves.sh index 89ba49b..a6d937c 100644 --- a/templates/fs_with_cves.sh +++ b/files/fs_with_cves.sh @@ -1,11 +1,8 @@ -{% raw %} -#! /usr/bin/env bash +{% raw %}#! /usr/bin/env bash # Based on original Script provided by CIS # CVEs correct at time of creation - April2024 -#! /usr/bin/env bash - { a_output=(); a_output2=(); a_modprope_config=(); a_excluded=(); a_available_modules=() a_ignore=("xfs" "vfat" "ext2" "ext3" "ext4") diff --git a/tasks/section_1/cis_1.1.1.x.yml b/tasks/section_1/cis_1.1.1.x.yml index bd56bde..02a387e 100644 --- a/tasks/section_1/cis_1.1.1.x.yml +++ b/tasks/section_1/cis_1.1.1.x.yml @@ -284,15 +284,15 @@ warn_control_id: '1.1.1.9' block: - name: "1.1.1.9 | PATCH | Ensure unused filesystems kernel modules are not available | Add discovery script" - ansible.builtin.template: + ansible.builtin.copy: src: fs_with_cves.sh dest: /var/fs_with_cves.sh owner: root group: root - mode: '0744' + mode: 'u+x,go-wx' - name: "1.1.1.9 | AUDIT | Ensure unused filesystems kernel modules are not available | Run discovery script" - ansible.builtin.shell: /var/fs_with_cves.sh + ansible.builtin.command: /var/fs_with_cves.sh changed_when: false failed_when: discovered_fs_modules_loaded.rc not in [ 0, 99 ] register: discovered_fs_modules_loaded diff --git a/tasks/section_1/cis_1.2.1.x.yml b/tasks/section_1/cis_1.2.1.x.yml index dca12b0..454fd95 100644 --- a/tasks/section_1/cis_1.2.1.x.yml +++ b/tasks/section_1/cis_1.2.1.x.yml @@ -15,13 +15,15 @@ - NIST800-53R5_SI-2 block: - name: "1.2.1.1 | AUDIT | Ensure GPG keys are configured | list installed pubkey keys" - ansible.builtin.shell: "rpm -qa | grep {{ os_gpg_key_pubkey_name }}" + ansible.builtin.shell: | + "rpm -qa | grep {{ os_gpg_key_pubkey_name }}" changed_when: false failed_when: false register: discovered_os_installed_pub_keys - name: "1.2.1.1 | AUDIT | Ensure GPG keys are configured | Query found keys" - ansible.builtin.shell: 'rpm -q --queryformat "%{PACKAGER} %{VERSION}\\n" {{ os_gpg_key_pubkey_name }} | grep "{{ os_gpg_key_pubkey_content }}"' + ansible.builtin.shell: | + 'rpm -q --queryformat "%{PACKAGER} %{VERSION}\\n" {{ os_gpg_key_pubkey_name }} | grep "{{ os_gpg_key_pubkey_content }}"' changed_when: false failed_when: false register: discovered_os_gpg_key_check @@ -107,7 +109,7 @@ warn_control_id: '1.2.1.4' block: - name: "1.2.1.4 | AUDIT | Ensure package manager repositories are configured | Get repo list" - ansible.builtin.shell: dnf repolist + ansible.builtin.command: dnf repolist changed_when: false failed_when: false register: discovered_dnf_configured diff --git a/tasks/section_2/cis_2.1.x.yml b/tasks/section_2/cis_2.1.x.yml index 73e7986..bf6a81d 100644 --- a/tasks/section_2/cis_2.1.x.yml +++ b/tasks/section_2/cis_2.1.x.yml @@ -718,7 +718,7 @@ warn_control_id: '2.1.22' block: - name: "2.1.22 | AUDIT | Ensure only approved services are listening on a network interface | Get list of services" - ansible.builtin.shell: systemctl list-units --type=service + ansible.builtin.command: systemctl list-units --type=service # noqa command-instead-of-module changed_when: false failed_when: discovered_running_services.rc not in [ 0, 1 ] check_mode: false diff --git a/tasks/section_2/cis_2.4.x.yml b/tasks/section_2/cis_2.4.x.yml index 16ed0e9..3789aae 100644 --- a/tasks/section_2/cis_2.4.x.yml +++ b/tasks/section_2/cis_2.4.x.yml @@ -146,7 +146,7 @@ - name: "2.4.1.8 | PATCH | Ensure crontab is restricted to authorized users | Ensure cron.allow is restricted to authorized users" ansible.builtin.file: path: /etc/cron.allow - state: '{{ "file" if discovered_cron_allow_state.stat.exists else "touch" }}' + state: '{{ "file" if discovered_cron_allow_state.stat.exists else "touch" }}' owner: root group: root mode: u-x,g-wx,o-rwx diff --git a/tasks/section_3/cis_3.1.x.yml b/tasks/section_3/cis_3.1.x.yml index 98e3a93..84d8784 100644 --- a/tasks/section_3/cis_3.1.x.yml +++ b/tasks/section_3/cis_3.1.x.yml @@ -40,7 +40,7 @@ block: - name: "3.1.2 | PATCH | Ensure wireless interfaces are disabled | Check for network-manager tool" when: "'network-manager' in ansible_facts.packages" - ansible.builtin.shell: nmcli radio wifi + ansible.builtin.command: nmcli radio wifi changed_when: false failed_when: false check_mode: false @@ -50,7 +50,7 @@ when: - "'network-manager' in ansible_facts.packages" - "'enabled' in discovered_wifi_status.stdout" - ansible.builtin.shell: nmcli radio all off + ansible.builtin.command: nmcli radio all off changed_when: discovered_nmcli_radio_off.rc == 0 register: discovered_nmcli_radio_off diff --git a/tasks/section_3/cis_3.2.x.yml b/tasks/section_3/cis_3.2.x.yml index bc210ae..4413d59 100644 --- a/tasks/section_3/cis_3.2.x.yml +++ b/tasks/section_3/cis_3.2.x.yml @@ -18,6 +18,7 @@ regexp: '^(#)?install dccp(\\s|$)' line: "{{ item }}" create: true + mode: 'u-x,go-rwx' loop: - install dccp /bin/true - blacklist dccp @@ -28,7 +29,7 @@ regexp: "^(#)?blacklist cramfs(\\s|$)" line: "blacklist cramfs" create: true - mode: '0600' + mode: 'u-x,go-rwx' - name: "3.2.2 | PATCH | Ensure tipc kernel module is not available" when: @@ -48,6 +49,7 @@ regexp: '^(#)?install tipc(\\s|$)' line: "{{ item }}" create: true + mode: 'u-x,go-rwx' loop: - install tipc /bin/true - blacklist tipc @@ -58,7 +60,7 @@ regexp: "^(#)?blacklist tipc(\\s|$)" line: "blacklist tipc" create: true - mode: '0600' + mode: 'u-x,go-rwx' - name: "3.2.3 | PATCH | Ensure rds kernel module is not available" when: @@ -78,6 +80,7 @@ regexp: '^(#)?install rds(\\s|$)' line: "{{ item }}" create: true + mode: 'u-x,go-rwx' loop: - install rds /bin/true - blacklist rds @@ -88,7 +91,7 @@ regexp: "^(#)?blacklist rds(\\s|$)" line: "blacklist rds" create: true - mode: '0600' + mode: 'u-x,go-rwx' - name: "3.2.4 | PATCH | Ensure sctp kernel module is not available" when: @@ -108,6 +111,7 @@ regexp: '^(#)?install sctp(\\s|$)' line: "{{ item }}" create: true + mode: 'u-x,go-rwx' loop: - install sctp /bin/true - blacklist sctp @@ -118,4 +122,4 @@ regexp: "^(#)?blacklist sctp(\\s|$)" line: "blacklist sctp" create: true - mode: '0600' + mode: 'u-x,go-rwx' diff --git a/tasks/section_4/cis_4.1.x.yml b/tasks/section_4/cis_4.1.x.yml index f0a6636..06cffbd 100644 --- a/tasks/section_4/cis_4.1.x.yml +++ b/tasks/section_4/cis_4.1.x.yml @@ -52,7 +52,7 @@ name: "{{ rhel9cis_firewall }}" state: installed - - name: "4.1.2 | PATCH | Ensure a single firewall configuration utility is in use | {{ rhel9cis_firewall }} started and enabled" + - name: "4.1.2 | PATCH | Ensure a single firewall configuration utility is in use | {{ rhel9cis_firewall }} started and enabled" # noqa name[template] ansible.builtin.systemd: name: "{{ rhel9cis_firewall }}" enabled: true diff --git a/tasks/section_4/cis_4.3.x.yml b/tasks/section_4/cis_4.3.x.yml index 4e85deb..9cab1b4 100644 --- a/tasks/section_4/cis_4.3.x.yml +++ b/tasks/section_4/cis_4.3.x.yml @@ -8,7 +8,8 @@ - rhel9cis_rule_4_3_3 - rhel9cis_rule_4_3_4 tags: always - ansible.builtin.shell: "nft add table inet {{ rhel9cis_nft_tables_tablename }}" + ansible.builtin.command: "nft add table inet {{ rhel9cis_nft_tables_tablename }}" + changed_when: true - name: "4.3.1 | PATCH | Ensure nftables base chains exist" when: @@ -22,19 +23,22 @@ - NIST800-55_CA-9 block: - name: "4.3.1 | AUDIT | Ensure nftables base chains exist | Get current chains for INPUT" - ansible.builtin.shell: nft list ruleset | grep 'hook input' + ansible.builtin.shell: | + nft list ruleset | grep 'hook input' changed_when: false failed_when: false register: discovered_nftables_input_chains - name: "4.3.1 | AUDIT | Ensure nftables base chains exist | Get current chains for FORWARD" - ansible.builtin.shell: nft list ruleset | grep 'hook forward' + ansible.builtin.shell: | + nft list ruleset | grep 'hook forward' changed_when: false failed_when: false register: discovered_nftables_forward_chains - name: "4.3.1 | AUDIT | Ensure nftables base chains exist | Get current chains for OUTPUT" - ansible.builtin.shell: nft list ruleset | grep 'hook output' + ansible.builtin.shell: | + nft list ruleset | grep 'hook output' changed_when: false failed_when: false register: discovered_nftables_output_chains @@ -52,7 +56,8 @@ - name: "4.3.1 | PATCH | Ensure nftables base chains exist | Create chains if needed" when: rhel9cis_nft_tables_autochaincreate - ansible.builtin.shell: "{{ item }}" + ansible.builtin.command: "{{ item }}" + changed_when: true failed_when: false loop: - nft create chain inet "{{ rhel9cis_nft_tables_tablename }}" input { type filter hook input priority 0 \; } @@ -71,44 +76,50 @@ - NIST800-55_CA-9 block: - name: "4.3.2 | AUDIT | Ensure nftables established connections are configured | Gather incoming connection rules" - ansible.builtin.shell: nft list ruleset | awk '/hook input/,/}/' | grep -E 'ip protocol (tcp|udp|icmp) ct state' + ansible.builtin.shell: | + nft list ruleset | awk '/hook input/,/}/' | grep -E 'ip protocol (tcp|udp|icmp) ct state' changed_when: false failed_when: false register: discovered_nftables_inconnectionrule - name: "4.3.2 | AUDIT | Ensure nftables established connections are configured | Gather outbound connection rules" - ansible.builtin.shell: nft list ruleset | awk '/hook output/,/}/' | grep -E 'ip protocol (tcp|udp|icmp) ct state' + ansible.builtin.command: nft list ruleset | awk '/hook output/,/}/' | grep -E 'ip protocol (tcp|udp|icmp) ct state' changed_when: false failed_when: false register: discovered_nftables_outconnectionrule - name: "4.3.2| PATCH | Ensure nftables established connections are configured | Add input tcp established accept policy" when: '"ip protocol tcp ct state established accept" not in discovered_nftables_inconnectionrule.stdout' - ansible.builtin.shell: nft add rule inet "{{ rhel9cis_nft_tables_tablename }}" input ip protocol tcp ct state established accept + ansible.builtin.command: nft add rule inet "{{ rhel9cis_nft_tables_tablename }}" input ip protocol tcp ct state established accept + changed_when: true - name: "4.3.2 | PATCH | Ensure nftables established connections are configured | Add input udp established accept policy" when: '"ip protocol udp ct state established accept" not in discovered_nftables_inconnectionrule.stdout' ansible.builtin.command: nft add rule inet "{{ rhel9cis_nft_tables_tablename }}" input ip protocol udp ct state established accept + changed_when: true - name: "4.3.2 | PATCH | Ensure nftables established connections are configured | Add input icmp established accept policy" when: '"ip protocol icmp ct state established accept" not in discovered_nftables_inconnectionrule.stdout' ansible.builtin.command: nft add rule inet "{{ rhel9cis_nft_tables_tablename }}" input ip protocol icmp ct state established accept + changed_when: true - name: "4.3.2 | PATCH | Ensure nftables established connections are configured | Add output tcp new, related, established accept policy" when: '"ip protocol tcp ct state established,related,new accept" not in discovered_nftables_outconnectionrule.stdout' ansible.builtin.command: nft add rule inet "{{ rhel9cis_nft_tables_tablename }}" output ip protocol tcp ct state new,related,established accept + changed_when: true - name: "4.3.2 | PATCH | Ensure nftables established connections are configured | Add output udp new, related, established accept policy" when: '"ip protocol udp ct state established,related,new accept" not in discovered_nftables_outconnectionrule.stdout' ansible.builtin.command: nft add rule inet "{{ rhel9cis_nft_tables_tablename }}" output ip protocol udp ct state new,related,established accept + changed_when: true - name: "4.3.2 | PATCH | Ensure nftables established connections are configured | Add output icmp new, related, established accept policy" when: '"ip protocol icmp ct state established,related,new accept" not in discovered_nftables_outconnectionrule.stdout' ansible.builtin.command: nft add rule inet "{{ rhel9cis_nft_tables_tablename }}" output ip protocol icmp ct state new,related,established accept + changed_when: true - name: "4.3.3 | PATCH | Ensure nftables default deny firewall policy" - when: - - rhel9cis_rule_4_3_3 + when: rhel9cis_rule_4_3_3 tags: - level1-server - level1-workstation @@ -118,25 +129,29 @@ - NIST800-55_CA-9 block: - name: "4.3.3 | AUDIT | Ensure nftables default deny firewall policy | Check for hook input deny policy" - ansible.builtin.shell: nft list table inet "{{ rhel9cis_nft_tables_tablename }}" | grep 'hook input' + ansible.builtin.shell: | + nft list table inet "{{ rhel9cis_nft_tables_tablename }}" | grep 'hook input' failed_when: false changed_when: false register: discovered_nftables_inputpolicy - name: "4.3.3 | AUDIT | Ensure nftables default deny firewall policy | Check for hook forward deny policy" - ansible.builtin.shell: nft list table inet "{{ rhel9cis_nft_tables_tablename }}" | grep 'hook forward' + ansible.builtin.shell: | + nft list table inet "{{ rhel9cis_nft_tables_tablename }}" | grep 'hook forward' failed_when: false changed_when: false register: discovered_nftables_forwardpolicy - name: "4.3.3 | AUDIT | Ensure nftables default deny firewall policy | Check for hook output deny policy" - ansible.builtin.shell: nft list table inet "{{ rhel9cis_nft_tables_tablename }}" | grep 'hook output' + ansible.builtin.shell: | + nft list table inet "{{ rhel9cis_nft_tables_tablename }}" | grep 'hook output' failed_when: false changed_when: false register: discovered_nftables_outputpolicy - name: "4.3.3 | AUDIT | Ensure nftables default deny firewall policy | Check for SSH allow" - ansible.builtin.shell: nft list table inet "{{ rhel9cis_nft_tables_tablename }}" | grep 'ssh' + ansible.builtin.shell: | + nft list table inet "{{ rhel9cis_nft_tables_tablename }}" | grep 'ssh' failed_when: false changed_when: false register: discovered_nftables_sshallowcheck @@ -144,22 +159,25 @@ - name: "4.3.3 | PATCH | Ensure nftables default deny firewall policy | Enable SSH traffic" when: '"tcp dport ssh accept" not in discovered_nftables_sshallowcheck.stdout' ansible.builtin.command: nft add rule inet "{{ rhel9cis_nft_tables_tablename }}" input tcp dport ssh accept + changed_when: true - name: "4.3.3 | PATCH | Ensure nftables default deny firewall policy | Set hook input deny policy" when: '"type filter hook input priority 0; policy drop;" not in discovered_nftables_inputpolicy.stdout' ansible.builtin.command: nft chain inet "{{ rhel9cis_nft_tables_tablename }}" input { policy drop \; } + changed_when: true - name: "4.3.3 | PATCH | Ensure nftables default deny firewall policy | Create hook forward deny policy" when: '"type filter hook forward priority 0; policy drop;" not in discovered_nftables_forwardpolicy.stdout' ansible.builtin.command: nft chain inet "{{ rhel9cis_nft_tables_tablename }}" forward { policy drop \; } + changed_when: true - name: "4.3.3 | PATCH | Ensure nftables default deny firewall policy | Create hook output deny policy" when: '"type filter hook output priority 0; policy drop;" not in discovered_nftables_outputpolicy.stdout' ansible.builtin.command: nft chain inet "{{ rhel9cis_nft_tables_tablename }}" output { policy drop \; } + changed_when: true - name: "4.3.4 | PATCH | Ensure nftables loopback traffic is configured" - when: - - rhel9cis_rule_4_3_4 + when: rhel9cis_rule_4_3_4 tags: - level1-server - level1-workstation @@ -169,19 +187,22 @@ - NIST800-55_CA-9 block: - name: "4.3.4 | AUDIT | Ensure nftables loopback traffic is configured | Gather iif lo accept existence | nftables" - ansible.builtin.shell: nft list ruleset | awk '/hook input/,/}/' | grep 'iif "lo" accept' + ansible.builtin.shell: | + nft list ruleset | awk '/hook input/,/}/' | grep 'iif "lo" accept' changed_when: false failed_when: false register: discovered_nftables_iiflo - name: "4.3.4 | AUDIT | Ensure nftables loopback traffic is configured | Gather ip saddr existence | nftables" - ansible.builtin.shell: nft list ruleset | awk '/hook input/,/}/' | grep 'ip saddr' + ansible.builtin.shell: | + nft list ruleset | awk '/hook input/,/}/' | grep 'ip saddr' changed_when: false failed_when: false register: discovered_nftables_ipsaddr - name: "4.3.4 | AUDIT | Ensure nftables loopback traffic is configured | Gather ip6 saddr existence | nftables" - ansible.builtin.shell: nft list ruleset | awk '/hook input/,/}/' | grep 'ip6 saddr' + ansible.builtin.shell: | + nft list ruleset | awk '/hook input/,/}/' | grep 'ip6 saddr' changed_when: false failed_when: false register: discovered_nftables_ip6saddr @@ -189,11 +210,14 @@ - name: "4.3.4 | PATCH | Ensure nftables loopback traffic is configured | Set iif lo accept rule | nftables" when: '"iif \"lo\" accept" not in discovered_nftables_iiflo.stdout' ansible.builtin.command: nft add rule inet "{{ rhel9cis_nft_tables_tablename }}" input iif lo accept + changed_when: true - name: "4.3.4 | PATCH | Ensure nftables loopback traffic is configured | Set ip sddr rule | nftables" when: '"ip saddr 127.0.0.0/8 counter packets 0 bytes 0 drop" not in discovered_nftables_ipsaddr.stdout' ansible.builtin.command: nft add rule inet "{{ rhel9cis_nft_tables_tablename }}" input ip saddr 127.0.0.0/8 counter drop + changed_when: true - name: "4.3.4 | PATCH | Ensure nftables loopback traffic is configured | Set ip6 saddr rule | nftables" when: '"ip6 saddr ::1 counter packets 0 bytes 0 drop" not in discovered_nftables_ip6saddr.stdout' ansible.builtin.command: nft add rule inet "{{ rhel9cis_nft_tables_tablename }}" input ip6 saddr ::1 counter drop + changed_when: true diff --git a/tasks/section_5/cis_5.3.2.x.yml b/tasks/section_5/cis_5.3.2.x.yml index 18e9cfd..696010f 100644 --- a/tasks/section_5/cis_5.3.2.x.yml +++ b/tasks/section_5/cis_5.3.2.x.yml @@ -17,12 +17,13 @@ when: - rhel9cis_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 {{ rhel9cis_authselect_custom_profile_name }} -b {{ rhel9cis_authselect_default_profile_to_copy }}" + ansible.builtin.command: "/usr/bin/authselect create-profile {{ rhel9cis_authselect_custom_profile_name }} -b {{ rhel9cis_authselect_default_profile_to_copy }}" + changed_when: false args: creates: "/etc/authselect/custom/{{ rhel9cis_authselect_custom_profile_name }}" - name: "5.3.2.1 | AUDIT | Ensure active authselect profile includes pam modules | get profile features" - ansible.builtin.shell: "/usr/bin/authselect list-features custom/{{ rhel9cis_authselect_custom_profile_name }}" + ansible.builtin.command: "/usr/bin/authselect list-features custom/{{ rhel9cis_authselect_custom_profile_name }}" changed_when: false register: discovered_authselect_profile_features @@ -37,7 +38,8 @@ - password - name: "5.3.2.1 | PATCH | Ensure active authselect profile includes pam modules | Backup and Add pam modules" - ansible.builtin.shell: "/usr/bin/authselect select custom/{{ rhel9cis_authselect_custom_profile_name }}{% if rhel9cis_rule_5_3_2_2 %} with-faillock{% endif %}{% if rhel9cis_rule_5_3_2_3 %} with-pwquality{% endif %}{% if rhel9cis_rule_5_3_2_4 %} with-pwhistory{% endif %}{% if rhel9cis_rule_5_3_3_4_1 %} without-nullok{% endif %} --force --backup=rhel9cis-preremediate-{{ lookup('pipe', 'date +%Y-%m-%d-%H%M') }}" + ansible.builtin.command: "/usr/bin/authselect select custom/{{ rhel9cis_authselect_custom_profile_name }}{% if rhel9cis_rule_5_3_2_2 %} with-faillock{% endif %}{% if rhel9cis_rule_5_3_2_3 %} with-pwquality{% endif %}{% if rhel9cis_rule_5_3_2_4 %} with-pwhistory{% endif %}{% if rhel9cis_rule_5_3_3_4_1 %} without-nullok{% endif %} --force --backup=rhel9cis-preremediate-{{ lookup('pipe', 'date +%Y-%m-%d-%H%M') }}" + changed_when: true - name: "5.3.2.2 | PATCH | Ensure pam_faillock module is enabled" when: @@ -59,14 +61,16 @@ notify: Authselect update block: - name: "5.3.2.2 | AUDIT | Ensure pam_faillock module is enabled | Get current config" - ansible.builtin.shell: authselect current | grep faillock + ansible.builtin.shell: | + authselect current | grep faillock changed_when: false failed_when: discovered_authselect_current_faillock.rc not in [ 0, 1 ] register: discovered_authselect_current_faillock - name: "5.3.2.2 | AUDIT | Ensure pam_faillock module is enabled | Add feature if missing" when: discovered_authselect_current_faillock.rc != 0 - ansible.builtin.shell: "/usr/bin/authselect select custom/{{ rhel9cis_authselect_custom_profile_name }}{% if rhel9cis_rule_5_3_2_2 %} with-faillock{% endif %}{% if rhel9cis_rule_5_3_2_3 %} with-pwquality{% endif %}{% if rhel9cis_rule_5_3_2_4 %} with-pwhistory{% endif %}{% if rhel9cis_rule_5_3_3_4_1 %} without-nullok{% endif %}" + ansible.builtin.command: "/usr/bin/authselect select custom/{{ rhel9cis_authselect_custom_profile_name }}{% if rhel9cis_rule_5_3_2_2 %} with-faillock{% endif %}{% if rhel9cis_rule_5_3_2_3 %} with-pwquality{% endif %}{% if rhel9cis_rule_5_3_2_4 %} with-pwhistory{% endif %}{% if rhel9cis_rule_5_3_3_4_1 %} without-nullok{% endif %}" + changed_when: true - name: "5.3.2.3 | PATCH | Ensure pam_pwquality module is enabled" when: @@ -83,14 +87,16 @@ - rule_5.3.2.3 block: - name: "5.3.2.3 | AUDIT | Ensure pam_pwquality module is enabled | Get current config" - ansible.builtin.shell: authselect current | grep quality + ansible.builtin.shell: | + authselect current | grep quality changed_when: false failed_when: discovered_authselect_current_quality.rc not in [ 0, 1 ] register: discovered_authselect_current_quality - - name: "5.3.2.3 | AUDIT | Ensure pam_pwquality module is enabled | Add feature if missing" + - name: "5.3.2.3 | PATCH | 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/{{ rhel9cis_authselect_custom_profile_name }}{% if rhel9cis_rule_5_3_2_2 %} with-faillock{% endif %}{% if rhel9cis_rule_5_3_2_3 %} with-pwquality{% endif %}{% if rhel9cis_rule_5_3_2_4 %} with-pwhistory{% endif %}{% if rhel9cis_rule_5_3_3_4_1 %} without-nullok{% endif %}" + ansible.builtin.command: "/usr/bin/authselect select custom/{{ rhel9cis_authselect_custom_profile_name }}{% if rhel9cis_rule_5_3_2_2 %} with-faillock{% endif %}{% if rhel9cis_rule_5_3_2_3 %} with-pwquality{% endif %}{% if rhel9cis_rule_5_3_2_4 %} with-pwhistory{% endif %}{% if rhel9cis_rule_5_3_3_4_1 %} without-nullok{% endif %}" + changed_when: true notify: Authselect update - name: "5.3.2.4 | PATCH | Ensure pam_pwhistory module is enabled" @@ -108,14 +114,16 @@ - rule_5.3.2.4 block: - name: "5.3.2.4 | AUDIT | Ensure pam_pwhistory module is enabled | Get current config" - ansible.builtin.shell: authselect current | grep pwhistory + ansible.builtin.shell: | + authselect current | grep pwhistory changed_when: false failed_when: discovered_authselect_current_history.rc not in [ 0, 1 ] register: discovered_authselect_current_history - name: "5.3.2.4 | PATCH | Ensure pam_pwhistory module is enabled | enable feature" when: discovered_authselect_current_history.rc != 0 - ansible.builtin.shell: "/usr/bin/authselect select custom/{{ rhel9cis_authselect_custom_profile_name }}{% if rhel9cis_rule_5_3_2_2 %} with-faillock{% endif %}{% if rhel9cis_rule_5_3_2_3 %} with-pwquality{% endif %}{% if rhel9cis_rule_5_3_2_4 %} with-pwhistory{% endif %}{% if rhel9cis_rule_5_3_3_4_1 %} without-nullok{% endif %}" + ansible.builtin.command: "/usr/bin/authselect select custom/{{ rhel9cis_authselect_custom_profile_name }}{% if rhel9cis_rule_5_3_2_2 %} with-faillock{% endif %}{% if rhel9cis_rule_5_3_2_3 %} with-pwquality{% endif %}{% if rhel9cis_rule_5_3_2_4 %} with-pwhistory{% endif %}{% if rhel9cis_rule_5_3_3_4_1 %} without-nullok{% endif %}" + changed_when: true notify: Authselect update - name: "5.3.2.5 | PATCH | Ensure pam_unix module is enabled" @@ -146,8 +154,8 @@ regexp: "{{ item.regexp }}" line: "{{ item.line }}" backrefs: true - insertafter: "{{ item.after | default (omit) }}" - insertbefore: "{{ item.before | default (omit) }}" + insertafter: "{{ item.after | default(omit) }}" + insertbefore: "{{ item.before | default(omit) }}" 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' } @@ -160,8 +168,8 @@ line: "{{ item.line }}" regexp: "{{ item.regexp }}" backrefs: true - insertafter: "{{ item.after | default (omit) }}" - insertbefore: "{{ item.before | default (omit) }}" + insertafter: "{{ item.after | default(omit) }}" + insertbefore: "{{ item.before | default(omit) }}" 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' } diff --git a/tasks/section_5/cis_5.3.3.1.x.yml b/tasks/section_5/cis_5.3.3.1.x.yml index 8206074..d625cac 100644 --- a/tasks/section_5/cis_5.3.3.1.x.yml +++ b/tasks/section_5/cis_5.3.3.1.x.yml @@ -104,6 +104,7 @@ line: "{{ rhel9cis_pamroot_lock_option }}" insertafter: '^# end of pam-auth-update config' create: true + mode: 'u-x,go-wx' - name: "5.3.3.1.3 | PATCH | Ensure password failed attempts lockout includes root account | remove lockout from pam files NOT AuthSelect" when: diff --git a/tasks/section_5/cis_5.4.1.x.yml b/tasks/section_5/cis_5.4.1.x.yml index 9e92e86..732fc5c 100644 --- a/tasks/section_5/cis_5.4.1.x.yml +++ b/tasks/section_5/cis_5.4.1.x.yml @@ -96,7 +96,8 @@ - discovered_warn_days.stdout_lines | length > 0 - item in prelim_interactive_usernames.stdout - rhel9cis_force_user_warnage - ansible.builtin.shell: "chage --warndays {{ rhel9cis_pass['warn_age'] }} {{ item }}" + ansible.builtin.command: "chage --warndays {{ rhel9cis_pass['warn_age'] }} {{ item }}" + changed_when: true loop: "{{ discovered_warn_days.stdout_lines }}" - name: "5.4.1.4 | PATCH | Ensure strong password hashing algorithm is configured" @@ -125,25 +126,29 @@ - rule_5.4.1.5 block: - name: "5.4.1.5 | AUDIT | Ensure inactive password lock is configured | Check current settings" - ansible.builtin.shell: useradd -D | grep INACTIVE={{ rhel9cis_inactivelock.lock_days }} | cut -f2 -d= + ansible.builtin.shell: | + useradd -D | grep INACTIVE={{ rhel9cis_inactivelock.lock_days }} | cut -f2 -d= changed_when: false failed_when: false check_mode: false register: discovered_passwdlck_inactive_settings - name: "5.4.1.5 | PATCH | Ensure inactive password lock is configured | Set default inactive setting" - ansible.builtin.shell: useradd -D -f {{ rhel9cis_inactivelock.lock_days }} when: discovered_passwdlck_inactive_settings.stdout | length == 0 + ansible.builtin.command: useradd -D -f {{ rhel9cis_inactivelock.lock_days }} + changed_when: true - name: "5.4.1.5 | AUDIT | Ensure inactive password lock is 30 days or less | Getting user list" - ansible.builtin.shell: "awk -F: '/^[^#:]+:[^\\!\\*:]*:[^:]*:[^:]*:[^:]*:[^:]*:(\\s*|-1|3[1-9]|[4-9][0-9]|[1-9][0-9][0-9]+):[^:]*:[^:]*\\s*$/ {print $1}' /etc/shadow" + ansible.builtin.shell: | + "awk -F: '/^[^#:]+:[^\\!\\*:]*:[^:]*:[^:]*:[^:]*:[^:]*:(\\s*|-1|3[1-9]|[4-9][0-9]|[1-9][0-9][0-9]+):[^:]*:[^:]*\\s*$/ {print $1}' /etc/shadow" changed_when: false check_mode: false register: discovered_passwdlck_user_list - name: "5.4.1.5 | PATCH | Ensure inactive password lock is 30 days or less | Apply Inactive setting to existing accounts" when: item in prelim_interactive_usernames.stdout - ansible.builtin.shell: chage --inactive {{ rhel9cis_inactivelock.lock_days }} "{{ item }}" + ansible.builtin.command: chage --inactive {{ rhel9cis_inactivelock.lock_days }} "{{ item }}" + changed_when: true loop: "{{ discovered_passwdlck_user_list.stdout_lines }}" - name: "5.4.1.6 | PATCH | Ensure all users last password change date is in the past" @@ -172,22 +177,23 @@ register: discovered_passwdlck_user_future - name: "5.4.1.6 | AUDIT | Ensure all users last password change date is in the past | Alert on accounts with pw change in the future" + when: + - discovered_passwdlck_user_future.stdout | length > 0 + - not rhel9cis_futurepwchgdate_autofix ansible.builtin.debug: msg: "Warning!! The following accounts have the last PW change date in the future: {{ discovered_passwdlck_user_future.stdout_lines }}" - when: - - discovered_passwdlck_user_future.stdout | length > 0 - - not rhel9cis_futurepwchgdate_autofix - name: "5.4.1.6 | AUDIT | Ensure all users last password change date is in the past | warning count" - ansible.builtin.import_tasks: - file: warning_facts.yml when: - discovered_passwdlck_user_future.stdout | length > 0 - not rhel9cis_futurepwchgdate_autofix + ansible.builtin.import_tasks: + file: warning_facts.yml - name: "5.4.1.6 | PATCH | Ensure all users last password change date is in the past | Fix accounts with pw change in the future" - ansible.builtin.shell: passwd --expire {{ item }} + changed_when: true when: - discovered_passwdlck_user_future.stdout | length > 0 - rhel9cis_futurepwchgdate_autofix loop: "{{ discovered_passwdlck_user_future.stdout_lines }}" + ansible.builtin.command: passwd --expire {{ item }} diff --git a/tasks/section_5/cis_5.4.2.x.yml b/tasks/section_5/cis_5.4.2.x.yml index 2cf378c..a367f72 100644 --- a/tasks/section_5/cis_5.4.2.x.yml +++ b/tasks/section_5/cis_5.4.2.x.yml @@ -17,7 +17,7 @@ - NIST800-53R5_CM-6 - NIST800-53R5_CM-7 - NIST800-53R5_IA-5 - ansible.builtin.shell: passwd -l {{ item }} + ansible.builtin.command: passwd -l {{ item }} changed_when: false failed_when: false loop: "{{ prelim_uid_zero_accounts_except_root.stdout_lines }}" @@ -194,6 +194,7 @@ regexp: \s*umask line: "umask {{ rhel9cis_root_umask }}" create: true + mode: 'u+x,go-rwx' - name: "5.4.2.7 | PATCH | Ensure system accounts do not have a valid login shell" when: diff --git a/tasks/section_6/cis_6.1.x.yml b/tasks/section_6/cis_6.1.x.yml index f889cd4..c000fe1 100644 --- a/tasks/section_6/cis_6.1.x.yml +++ b/tasks/section_6/cis_6.1.x.yml @@ -45,7 +45,8 @@ rhel9cis_aide_db_recreate block: - name: "6.1.1 | PATCH | Ensure AIDE is installed | Build AIDE DB" - ansible.builtin.shell: "{{ aide_initiate_command }}" + ansible.builtin.command: "{{ aide_initiate_command }}" + changed_when: true - name: "6.1.1 | PATCH | Ensure AIDE is installed | Build AIDE DB | Wait for file before continuing" ansible.builtin.wait_for: @@ -56,6 +57,7 @@ src: /var/lib/aide/aide.db.new.gz dest: /var/lib/aide/aide.db.gz remote_src: true + mode: 'ug-wx,o-rwx' - name: "6.1.2 | PATCH | Ensure filesystem integrity is regularly checked" when: @@ -85,15 +87,15 @@ - name: "6.1.2 | PATCH | Ensure filesystem integrity is regularly checked | aide service" when: rhel9cis_aide_scan == "timer" - ansible.builtin.systemd: + ansible.builtin.systemd_service: name: aidecheck.service enabled: true - name: "6.1.2 | PATCH | Ensure filesystem integrity is regularly checked | aide service" when: rhel9cis_aide_scan == "timer" - ansible.builtin.systemd: + ansible.builtin.systemd_service: name: aidecheck.timer - state: running + state: started enabled: true - name: "6.1.3 | PATCH | Ensure cryptographic mechanisms are used to protect the integrity of audit tools" diff --git a/tasks/section_6/cis_6.3.1.x.yml b/tasks/section_6/cis_6.3.1.x.yml index 3039f2c..b054848 100644 --- a/tasks/section_6/cis_6.3.1.x.yml +++ b/tasks/section_6/cis_6.3.1.x.yml @@ -1,8 +1,7 @@ --- - name: "6.3.1.1 | PATCH | Ensure auditd is installed" - when: - - rhel9cis_rule_6_3_1_1 + when: rhel9cis_rule_6_3_1_1 tags: - level2-server - level2-workstation @@ -27,8 +26,7 @@ state: present - name: "6.3.1.2 | PATCH | Ensure auditing for processes that start prior to auditd is enabled" - when: - - rhel9cis_rule_6_3_1_2 + when: rhel9cis_rule_6_3_1_2 tags: - level2-server - level2-workstation @@ -49,7 +47,8 @@ - discovered_grubby_curr_value_audit_linux.stdout == '' or '0' in discovered_grubby_curr_value_audit_linux.stdout or 'off' in discovered_grubby_curr_value_audit_linux.stdout|lower - ansible.builtin.shell: grubby --update-kernel=ALL --args="audit=1" + ansible.builtin.command: grubby --update-kernel=ALL --args="audit=1" + changed_when: true - name: "6.3.1.3 | PATCH | Ensure audit_backlog_limit is sufficient" when: @@ -81,17 +80,16 @@ discovered_reset_backlog_limits: true - name: "6.3.1.3 | AUDIT | Check to see if any limits are too low" - when: - - (item | int < rhel9cis_audit_back_log_limit) + when: (item | int < rhel9cis_audit_back_log_limit) ansible.builtin.set_fact: discovered_reset_backlog_limits: true loop: "{{ discovered_grubby_curr_value_backlog_linux.stdout_lines }}" - name: "6.3.1.3 | AUDIT | Ensure audit_backlog_limit is sufficient | Grubby update applied" - when: - - discovered_reset_backlog_limits is defined - ansible.builtin.shell: + when: discovered_reset_backlog_limits is defined + ansible.builtin.command: cmd: 'grubby --update-kernel=ALL --args="audit_backlog_limit={{ rhel9cis_audit_back_log_limit }}"' + changed_when: true - name: "6.3.1.4 | PATCH | Ensure auditd service is enabled and active" when: diff --git a/tasks/section_7/cis_7.1.x.yml b/tasks/section_7/cis_7.1.x.yml index 232b224..d70bf5f 100644 --- a/tasks/section_7/cis_7.1.x.yml +++ b/tasks/section_7/cis_7.1.x.yml @@ -221,7 +221,7 @@ warn_control_id: '7.1.12' block: - name: "7.1.12 | AUDIT | Ensure no files or directories without an owner and a group exist | Get list files or directories" - ansible.builtin.shell: find {{ rhel9cis_exclude_unowned_search_path }} {{ item.mount }} -xdev \( -nouser -o -nogroup \) -not -fstype nfs + ansible.builtin.command: find {{ rhel9cis_exclude_unowned_search_path }} {{ item.mount }} -xdev \( -nouser -o -nogroup \) -not -fstype nfs changed_when: false failed_when: false check_mode: false @@ -283,7 +283,7 @@ warn_control_id: '7.1.13' block: - name: "7.1.13 | AUDIT | Ensure SUID and SGID files are reviewed | Find SUID and SGID" - ansible.builtin.shell: find {{ item.mount }} -xdev -type f -perm \( -02000 or -04000 \) -not -fstype nfs + ansible.builtin.command: find {{ item.mount }} -xdev -type f -perm \( -02000 or -04000 \) -not -fstype nfs changed_when: false failed_when: false check_mode: false diff --git a/tasks/section_7/cis_7.2.x.yml b/tasks/section_7/cis_7.2.x.yml index 47d48f6..2a33f33 100644 --- a/tasks/section_7/cis_7.2.x.yml +++ b/tasks/section_7/cis_7.2.x.yml @@ -237,13 +237,13 @@ - users - rule_7.2.8 block: - - name: "7.2.8 | PATCH | Ensure local interactive user home directories are configured | Create dir if absent" + - name: "7.2.8 | PATCH | Ensure local interactive user home directories are configured | Create dir if absent" # noqa risky-file-permissions ansible.builtin.file: path: "{{ item.dir }}" state: directory owner: "{{ item.id }}" group: "{{ item.gid }}" - loop: "{{ rhel9cis_passwd | selectattr('uid', '>=', prelim_min_int_uid | int) | selectattr('uid', '<=', max_int_uid | int) | list }}" + loop: "{{ rhel9cis_passwd | selectattr('uid', '>=', prelim_min_int_uid | int) | selectattr('uid', '<=', prelim_max_int_uid | int) | list }}" loop_control: label: "{{ item.id }}" diff --git a/tasks/warning_facts.yml b/tasks/warning_facts.yml index 98cd4b6..36f61cb 100644 --- a/tasks/warning_facts.yml +++ b/tasks/warning_facts.yml @@ -14,7 +14,7 @@ # # warn_count the main variable for the number of warnings and each time a warn_control_id is added # the count increases by a value of 1 -- name: "{{ warn_control_id }} | AUDIT | Set fact for manual task warning." +- name: "{{ warn_control_id }} | AUDIT | Set fact for manual task warning." # noqa name[template] ansible.builtin.set_fact: warn_control_list: "{{ warn_control_list }} [{{ warn_control_id }}]" warn_count: "{{ warn_count | int + 1 }}" diff --git a/vars/audit.yml b/vars/audit.yml index e54deb8..1dc1cf1 100644 --- a/vars/audit.yml +++ b/vars/audit.yml @@ -35,7 +35,7 @@ audit_format: json audit_vars_path: "{{ audit_conf_dir }}/vars/{{ ansible_facts.hostname }}.yml" audit_results: | - The{% if not audit_only %} pre remediation{% endif %} audit results are: {{ pre_audit_results}} + 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 }} From 67df5b77b2633966caf0af79baf5e8c32be3c6b2 Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Wed, 11 Dec 2024 12:03:54 +0000 Subject: [PATCH 17/22] file updated and moved from templates Signed-off-by: Mark Bolwell --- {files => templates}/fs_with_cves.sh | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename {files => templates}/fs_with_cves.sh (100%) diff --git a/files/fs_with_cves.sh b/templates/fs_with_cves.sh similarity index 100% rename from files/fs_with_cves.sh rename to templates/fs_with_cves.sh From 51de8bf7c9931ffc038eb55f5cb70fffa5a693ec Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Wed, 11 Dec 2024 12:06:45 +0000 Subject: [PATCH 18/22] update var naming Signed-off-by: Mark Bolwell --- tasks/parse_etc_password.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tasks/parse_etc_password.yml b/tasks/parse_etc_password.yml index 49941bf..337889c 100644 --- a/tasks/parse_etc_password.yml +++ b/tasks/parse_etc_password.yml @@ -8,12 +8,12 @@ ansible.builtin.command: cat /etc/passwd changed_when: false check_mode: false - register: rhel9cis_passwd_file_audit + register: prelim_passwd_file_audit - name: "PRELIM | 5.5.2 | 6.2.7 | 6.2.8 | 6.2.20 | Split passwd entries" ansible.builtin.set_fact: - rhel9cis_passwd: "{{ rhel9cis_passwd_file_audit.stdout_lines | map('regex_replace', ld_passwd_regex, ld_passwd_yaml) | map('from_yaml') | list }}" - loop: "{{ rhel9cis_passwd_file_audit.stdout_lines }}" + rhel9cis_passwd: "{{ prelim_passwd_file_audit.stdout_lines | map('regex_replace', ld_passwd_regex, ld_passwd_yaml) | map('from_yaml') | list }}" + loop: "{{ prelim_passwd_file_audit.stdout_lines }}" vars: ld_passwd_regex: >- ^(?P[^:]*):(?P[^:]*):(?P[^:]*):(?P[^:]*):(?P[^:]*):(?P[^:]*):(?P[^:]*) From 148165ad4d578e43054b3174ae9277ca640c109e Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Wed, 11 Dec 2024 12:32:59 +0000 Subject: [PATCH 19/22] tidy up script as copy not template Signed-off-by: Mark Bolwell --- {templates => files}/fs_with_cves.sh | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) rename {templates => files}/fs_with_cves.sh (98%) diff --git a/templates/fs_with_cves.sh b/files/fs_with_cves.sh similarity index 98% rename from templates/fs_with_cves.sh rename to files/fs_with_cves.sh index a6d937c..a2bc1b7 100644 --- a/templates/fs_with_cves.sh +++ b/files/fs_with_cves.sh @@ -1,4 +1,4 @@ -{% raw %}#! /usr/bin/env bash +#! /usr/bin/env bash # Based on original Script provided by CIS # CVEs correct at time of creation - April2024 @@ -54,4 +54,3 @@ #[ "${#a_output[@]}" -gt 0 ] && printf '%s\n' "" "-- Correctly set: --" "${a_output[@]}" "" fi } -{% endraw %} From 8cbf82bbc9e2c2cf7d2b23b7293870be570d0979 Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Wed, 11 Dec 2024 12:35:48 +0000 Subject: [PATCH 20/22] improve layout 1.2.1.1 Signed-off-by: Mark Bolwell --- tasks/section_1/cis_1.2.1.x.yml | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/tasks/section_1/cis_1.2.1.x.yml b/tasks/section_1/cis_1.2.1.x.yml index 454fd95..960b495 100644 --- a/tasks/section_1/cis_1.2.1.x.yml +++ b/tasks/section_1/cis_1.2.1.x.yml @@ -14,9 +14,8 @@ - rule_1.2.1.1 - NIST800-53R5_SI-2 block: - - name: "1.2.1.1 | AUDIT | Ensure GPG keys are configured | list installed pubkey keys" - ansible.builtin.shell: | - "rpm -qa | grep {{ os_gpg_key_pubkey_name }}" + - name: "1.2.1.1 | AUDIT | Ensure GPG keys are configured | List installed pubkey keys" + ansible.builtin.shell: "rpm -qa | grep {{ os_gpg_key_pubkey_name }}" # noqa command-instead-of-module changed_when: false failed_when: false register: discovered_os_installed_pub_keys @@ -29,7 +28,7 @@ register: discovered_os_gpg_key_check when: discovered_os_installed_pub_keys.rc == 0 - - name: "1.2.1.1 | AUDIT | Ensure GPG keys are configured | expected keys fail" + - name: "1.2.1.1 | AUDIT | Ensure GPG keys are configured | If expected keys fail" when: - discovered_os_installed_pub_keys.rc == 1 or discovered_os_gpg_key_check.rc == 1 From ae228e3f96ea776627239810e218bfdc8b388eb9 Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Wed, 11 Dec 2024 12:37:40 +0000 Subject: [PATCH 21/22] 5.4.1.5 improvemet Signed-off-by: Mark Bolwell --- tasks/section_5/cis_5.4.1.x.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tasks/section_5/cis_5.4.1.x.yml b/tasks/section_5/cis_5.4.1.x.yml index 732fc5c..72dc50f 100644 --- a/tasks/section_5/cis_5.4.1.x.yml +++ b/tasks/section_5/cis_5.4.1.x.yml @@ -139,8 +139,7 @@ changed_when: true - name: "5.4.1.5 | AUDIT | Ensure inactive password lock is 30 days or less | Getting user list" - ansible.builtin.shell: | - "awk -F: '/^[^#:]+:[^\\!\\*:]*:[^:]*:[^:]*:[^:]*:[^:]*:(\\s*|-1|3[1-9]|[4-9][0-9]|[1-9][0-9][0-9]+):[^:]*:[^:]*\\s*$/ {print $1}' /etc/shadow" + ansible.builtin.shell: "awk -F: '/^[^#:]+:[^\\!\\*:]*:[^:]*:[^:]*:[^:]*:[^:]*:(\\s*|-1|3[1-9]|[4-9][0-9]|[1-9][0-9][0-9]+):[^:]*:[^:]*\\s*$/ {print $1}' /etc/shadow" changed_when: false check_mode: false register: discovered_passwdlck_user_list From c65e9cabb86dde67aef636be46ea5426f5c89eba Mon Sep 17 00:00:00 2001 From: Mark Bolwell Date: Wed, 11 Dec 2024 13:39:16 +0000 Subject: [PATCH 22/22] updated mode for line 131 Signed-off-by: Mark Bolwell --- tasks/section_1/cis_1.1.2.1.x.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tasks/section_1/cis_1.1.2.1.x.yml b/tasks/section_1/cis_1.1.2.1.x.yml index 355c32b..9cca1ec 100644 --- a/tasks/section_1/cis_1.1.2.1.x.yml +++ b/tasks/section_1/cis_1.1.2.1.x.yml @@ -128,5 +128,5 @@ dest: /etc/systemd/system/tmp.mount owner: root group: root - mode: "go-wx" + mode: 'go-wx' notify: *mount_option_notify