diff --git a/.rubocop.yml b/.rubocop.yml index 88326553..335d3442 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -17,9 +17,6 @@ Style/Documentation: Enabled: false Layout/DotPosition: EnforcedStyle: trailing -Layout/ExtraSpacing: - Exclude: - - attributes/default.rb Layout/AlignHash: EnforcedHashRocketStyle: table EnforcedColonStyle: table @@ -28,6 +25,8 @@ Style/NumericLiterals: Layout/SpaceAroundOperators: Exclude: - attributes/default.rb +Layout/ExtraSpacing: + AllowForAlignment: false Metrics/BlockLength: Exclude: - 'spec/**/*' diff --git a/attributes/default.rb b/attributes/default.rb index 8aff8b13..7c6004be 100644 --- a/attributes/default.rb +++ b/attributes/default.rb @@ -19,217 +19,236 @@ # See the License for the specific language governing permissions and # limitations under the License. -# Define the packages based on operating system -case node['platform_family'] -when 'rhel', 'fedora', 'amazon' - default['os-hardening']['packages']['pam_ccreds'] = 'pam_ccreds' - default['os-hardening']['packages']['pam_passwdqc'] = 'pam_passwdqc' - default['os-hardening']['packages']['pam_cracklib'] = 'pam_cracklib' - default['os-hardening']['packages']['pam_pwquality'] = 'libpwquality' - default['os-hardening']['packages']['auditd'] = 'audit' - - if node['platform_version'].to_f < 7 - default['os-hardening']['auth']['pam']['passwdqc']['enable'] = true - default['os-hardening']['auth']['pam']['pwquality']['enable'] = false - else - default['os-hardening']['auth']['pam']['passwdqc']['enable'] = false - default['os-hardening']['auth']['pam']['pwquality']['enable'] = true +# rubocop:disable Metrics/BlockLength + +default['config_disclaimer'] = '**Note:** This file was automatically created by dev-sec.io os-hardening configuration. If you use its automated setup, do not edit this file directly, but adjust the automation instead.' + +default['os-hardening'].tap do |os_hardening| + # components of this cookbook + %w[packages limits login_defs minimize_access pam profile securetty].each do |cp| + os_hardening['components'][cp] = true end -when 'debian' - default['os-hardening']['packages']['pam_ccreds'] = 'libpam-ccreds' - default['os-hardening']['packages']['pam_passwdqc'] = 'libpam-passwdqc' - default['os-hardening']['packages']['pam_cracklib'] = 'libpam-cracklib' - default['os-hardening']['packages']['auditd'] = 'auditd' - -when 'arch' - default['os-hardening']['packages']['pam_ccreds'] = 'pam_ccreds' - default['os-hardening']['packages']['pam_passwdqc'] = 'pam_passwdqc' - default['os-hardening']['packages']['pam_cracklib'] = 'pam_cracklib' - default['os-hardening']['packages']['auditd'] = 'audit' - -else - default['os-hardening']['packages']['pam_ccreds'] = 'pam_ccreds' - default['os-hardening']['packages']['pam_passwdqc'] = 'pam_passwdqc' - default['os-hardening']['packages']['pam_cracklib'] = 'pam_cracklib' - default['os-hardening']['packages']['auditd'] = 'audit' -end + # Define the packages based on operating system + os_hardening['packages'].tap do |packages| + case node['platform_family'] + when 'rhel', 'fedora', 'amazon' + packages['pam_ccreds'] = 'pam_ccreds' + packages['pam_passwdqc'] = 'pam_passwdqc' + packages['pam_cracklib'] = 'pam_cracklib' + packages['pam_pwquality'] = 'libpwquality' + packages['auditd'] = 'audit' + when 'debian' + packages['pam_ccreds'] = 'libpam-ccreds' + packages['pam_passwdqc'] = 'libpam-passwdqc' + packages['pam_cracklib'] = 'libpam-cracklib' + packages['auditd'] = 'auditd' + when 'arch' + packages['pam_ccreds'] = 'pam_ccreds' + packages['pam_passwdqc'] = 'pam_passwdqc' + packages['pam_cracklib'] = 'pam_cracklib' + packages['auditd'] = 'audit' + else + packages['pam_ccreds'] = 'pam_ccreds' + packages['pam_passwdqc'] = 'pam_passwdqc' + packages['pam_cracklib'] = 'pam_cracklib' + packages['auditd'] = 'audit' + end + end -%w[packages limits login_defs minimize_access pam profile securetty].each do |cp| - node.default['os-hardening']['components'][cp] = true -end + # rhel, centos autoconf configuration + os_hardening['authconfig']['shadow']['enable'] = true + os_hardening['authconfig']['md5']['enable'] = true + + os_hardening['desktop']['enable'] = false + os_hardening['network']['forwarding'] = false + os_hardening['network']['ipv6']['enable'] = false + os_hardening['network']['arp']['restricted'] = true + + os_hardening['env']['extra_user_paths'] = [] + os_hardening['env']['root_path'] = '/' + + os_hardening['auth'].tap do |auth| + auth['pw_max_age'] = 60 + auth['pw_min_age'] = 7 # discourage password cycling + auth['pw_warn_age'] = 7 + auth['retries'] = 5 + auth['lockout_time'] = 600 # 10min + auth['maildir'] = '/var/mail' + auth['timeout'] = 60 + auth['allow_homeless'] = false + auth['login_defs']['template_cookbook'] = 'os-hardening' + auth['root_ttys'] = %w[console tty1 tty2 tty3 tty4 tty5 tty6] + auth['uid_min'] = 1000 + auth['uid_max'] = 60000 + auth['gid_min'] = 1000 + auth['gid_max'] = 60000 + auth['sys_uid_max'] = 999 + auth['sys_gid_max'] = 999 + + # PAM settings + auth['pam'].tap do |pam| + case node['platform_family'] + when 'rhel', 'fedora', 'amazon' + if node['platform_version'].to_f < 7 + pam['passwdqc']['enable'] = true + pam['pwquality']['enable'] = false + else + pam['passwdqc']['enable'] = false + pam['pwquality']['enable'] = true + end + end + + pam['passwdqc']['options'] = 'min=disabled,disabled,16,12,8' + pam['cracklib']['options'] = 'try_first_pass retry=3 type=' + pam['pwquality']['options'] = 'try_first_pass retry=3 type=' + pam['tally2']['template_cookbook'] = 'os-hardening' + pam['passwdqc']['template_cookbook'] = 'os-hardening' + pam['system-auth']['template_cookbook'] = 'os-hardening' + pam['pam_systemd']['enable'] = node['os-hardening']['desktop']['enable'] + end + end -# rhel, centos autoconf configuration -default['os-hardening']['authconfig']['shadow']['enable'] = true -default['os-hardening']['authconfig']['md5']['enable'] = true - -default['config_disclaimer'] = '**Note:** This file was automatically created by dev-sec.io os-hardening configuration. If you use its automated setup, do not edit this file directly, but adjust the automation instead.' -default['os-hardening']['desktop']['enable'] = false -default['os-hardening']['network']['forwarding'] = false -default['os-hardening']['network']['ipv6']['enable'] = false -default['os-hardening']['network']['arp']['restricted'] = true -default['os-hardening']['env']['extra_user_paths'] = [] -default['os-hardening']['env']['root_path'] = '/' -default['os-hardening']['auth']['pw_max_age'] = 60 -default['os-hardening']['auth']['pw_min_age'] = 7 # discourage password cycling -default['os-hardening']['auth']['pw_warn_age'] = 7 -default['os-hardening']['auth']['retries'] = 5 -default['os-hardening']['auth']['lockout_time'] = 600 # 10min -default['os-hardening']['auth']['maildir'] = '/var/mail' -default['os-hardening']['auth']['timeout'] = 60 -default['os-hardening']['auth']['allow_homeless'] = false -default['os-hardening']['auth']['login_defs']['template_cookbook'] = 'os-hardening' -default['os-hardening']['auth']['pam']['passwdqc']['options'] = 'min=disabled,disabled,16,12,8' -default['os-hardening']['auth']['pam']['cracklib']['options'] = 'try_first_pass retry=3 type=' -default['os-hardening']['auth']['pam']['pwquality']['options'] = 'try_first_pass retry=3 type=' -default['os-hardening']['auth']['pam']['tally2']['template_cookbook'] = 'os-hardening' -default['os-hardening']['auth']['pam']['passwdqc']['template_cookbook'] = 'os-hardening' -default['os-hardening']['auth']['pam']['system-auth']['template_cookbook'] = 'os-hardening' -default['os-hardening']['auth']['pam']['pam_systemd']['enable'] = node['os-hardening']['desktop']['enable'] -default['os-hardening']['auth']['root_ttys'] = %w[console tty1 tty2 tty3 tty4 tty5 tty6] -default['os-hardening']['auth']['uid_min'] = 1000 -default['os-hardening']['auth']['uid_max'] = 60000 -default['os-hardening']['auth']['gid_min'] = 1000 -default['os-hardening']['auth']['gid_max'] = 60000 -default['os-hardening']['auth']['sys_uid_max'] = 999 -default['os-hardening']['auth']['sys_gid_max'] = 999 - -# RH has a bit different defaults on some places -case node['platform_family'] -when 'rhel', 'amazon' - default['os-hardening']['env']['umask'] = '077' - default['os-hardening']['auth']['sys_uid_min'] = 201 - default['os-hardening']['auth']['sys_gid_min'] = 201 -else - default['os-hardening']['env']['umask'] = '027' - default['os-hardening']['auth']['sys_uid_min'] = 100 - default['os-hardening']['auth']['sys_gid_min'] = 100 -end + # RH has a bit different defaults on some places + case node['platform_family'] + when 'rhel', 'amazon' + os_hardening['env']['umask'] = '077' + os_hardening['auth']['sys_uid_min'] = 201 + os_hardening['auth']['sys_gid_min'] = 201 + else + os_hardening['env']['umask'] = '027' + os_hardening['auth']['sys_uid_min'] = 100 + os_hardening['auth']['sys_gid_min'] = 100 + end -# may contain: change_user -default['os-hardening']['security']['users']['allow'] = [] -default['os-hardening']['security']['kernel']['enable_module_loading'] = true -default['os-hardening']['security']['kernel']['disable_filesystems'] = %w[cramfs freevxfs jffs2 hfs hfsplus squashfs udf vfat] -default['os-hardening']['security']['kernel']['enable_sysrq'] = false -default['os-hardening']['security']['kernel']['enable_core_dump'] = false -default['os-hardening']['security']['suid_sgid']['enforce'] = true -# user-defined blacklist and whitelist -default['os-hardening']['security']['suid_sgid']['blacklist'] = [] -default['os-hardening']['security']['suid_sgid']['whitelist'] = [] -# if this is true, remove any suid/sgid bits from files that were not in the -# whitelist -default['os-hardening']['security']['suid_sgid']['remove_from_unknown'] = false -default['os-hardening']['security']['suid_sgid']['dry_run_on_unknown'] = false - -# Allow interactive startup (rhel, centos) -default['os-hardening']['security']['init']['prompt'] = true -# Require root password for single user mode. (rhel, centos) -default['os-hardening']['security']['init']['single'] = false -default['os-hardening']['security']['init']['daemon_umask'] = '027' - -# remove packages with known issues -default['os-hardening']['security']['packages']['clean'] = true -# list of packages with known issues -default['os-hardening']['security']['packages']['list'] = [ - 'xinetd', - 'inetd', - 'ypserv', - 'telnet-server', - 'rsh-server' -] - -# SELinux enforcing (enforcing, permissive, unmanaged) -default['os-hardening']['security']['selinux_mode'] = 'unmanaged' - -# SYSTEM CONFIGURATION -# ==================== -# These are not meant to be modified by the user - -# misc -default['os-hardening']['security']['kernel']['secure_sysrq'] = 4 + 16 + 32 + 64 + 128 - -# suid and sgid blacklists and whitelists -# --------------------------------------- -# don't change values in the system_blacklist/whitelist -# adjust values for blacklist/whitelist instead, they can override system_blacklist/whitelist - -# list of suid/sgid entries that must be removed -default['os-hardening']['security']['suid_sgid']['system_blacklist'] = [ - # blacklist as provided by NSA - '/usr/bin/rcp', '/usr/bin/rlogin', '/usr/bin/rsh', - # sshd must not use host-based authentication (see ssh cookbook) - '/usr/libexec/openssh/ssh-keysign', - '/usr/lib/openssh/ssh-keysign', - # misc others - '/sbin/netreport', # not normally required for user - '/usr/sbin/usernetctl', # modify interfaces via functional accounts - # connecting to ... - '/usr/sbin/userisdnctl', # no isdn... - '/usr/sbin/pppd', # no ppp / dsl ... - # lockfile - '/usr/bin/lockfile', - '/usr/bin/mail-lock', - '/usr/bin/mail-unlock', - '/usr/bin/mail-touchlock', - '/usr/bin/dotlockfile', - # need more investigation, blacklist for now - '/usr/bin/arping', - '/usr/sbin/uuidd', - '/usr/bin/mtr', # investigate current state... - '/usr/lib/evolution/camel-lock-helper-1.2', # investigate current state... - '/usr/lib/pt_chown', # pseudo-tty, needed? - '/usr/lib/eject/dmcrypt-get-device', - '/usr/lib/mc/cons.saver' # midnight commander screensaver -] - -# list of suid/sgid entries that can remain untouched -default['os-hardening']['security']['suid_sgid']['system_whitelist'] = [ - # whitelist as provided by NSA - '/bin/mount', '/bin/ping', '/bin/su', '/bin/umount', '/sbin/pam_timestamp_check', - '/sbin/unix_chkpwd', '/usr/bin/at', '/usr/bin/gpasswd', '/usr/bin/locate', - '/usr/bin/newgrp', '/usr/bin/passwd', '/usr/bin/ssh-agent', '/usr/libexec/utempter/utempter', '/usr/sbin/lockdev', - '/usr/sbin/sendmail.sendmail', '/usr/bin/expiry', - # whitelist ipv6 - '/bin/ping6', '/usr/bin/traceroute6.iputils', - # whitelist nfs - '/sbin/mount.nfs', '/sbin/umount.nfs', - # whitelist nfs4 - '/sbin/mount.nfs4', '/sbin/umount.nfs4', - # whitelist cron - '/usr/bin/crontab', - # whitelist consolemssaging - '/usr/bin/wall', '/usr/bin/write', - # whitelist: only SGID with utmp group for multi-session access - # impact is limited; installation/usage has some remaining risk - '/usr/bin/screen', - # whitelist locate - '/usr/bin/mlocate', - # whitelist usermanagement - '/usr/bin/chage', '/usr/bin/chfn', '/usr/bin/chsh', - # whitelist fuse - '/bin/fusermount', - # whitelist pkexec - '/usr/bin/pkexec', - # whitelist sudo - '/usr/bin/sudo', '/usr/bin/sudoedit', - # whitelist postfix - '/usr/sbin/postdrop', '/usr/sbin/postqueue', - # whitelist apache - '/usr/sbin/suexec', - # whitelist squid - '/usr/lib/squid/ncsa_auth', '/usr/lib/squid/pam_auth', - # whitelist kerberos - '/usr/kerberos/bin/ksu', - # whitelist pam_caching - '/usr/sbin/ccreds_validate', - # whitelist Xorg - '/usr/bin/Xorg', # xorg - '/usr/bin/X', # xorg - '/usr/lib/dbus-1.0/dbus-daemon-launch-helper', # freedesktop ipc - '/usr/lib/vte/gnome-pty-helper', # gnome - '/usr/lib/libvte9/gnome-pty-helper', # gnome - '/usr/lib/libvte-2.90-9/gnome-pty-helper' # gnome -] - -# set default cpu vendor -default['os-hardening']['security']['cpu_vendor'] = 'intel' + os_hardening['security'].tap do |security| + # may contain: change_user + security['users']['allow'] = [] + security['kernel']['enable_module_loading'] = true + security['kernel']['disable_filesystems'] = %w[cramfs freevxfs jffs2 hfs hfsplus squashfs udf vfat] + security['kernel']['enable_sysrq'] = false + security['kernel']['enable_core_dump'] = false + security['suid_sgid']['enforce'] = true + # user-defined blacklist and whitelist + security['suid_sgid']['blacklist'] = [] + security['suid_sgid']['whitelist'] = [] + # if this is true, remove any suid/sgid bits from files that were not in the + # whitelist + security['suid_sgid']['remove_from_unknown'] = false + security['suid_sgid']['dry_run_on_unknown'] = false + + # Allow interactive startup (rhel, centos) + security['init']['prompt'] = true + # Require root password for single user mode. (rhel, centos) + security['init']['single'] = false + security['init']['daemon_umask'] = '027' + + # remove packages with known issues + security['packages']['clean'] = true + # list of packages with known issues + security['packages']['list'] = [ + 'xinetd', + 'inetd', + 'ypserv', + 'telnet-server', + 'rsh-server' + ] + + # SELinux enforcing (enforcing, permissive, unmanaged) + security['selinux_mode'] = 'unmanaged' + + # SYSTEM CONFIGURATION + # ==================== + # These are not meant to be modified by the user + + # misc + security['kernel']['secure_sysrq'] = 4 + 16 + 32 + 64 + 128 + + # suid and sgid blacklists and whitelists + # --------------------------------------- + # don't change values in the system_blacklist/whitelist + # adjust values for blacklist/whitelist instead, they can override system_blacklist/whitelist + + # list of suid/sgid entries that must be removed + security['suid_sgid']['system_blacklist'] = [ + # blacklist as provided by NSA + '/usr/bin/rcp', '/usr/bin/rlogin', '/usr/bin/rsh', + # sshd must not use host-based authentication (see ssh cookbook) + '/usr/libexec/openssh/ssh-keysign', + '/usr/lib/openssh/ssh-keysign', + # misc others + '/sbin/netreport', # not normally required for user + '/usr/sbin/usernetctl', # modify interfaces via functional accounts + # connecting to ... + '/usr/sbin/userisdnctl', # no isdn... + '/usr/sbin/pppd', # no ppp / dsl ... + # lockfile + '/usr/bin/lockfile', + '/usr/bin/mail-lock', + '/usr/bin/mail-unlock', + '/usr/bin/mail-touchlock', + '/usr/bin/dotlockfile', + # need more investigation, blacklist for now + '/usr/bin/arping', + '/usr/sbin/uuidd', + '/usr/bin/mtr', # investigate current state... + '/usr/lib/evolution/camel-lock-helper-1.2', # investigate current state... + '/usr/lib/pt_chown', # pseudo-tty, needed? + '/usr/lib/eject/dmcrypt-get-device', + '/usr/lib/mc/cons.saver' # midnight commander screensaver + ] + + # list of suid/sgid entries that can remain untouched + security['suid_sgid']['system_whitelist'] = [ + # whitelist as provided by NSA + '/bin/mount', '/bin/ping', '/bin/su', '/bin/umount', '/sbin/pam_timestamp_check', + '/sbin/unix_chkpwd', '/usr/bin/at', '/usr/bin/gpasswd', '/usr/bin/locate', + '/usr/bin/newgrp', '/usr/bin/passwd', '/usr/bin/ssh-agent', '/usr/libexec/utempter/utempter', '/usr/sbin/lockdev', + '/usr/sbin/sendmail.sendmail', '/usr/bin/expiry', + # whitelist ipv6 + '/bin/ping6', '/usr/bin/traceroute6.iputils', + # whitelist nfs + '/sbin/mount.nfs', '/sbin/umount.nfs', + # whitelist nfs4 + '/sbin/mount.nfs4', '/sbin/umount.nfs4', + # whitelist cron + '/usr/bin/crontab', + # whitelist consolemssaging + '/usr/bin/wall', '/usr/bin/write', + # whitelist: only SGID with utmp group for multi-session access + # impact is limited; installation/usage has some remaining risk + '/usr/bin/screen', + # whitelist locate + '/usr/bin/mlocate', + # whitelist usermanagement + '/usr/bin/chage', '/usr/bin/chfn', '/usr/bin/chsh', + # whitelist fuse + '/bin/fusermount', + # whitelist pkexec + '/usr/bin/pkexec', + # whitelist sudo + '/usr/bin/sudo', '/usr/bin/sudoedit', + # whitelist postfix + '/usr/sbin/postdrop', '/usr/sbin/postqueue', + # whitelist apache + '/usr/sbin/suexec', + # whitelist squid + '/usr/lib/squid/ncsa_auth', '/usr/lib/squid/pam_auth', + # whitelist kerberos + '/usr/kerberos/bin/ksu', + # whitelist pam_caching + '/usr/sbin/ccreds_validate', + # whitelist Xorg + '/usr/bin/Xorg', # xorg + '/usr/bin/X', # xorg + '/usr/lib/dbus-1.0/dbus-daemon-launch-helper', # freedesktop ipc + '/usr/lib/vte/gnome-pty-helper', # gnome + '/usr/lib/libvte9/gnome-pty-helper', # gnome + '/usr/lib/libvte-2.90-9/gnome-pty-helper' # gnome + ] + + # set default cpu vendor + security['cpu_vendor'] = 'intel' + end +end +# rubocop:enable Metrics/BlockLength diff --git a/metadata.rb b/metadata.rb index a2d42729..e73e26e7 100644 --- a/metadata.rb +++ b/metadata.rb @@ -16,15 +16,15 @@ # limitations under the License. # -name 'os-hardening' -maintainer 'Artem Sidorenko' +name 'os-hardening' +maintainer 'Artem Sidorenko' maintainer_email 'artem@posteo.de' -license 'Apache-2.0' -description 'Installs and configures operating system hardening' +license 'Apache-2.0' +description 'Installs and configures operating system hardening' long_description IO.read(File.join(File.dirname(__FILE__), 'README.md')) -version '3.2.1' -source_url 'https://github.com/dev-sec/chef-os-hardening' -issues_url 'https://github.com/dev-sec/chef-os-hardening/issues' +version '3.2.1' +source_url 'https://github.com/dev-sec/chef-os-hardening' +issues_url 'https://github.com/dev-sec/chef-os-hardening/issues' chef_version '>= 14' diff --git a/recipes/pam.rb b/recipes/pam.rb index 472ee7ae..a0e8696d 100644 --- a/recipes/pam.rb +++ b/recipes/pam.rb @@ -31,7 +31,7 @@ when 'debian' passwdqc_path = '/usr/share/pam-configs/passwdqc' - tally2_path = '/usr/share/pam-configs/tally2' + tally2_path = '/usr/share/pam-configs/tally2' # See NSA 2.3.3.1.2 if node['os-hardening']['auth']['pam']['passwdqc']['enable'] diff --git a/recipes/suid_sgid.rb b/recipes/suid_sgid.rb index 49cb9c63..bf933cbf 100644 --- a/recipes/suid_sgid.rb +++ b/recipes/suid_sgid.rb @@ -23,15 +23,15 @@ # make user-defined blacklist/whitelist override our default lists sb = node['os-hardening']['security']['suid_sgid']['system_blacklist'] sw = node['os-hardening']['security']['suid_sgid']['system_whitelist'] -b = node['os-hardening']['security']['suid_sgid']['blacklist'] -w = node['os-hardening']['security']['suid_sgid']['whitelist'] +b = node['os-hardening']['security']['suid_sgid']['blacklist'] +w = node['os-hardening']['security']['suid_sgid']['whitelist'] blacklist = (sb - w + b).uniq whitelist = (sw - b + w).uniq # root = "/" -dry_run = node['os-hardening']['security']['suid_sgid']['dry_run_on_unknown'] -root = node['os-hardening']['env']['root_path'] +dry_run = node['os-hardening']['security']['suid_sgid']['dry_run_on_unknown'] +root = node['os-hardening']['env']['root_path'] # walk the blacklist and remove suid and sgid bits from these items ruby_block 'remove_suid_from_blacklists' do