diff --git a/.config/requirements.txt b/.config/requirements.txt index 52cb84d..ba7d83b 100644 --- a/.config/requirements.txt +++ b/.config/requirements.txt @@ -1,5 +1,4 @@ passlib lxml xmltodict -jmespath yamllint diff --git a/.github/workflows/devel_pipeline_validation.yml b/.github/workflows/devel_pipeline_validation.yml index 64feef4..912b3db 100644 --- a/.github/workflows/devel_pipeline_validation.yml +++ b/.github/workflows/devel_pipeline_validation.yml @@ -1,139 +1,158 @@ --- - name: Devel pipeline + name: Devel pipeline - on: # yamllint disable-line rule:truthy - pull_request_target: - types: [opened, reopened, synchronize] - branches: - - devel - paths: - - '**.yml' - - '**.sh' - - '**.j2' - - '**.ps1' - - '**.cfg' + on: # yamllint disable-line rule:truthy + pull_request_target: + types: [opened, reopened, synchronize] + branches: + - devel + paths: + - '**.yml' + - '**.sh' + - '**.j2' + - '**.ps1' + - '**.cfg' + # Allow manual running of workflow + workflow_dispatch: - # A workflow run is made up of one or more jobs - # that can run sequentially or in parallel - jobs: - # This will create messages for first time contributers and direct them to the Discord server - welcome: - runs-on: ubuntu-latest + # Allow permissions for AWS auth + permissions: + id-token: write + contents: read + pull-requests: read - steps: - - uses: actions/first-interaction@main - with: - repo-token: ${{ secrets.GITHUB_TOKEN }} - pr-message: |- - Congrats on opening your first pull request and thank you for taking the time to help improve Ansible-Lockdown! - Please join in the conversation happening on the [Discord Server](https://www.lockdownenterprise.com/discord) as well. + # A workflow run is made up of one or more jobs + # that can run sequentially or in parallel + jobs: + # This will create messages for first time contributers and direct them to the Discord server + welcome: + runs-on: self-hosted - # This workflow contains a single job that tests the playbook - playbook-test: - # The type of runner that the job will run on - runs-on: ubuntu-latest - env: - ENABLE_DEBUG: ${{ vars.ENABLE_DEBUG }} - # Imported as a variable by terraform - TF_VAR_repository: ${{ github.event.repository.name }} - defaults: - run: - shell: bash - working-directory: .github/workflows/github_linux_IaC - - steps: - - name: Clone ${{ github.event.repository.name }} - uses: actions/checkout@v4 + steps: + - uses: actions/first-interaction@main with: - ref: ${{ github.event.pull_request.head.sha }} + repo-token: ${{ secrets.GITHUB_TOKEN }} + pr-message: |- + Congrats on opening your first pull request and thank you for taking the time to help improve Ansible-Lockdown! + Please join in the conversation happening on the [Discord Server](https://www.lockdownenterprise.com/discord) as well. - # Pull in terraform code for linux servers - - name: Clone GitHub IaC plan - uses: actions/checkout@v4 - with: - repository: ansible-lockdown/github_linux_IaC - path: .github/workflows/github_linux_IaC + # This workflow contains a single job that tests the playbook + playbook-test: + # The type of runner that the job will run on + runs-on: self-hosted + env: + ENABLE_DEBUG: ${{ vars.ENABLE_DEBUG }} + # Imported as a variable by terraform + TF_VAR_repository: ${{ github.event.repository.name }} + AWS_REGION: "us-east-1" + ANSIBLE_VERSION: ${{ vars.ANSIBLE_RUNNER_VERSION }} + defaults: + run: + shell: bash + working-directory: .github/workflows/github_linux_IaC + # working-directory: .github/workflows - - name: Add_ssh_key - working-directory: .github/workflows - env: - SSH_AUTH_SOCK: /tmp/ssh_agent.sock - PRIVATE_KEY: "${{ secrets.SSH_PRV_KEY }}" - run: | - mkdir .ssh - chmod 700 .ssh - echo $PRIVATE_KEY > .ssh/github_actions.pem - chmod 600 .ssh/github_actions.pem + steps: - - name: DEBUG - Show IaC files - if: env.ENABLE_DEBUG == 'true' - run: | - echo "OSVAR = $OSVAR" - echo "benchmark_type = $benchmark_type" - pwd - ls - env: - # Imported from GitHub variables this is used to load the relevant OS.tfvars file - OSVAR: ${{ vars.OSVAR }} - benchmark_type: ${{ vars.BENCHMARK_TYPE }} + - name: Git clone the lockdown repository to test + uses: actions/checkout@v4 + with: + ref: ${{ github.event.pull_request.head.sha }} - - name: Terraform_Init - id: init - run: terraform init - env: - # Imported from GitHub variables this is used to load the relevant OS.tfvars file - OSVAR: ${{ vars.OSVAR }} - TF_VAR_benchmark_type: ${{ vars.BENCHMARK_TYPE }} + - name: If a variable for IAC_BRANCH is set use that branch + working-directory: .github/workflows + run: | + if [ ${{ vars.IAC_BRANCH }} != '' ]; then + echo "IAC_BRANCH=${{ vars.IAC_BRANCH }}" >> $GITHUB_ENV + echo "Pipeline using the following IAC branch ${{ vars.IAC_BRANCH }}" + else + echo IAC_BRANCH=main >> $GITHUB_ENV + fi - - name: Terraform_Validate - id: validate - run: terraform validate - env: - # Imported from GitHub variables this is used to load the relevant OS.tfvars file - OSVAR: ${{ vars.OSVAR }} - TF_VAR_benchmark_type: ${{ vars.BENCHMARK_TYPE }} + # Pull in terraform code for linux servers + - name: Clone GitHub IaC plan + uses: actions/checkout@v4 + with: + repository: ansible-lockdown/github_linux_IaC + path: .github/workflows/github_linux_IaC + ref: ${{ env.IAC_BRANCH }} - - name: Terraform_Apply - id: apply - env: - AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} - AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} - OSVAR: ${{ vars.OSVAR }} - TF_VAR_benchmark_type: ${{ vars.BENCHMARK_TYPE }} - run: terraform apply -var-file "github_vars.tfvars" -var-file "${OSVAR}.tfvars" --auto-approve -input=false + # Uses dedicated restricted role and policy to enable this only for this task + # No credentials are part of github for AWS auth + - name: configure aws credentials + uses: aws-actions/configure-aws-credentials@main + with: + role-to-assume: ${{ secrets.AWS_ASSUME_ROLE }} + role-session-name: ${{ secrets.AWS_ROLE_SESSION }} + aws-region: ${{ env.AWS_REGION }} - ## Debug Section - - name: DEBUG - Show Ansible hostfile - if: env.ENABLE_DEBUG == 'true' - run: cat hosts.yml + - name: DEBUG - Show IaC files + if: env.ENABLE_DEBUG == 'true' + run: | + echo "OSVAR = $OSVAR" + echo "benchmark_type = $benchmark_type" + echo "PRIVSUBNET_ID = $AWS_PRIVSUBNET_ID" + echo "VPC_ID" = $AWS_VPC_SECGRP_ID" + pwd + ls + env: + # Imported from GitHub variables this is used to load the relevant OS.tfvars file + OSVAR: ${{ vars.OSVAR }} + benchmark_type: ${{ vars.BENCHMARK_TYPE }} + PRIVSUBNET_ID: ${{ secrets.AWS_PRIVSUBNET_ID }} + VPC_ID: ${{ secrets.AWS_VPC_SECGRP_ID }} - # Aws deployments taking a while to come up insert sleep or playbook fails + - name: Tofu init + id: init + run: tofu init + env: + # Imported from GitHub variables this is used to load the relevant OS.tfvars file + OSVAR: ${{ vars.OSVAR }} + TF_VAR_benchmark_type: ${{ vars.BENCHMARK_TYPE }} - - name: Sleep for 60 seconds - run: sleep ${{ vars.BUILD_SLEEPTIME }} + - name: Tofu validate + id: validate + run: tofu validate + env: + # Imported from GitHub variables this is used to load the relevant OS.tfvars file + OSVAR: ${{ vars.OSVAR }} + TF_VAR_benchmark_type: ${{ vars.BENCHMARK_TYPE }} - # Run the Ansibleplaybook - - name: Run_Ansible_Playbook - uses: arillso/action.playbook@master - with: - playbook: site.yml - inventory: .github/workflows/github_linux_IaC/hosts.yml - galaxy_file: collections/requirements.yml - private_key: ${{ secrets.SSH_PRV_KEY }} - # verbose: 3 - env: - ANSIBLE_HOST_KEY_CHECKING: "false" - ANSIBLE_DEPRECATION_WARNINGS: "false" - ANSIBLE_INJECT_FACT_VARS: "false" + - name: Tofu apply + id: apply + env: + OSVAR: ${{ vars.OSVAR }} + TF_VAR_benchmark_type: ${{ vars.BENCHMARK_TYPE }} + TF_VAR_privsubnet_id: ${{ secrets.AWS_PRIVSUBNET_ID }} + TF_VAR_vpc_secgrp_id: ${{ secrets.AWS_VPC_SECGRP_ID }} + run: tofu apply -var-file "${OSVAR}.tfvars" --auto-approve -input=false - # Remove test system - User secrets to keep if necessary +## Debug Section + - name: DEBUG - Show Ansible hostfile + if: env.ENABLE_DEBUG == 'true' + run: cat hosts.yml - - name: Terraform_Destroy - if: always() && env.ENABLE_DEBUG == 'false' - env: - AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} - AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} - OSVAR: ${{ vars.OSVAR }} - TF_VAR_benchmark_type: ${{ vars.BENCHMARK_TYPE }} - run: terraform destroy -var-file "github_vars.tfvars" -var-file "${OSVAR}.tfvars" --auto-approve -input=false + # Aws deployments taking a while to come up insert sleep or playbook fails + + - name: Sleep to allow system to come up + run: sleep ${{ vars.BUILD_SLEEPTIME }} + + # Run the Ansible playbook + - name: Run_Ansible_Playbook + env: + ANSIBLE_HOST_KEY_CHECKING: "false" + ANSIBLE_DEPRECATION_WARNINGS: "false" + run: | + /opt/ansible_${{ env.ANSIBLE_VERSION }}_venv/bin/ansible-playbook -i hosts.yml --private-key ~/.ssh/le_runner ../../../site.yml + + # Remove test system - User secrets to keep if necessary + + - name: Tofu Destroy + if: always() && env.ENABLE_DEBUG == 'false' + env: + OSVAR: ${{ vars.OSVAR }} + TF_VAR_benchmark_type: ${{ vars.BENCHMARK_TYPE }} + TF_VAR_privsubnet_id: ${{ secrets.AWS_PRIVSUBNET_ID }} + TF_VAR_vpc_secgrp_id: ${{ secrets.AWS_VPC_SECGRP_ID }} + run: tofu destroy -var-file "${OSVAR}.tfvars" --auto-approve -input=false diff --git a/.github/workflows/main_pipeline_validation.yml b/.github/workflows/main_pipeline_validation.yml index cfa5801..4a5adc9 100644 --- a/.github/workflows/main_pipeline_validation.yml +++ b/.github/workflows/main_pipeline_validation.yml @@ -1,128 +1,156 @@ --- - name: Main pipeline + name: Main pipeline - on: # yamllint disable-line rule:truthy - pull_request_target: - types: [opened, reopened, synchronize] - branches: - - main - paths: - - '**.yml' - - '**.sh' - - '**.j2' - - '**.ps1' - - '**.cfg' + on: # yamllint disable-line rule:truthy + pull_request_target: + types: [opened, reopened, synchronize] + branches: + - main + paths: + - '**.yml' + - '**.sh' + - '**.j2' + - '**.ps1' + - '**.cfg' - # A workflow run is made up of one or more jobs - # that can run sequentially or in parallel - jobs: + # Allow permissions for AWS auth + permissions: + id-token: write + contents: read + pull-requests: read - # This workflow contains a single job that tests the playbook - playbook-test: - # The type of runner that the job will run on - runs-on: ubuntu-latest - env: - ENABLE_DEBUG: ${{ vars.ENABLE_DEBUG }} - # Imported as a variable by terraform - TF_VAR_repository: ${{ github.event.repository.name }} - defaults: - run: - shell: bash - working-directory: .github/workflows/github_linux_IaC + # A workflow run is made up of one or more jobs + # that can run sequentially or in parallel + jobs: + # This will create messages for first time contributers and direct them to the Discord server + welcome: + runs-on: self-hosted - steps: - - name: Clone ${{ github.event.repository.name }} - uses: actions/checkout@v4 + steps: + - uses: actions/first-interaction@main with: - ref: ${{ github.event.pull_request.head.sha }} + repo-token: ${{ secrets.GITHUB_TOKEN }} + pr-message: |- + Congrats on opening your first pull request and thank you for taking the time to help improve Ansible-Lockdown! + Please join in the conversation happening on the [Discord Server](https://www.lockdownenterprise.com/discord) as well. - # Pull in terraform code for linux servers - - name: Clone GitHub IaC plan - uses: actions/checkout@v4 - with: - repository: ansible-lockdown/github_linux_IaC - path: .github/workflows/github_linux_IaC + # This workflow contains a single job that tests the playbook + playbook-test: + # The type of runner that the job will run on + runs-on: self-hosted + env: + ENABLE_DEBUG: ${{ vars.ENABLE_DEBUG }} + # Imported as a variable by terraform + TF_VAR_repository: ${{ github.event.repository.name }} + AWS_REGION : "us-east-1" + ANSIBLE_VERSION: ${{ vars.ANSIBLE_RUNNER_VERSION }} + defaults: + run: + shell: bash + working-directory: .github/workflows/github_linux_IaC + # working-directory: .github/workflows - - name: Add_ssh_key - working-directory: .github/workflows - env: - SSH_AUTH_SOCK: /tmp/ssh_agent.sock - PRIVATE_KEY: "${{ secrets.SSH_PRV_KEY }}" - run: | - mkdir .ssh - chmod 700 .ssh - echo $PRIVATE_KEY > .ssh/github_actions.pem - chmod 600 .ssh/github_actions.pem + steps: - - name: DEBUG - Show IaC files - if: env.ENABLE_DEBUG == 'true' - run: | - echo "OSVAR = $OSVAR" - echo "benchmark_type = $benchmark_type" - pwd - ls - env: - # Imported from GitHub variables this is used to load the relevant OS.tfvars file - OSVAR: ${{ vars.OSVAR }} - benchmark_type: ${{ vars.BENCHMARK_TYPE }} + - name: Git clone the lockdown repository to test + uses: actions/checkout@v4 + with: + ref: ${{ github.event.pull_request.head.sha }} - - name: Terraform_Init - id: init - run: terraform init - env: - # Imported from GitHub variables this is used to load the relevant OS.tfvars file - OSVAR: ${{ vars.OSVAR }} - TF_VAR_benchmark_type: ${{ vars.BENCHMARK_TYPE }} + - name: If a variable for IAC_BRANCH is set use that branch + working-directory: .github/workflows + run: | + if [ ${{ vars.IAC_BRANCH }} != '' ]; then + echo "IAC_BRANCH=${{ vars.IAC_BRANCH }}" >> $GITHUB_ENV + echo "Pipeline using the following IAC branch ${{ vars.IAC_BRANCH }}" + else + echo IAC_BRANCH=main >> $GITHUB_ENV + fi - - name: Terraform_Validate - id: validate - run: terraform validate - env: - # Imported from GitHub variables this is used to load the relevant OS.tfvars file - OSVAR: ${{ vars.OSVAR }} - TF_VAR_benchmark_type: ${{ vars.BENCHMARK_TYPE }} + # Pull in terraform code for linux servers + - name: Clone GitHub IaC plan + uses: actions/checkout@v4 + with: + repository: ansible-lockdown/github_linux_IaC + path: .github/workflows/github_linux_IaC + ref: ${{ env.IAC_BRANCH }} - - name: Terraform_Apply - id: apply - env: - AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} - AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} - OSVAR: ${{ vars.OSVAR }} - TF_VAR_benchmark_type: ${{ vars.BENCHMARK_TYPE }} - run: terraform apply -var-file "github_vars.tfvars" -var-file "${OSVAR}.tfvars" --auto-approve -input=false + # Uses dedicated restricted role and policy to enable this only for this task + # No credentials are part of github for AWS auth + - name: configure aws credentials + uses: aws-actions/configure-aws-credentials@main + with: + role-to-assume: ${{ secrets.AWS_ASSUME_ROLE }} + role-session-name: ${{ secrets.AWS_ROLE_SESSION }} + aws-region: ${{ env.AWS_REGION }} - ## Debug Section - - name: DEBUG - Show Ansible hostfile - if: env.ENABLE_DEBUG == 'true' - run: cat hosts.yml + - name: DEBUG - Show IaC files + if: env.ENABLE_DEBUG == 'true' + run: | + echo "OSVAR = $OSVAR" + echo "benchmark_type = $benchmark_type" + echo "PRIVSUBNET_ID = $AWS_PRIVSUBNET_ID" + echo "VPC_ID" = $AWS_VPC_SECGRP_ID" + pwd + ls + env: + # Imported from GitHub variables this is used to load the relevant OS.tfvars file + OSVAR: ${{ vars.OSVAR }} + benchmark_type: ${{ vars.BENCHMARK_TYPE }} + PRIVSUBNET_ID: ${{ secrets.AWS_PRIVSUBNET_ID }} + VPC_ID: ${{ secrets.AWS_VPC_SECGRP_ID }} - # Aws deployments taking a while to come up insert sleep or playbook fails + - name: Tofu init + id: init + run: tofu init + env: + # Imported from GitHub variables this is used to load the relevant OS.tfvars file + OSVAR: ${{ vars.OSVAR }} + TF_VAR_benchmark_type: ${{ vars.BENCHMARK_TYPE }} - - name: Sleep for 60 seconds - run: sleep ${{ vars.BUILD_SLEEPTIME }} + - name: Tofu validate + id: validate + run: tofu validate + env: + # Imported from GitHub variables this is used to load the relevant OS.tfvars file + OSVAR: ${{ vars.OSVAR }} + TF_VAR_benchmark_type: ${{ vars.BENCHMARK_TYPE }} - # Run the Ansibleplaybook - - name: Run_Ansible_Playbook - uses: arillso/action.playbook@master - with: - playbook: site.yml - inventory: .github/workflows/github_linux_IaC/hosts.yml - galaxy_file: collections/requirements.yml - private_key: ${{ secrets.SSH_PRV_KEY }} - # verbose: 3 - env: - ANSIBLE_HOST_KEY_CHECKING: "false" - ANSIBLE_DEPRECATION_WARNINGS: "false" - ANSIBLE_INJECT_FACT_VARS: "false" + - name: Tofu apply + id: apply + env: + OSVAR: ${{ vars.OSVAR }} + TF_VAR_benchmark_type: ${{ vars.BENCHMARK_TYPE }} + TF_VAR_privsubnet_id: ${{ secrets.AWS_PRIVSUBNET_ID }} + TF_VAR_vpc_secgrp_id: ${{ secrets.AWS_VPC_SECGRP_ID }} + run: tofu apply -var-file "${OSVAR}.tfvars" --auto-approve -input=false - # Remove test system - User secrets to keep if necessary +## Debug Section + - name: DEBUG - Show Ansible hostfile + if: env.ENABLE_DEBUG == 'true' + run: cat hosts.yml - - name: Terraform_Destroy - if: always() && env.ENABLE_DEBUG == 'false' - env: - AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} - AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} - OSVAR: ${{ vars.OSVAR }} - TF_VAR_benchmark_type: ${{ vars.BENCHMARK_TYPE }} - run: terraform destroy -var-file "github_vars.tfvars" -var-file "${OSVAR}.tfvars" --auto-approve -input=false + # Aws deployments taking a while to come up insert sleep or playbook fails + + - name: Sleep to allow system to come up + run: sleep ${{ vars.BUILD_SLEEPTIME }} + + # Run the Ansible playbook + - name: Run_Ansible_Playbook + env: + ANSIBLE_HOST_KEY_CHECKING: "false" + ANSIBLE_DEPRECATION_WARNINGS: "false" + run: | + /opt/ansible_${{ env.ANSIBLE_VERSION }}_venv/bin/ansible-playbook -i hosts.yml --private-key ~/.ssh/le_runner ../../../site.yml + + # Remove test system - User secrets to keep if necessary + + - name: Tofu Destroy + if: always() && env.ENABLE_DEBUG == 'false' + env: + OSVAR: ${{ vars.OSVAR }} + TF_VAR_benchmark_type: ${{ vars.BENCHMARK_TYPE }} + TF_VAR_privsubnet_id: ${{ secrets.AWS_PRIVSUBNET_ID }} + TF_VAR_vpc_secgrp_id: ${{ secrets.AWS_VPC_SECGRP_ID }} + run: tofu destroy -var-file "${OSVAR}.tfvars" --auto-approve -input=false diff --git a/.github/workflows/update_galaxy.yml b/.github/workflows/update_galaxy.yml index f935280..b6ee6a1 100644 --- a/.github/workflows/update_galaxy.yml +++ b/.github/workflows/update_galaxy.yml @@ -1,19 +1,19 @@ --- -name: update galaxy + name: update galaxy -on: - push: - branches: - - main -jobs: - update_role: - runs-on: ubuntu-latest - steps: - - name: Checkout repo - uses: actions/checkout@v4 + on: + push: + branches: + - main + jobs: + update_role: + runs-on: ubuntu-latest + steps: + - name: Checkout repo + uses: actions/checkout@v4 - - name: Action Ansible Galaxy Release ${{ github.ref_name }} - uses: ansible-actions/ansible-galaxy-action@main - with: - galaxy_api_key: ${{ secrets.GALAXY_API_KEY }} + - name: Action Ansible Galaxy Release ${{ github.ref_name }} + uses: ansible-actions/ansible-galaxy-action@main + with: + galaxy_api_key: ${{ secrets.GALAXY_API_KEY }} diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index e5a1186..260cffe 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -37,13 +37,13 @@ repos: exclude: .config/.gitleaks-report.json - repo: https://github.com/gitleaks/gitleaks - rev: v8.18.3 + rev: v8.18.4 hooks: - id: gitleaks args: ['--baseline-path', '.config/.gitleaks-report.json'] - repo: https://github.com/ansible-community/ansible-lint - rev: v24.6.0 + rev: v24.7.0 hooks: - id: ansible-lint name: Ansible-lint diff --git a/README.md b/README.md index f8f3680..3260cb0 100644 --- a/README.md +++ b/README.md @@ -78,7 +78,7 @@ The control found in the `defaults` main also needs to reflect this, as this con CIS release always contains changes, it is highly recommended to review the new references and available variables. This has changed significantly since the ansible-lockdown initial release. This is now compatible with python3 if it is found to be the default interpreter. This does come with prerequisites which configure the system accordingly. -Further details can be seen in the [Changelog](./ChangeLog.md) +Further details can be seen in the [Changelog](./Changelog.md) ## Auditing (new) diff --git a/defaults/main.yml b/defaults/main.yml index f1a2dea..622af55 100644 --- a/defaults/main.yml +++ b/defaults/main.yml @@ -421,7 +421,7 @@ rhel9cis_rule_enable_repogpg: true # 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...' -rhel9cis_bootloader_password_hash: 'grub.pbkdf2.sha512.10000.9306A36764A7BEA3BF492D1784396B27F52A71812E9955A58709F94EE70697F9BD5366F36E07DEC41B52279A056E2862A93E42069D7BBB08F5DFC2679CD43812.6C32ADA5449303AD5E67A4C150558592A05381331DE6B33463469A236871FA8E70738C6F9066091D877EF88A213C86825E093117F30E9E1BF158D0DB75E7581B' # pragma: allowlist secret +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. @@ -962,7 +962,7 @@ rhel9cis_logrotate: "daily" # This value, containing the absolute filepath of the produced 'sshd' config file, allows usage of # drop-in files('/etc/ssh/ssh_config.d/{ssh_drop_in_name}.conf', supported by RHEL9) when CIS adopts them. # Otherwise, the default value is '/etc/ssh/ssh_config'. -rhel9_cis_sshd_config_file: /etc/ssh/sshd_config +rhel9cis_sshd_config_file: /etc/ssh/sshd_config ## Controls: ## - 5.2.4 - Ensure SSH access is limited diff --git a/tasks/LE_audit_setup.yml b/tasks/LE_audit_setup.yml index 7ef94b4..08d047d 100644 --- a/tasks/LE_audit_setup.yml +++ b/tasks/LE_audit_setup.yml @@ -10,7 +10,7 @@ - name: Pre Audit Setup | Set audit package name | ARM64 ansible.builtin.set_fact: audit_pkg_arch_name: ARM64 - when: ansible_facts.machine == "arm64" + when: ansible_facts.machine == "aarch64" - name: Pre Audit Setup | Download audit binary ansible.builtin.get_url: diff --git a/tasks/audit_only.yml b/tasks/audit_only.yml index 864f5bb..ab5a573 100644 --- a/tasks/audit_only.yml +++ b/tasks/audit_only.yml @@ -22,7 +22,7 @@ when: - audit_only ansible.builtin.debug: - msg: "The Audit results are: {{ pre_audit_summary }}." + msg: "{{ audit_results.split('\n') }}" - name: Audit_only | Stop Playbook Audit Only selected when: diff --git a/tasks/post_remediation_audit.yml b/tasks/post_remediation_audit.yml index b3111c8..ad5bcb5 100644 --- a/tasks/post_remediation_audit.yml +++ b/tasks/post_remediation_audit.yml @@ -21,26 +21,24 @@ when: - audit_format == "json" block: - - name: capture data {{ post_audit_outfile }} - ansible.builtin.shell: "cat {{ post_audit_outfile }}" - register: post_audit + - name: Post Audit | Capture audit data if json format + ansible.builtin.shell: grep -E '"summary-line.*Count:.*Failed' "{{ post_audit_outfile }}" | cut -d'"' -f4 + register: post_audit_summary changed_when: false - - name: Capture post-audit result + - name: Post Audit | Set Fact for audit summary ansible.builtin.set_fact: - post_audit_summary: "{{ post_audit.stdout | from_json | json_query(summary) }}" - vars: - summary: summary."summary-line" + post_audit_results: "{{ post_audit_summary.stdout }}" - name: Post Audit | Capture audit data if documentation format when: - audit_format == "documentation" block: - - name: Post Audit | capture data {{ post_audit_outfile }} - ansible.builtin.shell: "tail -2 {{ post_audit_outfile }}" - register: post_audit + - name: Post Audit | Capture audit data if documentation format + ansible.builtin.shell: tail -2 "{{ post_audit_outfile }}" | tac | tr '\n' ' ' + register: post_audit_summary changed_when: false - - name: Post Audit | Capture post-audit result + - name: Post Audit | Set Fact for audit summary ansible.builtin.set_fact: - post_audit_summary: "{{ post_audit.stdout_lines }}" + post_audit_results: "{{ post_audit_summary.stdout }}" diff --git a/tasks/pre_remediation_audit.yml b/tasks/pre_remediation_audit.yml index 9777bd1..5a99844 100644 --- a/tasks/pre_remediation_audit.yml +++ b/tasks/pre_remediation_audit.yml @@ -90,31 +90,30 @@ when: - audit_format == "json" block: - - name: Pre Audit | Capture data {{ pre_audit_outfile }} - ansible.builtin.shell: "cat {{ pre_audit_outfile }}" - register: pre_audit + - name: Pre Audit | Capture audit data if json format + ansible.builtin.shell: grep -E '\"summary-line.*Count:.*Failed' "{{ pre_audit_outfile }}" | cut -d'"' -f4 + register: pre_audit_summary changed_when: false - - name: Pre Audit | Capture pre-audit result + - name: Pre Audit | Set Fact for audit summary ansible.builtin.set_fact: - pre_audit_summary: "{{ pre_audit.stdout | from_json | json_query(summary) }}" - vars: - summary: summary."summary-line" + pre_audit_results: "{{ pre_audit_summary.stdout }}" - name: Pre Audit | Capture audit data if documentation format when: - audit_format == "documentation" block: - - name: Pre Audit | Capture data {{ pre_audit_outfile }} | documentation format - ansible.builtin.shell: "tail -2 {{ pre_audit_outfile }}" - register: pre_audit + - name: Pre Audit | Capture audit data if documentation format + ansible.builtin.shell: tail -2 "{{ pre_audit_outfile }}" | tac | tr '\n' ' ' + register: pre_audit_summary changed_when: false - - name: Pre Audit | Capture pre-audit result | documentation format + - name: Pre Audit | Set Fact for audit summary ansible.builtin.set_fact: - pre_audit_summary: "{{ pre_audit.stdout_lines }}" + pre_audit_results: "{{ pre_audit_summary.stdout }}" - name: Audit_Only | Run Audit Only when: - audit_only - ansible.builtin.import_tasks: audit_only.yml + ansible.builtin.import_tasks: + file: audit_only.yml diff --git a/tasks/prelim.yml b/tasks/prelim.yml index 0db27d3..1db6db5 100644 --- a/tasks/prelim.yml +++ b/tasks/prelim.yml @@ -242,18 +242,16 @@ # Added to ensure ssh drop in file exists if not default /etc/ssh/sshd_config - name: "PRELIM | Section 5.2 | SSH" ansible.builtin.file: - path: "{{ rhel9_cis_sshd_config_file }}" + path: "{{ rhel9cis_sshd_config_file }}" owner: root group: root mode: '0600' state: touch when: - - rhel9_cis_sshd_config_file != '/etc/ssh/sshd_config' + - rhel9cis_sshd_config_file != '/etc/ssh/sshd_config' - "'openssh-server' in ansible_facts.packages" tags: - - ssh - - level1_server - - level1_workstation + - always - name: "PRELIM | 5.3.4 | Find all sudoers files." ansible.builtin.shell: "find /etc/sudoers /etc/sudoers.d/ -type f ! -name '*~' ! -name '*.*'" diff --git a/tasks/section_1/cis_1.8.x.yml b/tasks/section_1/cis_1.8.x.yml index b7f4791..ce35a48 100644 --- a/tasks/section_1/cis_1.8.x.yml +++ b/tasks/section_1/cis_1.8.x.yml @@ -89,8 +89,8 @@ group: root mode: '0644' loop: - - { regexp: '^user-db', line: 'user-db: user' } - - { regexp: '^system-db', line: 'system-db: local' } + - { regexp: '^user-db', line: 'user-db:user' } + - { regexp: '^system-db', line: 'system-db:local' } - name: "1.8.4 | PATCH | Ensure GDM screen locks when the user is idle | Make db directory" ansible.builtin.file: diff --git a/tasks/section_4/cis_4.1.4.x.yml b/tasks/section_4/cis_4.1.4.x.yml index c42f876..79c0f23 100644 --- a/tasks/section_4/cis_4.1.4.x.yml +++ b/tasks/section_4/cis_4.1.4.x.yml @@ -23,7 +23,7 @@ "4.1.4.3 | PATCH | Ensure only authorized groups are assigned ownership of audit log files" ansible.builtin.file: path: "{{ audit_discovered_logfile.stdout }}" - mode: "{% if auditd_logfile.stat.mode != '0600' %}0640{% endif %}" + mode: 'u-x,g-rw,o-rwx' owner: root group: root when: @@ -50,7 +50,7 @@ ansible.builtin.file: path: "{{ audit_discovered_logfile.stdout | dirname }}" state: directory - mode: '0750' + mode: 'g-w,o-rwx' when: not auditlog_dir.stat.mode is match('07(0|5)0') when: - rhel9cis_rule_4_1_4_4 @@ -64,7 +64,9 @@ - name: "4.1.4.5 | PATCH | Ensure audit configuration files are 640 or more restrictive" ansible.builtin.file: path: "{{ item.path }}" - mode: "{{ '0600' if item.mode == '0600' else '0640' }}" + mode: 'u-x,g-wx,o-rwx' + failed_when: rhel9cis_4_1_4_5_file_list.state not in '[ file, absent ]' + register: rhel9cis_4_1_4_5_file_list loop: "{{ auditd_conf_files.files }}" loop_control: label: "{{ item.path }}" @@ -81,6 +83,8 @@ ansible.builtin.file: path: "{{ item.path }}" owner: root + failed_when: rhel9cis_4_1_4_6_file_list.state not in '[ file, absent ]' + register: rhel9cis_4_1_4_6_file_list loop: "{{ auditd_conf_files.files | default([]) }}" loop_control: label: "{{ item.path }}" @@ -97,6 +101,8 @@ ansible.builtin.file: path: "{{ item.path }}" group: root + failed_when: rhel9cis_4_1_4_7_file_list.state not in '[ file, absent ]' + register: rhel9cis_4_1_4_7_file_list loop: "{{ auditd_conf_files.files | default([]) }}" loop_control: label: "{{ item.path }}" @@ -126,8 +132,7 @@ - name: "4.1.4.8 | PATCH | Ensure audit tools are 755 or more restrictive | set if required" ansible.builtin.file: path: "{{ item.item }}" - mode: '0750' - + mode: 'go-w' loop: "{{ audit_bins.results }}" loop_control: label: "{{ item.item }}" diff --git a/tasks/section_4/cis_4.2.1.x.yml b/tasks/section_4/cis_4.2.1.x.yml index 740f820..fd1961f 100644 --- a/tasks/section_4/cis_4.2.1.x.yml +++ b/tasks/section_4/cis_4.2.1.x.yml @@ -123,7 +123,7 @@ local2,local3.* -/var/log/localmessages local4,local5.* -/var/log/localmessages local6,local7.* -/var/log/localmessages - *.emrg :omusrmsg:* + *.emerg :omusrmsg:* insertafter: '#### RULES ####' notify: Restart rsyslog diff --git a/tasks/section_4/cis_4.2.3.yml b/tasks/section_4/cis_4.2.3.yml index 823975a..42bb419 100644 --- a/tasks/section_4/cis_4.2.3.yml +++ b/tasks/section_4/cis_4.2.3.yml @@ -14,6 +14,8 @@ ansible.builtin.file: path: "{{ item.path }}" mode: "{{ '0600' if item.mode == '0600' else '0640' }}" + failed_when: rhel9cis_4_2_3_file_list.state not in '[ file, absent ]' + register: rhel9cis_4_2_3_file_list loop: "{{ logfiles.files }}" loop_control: label: "{{ item.path }}" diff --git a/tasks/section_5/cis_5.2.x.yml b/tasks/section_5/cis_5.2.x.yml index ac62767..d6c6bf9 100644 --- a/tasks/section_5/cis_5.2.x.yml +++ b/tasks/section_5/cis_5.2.x.yml @@ -77,7 +77,7 @@ block: - name: "5.2.4 | PATCH | Ensure SSH access is limited | Add line to sshd_config for allowusers" ansible.builtin.lineinfile: - path: "{{ rhel9_cis_sshd_config_file }}" + path: "{{ rhel9cis_sshd_config_file }}" regexp: "^AllowUsers" line: "AllowUsers {{ rhel9cis_sshd['allowusers'] }}" validate: sshd -t -f %s @@ -86,7 +86,7 @@ - name: "5.2.4 | PATCH | Ensure SSH access is limited | Add line to sshd_config for allowgroups" ansible.builtin.lineinfile: - path: "{{ rhel9_cis_sshd_config_file }}" + path: "{{ rhel9cis_sshd_config_file }}" regexp: "^AllowGroups" line: "AllowGroups {{ rhel9cis_sshd['allowgroups'] }}" validate: sshd -t -f %s @@ -95,7 +95,7 @@ - name: "5.2.4 | PATCH | Ensure SSH access is limited | Add line to sshd_config for denyusers" ansible.builtin.lineinfile: - path: "{{ rhel9_cis_sshd_config_file }}" + path: "{{ rhel9cis_sshd_config_file }}" regexp: "^DenyUsers" line: "DenyUsers {{ rhel9cis_sshd['denyusers'] }}" validate: sshd -t -f %s @@ -104,7 +104,7 @@ - name: "5.2.4 | PATCH | Ensure SSH access is limited | Add line to sshd_config for denygroups" ansible.builtin.lineinfile: - path: "{{ rhel9_cis_sshd_config_file }}" + path: "{{ rhel9cis_sshd_config_file }}" regexp: "^DenyGroups" line: "DenyGroups {{ rhel9cis_sshd['denygroups'] }}" validate: sshd -t -f %s @@ -121,10 +121,11 @@ - name: "5.2.5 | PATCH | Ensure SSH LogLevel is appropriate" ansible.builtin.lineinfile: - path: "{{ rhel9_cis_sshd_config_file }}" + path: "{{ rhel9cis_sshd_config_file }}" regexp: "^#LogLevel|^LogLevel" line: 'LogLevel {{ rhel9cis_ssh_loglevel }}' validate: sshd -t -f %s + notify: Restart sshd when: - rhel9cis_rule_5_2_5 tags: @@ -136,10 +137,11 @@ - name: "5.2.6 | PATCH | Ensure SSH PAM is enabled" ansible.builtin.lineinfile: - path: "{{ rhel9_cis_sshd_config_file }}" + path: "{{ rhel9cis_sshd_config_file }}" regexp: "^#UsePAM|^UsePAM" line: 'UsePAM yes' validate: sshd -t -f %s + notify: Restart sshd when: - rhel9cis_rule_5_2_6 tags: @@ -153,7 +155,7 @@ block: - name: "5.2.7 | PATCH | Ensure SSH root login is disabled | config file" ansible.builtin.lineinfile: - path: "{{ rhel9_cis_sshd_config_file }}" + path: "{{ rhel9cis_sshd_config_file }}" regexp: "^#PermitRootLogin|^PermitRootLogin" line: 'PermitRootLogin no' validate: sshd -t -f %s @@ -162,6 +164,7 @@ ansible.builtin.file: path: /etc/ssh/sshd_config.d/01-permitrootlogin.conf state: absent + notify: Restart sshd when: - rhel9cis_rule_5_2_7 tags: @@ -173,10 +176,11 @@ - name: "5.2.8 | PATCH | Ensure SSH HostbasedAuthentication is disabled" ansible.builtin.lineinfile: - path: "{{ rhel9_cis_sshd_config_file }}" + path: "{{ rhel9cis_sshd_config_file }}" regexp: "^#HostbasedAuthentication|^HostbasedAuthentication" line: 'HostbasedAuthentication no' validate: sshd -t -f %s + notify: Restart sshd when: - rhel9cis_rule_5_2_8 tags: @@ -188,10 +192,11 @@ - name: "5.2.9 | PATCH | Ensure SSH PermitEmptyPasswords is disabled" ansible.builtin.lineinfile: - path: "{{ rhel9_cis_sshd_config_file }}" + path: "{{ rhel9cis_sshd_config_file }}" regexp: "^#PermitEmptyPasswords|^PermitEmptyPasswords" line: 'PermitEmptyPasswords no' validate: sshd -t -f %s + notify: Restart sshd when: - rhel9cis_rule_5_2_9 tags: @@ -203,10 +208,11 @@ - name: "5.2.10 | PATCH | Ensure SSH PermitUserEnvironment is disabled" ansible.builtin.lineinfile: - path: "{{ rhel9_cis_sshd_config_file }}" + path: "{{ rhel9cis_sshd_config_file }}" regexp: "^#PermitUserEnvironment|^PermitUserEnvironment" line: 'PermitUserEnvironment no' validate: sshd -t -f %s + notify: Restart sshd when: - rhel9cis_rule_5_2_10 tags: @@ -218,10 +224,11 @@ - name: "5.2.11 | PATCH | Ensure SSH IgnoreRhosts is enabled" ansible.builtin.lineinfile: - path: "{{ rhel9_cis_sshd_config_file }}" + path: "{{ rhel9cis_sshd_config_file }}" regexp: "^#IgnoreRhosts|^IgnoreRhosts" line: 'IgnoreRhosts yes' validate: sshd -t -f %s + notify: Restart sshd when: - rhel9cis_rule_5_2_11 tags: @@ -236,10 +243,11 @@ - name: "5.2.12 | PATCH | Ensure SSH X11 forwarding is disabled | config file" ansible.builtin.lineinfile: - path: "{{ rhel9_cis_sshd_config_file }}" + path: "{{ rhel9cis_sshd_config_file }}" regexp: "^#X11Forwarding|^X11Forwarding" line: 'X11Forwarding no' validate: sshd -t -f %s + notify: Restart sshd - name: "5.2.12 | PATCH | Ensure SSH X11 forwarding is disabled | override" ansible.builtin.lineinfile: @@ -247,6 +255,7 @@ regexp: "^#X11Forwarding|^X11Forwarding" line: 'X11Forwarding no' validate: sshd -t -f %s + notify: Restart sshd when: - rhel9cis_rule_5_2_12 tags: @@ -258,10 +267,11 @@ - name: "5.2.13 | PATCH | Ensure SSH AllowTcpForwarding is disabled" ansible.builtin.lineinfile: - path: "{{ rhel9_cis_sshd_config_file }}" + path: "{{ rhel9cis_sshd_config_file }}" regexp: "^#AllowTcpForwarding|^AllowTcpForwarding" line: 'AllowTcpForwarding no' validate: sshd -t -f %s + notify: Restart sshd when: - rhel9cis_rule_5_2_13 tags: @@ -294,9 +304,10 @@ - name: "5.2.15 | PATCH | Ensure SSH warning banner is configured" ansible.builtin.lineinfile: - path: "{{ rhel9_cis_sshd_config_file }}" + path: "{{ rhel9cis_sshd_config_file }}" regexp: '^Banner' line: 'Banner /etc/issue.net' + notify: Restart sshd when: - rhel9cis_rule_5_2_15 tags: @@ -308,10 +319,11 @@ - name: "5.2.16 | PATCH | Ensure SSH MaxAuthTries is set to 4 or less" ansible.builtin.lineinfile: - path: "{{ rhel9_cis_sshd_config_file }}" + path: "{{ rhel9cis_sshd_config_file }}" regexp: '^(#)?MaxAuthTries \d' line: 'MaxAuthTries 4' validate: sshd -t -f %s + notify: Restart sshd when: - rhel9cis_rule_5_2_16 tags: @@ -323,10 +335,11 @@ - name: "5.2.17 | PATCH | Ensure SSH MaxStartups is configured" ansible.builtin.lineinfile: - path: "{{ rhel9_cis_sshd_config_file }}" + path: "{{ rhel9cis_sshd_config_file }}" regexp: "^#MaxStartups|^MaxStartups" line: 'MaxStartups 10:30:60' validate: sshd -t -f %s + notify: Restart sshd when: - rhel9cis_rule_5_2_17 tags: @@ -338,10 +351,11 @@ - name: "5.2.18 | PATCH | Ensure SSH MaxSessions is set to 10 or less" ansible.builtin.lineinfile: - path: "{{ rhel9_cis_sshd_config_file }}" + path: "{{ rhel9cis_sshd_config_file }}" regexp: "^#MaxSessions|^MaxSessions" line: 'MaxSessions {{ rhel9cis_ssh_maxsessions }}' validate: sshd -t -f %s + notify: Restart sshd when: - rhel9cis_rule_5_2_18 tags: @@ -353,10 +367,11 @@ - name: "5.2.19 | PATCH | Ensure SSH LoginGraceTime is set to one minute or less" ansible.builtin.lineinfile: - path: "{{ rhel9_cis_sshd_config_file }}" + path: "{{ rhel9cis_sshd_config_file }}" regexp: "^#LoginGraceTime|^LoginGraceTime" line: "LoginGraceTime {{ rhel9cis_sshd['logingracetime'] }}" validate: sshd -t -f %s + notify: Restart sshd when: - rhel9cis_rule_5_2_19 tags: @@ -370,17 +385,19 @@ block: - name: "5.2.20 | PATCH | Ensure SSH Idle Timeout Interval is configured | Add line in sshd_config for ClientAliveInterval" ansible.builtin.lineinfile: - path: "{{ rhel9_cis_sshd_config_file }}" + path: "{{ rhel9cis_sshd_config_file }}" regexp: '^ClientAliveInterval' line: "ClientAliveInterval {{ rhel9cis_sshd['clientaliveinterval'] }}" validate: sshd -t -f %s + notify: Restart sshd - name: "5.2.20 | PATCH | Ensure SSH Idle Timeout Interval is configured | Ensure SSH ClientAliveCountMax set to <= 3" ansible.builtin.lineinfile: - path: "{{ rhel9_cis_sshd_config_file }}" + path: "{{ rhel9cis_sshd_config_file }}" regexp: '^ClientAliveCountMax' line: "ClientAliveCountMax {{ rhel9cis_sshd['clientalivecountmax'] }}" validate: sshd -t -f %s + notify: Restart sshd when: - rhel9cis_rule_5_2_20 tags: diff --git a/tasks/section_6/cis_6.1.x.yml b/tasks/section_6/cis_6.1.x.yml index 84df13e..a0e8dd6 100644 --- a/tasks/section_6/cis_6.1.x.yml +++ b/tasks/section_6/cis_6.1.x.yml @@ -150,7 +150,7 @@ - name: "6.1.10 | AUDIT | Ensure no unowned files or directories exist" block: - name: "6.1.10 | AUDIT | Ensure no unowned files or directories exist | Finding all unowned files or directories" - ansible.builtin.shell: find "{{ item.mount }}" -xdev -nouser + ansible.builtin.shell: find "{{ item.mount }}" -xdev -nouser -not -fstype nfs changed_when: false failed_when: false check_mode: false @@ -162,28 +162,21 @@ - item['device'].startswith('/dev') - not 'bind' in item['options'] - - name: "6.1.10 | AUDIT | Ensure no unowned files or directories exist | set fact" + - name: "6.1.10 | AUDIT | Ensure no unowned files or directories exist | Flatten no_user_items results for easier use" ansible.builtin.set_fact: - rhel_09_6_1_10_unowned_files_found: true - loop: "{{ rhel_09_6_1_10_audit.results }}" - when: - - item | length > 0 - - item.stdout is defined # skipped items are part of results list, but don't have the registered module properties - - item.stdout | length > 0 + discovered_unowned_files_flatten: "{{ rhel_09_6_1_10_audit.results | map(attribute='stdout_lines') | flatten }}" - name: "6.1.10 | AUDIT | Ensure no unowned files or directories exist | Displaying any unowned files or directories" ansible.builtin.debug: - msg: "Warning!! Missing owner on items in {{ rhel_09_6_1_10_audit | community.general.json_query('results[*].stdout_lines[*]') | flatten }}" # noqa jinja[invalid] - when: rhel_09_6_1_10_unowned_files_found + msg: "Warning!! Missing owner on items in {{ discovered_unowned_files_flatten }}" + when: discovered_unowned_files_flatten | length > 0 - name: "6.1.10 | AUDIT | Ensure no unowned files or directories exist | warning" ansible.builtin.import_tasks: file: warning_facts.yml vars: warn_control_id: '6.1.10' - when: rhel_09_6_1_10_unowned_files_found - vars: - rhel_09_6_1_10_unowned_files_found: false + when: discovered_unowned_files_flatten | length > 0 when: - rhel9cis_rule_6_1_10 tags: @@ -209,28 +202,21 @@ - item['device'].startswith('/dev') - not 'bind' in item['options'] - - name: "6.1.11 | AUDIT | Ensure no ungrouped files or directories exist | set fact" + - name: "6.1.11 | AUDIT | Ensure no ungrouped files or directories exist | Flatten no_user_items results for easier use" ansible.builtin.set_fact: - rhel_09_6_1_11_ungrouped_files_found: true - loop: "{{ rhel_09_6_1_11_audit.results }}" - when: - - item | length > 0 - - item.stdout is defined # skipped items are part of results list, but don't have the registered module properties - - item.stdout | length > 0 + discovered_ungrouped_files_flatten: "{{ rhel_09_6_1_11_audit.results | map(attribute='stdout_lines') | flatten }}" - name: "6.1.11 | AUDIT | Ensure no ungrouped files or directories exist | Displaying all ungrouped files or directories" ansible.builtin.debug: - msg: "Warning!! Missing group on items in {{ rhel_09_6_1_11_audit | community.general.json_query('results[*].stdout_lines[*]') | flatten }}" # noqa jinja[invalid] - when: rhel_09_6_1_11_ungrouped_files_found + msg: "Warning!! Missing group on items in {{ discovered_ungrouped_files_flatten }}" + when: discovered_ungrouped_files_flatten | length > 0 - name: "6.1.11 | AUDIT | Ensure no ungrouped files or directories exist | warning" ansible.builtin.import_tasks: file: warning_facts.yml vars: warn_control_id: '6.1.11' - when: rhel_09_6_1_11_ungrouped_files_found - vars: - rhel_09_6_1_11_ungrouped_files_found: false + when: discovered_ungrouped_files_flatten | length > 0 when: - rhel9cis_rule_6_1_11 tags: @@ -258,34 +244,26 @@ - name: "6.1.13 | AUDIT | Audit SUID executables" block: - name: "6.1.13 | AUDIT | Audit SUID executables | Find all SUID executables" - ansible.builtin.shell: df {{ item.mount }} -P | awk {'if (NR!=1) print $6'} | xargs -I '{}' find '{}' -xdev -type f -perm -4000 + ansible.builtin.shell: "df --local -P | awk {'if (NR!=1) print $6'} | xargs -I '{}' find '{}' -xdev -type f -perm -4000" failed_when: false changed_when: false register: rhel_09_6_1_13_suid_perms - loop: "{{ ansible_facts.mounts }}" - loop_control: - label: "{{ item.mount }}" - - - name: "6.1.13 | AUDIT | Audit SUID executables | set fact SUID executables" - ansible.builtin.set_fact: - rhel9_6_1_13_suid_found: true - loop: "{{ rhel_09_6_1_13_suid_perms.results }}" - when: - - item | length > 0 - - item.stdout is defined # skipped items are part of results list, but don't have the registered module properties - - item.stdout | length > 0 - name: "6.1.13 | AUDIT | Audit SUID executables | Alert SUID executables exist" ansible.builtin.debug: - msg: "Warning!! SUID set on items in {{ rhel_09_6_1_13_suid_perms | community.general.json_query('results[*].stdout_lines[*]') | flatten }}" # noqa jinja[invalid] - when: rhel9_6_1_13_suid_found + msg: "Warning!! SUID set on items in {{ rhel_09_6_1_13_suid_perms.stdout_lines }}" + when: + - rhel_09_6_1_13_suid_perms.stdout is defined + - rhel_09_6_1_13_suid_perms.stdout | length > 0 - name: "6.1.13 | AUDIT | Audit SUID executables | Alert SUID executables exist | warning" ansible.builtin.import_tasks: file: warning_facts.yml vars: warn_control_id: '6.1.13' - when: rhel9_6_1_13_suid_found + when: + - rhel_09_6_1_13_suid_perms.stdout is defined + - rhel_09_6_1_13_suid_perms.stdout | length > 0 vars: rhel9_6_1_13_suid_found: false when: @@ -301,34 +279,26 @@ - name: "6.1.14 | AUDIT | Audit SGID executables" block: - name: "6.1.14 | AUDIT | Audit SGID executables | Find all SGID executables" - ansible.builtin.shell: df {{ item.mount }} -P | awk {'if (NR!=1) print $6'} | xargs -I '{}' find '{}' -xdev -type f -perm -2000 + ansible.builtin.shell: df --local -P | awk {'if (NR!=1) print $6'} | xargs -I '{}' find '{}' -xdev -type f -perm -2000 failed_when: false changed_when: false register: rhel_09_6_1_14_sgid_perms - loop: "{{ ansible_facts.mounts }}" - loop_control: - label: "{{ item.mount }}" - - - name: "6.1.14 | AUDIT | Audit SGID executables | Set fact SGID executables" - ansible.builtin.set_fact: - rhel9_6_1_14_sgid_found: true - loop: "{{ rhel_09_6_1_14_sgid_perms.results }}" - when: - - item | length > 0 - - item.stdout is defined # skipped items are part of results list, but don't have the registered module properties - - item.stdout | length > 0 - name: "6.1.14 | AUDIT | Audit SGID executables | Alert SGID executables exist" ansible.builtin.debug: - msg: "Warning!! SGID set on items in {{ rhel_09_6_1_14_sgid_perms | community.general.json_query('results[*].stdout_lines[*]') | flatten }}" # noqa jinja[invalid] - when: rhel9_6_1_14_sgid_found + msg: "Warning!! SGID set on items in {{ rhel_09_6_1_14_sgid_perms.stdout_lines }}" + when: + - rhel_09_6_1_14_sgid_perms.stdout is defined + - rhel_09_6_1_14_sgid_perms.stdout | length > 0 - name: "6.1.14 | AUDIT | Audit SGID executables| warning" ansible.builtin.import_tasks: file: warning_facts.yml vars: warn_control_id: '6.1.14' - when: rhel9_6_1_14_sgid_found + when: + - rhel_09_6_1_14_sgid_perms.stdout is defined + - rhel_09_6_1_14_sgid_perms.stdout | length > 0 vars: rhel9_6_1_14_sgid_found: false when: diff --git a/templates/ansible_vars_goss.yml.j2 b/templates/ansible_vars_goss.yml.j2 index f3b8a98..e639bef 100644 --- a/templates/ansible_vars_goss.yml.j2 +++ b/templates/ansible_vars_goss.yml.j2 @@ -462,7 +462,7 @@ rhel9cis_syslog: {{ rhel9cis_syslog }} # Section 5 # This will allow use of drop in files when CIS adopts them. -rhel9_cis_sshd_config_file: {{ rhel9_cis_sshd_config_file }} +rhel9_cis_sshd_config_file: {{ rhel9cis_sshd_config_file }} ## 5.2.4 Note the following to understand precedence and layout rhel9cis_sshd_limited: false diff --git a/vars/audit.yml b/vars/audit.yml index bb50f6d..e677d8e 100644 --- a/vars/audit.yml +++ b/vars/audit.yml @@ -26,15 +26,16 @@ post_audit_outfile: "{{ audit_log_dir }}/{{ ansible_facts.hostname }}-{{ benchma ### Audit binary settings ### audit_bin_version: - release: v0.4.4 - AMD64_checksum: 'sha256:1c4f54b22fde9d4d5687939abc2606b0660a5d14a98afcd09b04b793d69acdc5' + release: v0.4.8 + AMD64_checksum: 'sha256:85d00b7bba5f175bec95de7dfe1f71f8f25204914aad4c6f03c8457868eb6e2f' + ARM64_checksum: 'sha256:bca8c898bfd35b94c51455ece6193c95e2cd7b2b183ac2047b2d76291e73e47d' audit_bin_path: /usr/local/bin/ audit_bin: "{{ audit_bin_path }}goss" audit_format: json audit_vars_path: "{{ audit_conf_dir }}/vars/{{ ansible_facts.hostname }}.yml" audit_results: | - The audit results are: {{ pre_audit_summary }} - {% if not audit_only %}The post remediation audit results are: {{ post_audit_summary }}{% endif %} + The{% if not audit_only %} pre remediation{% endif %} audit results are: {{ pre_audit_results}} + {% if not audit_only %}The post remediation audit results are: {{ post_audit_results }}{% endif %} Full breakdown can be found in {{ audit_log_dir }}