Compare commits

..

16 commits
devel ... 2.0.2

Author SHA1 Message Date
jjoympg
25b4bb780c
Merge pull request #355 from ansible-lockdown/devel
Merge latest into devel
2025-07-02 10:50:59 -04:00
uk-bolly
3d502efaef
Merge pull request #307 from ansible-lockdown/devel
Updates to benchmark v2.0.0
2025-03-18 09:22:32 +00:00
uk-bolly
f4a0bca52a
Merge pull request #290 from ansible-lockdown/devel
CIS V2 release to main
2025-02-14 10:44:12 +00:00
uk-bolly
ef2b7dca5d
Merge pull request #267 from ansible-lockdown/devel
CIS v1.0.0 final release to main
2024-12-19 15:07:56 +00:00
uk-bolly
81a929961a
Merge pull request #259 from ansible-lockdown/devel
CIS v1.0.0 updates Nov 2024
2024-11-19 18:11:52 +00:00
uk-bolly
16cb6a4617
Merge pull request #235 from ansible-lockdown/devel
rhel9-cis main release v1.0.0
2024-09-10 15:45:16 +01:00
uk-bolly
151896e113
Merge pull request #213 from ansible-lockdown/devel
Update to galaxy meta
2024-06-11 13:02:59 +01:00
uk-bolly
306eb59b88
Merge pull request #210 from ansible-lockdown/devel
Release to main
2024-06-10 12:49:41 +01:00
uk-bolly
7661bc0963
Merge pull request #205 from ansible-lockdown/devel
Release to main
2024-05-01 13:53:19 +01:00
uk-bolly
00e6f196b5
Merge pull request #89 from ansible-lockdown/devel
workflow check run
2023-08-10 14:25:08 +01:00
uk-bolly
4567a0baad
Merge pull request #86 from ansible-lockdown/devel
Readme layout update
2023-08-09 16:08:19 +01:00
uk-bolly
10dc297e9a
Merge pull request #84 from ansible-lockdown/devel
devel to main release
2023-08-09 14:34:53 +01:00
uk-bolly
21a886a81c
Merge pull request #64 from ansible-lockdown/devel
Devel to main - bug fixes
2023-06-06 14:40:39 +01:00
uk-bolly
759bbbad7e
Merge pull request #49 from ansible-lockdown/devel
Galaxy Compliance
2023-03-21 21:11:51 +00:00
uk-bolly
8bbccd6b62
Merge pull request #47 from ansible-lockdown/devel
Merge to Main galaxy workflow
2023-03-21 16:35:53 +00:00
uk-bolly
beaeb3a181
Merge pull request #45 from ansible-lockdown/devel
Initial 1.0 release CIS 1.0
2023-03-21 15:39:53 +00:00
38 changed files with 799 additions and 1129 deletions

View file

@ -1,17 +0,0 @@
---
name: Add Repo Issue to ALD GH project
on:
issues:
types:
- opened
- reopened
- transferred
jobs:
add-to-project:
runs-on: ubuntu-latest
steps:
- uses: actions/add-to-project@main
with:
project-url: https://github.com/orgs/ansible-lockdown/projects/1
github-token: ${{ secrets.ALD_GH_PROJECT }}

View file

@ -1,54 +0,0 @@
---
# GitHub schedules all cron jobs in UTC.
# ──────────────────────────────────────────────────────────────────────────────
# Schedule:
# - '0 13 * * *' runs at 13:00 UTC every day.
# - This corresponds to:
# • 9:00 AM Eastern **during Daylight Saving Time** (mid-Mar → early-Nov)
# • 8:00 AM Eastern **during Standard Time** (early-Nov → mid-Mar)
#
# Job routing:
# - call-benchmark-tracker:
# • Runs on manual dispatch, and on pushes to the 'latest' branch.
# - call-monitor-promotions:
# • Runs on schedule or manual dispatch **only in repos named ansible-lockdown/Private-***.
# • Skips automatically in public repos (e.g., Windows-2022-CIS) to avoid false failures.
#
# Defense-in-depth:
# - The called promotion workflow may still keep its own guard to ensure only Private-* repos execute it.
name: Central Benchmark Orchestrator
on:
push:
branches:
- latest
schedule:
- cron: '0 13 * * *' # 13:00 UTC → 9 AM ET (DST) / 8 AM ET (Standard Time)
workflow_dispatch:
jobs:
call-benchmark-tracker:
# Run on manual dispatch OR when 'latest' branch receives a push
if: github.event_name == 'workflow_dispatch' || (github.event_name == 'push' && github.ref_name == 'latest')
name: Start Benchmark Tracker
uses: ansible-lockdown/github_linux_IaC/.github/workflows/benchmark_track.yml@self_hosted
with:
repo_name: ${{ github.repository }}
secrets:
TEAMS_WEBHOOK_URL: ${{ secrets.TEAMS_WEBHOOK_URL }}
BADGE_PUSH_TOKEN: ${{ secrets.BADGE_PUSH_TOKEN }}
DISCORD_WEBHOOK_URL: ${{ secrets.DISCORD_WEBHOOK_URL }}
call-monitor-promotions:
# Run on schedule or manual dispatch, but only for Private-* repos
if: (github.event_name == 'schedule' || github.event_name == 'workflow_dispatch') && startsWith(github.repository, 'ansible-lockdown/Private-')
name: Monitor Promotions and Auto-Promote
uses: ansible-lockdown/github_linux_IaC/.github/workflows/benchmark_promote.yml@self_hosted
with:
repo_name: ${{ github.repository }}
secrets:
TEAMS_WEBHOOK_URL: ${{ secrets.TEAMS_WEBHOOK_URL }}
BADGE_PUSH_TOKEN: ${{ secrets.BADGE_PUSH_TOKEN }}
DISCORD_WEBHOOK_URL: ${{ secrets.DISCORD_WEBHOOK_URL }}

View file

@ -17,6 +17,12 @@
# Allow manual running of workflow # Allow manual running of workflow
workflow_dispatch: workflow_dispatch:
# Allow permissions for AWS auth
permissions:
id-token: write
contents: read
pull-requests: read
# A workflow run is made up of one or more jobs # A workflow run is made up of one or more jobs
# that can run sequentially or in parallel # that can run sequentially or in parallel
jobs: jobs:
@ -24,18 +30,11 @@
welcome: welcome:
runs-on: ubuntu-latest runs-on: ubuntu-latest
permissions:
issues: write
pull-requests: write
steps: steps:
- uses: actions/first-interaction@main - uses: actions/first-interaction@main
with: with:
repo_token: ${{ secrets.GITHUB_TOKEN }} repo-token: ${{ secrets.GITHUB_TOKEN }}
issue_message: |- pr-message: |-
Congrats on opening your first issue 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.
pr_message: |-
Congrats on opening your first pull request and thank you for taking the time to help improve Ansible-Lockdown! 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. Please join in the conversation happening on the [Discord Server](https://www.lockdownenterprise.com/discord) as well.
@ -43,13 +42,6 @@
playbook-test: playbook-test:
# The type of runner that the job will run on # The type of runner that the job will run on
runs-on: self-hosted runs-on: self-hosted
# Allow permissions for AWS auth
permissions:
id-token: write
contents: read
pull-requests: read
env: env:
ENABLE_DEBUG: ${{ vars.ENABLE_DEBUG }} ENABLE_DEBUG: ${{ vars.ENABLE_DEBUG }}
# Imported as a variable by terraform # Imported as a variable by terraform
@ -101,11 +93,16 @@
run: | run: |
echo "OSVAR = $OSVAR" echo "OSVAR = $OSVAR"
echo "benchmark_type = $benchmark_type" echo "benchmark_type = $benchmark_type"
echo "PRIVSUBNET_ID = $AWS_PRIVSUBNET_ID"
echo "VPC_ID" = $AWS_VPC_SECGRP_ID"
pwd pwd
ls
env: env:
# Imported from GitHub variables this is used to load the relevant OS.tfvars file # Imported from GitHub variables this is used to load the relevant OS.tfvars file
OSVAR: ${{ vars.OSVAR }} OSVAR: ${{ vars.OSVAR }}
benchmark_type: ${{ vars.BENCHMARK_TYPE }} benchmark_type: ${{ vars.BENCHMARK_TYPE }}
PRIVSUBNET_ID: ${{ secrets.AWS_PRIVSUBNET_ID }}
VPC_ID: ${{ secrets.AWS_VPC_SECGRP_ID }}
- name: Tofu init - name: Tofu init
id: init id: init

View file

@ -1,27 +0,0 @@
---
name: Export Private Repo Badges
# Use different minute offsets with the same hourly pattern:
# Repo Group Suggested Cron Expression Explanation
# Group A 0 */6 * * * Starts at top of hour
# Group B 10 */6 * * * Starts at 10 after
# And So On
on:
push:
branches:
- latest
schedule:
- cron: '0 */6 * * *'
workflow_dispatch:
jobs:
export-badges:
if: github.event_name == 'workflow_dispatch' || (github.event_name == 'schedule' && startsWith(github.repository, 'ansible-lockdown/Private-')) || (github.event_name == 'push' && github.ref_name == 'latest')
uses: ansible-lockdown/github_linux_IaC/.github/workflows/export_badges_private.yml@self_hosted
with:
# Full org/repo path passed for GitHub API calls (e.g., ansible-lockdown/Private-Windows-2016-CIS)
repo_name: ${{ github.repository }}
secrets:
BADGE_PUSH_TOKEN: ${{ secrets.BADGE_PUSH_TOKEN }}

View file

@ -1,19 +0,0 @@
---
name: Export Public Repo Badges
on:
push:
branches:
- main
- devel
workflow_dispatch:
jobs:
export-badges:
if: github.repository_visibility == 'public' && (github.event_name == 'workflow_dispatch' || (github.event_name == 'push' && (github.ref_name == 'devel' || github.ref_name == 'main')))
uses: ansible-lockdown/github_linux_IaC/.github/workflows/export_badges_public.yml@self_hosted
with:
repo_name: ${{ github.repository }}
secrets:
BADGE_PUSH_TOKEN: ${{ secrets.BADGE_PUSH_TOKEN }}

View file

@ -24,6 +24,7 @@
# A workflow run is made up of one or more jobs # A workflow run is made up of one or more jobs
# that can run sequentially or in parallel # that can run sequentially or in parallel
jobs: jobs:
# This workflow contains a single job that tests the playbook # This workflow contains a single job that tests the playbook
playbook-test: playbook-test:
# The type of runner that the job will run on # The type of runner that the job will run on
@ -79,12 +80,16 @@
run: | run: |
echo "OSVAR = $OSVAR" echo "OSVAR = $OSVAR"
echo "benchmark_type = $benchmark_type" echo "benchmark_type = $benchmark_type"
echo "PRIVSUBNET_ID = $AWS_PRIVSUBNET_ID"
echo "VPC_ID" = $AWS_VPC_SECGRP_ID"
pwd pwd
ls ls
env: env:
# Imported from GitHub variables this is used to load the relevant OS.tfvars file # Imported from GitHub variables this is used to load the relevant OS.tfvars file
OSVAR: ${{ vars.OSVAR }} OSVAR: ${{ vars.OSVAR }}
benchmark_type: ${{ vars.BENCHMARK_TYPE }} benchmark_type: ${{ vars.BENCHMARK_TYPE }}
PRIVSUBNET_ID: ${{ secrets.AWS_PRIVSUBNET_ID }}
VPC_ID: ${{ secrets.AWS_VPC_SECGRP_ID }}
- name: Tofu init - name: Tofu init
id: init id: init

19
.github/workflows/update_galaxy.yml vendored Normal file
View file

@ -0,0 +1,19 @@
---
name: update galaxy
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 }}

View file

@ -7,7 +7,7 @@ ci:
repos: repos:
- repo: https://github.com/pre-commit/pre-commit-hooks - repo: https://github.com/pre-commit/pre-commit-hooks
rev: v6.0.0 rev: v5.0.0
hooks: hooks:
# Safety # Safety
- id: detect-aws-credentials - id: detect-aws-credentials
@ -41,12 +41,12 @@ repos:
- id: detect-secrets - id: detect-secrets
- repo: https://github.com/gitleaks/gitleaks - repo: https://github.com/gitleaks/gitleaks
rev: v8.30.0 rev: v8.27.2
hooks: hooks:
- id: gitleaks - id: gitleaks
- repo: https://github.com/ansible-community/ansible-lint - repo: https://github.com/ansible-community/ansible-lint
rev: v25.12.2 rev: v25.6.1
hooks: hooks:
- id: ansible-lint - id: ansible-lint
name: Ansible-lint name: Ansible-lint

View file

@ -1,30 +1,5 @@
# Changes to rhel9CIS # Changes to rhel9CIS
## 2.0.4 - Based on CIS v2.0.0
- addressed issue #393 thank you to @fragglexarmy
- addressed issue #394 thank you to @dbeuker
- addressed issues #390 and #391 thanks to @polski-g
- addressed issue #398 & #399 thanks to trumbaut
- Added max-concurrent options for audit
- work flow updates
- audit logic improvements
- auditd template 2.19 compatible
- pre-commit updates
- #410 thanks to @kpi-nourman
- #413 thanks to @bbaassssiiee
## 2.0.3 - Based on CIS v2.0.0
- addressed issue #387, thank you @fragglexarmy
- addressed issue #382 to improve regex logic on 5.4.2.4
- improvement on crypto policy managed controls with var logic
- addressed issue #384 thank you @polski-g
- update command to shell module on tasks
- addressed issue 371 thanks to @bgro and kodebach
- addressed issue 350 thanks to @chrispipo
- addressed issue 364 thanks to @polski-g
- pre-commit update
## 2.0.2 - Based on CIS v2.0.0 ## 2.0.2 - Based on CIS v2.0.0
- Update to audit_only to allow fetching results - Update to audit_only to allow fetching results

196
README.md
View file

@ -6,96 +6,62 @@
--- ---
## Public Repository 📣
![Org Stars](https://img.shields.io/github/stars/ansible-lockdown?label=Org%20Stars&style=social) ![Org Stars](https://img.shields.io/github/stars/ansible-lockdown?label=Org%20Stars&style=social)
![Stars](https://img.shields.io/github/stars/ansible-lockdown/RHEL9-CIS?label=Repo%20Stars&style=social) ![Stars](https://img.shields.io/github/stars/ansible-lockdown/RHEL9-CIS?label=Repo%20Stars&style=social)
![Forks](https://img.shields.io/github/forks/ansible-lockdown/RHEL9-CIS?style=social) ![Forks](https://img.shields.io/github/forks/ansible-lockdown/RHEL9-CIS?style=social)
![Followers](https://img.shields.io/github/followers/ansible-lockdown?style=social) ![followers](https://img.shields.io/github/followers/ansible-lockdown?style=social)
[![Twitter URL](https://img.shields.io/twitter/url/https/twitter.com/AnsibleLockdown.svg?style=social&label=Follow%20%40AnsibleLockdown)](https://twitter.com/AnsibleLockdown) [![Twitter URL](https://img.shields.io/twitter/url/https/twitter.com/AnsibleLockdown.svg?style=social&label=Follow%20%40AnsibleLockdown)](https://twitter.com/AnsibleLockdown)
![Ansible Galaxy Quality](https://img.shields.io/ansible/quality/61781?label=Quality&&logo=ansible)
![Discord Badge](https://img.shields.io/discord/925818806838919229?logo=discord) ![Discord Badge](https://img.shields.io/discord/925818806838919229?logo=discord)
![License](https://img.shields.io/github/license/ansible-lockdown/RHEL9-CIS?label=License)
## Lint & Pre-Commit Tools 🔧
[![Pre-Commit.ci](https://img.shields.io/endpoint?url=https://ansible-lockdown.github.io/github_linux_IaC/badges/RHEL9-CIS/pre-commit-ci.json)](https://results.pre-commit.ci/latest/github/ansible-lockdown/RHEL9-CIS/devel)
![YamlLint](https://img.shields.io/badge/yamllint-Present-brightgreen?style=flat&logo=yaml&logoColor=white)
![Ansible-Lint](https://img.shields.io/badge/ansible--lint-Present-brightgreen?style=flat&logo=ansible&logoColor=white)
## Community Release Information 📂
![Release Branch](https://img.shields.io/badge/Release%20Branch-Main-brightgreen) ![Release Branch](https://img.shields.io/badge/Release%20Branch-Main-brightgreen)
![Release Tag](https://img.shields.io/github/v/tag/ansible-lockdown/RHEL9-CIS?label=Release%20Tag&&color=success) ![Release Tag](https://img.shields.io/github/v/release/ansible-lockdown/RHEL9-CIS)
![Main Release Date](https://img.shields.io/github/release-date/ansible-lockdown/RHEL9-CIS?label=Release%20Date) ![Release Date](https://img.shields.io/github/release-date/ansible-lockdown/RHEL9-CIS)
![Benchmark Version Main](https://img.shields.io/endpoint?url=https://ansible-lockdown.github.io/github_linux_IaC/badges/RHEL9-CIS/benchmark-version-main.json)
![Benchmark Version Devel](https://img.shields.io/endpoint?url=https://ansible-lockdown.github.io/github_linux_IaC/badges/RHEL9-CIS/benchmark-version-devel.json)
[![Main Pipeline Status](https://github.com/ansible-lockdown/RHEL9-CIS/actions/workflows/main_pipeline_validation.yml/badge.svg?)](https://github.com/ansible-lockdown/RHEL9-CIS/actions/workflows/main_pipeline_validation.yml) [![Main Pipeline Status](https://github.com/ansible-lockdown/RHEL9-CIS/actions/workflows/main_pipeline_validation.yml/badge.svg?)](https://github.com/ansible-lockdown/RHEL9-CIS/actions/workflows/main_pipeline_validation.yml)
[![Devel Pipeline Status](https://github.com/ansible-lockdown/RHEL9-CIS/actions/workflows/devel_pipeline_validation.yml/badge.svg?)](https://github.com/ansible-lockdown/RHEL9-CIS/actions/workflows/devel_pipeline_validation.yml) [![Devel Pipeline Status](https://github.com/ansible-lockdown/RHEL9-CIS/actions/workflows/devel_pipeline_validation.yml/badge.svg?)](https://github.com/ansible-lockdown/RHEL9-CIS/actions/workflows/devel_pipeline_validation.yml)
![Devel Commits](https://img.shields.io/github/commit-activity/m/ansible-lockdown/RHEL9-CIS/devel?color=dark%20green&label=Devel%20Branch%20Commits) ![Devel Commits](https://img.shields.io/github/commit-activity/m/ansible-lockdown/RHEL9-CIS/devel?color=dark%20green&label=Devel%20Branch%20Commits)
![Open Issues](https://img.shields.io/github/issues-raw/ansible-lockdown/RHEL9-CIS?label=Open%20Issues)
![Closed Issues](https://img.shields.io/github/issues-closed-raw/ansible-lockdown/RHEL9-CIS?label=Closed%20Issues&&color=success) ![Issues Open](https://img.shields.io/github/issues-raw/ansible-lockdown/RHEL9-CIS?label=Open%20Issues)
![Issues Closed](https://img.shields.io/github/issues-closed-raw/ansible-lockdown/RHEL9-CIS?label=Closed%20Issues&&color=success)
![Pull Requests](https://img.shields.io/github/issues-pr/ansible-lockdown/RHEL9-CIS?label=Pull%20Requests) ![Pull Requests](https://img.shields.io/github/issues-pr/ansible-lockdown/RHEL9-CIS?label=Pull%20Requests)
[![pre-commit](https://img.shields.io/badge/pre--commit-enabled-brightgreen?logo=pre-commit)](https://github.com/pre-commit/pre-commit)
![License](https://img.shields.io/github/license/ansible-lockdown/RHEL9-CIS?label=License)
--- ---
## Subscriber Release Information 🔐 ### Community
![Private Release Branch](https://img.shields.io/endpoint?url=https://ansible-lockdown.github.io/github_linux_IaC/badges/Private-RHEL9-CIS/release-branch.json) Join us on our [Discord Server](https://www.lockdownenterprise.com/discord) to ask questions, discuss features, or just chat with other Ansible-Lockdown users.
![Private Benchmark Version](https://img.shields.io/endpoint?url=https://ansible-lockdown.github.io/github_linux_IaC/badges/Private-RHEL9-CIS/benchmark-version.json)
[![Private Remediate Pipeline](https://img.shields.io/endpoint?url=https://ansible-lockdown.github.io/github_linux_IaC/badges/Private-RHEL9-CIS/remediate.json)](https://github.com/ansible-lockdown/Private-RHEL9-CIS/actions/workflows/main_pipeline_validation.yml)
[![Private GPO Pipeline](https://img.shields.io/endpoint?url=https://ansible-lockdown.github.io/github_linux_IaC/badges/Private-RHEL9-CIS/gpo.json)](https://github.com/ansible-lockdown/Private-RHEL9-CIS/actions/workflows/main_pipeline_validation_gpo.yml)
![Private Pull Requests](https://img.shields.io/endpoint?url=https://ansible-lockdown.github.io/github_linux_IaC/badges/Private-RHEL9-CIS/prs.json)
![Private Closed Issues](https://img.shields.io/endpoint?url=https://ansible-lockdown.github.io/github_linux_IaC/badges/Private-RHEL9-CIS/issues-closed.json)
--- ---
## Looking for support? 🤝 ## Caution(s)
[Lockdown Enterprise](https://www.lockdownenterprise.com#GH_AL_RHEL9-CIS)
[Ansible support](https://www.mindpointgroup.com/cybersecurity-products/ansible-counselor#GH_AL_RHEL9-CIS)
### Community 💬
On our [Discord Server](https://www.lockdownenterprise.com/discord) to ask questions, discuss features, or just chat with other Ansible-Lockdown users
---
## 🚨 Caution(s) 🚨
This role **will make changes to the system** which may have unintended consequences. This is not an auditing tool but rather a remediation tool to be used after an audit has been conducted. This role **will make changes to the system** which may have unintended consequences. This is not an auditing tool but rather a remediation tool to be used after an audit has been conducted.
- Testing is the most important thing you can do. - Testing is the most important thing you can do.
- Check Mode is not guaranteed! 🚫 The role will complete in check mode without errors, but it is not supported and should be used with caution. - Check Mode is not supported! The role will complete in check mode without errors, but it is not supported and should be used with caution. The RHEL9-CIS-Audit role or a compliance scanner should be used for compliance checking over check mode.
- This role was developed against a clean install of the Operating System. If you are implementing to an existing system please review this role for any site specific changes that are needed. - This role was developed against a clean install of the Operating System. If you are implementing to an existing system please review this role for any site specific changes that are needed.
- To use release version please point to main branch and relevant release for the cis benchmark you wish to work with. - To use release version please point to main branch and relevant release/tag for the cis benchmark you wish to work with.
- If moving across major releases e.g. v2.0.0 - v3.0.0 there are significant changes to the benchmarks and controls it is suggested to start as a new standard not to upgrade.
- Containers references vars/is_container.yml this is an example and to be updated for your requirements
- Did we mention testing?? - Did we mention testing??
--- ---
## Coming From A Previous Release ⏪
CIS release always contains changes, it is highly recommended to review the new references and available variables. This have changed significantly since ansible-lockdown initial release.
This is now compatible with python3 if it is found to be the default interpreter. This does come with pre-requisites which it configures the system accordingly.
Further details can be seen in the [Changelog](./ChangeLog.md)
---
## Matching a security Level for CIS ## Matching a security Level for CIS
It is possible to only run level 1 or level 2 controls for CIS. It is possible to to only run level 1 or level 2 controls for CIS.
This is managed using tags: This is managed using tags:
- level1-server - level1-server
@ -105,34 +71,14 @@ This is managed using tags:
The control found in defaults main also need to reflect this as this control the testing that takes place if you are using the audit component. The control found in defaults main also need to reflect this as this control the testing that takes place if you are using the audit component.
--- ## Coming from a previous release
## Requirements ✅
**General:** CIS release always contains changes, it is highly recommended to review the new references and available variables. This have changed significantly since ansible-lockdown initial release.
This is now compatible with python3 if it is found to be the default interpreter. This does come with pre-requisites which it configures the system accordingly.
- Basic knowledge of Ansible, below are some links to the Ansible documentation to help get started if you are unfamiliar with Ansible Further details can be seen in the [Changelog](./Changelog.md)
- [Main Ansible documentation page](https://docs.ansible.com) ## Auditing (new)
- [Ansible Getting Started](https://docs.ansible.com/ansible/latest/user_guide/intro_getting_started.html)
- [Tower User Guide](https://docs.ansible.com/ansible-tower/latest/html/userguide/index.html)
- [Ansible Community Info](https://docs.ansible.com/ansible/latest/community/index.html)
- Functioning Ansible and/or Tower Installed, configured, and running. This includes all of the base Ansible/Tower configurations, needed packages installed, and infrastructure setup.
- Please read through the tasks in this role to gain an understanding of what each control is doing. Some of the tasks are disruptive and can have unintended consequences in a live production system. Also familiarize yourself with the variables in the defaults/main.yml file.
**Technical Dependencies:**
RHEL Family OS 9
- Access to download or add the goss binary and content to the system if using auditing
(other options are available on how to get the content to the system.)
- Python3.8
- Ansible 2.12+
- python-def
- libselinux-python
---
## Auditing 🔍
This can be turned on or off within the defaults/main.yml file with the variable run_audit. The value is false by default, please refer to the wiki for more details. The defaults file also populates the goss checks to check only the controls that have been enabled in the ansible role. This can be turned on or off within the defaults/main.yml file with the variable run_audit. The value is false by default, please refer to the wiki for more details. The defaults file also populates the goss checks to check only the controls that have been enabled in the ansible role.
@ -163,7 +109,7 @@ PLAY RECAP *********************************************************************
default : ok=270 changed=23 unreachable=0 failed=0 skipped=140 rescued=0 ignored=0 default : ok=270 changed=23 unreachable=0 failed=0 skipped=140 rescued=0 ignored=0
``` ```
## Documentation 📖 ## Documentation
- [Read The Docs](https://ansible-lockdown.readthedocs.io/en/latest/) - [Read The Docs](https://ansible-lockdown.readthedocs.io/en/latest/)
- [Getting Started](https://www.lockdownenterprise.com/docs/getting-started-with-lockdown#GH_AL_RH9_cis) - [Getting Started](https://www.lockdownenterprise.com/docs/getting-started-with-lockdown#GH_AL_RH9_cis)
@ -171,32 +117,38 @@ default : ok=270 changed=23 unreachable=0 failed=0 s
- [Per-Host Configuration](https://www.lockdownenterprise.com/docs/per-host-lockdown-enterprise-configuration#GH_AL_RH9_cis) - [Per-Host Configuration](https://www.lockdownenterprise.com/docs/per-host-lockdown-enterprise-configuration#GH_AL_RH9_cis)
- [Getting the Most Out of the Role](https://www.lockdownenterprise.com/docs/get-the-most-out-of-lockdown-enterprise#GH_AL_RH9_cis) - [Getting the Most Out of the Role](https://www.lockdownenterprise.com/docs/get-the-most-out-of-lockdown-enterprise#GH_AL_RH9_cis)
## Requirements
**General:**
- Basic knowledge of Ansible, below are some links to the Ansible documentation to help get started if you are unfamiliar with Ansible
- [Main Ansible documentation page](https://docs.ansible.com)
- [Ansible Getting Started](https://docs.ansible.com/ansible/latest/user_guide/intro_getting_started.html)
- [Tower User Guide](https://docs.ansible.com/ansible-tower/latest/html/userguide/index.html)
- [Ansible Community Info](https://docs.ansible.com/ansible/latest/community/index.html)
- Functioning Ansible and/or Tower Installed, configured, and running. This includes all of the base Ansible/Tower configurations, needed packages installed, and infrastructure setup.
- Please read through the tasks in this role to gain an understanding of what each control is doing. Some of the tasks are disruptive and can have unintended consequences in a live production system. Also familiarize yourself with the variables in the defaults/main.yml file.
**Technical Dependencies:**
RHEL/AlmaLinux/Rocky/Oracle 9 - Other versions are not supported.
- Access to download or add the goss binary and content to the system if using auditing
(other options are available on how to get the content to the system.)
- Python3.8
- Ansible 2.12+
- python-def
- libselinux-python
## Role Variables ## Role Variables
This role is designed that the end user should not have to edit the tasks themselves. All customizing should be done via the defaults/main.yml file or with extra vars within the project, job, workflow, etc. This role is designed that the end user should not have to edit the tasks themselves. All customizing should be done via the defaults/main.yml file or with extra vars within the project, job, workflow, etc.
## Tags 🏷️ ## Tags
There are many tags available for added control precision. Each control has its own set of tags noting what level, what OS element it relates to, whether it's a patch or audit, and the rule number. Additionally, NIST references follow a specific conversion format for consistency and clarity. There are many tags available for added control precision. Each control has it's own set of tags noting what level, if it's scored/notscored, what OS element it relates to, if it's a patch or audit, and the rule number.
### Conversion Format for NIST References:
1. Standard Prefix:
- All references are prefixed with "NIST".
2. Standard Types:
- "800-53" references are formatted as NIST800-53.
- "800-53r5" references are formatted as NIST800-53R5 (with 'R' capitalized).
- "800-171" references are formatted as NIST800-171.
3. Details:
- Section and subsection numbers use periods (.) for numeric separators.
- Parenthetical elements are separated by underscores (_), e.g., IA-5(1)(d) becomes IA-5_1_d.
- Subsection letters (e.g., "b") are appended with an underscore.
Below is an example of the tag section from a control within this role. Using this example if you set your run to skip all controls with the tag services, this task will be skipped. The opposite can also happen where you run only controls tagged with services. Below is an example of the tag section from a control within this role. Using this example if you set your run to skip all controls with the tag services, this task will be skipped. The opposite can also happen where you run only controls tagged with services.
```sh ```sh
@ -210,34 +162,33 @@ Below is an example of the tag section from a control within this role. Using th
- rule_2.2.4 - rule_2.2.4
``` ```
## Community Contribution
## Community Contribution 🧑‍🤝‍🧑
We encourage you (the community) to contribute to this role. Please read the rules below. We encourage you (the community) to contribute to this role. Please read the rules below.
- Your work is done in your own individual branch. Make sure to Signed-off-by and GPG sign all commits you intend to merge. - Your work is done in your own individual branch. Make sure to Signed-off and GPG sign all commits you intend to merge.
- All community Pull Requests are pulled into the devel branch - All community Pull Requests are pulled into the devel branch
- Pull Requests into devel will confirm your commits have a GPG signature, Signed-off-by, and a functional test before being approved - Pull Requests into devel will confirm your commits have a GPG signature, Signed-off, and a functional test before being approved
- Once your changes are merged and a more detailed review is complete, an authorized member will merge your changes into the main branch for a new release - Once your changes are merged and a more detailed review is complete, an authorized member will merge your changes into the main branch for a new release
## Pipeline Testing 🔄
uses:
- ansible-core 2.16
- ansible collections - pulls in the latest version based on requirements file
- runs the audit using the devel branch
- This is an automated test that occurs on pull requests into devel
- self-hosted runners using OpenTofu
## Known Issues ## Known Issues
Almalinux BaseOS, EPEL and many cloud providers repositories, do not allow gpgcheck(rule_1.2.1.2) or repo_gpgcheck (rule_1.2.1.3) this will cause issues during the playbook unless or a workaround is found. Almalinux BaseOS, EPEL and many cloud providers repositories, do not allow gpgcheck(rule_1.2.1.2) or repo_gpgcheck (rule_1.2.1.3) this will cause issues during the playbook unless or a workaround is found.
## Pipeline Testing
## Local Testing 💻 uses:
### example - ansible-core 2.12
- ansible collections - pulls in the latest version based on requirements file
- runs the audit using the devel branch
- This is an automated test that occurs on pull requests into devel
## Local Testing
Molecule can be used to work on this role and test in distinct _scenarios_.
### examples
```bash ```bash
molecule test -s default molecule test -s default
@ -247,15 +198,24 @@ molecule verify -s localhost
local testing uses: local testing uses:
- ansible-core - ansible 2.13.3
- molecule 4.0.1 - molecule 4.0.1
- molecule-docker 2.0.0 - molecule-docker 2.0.0
- molecule-podman 2.0.2 - molecule-podman 2.0.2
- molecule-vagrant 1.0.0 - molecule-vagrant 1.0.0
- molecule-azure 0.5.0 - molecule-azure 0.5.0
## Added Extras
## Credits and Thanks 🙏 - [pre-commit](https://pre-commit.com) can be tested and can be run from within the directory
```sh
pre-commit run
```
## Credits and Thanks
Based on an original concept by Sam Doran
Massive thanks to the fantastic community and all its members. Massive thanks to the fantastic community and all its members.

File diff suppressed because it is too large Load diff

View file

@ -263,7 +263,7 @@
listen: Restart auditd listen: Restart auditd
- name: Start auditd process - name: Start auditd process
ansible.builtin.systemd: ansible.builtin.systemd_service:
name: auditd name: auditd
state: started state: started
listen: Restart auditd listen: Restart auditd

View file

@ -25,7 +25,7 @@
dest: /etc/audit/rules.d/99_auditd.rules dest: /etc/audit/rules.d/99_auditd.rules
owner: root owner: root
group: root group: root
mode: 'u-x,g-wx,o-rwx' mode: 'u-x,go-wx'
diff: "{{ discovered_auditd_rules_file.stat.exists }}" # Only run diff if not a new file diff: "{{ discovered_auditd_rules_file.stat.exists }}" # Only run diff if not a new file
register: discovered_auditd_rules_template_updated register: discovered_auditd_rules_template_updated
notify: notify:

View file

@ -93,14 +93,11 @@
block: block:
- name: "Check password set for {{ ansible_env.SUDO_USER }} | Assert local password set" # noqa name[template] - name: "Check password set for {{ ansible_env.SUDO_USER }} | Assert local password set" # noqa name[template]
ansible.builtin.assert: ansible.builtin.assert:
that: | that:
( - prelim_ansible_user_password_set.stdout | length != 0
((prelim_ansible_user_password_set.stdout | length != 0) and (prelim_ansible_user_password_set.stdout != "!!" )) - prelim_ansible_user_password_set.stdout != "!!"
or fail_msg: "You have {{ sudo_password_rule }} enabled but the user = {{ ansible_env.SUDO_USER }} has no password set - It can break access"
(ansible_env.SUDO_USER in rhel9cis_sudoers_exclude_nopasswd_list) success_msg: "You have a password set for the {{ ansible_env.SUDO_USER }} user"
)
fail_msg: "You have {{ sudo_password_rule }} enabled but the user = {{ ansible_env.SUDO_USER }} has no password set or or the user is not included in the exception list for rule 5.2.4 - It can break access"
success_msg: "You have a password set for the {{ ansible_env.SUDO_USER }} user or the user is included in the exception list for rule 5.2.4"
- name: "Check account is not locked for {{ ansible_env.SUDO_USER }} | Assert local account not locked" # noqa name[template] - name: "Check account is not locked for {{ ansible_env.SUDO_USER }} | Assert local account not locked" # noqa name[template]
ansible.builtin.assert: ansible.builtin.assert:
@ -134,7 +131,7 @@
- rule_5.4.2.4 - rule_5.4.2.4
block: block:
- name: "Ensure root password is set" - name: "Ensure root password is set"
ansible.builtin.shell: LC_ALL=C passwd -S root | grep -E "(Alternate authentication|Password set|Password locked)" ansible.builtin.shell: passwd -S root | grep -E "(Password set, SHA512 crypt|Password locked)"
changed_when: false changed_when: false
failed_when: prelim_root_passwd_set.rc not in [ 0, 1 ] failed_when: prelim_root_passwd_set.rc not in [ 0, 1 ]
register: prelim_root_passwd_set register: prelim_root_passwd_set

View file

@ -1,13 +1,22 @@
--- ---
- name: Post Audit | Run post_remediation {{ benchmark }} audit # noqa name[template] - name: Post Audit | Run post_remediation {{ benchmark }} audit # noqa name[template]
ansible.builtin.shell: "umask 0022 && {{ audit_conf_dir }}/run_audit.sh -v {{ audit_vars_path }} -f {{ audit_format }} -m {{ audit_max_concurrent }} -o {{ post_audit_outfile }} -g \"{{ group_names }}\"" # noqa yaml[line-length] ansible.builtin.command: "{{ audit_conf_dir }}/run_audit.sh -v {{ audit_vars_path }} -f {{ audit_format }} -o {{ post_audit_outfile }} -g \"{{ group_names }}\""
changed_when: true changed_when: true
environment: environment:
AUDIT_BIN: "{{ audit_bin }}" AUDIT_BIN: "{{ audit_bin }}"
AUDIT_CONTENT_LOCATION: "{{ audit_conf_dest | default('/opt') }}" AUDIT_CONTENT_LOCATION: "{{ audit_conf_dest | default('/opt') }}"
AUDIT_FILE: goss.yml AUDIT_FILE: goss.yml
- name: Post Audit | ensure audit files readable by users
ansible.builtin.file:
path: "{{ item }}"
mode: '0644'
state: file
loop:
- "{{ post_audit_outfile }}"
- "{{ pre_audit_outfile }}"
- name: Post Audit | Capture audit data if json format - name: Post Audit | Capture audit data if json format
when: audit_format == "json" when: audit_format == "json"
block: block:

View file

@ -1,5 +1,4 @@
--- ---
- name: Pre Audit Setup | Setup the LE audit - name: Pre Audit Setup | Setup the LE audit
when: setup_audit when: setup_audit
tags: setup_audit tags: setup_audit
@ -58,7 +57,6 @@
- name: Pre Audit Setup | If audit ensure goss is available - name: Pre Audit Setup | If audit ensure goss is available
when: not prelim_goss_available.stat.exists when: not prelim_goss_available.stat.exists
ansible.builtin.assert: ansible.builtin.assert:
that: prelim_goss_available['stat']['exists'] == true
msg: "Audit has been selected: unable to find goss binary at {{ audit_bin }}" msg: "Audit has been selected: unable to find goss binary at {{ audit_bin }}"
- name: Pre Audit Setup | Copy ansible default vars values to test audit - name: Pre Audit Setup | Copy ansible default vars values to test audit
@ -72,7 +70,7 @@
mode: 'go-rwx' mode: 'go-rwx'
- name: Pre Audit | Run pre_remediation audit {{ benchmark }} # noqa name[template] - name: Pre Audit | Run pre_remediation audit {{ benchmark }} # noqa name[template]
ansible.builtin.shell: "umask 0022 && {{ audit_conf_dir }}/run_audit.sh -v {{ audit_vars_path }} -f {{ audit_format }} -m {{ audit_max_concurrent }} -o {{ pre_audit_outfile }} -g \"{{ group_names }}\"" # noqa yaml[line-length] ansible.builtin.command: "{{ audit_conf_dir }}/run_audit.sh -v {{ audit_vars_path }} -f {{ audit_format }} -o {{ pre_audit_outfile }} -g \"{{ group_names }}\"" # noqa yaml[line-length]
changed_when: true changed_when: true
environment: environment:
AUDIT_BIN: "{{ audit_bin }}" AUDIT_BIN: "{{ audit_bin }}"
@ -85,7 +83,6 @@
- name: Pre Audit | Capture audit data if json format - name: Pre Audit | Capture audit data if json format
ansible.builtin.shell: grep -E '\"summary-line.*Count:.*Failed' "{{ pre_audit_outfile }}" | cut -d'"' -f4 ansible.builtin.shell: grep -E '\"summary-line.*Count:.*Failed' "{{ pre_audit_outfile }}" | cut -d'"' -f4
changed_when: false changed_when: false
failed_when: pre_audit_summary.stderr | length > 0
register: pre_audit_summary register: pre_audit_summary
- name: Pre Audit | Set Fact for audit summary - name: Pre Audit | Set Fact for audit summary
@ -98,7 +95,6 @@
- name: Pre Audit | Capture audit data if documentation format - name: Pre Audit | Capture audit data if documentation format
ansible.builtin.shell: tail -2 "{{ pre_audit_outfile }}" | tac | tr '\n' ' ' ansible.builtin.shell: tail -2 "{{ pre_audit_outfile }}" | tac | tr '\n' ' '
changed_when: false changed_when: false
failed_when: pre_audit_summary.stderr | length > 0
register: pre_audit_summary register: pre_audit_summary
- name: Pre Audit | Set Fact for audit summary - name: Pre Audit | Set Fact for audit summary

View file

@ -114,7 +114,6 @@
ansible.builtin.shell: rpm -qi redhat-release | grep Signature # noqa command-instead-of-module ansible.builtin.shell: rpm -qi redhat-release | grep Signature # noqa command-instead-of-module
changed_when: false changed_when: false
failed_when: false failed_when: false
check_mode: false
register: prelim_os_gpg_package_valid register: prelim_os_gpg_package_valid
- name: "PRELIM | PATCH | Force keys to be imported" # noqa command-instead-of-module - name: "PRELIM | PATCH | Force keys to be imported" # noqa command-instead-of-module
@ -137,7 +136,8 @@
register: prelim_systemd_coredump register: prelim_systemd_coredump
- name: "PRELIM | PATCH | Setup crypto-policy" - name: "PRELIM | PATCH | Setup crypto-policy"
when: rhel9cis_crypto_policy_ansiblemanaged when:
- rhel9cis_rule_1_6_1
tags: tags:
- level1-server - level1-server
- level1-workstation - level1-workstation
@ -167,7 +167,6 @@
current_crypto_module: "{{ prelim_system_wide_crypto_policy.stdout.split(':')[1] }}" current_crypto_module: "{{ prelim_system_wide_crypto_policy.stdout.split(':')[1] }}"
- name: "PRELIM | AUDIT | Set facts based on boot type" - name: "PRELIM | AUDIT | Set facts based on boot type"
tags: always
block: block:
- name: "PRELIM | AUDIT | Check whether machine is UEFI-based" - name: "PRELIM | AUDIT | Check whether machine is UEFI-based"
ansible.builtin.stat: ansible.builtin.stat:
@ -186,14 +185,17 @@
grub2_path: /etc/grub2-efi.cfg grub2_path: /etc/grub2-efi.cfg
- name: "PRELIM | AUDIT | Discover Gnome Desktop Environment" - name: "PRELIM | AUDIT | Discover Gnome Desktop Environment"
tags: always tags:
- always
ansible.builtin.stat: ansible.builtin.stat:
path: /usr/share/gnome/gnome-version.xml path: /usr/share/gnome/gnome-version.xml
register: prelim_gnome_present register: prelim_gnome_present
- name: "PRELIM | PATCH | Install dconf if gui installed" - name: "PRELIM | PATCH | Install dconf if gui installed"
when: rhel9cis_gui when:
tags: always - rhel9cis_gui
tags:
- always
ansible.builtin.package: ansible.builtin.package:
name: dconf name: dconf
state: present state: present
@ -202,13 +204,13 @@
when: when:
- rhel9cis_rule_3_1_2 - rhel9cis_rule_3_1_2
- not system_is_container - not system_is_container
tags: always tags:
- always
block: block:
- name: "PRELIM | AUDIT | Discover is wireless adapter on system" - name: "PRELIM | AUDIT | Discover is wireless adapter on system"
ansible.builtin.command: find /sys/class/net/*/ -type d -name wireless ansible.builtin.command: find /sys/class/net/*/ -type d -name wireless
register: discover_wireless_adapters register: discover_wireless_adapters
changed_when: false changed_when: false
check_mode: false
failed_when: discover_wireless_adapters.rc not in [ 0, 1 ] failed_when: discover_wireless_adapters.rc not in [ 0, 1 ]
- name: "PRELIM | PATCH | Install Network-Manager | if wireless adapter present" - name: "PRELIM | PATCH | Install Network-Manager | if wireless adapter present"
@ -249,7 +251,9 @@
state: touch state: touch
- name: "PRELIM | PATCH | sshd_config.d/50-redhat.conf exists" - name: "PRELIM | PATCH | sshd_config.d/50-redhat.conf exists"
when: rhel9cis_rule_5_1_10 or rhel9cis_rule_5_1_11 when:
- rhel9cis_rule_5_1_10 or
rhel9cis_rule_5_1_11
ansible.builtin.stat: ansible.builtin.stat:
path: /etc/ssh/sshd_config.d/50-redhat.conf path: /etc/ssh/sshd_config.d/50-redhat.conf
register: prelim_sshd_50_redhat_file register: prelim_sshd_50_redhat_file
@ -357,6 +361,7 @@
prelim_max_int_uid: "{{ prelim_uid_max_id.stdout | default(max_int_uid) }}" prelim_max_int_uid: "{{ prelim_uid_max_id.stdout | default(max_int_uid) }}"
- name: "PRELIM | AUDIT | Gather the package facts after prelim" - name: "PRELIM | AUDIT | Gather the package facts after prelim"
tags: always tags:
- always
ansible.builtin.package_facts: ansible.builtin.package_facts:
manager: auto manager: auto

View file

@ -1,6 +1,6 @@
--- ---
- name: "1.1.2.6.1 | PATCH | Ensure /var/log is a separate partition" - name: "1/.1 | PATCH | Ensure /var/log is a separate partition"
when: when:
- rhel9cis_rule_1_1_2_6_1 - rhel9cis_rule_1_1_2_6_1
- required_mount not in prelim_mount_names - required_mount not in prelim_mount_names

View file

@ -1,6 +1,6 @@
--- ---
- name: "1.1.2.7.1 | PATCH | Ensure /var/log/audit is a separate partition" - name: "1/.1 | PATCH | Ensure /var/log/audit is a separate partition"
when: when:
- rhel9cis_rule_1_1_2_7_1 - rhel9cis_rule_1_1_2_7_1
- required_mount not in prelim_mount_names - required_mount not in prelim_mount_names

View file

@ -52,7 +52,6 @@
- name: "1.4.2 | AUDIT | Ensure permissions on bootloader config are configured | efi based system | capture current state" - name: "1.4.2 | AUDIT | Ensure permissions on bootloader config are configured | efi based system | capture current state"
ansible.builtin.shell: grep "^[^#;]" /etc/fstab | grep '/boot/efi' | awk -F" " '{print $4}' ansible.builtin.shell: grep "^[^#;]" /etc/fstab | grep '/boot/efi' | awk -F" " '{print $4}'
changed_when: false changed_when: false
check_mode: false
register: discovered_efi_fstab register: discovered_efi_fstab
- name: "1.4.2 | PATCH | Ensure permissions on bootloader config are configured | efi based system | Build Options" - name: "1.4.2 | PATCH | Ensure permissions on bootloader config are configured | efi based system | Build Options"

View file

@ -1,9 +1,7 @@
--- ---
- name: "1.6.1 | AUDIT | Ensure system-wide crypto policy is not legacy" - name: "1.6.1 | AUDIT | Ensure system-wide crypto policy is not legacy"
when: when: rhel9cis_rule_1_6_1
- rhel9cis_rule_1_6_1
- rhel9cis_crypto_policy_ansiblemanaged
tags: tags:
- level1-server - level1-server
- level1-workstation - level1-workstation
@ -23,14 +21,12 @@
tags: tags:
- level1-server - level1-server
- level1-workstation - level1-workstation
- sshd
- automated - automated
- patch - patch
- rule_1.6.2 - rule_1.6.2
- NIST800-53R5_SC-8 - NIST800-53R5_SC-8
- NIST800-53R5_IA-5 - NIST800-53R5_IA-5
- NIST800-53R5_AC-17 - NIST800-53R5_AC-17- NIST800-53R5_SC-6
- NIST800-53R5_SC-6
ansible.builtin.lineinfile: ansible.builtin.lineinfile:
path: /etc/sysconfig/sshd path: /etc/sysconfig/sshd
regexp: ^CRYPTO_POLICY\s*= regexp: ^CRYPTO_POLICY\s*=
@ -41,7 +37,6 @@
when: when:
- rhel9cis_rule_1_6_3 - rhel9cis_rule_1_6_3
- "'NO-SHA1' not in rhel9cis_crypto_policy_module" - "'NO-SHA1' not in rhel9cis_crypto_policy_module"
- rhel9cis_crypto_policy_ansiblemanaged
tags: tags:
- level1-server - level1-server
- level1-workstation - level1-workstation
@ -72,7 +67,6 @@
when: when:
- rhel9cis_rule_1_6_4 - rhel9cis_rule_1_6_4
- "'NO-WEAKMAC' not in rhel9cis_crypto_policy_module" - "'NO-WEAKMAC' not in rhel9cis_crypto_policy_module"
- rhel9cis_crypto_policy_ansiblemanaged
tags: tags:
- level1-server - level1-server
- level1-workstation - level1-workstation
@ -82,6 +76,7 @@
- rule_1.6.4 - rule_1.6.4
- NIST800-53R5_SC-6 - NIST800-53R5_SC-6
block: block:
- name: "1.6.4 | PATCH | Ensure system wide crypto policy disables macs less than 128 bits | Add submodule exclusion" - name: "1.6.4 | PATCH | Ensure system wide crypto policy disables macs less than 128 bits | Add submodule exclusion"
ansible.builtin.template: ansible.builtin.template:
src: etc/crypto-policies/policies/modules/NO-WEAKMAC.pmod.j2 src: etc/crypto-policies/policies/modules/NO-WEAKMAC.pmod.j2
@ -103,7 +98,6 @@
when: when:
- rhel9cis_rule_1_6_5 - rhel9cis_rule_1_6_5
- "'NO-SSHCBC' not in rhel9cis_crypto_policy_module" - "'NO-SSHCBC' not in rhel9cis_crypto_policy_module"
- rhel9cis_crypto_policy_ansiblemanaged
tags: tags:
- level1-server - level1-server
- level1-workstation - level1-workstation
@ -134,7 +128,6 @@
when: when:
- rhel9cis_rule_1_6_6 - rhel9cis_rule_1_6_6
- "'NO-SSHWEAKCIPHERS' not in rhel9cis_crypto_policy_module" - "'NO-SSHWEAKCIPHERS' not in rhel9cis_crypto_policy_module"
- rhel9cis_crypto_policy_ansiblemanaged
tags: tags:
- level1-server - level1-server
- level1-workstation - level1-workstation
@ -165,7 +158,6 @@
when: when:
- rhel9cis_rule_1_6_7 - rhel9cis_rule_1_6_7
- "'NO-SSHETM' not in rhel9cis_crypto_policy_module" - "'NO-SSHETM' not in rhel9cis_crypto_policy_module"
- rhel9cis_crypto_policy_ansiblemanaged
tags: tags:
- level1-server - level1-server
- level1-workstation - level1-workstation

View file

@ -41,7 +41,7 @@
file: cis_1.2.2.x.yml file: cis_1.2.2.x.yml
- name: "SECTION | 1.3.1 | Configure SELinux" - name: "SECTION | 1.3.1 | Configure SELinux"
ansible.builtin.import_tasks: ansible.builtin.include_tasks:
file: cis_1.3.1.x.yml file: cis_1.3.1.x.yml
- name: "SECTION | 1.4 | Configure Bootloader" - name: "SECTION | 1.4 | Configure Bootloader"
@ -61,6 +61,5 @@
file: cis_1.7.x.yml file: cis_1.7.x.yml
- name: "SECTION | 1.8 | Gnome Display Manager" - name: "SECTION | 1.8 | Gnome Display Manager"
when: rhel9cis_display_manager == 'gdm'
ansible.builtin.import_tasks: ansible.builtin.import_tasks:
file: cis_1.8.x.yml file: cis_1.8.x.yml

View file

@ -16,30 +16,15 @@
- rule_3.1.1 - rule_3.1.1
- NIST800-53R5_CM-7 - NIST800-53R5_CM-7
block: block:
- name: "3.1.1 | PATCH | Ensure IPv6 status is identified | Set vars for sysctl template" - name: "3.1.1 | PATCH | Ensure IPv6 status is identified | refresh"
when: "'sysctl' in rhel9cis_ipv6_disable_method"
ansible.builtin.set_fact: ansible.builtin.set_fact:
rhel9cis_sysctl_update: true rhel9cis_sysctl_update: true
rhel9cis_flush_ipv6_route: true rhel9cis_flush_ipv6_route: true
- name: "3.1.1 | AUDIT | Ensure IPv6 status is identified | Message out implementation info" - name: "3.1.1 | PATCH | Ensure IPv6 status is identified | disable"
when: "'sysctl' in rhel9cis_ipv6_disable_method"
ansible.builtin.debug: ansible.builtin.debug:
msg: "Control being set via Handler 'update sysctl' which writes to /etc/sysctl.d/60-disable_ipv6.conf" msg: "Control being set via Handler 'update sysctl' which writes to /etc/sysctl.d/60-disable_ipv6.conf"
- name: "3.1.1 | AUDIT | Ensure IPv6 status is identified | Find IPv6 status"
when: "'kernel' in rhel9cis_ipv6_disable_method"
ansible.builtin.command: grubby --info=ALL
changed_when: false
failed_when: false
register: discovered_rhel9cis_3_1_1_ipv6_status
- name: "3.1.1 | PATCH | Ensure IPv6 status is identified | Disable IPV6 via Kernel"
when:
- "'kernel' in rhel9cis_ipv6_disable_method"
- "'ipv6.disable=1' not in discovered_rhel9cis_3_1_1_ipv6_status.stdout"
ansible.builtin.shell: grubby --update-kernel=ALL --args="ipv6.disable=1"
- name: "3.1.2 | PATCH | Ensure wireless interfaces are disabled" - name: "3.1.2 | PATCH | Ensure wireless interfaces are disabled"
when: when:
- rhel9cis_rule_3_1_2 - rhel9cis_rule_3_1_2

View file

@ -25,8 +25,8 @@
- name: "3.2.1 | PATCH | Ensure dccp kernel module is not available | blacklist" - name: "3.2.1 | PATCH | Ensure dccp kernel module is not available | blacklist"
ansible.builtin.lineinfile: ansible.builtin.lineinfile:
path: /etc/modprobe.d/blacklist.conf path: /etc/modprobe.d/blacklist.conf
regexp: "^(#)?blacklist dccp(\\s|$)" regexp: "^(#)?blacklist cramfs(\\s|$)"
line: "blacklist dccp" line: "blacklist cramfs"
create: true create: true
mode: 'u-x,go-rwx' mode: 'u-x,go-rwx'

View file

@ -240,12 +240,12 @@
- rule_3.3.9 - rule_3.3.9
- NIST800-53R5_AU-3 - NIST800-53R5_AU-3
block: block:
- name: "3.3.9 | PATCH | Ensure suspicious packets are logged | Set Fact" - name: "3.3.4 | PATCH | Ensure suspicious packets are logged | Set Fact"
ansible.builtin.set_fact: ansible.builtin.set_fact:
rhel9cis_sysctl_update: true rhel9cis_sysctl_update: true
rhel9cis_flush_ipv4_route: true rhel9cis_flush_ipv4_route: true
- name: "3.3.9 | PATCH | Ensure suspicious packets are logged" - name: "3.3.4 | PATCH | Ensure suspicious packets are logged"
ansible.builtin.debug: ansible.builtin.debug:
msg: "Control being set via Handler 'update sysctl' which writes to /etc/sysctl.d/60-netipv4_sysctl.conf" msg: "Control being set via Handler 'update sysctl' which writes to /etc/sysctl.d/60-netipv4_sysctl.conf"

View file

@ -81,7 +81,7 @@
register: discovered_nftables_inconnectionrule register: discovered_nftables_inconnectionrule
- name: "4.3.2 | AUDIT | Ensure nftables established connections are configured | Gather outbound connection rules" - name: "4.3.2 | AUDIT | Ensure nftables established connections are configured | Gather outbound connection rules"
ansible.builtin.shell: nft list ruleset | awk '/hook output/,/}/' | grep -E 'ip protocol (tcp|udp|icmp) ct state' ansible.builtin.command: nft list ruleset | awk '/hook output/,/}/' | grep -E 'ip protocol (tcp|udp|icmp) ct state'
changed_when: false changed_when: false
failed_when: false failed_when: false
register: discovered_nftables_outconnectionrule register: discovered_nftables_outconnectionrule

View file

@ -41,8 +41,8 @@
ansible.builtin.file: ansible.builtin.file:
path: "{{ item.path }}" path: "{{ item.path }}"
owner: root owner: root
group: "{{ 'ssh_keys' if (item.gr_name == 'ssh_keys') else 'root' }}" group: root
mode: "{{ 'u-x,g-wx,o-rwx' if (item.gr_name == 'ssh_keys') else 'u-x,go-rwx' }}" mode: 'u-x,go-rwx'
loop: "{{ discovered_ssh_private_host_key.files }}" loop: "{{ discovered_ssh_private_host_key.files }}"
loop_control: loop_control:
label: "{{ item.path }}" label: "{{ item.path }}"
@ -80,7 +80,6 @@
when: when:
- rhel9cis_rule_5_1_4 - rhel9cis_rule_5_1_4
- "'NO-SSHWEAKCIPHERS' not in rhel9cis_crypto_policy_module" - "'NO-SSHWEAKCIPHERS' not in rhel9cis_crypto_policy_module"
- rhel9cis_crypto_policy_ansiblemanaged
tags: tags:
- level1-server - level1-server
- level1-workstation - level1-workstation
@ -109,7 +108,6 @@
when: when:
- rhel9cis_rule_5_1_5 - rhel9cis_rule_5_1_5
- "'NO-SHA1' not in rhel9cis_crypto_policy_module" - "'NO-SHA1' not in rhel9cis_crypto_policy_module"
- rhel9cis_crypto_policy_ansiblemanaged
tags: tags:
- level1-server - level1-server
- level1-workstation - level1-workstation
@ -138,7 +136,6 @@
when: when:
- rhel9cis_rule_5_1_6 - rhel9cis_rule_5_1_6
- "'NO-SSHWEAKMACS' not in rhel9cis_crypto_policy_module" - "'NO-SSHWEAKMACS' not in rhel9cis_crypto_policy_module"
- rhel9cis_crypto_policy_ansiblemanaged
tags: tags:
- level1-server - level1-server
- level1-workstation - level1-workstation

View file

@ -91,15 +91,9 @@
insertafter: "{{ item.after | default(omit) }}" insertafter: "{{ item.after | default(omit) }}"
line: "{{ item.line }}" line: "{{ item.line }}"
loop: loop:
- regexp: "auth\\s+required\\s+pam_faillock.so\\s+preauth" - { regexp: auth\s*required\s*pam_faillock.so preauth, after: auth\s*required\s*pam_env.so, line: "auth required pam_faillock.so preauth silent deny=3 unlock_timeout={{ rhel9cis_pam_faillock_unlock_time }}" }
after: "auth\\s+required\\s+pam_env.so" # yamllint disable-line rule:colons - { regexp: auth\s*required\s*pam_faillock.so authfail, before: auth\s*required\s*pam_deny.so, line: "auth required pam_faillock.so authfail silent deny=3 unlock_timeout={{ rhel9cis_pam_faillock_unlock_time }}" }
line: "auth required pam_faillock.so preauth silent deny=3 unlock_timeout={{ rhel9cis_pam_faillock_unlock_time }}" # yamllint disable-line rule:colons - { regexp: account\s*required\s*pam_faillock.so, before: account\s*required\s*pam_unix.so, line: "account required pam_faillock.so" }
- regexp: "auth\\s+required\\s+pam_faillock.so\\s+authfail"
before: "auth\\s+required\\s+pam_deny.so"
line: "auth required pam_faillock.so authfail silent deny=3 unlock_timeout={{ rhel9cis_pam_faillock_unlock_time }}" # yamllint disable-line rule:colons
- regexp: "account\\s+required\\s+pam_faillock.so"
before: "account\\s+required\\s+pam_unix.so"
line: "account required pam_faillock.so" # yamllint disable-line rule:colons
- name: "5.3.2.2 | AUDIT | Ensure pam_faillock module is enabled | Add lines password-auth" - name: "5.3.2.2 | AUDIT | Ensure pam_faillock module is enabled | Add lines password-auth"
when: not rhel9cis_allow_authselect_updates when: not rhel9cis_allow_authselect_updates
@ -110,15 +104,9 @@
insertafter: "{{ item.after | default(omit) }}" insertafter: "{{ item.after | default(omit) }}"
line: "{{ item.line }}" line: "{{ item.line }}"
loop: loop:
- regexp: "auth\\s+required\\s+pam_faillock.so\\s+preauth" - { regexp: auth\s*required\s*pam_faillock.so preauth, after: auth\s*required\s*pam_env.so, line: "auth required pam_faillock.so preauth silent deny=3 unlock_timeout={{ rhel9cis_pam_faillock_unlock_time }}" }
after: "auth\\s+required\\s+pam_env.so" # yamllint disable-line rule:colons - { regexp: auth\s*required\s*pam_faillock.so authfail, before: auth\s*required\s*pam_deny.so, line: "auth required pam_faillock.so authfail silent deny=3 unlock_timeout={{ rhel9cis_pam_faillock_unlock_time }}" }
line: "auth required pam_faillock.so preauth silent deny=3 unlock_timeout={{ rhel9cis_pam_faillock_unlock_time }}" # yamllint disable-line rule:colons - { regexp: account\s*required\s*pam_faillock.so, before: account\s*required\s*pam_unix.so, line: "account required pam_faillock.so" }
- regexp: "auth\\s+required\\s+pam_faillock.so\\s+authfail"
before: "auth\\s+required\\s+pam_deny.so"
line: "auth required pam_faillock.so authfail silent deny=3 unlock_timeout={{ rhel9cis_pam_faillock_unlock_time }}" # yamllint disable-line rule:colons
- regexp: "account\\s+required\\s+pam_faillock.so"
before: "account\\s+required\\s+pam_unix.so"
line: "account required pam_faillock.so" # yamllint disable-line rule:colons
- name: "5.3.2.3 | PATCH | Ensure pam_pwquality module is enabled" - name: "5.3.2.3 | PATCH | Ensure pam_pwquality module is enabled"
when: when:

View file

@ -24,7 +24,6 @@
ansible.builtin.shell: "awk -F: '(/^[^:]+:[^!*]/ && ($5> {{ rhel9cis_pass_max_days }} || $5< {{ rhel9cis_pass_max_days }} || $5 == -1)){print $1}' /etc/shadow" ansible.builtin.shell: "awk -F: '(/^[^:]+:[^!*]/ && ($5> {{ rhel9cis_pass_max_days }} || $5< {{ rhel9cis_pass_max_days }} || $5 == -1)){print $1}' /etc/shadow"
changed_when: false changed_when: false
failed_when: false failed_when: false
check_mode: false
register: discovered_max_days register: discovered_max_days
- name: "5.4.1.1 | PATCH | Ensure password expiration is 365 days or less | Set existing users PASS_MAX_DAYS" - name: "5.4.1.1 | PATCH | Ensure password expiration is 365 days or less | Set existing users PASS_MAX_DAYS"
@ -65,7 +64,7 @@
- rhel9cis_force_user_mindays - rhel9cis_force_user_mindays
ansible.builtin.user: ansible.builtin.user:
name: "{{ item }}" name: "{{ item }}"
password_expire_min: "{{ rhel9cis_pass_min_days }}" password_expire_max: "{{ rhel9cis_pass_min_days }}"
loop: "{{ discovered_min_days.stdout_lines }}" loop: "{{ discovered_min_days.stdout_lines }}"
- name: "5.4.1.3 | PATCH | Ensure password expiration warning days is configured" - name: "5.4.1.3 | PATCH | Ensure password expiration warning days is configured"
@ -94,7 +93,7 @@
- discovered_warn_days.stdout_lines | length > 0 - discovered_warn_days.stdout_lines | length > 0
- item in prelim_interactive_users | map(attribute='username') | list - item in prelim_interactive_users | map(attribute='username') | list
- rhel9cis_force_user_warnage - rhel9cis_force_user_warnage
ansible.builtin.command: "chage --warndays {{ rhel9cis_pass_warn_age }} {{ item }}" ansible.builtin.command: "chage --warndays {{ rhel9cis_pass['warn_age'] }} {{ item }}"
changed_when: true changed_when: true
loop: "{{ discovered_warn_days.stdout_lines }}" loop: "{{ discovered_warn_days.stdout_lines }}"

View file

@ -61,7 +61,7 @@
- level1-server - level1-server
- level1-workstation - level1-workstation
- patch - patch
- rule_5.4.2.3 - rule_5.4.2.2
- user - user
- system - system
- NIST800-53R5_CM-1 - NIST800-53R5_CM-1
@ -135,22 +135,6 @@
ansible.builtin.set_fact: ansible.builtin.set_fact:
root_paths: "{{ discovered_root_paths.stdout }}" root_paths: "{{ discovered_root_paths.stdout }}"
- name: "5.4.2.5 | AUDIT | Ensure root PATH Integrity | Check for presence of non-dirs"
ansible.builtin.stat:
path: "{{ item }}"
loop: "{{ discovered_root_paths_split.stdout_lines }}"
register: discovered_root_paths_stat
- name: "5.4.2.5 | AUDIT | Ensure root PATH Integrity | Create dirs for some paths that are not dirs"
ansible.builtin.file:
path: "{{ item.item }}"
state: directory
owner: root
group: root
mode: 'go-w'
loop: "{{ discovered_root_paths_stat.results }}"
when: not item.stat.exists
- name: "5.4.2.5 | AUDIT | Ensure root PATH Integrity | Check for empty dirs" - name: "5.4.2.5 | AUDIT | Ensure root PATH Integrity | Check for empty dirs"
when: discovered_root_paths is defined when: discovered_root_paths is defined
ansible.builtin.shell: 'echo {{ root_paths }} | grep -q "::" && echo "roots path contains a empty directory (::)"' ansible.builtin.shell: 'echo {{ root_paths }} | grep -q "::" && echo "roots path contains a empty directory (::)"'

View file

@ -5,56 +5,45 @@
- name: "SECTION | 5.1 | Configure SSH Server" - name: "SECTION | 5.1 | Configure SSH Server"
when: when:
- "'openssh-server' in ansible_facts.packages" - "'openssh-server' in ansible_facts.packages"
- rhel9cis_section5_1
ansible.builtin.import_tasks: ansible.builtin.import_tasks:
file: cis_5.1.x.yml file: cis_5.1.x.yml
- name: "SECTION | 5.2 | Configure privilege escalation" - name: "SECTION | 5.2 | Configure privilege escalation"
when:
- rhel9cis_section5_2
ansible.builtin.import_tasks: ansible.builtin.import_tasks:
file: cis_5.2.x.yml file: cis_5.2.x.yml
- name: "SECTION | 5.3" - name: "SECTION | 5.3.1.x | Configure PAM software packages"
when:
- rhel9cis_section5_3
block:
- name: "SECTION | 5.3.1.x | Configure PAM software packages"
ansible.builtin.import_tasks: ansible.builtin.import_tasks:
file: cis_5.3.1.x.yml file: cis_5.3.1.x.yml
- name: "SECTION | 5.3.2.x | Configure authselect" - name: "SECTION | 5.3.2.x | Configure authselect"
ansible.builtin.import_tasks: ansible.builtin.import_tasks:
file: cis_5.3.2.x.yml file: cis_5.3.2.x.yml
- name: "SECTION | 5.3.3.1.x | Configure pam_faillock module" - name: "SECTION | 5.3.3.1.x | Configure pam_faillock module"
ansible.builtin.import_tasks: ansible.builtin.import_tasks:
file: cis_5.3.3.1.x.yml file: cis_5.3.3.1.x.yml
- name: "SECTION | 5.3.3.2.x | Configure pam_pwquality module" - name: "SECTION | 5.3.3.2.x | Configure pam_pwquality module"
ansible.builtin.import_tasks: ansible.builtin.import_tasks:
file: cis_5.3.3.2.x.yml file: cis_5.3.3.2.x.yml
- name: "SECTION | 5.3.3.3.x | Configure pam_pwhistory module" - name: "SECTION | 5.3.3.3.x | Configure pam_pwhistory module"
ansible.builtin.import_tasks: ansible.builtin.import_tasks:
file: cis_5.3.3.3.x.yml file: cis_5.3.3.3.x.yml
- name: "SECTION | 5.3.3.4.x | Configure pam_unix module" - name: "SECTION | 5.3.3.4.x | Configure pam_unix module"
ansible.builtin.import_tasks: ansible.builtin.import_tasks:
file: cis_5.3.3.4.x.yml file: cis_5.3.3.4.x.yml
- name: "SECTION | 5.4" - name: "SECTION | 5.4.1.x | Configure shadow password suite parameters"
when:
- rhel9cis_section5_4
block:
- name: "SECTION | 5.4.1.x | Configure shadow password suite parameters"
ansible.builtin.import_tasks: ansible.builtin.import_tasks:
file: cis_5.4.1.x.yml file: cis_5.4.1.x.yml
- name: "SECTION | 5.4.2.x | Configure root and system accounts and environment" - name: "SECTION | 5.4.2.x | Configure root and system accounts and environment"
ansible.builtin.import_tasks: ansible.builtin.import_tasks:
file: cis_5.4.2.x.yml file: cis_5.4.2.x.yml
- name: "SECTION | 5.4.3.x | Configure user default environment" - name: "SECTION | 5.4.3.x | Configure user default environment"
ansible.builtin.import_tasks: ansible.builtin.import_tasks:
file: cis_5.4.3.x.yml file: cis_5.4.3.x.yml

View file

@ -91,13 +91,13 @@
- name: "6.1.2 | PATCH | Ensure filesystem integrity is regularly checked | aide service" - name: "6.1.2 | PATCH | Ensure filesystem integrity is regularly checked | aide service"
when: rhel9cis_aide_scan == "timer" when: rhel9cis_aide_scan == "timer"
ansible.builtin.systemd: ansible.builtin.systemd_service:
name: aidecheck.service name: aidecheck.service
enabled: true enabled: true
- name: "6.1.2 | PATCH | Ensure filesystem integrity is regularly checked | aide service" - name: "6.1.2 | PATCH | Ensure filesystem integrity is regularly checked | aide service"
when: rhel9cis_aide_scan == "timer" when: rhel9cis_aide_scan == "timer"
ansible.builtin.systemd: ansible.builtin.systemd_service:
name: aidecheck.timer name: aidecheck.timer
state: started state: started
enabled: true enabled: true

View file

@ -131,7 +131,7 @@
*.=warning;*.=err -/var/log/warn *.=warning;*.=err -/var/log/warn
*.crit /var/log/warn *.crit /var/log/warn
*.*;mail.none;news.none /var/log/messages *.*;mail.none;news.none /var/log/messages
insertbefore: '# ### sample forwarding rule ###' insertafter: '#### RULES ####'
notify: Restart rsyslog notify: Restart rsyslog
- name: "6.2.3.5 | PATCH | Ensure logging is configured | Local log settings" - name: "6.2.3.5 | PATCH | Ensure logging is configured | Local log settings"

View file

@ -27,9 +27,9 @@
- level2-workstation - level2-workstation
- patch - patch
- auditd - auditd
- rule_6.3.4.1
- rule_6.3.4.2 - rule_6.3.4.2
- rule_6.3.4.3 - rule_6.3.4.3
- rule_6.3.4.4
- NIST800-53R5_AU-3 - NIST800-53R5_AU-3
ansible.builtin.file: ansible.builtin.file:
path: "{{ prelim_auditd_logfile.stdout }}" path: "{{ prelim_auditd_logfile.stdout }}"

View file

@ -37,7 +37,7 @@ rhel9cis_legacy_boot: {{ rhel9cis_legacy_boot }}
## Benchmark name used by auditing control role ## Benchmark name used by auditing control role
# The audit variable found at the base # The audit variable found at the base
## metadata for Audit benchmark ## metadata for Audit benchmark
benchmark_version: {{ benchmark_version }} benchmark_version: 'v2.0.0'
benchmark: RHEL9-CIS benchmark: RHEL9-CIS

View file

@ -10,7 +10,12 @@
{% endif %} {% endif %}
{% if rhel9cis_rule_6_3_3_2 %} {% if rhel9cis_rule_6_3_3_2 %}
{% set syscalls = ["execve"] %} {% set syscalls = ["execve"] %}
{% set arch_syscalls = syscalls | select("in", supported_syscalls) | list %} {% set arch_syscalls = [] %}
{%- for syscall in syscalls %}
{% if syscall in supported_syscalls %}
{{ arch_syscalls.append(syscall) }}
{% endif %}
{% endfor -%}
-a always,exit -F arch=b64 -C euid!=uid -F auid!=unset -S {{ arch_syscalls|join(',') }} -k user_emulation -a always,exit -F arch=b64 -C euid!=uid -F auid!=unset -S {{ arch_syscalls|join(',') }} -k user_emulation
-a always,exit -F arch=b32 -C euid!=uid -F auid!=unset -S {{ arch_syscalls|join(',') }} -k user_emulation -a always,exit -F arch=b32 -C euid!=uid -F auid!=unset -S {{ arch_syscalls|join(',') }} -k user_emulation
{% endif %} {% endif %}
@ -19,27 +24,40 @@
{% endif %} {% endif %}
{% if rhel9cis_rule_6_3_3_4 %} {% if rhel9cis_rule_6_3_3_4 %}
{% set syscalls = ["adjtimex","settimeofday"] %} {% set syscalls = ["adjtimex","settimeofday"] %}
{% set arch_syscalls = syscalls | select("in", supported_syscalls) | list %} {% set arch_syscalls = [] %}
{% for syscall in syscalls %}
{% if syscall in supported_syscalls %}
{{ arch_syscalls.append(syscall) }}
{% endif %}
{% endfor %}
-a always,exit -F arch=b64 -S {{ arch_syscalls|join(',') }} -k time-change -a always,exit -F arch=b64 -S {{ arch_syscalls|join(',') }} -k time-change
-a always,exit -F arch=b32 -S {{ arch_syscalls|join(',') }} -k time-change -a always,exit -F arch=b32 -S {{ arch_syscalls|join(',') }} -k time-change
{% set syscalls = ["clock_settime"] %} {% set syscalls = ["clock_settime"] %}
{% set arch_syscalls = syscalls | select("in", supported_syscalls) | list %} {% set arch_syscalls = [] %}
{% for syscall in syscalls %}
{% if syscall in supported_syscalls %}
{{ arch_syscalls.append(syscall) }}
-a always,exit -F arch=b32 -S {{ arch_syscalls|join(',') }} -F a0=0x0 -k time-change -a always,exit -F arch=b32 -S {{ arch_syscalls|join(',') }} -F a0=0x0 -k time-change
-a always,exit -F arch=b64 -S {{ arch_syscalls|join(',') }} -F a0=0x0 -k time-change -a always,exit -F arch=b64 -S {{ arch_syscalls|join(',') }} -F a0=0x0 -k time-change
{% endif %}
{% endfor %}
-w /etc/localtime -p wa -k time-change -w /etc/localtime -p wa -k time-change
{% endif %} {% endif %}
{% if rhel9cis_rule_6_3_3_5 %} {% if rhel9cis_rule_6_3_3_5 %}
{% set syscalls = ["sethostname","setdomainname"] %} {% set syscalls = ["sethostname","setdomainname"] %}
{% set arch_syscalls = syscalls | select("in", supported_syscalls) | list %} {% set arch_syscalls = [] %}
{% for syscall in syscalls %}
{% if syscall in supported_syscalls %}
{{ arch_syscalls.append(syscall) }}
{% endif %}
{% endfor %}
-a always,exit -F arch=b64 -S {{ arch_syscalls|join(',') }} -k system-locale -a always,exit -F arch=b64 -S {{ arch_syscalls|join(',') }} -k system-locale
-a always,exit -F arch=b32 -S {{ arch_syscalls|join(',') }} -k system-locale -a always,exit -F arch=b32 -S {{ arch_syscalls|join(',') }} -k system-locale
-w /etc/issue -p wa -k system-locale -w /etc/issue -p wa -k system-locale
-w /etc/issue.net -p wa -k system-locale -w /etc/issue.net -p wa -k system-locale
-w /etc/hosts -p wa -k system-locale -w /etc/hosts -p wa -k system-locale
-w /etc/hostname -p wa -k system-locale
-w /etc/sysconfig/network -p wa -k system-locale -w /etc/sysconfig/network -p wa -k system-locale
-w /etc/sysconfig/network-scripts -p wa -k system-locale -w /etc/sysconfig/network-scripts -p wa -k system-locale
-w /etc/NetworkManager -p wa -k system-locale
{% endif %} {% endif %}
{% if rhel9cis_rule_6_3_3_6 %} {% if rhel9cis_rule_6_3_3_6 %}
{% for proc in discovered_priv_procs.stdout_lines -%} {% for proc in discovered_priv_procs.stdout_lines -%}
@ -48,7 +66,12 @@
{% endif %} {% endif %}
{% if rhel9cis_rule_6_3_3_7 %} {% if rhel9cis_rule_6_3_3_7 %}
{% set syscalls = ["creat","open","openat","truncate","ftruncate"] %} {% set syscalls = ["creat","open","openat","truncate","ftruncate"] %}
{% set arch_syscalls = syscalls | select("in", supported_syscalls) | list %} {% set arch_syscalls = [] %}
{% for syscall in syscalls %}
{% if syscall in supported_syscalls %}
{{ arch_syscalls.append(syscall) }}
{% endif %}
{% endfor %}
-a always,exit -F arch=b64 -S {{ arch_syscalls|join(',') }} -F exit=-EACCES -F auid>={{ prelim_min_int_uid }} -F auid!=unset -k access -a always,exit -F arch=b64 -S {{ arch_syscalls|join(',') }} -F exit=-EACCES -F auid>={{ prelim_min_int_uid }} -F auid!=unset -k access
-a always,exit -F arch=b64 -S {{ arch_syscalls|join(',') }} -F exit=-EPERM -F auid>={{ prelim_min_int_uid }} -F auid!=unset -k access -a always,exit -F arch=b64 -S {{ arch_syscalls|join(',') }} -F exit=-EPERM -F auid>={{ prelim_min_int_uid }} -F auid!=unset -k access
-a always,exit -F arch=b32 -S {{ arch_syscalls|join(',') }} -F exit=-EACCES -F auid>={{ prelim_min_int_uid }} -F auid!=unset -k access -a always,exit -F arch=b32 -S {{ arch_syscalls|join(',') }} -F exit=-EACCES -F auid>={{ prelim_min_int_uid }} -F auid!=unset -k access
@ -66,27 +89,62 @@
{% endif %} {% endif %}
{% if rhel9cis_rule_6_3_3_9 %} {% if rhel9cis_rule_6_3_3_9 %}
{% set syscalls = ["chmod","fchmod","fchmodat"] %} {% set syscalls = ["chmod","fchmod","fchmodat"] %}
{% set arch_syscalls = syscalls | select("in", supported_syscalls) | list %} {% set arch_syscalls = [] %}
{% for syscall in syscalls %}
{% if syscall in supported_syscalls %}
{{ arch_syscalls.append(syscall) }}
{% endif %}
{% endfor %}
-a always,exit -F arch=b64 -S {{ arch_syscalls|join(',') }} -F auid>={{ prelim_min_int_uid }} -F auid!=unset -k perm_mod -a always,exit -F arch=b64 -S {{ arch_syscalls|join(',') }} -F auid>={{ prelim_min_int_uid }} -F auid!=unset -k perm_mod
{% set syscalls = ["chown","fchown","lchown","fchownat"] %} {% set syscalls = ["chown","fchown","lchown","fchownat"] %}
{% set arch_syscalls = syscalls | select("in", supported_syscalls) | list %} {% set arch_syscalls = [] %}
{% for syscall in syscalls %}
{% if syscall in supported_syscalls %}
{{ arch_syscalls.append(syscall) }}
{% endif %}
{% endfor %}
-a always,exit -F arch=b64 -S {{ arch_syscalls|join(',') }} -F auid>={{ prelim_min_int_uid }} -F auid!=unset -k perm_mod -a always,exit -F arch=b64 -S {{ arch_syscalls|join(',') }} -F auid>={{ prelim_min_int_uid }} -F auid!=unset -k perm_mod
{% set syscalls = ["setxattr","lsetxattr","fsetxattr","removexattr","lremovexattr","fremovexattr"] %} {% set syscalls = ["setxattr","lsetxattr","fsetxattr","removexattr","lremovexattr","fremovexattr"] %}
{% set arch_syscalls = syscalls | select("in", supported_syscalls) | list %} {% set arch_syscalls = [] %}
{% for syscall in syscalls %}
{% if syscall in supported_syscalls %}
{{ arch_syscalls.append(syscall) }}
{% endif %}
{% endfor %}
-a always,exit -F arch=b64 -S {{ arch_syscalls|join(',') }} -F auid>={{ prelim_min_int_uid }} -F auid!=unset -k perm_mod -a always,exit -F arch=b64 -S {{ arch_syscalls|join(',') }} -F auid>={{ prelim_min_int_uid }} -F auid!=unset -k perm_mod
{% set syscalls = ["chmod","fchmod","fchmodat"] %} {% set syscalls = ["chmod","fchmod","fchmodat"] %}
{% set arch_syscalls = syscalls | select("in", supported_syscalls) | list %} {% set arch_syscalls = [] %}
{% for syscall in syscalls %}
{% if syscall in supported_syscalls %}
{{ arch_syscalls.append(syscall) }}
{% endif %}
{% endfor %}
-a always,exit -F arch=b32 -S {{ arch_syscalls|join(',') }} -F auid>={{ prelim_min_int_uid }} -F auid!=unset -k perm_mod -a always,exit -F arch=b32 -S {{ arch_syscalls|join(',') }} -F auid>={{ prelim_min_int_uid }} -F auid!=unset -k perm_mod
{% set syscalls = ["chown","fchown","lchown","fchownat"] %} {% set syscalls = ["chown","fchown","lchown","fchownat"] %}
{% set arch_syscalls = syscalls | select("in", supported_syscalls) | list %} {% set arch_syscalls = [] %}
{% for syscall in syscalls %}
{% if syscall in supported_syscalls %}
{{ arch_syscalls.append(syscall) }}
{% endif %}
{% endfor %}
-a always,exit -F arch=b32 -S {{ arch_syscalls|join(',') }} -F auid>={{ prelim_min_int_uid }} -F auid!=unset -k perm_mod -a always,exit -F arch=b32 -S {{ arch_syscalls|join(',') }} -F auid>={{ prelim_min_int_uid }} -F auid!=unset -k perm_mod
{% set syscalls = ["setxattr","lsetxattr","fsetxattr","removexattr","lremovexattr","fremovexattr"] %} {% set syscalls = ["setxattr","lsetxattr","fsetxattr","removexattr","lremovexattr","fremovexattr"] %}
{% set arch_syscalls = syscalls | select("in", supported_syscalls) | list %} {% set arch_syscalls = [] %}
{% for syscall in syscalls %}
{% if syscall in supported_syscalls %}
{{ arch_syscalls.append(syscall) }}
{% endif %}
{% endfor %}
-a always,exit -F arch=b32 -S {{ arch_syscalls|join(',') }} -F auid>={{ prelim_min_int_uid }} -F auid!=unset -k perm_mod -a always,exit -F arch=b32 -S {{ arch_syscalls|join(',') }} -F auid>={{ prelim_min_int_uid }} -F auid!=unset -k perm_mod
{% endif %} {% endif %}
{% if rhel9cis_rule_6_3_3_10 %} {% if rhel9cis_rule_6_3_3_10 %}
{% set syscalls = ["mount"] %} {% set syscalls = ["mount"] %}
{% set arch_syscalls = syscalls | select("in", supported_syscalls) | list %} {% set arch_syscalls = [] %}
{% for syscall in syscalls %}
{% if syscall in supported_syscalls %}
{{ arch_syscalls.append(syscall) }}
{% endif %}
{% endfor %}
-a always,exit -F arch=b64 -S {{ arch_syscalls|join(',') }} -F auid>={{ prelim_min_int_uid }} -F auid!=unset -k mounts -a always,exit -F arch=b64 -S {{ arch_syscalls|join(',') }} -F auid>={{ prelim_min_int_uid }} -F auid!=unset -k mounts
-a always,exit -F arch=b32 -S {{ arch_syscalls|join(',') }} -F auid>={{ prelim_min_int_uid }} -F auid!=unset -k mounts -a always,exit -F arch=b32 -S {{ arch_syscalls|join(',') }} -F auid>={{ prelim_min_int_uid }} -F auid!=unset -k mounts
{% endif %} {% endif %}
@ -101,7 +159,12 @@
{% endif %} {% endif %}
{% if rhel9cis_rule_6_3_3_13 %} {% if rhel9cis_rule_6_3_3_13 %}
{% set syscalls = ["unlink","unlinkat","rename","renameat"] %} {% set syscalls = ["unlink","unlinkat","rename","renameat"] %}
{% set arch_syscalls = syscalls | select("in", supported_syscalls) | list %} {% set arch_syscalls = [] %}
{% for syscall in syscalls %}
{% if syscall in supported_syscalls %}
{{ arch_syscalls.append( syscall) }}
{% endif %}
{% endfor %}
-a always,exit -F arch=b64 -S {{ arch_syscalls|join(',') }} -F auid>={{ prelim_min_int_uid }} -F auid!=unset -k delete -a always,exit -F arch=b64 -S {{ arch_syscalls|join(',') }} -F auid>={{ prelim_min_int_uid }} -F auid!=unset -k delete
-a always,exit -F arch=b32 -S {{ arch_syscalls|join(',') }} -F auid>={{ prelim_min_int_uid }} -F auid!=unset -k delete -a always,exit -F arch=b32 -S {{ arch_syscalls|join(',') }} -F auid>={{ prelim_min_int_uid }} -F auid!=unset -k delete
{% endif %} {% endif %}
@ -124,7 +187,12 @@
{% if rhel9cis_rule_6_3_3_19 %} {% if rhel9cis_rule_6_3_3_19 %}
-a always,exit -F path=/usr/bin/kmod -F perm=x -F auid>={{ prelim_min_int_uid }} -F auid!=unset -k kernel_modules -a always,exit -F path=/usr/bin/kmod -F perm=x -F auid>={{ prelim_min_int_uid }} -F auid!=unset -k kernel_modules
{% set syscalls = ["init_module","finit_module","delete_module","create_module","query_module"] %} {% set syscalls = ["init_module","finit_module","delete_module","create_module","query_module"] %}
{% set arch_syscalls = syscalls | select("in", supported_syscalls) | list %} {% set arch_syscalls = [] %}
{% for syscall in syscalls %}
{% if syscall in supported_syscalls %}
{{ arch_syscalls.append( syscall) }}
{% endif %}
{% endfor %}
-a always,exit -F arch=b64 -S {{ arch_syscalls|join(',') }} -F auid>={{ prelim_min_int_uid }} -F auid!=unset -k kernel_modules -a always,exit -F arch=b64 -S {{ arch_syscalls|join(',') }} -F auid>={{ prelim_min_int_uid }} -F auid!=unset -k kernel_modules
{% endif %} {% endif %}
{% if rhel9cis_rule_6_3_3_20 %} {% if rhel9cis_rule_6_3_3_20 %}

View file

@ -4,4 +4,4 @@
[org/gnome/login-screen] [org/gnome/login-screen]
banner-message-enable=true banner-message-enable=true
banner-message-text="{{ rhel9cis_warning_banner | trim | replace("\n", "\\n") }}" banner-message-text="{{ rhel9cis_warning_banner }}"

View file

@ -4,7 +4,4 @@
{% if rhel9cis_rule_3_1_1 and not rhel9cis_ipv6_required %} {% if rhel9cis_rule_3_1_1 and not rhel9cis_ipv6_required %}
net.ipv6.conf.all.disable_ipv6 = 1 net.ipv6.conf.all.disable_ipv6 = 1
net.ipv6.conf.default.disable_ipv6 = 1 net.ipv6.conf.default.disable_ipv6 = 1
{% for interface in ansible_interfaces %}
net.ipv6.conf.{{ interface }}.disable_ipv6 = 1
{% endfor %}
{% endif %} {% endif %}