def configure_ipv6_params(): """3.3 IPv6""" PropertyFile('/etc/sysctl.conf', ' = ').override({ 'net.ipv6.conf.all.accept_ra': '0', 'net.ipv6.conf.default.accept_ra': '0', 'net.ipv6.conf.all.accept_redirects': '0', 'net.ipv6.conf.default.accept_redirects': '0' }).write() # 3.3.3 Ensure IPv6 is disabled PropertyFile('/etc/modprobe.d/CIS.conf', ' ').override({ 'options ipv6': 'disable=1' }).write()
def apply_process_hardenings(): """1.5 Additional Process Hardening""" # 1.5.1 Ensure core dumps are restricted PropertyFile('/etc/security/limits.conf', ' ').override({ '* hard core': '0' }).write() PropertyFile('/etc/sysctl.conf', ' = ').override({ 'fs.suid_dumpable': '0' }).write() # 1.5.3 Ensure address space layout randomization (ASLR) is enable PropertyFile('/etc/sysctl.conf', ' = ').override({ 'kernel.randomize_va_space': '2' }).write() # 1.5.4 Ensure prelink is disabled Package('prelink').remove()
def configure_host_network_params(): """3.1 Network Parameters(Host Only)""" PropertyFile('/etc/sysctl.conf', ' = ').override({ 'net.ipv4.ip_forward': '0', 'net.ipv4.conf.all.send_redirects': '0', 'net.ipv4.conf.default.send_redirects': '0', }).write()
def configure_chrony(upstream): """2.2.1 Time Synchronization""" # 2.2.1.1 Ensure time synchronization is in use Package('ntp').remove() Package('chrony').install() # 2.2.1.3 Ensure chrony is configured PropertyFile('/etc/chrony.conf', ' ').override({ 'server': upstream }).write() PropertyFile('/etc/sysconfig/chronyd', '=').override({ 'OPTIONS': '"-u chrony"' }).write() exec_shell([ 'chkconfig chronyd on', ])
def configure_password_parmas(): """5.4.1 Set Shadow Password Suite Parameters""" PropertyFile('/etc/login.defs', '\t').override({ 'PASS_MAX_DAYS': '90', 'PASS_MIN_DAYS': '7', 'PASS_WARN_AGE': '7' }).write() exec_shell([ 'useradd -D -f 30' ])
def disable_uncommon_protocols(): """3.5 Uncommon Network Protocols""" modules = ['dccp', 'sctp', 'rds', 'tipc'] prop = PropertyFile('/etc/modprobe.d/CIS.conf', ' ') for mod in modules: prop.override({'install {}'.format(mod): '/bin/true'}) prop.write()
def secure_boot_settings(): """1.4 Secure Boot Settings""" if os.path.isfile('/boot/grub/menu.lst'): exec_shell([ 'chown root:root /boot/grub/menu.lst', 'chmod og-rwx /boot/grub/menu.lst' ]) PropertyFile('/etc/sysconfig/init', '=').override({ 'SINGLE': '/sbin/sulogin', 'PROMPT': 'no' }).write()
def disable_unused_filesystems(): """1.1.1 Disable unused filesystems""" filesystems = [ 'cramfs', 'freevxfs', 'jffs2', 'hfs', 'hfsplus', 'squashfs', 'udf', 'vfat' ] prop = PropertyFile('/etc/modprobe.d/CIS.conf', ' ') for filesystem in filesystems: prop.override({'install {}'.format(filesystem): '/bin/true'}) prop.write()
def configure_network_params(): """3.2 Network Parameters(Host and Router)""" PropertyFile('/etc/sysctl.conf', ' = ').override({ 'net.ipv4.conf.all.accept_source_route': '0', 'net.ipv4.conf.default.accept_source_route': '0', 'net.ipv4.conf.all.accept_redirects': '0', 'net.ipv4.conf.default.accept_redirects': '0', 'net.ipv4.conf.all.secure_redirects': '0', 'net.ipv4.conf.default.secure_redirects': '0', 'net.ipv4.conf.all.log_martians': '1', 'net.ipv4.conf.default.log_martians': '1', 'net.ipv4.icmp_echo_ignore_broadcasts': '1', 'net.ipv4.icmp_ignore_bogus_error_responses': '1', 'net.ipv4.conf.all.rp_filter': '1', 'net.ipv4.conf.default.rp_filter': '1', 'net.ipv4.tcp_syncookies': '1' }).write()
def configure_pam(): """5.3 Configure PAM""" def convert_password(line): if password_unix_re.match(line): if 'remember=5' not in line: line += ' remember=5' if 'sha512' not in line: line += ' sha512' return line password_unix_re = re.compile(r'^password\s+sufficient\s+pam_unix.so') password_auth_content = get_string_asset('/etc/pam.d/password-auth') password_auth_content += exec_shell([ 'cat /etc/pam.d/password-auth | grep -v "^auth"' ]) password_auth_content = '\n'.join([ convert_password(line) for line in password_auth_content.splitlines() ]) with open('/etc/pam.d/password-auth-local', 'w') as f: f.write(password_auth_content) exec_shell(['ln -sf /etc/pam.d/password-auth-local /etc/pam.d/password-auth']) system_auth_content = get_string_asset('/etc/pam.d/system-auth') system_auth_content += exec_shell([ 'cat /etc/pam.d/system-auth | grep -v "^auth"' ]) system_auth_content = '\n'.join([ convert_password(line) for line in system_auth_content.splitlines() ]) with open('/etc/pam.d/system-auth-local', 'w') as f: f.write(system_auth_content) exec_shell( ['ln -sf /etc/pam.d/system-auth-local /etc/pam.d/system-auth']) PropertyFile('/etc/security/pwquality.conf', '=').override({ 'minlen': '14', 'dcredit': '-1', 'ucredit': '-1', 'ocredit': '-1', 'lcredit': '-1' }).write()
def configure_sshd(): """5.2 SSH Server Configuration""" # 5.2.1 Ensure permissions on /etc/ssh/sshd_config are configured exec_shell([ 'chown root:root /etc/ssh/sshd_config', 'chmod og-rwx /etc/ssh/sshd_config' ]) # 5.2.2 - 5.2.16 PropertyFile('/etc/ssh/sshd_config', ' ').override({ 'Protocol': '2', 'LogLevel': 'INFO', 'X11Forwarding': 'no', 'MaxAuthTries': '4', 'IgnoreRhosts': 'yes', 'HostbasedAuthentication': 'no', 'PermitRootLogin': '******', 'PermitEmptyPasswords': 'no', 'PermitUserEnvironment': 'no', 'Ciphers': 'aes256-ctr,aes192-ctr,aes128-ctr', 'MACs': '[email protected],[email protected],[email protected],hmac-sha2-512,hmac-sha2-256,[email protected]', 'ClientAliveInterval': '300', 'ClientAliveCountMax': '0', 'LoginGraceTime': '60', 'AllowUsers': 'ec2-user', 'Banner': '/etc/issue.net' }).write()
def configure_rsyslog(): """4.2.1 Configure rsyslog""" Package('rsyslog').install() PropertyFile('/etc/rsyslog.conf', ' ').override({ '*.emerg': ':omusrmsg:*', 'mail.*': '-/var/log/mail', 'mail.info': '-/var/log/mail.info', 'mail.warning': '-/var/log/mail.warn', 'mail.err': '/var/log/mail.err', 'news.crit': '-/var/log/news/news.crit', 'news.err': '-/var/log/news/news.err', 'news.notice': '-/var/log/news/news.notice', '*.=warning;*.=err': '-/var/log/warn', '*.crit': '/var/log/warn', '*.*;mail.none;news.none': '-/var/log/messages', 'local0,local1.*': '-/var/log/localmessages', 'local2,local3.*': '-/var/log/localmessages', 'local4,local5.*': '-/var/log/localmessages', 'local6,local7.*': '-/var/log/localmessages ', '$FileCreateMode': '0640' }).write()
def configure_auditd(): """4.1.1 Configure Data Retention""" PropertyFile('/etc/audit/auditd.conf', ' = ').override({ 'max_log_file': '8', 'space_left_action': 'email', 'action_mail_acct': 'root', 'admin_space_left_action': 'halt', 'max_log_file_action': 'keep_logs' }).write() kernel=exec_shell([ 'cat /boot/grub/menu.lst | grep ^kernel' ]) # add audit=1 if not 'audit' in kernel: boot = exec_shell([ 'cat /boot/grub/menu.lst | sed -E "s/^(kernel.*)$/\\1 audit=1/"' ]) else: boot = exec_shell([ 'cat /boot/grub/menu.lst | sed -E "s/(audit)=0/\\1=1/g"' ]) File('/boot/grub/menu.lst').write(boot) audit_rules = """-D -b 320 -a always,exit -F arch=b64 -S adjtimex -S settimeofday -k time-change -a always,exit -F arch=b32 -S adjtimex -S settimeofday -S stime -k time-change -a always,exit -F arch=b64 -S clock_settime -k time-change -a always,exit -F arch=b32 -S clock_settime -k time-change -w /etc/localtime -p wa -k time-change -w /etc/group -p wa -k identity -w /etc/passwd -p wa -k identity -w /etc/gshadow -p wa -k identity -w /etc/shadow -p wa -k identity -w /etc/security/opasswd -p wa -k identity -a always,exit -F arch=b64 -S sethostname -S setdomainname -k system-locale -a always,exit -F arch=b32 -S sethostname -S setdomainname -k system-locale -w /etc/issue -p wa -k system-locale -w /etc/issue.net -p wa -k system-locale -w /etc/hosts -p wa -k system-locale -w /etc/sysconfig/network -p wa -k system-locale -w /etc/sysconfig/network-scripts/ -p wa -k system-locale -w /etc/selinux/ -p wa -k MAC-policy -w /usr/share/selinux/ -p wa -k MAC-policy -w /var/log/lastlog -p wa -k logins -w /var/run/faillock/ -p wa -k logins -w /var/run/utmp -p wa -k session -w /var/log/wtmp -p wa -k logins -w /var/log/btmp -p wa -k logins -a always,exit -F arch=b64 -S chmod -S fchmod -S fchmodat -F auid>=500 -F auid!=4294967295 -k perm_mod -a always,exit -F arch=b32 -S chmod -S fchmod -S fchmodat -F auid>=500 -F auid!=4294967295 -k perm_mod -a always,exit -F arch=b64 -S chown -S fchown -S fchownat -S lchown -F auid>=500 -F auid!=4294967295 -k perm_mod -a always,exit -F arch=b32 -S chown -S fchown -S fchownat -S lchown -F auid>=500 -F auid!=4294967295 -k perm_mod -a always,exit -F arch=b64 -S setxattr -S lsetxattr -S fsetxattr -S removexattr -S lremovexattr -S fremovexattr -F auid>=500 -F auid!=4294967295 -k perm_mod -a always,exit -F arch=b32 -S setxattr -S lsetxattr -S fsetxattr -S removexattr -S lremovexattr -S fremovexattr -F auid>=500 -F auid!=4294967295 -k perm_mod -a always,exit -F arch=b64 -S creat -S open -S openat -S truncate -S ftruncate -F exit=-EACCES -F auid>=500 -F auid!=4294967295 -k access -a always,exit -F arch=b32 -S creat -S open -S openat -S truncate -S ftruncate -F exit=-EACCES -F auid>=500 -F auid!=4294967295 -k access -a always,exit -F arch=b64 -S creat -S open -S openat -S truncate -S ftruncate -F exit=-EPERM -F auid>=500 -F auid!=4294967295 -k access -a always,exit -F arch=b32 -S creat -S open -S openat -S truncate -S ftruncate -F exit=-EPERM -F auid>=500 -F auid!=4294967295 -k access -a always,exit -F arch=b64 -S mount -F auid>=500 -F auid!=4294967295 -k mounts -a always,exit -F arch=b32 -S mount -F auid>=500 -F auid!=4294967295 -k mounts -a always,exit -F arch=b64 -S unlink -S unlinkat -S rename -S renameat -F auid>=500 -F auid!=4294967295 -k delete -a always,exit -F arch=b32 -S unlink -S unlinkat -S rename -S renameat -F auid>=500 -F auid!=4294967295 -k delete -w /etc/sudoers -p wa -k scope -w /etc/sudoers.d/ -p wa -k scope -w /var/log/sudo.log -p wa -k actions -w /sbin/insmod -p x -k modules -w /sbin/rmmod -p x -k modules -w /sbin/modprobe -p x -k modules -a always,exit -F arch=b64 -S init_module -S delete_module -k modules -e 2 """ bashrc = exec_shell([ 'echo "{}" > /etc/audit/audit.rules'.format(audit_rules) ])