4
0
Fork 0

Merge pull request #235 from ansible-lockdown/devel

rhel9-cis main release v1.0.0
This commit is contained in:
uk-bolly 2024-09-10 15:45:16 +01:00 committed by GitHub
commit 16cb6a4617
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
20 changed files with 408 additions and 372 deletions

View file

@ -1,5 +1,4 @@
passlib passlib
lxml lxml
xmltodict xmltodict
jmespath
yamllint yamllint

View file

@ -1,139 +1,158 @@
--- ---
name: Devel pipeline name: Devel pipeline
on: # yamllint disable-line rule:truthy on: # yamllint disable-line rule:truthy
pull_request_target: pull_request_target:
types: [opened, reopened, synchronize] types: [opened, reopened, synchronize]
branches: branches:
- devel - devel
paths: paths:
- '**.yml' - '**.yml'
- '**.sh' - '**.sh'
- '**.j2' - '**.j2'
- '**.ps1' - '**.ps1'
- '**.cfg' - '**.cfg'
# Allow manual running of workflow
workflow_dispatch:
# A workflow run is made up of one or more jobs # Allow permissions for AWS auth
# that can run sequentially or in parallel permissions:
jobs: id-token: write
# This will create messages for first time contributers and direct them to the Discord server contents: read
welcome: pull-requests: read
runs-on: ubuntu-latest
steps: # A workflow run is made up of one or more jobs
- uses: actions/first-interaction@main # that can run sequentially or in parallel
with: jobs:
repo-token: ${{ secrets.GITHUB_TOKEN }} # This will create messages for first time contributers and direct them to the Discord server
pr-message: |- welcome:
Congrats on opening your first pull request and thank you for taking the time to help improve Ansible-Lockdown! runs-on: self-hosted
Please join in the conversation happening on the [Discord Server](https://www.lockdownenterprise.com/discord) as well.
# This workflow contains a single job that tests the playbook steps:
playbook-test: - uses: actions/first-interaction@main
# 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
with: 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 # This workflow contains a single job that tests the playbook
- name: Clone GitHub IaC plan playbook-test:
uses: actions/checkout@v4 # The type of runner that the job will run on
with: runs-on: self-hosted
repository: ansible-lockdown/github_linux_IaC env:
path: .github/workflows/github_linux_IaC 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 steps:
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
- name: DEBUG - Show IaC files - name: Git clone the lockdown repository to test
if: env.ENABLE_DEBUG == 'true' uses: actions/checkout@v4
run: | with:
echo "OSVAR = $OSVAR" ref: ${{ github.event.pull_request.head.sha }}
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: Terraform_Init - name: If a variable for IAC_BRANCH is set use that branch
id: init working-directory: .github/workflows
run: terraform init run: |
env: if [ ${{ vars.IAC_BRANCH }} != '' ]; then
# Imported from GitHub variables this is used to load the relevant OS.tfvars file echo "IAC_BRANCH=${{ vars.IAC_BRANCH }}" >> $GITHUB_ENV
OSVAR: ${{ vars.OSVAR }} echo "Pipeline using the following IAC branch ${{ vars.IAC_BRANCH }}"
TF_VAR_benchmark_type: ${{ vars.BENCHMARK_TYPE }} else
echo IAC_BRANCH=main >> $GITHUB_ENV
fi
- name: Terraform_Validate # Pull in terraform code for linux servers
id: validate - name: Clone GitHub IaC plan
run: terraform validate uses: actions/checkout@v4
env: with:
# Imported from GitHub variables this is used to load the relevant OS.tfvars file repository: ansible-lockdown/github_linux_IaC
OSVAR: ${{ vars.OSVAR }} path: .github/workflows/github_linux_IaC
TF_VAR_benchmark_type: ${{ vars.BENCHMARK_TYPE }} ref: ${{ env.IAC_BRANCH }}
- name: Terraform_Apply # Uses dedicated restricted role and policy to enable this only for this task
id: apply # No credentials are part of github for AWS auth
env: - name: configure aws credentials
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} uses: aws-actions/configure-aws-credentials@main
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} with:
OSVAR: ${{ vars.OSVAR }} role-to-assume: ${{ secrets.AWS_ASSUME_ROLE }}
TF_VAR_benchmark_type: ${{ vars.BENCHMARK_TYPE }} role-session-name: ${{ secrets.AWS_ROLE_SESSION }}
run: terraform apply -var-file "github_vars.tfvars" -var-file "${OSVAR}.tfvars" --auto-approve -input=false aws-region: ${{ env.AWS_REGION }}
## Debug Section - name: DEBUG - Show IaC files
- name: DEBUG - Show Ansible hostfile if: env.ENABLE_DEBUG == 'true'
if: env.ENABLE_DEBUG == 'true' run: |
run: cat hosts.yml 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 - name: Tofu validate
run: sleep ${{ vars.BUILD_SLEEPTIME }} 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: Tofu apply
- name: Run_Ansible_Playbook id: apply
uses: arillso/action.playbook@master env:
with: OSVAR: ${{ vars.OSVAR }}
playbook: site.yml TF_VAR_benchmark_type: ${{ vars.BENCHMARK_TYPE }}
inventory: .github/workflows/github_linux_IaC/hosts.yml TF_VAR_privsubnet_id: ${{ secrets.AWS_PRIVSUBNET_ID }}
galaxy_file: collections/requirements.yml TF_VAR_vpc_secgrp_id: ${{ secrets.AWS_VPC_SECGRP_ID }}
private_key: ${{ secrets.SSH_PRV_KEY }} run: tofu apply -var-file "${OSVAR}.tfvars" --auto-approve -input=false
# verbose: 3
env:
ANSIBLE_HOST_KEY_CHECKING: "false"
ANSIBLE_DEPRECATION_WARNINGS: "false"
ANSIBLE_INJECT_FACT_VARS: "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 # Aws deployments taking a while to come up insert sleep or playbook fails
if: always() && env.ENABLE_DEBUG == 'false'
env: - name: Sleep to allow system to come up
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} run: sleep ${{ vars.BUILD_SLEEPTIME }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
OSVAR: ${{ vars.OSVAR }} # Run the Ansible playbook
TF_VAR_benchmark_type: ${{ vars.BENCHMARK_TYPE }} - name: Run_Ansible_Playbook
run: terraform destroy -var-file "github_vars.tfvars" -var-file "${OSVAR}.tfvars" --auto-approve -input=false 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

View file

@ -1,128 +1,156 @@
--- ---
name: Main pipeline name: Main pipeline
on: # yamllint disable-line rule:truthy on: # yamllint disable-line rule:truthy
pull_request_target: pull_request_target:
types: [opened, reopened, synchronize] types: [opened, reopened, synchronize]
branches: branches:
- main - main
paths: paths:
- '**.yml' - '**.yml'
- '**.sh' - '**.sh'
- '**.j2' - '**.j2'
- '**.ps1' - '**.ps1'
- '**.cfg' - '**.cfg'
# A workflow run is made up of one or more jobs # Allow permissions for AWS auth
# that can run sequentially or in parallel permissions:
jobs: id-token: write
contents: read
pull-requests: read
# This workflow contains a single job that tests the playbook # A workflow run is made up of one or more jobs
playbook-test: # that can run sequentially or in parallel
# The type of runner that the job will run on jobs:
runs-on: ubuntu-latest # This will create messages for first time contributers and direct them to the Discord server
env: welcome:
ENABLE_DEBUG: ${{ vars.ENABLE_DEBUG }} runs-on: self-hosted
# 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: steps:
- name: Clone ${{ github.event.repository.name }} - uses: actions/first-interaction@main
uses: actions/checkout@v4
with: 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 # This workflow contains a single job that tests the playbook
- name: Clone GitHub IaC plan playbook-test:
uses: actions/checkout@v4 # The type of runner that the job will run on
with: runs-on: self-hosted
repository: ansible-lockdown/github_linux_IaC env:
path: .github/workflows/github_linux_IaC 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 steps:
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
- name: DEBUG - Show IaC files - name: Git clone the lockdown repository to test
if: env.ENABLE_DEBUG == 'true' uses: actions/checkout@v4
run: | with:
echo "OSVAR = $OSVAR" ref: ${{ github.event.pull_request.head.sha }}
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: Terraform_Init - name: If a variable for IAC_BRANCH is set use that branch
id: init working-directory: .github/workflows
run: terraform init run: |
env: if [ ${{ vars.IAC_BRANCH }} != '' ]; then
# Imported from GitHub variables this is used to load the relevant OS.tfvars file echo "IAC_BRANCH=${{ vars.IAC_BRANCH }}" >> $GITHUB_ENV
OSVAR: ${{ vars.OSVAR }} echo "Pipeline using the following IAC branch ${{ vars.IAC_BRANCH }}"
TF_VAR_benchmark_type: ${{ vars.BENCHMARK_TYPE }} else
echo IAC_BRANCH=main >> $GITHUB_ENV
fi
- name: Terraform_Validate # Pull in terraform code for linux servers
id: validate - name: Clone GitHub IaC plan
run: terraform validate uses: actions/checkout@v4
env: with:
# Imported from GitHub variables this is used to load the relevant OS.tfvars file repository: ansible-lockdown/github_linux_IaC
OSVAR: ${{ vars.OSVAR }} path: .github/workflows/github_linux_IaC
TF_VAR_benchmark_type: ${{ vars.BENCHMARK_TYPE }} ref: ${{ env.IAC_BRANCH }}
- name: Terraform_Apply # Uses dedicated restricted role and policy to enable this only for this task
id: apply # No credentials are part of github for AWS auth
env: - name: configure aws credentials
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} uses: aws-actions/configure-aws-credentials@main
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} with:
OSVAR: ${{ vars.OSVAR }} role-to-assume: ${{ secrets.AWS_ASSUME_ROLE }}
TF_VAR_benchmark_type: ${{ vars.BENCHMARK_TYPE }} role-session-name: ${{ secrets.AWS_ROLE_SESSION }}
run: terraform apply -var-file "github_vars.tfvars" -var-file "${OSVAR}.tfvars" --auto-approve -input=false aws-region: ${{ env.AWS_REGION }}
## Debug Section - name: DEBUG - Show IaC files
- name: DEBUG - Show Ansible hostfile if: env.ENABLE_DEBUG == 'true'
if: env.ENABLE_DEBUG == 'true' run: |
run: cat hosts.yml 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 - name: Tofu validate
run: sleep ${{ vars.BUILD_SLEEPTIME }} 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: Tofu apply
- name: Run_Ansible_Playbook id: apply
uses: arillso/action.playbook@master env:
with: OSVAR: ${{ vars.OSVAR }}
playbook: site.yml TF_VAR_benchmark_type: ${{ vars.BENCHMARK_TYPE }}
inventory: .github/workflows/github_linux_IaC/hosts.yml TF_VAR_privsubnet_id: ${{ secrets.AWS_PRIVSUBNET_ID }}
galaxy_file: collections/requirements.yml TF_VAR_vpc_secgrp_id: ${{ secrets.AWS_VPC_SECGRP_ID }}
private_key: ${{ secrets.SSH_PRV_KEY }} run: tofu apply -var-file "${OSVAR}.tfvars" --auto-approve -input=false
# verbose: 3
env:
ANSIBLE_HOST_KEY_CHECKING: "false"
ANSIBLE_DEPRECATION_WARNINGS: "false"
ANSIBLE_INJECT_FACT_VARS: "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 # Aws deployments taking a while to come up insert sleep or playbook fails
if: always() && env.ENABLE_DEBUG == 'false'
env: - name: Sleep to allow system to come up
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} run: sleep ${{ vars.BUILD_SLEEPTIME }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
OSVAR: ${{ vars.OSVAR }} # Run the Ansible playbook
TF_VAR_benchmark_type: ${{ vars.BENCHMARK_TYPE }} - name: Run_Ansible_Playbook
run: terraform destroy -var-file "github_vars.tfvars" -var-file "${OSVAR}.tfvars" --auto-approve -input=false 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

View file

@ -1,19 +1,19 @@
--- ---
name: update galaxy name: update galaxy
on: on:
push: push:
branches: branches:
- main - main
jobs: jobs:
update_role: update_role:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Checkout repo - name: Checkout repo
uses: actions/checkout@v4 uses: actions/checkout@v4
- name: Action Ansible Galaxy Release ${{ github.ref_name }} - name: Action Ansible Galaxy Release ${{ github.ref_name }}
uses: ansible-actions/ansible-galaxy-action@main uses: ansible-actions/ansible-galaxy-action@main
with: with:
galaxy_api_key: ${{ secrets.GALAXY_API_KEY }} galaxy_api_key: ${{ secrets.GALAXY_API_KEY }}

View file

@ -37,13 +37,13 @@ repos:
exclude: .config/.gitleaks-report.json exclude: .config/.gitleaks-report.json
- repo: https://github.com/gitleaks/gitleaks - repo: https://github.com/gitleaks/gitleaks
rev: v8.18.3 rev: v8.18.4
hooks: hooks:
- id: gitleaks - id: gitleaks
args: ['--baseline-path', '.config/.gitleaks-report.json'] args: ['--baseline-path', '.config/.gitleaks-report.json']
- repo: https://github.com/ansible-community/ansible-lint - repo: https://github.com/ansible-community/ansible-lint
rev: v24.6.0 rev: v24.7.0
hooks: hooks:
- id: ansible-lint - id: ansible-lint
name: Ansible-lint name: Ansible-lint

View file

@ -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. 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. 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) ## Auditing (new)

View file

@ -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 # 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 # 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.<Rounds>.<Salt>.<Checksum>' # this format: 'grub.pbkdf2.sha512.<Rounds>.<Salt>.<Checksum>'
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 ## Control 1.4.1
# This variable governs whether a bootloader password should be set in '/boot/grub2/user.cfg' file. # 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 # 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. # 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'. # 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: ## Controls:
## - 5.2.4 - Ensure SSH access is limited ## - 5.2.4 - Ensure SSH access is limited

View file

@ -10,7 +10,7 @@
- name: Pre Audit Setup | Set audit package name | ARM64 - name: Pre Audit Setup | Set audit package name | ARM64
ansible.builtin.set_fact: ansible.builtin.set_fact:
audit_pkg_arch_name: ARM64 audit_pkg_arch_name: ARM64
when: ansible_facts.machine == "arm64" when: ansible_facts.machine == "aarch64"
- name: Pre Audit Setup | Download audit binary - name: Pre Audit Setup | Download audit binary
ansible.builtin.get_url: ansible.builtin.get_url:

View file

@ -22,7 +22,7 @@
when: when:
- audit_only - audit_only
ansible.builtin.debug: ansible.builtin.debug:
msg: "The Audit results are: {{ pre_audit_summary }}." msg: "{{ audit_results.split('\n') }}"
- name: Audit_only | Stop Playbook Audit Only selected - name: Audit_only | Stop Playbook Audit Only selected
when: when:

View file

@ -21,26 +21,24 @@
when: when:
- audit_format == "json" - audit_format == "json"
block: block:
- name: capture data {{ post_audit_outfile }} - name: Post Audit | Capture audit data if json format
ansible.builtin.shell: "cat {{ post_audit_outfile }}" ansible.builtin.shell: grep -E '"summary-line.*Count:.*Failed' "{{ post_audit_outfile }}" | cut -d'"' -f4
register: post_audit register: post_audit_summary
changed_when: false changed_when: false
- name: Capture post-audit result - name: Post Audit | Set Fact for audit summary
ansible.builtin.set_fact: ansible.builtin.set_fact:
post_audit_summary: "{{ post_audit.stdout | from_json | json_query(summary) }}" post_audit_results: "{{ post_audit_summary.stdout }}"
vars:
summary: summary."summary-line"
- name: Post Audit | Capture audit data if documentation format - name: Post Audit | Capture audit data if documentation format
when: when:
- audit_format == "documentation" - audit_format == "documentation"
block: block:
- name: Post Audit | capture data {{ post_audit_outfile }} - name: Post Audit | Capture audit data if documentation format
ansible.builtin.shell: "tail -2 {{ post_audit_outfile }}" ansible.builtin.shell: tail -2 "{{ post_audit_outfile }}" | tac | tr '\n' ' '
register: post_audit register: post_audit_summary
changed_when: false changed_when: false
- name: Post Audit | Capture post-audit result - name: Post Audit | Set Fact for audit summary
ansible.builtin.set_fact: ansible.builtin.set_fact:
post_audit_summary: "{{ post_audit.stdout_lines }}" post_audit_results: "{{ post_audit_summary.stdout }}"

View file

@ -90,31 +90,30 @@
when: when:
- audit_format == "json" - audit_format == "json"
block: block:
- name: Pre Audit | Capture data {{ pre_audit_outfile }} - name: Pre Audit | Capture audit data if json format
ansible.builtin.shell: "cat {{ pre_audit_outfile }}" ansible.builtin.shell: grep -E '\"summary-line.*Count:.*Failed' "{{ pre_audit_outfile }}" | cut -d'"' -f4
register: pre_audit register: pre_audit_summary
changed_when: false changed_when: false
- name: Pre Audit | Capture pre-audit result - name: Pre Audit | Set Fact for audit summary
ansible.builtin.set_fact: ansible.builtin.set_fact:
pre_audit_summary: "{{ pre_audit.stdout | from_json | json_query(summary) }}" pre_audit_results: "{{ pre_audit_summary.stdout }}"
vars:
summary: summary."summary-line"
- name: Pre Audit | Capture audit data if documentation format - name: Pre Audit | Capture audit data if documentation format
when: when:
- audit_format == "documentation" - audit_format == "documentation"
block: block:
- name: Pre Audit | Capture data {{ pre_audit_outfile }} | documentation format - name: Pre Audit | Capture audit data if documentation format
ansible.builtin.shell: "tail -2 {{ pre_audit_outfile }}" ansible.builtin.shell: tail -2 "{{ pre_audit_outfile }}" | tac | tr '\n' ' '
register: pre_audit register: pre_audit_summary
changed_when: false changed_when: false
- name: Pre Audit | Capture pre-audit result | documentation format - name: Pre Audit | Set Fact for audit summary
ansible.builtin.set_fact: ansible.builtin.set_fact:
pre_audit_summary: "{{ pre_audit.stdout_lines }}" pre_audit_results: "{{ pre_audit_summary.stdout }}"
- name: Audit_Only | Run Audit Only - name: Audit_Only | Run Audit Only
when: when:
- audit_only - audit_only
ansible.builtin.import_tasks: audit_only.yml ansible.builtin.import_tasks:
file: audit_only.yml

View file

@ -242,18 +242,16 @@
# Added to ensure ssh drop in file exists if not default /etc/ssh/sshd_config # Added to ensure ssh drop in file exists if not default /etc/ssh/sshd_config
- name: "PRELIM | Section 5.2 | SSH" - name: "PRELIM | Section 5.2 | SSH"
ansible.builtin.file: ansible.builtin.file:
path: "{{ rhel9_cis_sshd_config_file }}" path: "{{ rhel9cis_sshd_config_file }}"
owner: root owner: root
group: root group: root
mode: '0600' mode: '0600'
state: touch state: touch
when: when:
- rhel9_cis_sshd_config_file != '/etc/ssh/sshd_config' - rhel9cis_sshd_config_file != '/etc/ssh/sshd_config'
- "'openssh-server' in ansible_facts.packages" - "'openssh-server' in ansible_facts.packages"
tags: tags:
- ssh - always
- level1_server
- level1_workstation
- name: "PRELIM | 5.3.4 | Find all sudoers files." - name: "PRELIM | 5.3.4 | Find all sudoers files."
ansible.builtin.shell: "find /etc/sudoers /etc/sudoers.d/ -type f ! -name '*~' ! -name '*.*'" ansible.builtin.shell: "find /etc/sudoers /etc/sudoers.d/ -type f ! -name '*~' ! -name '*.*'"

View file

@ -89,8 +89,8 @@
group: root group: root
mode: '0644' mode: '0644'
loop: loop:
- { regexp: '^user-db', line: 'user-db: user' } - { regexp: '^user-db', line: 'user-db:user' }
- { regexp: '^system-db', line: 'system-db: local' } - { regexp: '^system-db', line: 'system-db:local' }
- name: "1.8.4 | PATCH | Ensure GDM screen locks when the user is idle | Make db directory" - name: "1.8.4 | PATCH | Ensure GDM screen locks when the user is idle | Make db directory"
ansible.builtin.file: ansible.builtin.file:

View file

@ -23,7 +23,7 @@
"4.1.4.3 | PATCH | Ensure only authorized groups are assigned ownership of audit log files" "4.1.4.3 | PATCH | Ensure only authorized groups are assigned ownership of audit log files"
ansible.builtin.file: ansible.builtin.file:
path: "{{ audit_discovered_logfile.stdout }}" path: "{{ audit_discovered_logfile.stdout }}"
mode: "{% if auditd_logfile.stat.mode != '0600' %}0640{% endif %}" mode: 'u-x,g-rw,o-rwx'
owner: root owner: root
group: root group: root
when: when:
@ -50,7 +50,7 @@
ansible.builtin.file: ansible.builtin.file:
path: "{{ audit_discovered_logfile.stdout | dirname }}" path: "{{ audit_discovered_logfile.stdout | dirname }}"
state: directory state: directory
mode: '0750' mode: 'g-w,o-rwx'
when: not auditlog_dir.stat.mode is match('07(0|5)0') when: not auditlog_dir.stat.mode is match('07(0|5)0')
when: when:
- rhel9cis_rule_4_1_4_4 - 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" - name: "4.1.4.5 | PATCH | Ensure audit configuration files are 640 or more restrictive"
ansible.builtin.file: ansible.builtin.file:
path: "{{ item.path }}" 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: "{{ auditd_conf_files.files }}"
loop_control: loop_control:
label: "{{ item.path }}" label: "{{ item.path }}"
@ -81,6 +83,8 @@
ansible.builtin.file: ansible.builtin.file:
path: "{{ item.path }}" path: "{{ item.path }}"
owner: root 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: "{{ auditd_conf_files.files | default([]) }}"
loop_control: loop_control:
label: "{{ item.path }}" label: "{{ item.path }}"
@ -97,6 +101,8 @@
ansible.builtin.file: ansible.builtin.file:
path: "{{ item.path }}" path: "{{ item.path }}"
group: root 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: "{{ auditd_conf_files.files | default([]) }}"
loop_control: loop_control:
label: "{{ item.path }}" label: "{{ item.path }}"
@ -126,8 +132,7 @@
- name: "4.1.4.8 | PATCH | Ensure audit tools are 755 or more restrictive | set if required" - name: "4.1.4.8 | PATCH | Ensure audit tools are 755 or more restrictive | set if required"
ansible.builtin.file: ansible.builtin.file:
path: "{{ item.item }}" path: "{{ item.item }}"
mode: '0750' mode: 'go-w'
loop: "{{ audit_bins.results }}" loop: "{{ audit_bins.results }}"
loop_control: loop_control:
label: "{{ item.item }}" label: "{{ item.item }}"

View file

@ -123,7 +123,7 @@
local2,local3.* -/var/log/localmessages local2,local3.* -/var/log/localmessages
local4,local5.* -/var/log/localmessages local4,local5.* -/var/log/localmessages
local6,local7.* -/var/log/localmessages local6,local7.* -/var/log/localmessages
*.emrg :omusrmsg:* *.emerg :omusrmsg:*
insertafter: '#### RULES ####' insertafter: '#### RULES ####'
notify: Restart rsyslog notify: Restart rsyslog

View file

@ -14,6 +14,8 @@
ansible.builtin.file: ansible.builtin.file:
path: "{{ item.path }}" path: "{{ item.path }}"
mode: "{{ '0600' if item.mode == '0600' else '0640' }}" 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: "{{ logfiles.files }}"
loop_control: loop_control:
label: "{{ item.path }}" label: "{{ item.path }}"

View file

@ -77,7 +77,7 @@
block: block:
- name: "5.2.4 | PATCH | Ensure SSH access is limited | Add line to sshd_config for allowusers" - name: "5.2.4 | PATCH | Ensure SSH access is limited | Add line to sshd_config for allowusers"
ansible.builtin.lineinfile: ansible.builtin.lineinfile:
path: "{{ rhel9_cis_sshd_config_file }}" path: "{{ rhel9cis_sshd_config_file }}"
regexp: "^AllowUsers" regexp: "^AllowUsers"
line: "AllowUsers {{ rhel9cis_sshd['allowusers'] }}" line: "AllowUsers {{ rhel9cis_sshd['allowusers'] }}"
validate: sshd -t -f %s 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" - name: "5.2.4 | PATCH | Ensure SSH access is limited | Add line to sshd_config for allowgroups"
ansible.builtin.lineinfile: ansible.builtin.lineinfile:
path: "{{ rhel9_cis_sshd_config_file }}" path: "{{ rhel9cis_sshd_config_file }}"
regexp: "^AllowGroups" regexp: "^AllowGroups"
line: "AllowGroups {{ rhel9cis_sshd['allowgroups'] }}" line: "AllowGroups {{ rhel9cis_sshd['allowgroups'] }}"
validate: sshd -t -f %s 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" - name: "5.2.4 | PATCH | Ensure SSH access is limited | Add line to sshd_config for denyusers"
ansible.builtin.lineinfile: ansible.builtin.lineinfile:
path: "{{ rhel9_cis_sshd_config_file }}" path: "{{ rhel9cis_sshd_config_file }}"
regexp: "^DenyUsers" regexp: "^DenyUsers"
line: "DenyUsers {{ rhel9cis_sshd['denyusers'] }}" line: "DenyUsers {{ rhel9cis_sshd['denyusers'] }}"
validate: sshd -t -f %s 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" - name: "5.2.4 | PATCH | Ensure SSH access is limited | Add line to sshd_config for denygroups"
ansible.builtin.lineinfile: ansible.builtin.lineinfile:
path: "{{ rhel9_cis_sshd_config_file }}" path: "{{ rhel9cis_sshd_config_file }}"
regexp: "^DenyGroups" regexp: "^DenyGroups"
line: "DenyGroups {{ rhel9cis_sshd['denygroups'] }}" line: "DenyGroups {{ rhel9cis_sshd['denygroups'] }}"
validate: sshd -t -f %s validate: sshd -t -f %s
@ -121,10 +121,11 @@
- name: "5.2.5 | PATCH | Ensure SSH LogLevel is appropriate" - name: "5.2.5 | PATCH | Ensure SSH LogLevel is appropriate"
ansible.builtin.lineinfile: ansible.builtin.lineinfile:
path: "{{ rhel9_cis_sshd_config_file }}" path: "{{ rhel9cis_sshd_config_file }}"
regexp: "^#LogLevel|^LogLevel" regexp: "^#LogLevel|^LogLevel"
line: 'LogLevel {{ rhel9cis_ssh_loglevel }}' line: 'LogLevel {{ rhel9cis_ssh_loglevel }}'
validate: sshd -t -f %s validate: sshd -t -f %s
notify: Restart sshd
when: when:
- rhel9cis_rule_5_2_5 - rhel9cis_rule_5_2_5
tags: tags:
@ -136,10 +137,11 @@
- name: "5.2.6 | PATCH | Ensure SSH PAM is enabled" - name: "5.2.6 | PATCH | Ensure SSH PAM is enabled"
ansible.builtin.lineinfile: ansible.builtin.lineinfile:
path: "{{ rhel9_cis_sshd_config_file }}" path: "{{ rhel9cis_sshd_config_file }}"
regexp: "^#UsePAM|^UsePAM" regexp: "^#UsePAM|^UsePAM"
line: 'UsePAM yes' line: 'UsePAM yes'
validate: sshd -t -f %s validate: sshd -t -f %s
notify: Restart sshd
when: when:
- rhel9cis_rule_5_2_6 - rhel9cis_rule_5_2_6
tags: tags:
@ -153,7 +155,7 @@
block: block:
- name: "5.2.7 | PATCH | Ensure SSH root login is disabled | config file" - name: "5.2.7 | PATCH | Ensure SSH root login is disabled | config file"
ansible.builtin.lineinfile: ansible.builtin.lineinfile:
path: "{{ rhel9_cis_sshd_config_file }}" path: "{{ rhel9cis_sshd_config_file }}"
regexp: "^#PermitRootLogin|^PermitRootLogin" regexp: "^#PermitRootLogin|^PermitRootLogin"
line: 'PermitRootLogin no' line: 'PermitRootLogin no'
validate: sshd -t -f %s validate: sshd -t -f %s
@ -162,6 +164,7 @@
ansible.builtin.file: ansible.builtin.file:
path: /etc/ssh/sshd_config.d/01-permitrootlogin.conf path: /etc/ssh/sshd_config.d/01-permitrootlogin.conf
state: absent state: absent
notify: Restart sshd
when: when:
- rhel9cis_rule_5_2_7 - rhel9cis_rule_5_2_7
tags: tags:
@ -173,10 +176,11 @@
- name: "5.2.8 | PATCH | Ensure SSH HostbasedAuthentication is disabled" - name: "5.2.8 | PATCH | Ensure SSH HostbasedAuthentication is disabled"
ansible.builtin.lineinfile: ansible.builtin.lineinfile:
path: "{{ rhel9_cis_sshd_config_file }}" path: "{{ rhel9cis_sshd_config_file }}"
regexp: "^#HostbasedAuthentication|^HostbasedAuthentication" regexp: "^#HostbasedAuthentication|^HostbasedAuthentication"
line: 'HostbasedAuthentication no' line: 'HostbasedAuthentication no'
validate: sshd -t -f %s validate: sshd -t -f %s
notify: Restart sshd
when: when:
- rhel9cis_rule_5_2_8 - rhel9cis_rule_5_2_8
tags: tags:
@ -188,10 +192,11 @@
- name: "5.2.9 | PATCH | Ensure SSH PermitEmptyPasswords is disabled" - name: "5.2.9 | PATCH | Ensure SSH PermitEmptyPasswords is disabled"
ansible.builtin.lineinfile: ansible.builtin.lineinfile:
path: "{{ rhel9_cis_sshd_config_file }}" path: "{{ rhel9cis_sshd_config_file }}"
regexp: "^#PermitEmptyPasswords|^PermitEmptyPasswords" regexp: "^#PermitEmptyPasswords|^PermitEmptyPasswords"
line: 'PermitEmptyPasswords no' line: 'PermitEmptyPasswords no'
validate: sshd -t -f %s validate: sshd -t -f %s
notify: Restart sshd
when: when:
- rhel9cis_rule_5_2_9 - rhel9cis_rule_5_2_9
tags: tags:
@ -203,10 +208,11 @@
- name: "5.2.10 | PATCH | Ensure SSH PermitUserEnvironment is disabled" - name: "5.2.10 | PATCH | Ensure SSH PermitUserEnvironment is disabled"
ansible.builtin.lineinfile: ansible.builtin.lineinfile:
path: "{{ rhel9_cis_sshd_config_file }}" path: "{{ rhel9cis_sshd_config_file }}"
regexp: "^#PermitUserEnvironment|^PermitUserEnvironment" regexp: "^#PermitUserEnvironment|^PermitUserEnvironment"
line: 'PermitUserEnvironment no' line: 'PermitUserEnvironment no'
validate: sshd -t -f %s validate: sshd -t -f %s
notify: Restart sshd
when: when:
- rhel9cis_rule_5_2_10 - rhel9cis_rule_5_2_10
tags: tags:
@ -218,10 +224,11 @@
- name: "5.2.11 | PATCH | Ensure SSH IgnoreRhosts is enabled" - name: "5.2.11 | PATCH | Ensure SSH IgnoreRhosts is enabled"
ansible.builtin.lineinfile: ansible.builtin.lineinfile:
path: "{{ rhel9_cis_sshd_config_file }}" path: "{{ rhel9cis_sshd_config_file }}"
regexp: "^#IgnoreRhosts|^IgnoreRhosts" regexp: "^#IgnoreRhosts|^IgnoreRhosts"
line: 'IgnoreRhosts yes' line: 'IgnoreRhosts yes'
validate: sshd -t -f %s validate: sshd -t -f %s
notify: Restart sshd
when: when:
- rhel9cis_rule_5_2_11 - rhel9cis_rule_5_2_11
tags: tags:
@ -236,10 +243,11 @@
- name: "5.2.12 | PATCH | Ensure SSH X11 forwarding is disabled | config file" - name: "5.2.12 | PATCH | Ensure SSH X11 forwarding is disabled | config file"
ansible.builtin.lineinfile: ansible.builtin.lineinfile:
path: "{{ rhel9_cis_sshd_config_file }}" path: "{{ rhel9cis_sshd_config_file }}"
regexp: "^#X11Forwarding|^X11Forwarding" regexp: "^#X11Forwarding|^X11Forwarding"
line: 'X11Forwarding no' line: 'X11Forwarding no'
validate: sshd -t -f %s validate: sshd -t -f %s
notify: Restart sshd
- name: "5.2.12 | PATCH | Ensure SSH X11 forwarding is disabled | override" - name: "5.2.12 | PATCH | Ensure SSH X11 forwarding is disabled | override"
ansible.builtin.lineinfile: ansible.builtin.lineinfile:
@ -247,6 +255,7 @@
regexp: "^#X11Forwarding|^X11Forwarding" regexp: "^#X11Forwarding|^X11Forwarding"
line: 'X11Forwarding no' line: 'X11Forwarding no'
validate: sshd -t -f %s validate: sshd -t -f %s
notify: Restart sshd
when: when:
- rhel9cis_rule_5_2_12 - rhel9cis_rule_5_2_12
tags: tags:
@ -258,10 +267,11 @@
- name: "5.2.13 | PATCH | Ensure SSH AllowTcpForwarding is disabled" - name: "5.2.13 | PATCH | Ensure SSH AllowTcpForwarding is disabled"
ansible.builtin.lineinfile: ansible.builtin.lineinfile:
path: "{{ rhel9_cis_sshd_config_file }}" path: "{{ rhel9cis_sshd_config_file }}"
regexp: "^#AllowTcpForwarding|^AllowTcpForwarding" regexp: "^#AllowTcpForwarding|^AllowTcpForwarding"
line: 'AllowTcpForwarding no' line: 'AllowTcpForwarding no'
validate: sshd -t -f %s validate: sshd -t -f %s
notify: Restart sshd
when: when:
- rhel9cis_rule_5_2_13 - rhel9cis_rule_5_2_13
tags: tags:
@ -294,9 +304,10 @@
- name: "5.2.15 | PATCH | Ensure SSH warning banner is configured" - name: "5.2.15 | PATCH | Ensure SSH warning banner is configured"
ansible.builtin.lineinfile: ansible.builtin.lineinfile:
path: "{{ rhel9_cis_sshd_config_file }}" path: "{{ rhel9cis_sshd_config_file }}"
regexp: '^Banner' regexp: '^Banner'
line: 'Banner /etc/issue.net' line: 'Banner /etc/issue.net'
notify: Restart sshd
when: when:
- rhel9cis_rule_5_2_15 - rhel9cis_rule_5_2_15
tags: tags:
@ -308,10 +319,11 @@
- name: "5.2.16 | PATCH | Ensure SSH MaxAuthTries is set to 4 or less" - name: "5.2.16 | PATCH | Ensure SSH MaxAuthTries is set to 4 or less"
ansible.builtin.lineinfile: ansible.builtin.lineinfile:
path: "{{ rhel9_cis_sshd_config_file }}" path: "{{ rhel9cis_sshd_config_file }}"
regexp: '^(#)?MaxAuthTries \d' regexp: '^(#)?MaxAuthTries \d'
line: 'MaxAuthTries 4' line: 'MaxAuthTries 4'
validate: sshd -t -f %s validate: sshd -t -f %s
notify: Restart sshd
when: when:
- rhel9cis_rule_5_2_16 - rhel9cis_rule_5_2_16
tags: tags:
@ -323,10 +335,11 @@
- name: "5.2.17 | PATCH | Ensure SSH MaxStartups is configured" - name: "5.2.17 | PATCH | Ensure SSH MaxStartups is configured"
ansible.builtin.lineinfile: ansible.builtin.lineinfile:
path: "{{ rhel9_cis_sshd_config_file }}" path: "{{ rhel9cis_sshd_config_file }}"
regexp: "^#MaxStartups|^MaxStartups" regexp: "^#MaxStartups|^MaxStartups"
line: 'MaxStartups 10:30:60' line: 'MaxStartups 10:30:60'
validate: sshd -t -f %s validate: sshd -t -f %s
notify: Restart sshd
when: when:
- rhel9cis_rule_5_2_17 - rhel9cis_rule_5_2_17
tags: tags:
@ -338,10 +351,11 @@
- name: "5.2.18 | PATCH | Ensure SSH MaxSessions is set to 10 or less" - name: "5.2.18 | PATCH | Ensure SSH MaxSessions is set to 10 or less"
ansible.builtin.lineinfile: ansible.builtin.lineinfile:
path: "{{ rhel9_cis_sshd_config_file }}" path: "{{ rhel9cis_sshd_config_file }}"
regexp: "^#MaxSessions|^MaxSessions" regexp: "^#MaxSessions|^MaxSessions"
line: 'MaxSessions {{ rhel9cis_ssh_maxsessions }}' line: 'MaxSessions {{ rhel9cis_ssh_maxsessions }}'
validate: sshd -t -f %s validate: sshd -t -f %s
notify: Restart sshd
when: when:
- rhel9cis_rule_5_2_18 - rhel9cis_rule_5_2_18
tags: tags:
@ -353,10 +367,11 @@
- name: "5.2.19 | PATCH | Ensure SSH LoginGraceTime is set to one minute or less" - name: "5.2.19 | PATCH | Ensure SSH LoginGraceTime is set to one minute or less"
ansible.builtin.lineinfile: ansible.builtin.lineinfile:
path: "{{ rhel9_cis_sshd_config_file }}" path: "{{ rhel9cis_sshd_config_file }}"
regexp: "^#LoginGraceTime|^LoginGraceTime" regexp: "^#LoginGraceTime|^LoginGraceTime"
line: "LoginGraceTime {{ rhel9cis_sshd['logingracetime'] }}" line: "LoginGraceTime {{ rhel9cis_sshd['logingracetime'] }}"
validate: sshd -t -f %s validate: sshd -t -f %s
notify: Restart sshd
when: when:
- rhel9cis_rule_5_2_19 - rhel9cis_rule_5_2_19
tags: tags:
@ -370,17 +385,19 @@
block: block:
- name: "5.2.20 | PATCH | Ensure SSH Idle Timeout Interval is configured | Add line in sshd_config for ClientAliveInterval" - name: "5.2.20 | PATCH | Ensure SSH Idle Timeout Interval is configured | Add line in sshd_config for ClientAliveInterval"
ansible.builtin.lineinfile: ansible.builtin.lineinfile:
path: "{{ rhel9_cis_sshd_config_file }}" path: "{{ rhel9cis_sshd_config_file }}"
regexp: '^ClientAliveInterval' regexp: '^ClientAliveInterval'
line: "ClientAliveInterval {{ rhel9cis_sshd['clientaliveinterval'] }}" line: "ClientAliveInterval {{ rhel9cis_sshd['clientaliveinterval'] }}"
validate: sshd -t -f %s 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" - name: "5.2.20 | PATCH | Ensure SSH Idle Timeout Interval is configured | Ensure SSH ClientAliveCountMax set to <= 3"
ansible.builtin.lineinfile: ansible.builtin.lineinfile:
path: "{{ rhel9_cis_sshd_config_file }}" path: "{{ rhel9cis_sshd_config_file }}"
regexp: '^ClientAliveCountMax' regexp: '^ClientAliveCountMax'
line: "ClientAliveCountMax {{ rhel9cis_sshd['clientalivecountmax'] }}" line: "ClientAliveCountMax {{ rhel9cis_sshd['clientalivecountmax'] }}"
validate: sshd -t -f %s validate: sshd -t -f %s
notify: Restart sshd
when: when:
- rhel9cis_rule_5_2_20 - rhel9cis_rule_5_2_20
tags: tags:

View file

@ -150,7 +150,7 @@
- name: "6.1.10 | AUDIT | Ensure no unowned files or directories exist" - name: "6.1.10 | AUDIT | Ensure no unowned files or directories exist"
block: block:
- name: "6.1.10 | AUDIT | Ensure no unowned files or directories exist | Finding all unowned files or directories" - 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 changed_when: false
failed_when: false failed_when: false
check_mode: false check_mode: false
@ -162,28 +162,21 @@
- item['device'].startswith('/dev') - item['device'].startswith('/dev')
- not 'bind' in item['options'] - 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: ansible.builtin.set_fact:
rhel_09_6_1_10_unowned_files_found: true discovered_unowned_files_flatten: "{{ rhel_09_6_1_10_audit.results | map(attribute='stdout_lines') | flatten }}"
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
- name: "6.1.10 | AUDIT | Ensure no unowned files or directories exist | Displaying any unowned files or directories" - name: "6.1.10 | AUDIT | Ensure no unowned files or directories exist | Displaying any unowned files or directories"
ansible.builtin.debug: 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] msg: "Warning!! Missing owner on items in {{ discovered_unowned_files_flatten }}"
when: rhel_09_6_1_10_unowned_files_found when: discovered_unowned_files_flatten | length > 0
- name: "6.1.10 | AUDIT | Ensure no unowned files or directories exist | warning" - name: "6.1.10 | AUDIT | Ensure no unowned files or directories exist | warning"
ansible.builtin.import_tasks: ansible.builtin.import_tasks:
file: warning_facts.yml file: warning_facts.yml
vars: vars:
warn_control_id: '6.1.10' warn_control_id: '6.1.10'
when: rhel_09_6_1_10_unowned_files_found when: discovered_unowned_files_flatten | length > 0
vars:
rhel_09_6_1_10_unowned_files_found: false
when: when:
- rhel9cis_rule_6_1_10 - rhel9cis_rule_6_1_10
tags: tags:
@ -209,28 +202,21 @@
- item['device'].startswith('/dev') - item['device'].startswith('/dev')
- not 'bind' in item['options'] - 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: ansible.builtin.set_fact:
rhel_09_6_1_11_ungrouped_files_found: true discovered_ungrouped_files_flatten: "{{ rhel_09_6_1_11_audit.results | map(attribute='stdout_lines') | flatten }}"
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
- name: "6.1.11 | AUDIT | Ensure no ungrouped files or directories exist | Displaying all ungrouped files or directories" - name: "6.1.11 | AUDIT | Ensure no ungrouped files or directories exist | Displaying all ungrouped files or directories"
ansible.builtin.debug: 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] msg: "Warning!! Missing group on items in {{ discovered_ungrouped_files_flatten }}"
when: rhel_09_6_1_11_ungrouped_files_found when: discovered_ungrouped_files_flatten | length > 0
- name: "6.1.11 | AUDIT | Ensure no ungrouped files or directories exist | warning" - name: "6.1.11 | AUDIT | Ensure no ungrouped files or directories exist | warning"
ansible.builtin.import_tasks: ansible.builtin.import_tasks:
file: warning_facts.yml file: warning_facts.yml
vars: vars:
warn_control_id: '6.1.11' warn_control_id: '6.1.11'
when: rhel_09_6_1_11_ungrouped_files_found when: discovered_ungrouped_files_flatten | length > 0
vars:
rhel_09_6_1_11_ungrouped_files_found: false
when: when:
- rhel9cis_rule_6_1_11 - rhel9cis_rule_6_1_11
tags: tags:
@ -258,34 +244,26 @@
- name: "6.1.13 | AUDIT | Audit SUID executables" - name: "6.1.13 | AUDIT | Audit SUID executables"
block: block:
- name: "6.1.13 | AUDIT | Audit SUID executables | Find all SUID executables" - 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 failed_when: false
changed_when: false changed_when: false
register: rhel_09_6_1_13_suid_perms 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" - name: "6.1.13 | AUDIT | Audit SUID executables | Alert SUID executables exist"
ansible.builtin.debug: 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] msg: "Warning!! SUID set on items in {{ rhel_09_6_1_13_suid_perms.stdout_lines }}"
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
- name: "6.1.13 | AUDIT | Audit SUID executables | Alert SUID executables exist | warning" - name: "6.1.13 | AUDIT | Audit SUID executables | Alert SUID executables exist | warning"
ansible.builtin.import_tasks: ansible.builtin.import_tasks:
file: warning_facts.yml file: warning_facts.yml
vars: vars:
warn_control_id: '6.1.13' 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: vars:
rhel9_6_1_13_suid_found: false rhel9_6_1_13_suid_found: false
when: when:
@ -301,34 +279,26 @@
- name: "6.1.14 | AUDIT | Audit SGID executables" - name: "6.1.14 | AUDIT | Audit SGID executables"
block: block:
- name: "6.1.14 | AUDIT | Audit SGID executables | Find all SGID executables" - 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 failed_when: false
changed_when: false changed_when: false
register: rhel_09_6_1_14_sgid_perms 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" - name: "6.1.14 | AUDIT | Audit SGID executables | Alert SGID executables exist"
ansible.builtin.debug: 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] msg: "Warning!! SGID set on items in {{ rhel_09_6_1_14_sgid_perms.stdout_lines }}"
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
- name: "6.1.14 | AUDIT | Audit SGID executables| warning" - name: "6.1.14 | AUDIT | Audit SGID executables| warning"
ansible.builtin.import_tasks: ansible.builtin.import_tasks:
file: warning_facts.yml file: warning_facts.yml
vars: vars:
warn_control_id: '6.1.14' 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: vars:
rhel9_6_1_14_sgid_found: false rhel9_6_1_14_sgid_found: false
when: when:

View file

@ -462,7 +462,7 @@ rhel9cis_syslog: {{ rhel9cis_syslog }}
# Section 5 # Section 5
# This will allow use of drop in files when CIS adopts them. # 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 ## 5.2.4 Note the following to understand precedence and layout
rhel9cis_sshd_limited: false rhel9cis_sshd_limited: false

View file

@ -26,15 +26,16 @@ post_audit_outfile: "{{ audit_log_dir }}/{{ ansible_facts.hostname }}-{{ benchma
### Audit binary settings ### ### Audit binary settings ###
audit_bin_version: audit_bin_version:
release: v0.4.4 release: v0.4.8
AMD64_checksum: 'sha256:1c4f54b22fde9d4d5687939abc2606b0660a5d14a98afcd09b04b793d69acdc5' AMD64_checksum: 'sha256:85d00b7bba5f175bec95de7dfe1f71f8f25204914aad4c6f03c8457868eb6e2f'
ARM64_checksum: 'sha256:bca8c898bfd35b94c51455ece6193c95e2cd7b2b183ac2047b2d76291e73e47d'
audit_bin_path: /usr/local/bin/ audit_bin_path: /usr/local/bin/
audit_bin: "{{ audit_bin_path }}goss" audit_bin: "{{ audit_bin_path }}goss"
audit_format: json audit_format: json
audit_vars_path: "{{ audit_conf_dir }}/vars/{{ ansible_facts.hostname }}.yml" audit_vars_path: "{{ audit_conf_dir }}/vars/{{ ansible_facts.hostname }}.yml"
audit_results: | audit_results: |
The audit results are: {{ pre_audit_summary }} 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_summary }}{% endif %} {% if not audit_only %}The post remediation audit results are: {{ post_audit_results }}{% endif %}
Full breakdown can be found in {{ audit_log_dir }} Full breakdown can be found in {{ audit_log_dir }}