refactor(cis): extract hardcoded values to cis_defaults and add _normalize.yml
This commit is contained in:
@@ -1,4 +1,85 @@
|
||||
---
|
||||
# User-facing API: override via top-level `cis` dict in inventory.
|
||||
# Merged with these defaults in _normalize.yml → cis_cfg.
|
||||
cis_defaults:
|
||||
modules_blacklist:
|
||||
- freevxfs
|
||||
- jffs2
|
||||
- hfs
|
||||
- hfsplus
|
||||
- cramfs
|
||||
- udf
|
||||
- usb-storage
|
||||
- dccp
|
||||
- sctp
|
||||
- rds
|
||||
- tipc
|
||||
- firewire-core
|
||||
- firewire-sbp2
|
||||
- thunderbolt
|
||||
sysctl:
|
||||
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
|
||||
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
|
||||
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
|
||||
sshd_options:
|
||||
- { 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 }
|
||||
pwquality_minlen: 14
|
||||
tmout: 900
|
||||
umask: "077"
|
||||
umask_profile: "027"
|
||||
faillock_deny: 5
|
||||
faillock_unlock_time: 900
|
||||
password_remember: 5
|
||||
|
||||
# Platform-specific binary names for CIS permission targets
|
||||
cis_fusermount_binary: "{{ 'fusermount3' if is_rhel | default(false) | bool else 'fusermount' }}"
|
||||
cis_write_binary: "{{ 'write' if is_rhel | default(false) | bool else 'wall' }}"
|
||||
|
||||
4
roles/cis/tasks/_normalize.yml
Normal file
4
roles/cis/tasks/_normalize.yml
Normal 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) }}"
|
||||
@@ -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
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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 }}"
|
||||
|
||||
|
||||
@@ -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 %}
|
||||
|
||||
Reference in New Issue
Block a user