feat(cis): add selectable profile and per-rule hardening toggles
This commit is contained in:
@@ -1,6 +1,5 @@
|
||||
---
|
||||
# OS-specific binary names for CIS permission targets.
|
||||
# fusermount3 is the modern name; older distros still use fusermount.
|
||||
# fusermount3 is the modern name; older distros still ship fusermount.
|
||||
cis_fusermount_binary: >-
|
||||
{{
|
||||
'fusermount3'
|
||||
@@ -19,3 +18,235 @@ cis_write_binary: >-
|
||||
if (os == 'debian' and (os_version | string) == '11')
|
||||
else 'write'
|
||||
}}
|
||||
|
||||
cis_pkg_install: >-
|
||||
{{ chroot_command }} {{
|
||||
'apt-get install -y'
|
||||
if is_debian | bool
|
||||
else 'pacman -S --noconfirm'
|
||||
if os == 'archlinux'
|
||||
else 'dnf install -y'
|
||||
}}
|
||||
|
||||
# Rule catalog: control -> CIS level + whether a task implements it.
|
||||
# `default` enables only implemented rules; `l1`/`l2` add the level-tagged ones.
|
||||
cis_rule_catalog:
|
||||
module_blacklist: {level: l1, implemented: true} # fs/net modprobe blacklist (list per profile)
|
||||
usb_lockdown: {level: l2, implemented: true} # udev authorized_default=0 (aggressive)
|
||||
sysctl_hardening: {level: l1, implemented: true}
|
||||
ipv6_disable: {level: l2, implemented: true} # disable_ipv6 subset of the sysctl set
|
||||
umask_default: {level: l1, implemented: true}
|
||||
empty_password_login: {level: l1, implemented: true}
|
||||
pwquality: {level: l1, implemented: true}
|
||||
core_dumps: {level: l1, implemented: true}
|
||||
shell_timeout: {level: l1, implemented: true}
|
||||
journald_persistent: {level: l1, implemented: true}
|
||||
sudo_logfile: {level: l1, implemented: true}
|
||||
su_restriction: {level: l1, implemented: true}
|
||||
faillock: {level: l1, implemented: true}
|
||||
password_history: {level: l1, implemented: true}
|
||||
tcp_wrappers: {level: l1, implemented: true}
|
||||
crypto_policy: {level: l1, implemented: true} # RedHat non-Fedora only
|
||||
mask_services: {level: l1, implemented: true}
|
||||
cron_at_access: {level: l1, implemented: true}
|
||||
file_permissions: {level: l1, implemented: true}
|
||||
sshd_hardening: {level: l1, implemented: true}
|
||||
password_expiry: {level: l1, implemented: true} # login.defs aging policy
|
||||
aide: {level: l1, implemented: true} # file-integrity db + daily check
|
||||
warning_banners: {level: l1, implemented: true} # /etc/issue, issue.net, motd
|
||||
auditd: {level: l2, implemented: true} # audit daemon + CIS rule set
|
||||
grub_password: {level: l1, implemented: true} # opt-in only; needs params.grub_password_hash
|
||||
|
||||
# Rules not listed are off. A per-host system.features.cis.rules map overlays this.
|
||||
cis_profiles:
|
||||
# default = established house behaviour, kept byte-for-byte unchanged.
|
||||
default:
|
||||
module_blacklist: true
|
||||
usb_lockdown: true
|
||||
sysctl_hardening: true
|
||||
ipv6_disable: true
|
||||
umask_default: true
|
||||
empty_password_login: true
|
||||
pwquality: true
|
||||
core_dumps: true
|
||||
shell_timeout: true
|
||||
journald_persistent: true
|
||||
sudo_logfile: true
|
||||
su_restriction: true
|
||||
faillock: true
|
||||
password_history: true
|
||||
tcp_wrappers: true
|
||||
crypto_policy: true
|
||||
mask_services: true
|
||||
cron_at_access: true
|
||||
file_permissions: true
|
||||
sshd_hardening: true
|
||||
# l1 = clean CIS Level 1: drops the L2 extras (usb_lockdown, ipv6_disable).
|
||||
l1:
|
||||
module_blacklist: true
|
||||
sysctl_hardening: true
|
||||
umask_default: true
|
||||
empty_password_login: true
|
||||
pwquality: true
|
||||
core_dumps: true
|
||||
shell_timeout: true
|
||||
journald_persistent: true
|
||||
sudo_logfile: true
|
||||
su_restriction: true
|
||||
faillock: true
|
||||
password_history: true
|
||||
tcp_wrappers: true
|
||||
crypto_policy: true
|
||||
mask_services: true
|
||||
cron_at_access: true
|
||||
file_permissions: true
|
||||
sshd_hardening: true
|
||||
password_expiry: true
|
||||
aide: true
|
||||
warning_banners: true
|
||||
# l2 = l1 plus the defence-in-depth Level 2 controls.
|
||||
l2:
|
||||
module_blacklist: true
|
||||
usb_lockdown: true
|
||||
sysctl_hardening: true
|
||||
ipv6_disable: true
|
||||
umask_default: true
|
||||
empty_password_login: true
|
||||
pwquality: true
|
||||
core_dumps: true
|
||||
shell_timeout: true
|
||||
journald_persistent: true
|
||||
sudo_logfile: true
|
||||
su_restriction: true
|
||||
faillock: true
|
||||
password_history: true
|
||||
tcp_wrappers: true
|
||||
crypto_policy: true
|
||||
mask_services: true
|
||||
cron_at_access: true
|
||||
file_permissions: true
|
||||
sshd_hardening: true
|
||||
password_expiry: true
|
||||
aide: true
|
||||
warning_banners: true
|
||||
auditd: true
|
||||
|
||||
# Override per host via system.features.cis.params: dicts deep-merge,
|
||||
# list-valued keys (e.g. sshd_options) replace wholesale.
|
||||
cis_param_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
|
||||
# pwquality strict set (l1/l2 only, cis_strict): SSG cis_server_l1 values.
|
||||
pwquality_difok: 2
|
||||
pwquality_maxrepeat: 3
|
||||
pwquality_maxsequence: 3
|
||||
pwquality_minclass: 4
|
||||
pwquality_dictcheck: 1
|
||||
tmout: 900
|
||||
umask: "077"
|
||||
umask_profile: "027"
|
||||
faillock_deny: 5
|
||||
faillock_unlock_time: 900
|
||||
password_remember: 5
|
||||
# pwhistory remember (l1/l2 only, cis_strict): SSG wants 24 via pam_pwhistory.
|
||||
pwhistory_remember: 24
|
||||
# password_expiry (l1/l2): /etc/login.defs aging.
|
||||
pass_max_days: 365
|
||||
pass_min_days: 1
|
||||
pass_warn_age: 7
|
||||
# account_disable_post_pw_expiration (l1/l2): days after expiry to lock (SSG=45).
|
||||
pass_inactive: 45
|
||||
# aide (l1/l2): daily integrity-check schedule.
|
||||
aide_cron_hour: "5"
|
||||
aide_cron_minute: "0"
|
||||
# warning_banners (l1/l2): login/MOTD text.
|
||||
banner_text: "Authorized access only. All activity may be monitored and reported."
|
||||
# grub_password (opt-in only): a grub2 pbkdf2 hash; empty unless opted in.
|
||||
grub_password_hash: ""
|
||||
# insecure_packages (l1/l2 only, cis_strict): legacy cleartext clients to remove.
|
||||
insecure_packages:
|
||||
- telnet
|
||||
|
||||
# Only the module blacklist differs by profile: l1 trims to the L1 filesystem
|
||||
# modules; default/l2 keep the full list.
|
||||
cis_profile_params:
|
||||
default: {}
|
||||
l1:
|
||||
modules_blacklist:
|
||||
- cramfs
|
||||
- freevxfs
|
||||
- jffs2
|
||||
- hfs
|
||||
- hfsplus
|
||||
- udf
|
||||
- usb-storage
|
||||
l2: {}
|
||||
|
||||
Reference in New Issue
Block a user