4
0
Fork 0

Merge pull request #18 from ansible-lockdown/updates

logic, idempotency, auditd, sysctl improvements
This commit is contained in:
uk-bolly 2022-09-24 09:43:43 +01:00 committed by GitHub
commit 5098beec03
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
65 changed files with 801 additions and 461 deletions

View file

@ -1,6 +1,9 @@
parseable: true
quiet: true
skip_list:
- 'schema'
- 'no-changed-when'
- 'fqcn-builtins'
- '204'
- '305'
- '303'

View file

@ -8,7 +8,7 @@ environment = "lockdown_github_repo_workflow"
// Matching pair name found in AWS for keypairs PEM key
ami_key_pair_name = "github_actions"
private_key = "'.ssh/github_actions.pem'"
private_key = ".ssh/github_actions.pem"
main_vpc_cidr = "172.22.0.0/24"
public_subnets = "172.22.0.128/26"
private_subnets = "172.22.0.192/26"

View file

@ -81,18 +81,9 @@ jobs:
working-directory: .github/workflows
run: cat hosts.yml
# Centos 7 images take a while to come up insert sleep or playbook fails
# Aws deployments taking a while to come up insert sleep or playbook fails
- name: Check if test os is rhel7
working-directory: .github/workflows
id: test_os
run: >-
echo "::set-output name=RHEL7::$(
grep -c RHEL7 OS.tfvars
)"
- name: if RHEL7 - Sleep for 60 seconds
#if: steps.test_os.outputs.RHEL7 >= 1
- name: Sleep for 60 seconds
run: sleep 60s
shell: bash
@ -117,4 +108,4 @@ jobs:
env:
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
run: terraform destroy -var-file "github_vars.tfvars" -var-file "OS.tfvars" --auto-approve -input=false
run: terraform destroy -var-file "github_vars.tfvars" -var-file "OS.tfvars" --auto-approve -input=false

View file

@ -2,22 +2,34 @@
ignore: |
tests/
molecule/
.github/
.gitlab-ci.yml
*molecule.yml
extends: default
rules:
indentation:
# Requiring 4 space indentation
spaces: 4
# Requiring consistent indentation within a file, either indented or not
indent-sequences: consistent
truthy: disable
braces:
max-spaces-inside: 1
level: error
brackets:
max-spaces-inside: 1
level: error
line-length: disable
indentation:
# Requiring 4 space indentation
spaces: 4
# Requiring consistent indentation within a file, either indented or not
indent-sequences: consistent
truthy: disable
braces:
max-spaces-inside: 1
level: error
brackets:
max-spaces-inside: 1
level: error
indentation:
indent-sequences: consistent
level: error
line-length: disable
key-duplicates: enable
new-line-at-end-of-file: enable
new-lines:
type: unix
trailing-spaces: enable
truthy:
allowed-values: ['true', 'false']
check-keys: false

View file

@ -1,5 +1,33 @@
# Changes to rhel9CIS
## 0.4
- Added assertion that ansible_user has password set for rule 5.3.4
- RockyLinux now supported - release since initial branches
- gpg check updates
- audit out dir now /opt
- lint updates and improvements
- workflow updates and improvements moved to rocky image
- selinux regexp improvements
- warning summary now at end of play
- advanced auditd options to exclude users in POST section
- Issues fixed thanks to fgierlinger
- [#21](https://github.com/ansible-lockdown/RHEL9-CIS/issues/21)
- [#22](https://github.com/ansible-lockdown/RHEL9-CIS/issues/22)
## 0.3
- update to auditd template
- uses facts and template new variable
- update_audit_template (default false)
- sysctl template updates and idempotency improvements
- container discovery usage improvements
- 3.4.1.5 discovery improvement
- 5.6.1.4 discovery improvement
- logrotate process logrotate.timer
- tidy up become:
- logic improvements
## 0.2
- not all controls work with rhel8 releases any longer

View file

@ -1,6 +1,6 @@
# Development Only
## RHEL 9 CIS (predicted) - ALPHA - CIS baselines or OS not yet GA
## RHEL 9 CIS (predicted) - Beta - CIS baselines or OS not yet GA
## Testing if you have access to the RH developer branches
@ -17,7 +17,7 @@ Based on [CIS RedHat Enterprise Linux 8 Benchmark v2.0.0. - 02-23-2022 ](https:/
## Join us
On our [Discord Server](https://discord.gg/JFxpSgPFEJ) to ask questions, discuss features, or just chat with other Ansible-Lockdown users
On our [Discord Server](https://discord.io/ansible-lockdown) to ask questions, discuss features, or just chat with other Ansible-Lockdown users
## Caution(s)
@ -49,7 +49,9 @@ Refer to [RHEL9-CIS-Audit](https://github.com/ansible-lockdown/RHEL9-CIS-Audit).
## Requirements
RHEL 9 - Other versions are not supported.
RHEL 9
Almalinux 9
Rocky 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.)

View file

@ -369,7 +369,6 @@ rhel9cis_rh_sub_password: password
# RedHat Satellite Subscription items
rhel9cis_rhnsd_required: false
# 1.4.2 Bootloader password
rhel9cis_bootloader_password_hash: 'grub.pbkdf2.sha512.changethispassword'
rhel9cis_bootloader_password: random
@ -460,6 +459,11 @@ rhel9cis_tftp_client: false
## Section3 vars
## Sysctl
sysctl_update: false
flush_ipv4_route: false
flush_ipv6_route: false
### Firewall Service - either firewalld, iptables, or nftables
#### Some control allow for services to be removed or masked
#### The options are under each heading
@ -498,6 +502,12 @@ rhel9cis_audit_back_log_limit: 8192
# The max_log_file parameter should be based on your sites policy
rhel9cis_max_log_file_size: 10
### 4.1.3.x audit template
update_audit_template: false
## Advanced option found in auditd post
allow_auditd_uid_user_exclusions: false
## Preferred method of logging
## Whether rsyslog or journald preferred method for local logging
## Affects rsyslog cis 4.2.1.3 and journald cis 4.2.2.5
@ -633,8 +643,8 @@ audit_run_script_environment:
### Goss binary settings ###
goss_version:
release: v0.3.16
checksum: 'sha256:827e354b48f93bce933f5efcd1f00dc82569c42a179cf2d384b040d8a80bfbfb'
release: v0.3.18
checksum: 'sha256:432308ebca0caf8165d45bd27e3262126aad9d15572ac8cb3149b3c91f75aace'
audit_bin_path: /usr/local/bin/
audit_bin: "{{ audit_bin_path }}goss"
audit_format: json
@ -651,7 +661,7 @@ copy_goss_from_path: /some/accessible/path
## managed by the control audit_content
# git
audit_file_git: "https://github.com/ansible-lockdown/{{ benchmark }}-Audit.git"
audit_git_version: main
audit_git_version: devel
# copy:
audit_local_copy: "some path to copy from"
@ -659,12 +669,9 @@ audit_local_copy: "some path to copy from"
# get_url:
audit_files_url: "some url maybe s3?"
# Where the goss audit configuration will be stored
audit_files: "/var/tmp/{{ benchmark }}-Audit/"
## Goss configuration information
# Where the goss configs and outputs are stored
audit_out_dir: '/var/tmp'
audit_out_dir: '/opt'
audit_conf_dir: "{{ audit_out_dir }}/{{ benchmark }}-Audit/"
pre_audit_outfile: "{{ audit_out_dir }}/{{ ansible_hostname }}_pre_scan_{{ ansible_date_time.epoch }}.{{ audit_format }}"
post_audit_outfile: "{{ audit_out_dir }}/{{ ansible_hostname }}_post_scan_{{ ansible_date_time.epoch }}.{{ audit_format }}"

View file

@ -1,14 +1,23 @@
---
# handlers file for RHEL9-CIS
- name: reload sysctl
shell: sysctl --system
args:
warn: false
when:
- sysctl_updated.changed
- name: sysctl flush ipv4 route table
become: true
sysctl:
name: net.ipv4.route.flush
value: '1'
sysctl_set: true
ignore_errors: true
when: ansible_virtualization_type != "docker"
ignore_errors: true # noqa ignore-errors
when:
- flush_ipv4_route
- not system_is_container
tags:
- skip_ansible_lint
@ -18,35 +27,9 @@
name: net.ipv6.route.flush
value: '1'
sysctl_set: true
when: ansible_virtualization_type != "docker"
- name: update sysctl
template:
src: "etc/sysctl.d/{{ item }}.j2"
dest: "/etc/sysctl.d/{{ item }}"
owner: root
group: root
mode: 0600
notify: reload sysctl
with_items:
- 60-kernel_sysctl.conf
- 60-disable_ipv6.conf
- 60-netipv4_sysctl.conf
- 60-netipv6_sysctl.conf
when:
- ansible_virtualization_type != "docker"
- "'procps-ng' in ansible_facts.packages"
- name: reload sysctl
sysctl:
name: net.ipv4.route.flush
value: '1'
state: present
reload: true
ignoreerrors: true
when:
- ansible_virtualization_type != "docker"
- "'systemd' in ansible_facts.packages"
- flush_ipv6_route
- not system_is_container
- name: systemd restart tmp.mount
become: true
@ -72,53 +55,30 @@
warn: false
- name: restart firewalld
become: true
service:
name: firewalld
state: restarted
- name: restart sshd
become: true
service:
name: sshd
state: restarted
- name: restart postfix
become: true
service:
name: postfix
state: restarted
- name: reload dconf
become: true
shell: dconf update
args:
warn: false
- name: update auditd
template:
src: audit/99_auditd.rules.j2
dest: /etc/audit/rules.d/99_auditd.rules
owner: root
group: root
mode: 0600
notify: restart auditd
- name: restart auditd
shell: /sbin/service auditd restart
changed_when: false
check_mode: false
failed_when: false
args:
warn: false
tags:
- skip_ansible_lint
- name: grub2cfg
shell: "grub2-mkconfig -o /boot/grub2/grub.cfg"
args:
warn: false
ignore_errors: True
ignore_errors: true # noqa ignore-errors
tags:
- skip_ansible_lint
@ -142,6 +102,27 @@
systemd:
daemon-reload: true
## Auditd tasks note order for handlers to run
- name: auditd_immutable_check
shell: grep -c "^-e 2" /etc/audit/rules.d/99_auditd.rules
changed_when: false
register: auditd_immutable_check
- name: audit_immutable_fact
debug:
msg: "Reboot required for auditd to apply new rules as immutable set"
notify: change_requires_reboot
when:
- auditd_immutable_check.stdout == '1'
- name: restart auditd
shell: service auditd restart
args:
warn: false
tags:
- skip_ansible_lint
- name: change_requires_reboot
set_fact:
change_requires_reboot: true

View file

@ -1,7 +1,6 @@
---
- hosts: all
become: true
roles:
- role: "{{ playbook_dir }}"

View file

@ -22,7 +22,7 @@
- get_goss_file == 'copy'
- name: install git if not present
package:
package:
name: git
state: present
register: git_installed

26
tasks/auditd.yml Normal file
View file

@ -0,0 +1,26 @@
---
- name: POST | AUDITD | Apply auditd template will for section 4.1.3 - only required rules will be added
template:
src: audit/99_auditd.rules.j2
dest: /etc/audit/rules.d/99_auditd.rules
owner: root
group: root
mode: 0600
register: audit_rules_updated
notify:
- auditd_immutable_check
- audit_immutable_fact
- restart auditd
- name: POST | Set up auditd user logging exceptions
template:
src: audit/98_auditd_exception.rules.j2
dest: /etc/audit/rules.d/98_auditd_exceptions.rules
owner: root
group: root
mode: 0600
notify: restart auditd
when:
- allow_auditd_uid_user_exclusions
- rhel9cis_auditd_uid_exclude | length > 0

View file

@ -20,6 +20,28 @@
tags:
- always
- name: "Check password set for {{ ansible_user }}"
block:
- name: Capture current password state of "{{ ansible_user }}"
shell: "grep {{ ansible_user }} /etc/shadow | awk -F: '{print $2}'"
changed_when: false
failed_when: false
check_mode: false
register: ansible_user_password_set
- name: "Assert that password set for {{ ansible_user }} and account not locked"
assert:
that: ansible_user_password_set.stdout | length != 0 and ansible_user_password_set.stdout != "!!"
fail_msg: "You have {{ sudo_password_rule }} enabled but the user = {{ ansible_user }} has no password set - It can break access"
success_msg: "You a password set for the {{ ansible_user }}"
vars:
sudo_password_rule: rhel9cis_rule_5_3_4
when:
- rhel9cis_rule_5_3_4
- not system_is_ec2
tags:
- user_passwd
- name: Setup rules if container
block:
- name: Discover and set container variable if required
@ -123,49 +145,49 @@
- name: run Section 1 tasks
import_tasks: section_1/main.yml
become: true
when: rhel9cis_section1
tags:
- rhel9cis_section1
- name: run Section 2 tasks
import_tasks: section_2/main.yml
become: true
when: rhel9cis_section2
tags:
- rhel9cis_section2
- name: run Section 3 tasks
import_tasks: section_3/main.yml
become: true
when: rhel9cis_section3
tags:
- rhel9cis_section3
- name: run Section 4 tasks
import_tasks: section_4/main.yml
become: true
when: rhel9cis_section4
tags:
- rhel9cis_section4
- name: run Section 5 tasks
import_tasks: section_5/main.yml
become: true
when: rhel9cis_section5
tags:
- rhel9cis_section5
- name: run Section 6 tasks
import_tasks: section_6/main.yml
become: true
when: rhel9cis_section6
tags:
- rhel9cis_section6
- name: run auditd logic
import_tasks: auditd.yml
when:
- update_audit_template
tags:
- always
- name: run post remediation tasks
import_tasks: post.yml
become: true
tags:
- post_tasks
- always
@ -180,3 +202,10 @@
msg: "{{ audit_results.split('\n') }}"
when:
- run_audit
- name: If Warnings found Output count and control IDs affected
debug:
msg: "You have {{ warn_count }} Warning(s) that require investigating that are related to the following benchmark ID(s) {{ control_number }}"
when: warn_count != 0
tags:
- always

View file

@ -12,57 +12,24 @@
tags:
- always
- name: trigger update sysctl
shell: /bin/true
args:
warn: false
changed_when: true
check_mode: false
notify: update sysctl
- name: update sysctl
template:
src: "etc/sysctl.d/{{ item }}.j2"
dest: "/etc/sysctl.d/{{ item }}"
owner: root
group: root
mode: 0600
register: sysctl_updated
notify: reload sysctl
with_items:
- 60-kernel_sysctl.conf
- 60-disable_ipv6.conf
- 60-netipv4_sysctl.conf
- 60-netipv6_sysctl.conf
when:
- rhel9cis_rule_3_1_1 or
rhel9cis_rule_3_1_2 or
rhel9cis_rule_3_1_3 or
rhel9cis_rule_3_2_1 or
rhel9cis_rule_3_2_2 or
rhel9cis_rule_3_3_1 or
rhel9cis_rule_3_3_2 or
rhel9cis_rule_3_3_3 or
rhel9cis_rule_3_3_4 or
rhel9cis_rule_3_3_5 or
rhel9cis_rule_3_3_6 or
rhel9cis_rule_3_3_7 or
rhel9cis_rule_3_3_8 or
rhel9cis_rule_3_3_9
tags:
- sysctl
- name: trigger update auditd
shell: /bin/true
args:
warn: false
notify: update auditd
changed_when: true
check_mode: false
when:
- rhel9cis_rule_4_1_1_1 or
rhel9cis_rule_4_1_1_2 or
rhel9cis_rule_4_1_1_3 or
rhel9cis_rule_4_1_2_1 or
rhel9cis_rule_4_1_2_2 or
rhel9cis_rule_4_1_2_3 or
rhel9cis_rule_4_1_3 or
rhel9cis_rule_4_1_4 or
rhel9cis_rule_4_1_5 or
rhel9cis_rule_4_1_6 or
rhel9cis_rule_4_1_7 or
rhel9cis_rule_4_1_8 or
rhel9cis_rule_4_1_9 or
rhel9cis_rule_4_1_10 or
rhel9cis_rule_4_1_11 or
rhel9cis_rule_4_1_12
tags:
- auditd
- sysctl_update
- not system_is_container
- "'procps-ng' in ansible_facts.packages"
- name: flush handlers
meta: flush_handlers
@ -77,11 +44,20 @@
- name: POST | Warning a reboot required but skip option set
debug:
msg: "Warning! changes have been made that require a reboot to be implemented but skip reboot was set - Can affect compliance check results"
msg: "Warning!! changes have been made that require a reboot to be implemented but skip reboot was set - Can affect compliance check results"
changed_when: true
when:
- change_requires_reboot
- skip_reboot
- name: "POST | Warning a reboot required but skip option set | warning count"
set_fact:
control_number: "{{ control_number }} + [ 'Reboot_required' ]"
warn_count: "{{ warn_count | int + 1 }}"
when:
- change_requires_reboot
- skip_reboot
tags:
- grub
- level1-server

View file

@ -2,7 +2,7 @@
- name: "Post Audit | Run post_remediation {{ benchmark }} audit"
shell: "{{ audit_conf_dir }}/run_audit.sh -v {{ audit_vars_path }} -o {{ post_audit_outfile }} -g {{ group_names }}"
environment: "{{ audit_run_script_environment|default({}) }}"
environment: "{{ audit_run_script_environment | default({}) }}"
changed_when: audit_run_post_remediation.rc == 0
register: audit_run_post_remediation
args:
@ -28,7 +28,7 @@
- name: Capture post-audit result
set_fact:
post_audit_summary: "{{ post_audit.stdout | from_json |json_query(summary) }}"
post_audit_summary: "{{ post_audit.stdout | from_json | json_query(summary) }}"
vars:
summary: 'summary."summary-line"'
when:

View file

@ -33,6 +33,9 @@
get_url:
url: "{{ audit_files_url }}"
dest: "{{ audit_conf_dir }}"
owner: root
group: root
mode: 0755
when:
- audit_content == 'get_url'
@ -70,7 +73,7 @@
- name: "Pre Audit | Run pre_remediation {{ benchmark }} audit"
shell: "{{ audit_conf_dir }}/run_audit.sh -v {{ audit_vars_path }} -o {{ pre_audit_outfile }} -g {{ group_names }}"
environment: "{{ audit_run_script_environment|default({}) }}"
environment: "{{ audit_run_script_environment | default({}) }}"
changed_when: audit_run_pre_remediation.rc == 0
register: audit_run_pre_remediation
args:
@ -87,7 +90,7 @@
- name: Pre Audit | Capture pre-audit result
set_fact:
pre_audit_summary: "{{ pre_audit.stdout | from_json |json_query(summary) }}"
pre_audit_summary: "{{ pre_audit.stdout | from_json | json_query(summary) }}"
vars:
summary: 'summary."summary-line"'
when:

View file

@ -82,6 +82,31 @@
- level1-server
- level1-workstation
- name: "PRELIM | Ensure python3-libselinux is installed"
package:
name: python3-libselinux
state: present
when:
- '"python3-libselinux" not in ansible_facts.packages'
- name: "PRELIM | Set facts based on boot type"
block:
- name: "PRELIM | Check whether machine is UEFI-based"
stat:
path: /sys/firmware/efi
register: rhel_09_efi_boot
- name: "PRELIM | AUDIT | set legacy boot and grub path | Bios"
set_fact:
rhel9cis_legacy_boot: true
grub2_path: /etc/grub2.cfg
when: not rhel_09_efi_boot.stat.exists
- name: "PRELIM | set grub fact | UEFI"
set_fact:
grub2_path: /etc/grub2-efi.cfg
when: rhel_09_efi_boot.stat.exists
- name: "PRELIM | Section 4.1 | Configure System Accounting (auditd)"
package:
name: audit
@ -191,7 +216,9 @@
min_int_uid: "{{ uid_min_id.stdout }}"
max_int_uid: "{{ uid_max_id.stdout }}"
min_int_gid: "{{ gid_min_id.stdout }}"
- debug:
- name: Output of uid findings
debug:
msg: "{{ min_int_uid }} {{ max_int_uid }}"
when:

View file

@ -7,14 +7,14 @@
path: /etc/modprobe.d/CIS.conf
regexp: "^(#)?install cramfs(\\s|$)"
line: "install cramfs /bin/true"
create: yes
create: true
mode: 0600
- name: "1.1.1.1 | PATCH | Ensure mounting of cramfs filesystems is disabled | Disable cramfs"
modprobe:
name: cramfs
state: absent
when: ansible_connection != 'docker'
when: not system_is_container
when:
- rhel9cis_rule_1_1_1_1
tags:
@ -32,14 +32,14 @@
path: /etc/modprobe.d/CIS.conf
regexp: "^(#)?install squashfs(\\s|$)"
line: "install squashfs /bin/true"
create: yes
create: true
mode: 0600
- name: "1.1.1.2 | PATCH | Ensure mounting of squashfs filesystems is disabled | Disable squashfs"
modprobe:
name: squashfs
state: absent
when: ansible_connection != 'docker'
when: not system_is_container
when:
- rhel9cis_rule_1_1_1_2
tags:
@ -57,14 +57,14 @@
path: /etc/modprobe.d/CIS.conf
regexp: "^(#)?install udf(\\s|$)"
line: "install udf /bin/true"
create: yes
create: true
mode: 0600
- name: "1.1.1.3 | PATCH | Ensure mounting of udf filesystems is disable | Disable udf"
modprobe:
name: udf
state: absent
when: ansible_connection != 'docker'
when: not system_is_container
when:
- rhel9cis_rule_1_1_1_3
tags:

View file

@ -1,11 +1,30 @@
---
- name: "1.1.2.1 | PATCH | Ensure /tmp is a separate partition"
debug:
msg: "Warning! /tmp is not mounted on a separate partition"
block:
- name: "1.1.2.1 | PATCH | Ensure /tmp is a separate partition | Absent"
debug:
msg: "Warning!! /tmp is not mounted on a separate partition"
when:
- required_mount not in mount_names
- name: "1.1.2.1 | PATCH | Ensure /tmp is a separate partition | Warn Count"
set_fact:
control_number: "{{ control_number }} + [ 'rule_1.1.2.1' ]"
warn_count: "{{ warn_count | int + 1 }}"
when:
- required_mount not in mount_names
- name: "1.1.3.1 | AUDIT | Ensure separate partition exists for /var | Present"
debug:
msg: "Congratulations: {{ required_mount }} exists."
register: var_mount_present
when:
- required_mount in mount_names
vars:
required_mount: '/tmp'
when:
- rhel9cis_rule_1_1_2_1
- ansible_mounts | selectattr('mount', 'match', '^/tmp$') | list | length == 0
tags:
- level1-server
- level1-workstation
@ -68,7 +87,6 @@
tags:
- level1-server
- level1-workstation
- scored
- patch
- mounts
- rule_1.1.2.1

View file

@ -4,12 +4,19 @@
block:
- name: "1.1.3.1 | AUDIT | Ensure separate partition exists for /var | Absent"
debug:
msg: "Warning! {{ required_mount }} doesn't exist. This is a manual task"
msg: "Warning!! {{ required_mount }} doesn't exist. This is a manual task"
register: var_mount_absent
changed_when: var_mount_absent.skipped is undefined
when:
- required_mount not in mount_names
- name: "1.1.3.1 | AUDIT | Ensure separate partition exists for /var | Warn Count"
set_fact:
control_number: "{{ control_number }} + [ 'rule_1.1.3.1' ]"
warn_count: "{{ warn_count | int + 1 }}"
when:
- required_mount not in mount_names
- name: "1.1.3.1 | AUDIT | Ensure separate partition exists for /var | Present"
debug:
msg: "Congratulations: {{ required_mount }} exists."
@ -38,7 +45,7 @@
src: "{{ item.device }}"
fstype: "{{ item.fstype }}"
state: present
opts: defaults,{% if rhel9cis_rule_1_1_3_2 %}nodev,{% endif %}{% if rhel9cis_rule_1_1_3_3 %}noexec,{% endif %}{% if rhel9cis_rule_1_1_3_4 %}nosuid{% endif %}
opts: defaults,{% if rhel9cis_rule_1_1_3_3 %}noexec,{% endif %}{% if rhel9cis_rule_1_1_3_2 %}nodev,{% endif %}{% if rhel9cis_rule_1_1_3_4 %}nosuid{% endif %}
with_items:
- "{{ ansible_mounts }}"
loop_control:

View file

@ -5,12 +5,19 @@
block:
- name: "1.1.4.1 | AUDIT | Ensure separate partition exists for /var/tmp | Absent"
debug:
msg: "Warning! {{ required_mount }} doesn't exist. This is a manual task"
msg: "Warning!! {{ required_mount }} doesn't exist. This is a manual task"
register: var_tmp_mount_absent
changed_when: var_tmp_mount_absent.skipped is undefined
when:
- required_mount not in mount_names
- name: "1.1.4.1 | AUDIT | Ensure separate partition exists for /var/tmp | Warn Count"
set_fact:
control_number: "{{ control_number }} + [ 'rule_1.1.4.1' ]"
warn_count: "{{ warn_count | int + 1 }}"
when:
- required_mount not in mount_names
- name: "1.1.4.1 | AUDIT | Ensure separate partition exists for /var/tmp | Present"
debug:
msg: "Congratulations: {{ required_mount }} exists."
@ -39,7 +46,7 @@
src: "{{ item.device }}"
fstype: "{{ item.fstype }}"
state: present
opts: defaults,{% if rhel9cis_rule_1_1_4_2 %}noexec,{% endif %}{% if rhel9cis_rule_1_1_4_3 %}nosuid,{% endif %}{% if rhel9cis_rule_1_1_4_4 %}nodev{% endif %}
opts: defaults,{% if rhel9cis_rule_1_1_4_2 %}noexec,{% endif %}{% if rhel9cis_rule_1_1_4_4 %}nodev,{% endif %}{% if rhel9cis_rule_1_1_4_3 %}nosuid{% endif %}
with_items:
- "{{ ansible_mounts }}"
loop_control:

View file

@ -4,11 +4,19 @@
block:
- name: "1.1.5.1 | AUDIT | Ensure separate partition exists for /var/log | Absent"
debug:
msg: "Warning! {{ required_mount }} doesn't exist. This is a manual task"
msg: "Warning!! {{ required_mount }} doesn't exist. This is a manual task"
register: var_log_mount_absent
changed_when: var_log_mount_absent.skipped is undefined
when:
- required_mount not in mount_names
- name: "1.1.5.1 | AUDIT | Ensure separate partition exists for /var/log | Warn Count"
set_fact:
control_number: "{{ control_number }} + [ 'rule_1.1.5.1' ]"
warn_count: "{{ warn_count | int + 1 }}"
when:
- required_mount not in mount_names
- name: "1.1.5.1 | AUDIT | Ensure separate partition exists for /var/log | Present"
debug:
msg: "Congratulations: {{ required_mount }} exists."
@ -37,7 +45,7 @@
src: "{{ item.device }}"
fstype: "{{ item.fstype }}"
state: present
opts: defaults,{% if rhel9cis_rule_1_1_5_2 %}nodev,{% endif %}{% if rhel9cis_rule_1_1_5_3 %}noexec,{% endif %}{% if rhel9cis_rule_1_1_5_4 %}nosuid{% endif %}
opts: defaults,{% if rhel9cis_rule_1_1_5_3 %}noexec,{% endif %}{% if rhel9cis_rule_1_1_5_2 %}nodev,{% endif %}{% if rhel9cis_rule_1_1_5_4 %}nosuid{% endif %}
with_items:
- "{{ ansible_mounts }}"
loop_control:

View file

@ -4,11 +4,19 @@
block:
- name: "1.1.6.1 | AUDIT | Ensure separate partition exists for /var/log/audit | Absent"
debug:
msg: "Warning! {{ required_mount }} doesn't exist. This is a manual task"
msg: "Warning!! {{ required_mount }} doesn't exist. This is a manual task"
register: var_log_audit_mount_absent
changed_when: var_log_audit_mount_absent.skipped is undefined
when:
- required_mount not in mount_names
- name: "1.1.6.1 | AUDIT | Ensure separate partition exists for /var/log/audit | Warn Count"
set_fact:
control_number: "{{ control_number }} + [ 'rule_1.1.6.1' ]"
warn_count: "{{ warn_count | int + 1 }}"
when:
- required_mount not in mount_names
- name: "1.1.6.1 | AUDIT | Ensure separate partition exists for /var/log/audit | Present"
debug:
msg: "Congratulations: {{ required_mount }} exists."

View file

@ -4,11 +4,19 @@
block:
- name: "1.1.7.1 | AUDIT | Ensure separate partition exists for /home | Absent"
debug:
msg: "Warning! {{ required_mount }} doesn't exist. This is a manual task"
msg: "Warning!! {{ required_mount }} doesn't exist. This is a manual task"
register: home_mount_absent
changed_when: home_mount_absent.skipped is undefined
when:
- required_mount not in mount_names
- name: "1.1.7.1 | AUDIT | Ensure separate partition exists for /home | Warn Count"
set_fact:
control_number: "{{ control_number }} + [ 'rule_1.1.7.1' ]"
warn_count: "{{ warn_count | int + 1 }}"
when:
- required_mount not in mount_names
- name: "1.1.7.1 | AUDIT | Ensure separate partition exists for /home | Present"
debug:
msg: "Congratulations: {{ required_mount }} exists."

View file

@ -13,7 +13,7 @@
shell: mount -l | grep -E '\s/dev/shm\s'
changed_when: false
failed_when: false
check_mode: no
check_mode: false
register: rhel9cis_1_1_8_x_dev_shm_status
- name: |
@ -25,7 +25,7 @@
src: tmpfs
fstype: tmpfs
state: mounted
opts: defaults,{% if rhel9cis_rule_1_1_8_1 %}nodev,{% endif %}{% if rhel9cis_rule_1_1_8_2 %}noexec,{% endif %}{% if rhel9cis_rule_1_1_8_3 %}nosuid{% endif %}
opts: defaults,{% if rhel9cis_rule_1_1_8_2 %}noexec,{% endif %}{% if rhel9cis_rule_1_1_8_1 %}nodev,{% endif %}{% if rhel9cis_rule_1_1_8_3 %}nosuid{% endif %}
when: "'dev/shm' in rhel9cis_1_1_8_x_dev_shm_status.stdout"
notify: change_requires_reboot
when:

View file

@ -3,7 +3,7 @@
- name: "1.1.9 | PATCH | Disable Automounting"
service:
name: autofs
enabled: no
enabled: false
when:
- not rhel9cis_allow_autofs
- "'autofs' in ansible_facts.packages"
@ -24,7 +24,7 @@
path: /etc/modprobe.d/CIS.conf
regexp: "^(#)?install usb-storage(\\s|$)"
line: "install usb-storage /bin/true"
create: yes
create: true
owner: root
group: root
mode: 0600

View file

@ -20,12 +20,38 @@
- skip_ansible_lint # Added as no_log still errors on ansuible-lint
- name: "1.2.2 | AUDIT | Ensure GPG keys are configured"
shell: "PKG=`rpm -qf {{ rpm_gpg_key }}` && rpm -q --queryformat \"%{PACKAGER} %{SIGPGP:pgpsig}\\n\" \"${PKG}\" | grep \"^{{ rpm_packager }}.*Key.ID.{{ rpm_key }}\""
changed_when: false
block:
- name: "1.2.2 | AUDIT | Ensure GPG keys are configured | list installed pubkey keys"
shell: "rpm -qa | grep {{ os_gpg_key_pubkey_name }}"
changed_when: false
failed_when: false
register: os_installed_pub_keys
- name: "1.2.2 | AUDIT | Ensure GPG keys are configured | Query found keys"
shell: "rpm -q --queryformat \"%{PACKAGER} %{VERSION}\\n\" {{ os_gpg_key_pubkey_name }} | grep \"{{ os_gpg_key_pubkey_content }}\""
changed_when: false
failed_when: false
register: os_gpg_key_check
when: os_installed_pub_keys.rc == 0
- name: "1.2.2 | AUDIT | Ensure GPG keys are configured | expected keys pass"
debug:
msg: "Congratulations !! - The installed gpg keys match expected values"
when:
- os_installed_pub_keys.rc == 0
- os_gpg_key_check.rc == 0
- name: "1.2.2 | AUDIT | Ensure GPG keys are configured | expected keys fail"
fail:
msg: Installed GPG Keys do not meet expected values or keys installed that are not expected
when:
- os_installed_pub_keys.rc == 1 or
os_gpg_key_check.rc == 1
when:
- rhel9cis_rule_1_2_2
- ansible_distribution == "RedHat" or
ansible_distribution == "Rocky"
ansible_distribution == "Rocky" or
ansible_distribution == "AlmaLinux"
tags:
- level1-server
- level1-workstation
@ -45,7 +71,7 @@
- name: "1.2.3 | PATCH | Ensure gpgcheck is globally activated | Update yum.repos"
replace:
name: "{{ item.path }}"
regexp: '^gpgcheck\s+=\s+0'
regexp: "^gpgcheck=0"
replace: "gpgcheck=1"
with_items:
- "{{ yum_repos.files }}"
@ -67,15 +93,20 @@
changed_when: false
failed_when: false
register: dnf_configured
check_mode: no
check_mode: false
args:
warn: false
- name: "1.2.4 | AUDIT | Ensure package manager repositories are configured | Display repo list"
debug:
msg:
- "Warning! Below are the configured repos. Please review and make sure all align with site policy"
- "Warning!! Below are the configured repos. Please review and make sure all align with site policy"
- "{{ dnf_configured.stdout_lines }}"
- name: "1.2.4 | AUDIT | Ensure package manager repositories are configured | Warn Count"
set_fact:
control_number: "{{ control_number }} + ['rule_1.2.4']"
warn_count: "{{ warn_count | int + 1 }}"
when:
- rhel9cis_rule_1_2_4
tags:

View file

@ -58,7 +58,7 @@
path: /etc/systemd/system/rescue.service.d/00-require-auth.conf
regexp: '^ExecStart='
line: "ExecStart=-/usr/lib/systemd/systemd-sulogin-shell rescue"
create: yes
create: true
owner: root
group: root
mode: 0644

View file

@ -32,10 +32,13 @@
- rule_1.5.2
- name: "1.5.3 | PATCH | Ensure address space layout randomization (ASLR) is enabled"
debug:
msg: "Control being set via Handler 'update sysctl' which writes to /etc/sysctl.d/60-kernel_sysctl.conf"
notify:
- update sysctl
block:
- name: "1.5.3 | PATCH | Ensure address space layout randomization (ASLR) is enabled"
set_fact:
sysctl_update: true
- name: "1.5.3 | PATCH | Ensure address space layout randomization (ASLR) is enabled"
debug:
msg: "Control being set via Handler 'update sysctl' which writes to /etc/sysctl.d/60-kernel_sysctl.conf"
when:
- rhel9cis_rule_1_5_3
tags:

View file

@ -16,10 +16,10 @@
- name: "1.6.1.2 | PATCH | Ensure SELinux is not disabled in bootloader configuration"
replace:
dest: /etc/default/grub
regexp: '(selinux|enforcing)\s*=(\s0|0).*'
regexp: 'selinux=0'
replace: ''
register: selinux_grub_patch
ignore_errors: yes
ignore_errors: true # noqa ignore-errors
notify: grub2cfg
when:
- rhel9cis_rule_1_6_1_2
@ -78,7 +78,13 @@
- name: "1.6.1.5 | AUDIT | Ensure no unconfined services exist | Message on unconfined services"
debug:
msg: "Warning! You have unconfined services: {{ rhelcis_1_6_1_5_unconf_services.stdout_lines }}"
msg: "Warning!! You have unconfined services: {{ rhelcis_1_6_1_5_unconf_services.stdout_lines }}"
when: rhelcis_1_6_1_5_unconf_services.stdout | length > 0
- name: "1.6.1.5 | AUDIT | Ensure no unconfined services exist | warning count"
set_fact:
control_number: "{{ control_number }} + [ 'rule_1.6.1.5' ]"
warn_count: "{{ warn_count | int + 1 }}"
when: rhelcis_1_6_1_5_unconf_services.stdout | length > 0
when:
- rhel9cis_rule_1_6_1_5

View file

@ -21,7 +21,7 @@
regexp: "{{ item.regexp }}"
line: "{{ item.line }}"
state: present
create: yes
create: true
owner: root
group: root
mode: 0644
@ -50,7 +50,7 @@
path: "{{ item.file }}"
regexp: "{{ item.regexp }}"
line: "{{ item.line }}"
create: yes
create: true
owner: root
group: root
mode: 0644
@ -93,7 +93,10 @@
path: /etc/dconf/db/local.d/00-media-automount
regexp: "{{ item.regex }}"
line: "{{ item.line }}"
create: yes
create: true
owner: root
group: root
mode: 0644
notify: reload dconf
with_items:
- { regex: '\[org\/gnome\/desktop\/media-handling\]', line: '[org/gnome/desktop/media-handling]' }

View file

@ -29,7 +29,7 @@
path: /etc/sysconfig/chronyd
regexp: "^(#)?OPTIONS"
line: "OPTIONS=\"-u chrony\""
create: yes
create: true
mode: 0644
when:
- rhel9cis_rule_2_1_2

View file

@ -6,15 +6,20 @@
shell: systemctl list-units --type=service
changed_when: false
failed_when: false
check_mode: no
check_mode: false
register: rhel9cis_2_4_services
- name: "2.4 | AUDIT | Ensure nonessential services are removed or masked | Display list of services"
debug:
msg:
- "Warning! Below are the list of services, both active and inactive"
- "Warning!! Below are the list of services, both active and inactive"
- "Please review to make sure all are essential"
- "{{ rhel9cis_2_4_services.stdout_lines }}"
- name: "2.4 | AUDIT | Ensure nonessential services are removed or masked | Warn Count"
set_fact:
control_number: "{{ control_number }} + ['rule_2.4']"
warn_count: "{{ warn_count | int + 1 }}"
when:
- rhel9cis_rule_2_4
tags:

View file

@ -3,11 +3,15 @@
# The CIS Control wants IPv6 disabled if not in use.
# We are using the rhel9cis_ipv6_required to specify if you have IPv6 in use
- name: "3.1.1 | PATCH | Verify if IPv6 is enabled on the system"
debug:
msg: "Control being set via Handler 'update sysctl' which writes to /etc/sysctl.d/60-disable_ipv6.conf"
notify:
- update sysctl
- sysctl flush ipv6 route table
block:
- name: "3.1.1 | PATCH | Verify if IPv6 is enabled on the system"
set_fact:
sysctl_update: true
flush_ipv6_route: true
- name: "3.1.1 | PATCH | Verify if IPv6 is enabled on the system"
debug:
msg: "Control being set via Handler 'update sysctl' which writes to /etc/sysctl.d/60-disable_ipv6.conf"
when:
- not rhel9cis_ipv6_required
- rhel9cis_rule_3_1_1
@ -64,9 +68,9 @@
command: rpm -q NetworkManager
changed_when: false
failed_when: false
check_mode: no
check_mode: false
args:
warn: no
warn: false
register: rhel_08_nmcli_available
- name: "3.1.4 | AUDIT | Ensure wireless interfaces are disabled | Check if wifi is enabled"

View file

@ -2,19 +2,25 @@
- name: "3.2.1 | PATCH | Ensure IP forwarding is disabled"
block:
- name: "3.2.1 | PATCH | Ensure IP forwarding is disabled | Disable IPv4 forwarding | Set Fact"
set_fact:
sysctl_update: true
flush_ipv4_route: true
- name: "3.2.1 | PATCH | Ensure IP forwarding is disabled | Disable IPv4 forwarding"
debug:
msg: "Control being set via Handler 'update sysctl' which writes to /etc/sysctl.d/60-netipv4_sysctl.conf"
notify:
- update sysctl
- sysctl flush ipv4 route table
- name: "3.2.1 | PATCH | Ensure IP forwarding is disabled | Disable IPv6 forwarding"
debug:
msg: "Control being set via Handler 'update sysctl' which writes to /etc/sysctl.d/60-netipv6_sysctl.conf"
notify:
- update sysctl
- sysctl flush ipv6 route table
- name: "3.2.1 | PATCH | Ensure IP forwarding is disabled | IPv6"
block:
- name: "3.2.1 | PATCH | Ensure IP forwarding is disabled | Disable IPv6 forwarding | Set Fact"
set_fact:
flush_ipv6_route: true
- name: "3.2.1 | PATCH | Ensure IP forwarding is disabled | Disable IPv6 forwarding"
debug:
msg: "Control being set via Handler 'update sysctl' which writes to /etc/sysctl.d/60-netipv6_sysctl.conf"
when: rhel9cis_ipv6_required
when:
- not rhel9cis_is_router
@ -28,11 +34,14 @@
- rule_3.2.1
- name: "3.2.2 | PATCH | Ensure packet redirect sending is disabled"
debug:
msg: "Control being set via Handler 'update sysctl' which writes to /etc/sysctl.d/60-netipv4_sysctl.conf"
notify:
- update sysctl
- sysctl flush ipv4 route table
block:
- name: "3.2.2 | PATCH | Ensure packet redirect sending is disabled | Set Fact"
set_fact:
sysctl_update: true
flush_ipv4_route: true
- name: "3.2.2 | PATCH | Ensure packet redirect sending is disabled"
debug:
msg: "Control being set via Handler 'update sysctl' which writes to /etc/sysctl.d/60-netipv4_sysctl.conf"
when:
- not rhel9cis_is_router
- rhel9cis_rule_3_2_2

View file

@ -2,19 +2,23 @@
- name: "3.3.1 | PATCH | Ensure source routed packets are not accepted"
block:
- name: "3.3.1 | PATCH | Ensure source routed packets are not accepted"
- name: "3.3.1 | PATCH | Ensure source routed packets are not accepted | IPv4 | Set Fact"
set_fact:
sysctl_update: true
flush_ipv4_route: true
- name: "3.3.1 | PATCH | Ensure source routed packets are not accepted | IPv4"
debug:
msg: "Control being set via Handler 'update sysctl' which writes to /etc/sysctl.d/60-netipv4_sysctl.conf"
notify:
- update sysctl
- sysctl flush ipv4 route table
- name: "3.3.1 | PATCH | Ensure source routed packets are not accepted"
debug:
msg: "Control being set via Handler 'update sysctl' which writes to /etc/sysctl.d/60-netipv6_sysctl.conf"
notify:
- sysctl flush ipv6 route table
- update sysctl
- name: "3.3.1 | PATCH | Ensure source routed packets are not accepted | IPv6"
block:
- name: "3.3.1 | PATCH | Ensure source routed packets are not accepted | IPv6 | Set Fact"
set_fact:
flush_ipv6_route: true
- name: "3.3.1 | PATCH | Ensure source routed packets are not accepted | IPv6"
debug:
msg: "Control being set via Handler 'update sysctl' which writes to /etc/sysctl.d/60-netipv6_sysctl.conf"
when: rhel9cis_ipv6_required
when:
- rhel9cis_rule_3_3_1
@ -27,19 +31,24 @@
- name: "3.3.2 | PATCH | Ensure ICMP redirects are not accepted"
block:
- name: "3.3.2 | PATCH | Ensure ICMP redirects are not accepted"
- name: "3.3.2 | PATCH | Ensure ICMP redirects are not accepted | IPv4 | Set Fact"
set_fact:
sysctl_update: true
flush_ipv4_route: true
- name: "3.3.2 | PATCH | Ensure ICMP redirects are not accepted | IPv4"
debug:
msg: "Control being set via Handler 'update sysctl' which writes to /etc/sysctl.d/60-netipv4_sysctl.conf"
notify:
- update sysctl
- sysctl flush ipv4 route table
- name: "3.3.2 | PATCH | Ensure ICMP redirects are not accepted"
debug:
msg: "Control being set via Handler 'update sysctl' which writes to /etc/sysctl.d/60-netipv6_sysctl.conf"
notify:
- sysctl flush ipv6 route table
- update sysctl
- name: "3.3.2 | PATCH | Ensure ICMP redirects are not accepted | IPv6"
block:
- name: "3.3.2 | PATCH | Ensure ICMP redirects are not accepted | IPv6 | Set Fact"
set_fact:
flush_ipv6_route: true
- name: "3.3.2 | PATCH | Ensure ICMP redirects are not accepted | IPv6"
debug:
msg: "Control being set via Handler 'update sysctl' which writes to /etc/sysctl.d/60-netipv6_sysctl.conf"
when: rhel9cis_ipv6_required
when:
- rhel9cis_rule_3_3_2
@ -51,9 +60,15 @@
- rule_3.3.2
- name: "3.3.3 | PATCH | Ensure secure ICMP redirects are not accepted"
debug:
msg: "Control being set via Handler 'update sysctl' which writes to /etc/sysctl.d/60-netipv4_sysctl.conf"
notify: update sysctl
block:
- name: "3.3.3 | PATCH | Ensure secure ICMP redirects are not accepted | Set Fact"
set_fact:
sysctl_update: true
flush_ipv4_route: true
- name: "3.3.3 | PATCH | Ensure secure ICMP redirects are not accepted"
debug:
msg: "Control being set via Handler 'update sysctl' which writes to /etc/sysctl.d/60-netipv4_sysctl.conf"
when:
- rhel9cis_rule_3_3_3
tags:
@ -64,9 +79,15 @@
- rule_3.3.3
- name: "3.3.4 | PATCH | Ensure suspicious packets are logged"
debug:
msg: "Control being set via Handler 'update sysctl' which writes to /etc/sysctl.d/60-netipv4_sysctl.conf"
notify: update sysctl
block:
- name: "3.3.4 | PATCH | Ensure suspicious packets are logged | Set Fact"
set_fact:
sysctl_update: true
flush_ipv4_route: true
- name: "3.3.4 | PATCH | Ensure suspicious packets are logged"
debug:
msg: "Control being set via Handler 'update sysctl' which writes to /etc/sysctl.d/60-netipv4_sysctl.conf"
when:
- rhel9cis_rule_3_3_4
tags:
@ -77,9 +98,15 @@
- rule_3.3.4
- name: "3.3.5 | PATCH | Ensure broadcast ICMP requests are ignored"
debug:
msg: "Control being set via Handler 'update sysctl' which writes to /etc/sysctl.d/60-netipv4_sysctl.conf"
notify: update sysctl
block:
- name: "3.3.5 | PATCH | Ensure broadcast ICMP requests are ignored | Set Fact"
set_fact:
sysctl_update: true
flush_ipv4_route: true
- name: 3.3.5 | PATCH | Ensure broadcast ICMP requests are ignored"
debug:
msg: "Control being set via Handler 'update sysctl' which writes to /etc/sysctl.d/60-netipv4_sysctl.conf"
when:
- rhel9cis_rule_3_3_5
tags:
@ -90,9 +117,15 @@
- rule_3.3.5
- name: "3.3.6 | PATCH | Ensure bogus ICMP responses are ignored"
debug:
msg: "Control being set via Handler 'update sysctl' which writes to /etc/sysctl.d/60-netipv4_sysctl.conf"
notify: update sysctl
block:
- name: "3.3.6 | PATCH | Ensure bogus ICMP responses are ignored | Set Fact"
set_fact:
sysctl_update: true
flush_ipv4_route: true
- name: "3.3.6 | PATCH | Ensure bogus ICMP responses are ignored"
debug:
msg: "Control being set via Handler 'update sysctl' which writes to /etc/sysctl.d/60-netipv4_sysctl.conf"
when:
- rhel9cis_rule_3_3_6
tags:
@ -103,9 +136,15 @@
- rule_3.3.6
- name: "3.3.7 | PATCH | Ensure Reverse Path Filtering is enabled"
debug:
msg: "Control being set via Handler 'update sysctl' which writes to /etc/sysctl.d/60-netipv4_sysctl.conf"
notify: update sysctl
block:
- name: "3.3.7 | PATCH | Ensure Reverse Path Filtering is enabled | Set Fact"
set_fact:
sysctl_update: true
flush_ipv4_route: true
- name: "3.3.7 | PATCH | Ensure Reverse Path Filtering is enabled"
debug:
msg: "Control being set via Handler 'update sysctl' which writes to /etc/sysctl.d/60-netipv4_sysctl.conf"
when:
- rhel9cis_rule_3_3_7
tags:
@ -116,9 +155,15 @@
- rule_3.3.7
- name: "3.3.8 | PATCH | Ensure TCP SYN Cookies is enabled"
debug:
msg: "Control being set via Handler 'update sysctl' which writes to /etc/sysctl.d/60-netipv4_sysctl.conf"
notify: update sysctl
block:
- name: "3.3.8 | PATCH | Ensure TCP SYN Cookies is enabled | Set Fact"
set_fact:
sysctl_update: true
flush_ipv4_route: true
- name: "3.3.8 | PATCH | Ensure TCP SYN Cookies is enabled"
debug:
msg: "Control being set via Handler 'update sysctl' which writes to /etc/sysctl.d/60-netipv4_sysctl.conf"
when:
- rhel9cis_rule_3_3_8
tags:
@ -130,20 +175,14 @@
- name: "3.3.9 | PATCH | Ensure IPv6 router advertisements are not accepted"
block:
- name: "3.3.9 | PATCH | Ensure IPv6 router advertisements are not accepted"
debug:
msg: "Control being set via Handler 'update sysctl' which writes to /etc/sysctl.d/60-netipv4_sysctl.conf"
notify:
- update sysctl
- sysctl flush ipv4 route table
- name: "3.3.9 | PATCH | Ensure IPv6 router advertisements are not accepted | IPv6 | Set Fact"
set_fact:
sysctl_update: true
flush_ipv6_route: true
- name: "3.3.9 | PATCH | Ensure IPv6 router advertisements are not accepted"
- name: "3.3.9 | PATCH | Ensure IPv6 router advertisements are not accepted | IPv6"
debug:
msg: "Control being set via Handler 'update sysctl' which writes to /etc/sysctl.d/60-netipv6_sysctl"
notify:
- sysctl flush ipv6 route table
- update sysctl
when: rhel9cis_ipv6_required
when:
- rhel9cis_ipv6_required
- rhel9cis_rule_3_3_9

View file

@ -49,7 +49,7 @@
systemd:
name: nftables
state: stopped
masked: yes
masked: true
when:
- rhel9cis_firewalld_nftables_state == "masked"
@ -73,7 +73,7 @@
systemd:
name: firewalld
state: started
enabled: yes
enabled: true
when:
- rhel9cis_rule_3_4_1_4
tags:
@ -83,10 +83,20 @@
- patch
- firewalld
- rule_3_4_1_4
- name: "3.4.1.5 | PATCH | Ensure firewalld default zone is set"
command: firewall-cmd --set-default-zone="{{ rhel9cis_default_zone }}"
block:
- name: "3.4.1.5 | AUDIT | Ensure firewalld default zone is set"
shell: "firewall-cmd --get-default-zone | grep {{ rhel9cis_default_zone }}"
changed_when: false
failed_when: ( firewalld_zone_set.rc not in [ 0, 1 ] )
register: firewalld_zone_set
- name: "3.4.1.5 | AUDIT | Ensure firewalld default zone is set"
command: firewall-cmd --set-default-zone="{{ rhel9cis_default_zone }}"
when:
- firewalld_zone_set.rc != 0
when:
- rhel9cis_firewall == "firewalld"
- rhel9cis_rule_3_4_1_5
tags:
- level1-server
@ -102,7 +112,7 @@
shell: "nmcli -t connection show | awk -F: '{ if($4){print $4} }' | while read INT; do firewall-cmd --get-active-zones | grep -B1 $INT; done"
changed_when: false
failed_when: false
check_mode: no
check_mode: false
register: rhel9cis_3_4_1_6_interfacepolicy
- name: "3.4.1.6 | AUDIT | Ensure network interfaces are assigned to appropriate zone | Get list of interfaces and polocies | Show the interface to policy"
@ -125,7 +135,7 @@
shell: "firewall-cmd --get-active-zones | awk '!/:/ {print $1}' | while read ZN; do firewall-cmd --list-all --zone=$ZN; done"
changed_when: false
failed_when: false
check_mode: no
check_mode: false
register: rhel9cis_3_4_1_7_servicesport
- name: "3.4.1.7 | AUDIT | Ensure firewalld drops unnecessary services and ports | Show services and ports"

View file

@ -5,6 +5,7 @@
name: nftables
state: present
when:
- rhel9cis_firewall == "nftables"
- rhel9cis_rule_3_4_2_1
tags:
- level1-server
@ -17,22 +18,11 @@
# The control allows the service it be masked or not installed
# We have chosen not installed
- name: "3.4.2.2 | PATCH | Ensure firewalld is either not installed or masked with nftables"
block:
- name: "3.4.2.2 | PATCH | Ensure firewalld is either not installed or masked with nftables | mask service"
systemd:
name: firewalld
masked: true
state: stopped
when:
- rhel9cis_nftables_firewalld_state == "masked"
- name: "3.4.2.2 | PATCH | Ensure firewalld is either not installed or masked with nftables | pkg removed"
package:
name: firewalld
state: absent
when:
- rhel9cis_nftables_firewalld_state == "absent"
package:
name: firewalld
state: absent
when:
- rhel9cis_firewall == "nftables"
- rhel9cis_rule_3_4_2_2
tags:
- level1-server
@ -49,7 +39,7 @@
name: "{{ item }}"
enabled: false
masked: true
ignore_errors: true
ignore_errors: true # noqa ignore-errors
with_items:
- iptables
- ip6tables
@ -59,6 +49,7 @@
name: iptables-service
state: absent
when:
- rhel9cis_firewall == "nftables"
- rhel9cis_rule_3_4_2_3
tags:
- level1-server
@ -105,17 +96,26 @@
- name: "3.4.2.5 | AUDIT | Ensure an nftables table exists | Alert on no tables"
debug:
msg:
- "Warning! You currently have no nft tables, please review your setup"
- "Warning!! You currently have no nft tables, please review your setup"
- 'Use the command "nft create table inet <table name>" to create a new table'
when:
- rhel9cis_3_4_2_5_nft_tables.stdout | length == 0
- not rhel9cis_nft_tables_autonewtable
- name: "3.4.2.5 | AUDIT | Ensure an nftables table exists | Alert on no tables | warning count"
set_fact:
control_number: "{{ control_number }} + [ 'rule_3.4.2.5' ]"
warn_count: "{{ warn_count | int + 1 }}"
when:
- rhel9cis_3_4_2_5_nft_tables.stdout | length == 0
- not rhel9cis_nft_tables_autonewtable
- name: "3.4.2.5 | PATCH | Ensure a table exists | Create table if needed"
command: nft create table inet "{{ rhel9cis_nft_tables_tablename }}"
failed_when: no
failed_when: false
when: rhel9cis_nft_tables_autonewtable
when:
- rhel9cis_firewall == "nftables"
- rhel9cis_rule_3_4_2_5
tags:
- level1-server
@ -159,14 +159,15 @@
- name: "3.4.2.6 | PATCH | Ensure nftables base chains exist | Create chains if needed"
shell: "{{ item }}"
args:
warn: no
failed_when: no
warn: false
failed_when: false
with_items:
- nft create chain inet "{{ rhel9cis_nft_tables_tablename }}" input { type filter hook input priority 0 \; }
- nft create chain inet "{{ rhel9cis_nft_tables_tablename }}" forward { type filter hook forward priority 0 \; }
- nft create chain inet "{{ rhel9cis_nft_tables_tablename }}" output { type filter hook output priority 0 \; }
when: rhel9cis_nft_tables_autochaincreate
when:
- rhel9cis_firewall == "nftables"
- rhel9cis_rule_3_4_2_6
tags:
- level1-server
@ -208,6 +209,7 @@
command: nft add rule inet "{{ rhel9cis_nft_tables_tablename }}" input ip6 saddr ::1 counter drop
when: '"ip6 saddr ::1 counter packets 0 bytes 0 drop" not in rhel9cis_3_4_2_7_ip6saddr.stdout'
when:
- rhel9cis_firewall == "nftables"
- rhel9cis_rule_3_4_2_7
tags:
- level1-server
@ -255,6 +257,7 @@
command: nft add rule inet "{{ rhel9cis_nft_tables_tablename }}" output ip protocol icmp ct state new,related,established accept
when: '"ip protocol icmp ct state established,related,new accept" not in rhel9cis_3_4_2_8_outconnectionrule.stdout'
when:
- rhel9cis_firewall == "nftables"
- rhel9cis_rule_3_4_2_8
tags:
- level1-server
@ -306,6 +309,7 @@
command: nft chain inet "{{ rhel9cis_nft_tables_tablename }}" output { policy drop \; }
when: '"type filter hook output priority 0; policy drop;" not in rhel9cis_3_4_2_9_outputpolicy.stdout'
when:
- rhel9cis_firewall == "nftables"
- rhel9cis_rule_3_4_2_9
tags:
- level1-server
@ -318,8 +322,9 @@
- name: "3.4.2.10 | PATCH | Ensure nftables service is enabled"
service:
name: nftables
enabled: yes
enabled: true
when:
- rhel9cis_firewall == "nftables"
- rhel9cis_rule_3_4_2_10
tags:
- level1-server
@ -332,9 +337,11 @@
- name: "3.4.2.11 | PATCH | Ensure nftables rules are permanent"
lineinfile:
path: /etc/sysconfig/nftables.conf
state: present
insertafter: EOF
line: include "/etc/nftables/inet-{{ rhel9cis_nft_tables_tablename }}"
when:
- rhel9cis_firewall == "nftables"
- rhel9cis_rule_3_4_2_11
tags:
- level1-server

View file

@ -27,10 +27,9 @@
service:
name: auditd
state: started
enabled: yes
enabled: true
when:
- rhel9cis_rule_4_1_1_2
- ansible_connection != 'docker'
tags:
- level2-server
- level2-workstation
@ -45,7 +44,7 @@
shell: grep 'GRUB_CMDLINE_LINUX=' /etc/default/grub | sed 's/.$//'
changed_when: false
failed_when: false
check_mode: no
check_mode: false
register: rhel9cis_4_1_1_3_grub_cmdline_linux
- name: "4.1.1.3 | PATCH | Ensure auditing for processes that start prior to auditd is enabled | Replace existing setting"
@ -80,7 +79,7 @@
shell: grep 'GRUB_CMDLINE_LINUX=' /etc/default/grub | sed 's/.$//'
changed_when: false
failed_when: false
check_mode: no
check_mode: false
register: rhel9cis_4_1_1_4_grub_cmdline_linux
- name: "4.1.1.4 | PATCH | Ensure audit_backlog_limit is sufficient | Replace existing setting"

View file

@ -1,10 +1,9 @@
---
# All changes selected are managed by the POST audit and handlers to update
- name: "4.1.3.1 | PATCH | Ensure changes to system administration scope (sudoers) is collected"
debug:
msg: "Control being set via Handler 'update auditd' which writes to /etc/audit.d/99_auditd.rules"
changed_when: true
notify: update auditd
set_fact:
update_audit_template: true
when:
- rhel9cis_rule_4_1_3_1
tags:
@ -15,11 +14,10 @@
- auditd
- rule_4.1.3.1
# All changes selected are managed by the POST audit and handlers to update
- name: "4.1.3.2 | PATCH | Ensure actions as another user are always logged"
debug:
msg: "Control being set via Handler 'update auditd' which writes to /etc/audit.d/99_auditd.rules"
changed_when: true
notify: update auditd
set_fact:
update_audit_template: true
when:
- rhel9cis_rule_4_1_3_2
tags:
@ -30,11 +28,10 @@
- auditd
- rule_4.1.3.2
# All changes selected are managed by the POST audit and handlers to update
- name: "4.1.3.3 | PATCH | Ensure events that modify the sudo log file are collected"
debug:
msg: "Control being set via Handler 'update auditd' which writes to /etc/audit.d/99_auditd.rules"
changed_when: true
notify: update auditd
set_fact:
update_audit_template: true
when:
- rhel9cis_rule_4_1_3_3
tags:
@ -45,11 +42,10 @@
- auditd
- rule_4.1.3.3
# All changes selected are managed by the POST audit and handlers to update
- name: "4.1.3.4 | PATCH | Ensure events that modify date and time information are collected"
debug:
msg: "Control being set via Handler 'update auditd' which writes to /etc/audit.d/99_auditd.rules"
changed_when: true
notify: update auditd
set_fact:
update_audit_template: true
when:
- rhel9cis_rule_4_1_3_4
tags:
@ -60,11 +56,10 @@
- auditd
- rule_4.1.3.4
# All changes selected are managed by the POST audit and handlers to update
- name: "4.1.3.5 | PATCH | Ensure events that modify the system's network environment are collected"
debug:
msg: "Control being set via Handler 'update auditd' which writes to /etc/audit.d/99_auditd.rules"
changed_when: true
notify: update auditd
set_fact:
update_audit_template: true
when:
- rhel9cis_rule_4_1_3_5
tags:
@ -75,19 +70,19 @@
- auditd
- rule_4.1.3.5
# All changes selected are managed by the POST audit and handlers to update
- name: "4.1.3.6 | PATCH | Ensure use of privileged commands is collected"
block:
- name: "4.1.3.6 | PATCH | Ensure use of privileged commands is collected"
shell: for i in $(df | grep '^/dev' | awk '{ print $NF }'); do find $i -xdev -type f -perm -4000 -o -type f -perm -2000 2>/dev/null; done
changed_when: false
failed_when: false
check_mode: no
check_mode: false
register: priv_procs
- name: "4.1.3.6 | PATCH | Ensure use of privileged commands is collected"
debug:
msg: "Control being set via Handler 'update auditd' which writes to /etc/audit.d/99_auditd.rules"
changed_when: true
set_fact:
update_audit_template: true
notify: update auditd
when:
- rhel9cis_rule_4_1_3_6
@ -99,11 +94,10 @@
- auditd
- rule_4.1.3.6
# All changes selected are managed by the POST audit and handlers to update
- name: "4.1.3.7 | PATCH | Ensure unsuccessful unauthorized file access attempts are collected"
debug:
msg: "Control being set via Handler 'update auditd' which writes to /etc/audit.d/99_auditd.rules"
changed_when: true
notify: update auditd
set_fact:
update_audit_template: true
when:
- rhel9cis_rule_4_1_3_7
tags:
@ -114,11 +108,10 @@
- auditd
- rule_4.1.3_7
# All changes selected are managed by the POST audit and handlers to update
- name: "4.1.3.8 | PATCH | Ensure events that modify user/group information are collected"
debug:
msg: "Control being set via Handler 'update auditd' which writes to /etc/audit.d/99_auditd.rules"
changed_when: true
notify: update auditd
set_fact:
update_audit_template: true
when:
- rhel9cis_rule_4_1_3_8
tags:
@ -129,11 +122,10 @@
- auditd
- rule_4.1.3.8
# All changes selected are managed by the POST audit and handlers to update
- name: "4.1.3.9 | PATCH | Ensure discretionary access control permission modification events are collected"
debug:
msg: "Control being set via Handler 'update auditd' which writes to /etc/audit.d/99_auditd.rules"
changed_when: true
notify: update auditd
set_fact:
update_audit_template: true
when:
- rhel9cis_rule_4_1_3_9
tags:
@ -144,11 +136,10 @@
- auditd
- rule_4.1.3.9
# All changes selected are managed by the POST audit and handlers to update
- name: "4.1.3.10 | PATCH | Ensure successful file system mounts are collected"
debug:
msg: "Control being set via Handler 'update auditd' which writes to /etc/audit.d/99_auditd.rules"
changed_when: true
notify: update auditd
set_fact:
update_audit_template: true
when:
- rhel9cis_rule_4_1_3_10
tags:
@ -159,11 +150,10 @@
- auditd
- rule_4.1.3.10
# All changes selected are managed by the POST audit and handlers to update
- name: "4.1.3.11 | PATCH | Ensure session initiation information is collected"
debug:
msg: "Control being set via Handler 'update auditd' which writes to /etc/audit.d/99_auditd.rules"
changed_when: true
notify: update auditd
set_fact:
update_audit_template: true
when:
- rhel9cis_rule_4_1_3_11
tags:
@ -174,11 +164,10 @@
- auditd
- rule_4.1.3.11
# All changes selected are managed by the POST audit and handlers to update
- name: "4.1.3.12 | PATCH | Ensure login and logout events are collected"
debug:
msg: "Control being set via Handler 'update auditd' which writes to /etc/audit.d/99_auditd.rules"
changed_when: true
notify: update auditd
set_fact:
update_audit_template: true
when:
- rhel9cis_rule_4_1_3_12
tags:
@ -189,11 +178,10 @@
- auditd
- rule_4.1.3.12
# All changes selected are managed by the POST audit and handlers to update
- name: "4.1.3.13 | PATCH | Ensure file deletion events by users are collected"
debug:
msg: "Control being set via Handler 'update auditd' which writes to /etc/audit.d/99_auditd.rules"
changed_when: true
notify: update auditd
set_fact:
update_audit_template: true
when:
- rhel9cis_rule_4_1_3_13
tags:
@ -203,11 +191,10 @@
- patch
- rule_4.1.3.13
# All changes selected are managed by the POST audit and handlers to update
- name: "4.1.3.14 | PATCH | Ensure events that modify the system's Mandatory Access Controls are collected"
debug:
msg: "Control being set via Handler 'update auditd' which writes to /etc/audit.d/99_auditd.rules"
changed_when: true
notify: update auditd
set_fact:
update_audit_template: true
when:
- rhel9cis_rule_4_1_3_14
tags:
@ -218,11 +205,10 @@
- auditd
- rule_4.1.3.14
# All changes selected are managed by the POST audit and handlers to update
- name: "4.1.3.15 | PATCH | Ensure successful and unsuccessful attempts to use the chcon command are recorded"
debug:
msg: "Control being set via Handler 'update auditd' which writes to /etc/audit.d/99_auditd.rules"
changed_when: true
notify: update auditd
set_fact:
update_audit_template: true
when:
- rhel9cis_rule_4_1_3_15
tags:
@ -233,11 +219,10 @@
- auditd
- rule_4.1.3.15
# All changes selected are managed by the POST audit and handlers to update
- name: "4.1.3.16 | PATCH | Ensure successful and unsuccessful attempts to use the setfacl command are recorded"
debug:
msg: "Control being set via Handler 'update auditd' which writes to /etc/audit.d/99_auditd.rules"
changed_when: true
notify: update auditd
set_fact:
update_audit_template: true
when:
- rhel9cis_rule_4_1_3_16
tags:
@ -248,11 +233,10 @@
- auditd
- rule_4.1.3.16
# All changes selected are managed by the POST audit and handlers to update
- name: "4.1.3.17 | PATCH | Ensure successful and unsuccessful attempts to use the chacl command are recorded"
debug:
msg: "Control being set via Handler 'update auditd' which writes to /etc/audit.d/99_auditd.rules"
changed_when: true
notify: update auditd
set_fact:
update_audit_template: true
when:
- rhel9cis_rule_4_1_3_17
tags:
@ -263,11 +247,10 @@
- auditd
- rule_4.1.3.17
# All changes selected are managed by the POST audit and handlers to update
- name: "4.1.3.18 | PATCH | Ensure successful and unsuccessful attempts to use the usermod command are recorded"
debug:
msg: "Control being set via Handler 'update auditd' which writes to /etc/audit.d/99_auditd.rules"
changed_when: true
notify: update auditd
set_fact:
update_audit_template: true
when:
- rhel9cis_rule_4_1_3_18
tags:
@ -278,11 +261,10 @@
- auditd
- rule_4.1.3.18
# All changes selected are managed by the POST audit and handlers to update
- name: "4.1.3.19 | PATCH | Ensure kernel module loading and unloading is collected"
debug:
msg: "Control being set via Handler 'update auditd' which writes to /etc/audit.d/99_auditd.rules"
changed_when: true
notify: update auditd
set_fact:
update_audit_template: true
when:
- rhel9cis_rule_4_1_3_19
tags:
@ -293,11 +275,10 @@
- auditd
- rule_4.1.3.19
# All changes selected are managed by the POST audit and handlers to update
- name: "4.1.3.20 | PATCH | Ensure the audit configuration is immutable"
debug:
msg: "Control being set via Handler 'update auditd' which writes to /etc/audit.d/99_auditd.rules"
changed_when: true
notify: update auditd
set_fact:
update_audit_template: true
when:
- rhel9cis_rule_4_1_3_20
tags:
@ -321,3 +302,10 @@
- patch
- auditd
- rule_4.1.3.21
- name: Auditd | 4.1.3 | Auditd controls updated
debug:
msg: "Auditd Controls handled in POST using template - updating /etc/auditd/rules.d/99_auditd.rules"
changed_when: false
when:
- update_audit_template

View file

@ -18,7 +18,7 @@
- name: "4.2.1.2 | PATCH | Ensure rsyslog Service is enabled"
service:
name: rsyslog
enabled: yes
enabled: true
when:
- rhel9cis_rule_4_2_1_2
tags:
@ -65,10 +65,9 @@
block:
- name: "4.2.1.5 | AUDIT | Ensure logging is configured | rsyslog current config message out"
command: cat /etc/rsyslog.conf
become: yes
changed_when: false
failed_when: no
check_mode: no
failed_when: false
check_mode: false
register: rhel_08_4_2_1_5_audit
- name: "4.2.1.5 | AUDIT | Ensure logging is configured | rsyslog current config message out"

View file

@ -39,8 +39,9 @@
systemd:
name: systemd-journal-upload
state: started
enabled: yes
enabled: true
when:
- rhel9cis_system_is_log_server
- rhel9cis_rule_4_2_2_1_3
tags:
- level1-server
@ -52,11 +53,12 @@
- name: "4.2.2.1.4 | PATCH | Ensure journald is not configured to recieve logs from a remote client"
systemd:
name: systemd-journal-remote
name: systemd-journal-remote.socket
state: stopped
enabled: no
masked: yes
enabled: false
masked: true
when:
- not rhel9cis_system_is_log_server
- rhel9cis_rule_4_2_2_1_4
tags:
- level1-server
@ -72,7 +74,7 @@
systemd:
name: systemd-journald
state: started
enabled: yes
enabled: true
- name: "4.2.2.2 | AUDIT | Ensure journald service is enabled | Capture status"
shell: systemctl is-enabled systemd-journald.service
@ -83,7 +85,13 @@
- name: "4.2.2.2 | AUDIT | Ensure journald service is enabled | Alert on bad status"
debug:
msg:
- "Warning! The status of systemd-journald should be static and it is not. Please investigate"
- "Warning!! The status of systemd-journald should be static and it is not. Please investigate"
when: "'static' not in rhel9cis_4_2_2_2_status.stdout"
- name: "4.2.2.2 | AUDIT | Ensure journald service is enabled | Warn Count"
set_fact:
control_number: "{{ control_number }} + [ 'rule_4.2.2.2' ]"
warn_count: "{{ warn_count | int + 1 }}"
when: "'static' not in rhel9cis_4_2_2_2_status.stdout"
when:
- rhel9cis_rule_4_2_2_2
@ -134,7 +142,6 @@
notify: restart systemd_journal_upload
when:
- rhel9cis_rule_4_2_2_5
- rhel9cis_preferred_log_capture == "journald"
tags:
- level1-server
- level2-workstation
@ -190,9 +197,13 @@
- name: "4.2.2.7 | AUDIT | Ensure journald default file permissions configured | Display file settings"
debug:
msg:
- "Warning! Below are the current default settings for journald, please confirm they align with your site policies"
# - "{{ rhel9cis_4_2_2_7_override_settings.stdout_lines }}"
- "Warning!! Below are the current default settings for journald, please confirm they align with your site policies"
- "{{ (rhel9cis_4_2_2_7_override_status.matched >= 1) | ternary(rhel9cis_4_2_2_7_override_settings.stdout_lines, rhel9cis_4_2_2_7_notoverride_settings.stdout_lines) }}"
- name: "4.2.2.7 | AUDIT | Ensure journald default file permissions configured | Warn Count"
set_fact:
control_number: "{{ control_number }} + [ 'rule_4.2.2.7' ]"
warn_count: "{{ warn_count | int + 1 }}"
when:
- rhel9cis_rule_4_2_2_7
tags:

View file

@ -16,7 +16,7 @@
- name: "4.3.2 | PATCH | Ensure logrotate is running and enabled"
systemd:
name: logrotate
name: logrotate.timer
state: started
enabled: true
when:

View file

@ -17,6 +17,7 @@
- name: "SECTION | 4.2.2 Configure journald"
import_tasks: cis_4.2.2.x.yml
when: rhel9cis_syslog == 'journald'
- name: "SECTION | 4.2.3 | Configure logile perms"
import_tasks: cis_4.2.3.yml

View file

@ -3,7 +3,7 @@
- name: "5.1.1 | PATCH | Ensure cron daemon is enabled"
service:
name: crond
enabled: yes
enabled: true
when:
- rhel9cis_rule_5_1_1
tags:

View file

@ -271,10 +271,21 @@
- rule_5.2.13
- name: "5.2.14 | PATCH | Ensure system-wide crypto policy is not over-ridden"
shell: sed -ri "s/^\s*(CRYPTO_POLICY\s*=.*)$/# \1/" /etc/sysconfig/sshd
args:
warn: no
notify: restart sshd
block:
- name: "5.2.14 | AUDIT | Ensure system-wide crypto policy is not over-ridden"
shell: grep -i '^\s*CRYPTO_POLICY=' /etc/sysconfig/sshd
args:
warn: false
changed_when: false
failed_when: ( ssh_crypto_discovery.rc not in [ 0, 1 ] )
register: ssh_crypto_discovery
- name: "5.2.14 | PATCH | Ensure system-wide crypto policy is not over-ridden"
shell: sed -ri "s/^\s*(CRYPTO_POLICY\s*=.*)$/# \1/" /etc/sysconfig/sshd
args:
warn: false
notify: restart sshd
when: ssh_crypto_discovery.stdout | length > 0
when:
- rhel9cis_rule_5_2_14
tags:

View file

@ -6,7 +6,7 @@
shell: 'authselect current | grep "Profile ID: custom/"'
failed_when: false
changed_when: false
check_mode: no
check_mode: false
register: rhel9cis_5_4_1_profiles
- name: "5.4.1 | AUDIT | Ensure custom authselect profile is used | Show profiles"
@ -18,7 +18,7 @@
- name: "5.4.1 | PATCH | Ensure custom authselect profile is used | Create custom profiles"
shell: authselect create-profile {{ rhel9cis_authselect['custom_profile_name'] }} -b {{ rhel9cis_authselect['default_file_to_copy'] }}
args:
warn: no
warn: false
when: rhel9cis_authselect_custom_profile_create
when:
- rhel9cis_rule_5_4_1
@ -36,7 +36,7 @@
shell: "authselect current | grep with-faillock"
failed_when: false
changed_when: false
check_mode: no
check_mode: false
register: rhel9cis_5_4_2_profiles_faillock
- name: "5.4.2 | AUDIT | Ensure authselect includes with-faillock| Show profiles"
@ -48,7 +48,7 @@
- name: "5.4.2 | PATCH | Ensure authselect includes with-faillock | Create custom profiles"
shell: "authselect select custom/{{ rhel9cis_authselect['custom_profile_name'] }} with-faillock"
args:
warn: no
warn: false
when: rhel9cis_authselect_custom_profile_select
when:
- rhel9cis_rule_5_4_2

View file

@ -51,7 +51,7 @@
shell: useradd -D | grep INACTIVE={{ rhel9cis_inactivelock.lock_days }} | cut -f2 -d=
changed_when: false
failed_when: false
check_mode: no
check_mode: false
register: rhel9cis_5_6_1_4_inactive_settings
- name: "5.6.1.4 | PATCH | Ensure inactive password lock is 30 days or less | Set default inactive setting"
@ -59,9 +59,9 @@
when: rhel9cis_5_6_1_4_inactive_settings.stdout | length == 0
- name: "5.6.1.4 | AUDIT | Ensure inactive password lock is 30 days or less | Getting user list"
shell: 'egrep ^[^:]+:[^\!*] /etc/shadow | cut -d: -f1'
shell: "awk -F: '/^[^#:]+:[^\\!\\*:]*:[^:]*:[^:]*:[^:]*:[^:]*:(\\s*|-1|3[1-9]|[4-9][0-9]|[1-9][0-9][0-9]+):[^:]*:[^:]*\\s*$/ {print $1}' /etc/shadow"
changed_when: false
check_mode: no
check_mode: false
register: rhel_8_5_6_1_4_user_list
- name: "5.6.1.4 | PATCH | Ensure inactive password lock is 30 days or less | Apply Inactive setting to existing accounts"
@ -78,20 +78,20 @@
- password
- rule_5.6.1.4
- name: "5.6.1.5 | PATCH | Ensure all users last password change date is in the past"
- name: "5.6.1.5 | PATCH | Ensure all users last password change date is in the past"
block:
- name: "5.6.1.5 | AUDIT | Ensure all users last password change date is in the past | Get current date in Unix Time"
shell: echo $(($(date --utc --date "$1" +%s)/86400))
changed_when: false
failed_when: false
check_mode: no
check_mode: false
register: rhel9cis_5_6_1_5_currentut
- name: "5.6.1.5 | AUDIT | Ensure all users last password change date is in the past | Get list of users with last changed pw date in the future"
shell: "cat /etc/shadow | awk -F: '{if($3>{{ rhel9cis_5_6_1_5_currentut.stdout }})print$1}'"
changed_when: false
failed_when: false
check_mode: no
check_mode: false
register: rhel9cis_5_6_1_5_user_list
- name: "5.6.1.5 | AUDIT | Ensure all users last password change date is in the past | Alert no pw change in the future exist"
@ -101,7 +101,15 @@
- name: "5.6.1.5 | AUDIT | Ensure all users last password change date is in the past | Alert on accounts with pw change in the future"
debug:
msg: "Warning! The following accounts have the last PW change date in the future: {{ rhel9cis_5_6_1_5_user_list.stdout_lines }}"
msg: "Warning!! The following accounts have the last PW change date in the future: {{ rhel9cis_5_6_1_5_user_list.stdout_lines }}"
when:
- rhel9cis_5_6_1_5_user_list.stdout | length > 0
- not rhel9cis_futurepwchgdate_autofix
- name: "5.6.1.5 | AUDIT | Ensure all users last password change date is in the past | warning count"
set_fact:
control_number: "{{ control_number }} + [ 'rule_5.6.1.5' ]"
warn_count: "{{ warn_count | int + 1 }}"
when:
- rhel9cis_5_6_1_5_user_list.stdout | length > 0
- not rhel9cis_futurepwchgdate_autofix
@ -109,7 +117,7 @@
- name: "5.6.1.5 | PATCH | Ensure all users last password change date is in the past | Fix accounts with pw change in the future"
command: passwd --expire {{ item }}
when:
- rhel9cis_5_6_1_5_user_list | length > 0
- rhel9cis_5_6_1_5_user_list.stdout | length > 0
- rhel9cis_futurepwchgdate_autofix
with_items:
- "{{ rhel9cis_5_6_1_5_user_list.stdout_lines }}"

View file

@ -32,7 +32,7 @@
- item.id != "sync"
- item.id != "root"
- item.id != "nfsnobody"
- min_int_uid | int < item.gid
- item.gid < min_int_uid | int
- item.shell != " /bin/false"
- item.shell != " /usr/sbin/nologin"
loop_control:
@ -49,7 +49,7 @@
- name: "5.6.3 | PATCH | Ensure default user shell timeout is 900 seconds or less"
blockinfile:
create: yes
create: true
mode: 0644
dest: "{{ item.dest }}"
state: "{{ item.state }}"

View file

@ -5,23 +5,31 @@
- name: "6.1.1 | AUDIT | Audit system file permissions | Audit the packages"
shell: rpm -Va --nomtime --nosize --nomd5 --nolinkto
args:
warn: no
warn: false
changed_when: false
failed_when: false
register: rhel9cis_6_1_1_packages_rpm
- name: "6.1.1 | AUDIT | Audit system file permissions | Create list and warning"
block:
- name: "6.1.1 | Audit system file permissions | Add file discrepancy list to system"
- name: "6.1.1 | AUDIT | Audit system file permissions | Add file discrepancy list to system"
copy:
dest: "{{ rhel9cis_rpm_audit_file }}"
content: "{{ rhel9cis_6_1_1_packages_rpm.stdout }}"
owner: root
group: root
mode: 0640
- name: "6.1.1 | AUDIT | Audit system file permissions | Message out alert for package descrepancies"
debug:
msg: |
"Warning! You have some package descrepancies issues.
"Warning!! You have some package descrepancies issues.
The file list can be found in {{ rhel9cis_rpm_audit_file }}"
- name: "6.1.1 | AUDIT | Audit system file permissions | warning count"
set_fact:
control_number: "{{ control_number }} + [ 'rule_6.1.1' ]"
warn_count: "{{ warn_count | int + 1 }}"
when: rhel9cis_6_1_1_packages_rpm.stdout|length > 0
- name: "6.1.1 | AUDIT | Audit system file permissions | Message out no package descrepancies"
@ -41,7 +49,7 @@
- name: "6.1.2 | PATCH | Ensure sticky bit is set on all world-writable directories"
shell: df --local -P | awk {'if (NR!=1) print $6'} | xargs -I '{}' find '{}' -xdev -type d -perm -0002 2>/dev/null | xargs chmod a+t
args:
warn: no
warn: false
changed_when: false
failed_when: false
when:

View file

@ -33,8 +33,14 @@
- name: "6.2.2 | AUDIT | Ensure all groups in /etc/passwd exist in /etc/group | Print warning about users with invalid GIDs missing GID entries in /etc/group"
debug:
msg: "Warning! The following users have non-existent GIDs (Groups): {{ rhel9cis_6_2_2_passwd_gid_check.stdout_lines | join (', ') }}"
when: rhel9cis_6_2_2_passwd_gid_check.stdout | length > 0
msg: "Warning!! The following users have non-existent GIDs (Groups): {{ rhel9cis_6_2_2_passwd_gid_check.stdout_lines | join (', ') }}"
when: rhel9cis_6_2_2_passwd_gid_check.stdout | length >= 1
- name: "6.2.2 | AUDIT | Ensure all groups in /etc/passwd exist in /etc/group | warning count"
set_fact:
control_number: "{{ control_number }} + [ 'rule_6.2.2' ]"
warn_count: "{{ warn_count | int + 1 }}"
when: rhel9cis_6_2_2_passwd_gid_check.stdout | length >= 1
when:
- rhel9cis_rule_6_2_2
tags:
@ -61,8 +67,14 @@
- name: "6.2.3 | AUDIT| Ensure no duplicate UIDs exist | Print warning about users with duplicate UIDs"
debug:
msg: "Warning! The following users have UIDs that are duplicates: {{ rhel9cis_6_2_3_user_uid_check.stdout_lines }}"
when: rhel9cis_6_2_3_user_uid_check.stdout | length > 0
msg: "Warning!! The following users have UIDs that are duplicates: {{ rhel9cis_6_2_3_user_uid_check.stdout_lines }}"
when: rhel9cis_6_2_3_user_uid_check.stdout | length >= 1
- name: "6.2.3 | AUDIT| Ensure no duplicate UIDs exist | warning count"
set_fact:
control_number: "{{ control_number }} + [ 'rule_6.2.3' ]"
warn_count: "{{ warn_count | int + 1 }}"
when: rhel9cis_6_2_3_user_uid_check.stdout | length >= 1
when:
- rhel9cis_rule_6_2_3
tags:
@ -89,8 +101,15 @@
- name: "6.2.4 | AUDIT | Ensure no duplicate GIDs exist | Print warning about users with duplicate GIDs"
debug:
msg: "Warning! The following groups have duplicate GIDs: {{ rhel9cis_6_2_4_user_user_check.stdout_lines }}"
when: rhel9cis_6_2_4_user_user_check.stdout | length > 0
msg: "Warning!! The following groups have duplicate GIDs: {{ rhel9cis_6_2_4_user_user_check.stdout_lines }}"
when: rhel9cis_6_2_4_user_user_check.stdout | length >= 1
- name: "6.2.4 | AUDIT | Ensure no duplicate GIDs exist | warning count"
set_fact:
control_number: "{{ control_number }} + [ 'rule_6.2.4' ]"
warn_count: "{{ warn_count | int + 1 }}"
when: rhel9cis_6_2_4_user_user_check.stdout | length >= 1
when:
- rhel9cis_rule_6_2_4
tags:
@ -117,8 +136,14 @@
- name: "6.2.5 | AUDIT | Ensure no duplicate user names exist | Print warning about users with duplicate User Names"
debug:
msg: "Warning! The following user names are duplicates: {{ rhel9cis_6_2_5_user_username_check.stdout_lines }}"
when: rhel9cis_6_2_5_user_username_check.stdout | length > 0
msg: "Warning!! The following user names are duplicates: {{ rhel9cis_6_2_5_user_username_check.stdout_lines }}"
when: rhel9cis_6_2_5_user_username_check.stdout | length >= 1
- name: "6.2.5 | AUDIT | Ensure no duplicate user names exist | warning count"
set_fact:
control_number: "{{ control_number }} + [ 'rule_6.2.5' ]"
warn_count: "{{ warn_count | int + 1 }}"
when: rhel9cis_6_2_5_user_username_check.stdout | length >= 1
when:
- rhel9cis_rule_6_2_5
tags:
@ -136,18 +161,24 @@
shell: 'getent passwd | cut -d: -f1 | sort -n | uniq -d'
changed_when: false
failed_when: false
check_mode: no
check_mode: false
register: rhel9cis_6_2_6_group_group_check
- name: "6.2.6 | AUDIT | Ensure no duplicate group names exist | Print message that no duplicate groups exist"
debug:
msg: "Good News! There are no duplicate group names in the system"
when: rhel9cis_6_2_6_group_group_check.stdout | length == 0
when: rhel9cis_6_2_6_group_group_check.stdout is defined
- name: "6.2.6 | AUDIT | Ensure no duplicate group names exist | Print warning about users with duplicate group names"
debug:
msg: "Warning! The following group names are duplicates: {{ rhel9cis_6_2_6_group_group_check.stdout_lines }}"
when: rhel9cis_6_2_6_group_group_check.stdout | length > 0
msg: "Warning!! The following group names are duplicates: {{ rhel9cis_6_2_6_group_group_check.stdout_lines }}"
when: rhel9cis_6_2_6_group_group_check.stdout is not defined
- name: "6.2.6 | AUDIT | Ensure no duplicate group names exist | warning count"
set_fact:
control_number: "{{ control_number }} + [ 'rule_6.2.6' ]"
warn_count: "{{ warn_count | int + 1 }}"
when: rhel9cis_6_2_6_group_group_check.stdout is not defined
when:
- rhel9cis_rule_6_2_6
tags:
@ -163,23 +194,23 @@
block:
- name: "6.2.7 | AUDIT | Ensure root PATH Integrity | Determine empty value"
shell: 'echo $PATH | grep ::'
changed_when: False
changed_when: false
failed_when: rhel9cis_6_2_7_path_colon.rc == 0
check_mode: no
check_mode: false
register: rhel9cis_6_2_7_path_colon
- name: "6.2.7 | AUDIT | Ensure root PATH Integrity | Determin colon end"
shell: 'echo $PATH | grep :$'
changed_when: False
changed_when: false
failed_when: rhel9cis_6_2_7_path_colon_end.rc == 0
check_mode: no
check_mode: false
register: rhel9cis_6_2_7_path_colon_end
- name: "6.2.7 | AUDIT | Ensure root PATH Integrity | Determine dot in path"
shell: "/bin/bash --login -c 'env | grep ^PATH=' | sed -e 's/PATH=//' -e 's/::/:/' -e 's/:$//' -e 's/:/\\n/g'"
changed_when: False
changed_when: false
failed_when: '"." in rhel9cis_6_2_7_dot_in_path.stdout_lines'
check_mode: no
check_mode: false
register: rhel9cis_6_2_7_dot_in_path
- name: "6.2.7 | AUDIT | Ensure root PATH Integrity | Alert on empty value, colon end, and dot in path"
@ -230,7 +261,7 @@
stat:
path: "{{ item }}"
register: rhel_08_6_2_9_audit
with_items: "{{ rhel9cis_passwd | selectattr('uid', '>=', min_int_uid | int ) | selectattr('uid', '<', max_int_uid | int ) | map(attribute='dir') | list }}"
with_items: "{{ rhel9cis_passwd | selectattr('uid', '>=', min_int_uid | int ) | selectattr('uid', '<=', max_int_uid | int ) | map(attribute='dir') | list }}"
- name: "6.2.9 | AUDIT | Ensure all users' home directories exist"
command: find -H {{ item.0 | quote }} -not -type l -perm /027
@ -249,7 +280,7 @@
- name: "6.2.9 | PATCH | Ensure all users' home directories exist"
file:
path: "{{ item.0 }}"
recurse: yes
recurse: true
mode: a-st,g-w,o-rwx
register: rhel_08_6_2_9_patch
when:
@ -265,12 +296,13 @@
- name: "6.2.9 | PATCH | Ensure all users' home directories exist"
acl:
path: "{{ item.0 }}"
default: yes
default: true
state: present
recursive: yes
recursive: true
etype: "{{ item.1.etype }}"
permissions: "{{ item.1.mode }}"
when: not system_is_container
when:
- not system_is_container
with_nested:
- "{{ (ansible_check_mode | ternary(rhel_08_6_2_9_patch_audit, rhel_08_6_2_9_patch)).results |
rejectattr('skipped', 'defined') | map(attribute='item') | map('first') | list }}"
@ -299,7 +331,8 @@
loop_control:
label: "{{ rhel9cis_passwd_label }}"
when:
- min_int_uid | int <= item.uid
- item.uid >= min_int_uid | int
- item.id != 'nobody'
- rhel9cis_rule_6_2_10
tags:
- skip_ansible_lint # settings found on 6_2_7
@ -315,7 +348,7 @@
- name: "6.2.11 | AUDIT | Ensure users' home directories permissions are 750 or more restrictive"
stat:
path: "{{ item }}"
with_items: "{{ rhel9cis_passwd | selectattr('uid', '>=', min_int_uid | int ) | selectattr('uid', '<', max_int_uid | int ) | map(attribute='dir') | list }}"
with_items: "{{ rhel9cis_passwd | selectattr('uid', '>=', min_int_uid | int) | selectattr('uid', '<=', max_int_uid | int) | map(attribute='dir') | list }}"
register: rhel_08_6_2_11_audit
- name: "6.2.11 | AUDIT | Ensure users' home directories permissions are 750 or more restrictive"
@ -335,7 +368,7 @@
- name: "6.2.11 | PATCH | Ensure users' home directories permissions are 750 or more restrictive"
file:
path: "{{ item.0 }}"
recurse: yes
recurse: true
mode: a-st,g-w,o-rwx
register: rhel_08_6_2_11_patch
when:
@ -351,12 +384,13 @@
- name: "6.2.11 | PATCH | Ensure users' home directories permissions are 750 or more restrictive"
acl:
path: "{{ item.0 }}"
default: yes
default: true
state: present
recursive: yes
recursive: true
etype: "{{ item.1.etype }}"
permissions: "{{ item.1.mode }}"
when: not system_is_container
when:
- not system_is_container
with_nested:
- "{{ (ansible_check_mode | ternary(rhel_08_6_2_11_patch_audit, rhel_08_6_2_11_patch)).results |
rejectattr('skipped', 'defined') | map(attribute='item') | map('first') | list }}"
@ -427,8 +461,8 @@
- name: "6.2.14 | PATCH | Ensure no users have .forward files"
file:
path: "~{{ item }}/.forward"
state: absent
dest: "~{{ item }}/.forward"
with_items:
- "{{ users.stdout_lines }}"
when:
@ -444,8 +478,8 @@
- name: "6.2.15 | PATCH | Ensure no users have .netrc files"
file:
path: "~{{ item }}/.netrc"
state: absent
dest: "~{{ item }}/.netrc"
with_items:
- "{{ users.stdout_lines }}"
when:
@ -461,8 +495,8 @@
- name: "6.2.16 | PATCH | Ensure no users have .rhosts files"
file:
path: "~{{ item }}/.rhosts"
state: absent
dest: "~{{ item }}/.rhosts"
with_items: "{{ users.stdout_lines }}"
when:
- rhel9cis_rule_6_2_16

View file

@ -1,3 +1,5 @@
## This file is managed by Ansible, YOUR CHANGED WILL BE LOST!
## metadata for benchmark
## metadata for Audit benchmark
@ -157,6 +159,7 @@ rhel9cis_rule_2_3_2: {{ rhel9cis_rule_2_3_2 }}
rhel9cis_rule_2_3_3: {{ rhel9cis_rule_2_3_3 }}
rhel9cis_rule_2_3_4: {{ rhel9cis_rule_2_3_4 }}
rhel9cis_rule_2_3_5: {{ rhel9cis_rule_2_3_5 }}
rhel9cis_rule_2_3_6: {{ rhel9cis_rule_2_3_6 }}
rhel9cis_rule_2_4: true # todo
@ -274,6 +277,7 @@ rhel9cis_rule_5_1_5: {{ rhel9cis_rule_5_1_5 }}
rhel9cis_rule_5_1_6: {{ rhel9cis_rule_5_1_6 }}
rhel9cis_rule_5_1_7: {{ rhel9cis_rule_5_1_7 }}
rhel9cis_rule_5_1_8: {{ rhel9cis_rule_5_1_8 }}
rhel9cis_rule_5_1_9: {{ rhel9cis_rule_5_1_9 }}
# 5.2 Configure SSH Server
rhel9cis_rule_5_2_1: {{ rhel9cis_rule_5_2_1 }}
@ -492,4 +496,4 @@ rhel9cis_pass:
rhel9cis_sugroup: {% if rhel9cis_sugroup is undefined %}wheel{% else %}{{ rhel9cis_sugroup }}{% endif %}
## 5.3.7 sugroup users list
rhel9cis_sugroup_users: {{ rhel9cis_sugroup_users }}
rhel9cis_sugroup_users: {{ rhel9cis_sugroup_users }}

View file

@ -0,0 +1,8 @@
## This file is managed by Ansible, YOUR CHANGES WILL BE LOST!
# This file contains users whose actions are not logged by auditd
{% if allow_auditd_uid_user_exclusions %}
{% for user in rhel9cis_auditd_uid_exclude %}
-a never,user -F uid!={{ user }} -F auid!={{ user }}
{% endfor %}
{% endif %}

View file

@ -1,3 +1,5 @@
## This file is managed by Ansible, YOUR CHANGES WILL BE LOST!
# This template will set all of the auditd configurations via a handler in the role in one task instead of individually
{% if rhel9cis_rule_4_1_3_1 %}
-w /etc/sudoers -p wa -k scope

View file

@ -1,3 +1,5 @@
## This file is managed by Ansible, YOUR CHANGED WILL BE LOST!
# This the default chrony.conf file for the Debian chrony package. After
# editing this file use the command 'invoke-rc.d chrony restart' to make
# your changes take effect. John Hasler <jhasler@debian.org> 1998-2008

View file

@ -1,5 +1,5 @@
# Run AIDE integrity check
# added via ansible-lockdown remediation
## This file is managed by Ansible, YOUR CHANGES WILL BE LOST!
# CIS 1.3.2
{{ rhel9cis_aide_cron['aide_minute'] }} {{ rhel9cis_aide_cron['aide_hour'] }} {{ rhel9cis_aide_cron['aide_month'] }} {{ rhel9cis_aide_cron['aide_weekday'] }} {{ rhel9cis_aide_cron['aide_job'] }}

View file

@ -1,5 +1,6 @@
# Disable usage of protocol {{ item }}
# Set by ansible {{ benchmark }} remediation role
# https://github.com/ansible-lockdown
## This file is managed by Ansible, YOUR CHANGES WILL BE LOST!
install {{ item }} /bin/true
install {{ item }} /bin/true

View file

@ -1,4 +1,4 @@
# Setting added via ansible CIS remediation playbook
## This file is managed by Ansible, YOUR CHANGES WILL BE LOST!
# IPv6 disable
{% if rhel9cis_rule_3_1_1 and rhel9cis_ipv6_required %}

View file

@ -1,4 +1,4 @@
# Setting added via ansible CIS remediation playbook
## This file is managed by Ansible, YOUR CHANGES WILL BE LOST!
{% if rhel9cis_rule_1_5_3 %}

View file

@ -1,4 +1,4 @@
# Setting added via ansible CIS remediation playbook
## This file is managed by Ansible, YOUR CHANGES WILL BE LOST!
# IPv4 Network sysctl
{% if rhel9cis_rule_3_2_1 %}

View file

@ -1,4 +1,4 @@
# Setting added via ansible CIS remediation playbook
## This file is managed by Ansible, YOUR CHANGES WILL BE LOST!
# IPv6 Network sysctl
{% if rhel9cis_ipv6_required %}

View file

@ -7,6 +7,8 @@
# the Free Software Foundation; either version 2.1 of the License, or
# (at your option) any later version.
## This file is managed by Ansible, YOUR CHANGED WILL BE LOST!
[Unit]
Description=Temporary Directory (/tmp)
Documentation=man:hier(7)

View file

@ -1,4 +1,5 @@
---
# OS Specific Settings
rpm_gpg_key: RPM-GPG-KEY-AlmaLinux
os_gpg_key_pubkey_name: gpg-pubkey-b86b3716-61e69f29
os_gpg_key_pubkey_content: "AlmaLinux OS 9 <packager@almalinux.org> b86b3716"

View file

@ -1,6 +1,5 @@
---
# OS Specific Settings
rpm_gpg_key: /etc/pki/rpm-gpg/RPM-GPG-KEY-{{ ansible_distribution|lower }}-release
rpm_packager: "Red Hat, Inc"
rpm_key: "199e2f91fd431d51" # found on https://access.redhat.com/security/team/key/
os_gpg_key_pubkey_name: gpg-pubkey-fd431d51-4ae0493b
os_gpg_key_pubkey_content: "Red Hat, Inc. (release key 2) <security@redhat.com> fd431d51"

View file

@ -1,4 +1,5 @@
---
# OS Specific Settings
rpm_gpg_key: /etc/pki/rpm-gpg/RPM-GPG-KEY-rockyofficial
os_gpg_key_pubkey_name: gpg-pubkey-350d275d-6279464b
os_gpg_key_pubkey_content: "Rocky Enterprise Software Foundation - Release key 2022 <releng@rockylinux.org> 350d275d"

View file

@ -1,8 +1,12 @@
---
# vars file for RHEL9-CIS
min_ansible_version: 2.10
min_ansible_version: 2.9.4
rhel9cis_allowed_crypto_policies:
- 'DEFAULT'
- 'FUTURE'
- 'FIPS'
# Used to control warning summary
control_number: ""
warn_count: 0