refactor(cis): extract hardcoded values to cis_defaults and add _normalize.yml

This commit is contained in:
2026-02-21 01:26:31 +01:00
parent bef15af69f
commit f74ec325ea
8 changed files with 99 additions and 79 deletions

View File

@@ -0,0 +1,4 @@
---
- name: Build cis_cfg from defaults and user overrides
ansible.builtin.set_fact:
cis_cfg: "{{ cis_defaults | combine(cis | default({}), recursive=true) }}"

View File

@@ -3,7 +3,7 @@
ansible.builtin.lineinfile:
path: "/mnt/etc/profile"
regexp: "^(\\s*)umask\\s+\\d+"
line: "umask 027"
line: "umask {{ cis_cfg.umask_profile }}"
# Non-RHEL/non-Debian distros: loop evaluates to [] (intentional skip)
- name: Prevent Login to Accounts With Empty Password

View File

@@ -1,4 +1,7 @@
---
- name: Normalize CIS configuration
ansible.builtin.include_tasks: _normalize.yml
- name: Include CIS hardening tasks
ansible.builtin.include_tasks: "{{ cis_task }}"
loop:

View File

@@ -1,23 +1,8 @@
---
- name: Disable Kernel Modules
vars:
cis_modules_base:
- freevxfs
- jffs2
- hfs
- hfsplus
- cramfs
- udf
- usb-storage
- dccp
- sctp
- rds
- tipc
- firewire-core
- firewire-sbp2
- thunderbolt
cis_modules_squashfs: "{{ [] if os in ['ubuntu', 'ubuntu-lts'] else ['squashfs'] }}"
cis_modules_all: "{{ cis_modules_base + cis_modules_squashfs }}"
cis_modules_all: "{{ cis_cfg.modules_blacklist + cis_modules_squashfs }}"
ansible.builtin.copy:
dest: /mnt/etc/modprobe.d/cis.conf
mode: "0644"

View File

@@ -6,17 +6,17 @@
line: "{{ item.content }}"
loop:
- { path: /mnt/etc/security/limits.conf, regexp: '^\*\s+hard\s+core\s+', content: "* hard core 0" }
- { path: /mnt/etc/security/pwquality.conf, regexp: '^\s*#?\s*minlen\s*=', content: minlen = 14 }
- { path: /mnt/etc/security/pwquality.conf, regexp: '^\s*#?\s*minlen\s*=', content: "minlen = {{ cis_cfg.pwquality_minlen }}" }
- { path: /mnt/etc/security/pwquality.conf, regexp: '^\s*#?\s*dcredit\s*=', content: dcredit = -1 }
- { path: /mnt/etc/security/pwquality.conf, regexp: '^\s*#?\s*ucredit\s*=', content: ucredit = -1 }
- { path: /mnt/etc/security/pwquality.conf, regexp: '^\s*#?\s*ocredit\s*=', content: ocredit = -1 }
- { path: /mnt/etc/security/pwquality.conf, regexp: '^\s*#?\s*lcredit\s*=', content: lcredit = -1 }
- path: '/mnt/etc/{{ "bashrc" if is_rhel else "bash.bashrc" }}'
regexp: '^\s*umask\s+\d+'
content: umask 077
content: "umask {{ cis_cfg.umask }}"
- path: '/mnt/etc/{{ "bashrc" if is_rhel else "bash.bashrc" }}'
regexp: '^\s*(export\s+)?TMOUT='
content: export TMOUT=900
content: "export TMOUT={{ cis_cfg.tmout }}"
- path: '/mnt/{{ "usr/lib/systemd/journald.conf" if is_rhel | bool else "etc/systemd/journald.conf" }}'
regexp: '^\s*#?\s*Storage='
content: Storage=persistent
@@ -36,7 +36,7 @@
}}
regexp: '^\s*auth\s+required\s+pam_faillock\.so'
content: >-
auth required pam_faillock.so onerr=fail audit silent deny=5 unlock_time=900
auth required pam_faillock.so onerr=fail audit silent deny={{ cis_cfg.faillock_deny }} unlock_time={{ cis_cfg.faillock_unlock_time }}
- path: >-
/mnt/etc/{{
"pam.d/common-account"
@@ -55,7 +55,7 @@
}}
regexp: '^\s*password\s+\[success=1.*\]\s+pam_unix\.so'
content: >-
password [success=1 default=ignore] pam_unix.so obscure sha512 remember=5
password [success=1 default=ignore] pam_unix.so obscure sha512 remember={{ cis_cfg.password_remember }}
- { path: /mnt/etc/hosts.deny, regexp: '^ALL:\s*ALL', content: "ALL: ALL" }
- { path: /mnt/etc/hosts.allow, regexp: '^sshd:\s*ALL', content: "sshd: ALL" }
loop_control:

View File

@@ -4,31 +4,7 @@
path: /mnt/etc/ssh/sshd_config
regexp: ^\s*#?{{ item.option }}\s+.*$
line: "{{ item.option }} {{ item.value }}"
loop:
- { option: LogLevel, value: VERBOSE }
- { option: LoginGraceTime, value: "60" }
- { option: PermitRootLogin, value: "no" }
- { option: StrictModes, value: "yes" }
- { option: MaxAuthTries, value: "4" }
- { option: MaxSessions, value: "10" }
- { option: MaxStartups, value: "10:30:60" }
- { option: PubkeyAuthentication, value: "yes" }
- { option: HostbasedAuthentication, value: "no" }
- { option: IgnoreRhosts, value: "yes" }
- { option: PasswordAuthentication, value: "no" }
- { option: PermitEmptyPasswords, value: "no" }
- { option: KerberosAuthentication, value: "no" }
- { option: GSSAPIAuthentication, value: "no" }
- { option: AllowAgentForwarding, value: "no" }
- { option: AllowTcpForwarding, value: "no" }
- { option: KbdInteractiveAuthentication, value: "no" }
- { option: GatewayPorts, value: "no" }
- { option: X11Forwarding, value: "no" }
- { option: PermitUserEnvironment, value: "no" }
- { option: ClientAliveInterval, value: "300" }
- { option: ClientAliveCountMax, value: "1" }
- { option: PermitTunnel, value: "no" }
- { option: Banner, value: /etc/issue.net }
loop: "{{ cis_cfg.sshd_options }}"
loop_control:
label: "{{ item.option }}"

View File

@@ -5,35 +5,6 @@
mode: "0644"
content: |
## CIS Sysctl configurations
fs.suid_dumpable=0
kernel.dmesg_restrict=1
kernel.kptr_restrict=2
kernel.perf_event_paranoid=3
kernel.unprivileged_bpf_disabled=1
kernel.yama.ptrace_scope=2
kernel.randomize_va_space=2
# Network
# Disable forwarding; override in inventory for routers/containers
net.ipv4.ip_forward=0
net.ipv4.tcp_syncookies=1
net.ipv4.icmp_echo_ignore_broadcasts=1
net.ipv4.icmp_ignore_bogus_error_responses=1
net.ipv4.conf.all.log_martians=1
net.ipv4.conf.all.rp_filter=1
net.ipv4.conf.all.secure_redirects=0
net.ipv4.conf.all.send_redirects=0
net.ipv4.conf.all.accept_redirects=0
net.ipv4.conf.all.accept_source_route=0
net.ipv4.conf.all.arp_ignore=1
net.ipv4.conf.all.arp_announce=2
net.ipv4.conf.default.log_martians=1
net.ipv4.conf.default.rp_filter=1
net.ipv4.conf.default.secure_redirects=0
net.ipv4.conf.default.send_redirects=0
net.ipv4.conf.default.accept_redirects=0
net.ipv6.conf.all.accept_redirects=0
# Disable IPv6; override in inventory if IPv6 is needed
net.ipv6.conf.all.disable_ipv6=1
net.ipv6.conf.default.accept_redirects=0
net.ipv6.conf.default.disable_ipv6=1
net.ipv6.conf.lo.disable_ipv6=1
{% for key, value in cis_cfg.sysctl | dictsort %}
{{ key }}={{ value }}
{% endfor %}