diff --git a/.ansible-lint b/.ansible-lint index 3b7c373..7aa8478 100644 --- a/.ansible-lint +++ b/.ansible-lint @@ -1,6 +1,5 @@ --- -parseable: true quiet: true skip_list: - 'package-latest' diff --git a/.github/workflows/export_badges_private.yml b/.github/workflows/export_badges_private.yml index d316cbf..761c42e 100644 --- a/.github/workflows/export_badges_private.yml +++ b/.github/workflows/export_badges_private.yml @@ -12,8 +12,6 @@ on: push: branches: - latest - schedule: - - cron: '0 */6 * * *' workflow_dispatch: jobs: diff --git a/CONTRIBUTING.rst b/CONTRIBUTING.rst index 13e0b49..d7cdcbf 100644 --- a/CONTRIBUTING.rst +++ b/CONTRIBUTING.rst @@ -7,7 +7,7 @@ Rules 2) All commits must have Signed-off-by (Signed-off-by: Joan Doe ) in the commit message (details in Signing section) 3) All work is done in your own branch 4) All pull requests go into the devel branch. There are automated checks for signed commits, signoff in commit message, and functional testing) -5) Be open and nice to eachother +5) Be open and nice to each other Workflow -------- diff --git a/Changelog.md b/Changelog.md index c5ef6e1..bd7162b 100644 --- a/Changelog.md +++ b/Changelog.md @@ -6,7 +6,7 @@ addressed issue #419, thank you @aaronk1 addressed issue #418 thank you @bbaassssiiee Added better sysctl logic to disable IPv6 Added option to disable IPv6 via sysctl (original method) or via the kernel -pre-commit udpates +pre-commit updates public issue #410 thanks to @kpi-nourman public issue #413 thanks to @bbaassssiiee Public issues incorporated @@ -18,6 +18,8 @@ Benchmark version variable in audit template fixed typo thanks to @fragglexarmy #393 fixed typo thanks to @trumbaut #397 & #399 updated auditd template to be 2.19 complaint +PR345 thanks to thulium-drake boot password hash - if used needs passlib module +tidy up tags on tasks/main.yml ## 2.0.3 - Based on CIS v2.0.0 diff --git a/README.md b/README.md index 2d34dd8..62e316f 100644 --- a/README.md +++ b/README.md @@ -128,6 +128,9 @@ RHEL Family OS 9 - python-def - libselinux-python +If you are using the option to create your own bootloader hash the ansible controller +- passlib + --- ## Auditing 🔍 diff --git a/defaults/main.yml b/defaults/main.yml index 2fdb1f6..931ea93 100644 --- a/defaults/main.yml +++ b/defaults/main.yml @@ -566,14 +566,18 @@ rhel9cis_selinux_pol: targeted rhel9cis_selinux_enforce: enforcing ## Control 1.4.1 -# This variable will store the hashed GRUB bootloader password to be stored in '/boot/grub2/user.cfg' file. The default value -# must be changed to a value that may be generated with this command 'grub2-mkpasswd-pbkdf2' and must comply with -# this format: 'grub.pbkdf2.sha512...' +# This variable governs whether a bootloader password should be set in '/boot/grub2/user.cfg' file. +rhel9cis_set_boot_pass: false + +# Either set rhel9cis_bootloader_password_hash or rhel9cis_bootloader_password and rhel9cis_bootloader_salt +# If you are not using the bootloader hash filter you can set it here if the encrypted format e.g. grub.pbkdf2.sha512.hashstring rhel9cis_bootloader_password_hash: 'grub.pbkdf2.sha512.changethispassword' # pragma: allowlist secret -## Control 1.4.1 -# This variable governs whether a bootloader password should be set in '/boot/grub2/user.cfg' file. -rhel9cis_set_boot_pass: true +# This variable will store the GRUB bootloader password to be stored in '/boot/grub2/user.cfg' file. The default value must be changed. +rhel9cis_bootloader_password: 'password' # pragma: allowlist secret + +# Set this value to anything secure to have predictable hashes, which will prevent unnecessary changes +rhel9cis_bootloader_salt: '' ## Controls 1.6.x and Controls 5.1.x # This variable governs if current Ansible role should manage system-wide crypto policy. diff --git a/filter_plugins/grub_hash.py b/filter_plugins/grub_hash.py new file mode 100644 index 0000000..245756b --- /dev/null +++ b/filter_plugins/grub_hash.py @@ -0,0 +1,73 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +# Copyright (c) 2025, Jeffrey van Pelt +# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt) +# SPDX-License-Identifier: GPL-3.0-or-later + +from __future__ import annotations + +DOCUMENTATION = r""" +name: grub_hash +short_description: Generate a GRUB2 password hash +version_added: 1.0.0 +author: Jeffrey van Pelt (@Thulium-Drake) +description: + - Generate a GRUB2 password hash from the input +options: + _input: + description: The desired password for the GRUB bootloader + type: string + required: true + salt: + description: The salt used to generate the hash + type: string + required: false + rounds: + description: The amount of rounds to run the PBKDF2 function + type: int + required: false +""" + +EXAMPLES = r""" +- name: 'Generate hash with defaults' + ansible.builtin.debug: + msg: "{{ 'mango123!' | grub_hash }}" + +- name: 'Generate hash with custom rounds and salt' + ansible.builtin.debug: + msg: "{{ 'mango123!' | grub_hash(rounds=10001, salt='andpepper') }}" + # Produces: grub.pbkdf2.sha512.10001.616E64706570706572.4C6AEA2A811B4059D4F47AEA36B77DB185B41E9F08ECC3C4C694427DB876C21B24E6CBA0319053E4F1431CDEE83076398C73B9AA8F50A7355E446229BC69A97C +""" + +RETURN = r""" +_value: + description: A GRUB2 password hash + type: string +""" + +from ansible.errors import AnsibleFilterError +import os +import base64 +from passlib.hash import grub_pbkdf2_sha512 + +def grub_hash(password, rounds=10000, salt=None): + if salt is None: + # Generate 64-byte salt if not provided + salt = os.urandom(64) + + # Check if the salt, when not generated, is a valid bytes value and attempt to convert if needed + if not isinstance(salt, bytes): + try: + salt = salt.encode("utf-8") + except AttributeError: + raise TypeError("Salt must be a string, not int.") + + # Configure hash generator + pbkdf2_generator = grub_pbkdf2_sha512.using(rounds=rounds, salt=salt) + return pbkdf2_generator.hash(password) + +class FilterModule(object): + def filters(self): + return { + 'grub_hash': grub_hash + } diff --git a/tasks/main.yml b/tasks/main.yml index 4e1e5ae..d6325fd 100644 --- a/tasks/main.yml +++ b/tasks/main.yml @@ -41,14 +41,14 @@ fail_msg: "Crypto policy is not a permitted version" success_msg: "Crypto policy is a permitted version" -- name: "Check rhel9cis_bootloader_password_hash variable has been changed" +- name: "Check rhel9cis_bootloader_password variable has been changed" when: - rhel9cis_set_boot_pass - rhel9cis_rule_1_4_1 tags: always ansible.builtin.assert: - that: rhel9cis_bootloader_password_hash.find('grub.pbkdf2.sha512') != -1 and rhel9cis_bootloader_password_hash != 'grub.pbkdf2.sha512.changethispassword' # pragma: allowlist secret - msg: "This role will not be able to run single user password commands as rhel9cis_bootloader_password_hash variable has not been set correctly" + that: rhel9cis_bootloader_password_hash != 'grub.pbkdf2.sha512.changethispassword' or (rhel9cis_bootloader_salt != '' and rhel9cis_bootloader_password != 'password') # pragma: allowlist secret + msg: "This role will not be able to run single user password commands as rhel9cis_bootloader_password or rhel9cis_bootloader_password_hash variable has not been set correctly" - name: "Check crypto-policy module input" when: @@ -154,9 +154,7 @@ file: "{{ ansible_facts.distribution }}.yml" - name: "Include preliminary steps" - tags: - - prelim_tasks - - always + tags: prelim_tasks ansible.builtin.import_tasks: file: prelim.yml diff --git a/tasks/prelim.yml b/tasks/prelim.yml index c415e65..400c88d 100644 --- a/tasks/prelim.yml +++ b/tasks/prelim.yml @@ -4,7 +4,9 @@ # List users in order to look up files inside each home directory - name: "PRELIM | Include audit specific variables" - when: run_audit or audit_only or setup_audit + when: + - run_audit or audit_only + - setup_audit tags: - setup_audit - run_audit @@ -12,7 +14,8 @@ file: audit.yml - name: "PRELIM | Include pre-remediation audit tasks" - when: run_audit or audit_only or setup_audit + when: + - run_audit or audit_only tags: run_audit ansible.builtin.import_tasks: pre_remediation_audit.yml @@ -92,6 +95,11 @@ - rhel9cis_rule_1_2_1_1 - ansible_facts.distribution != 'RedHat' - ansible_facts.distribution != 'OracleLinux' + tags: + - level1-server + - level1-workstation + - rule_1.2.1.1 + - gpg ansible.builtin.package: name: "{{ gpg_key_package }}" state: latest diff --git a/tasks/section_1/cis_1.4.x.yml b/tasks/section_1/cis_1.4.x.yml index 5969dff..4476d30 100644 --- a/tasks/section_1/cis_1.4.x.yml +++ b/tasks/section_1/cis_1.4.x.yml @@ -13,7 +13,7 @@ - NIST800-53R5_AC-3 ansible.builtin.copy: dest: /boot/grub2/user.cfg - content: "GRUB2_PASSWORD={{ rhel9cis_bootloader_password_hash }}" # noqa template-instead-of-copy + content: "GRUB2_PASSWORD={{ rhel9_compiled_bootloader_password }}" # noqa template-instead-of-copy owner: root group: root mode: 'go-rwx' diff --git a/tasks/section_7/cis_7.1.x.yml b/tasks/section_7/cis_7.1.x.yml index b23fb89..d958c9b 100644 --- a/tasks/section_7/cis_7.1.x.yml +++ b/tasks/section_7/cis_7.1.x.yml @@ -58,7 +58,7 @@ - level1-server - level1-workstation - patch - - permissionss + - permissions - rule_7.1.4 - NIST800-53R5_AC-3 - NIST800-53R5_MP-2 diff --git a/templates/audit/98_auditd_exception.rules.j2 b/templates/audit/98_auditd_exception.rules.j2 index 70ebd03..1bec877 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 Mindpoint Group - A Tyto Athene Company +# provided by {{ company_title }} ### 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 c3c2b6c..0a0cadf 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 Mindpoint Group - A Tyto Athene Company +# provided by {{ company_title }} ### 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/ansible/compliance_facts.j2 b/templates/etc/ansible/compliance_facts.j2 index f8725e1..896c159 100644 --- a/templates/etc/ansible/compliance_facts.j2 +++ b/templates/etc/ansible/compliance_facts.j2 @@ -1,6 +1,6 @@ # CIS Hardening Carried out # Added as part of ansible-lockdown CIS baseline -# provided by Mindpoint Group - A Tyto Athene Company +# provided by {{ company_title }} [lockdown_details] # Benchmark release diff --git a/templates/etc/cron.d/aide.cron.j2 b/templates/etc/cron.d/aide.cron.j2 index 4c1af92..15ea95f 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 Mindpoint Group - A Tyto Athene Company +# provided by {{ company_title }} ### 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 0e55b5a..f6ac336 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 Mindpoint Group - A Tyto Athene Company +# provided by {{ company_title }} # 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 cf9ed5d..17dcd56 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 Mindpoint Group - A Tyto Athene Company +# provided by {{ company_title }} # 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 640538c..84f086d 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 Mindpoint Group - A Tyto Athene Company +# provided by {{ company_title }} [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 382469c..528f1be 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 Mindpoint Group - A Tyto Athene Company +# provided by {{ company_title }} [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 a747336..a6c6894 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 Mindpoint Group - A Tyto Athene Company +# provided by {{ company_title }} # 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 5988316..ab8d41d 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 Mindpoint Group - A Tyto Athene Company +# provided by {{ company_title }} # 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 ec42bfc..b5fac22 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 Mindpoint Group - A Tyto Athene Company +# provided by {{ company_title }} [org/gnome/login-screen] banner-message-enable=true diff --git a/vars/main.yml b/vars/main.yml index 9337d58..dfff3c5 100644 --- a/vars/main.yml +++ b/vars/main.yml @@ -24,6 +24,8 @@ rhel9cis_allowed_crypto_policies_modules: - 'NO-SSHWEAKMAC' - 'NO-WEAKMAC' +rhel9_compiled_bootloader_password: "{% if rhel9cis_bootloader_salt != '' %}(rhel9cis_bootloader_password | grub_hash(salt=rhel9cis_bootloader_salt)) }}{% else %}{{ rhel9cis_bootloader_password_hash }}{% endif %}" # noqa template-instead-of-copy + # Used to control warning summary warn_control_list: "" warn_count: 0 @@ -74,3 +76,5 @@ audit_bins: - /sbin/autrace - /sbin/auditd - /sbin/augenrules + +company_title: 'Mindpoint Group - A Tyto Athene Company'