From 6046cc65366c1ce2a782628fa51af958376c65e7 Mon Sep 17 00:00:00 2001 From: Benjamin Blakely Date: Tue, 6 Feb 2018 16:39:59 -0600 Subject: [PATCH 01/24] Initial (sans Arch) auditd management support. --- attributes/default.rb | 16 +++++++++ recipes/auditd.rb | 39 ++++++++++++++++++++++ templates/default/auditd.conf.erb | 33 ++++++++++++++++++ test/integration/default/controls/tests.rb | 2 -- 4 files changed, 88 insertions(+), 2 deletions(-) create mode 100644 templates/default/auditd.conf.erb diff --git a/attributes/default.rb b/attributes/default.rb index dab2b6cb..39720353 100644 --- a/attributes/default.rb +++ b/attributes/default.rb @@ -220,3 +220,19 @@ # set default cpu vendor default['os-hardening']['security']['cpu_vendor'] = 'intel' + +# auditd config +default['os-hardening']['auditd']['flush'] = 'INCREMENTAL' +default['os-hardening']['auditd']['log_group'] = 'root' +default['os-hardening']['auditd']['priority_boost'] = '4' +default['os-hardening']['auditd']['freq'] = '20' +default['os-hardening']['auditd']['num_logs'] = '5' +default['os-hardening']['auditd']['disp_qos'] = 'lossy' +default['os-hardening']['auditd']['dispatcher'] = '/sbin/audispd' +default['os-hardening']['auditd']['name_format'] = 'NONE' +default['os-hardening']['auditd']['max_log_file'] = '6' +default['os-hardening']['auditd']['tcp_listen_queue'] = '5' +default['os-hardening']['auditd']['tcp_max_per_addr'] = '1' +default['os-hardening']['auditd']['tcp_client_max_idle'] = '0' +default['os-hardening']['auditd']['enable_krb5'] = 'no' +default['os-hardening']['auditd']['krb5_principal'] = 'auditd' diff --git a/recipes/auditd.rb b/recipes/auditd.rb index 34cfe29b..00ffc959 100644 --- a/recipes/auditd.rb +++ b/recipes/auditd.rb @@ -20,3 +20,42 @@ # package node['os-hardening']['packages']['auditd'] + +service "auditd" do + supports [:start, :stop, :restart, :reload, :status] + if (node['platform_family'] == 'rhel' && node['platform_version'].to_f >= 7) || + (node['platform_family'] == 'fedora' && node['platform_version'].to_f >= 27) + restart_command 'service auditd restart' + end + action [ :enable ] +end +unless (node['os-hardening']['auditd']['flush'].match? /^INCREMENTAL|INCREMENTAL_ASYNC$/ || + node['os-hardening']['auditd']['flush'].empty?) + Chef::Log.fatal('If specifying a value for auditd flush parameter, must be one of INCREMENTAL or INCREMENTAL_ASYNC') + raise +end + +template '/etc/audit/auditd.conf' do + source 'auditd.conf.erb' + mode '0400' + owner 'root' + group 'root' + variables( + flush: node['os-hardening']['auditd']['flush'], + log_group: node['os-hardening']['auditd']['log_group'], + priority_boost: node['os-hardening']['auditd']['priority_boost'], + freq: node['os-hardening']['auditd']['freq'], + num_logs: node['os-hardening']['auditd']['num_logs'], + disp_qos: node['os-hardening']['auditd']['disp_qos'], + dispatcher: node['os-hardening']['auditd']['dispatcher'], + name_format: node['os-hardening']['auditd']['name_format'], + max_log_file: node['os-hardening']['auditd']['max_log_file'], + tcp_listen_queue: node['os-hardening']['auditd']['tcp_listen_queue'], + tcp_max_per_addr: node['os-hardening']['auditd']['tcp_max_per_addr'], + tcp_client_max_idle: node['os-hardening']['auditd']['tcp_client_max_idle'], + enable_krb5: node['os-hardening']['auditd']['enable_krb5'], + krb5_principal: node['os-hardening']['auditd']['krb5_principal'] + ) + notifies :restart, 'service[auditd]' + action :create +end diff --git a/templates/default/auditd.conf.erb b/templates/default/auditd.conf.erb new file mode 100644 index 00000000..9a841b34 --- /dev/null +++ b/templates/default/auditd.conf.erb @@ -0,0 +1,33 @@ +<% node['config_disclaimer'].to_s.split("\n").each do |l| %> +# <%= l %> +<% end %> +# +#-- + +# Specified by linux-baseline +log_file = /var/log/audit/audit.log +log_format = RAW +flush = <%= @flush %> +max_log_file_action = keep_logs +space_left = 75 +action_mail_acct = root +space_left_action = SYSLOG +admin_space_left = 50 +admin_space_left_action = SUSPEND +disk_full_action = SUSPEND +disk_error_action = SUSPEND + +# Unspecified, auditd defaults unless overwritten +log_group = <%= @log_group %> +priority_boost = <%= @priority_boost %> +freq = <%= @freq %> +num_logs = <%= @num_logs %> +disp_qos = <%= @disp_qos %> +dispatcher = <%= @dispatcher %> +name_format = <%= @name_format %> +max_log_file = <%= @max_log_file %> +tcp_listen_queue = <%= @tcp_listen_queue %> +tcp_max_per_addr = <%= @tcp_max_per_addr %> +tcp_client_max_idle = <%= @tcp_client_max_idle %> +enable_krb5 = <%= @enable_krb5 %> +krb5_principal = <%= @krb5_principal %> diff --git a/test/integration/default/controls/tests.rb b/test/integration/default/controls/tests.rb index c1913a29..7b58667d 100644 --- a/test/integration/default/controls/tests.rb +++ b/test/integration/default/controls/tests.rb @@ -2,6 +2,4 @@ # skip entropy test, as our short living test VMs usually do not # have enough skip_control 'os-08' - # skip auditd tests, we do not have any implementation for audit management yet - skip_control 'package-08' end From 24a38330d36fa1399c3235d8eb9ab69f2b02cf38 Mon Sep 17 00:00:00 2001 From: Benjamin Blakely Date: Tue, 6 Feb 2018 16:42:06 -0600 Subject: [PATCH 02/24] Newline for readability. --- recipes/auditd.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/recipes/auditd.rb b/recipes/auditd.rb index 00ffc959..132484f6 100644 --- a/recipes/auditd.rb +++ b/recipes/auditd.rb @@ -29,6 +29,7 @@ end action [ :enable ] end + unless (node['os-hardening']['auditd']['flush'].match? /^INCREMENTAL|INCREMENTAL_ASYNC$/ || node['os-hardening']['auditd']['flush'].empty?) Chef::Log.fatal('If specifying a value for auditd flush parameter, must be one of INCREMENTAL or INCREMENTAL_ASYNC') From 31c591511970b71fdea28b66924d3baa4ae4ab4c Mon Sep 17 00:00:00 2001 From: Artem Sidorenko Date: Wed, 7 Feb 2018 12:20:20 +0100 Subject: [PATCH 03/24] Fix fedora shadow permissions Fedora belongs in our tests to the RH family, lets make it explicitely here, as ohai detects platform_family on fedora as 'fedora' and not 'rhel'. See https://github.com/dev-sec/linux-baseline/pull/82 for reference Signed-off-by: Artem Sidorenko --- recipes/minimize_access.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/recipes/minimize_access.rb b/recipes/minimize_access.rb index f42f7087..45f4a67e 100644 --- a/recipes/minimize_access.rb +++ b/recipes/minimize_access.rb @@ -34,7 +34,7 @@ file '/etc/shadow' do owner 'root' case node['platform_family'] - when 'rhel' + when 'rhel', 'fedora' group 'root' mode '0000' when 'debian' From f5210fb0fdcd270a97d5caa3222b474fc830454b Mon Sep 17 00:00:00 2001 From: Benjamin Blakely Date: Wed, 7 Feb 2018 16:17:08 -0600 Subject: [PATCH 04/24] Fixed syntax error on string match --- recipes/auditd.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/recipes/auditd.rb b/recipes/auditd.rb index 132484f6..c21749f1 100644 --- a/recipes/auditd.rb +++ b/recipes/auditd.rb @@ -30,7 +30,7 @@ action [ :enable ] end -unless (node['os-hardening']['auditd']['flush'].match? /^INCREMENTAL|INCREMENTAL_ASYNC$/ || +unless (node['os-hardening']['auditd']['flush'].match(/^INCREMENTAL|INCREMENTAL_ASYNC$/) || node['os-hardening']['auditd']['flush'].empty?) Chef::Log.fatal('If specifying a value for auditd flush parameter, must be one of INCREMENTAL or INCREMENTAL_ASYNC') raise From 8921f8f20d7d04a9caff9f6f96475ba98dec5c48 Mon Sep 17 00:00:00 2001 From: Artem Sidorenko Date: Thu, 8 Feb 2018 14:12:54 +0100 Subject: [PATCH 05/24] Use the new droplets with more memory Fedora 27 fails during the converge phase with OOMs with 512mb --- .kitchen.do.local.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.kitchen.do.local.yml b/.kitchen.do.local.yml index b94f3791..bd3622ff 100644 --- a/.kitchen.do.local.yml +++ b/.kitchen.do.local.yml @@ -3,7 +3,7 @@ --- driver: name: digitalocean - size: 512mb + size: s-1vcpu-1gb region: nyc3 transport: From afdec51f882329ae7bcdca0ca136cd583b650054 Mon Sep 17 00:00:00 2001 From: bablakely Date: Mon, 12 Feb 2018 15:16:25 -0600 Subject: [PATCH 06/24] Remove dependency on compat_resource (#188) * Remove dependency on compat_resource (deprecated). Fixes #186, but may break older clients * Bumped Chef version to 12.14.60 --- .travis.yml | 8 ++++---- metadata.rb | 1 - 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/.travis.yml b/.travis.yml index 9c31a7ec..4fe38ffb 100644 --- a/.travis.yml +++ b/.travis.yml @@ -13,10 +13,10 @@ before_install: env: - INSTANCE=ubuntu-14-04 - INSTANCE=ubuntu-16-04 - - INSTANCE=ubuntu-16-04 CHEF_VERSION=12.5.1 + - INSTANCE=ubuntu-16-04 CHEF_VERSION=12.14.60 - INSTANCE=centos-6 - INSTANCE=centos-7 - - INSTANCE=centos-7 CHEF_VERSION=12.5.1 + - INSTANCE=centos-7 CHEF_VERSION=12.14.60 - INSTANCE=debian-7 - INSTANCE=debian-8 - INSTANCE=fedora-26 @@ -29,10 +29,10 @@ matrix: allow_failures: # allow failues of integration tests as the forks might miss the DO token - env: INSTANCE=ubuntu-14-04 - env: INSTANCE=ubuntu-16-04 - - env: INSTANCE=ubuntu-16-04 CHEF_VERSION=12.5.1 + - env: INSTANCE=ubuntu-16-04 CHEF_VERSION=12.14.60 - env: INSTANCE=centos-6 - env: INSTANCE=centos-7 - - env: INSTANCE=centos-7 CHEF_VERSION=12.5.1 + - env: INSTANCE=centos-7 CHEF_VERSION=12.14.60 - env: INSTANCE=debian-7 - env: INSTANCE=debian-8 - env: INSTANCE=fedora-26 diff --git a/metadata.rb b/metadata.rb index ec4898be..c26aed19 100644 --- a/metadata.rb +++ b/metadata.rb @@ -35,7 +35,6 @@ # temporary version pinning of sysctl # https://github.com/dev-sec/chef-os-hardening/issues/166#issuecomment-322433264 depends 'sysctl', '<= 0.9.0' -depends 'compat_resource', '>= 12.16.3' recipe 'os-hardening::default', 'harden the operating system (all recipes)' recipe 'os-hardening::limits', 'prevent core dumps' From 6864dd3207c95697efb35a8861dd7c5fac4a5534 Mon Sep 17 00:00:00 2001 From: Artem Sidorenko Date: Tue, 13 Feb 2018 12:42:26 +0100 Subject: [PATCH 07/24] Unpin sysctl dependency and resolve the cleanup issue of old configs on our side Signed-off-by: Artem Sidorenko --- metadata.rb | 4 +--- recipes/sysctl.rb | 17 +++++++++++++++++ 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/metadata.rb b/metadata.rb index c26aed19..179985cc 100644 --- a/metadata.rb +++ b/metadata.rb @@ -32,9 +32,7 @@ supports 'redhat', '>= 5.0' supports 'oracle', '>= 6.4' -# temporary version pinning of sysctl -# https://github.com/dev-sec/chef-os-hardening/issues/166#issuecomment-322433264 -depends 'sysctl', '<= 0.9.0' +depends 'sysctl', '>= 0.10.0' recipe 'os-hardening::default', 'harden the operating system (all recipes)' recipe 'os-hardening::limits', 'prevent core dumps' diff --git a/recipes/sysctl.rb b/recipes/sysctl.rb index 0e36082a..72f8eeee 100644 --- a/recipes/sysctl.rb +++ b/recipes/sysctl.rb @@ -20,6 +20,23 @@ # limitations under the License. # +# cleanup of old sysctl related configurations. This can be removed at some point in the future +# https://github.com/dev-sec/chef-os-hardening/issues/166#issuecomment-322433264 +# https://github.com/sous-chefs/sysctl/pull/61/files#diff-25e5d4a4446ae12a0d6f1162b6160375 +old_sysctl_conf_file = '/etc/sysctl.conf' +if platform_family?('arch', 'debian', 'rhel', 'fedora', 'amazon', 'suse') + old_sysctl_conf_file = if platform_family?('suse') && node['platform_version'].to_f < 12.0 + '/etc/sysctl.conf' + else + '/etc/sysctl.d/99-chef-attributes.conf' + end +end + +file 'cleanup of old sysctl settings' do + path old_sysctl_conf_file + action :delete +end + # default attributes # We can not set this kind of defaults in the attribute files # as we react on value of other attributes From 25f69fbc814114bee6e0269a3e735332d58dfb1d Mon Sep 17 00:00:00 2001 From: Christoph Hartmann Date: Tue, 13 Feb 2018 10:56:26 +0100 Subject: [PATCH 08/24] add support for amazon linux Signed-off-by: Christoph Hartmann --- .kitchen.yml | 3 +++ attributes/default.rb | 4 ++-- metadata.rb | 1 + recipes/minimize_access.rb | 2 +- recipes/packages.rb | 2 +- recipes/selinux.rb | 2 +- recipes/sysctl.rb | 2 +- 7 files changed, 10 insertions(+), 6 deletions(-) diff --git a/.kitchen.yml b/.kitchen.yml index 226d9b0b..4562d216 100644 --- a/.kitchen.yml +++ b/.kitchen.yml @@ -37,6 +37,9 @@ platforms: - name: opensuse-leap-42 driver_config: box: bento/opensuse-leap-42.1 +- name: amzn2 + driver_config: + box: stakahashi/amazonlinux2 provisioner: name: chef_solo diff --git a/attributes/default.rb b/attributes/default.rb index dab2b6cb..e2d4b7f0 100644 --- a/attributes/default.rb +++ b/attributes/default.rb @@ -21,7 +21,7 @@ # Define the packages based on operating system case node['platform_family'] -when 'rhel', 'fedora' +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' @@ -84,7 +84,7 @@ # RH has a bit different defaults on some places case node['platform_family'] -when 'rhel' +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 diff --git a/metadata.rb b/metadata.rb index 179985cc..23ed224b 100644 --- a/metadata.rb +++ b/metadata.rb @@ -26,6 +26,7 @@ chef_version '>= 12.5' if respond_to?(:chef_version) +supports 'amazon' supports 'ubuntu', '>= 12.04' supports 'debian', '>= 6.0' supports 'centos', '>= 5.0' diff --git a/recipes/minimize_access.rb b/recipes/minimize_access.rb index 45f4a67e..e67b7e2d 100644 --- a/recipes/minimize_access.rb +++ b/recipes/minimize_access.rb @@ -34,7 +34,7 @@ file '/etc/shadow' do owner 'root' case node['platform_family'] - when 'rhel', 'fedora' + when 'rhel', 'fedora', 'amazon' group 'root' mode '0000' when 'debian' diff --git a/recipes/packages.rb b/recipes/packages.rb index 9190d2d8..4fe4f96d 100644 --- a/recipes/packages.rb +++ b/recipes/packages.rb @@ -27,6 +27,6 @@ # do package config for rhel-family case node['platform_family'] -when 'rhel', 'fedora' +when 'rhel', 'fedora', 'amazon' include_recipe('os-hardening::yum') end diff --git a/recipes/selinux.rb b/recipes/selinux.rb index 7463dd5e..d705c44c 100644 --- a/recipes/selinux.rb +++ b/recipes/selinux.rb @@ -22,7 +22,7 @@ # SELinux enforcing support case node['platform_family'] -when 'rhel', 'fedora' +when 'rhel', 'fedora', 'amazon' unless node['os-hardening']['security']['selinux_mode'] == 'unmanaged' semode = case node['os-hardening']['security']['selinux_mode'] when 'enforcing' diff --git a/recipes/sysctl.rb b/recipes/sysctl.rb index 72f8eeee..fcd167ff 100644 --- a/recipes/sysctl.rb +++ b/recipes/sysctl.rb @@ -150,7 +150,7 @@ # NSA 2.2.4.1 Set Daemon umask # do config for rhel-family case node['platform_family'] -when 'rhel', 'fedora' +when 'rhel', 'fedora', 'amazon' template '/etc/sysconfig/init' do source 'rhel_sysconfig_init.erb' mode 0544 From 8d4e2398c78ea23a87b082149658b527c8e48aea Mon Sep 17 00:00:00 2001 From: Artem Sidorenko Date: Tue, 20 Feb 2018 10:05:45 +0100 Subject: [PATCH 09/24] Lazy pin the sysctl major version The new major release 1.0.0 does not have recipes anymore, we will have to reflect that. Pinning the major version for now. Signed-off-by: Artem Sidorenko --- metadata.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/metadata.rb b/metadata.rb index 23ed224b..6a1960c9 100644 --- a/metadata.rb +++ b/metadata.rb @@ -33,7 +33,7 @@ supports 'redhat', '>= 5.0' supports 'oracle', '>= 6.4' -depends 'sysctl', '>= 0.10.0' +depends 'sysctl', '~> 0.10' recipe 'os-hardening::default', 'harden the operating system (all recipes)' recipe 'os-hardening::limits', 'prevent core dumps' From 1abdf54ce2dce7a4eb89325eb9e8e55212ee412f Mon Sep 17 00:00:00 2001 From: Justin Spies Date: Fri, 16 Feb 2018 01:00:44 -0500 Subject: [PATCH 10/24] Allow specifying an alternate cookbook name for PAM templates --- README.md | 6 ++++++ attributes/default.rb | 3 +++ recipes/pam.rb | 3 +++ 3 files changed, 12 insertions(+) diff --git a/README.md b/README.md index 098d2bce..0acc116b 100644 --- a/README.md +++ b/README.md @@ -66,6 +66,12 @@ It will not: true if you want to use strong password checking in PAM using passwdqc * `['os-hardening']['auth']['pam']['passwdqc']['options'] = "min=disabled,disabled,16,12,8"` set to any option line (as a string) that you want to pass to passwdqc +* `['os-hardening']['auth']['pam']['passwdqc']['template_cookbook'] = 'os-hardening'` + set to the name of the cookbook from which the template is obtained for the `/usr/share/pam-configs/passwdqc` file +* `['os-hardening']['auth']['pam']['tally2']['template_cookbook'] = 'os-hardening'` + set to the name of the cookbook from which the template is obtained for the `/usr/share/pam-configs/tally2` file +* `['os-hardening']['auth']['pam']['system-auth']['template_cookbook'] = 'os-hardening'` + set to the name of the cookbook from which the template is obtained for the `/etc/pam.d/system-auth-ac` file * `['os-hardening']['security']['users']['allow'] = []` list of things, that a user is allowed to do. May contain: `change_user` * `['os-hardening']['security']['kernel']['enable_module_loading'] = true` diff --git a/attributes/default.rb b/attributes/default.rb index e2d4b7f0..857a22d3 100644 --- a/attributes/default.rb +++ b/attributes/default.rb @@ -76,6 +76,9 @@ 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']['root_ttys'] = %w[console tty1 tty2 tty3 tty4 tty5 tty6] default['os-hardening']['auth']['uid_min'] = 1000 default['os-hardening']['auth']['gid_min'] = 1000 diff --git a/recipes/pam.rb b/recipes/pam.rb index b88b674d..dce11b2b 100644 --- a/recipes/pam.rb +++ b/recipes/pam.rb @@ -50,6 +50,7 @@ # configure passwdqc via central module: template passwdqc_path do source 'pam_passwdqc.erb' + cookbook node['os-hardening']['auth']['pam']['passwdqc']['template_cookbook'] mode 0640 owner 'root' group 'root' @@ -78,6 +79,7 @@ template tally2_path do source 'pam_tally2.erb' + cookbook node['os-hardening']['auth']['pam']['tally2']['template_cookbook'] mode 0640 owner 'root' group 'root' @@ -122,6 +124,7 @@ # configure passwdqc and tally via central system-auth confic: template '/etc/pam.d/system-auth-ac' do source 'rhel_system_auth.erb' + cookbook node['os-hardening']['auth']['pam']['system-auth']['template_cookbook'] mode 0640 owner 'root' group 'root' From 9f68792ed948c526cfe275b0933f3364bdc0041a Mon Sep 17 00:00:00 2001 From: Artem Sidorenko Date: Thu, 1 Mar 2018 05:12:08 +0100 Subject: [PATCH 11/24] Flexible control of included recipes Try to detect the good defaults via ohai. Allow overriding of recipes Signed-off-by: Artem Sidorenko --- README.md | 26 +++++++++++++++++++++++--- recipes/default.rb | 39 ++++++++++++++++++++++++++++----------- 2 files changed, 51 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index 0acc116b..2fc939a1 100644 --- a/README.md +++ b/README.md @@ -35,6 +35,7 @@ It will not: ## Attributes +* `['os-hardening']['components'][COMPONENT_NAME]` - allows the fine control over which components should be executed via default recipe. See below for more details * `['os-hardening']['desktop']['enable'] = false` true if this is a desktop system, ie Xorg, KDE/GNOME/Unity/etc * `['os-hardening']['network']['forwarding'] = false` @@ -104,6 +105,22 @@ It will not: * `['os-hardening']['security']['selinux_mode'] = 'unmanaged'` set to `unmanaged` if you want to let selinux configuration as it is. Set to `enforcing` to enforce or `permissive` to permissive SELinux. +### Controlling the included components + +`default.rb` includes other components based on the ohai autodetection attributes of your system. E.g. do not execute selinux on non-RHEL systems. You can override this behavior and force components to be executed or not via setting attributes in `node['os-hardening']['components']` on the override level. Example + +```ruby +# some attribute file +# do not include sysctl and auditd +override['os-hardening']['components']['sysctl'] = false +override['os-hardening']['components']['auditd'] = false + +# force selinux to be included +override['os-hardening']['components']['selinux'] = true +``` + +In the current implementation different components are located in the different recipes. See the available recipes or `default.rb` for possible component names. + ## Usage Add the recipes to the `run_list`, it should be last: @@ -149,11 +166,12 @@ $ kitchen test ### CI testing of forks -You can enable testing of your fork in [Travis CI](http://travis-ci.org/). By default you will get linting and spec tests. +You can enable testing of your fork in [Travis CI](http://travis-ci.org/). By default you will get linting, spec tests and integration tests with [kitchen-dokken]. -Integration tests of this repository are conducted using [DigitalOcean](http://digitalocean.com/). +Integration tests with [kitchen-dokken] do not cover everything as they run in the container environment. +Full integration tests can be executed using [DigitalOcean](http://digitalocean.com/). -If you want to have integration tests for your fork, you will have to add following [environment variables](https://docs.travis-ci.com/user/environment-variables/#Defining-Variables-in-Repository-Settings) in the settings of your fork: +If you want to have full integration tests for your fork, you will have to add following [environment variables](https://docs.travis-ci.com/user/environment-variables/#Defining-Variables-in-Repository-Settings) in the settings of your fork: - `DIGITALOCEAN_ACCESS_TOKEN` - [access token for DigitalOcean](https://www.digitalocean.com/community/tutorials/how-to-use-the-digitalocean-api-v2) - `CI_SSH_KEY` - private part of some ssh key, available on DigitalOcean for your instances, in base64 encoded form (e.g. `cat id_rsa | base64 -w0 ; echo`) - `DIGITALOCEAN_SSH_KEY_IDS` - ID in DigitalOcean of `CI_SSH_KEY`, see [this](https://github.com/test-kitchen/kitchen-digitalocean#installation-and-setup) for more information @@ -165,6 +183,7 @@ If you want to have integration tests for your fork, you will have to add follow * Christoph Hartmann [chris-rock](https://github.com/chris-rock) * Edmund Haselwanter [ehaselwanter](https://github.com/ehaselwanter) * Patrick Meier [atomic111](https://github.com/atomic111) +* Artem Sidorenko [artem-sidorenko](https://github.com/artem-sidorenko) This cookbook is mostly based on guides by: @@ -202,3 +221,4 @@ limitations under the License. [3]: https://coveralls.io/r/dev-sec/chef-os-hardening [4]: https://gemnasium.com/dev-sec/chef-os-hardening [5]: https://gitter.im/dev-sec/general +[kitchen-dokken]: https://github.com/someara/kitchen-dokken diff --git a/recipes/default.rb b/recipes/default.rb index c0bed613..0b03c312 100644 --- a/recipes/default.rb +++ b/recipes/default.rb @@ -20,14 +20,31 @@ # limitations under the License. # -include_recipe('os-hardening::packages') -include_recipe('os-hardening::limits') -include_recipe('os-hardening::login_defs') -include_recipe('os-hardening::minimize_access') -include_recipe('os-hardening::pam') -include_recipe('os-hardening::profile') -include_recipe('os-hardening::securetty') -include_recipe('os-hardening::suid_sgid') if node['os-hardening']['security']['suid_sgid']['enforce'] -include_recipe('os-hardening::sysctl') -include_recipe('os-hardening::auditd') -include_recipe('os-hardening::selinux') if node['platform_family'] == 'rhel' || node['platform_family'] == 'fedora' +# here we try to determine which components should be included. +# You can control the behaviour via setting the node['os-hardening']['components'][recipe_name] +# to true (to include it) or to false (to skip it) on the override level, e.g. +# +# override['os-hardening']['components']['sysctl'] = false +# + +# generic components, include them per default +%w[packages limits login_defs minimize_access pam profile securetty].each do |cp| + node.default['os-hardening']['components'][cp] = true +end + +node.default['os-hardening']['components']['suid_sgid'] = node['os-hardening']['security']['suid_sgid']['enforce'] + +# components which are not suitable for containers +unless node['virtualization']['system'] =~ /^(lxc|docker)$/ && node['virtualization']['role'] == 'guest' + node.default['os-hardening']['components']['sysctl'] = true + node.default['os-hardening']['components']['auditd'] = true + + # selinux should be included only on RH based systems + node.default['os-hardening']['components']['selinux'] = + node['platform_family'] == 'rhel' || node['platform_family'] == 'fedora' +end + +# include all required components +node['os-hardening']['components'].each do |component, state| + include_recipe "#{cookbook_name}::#{component}" if state +end From 05106531e0c4a79351cdd2a6fdb170677f04970f Mon Sep 17 00:00:00 2001 From: Artem Sidorenko Date: Tue, 20 Feb 2018 12:37:57 +0100 Subject: [PATCH 12/24] Run dokken tests in the Travis CI for forks and DO tests on the full VMs if possible Signed-off-by: Artem Sidorenko --- .kitchen.do.local.yml => .kitchen.do.yml | 0 .kitchen.dokken.yml | 79 ++++++++++++++++++++++++ .kitchen.yml | 2 +- .travis.yml | 52 +++++++++------- Gemfile | 1 + Rakefile | 32 ++++++---- 6 files changed, 129 insertions(+), 37 deletions(-) rename .kitchen.do.local.yml => .kitchen.do.yml (100%) create mode 100644 .kitchen.dokken.yml diff --git a/.kitchen.do.local.yml b/.kitchen.do.yml similarity index 100% rename from .kitchen.do.local.yml rename to .kitchen.do.yml diff --git a/.kitchen.dokken.yml b/.kitchen.dokken.yml new file mode 100644 index 00000000..9b1eef4b --- /dev/null +++ b/.kitchen.dokken.yml @@ -0,0 +1,79 @@ +# this file is used for configuration of kitchen dokken +# for integration tests in the CI +--- +driver: + name: dokken + privileged: true # because Docker and SystemD/Upstart +<% if ENV['CHEF_VERSION'] %> + chef_version: <%= ENV['CHEF_VERSION'] %> +<% end %> + +transport: + name: dokken + +provisioner: + name: dokken + +verifier: + name: inspec + sudo: true + +platforms: +- name: ubuntu-14-04 + driver: + image: ubuntu:14.04 +- name: ubuntu-16-04 + driver: + image: ubuntu:16.04 + intermediate_instructions: + - RUN /usr/bin/apt-get update + pid_one_command: /bin/systemd +- name: centos-6 + driver: + image: centos:6 + intermediate_instructions: + - RUN yum install -y initscripts +- name: centos-7 + driver: + image: centos:7 + pid_one_command: /usr/lib/systemd/systemd +- name: oracle-6 + driver: + image: oraclelinux:6 +- name: oracle-7 + driver: + image: oraclelinux:7 + pid_one_command: /usr/lib/systemd/systemd +- name: debian-7 + driver: + image: debian:7 + intermediate_instructions: + - RUN /usr/bin/apt-get update + - RUN /usr/bin/apt-get install -y procps +- name: debian-8 + driver: + image: debian:8 + intermediate_instructions: + - RUN /usr/bin/apt-get update + - RUN /usr/bin/apt-get install -y procps + pid_one_command: /bin/systemd +- name: fedora-26 + driver: + image: fedora:26 + pid_one_command: /usr/lib/systemd/systemd + intermediate_instructions: + - RUN dnf install -y yum +- name: fedora-27 + driver: + image: fedora:27 + pid_one_command: /usr/lib/systemd/systemd + intermediate_instructions: + - RUN dnf install -y yum +- name: opensuse-42 + driver: + image: opensuse:leap + pid_one_command: /usr/lib/systemd/systemd +- name: amazonlinux-2 + driver: + image: dokken/amazonlinux-2 + pid_one_command: /usr/lib/systemd/systemd diff --git a/.kitchen.yml b/.kitchen.yml index 4562d216..5b35b1ed 100644 --- a/.kitchen.yml +++ b/.kitchen.yml @@ -37,7 +37,7 @@ platforms: - name: opensuse-leap-42 driver_config: box: bento/opensuse-leap-42.1 -- name: amzn2 +- name: amazonlinux-2 driver_config: box: stakahashi/amazonlinux2 diff --git a/.travis.yml b/.travis.yml index 4fe38ffb..76596b05 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,42 +1,48 @@ --- -sudo: false +sudo: required language: ruby bundler_args: "--without development" dist: trusty cache: bundler +services: +- docker + rvm: 2.4.1 before_install: - gem update --system # see https://github.com/bundler/bundler/issues/5357 env: - - INSTANCE=ubuntu-14-04 - - INSTANCE=ubuntu-16-04 - - INSTANCE=ubuntu-16-04 CHEF_VERSION=12.14.60 - - INSTANCE=centos-6 - - INSTANCE=centos-7 - - INSTANCE=centos-7 CHEF_VERSION=12.14.60 - - INSTANCE=debian-7 - - INSTANCE=debian-8 - - INSTANCE=fedora-26 - - INSTANCE=fedora-27 + - INSTANCE=ubuntu-14-04 KITCHEN_LOCAL_YAML=.kitchen.do.yml + - INSTANCE=ubuntu-16-04 KITCHEN_LOCAL_YAML=.kitchen.do.yml + - INSTANCE=ubuntu-16-04 CHEF_VERSION=12.14.60 KITCHEN_LOCAL_YAML=.kitchen.do.yml + - INSTANCE=centos-6 KITCHEN_LOCAL_YAML=.kitchen.do.yml + - INSTANCE=centos-7 KITCHEN_LOCAL_YAML=.kitchen.do.yml + - INSTANCE=centos-7 CHEF_VERSION=12.14.60 KITCHEN_LOCAL_YAML=.kitchen.do.yml + - INSTANCE=debian-7 KITCHEN_LOCAL_YAML=.kitchen.do.yml + - INSTANCE=debian-8 KITCHEN_LOCAL_YAML=.kitchen.do.yml + - INSTANCE=fedora-26 KITCHEN_LOCAL_YAML=.kitchen.do.yml + - INSTANCE=fedora-27 KITCHEN_LOCAL_YAML=.kitchen.do.yml + - INSTANCE=ubuntu-14-04 KITCHEN_LOCAL_YAML=.kitchen.dokken.yml + - INSTANCE=ubuntu-16-04 KITCHEN_LOCAL_YAML=.kitchen.dokken.yml + - INSTANCE=ubuntu-16-04 CHEF_VERSION=12.14.60 KITCHEN_LOCAL_YAML=.kitchen.dokken.yml + - INSTANCE=centos-6 KITCHEN_LOCAL_YAML=.kitchen.dokken.yml + - INSTANCE=centos-7 KITCHEN_LOCAL_YAML=.kitchen.dokken.yml + - INSTANCE=centos-7 CHEF_VERSION=12.14.60 KITCHEN_LOCAL_YAML=.kitchen.dokken.yml + - INSTANCE=oracle-6 KITCHEN_LOCAL_YAML=.kitchen.dokken.yml + - INSTANCE=oracle-7 KITCHEN_LOCAL_YAML=.kitchen.dokken.yml + - INSTANCE=debian-7 KITCHEN_LOCAL_YAML=.kitchen.dokken.yml + - INSTANCE=debian-8 KITCHEN_LOCAL_YAML=.kitchen.dokken.yml + - INSTANCE=fedora-26 KITCHEN_LOCAL_YAML=.kitchen.dokken.yml + - INSTANCE=fedora-27 KITCHEN_LOCAL_YAML=.kitchen.dokken.yml + - INSTANCE=opensuse-42 KITCHEN_LOCAL_YAML=.kitchen.dokken.yml + - INSTANCE=amazonlinux-2 KITCHEN_LOCAL_YAML=.kitchen.dokken.yml script: - - bundle exec rake prepare_do_env kitchen KITCHEN_LOCAL_YAML=.kitchen.do.local.yml + - bundle exec rake kitchen matrix: - allow_failures: # allow failues of integration tests as the forks might miss the DO token - - env: INSTANCE=ubuntu-14-04 - - env: INSTANCE=ubuntu-16-04 - - env: INSTANCE=ubuntu-16-04 CHEF_VERSION=12.14.60 - - env: INSTANCE=centos-6 - - env: INSTANCE=centos-7 - - env: INSTANCE=centos-7 CHEF_VERSION=12.14.60 - - env: INSTANCE=debian-7 - - env: INSTANCE=debian-8 - - env: INSTANCE=fedora-26 - - env: INSTANCE=fedora-27 include: - env: UNIT_AND_LINT=1 script: diff --git a/Gemfile b/Gemfile index 465c54ea..780d0569 100644 --- a/Gemfile +++ b/Gemfile @@ -23,6 +23,7 @@ end group :integration do gem 'kitchen-digitalocean' + gem 'kitchen-dokken' gem 'kitchen-inspec' gem 'kitchen-vagrant' gem 'test-kitchen', '~> 1.0' diff --git a/Rakefile b/Rakefile index 3a0592a6..887ae111 100644 --- a/Rakefile +++ b/Rakefile @@ -65,24 +65,30 @@ end desc 'Run kitchen integration tests' task :kitchen do + SSH_KEY_FILE = '~/.ssh/ci_id_rsa'.freeze + SSH_KEY_ENV_VAR_NAME = 'CI_SSH_KEY'.freeze concurrency = ENV['CONCURRENCY'] || 1 instance = ENV['INSTANCE'] || '' args = ENV['CI'] ? '--destroy=always' : '' - sh('sh', '-c', "bundle exec kitchen test -c #{concurrency} #{args} #{instance}") -end -desc 'Prepare CI environment for DigitalOcean usage' -task :prepare_do_env do - SSH_KEY_FILE = '~/.ssh/ci_id_rsa'.freeze - ENV_VAR_NAME = 'CI_SSH_KEY'.freeze + if ENV['CI'] && ENV['KITCHEN_LOCAL_YAML'] == '.kitchen.do.yml' + puts 'Preparing CI environment for DigitalOcean...' + + ['DIGITALOCEAN_ACCESS_TOKEN', 'DIGITALOCEAN_SSH_KEY_IDS', SSH_KEY_ENV_VAR_NAME].each do |var| + unless ENV[var] # rubocop:disable Style/Next + puts "#{var} isn't defined. Skipping the task" + # We are not raising exit 1 as we want our CI tests in the forks to succeed. + # Our forks usually do not have the DO environment variables and are tested via dokken + exit + end + end - ['DIGITALOCEAN_ACCESS_TOKEN', 'DIGITALOCEAN_SSH_KEY_IDS', ENV_VAR_NAME].each do |var| - raise "Environment variable #{var} should be set" unless ENV[var] + ssh_file = File.expand_path(SSH_KEY_FILE) + dir = File.dirname(ssh_file) + Dir.mkdir(dir, 0o700) unless Dir.exist?(dir) + File.open(ssh_file, 'w') { |f| f.puts Base64.decode64(ENV[SSH_KEY_ENV_VAR_NAME]) } + File.chmod(0o600, ssh_file) end - ssh_file = File.expand_path(SSH_KEY_FILE) - dir = File.dirname(ssh_file) - Dir.mkdir(dir, 0o700) unless Dir.exist?(dir) - File.open(ssh_file, 'w') { |f| f.puts Base64.decode64(ENV[ENV_VAR_NAME]) } - File.chmod(0o600, ssh_file) + sh('sh', '-c', "bundle exec kitchen test -c #{concurrency} #{args} #{instance}") end From cc47affe4997ca9f151415c56b3ce48d7bede350 Mon Sep 17 00:00:00 2001 From: Artem Sidorenko Date: Tue, 27 Feb 2018 20:23:55 +0100 Subject: [PATCH 13/24] Fix ubuntu /var/log permissions for containers as rsyslog isn't installed within containers, syslog group doesn't exist and the group of /var/log is root --- recipes/minimize_access.rb | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/recipes/minimize_access.rb b/recipes/minimize_access.rb index e67b7e2d..0dbc4b76 100644 --- a/recipes/minimize_access.rb +++ b/recipes/minimize_access.rb @@ -57,5 +57,10 @@ # /var/log should restricted to root or syslog on ubuntu systems directory '/var/log' do owner 'root' - group node['platform'] == 'ubuntu' ? 'syslog' : 'root' + # ubuntu with containers does not have rsyslog installed and syslog group does not exist + if node['platform'] == 'ubuntu' && node['packages']['rsyslog'] + group 'syslog' + else + group 'root' + end end From 2b6b71879da9f281f29ab355f654b55a8efa3a17 Mon Sep 17 00:00:00 2001 From: Artem Sidorenko Date: Fri, 9 Mar 2018 04:51:12 +0100 Subject: [PATCH 14/24] Require the kitchen-inspec 0.23.1 https://github.com/chef/inspec/issues/2773 --- Gemfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile b/Gemfile index 780d0569..16e92a31 100644 --- a/Gemfile +++ b/Gemfile @@ -24,7 +24,7 @@ end group :integration do gem 'kitchen-digitalocean' gem 'kitchen-dokken' - gem 'kitchen-inspec' + gem 'kitchen-inspec', '>= 0.23.1' gem 'kitchen-vagrant' gem 'test-kitchen', '~> 1.0' end From 318e0c00f9224bd161e8802878e30f128c4d38af Mon Sep 17 00:00:00 2001 From: Artem Sidorenko Date: Fri, 9 Mar 2018 13:00:47 +0100 Subject: [PATCH 15/24] Temporary disable failing tests They will be addressed in a dedicated PRs, esp to the linux-baseline --- .travis.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.travis.yml b/.travis.yml index 76596b05..879c1546 100644 --- a/.travis.yml +++ b/.travis.yml @@ -43,6 +43,12 @@ script: - bundle exec rake kitchen matrix: + allow_failures: # temporaray disable failing tests until all problems are fixed + - env: INSTANCE=ubuntu-16-04 KITCHEN_LOCAL_YAML=.kitchen.dokken.yml + - env: INSTANCE=ubuntu-16-04 CHEF_VERSION=12.14.60 KITCHEN_LOCAL_YAML=.kitchen.dokken.yml + - env: INSTANCE=centos-7 KITCHEN_LOCAL_YAML=.kitchen.dokken.yml + - env: INSTANCE=centos-7 CHEF_VERSION=12.14.60 KITCHEN_LOCAL_YAML=.kitchen.dokken.yml + - env: INSTANCE=opensuse-42 KITCHEN_LOCAL_YAML=.kitchen.dokken.yml include: - env: UNIT_AND_LINT=1 script: From 1ed3e9abfcc95455562c8a7d306a9e419b8e51cc Mon Sep 17 00:00:00 2001 From: Christoph Hartmann Date: Fri, 16 Mar 2018 19:17:40 +0100 Subject: [PATCH 16/24] improve testing around amazon linux (#202) --- .kitchen.dokken.yml | 4 ++++ .kitchen.yml | 3 +++ .travis.yml | 1 + 3 files changed, 8 insertions(+) diff --git a/.kitchen.dokken.yml b/.kitchen.dokken.yml index 9b1eef4b..d32d8cbb 100644 --- a/.kitchen.dokken.yml +++ b/.kitchen.dokken.yml @@ -73,6 +73,10 @@ platforms: driver: image: opensuse:leap pid_one_command: /usr/lib/systemd/systemd +- name: amazonlinux-1 + driver: + image: dokken/amazonlinux + pid_one_command: /sbin/init - name: amazonlinux-2 driver: image: dokken/amazonlinux-2 diff --git a/.kitchen.yml b/.kitchen.yml index 5b35b1ed..1aa9f48d 100644 --- a/.kitchen.yml +++ b/.kitchen.yml @@ -37,6 +37,9 @@ platforms: - name: opensuse-leap-42 driver_config: box: bento/opensuse-leap-42.1 +- name: amazonlinux-1 + driver_config: + box: realreadme/amazon2016.09 - name: amazonlinux-2 driver_config: box: stakahashi/amazonlinux2 diff --git a/.travis.yml b/.travis.yml index 879c1546..e850aa1a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -37,6 +37,7 @@ env: - INSTANCE=fedora-26 KITCHEN_LOCAL_YAML=.kitchen.dokken.yml - INSTANCE=fedora-27 KITCHEN_LOCAL_YAML=.kitchen.dokken.yml - INSTANCE=opensuse-42 KITCHEN_LOCAL_YAML=.kitchen.dokken.yml + - INSTANCE=amazonlinux-1 KITCHEN_LOCAL_YAML=.kitchen.dokken.yml - INSTANCE=amazonlinux-2 KITCHEN_LOCAL_YAML=.kitchen.dokken.yml script: From 4c0f7aef456500cbbeacf3dffc8a953710e119fb Mon Sep 17 00:00:00 2001 From: Christoph Hartmann Date: Fri, 16 Mar 2018 20:39:56 +0100 Subject: [PATCH 17/24] fix metadata (#204) --- README.md | 12 ++++++++++++ metadata.rb | 9 ++++++--- 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 2fc939a1..4067ae5b 100644 --- a/README.md +++ b/README.md @@ -33,6 +33,18 @@ It will not: * Cookbooks: * Sander van Zoest sysctl `https://github.com/svanzoest-cookbooks/sysctl` +### Platform + +- Debian 7, 8 +- Ubuntu 14.04, 16.04 +- RHEL 6, 7 +- CentOS 6, 7 +- Oracle Linux 6, 7 +- Fedora 26, 27 +- OpenSuse Leap 42 +- Amazon Linux 1, 2 + + ## Attributes * `['os-hardening']['components'][COMPONENT_NAME]` - allows the fine control over which components should be executed via default recipe. See below for more details diff --git a/metadata.rb b/metadata.rb index 6a1960c9..837d986a 100644 --- a/metadata.rb +++ b/metadata.rb @@ -27,11 +27,14 @@ chef_version '>= 12.5' if respond_to?(:chef_version) supports 'amazon' -supports 'ubuntu', '>= 12.04' +supports 'ubuntu', '>= 14.04' supports 'debian', '>= 6.0' -supports 'centos', '>= 5.0' -supports 'redhat', '>= 5.0' +supports 'centos', '>= 6.0' +supports 'redhat', '>= 6.0' supports 'oracle', '>= 6.4' +supports 'fedora', '>= 26.0' +supports 'suse' +supports 'opensuseleap', '>= 42.1' depends 'sysctl', '~> 0.10' From 30c5b93907f8dcb69b6dbfdc912def7050b5c5b2 Mon Sep 17 00:00:00 2001 From: Tim Smith Date: Thu, 10 May 2018 12:01:46 -0700 Subject: [PATCH 18/24] Test on Ruby 2.4.4 Signed-off-by: Tim Smith --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index e850aa1a..8c2018b6 100644 --- a/.travis.yml +++ b/.travis.yml @@ -8,7 +8,7 @@ cache: bundler services: - docker -rvm: 2.4.1 +rvm: 2.4.4 before_install: - gem update --system # see https://github.com/bundler/bundler/issues/5357 From 50c7216ded43dada810032c4666d38b669625242 Mon Sep 17 00:00:00 2001 From: Tim Smith Date: Thu, 10 May 2018 12:02:38 -0700 Subject: [PATCH 19/24] Test with Foodcritic 13 There's been a ton of bugfixes and improvements since 11.1. Signed-off-by: Tim Smith --- Gemfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile b/Gemfile index 16e92a31..e52ff532 100644 --- a/Gemfile +++ b/Gemfile @@ -8,7 +8,7 @@ gem 'chef', '~> 12.5' # chefspec builds get stucked with 13.1 group :test do gem 'chefspec', '~> 7.1.0' gem 'coveralls', require: false - gem 'foodcritic', '~> 11.1' + gem 'foodcritic', '~> 13.0' gem 'rake' gem 'rubocop', '~> 0.49.0' gem 'simplecov', '~> 0.10' From e497d988af0642fc08ab863abf0c1aed9757ce17 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Hohenga=C3=9Fner?= <34940716+dhohengassner@users.noreply.github.com> Date: Mon, 14 May 2018 11:54:00 +0200 Subject: [PATCH 20/24] use sysctl 1.0 (#210) * use sysctl cookbook 1.0 most of the code was already written by symondsandson https://github.com/symondsandson/chef-os-hardening.git remove the sysctl attributes file - values are now set in the recipe remove the lazy evaluation from symondsandson adapt test cases to test usage of sysctl_param resource * use again node attributes for sysctl param values This should be done to ensure downward compatibility and keep flexibility. See discussion on: https://github.com/dev-sec/chef-os-hardening/pull/210 --- libraries/helpers_param.rb | 39 ++++++++++++++++++ metadata.rb | 2 +- recipes/sysctl.rb | 12 +++++- spec/recipes/sysctl_spec.rb | 81 +++++++++++++++++-------------------- 4 files changed, 87 insertions(+), 47 deletions(-) create mode 100644 libraries/helpers_param.rb diff --git a/libraries/helpers_param.rb b/libraries/helpers_param.rb new file mode 100644 index 00000000..315f314c --- /dev/null +++ b/libraries/helpers_param.rb @@ -0,0 +1,39 @@ +# encoding: utf-8 + +# +# Cookbook Name:: os-hardening +# Library:: gpgcheck +# +# Copyright 2012, Dominik Richter +# Copyright 2014, Deutsche Telekom AG +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +module SysctlCookbook + module SysctlHelpers + module Param + def coerce_attributes(a, out = nil) + case a + when Array + "#{out}=#{a.join(' ')}" + when String, Integer + "#{out}=#{a}" + when Hash + out += '.' unless out.nil? + a.map { |k, v| coerce_attributes(v, "#{out}#{k}") }.flatten.sort + end + end + end + end +end diff --git a/metadata.rb b/metadata.rb index 837d986a..2957aeb5 100644 --- a/metadata.rb +++ b/metadata.rb @@ -36,7 +36,7 @@ supports 'suse' supports 'opensuseleap', '>= 42.1' -depends 'sysctl', '~> 0.10' +depends 'sysctl', '~> 1.0' recipe 'os-hardening::default', 'harden the operating system (all recipes)' recipe 'os-hardening::limits', 'prevent core dumps' diff --git a/recipes/sysctl.rb b/recipes/sysctl.rb index fcd167ff..3677ec63 100644 --- a/recipes/sysctl.rb +++ b/recipes/sysctl.rb @@ -20,6 +20,8 @@ # limitations under the License. # +::Chef::Recipe.send(:include, SysctlCookbook::SysctlHelpers::Param) + # cleanup of old sysctl related configurations. This can be removed at some point in the future # https://github.com/dev-sec/chef-os-hardening/issues/166#issuecomment-322433264 # https://github.com/sous-chefs/sysctl/pull/61/files#diff-25e5d4a4446ae12a0d6f1162b6160375 @@ -125,8 +127,14 @@ node.default['sysctl']['params']['fs']['suid_dumpable'] = node['os-hardening']['security']['kernel']['enable_core_dump'] ? 2 : 0 -# include sysctl recipe and set /etc/sysctl.d/99-chef-attributes.conf -include_recipe 'sysctl::apply' +if node.attribute?('sysctl') && node['sysctl'].attribute?('params') + coerce_attributes(node['sysctl']['params']).each do |x| + k, v = x.split('=') + sysctl_param k do + value v + end + end +end # try to determine the real cpu vendor begin diff --git a/spec/recipes/sysctl_spec.rb b/spec/recipes/sysctl_spec.rb index 9c1290f3..780e159a 100644 --- a/spec/recipes/sysctl_spec.rb +++ b/spec/recipes/sysctl_spec.rb @@ -154,15 +154,13 @@ end describe 'IPv4 forwarding' do - subject do - chef_run.node['sysctl']['params']['net']['ipv4']['ip_forward'] - end - context 'when forwarding is enabled' do let(:network_forwarding) { true } it 'should enable IPv4 forwarding in sysctl attributes' do - is_expected.to eq(1) + expect(chef_run).to apply_sysctl_param('net.ipv4.ip_forward').with( + value: '1' + ) end end @@ -170,17 +168,19 @@ let(:network_forwarding) { false } it 'should disable IPv4 forwarding in sysctl attributes' do - is_expected.to eq(0) + expect(chef_run).to apply_sysctl_param('net.ipv4.ip_forward').with( + value: '0' + ) end end end describe 'IPv6 forwarding' do RSpec.shared_examples 'IPv6 forwarding in sysctl attributes' do |state| - subject { chef_run.node['sysctl']['params']['net']['ipv6']['conf']['all']['forwarding'] } # rubocop:disable Metrics/LineLength - it "should #{state == 1 ? 'enable' : 'disable'} IPv6 forwarding in sysctl attributes" do # rubocop:disable Metrics/LineLength - is_expected.to eq(state) + expect(chef_run).to apply_sysctl_param('net.ipv6.conf.all.forwarding').with( + value: state.to_s + ) end end @@ -217,16 +217,13 @@ end describe 'Control IPv6' do - subject do - chef_run. - node['sysctl']['params']['net']['ipv6']['conf']['all']['disable_ipv6'] - end - context 'when IPv6 is enabled' do let(:ipv6_enable) { true } it 'should not disable IPv6' do - is_expected.to eq(0) + expect(chef_run).to apply_sysctl_param('net.ipv4.ip_forward').with( + value: '0' + ) end end @@ -234,7 +231,9 @@ let(:ipv6_enable) { false } it 'should not disable IPv6' do - is_expected.to eq(1) + expect(chef_run).to apply_sysctl_param('net.ipv6.conf.all.forwarding').with( + value: '0' + ) end end end @@ -242,22 +241,18 @@ describe 'ARP restrictions' do RSpec.shared_examples 'ARP restrictions in sysctl attributes' do |arp_ignore, arp_announce| # rubocop:disable Metrics/LineLength describe 'arp_ignore' do - subject do - chef_run.node['sysctl']['params']['net']['ipv4']['conf']['all']['arp_ignore'] # rubocop:disable Metrics/LineLength - end - it "should be set to #{arp_ignore}" do - is_expected.to eq(arp_ignore) + expect(chef_run).to apply_sysctl_param('net.ipv4.conf.all.arp_ignore').with( + value: arp_ignore.to_s + ) end end describe 'arp_announce' do - subject do - chef_run.node['sysctl']['params']['net']['ipv4']['conf']['all']['arp_announce'] # rubocop:disable Metrics/LineLength - end - it "should be set to #{arp_announce}" do - is_expected.to eq(arp_announce) + expect(chef_run).to apply_sysctl_param('net.ipv4.conf.all.arp_announce').with( + value: arp_announce.to_s + ) end end end @@ -276,15 +271,11 @@ end describe 'Module loading' do - subject do - chef_run.node['sysctl']['params']['kernel']['modules_disabled'] - end - context 'when module loading is enabled' do let(:enable_module_loading) { true } it 'should not set the sysctl flag' do - is_expected.to eq(nil) + expect(chef_run).to_not apply_sysctl_param('kernel.modules_disabled') end describe 'rebuild of initramfs' do @@ -304,7 +295,9 @@ let(:enable_module_loading) { false } it 'should disable module loading via sysctl flag' do - is_expected.to eq(1) + expect(chef_run).to apply_sysctl_param('kernel.modules_disabled').with( + value: '1' + ) end describe 'rebuild of initramfs' do @@ -322,15 +315,13 @@ end describe 'Control magic SysRq' do - subject do - chef_run.node['sysctl']['params']['kernel']['sysrq'] - end - context 'when sysrq is enabled' do let(:enable_sysrq) { true } it 'should enable sysrq with safe value' do - is_expected.to eq(244) + expect(chef_run).to apply_sysctl_param('kernel.sysrq').with( + value: '244' + ) end end @@ -338,21 +329,21 @@ let(:enable_sysrq) { false } it 'should disable sysrq' do - is_expected.to eq(0) + expect(chef_run).to apply_sysctl_param('kernel.sysrq').with( + value: '0' + ) end end end describe 'Core dumps with SUID' do - subject do - chef_run.node['sysctl']['params']['fs']['suid_dumpable'] - end - context 'when core dumps are enabled' do let(:enable_core_dump) { true } it 'should set suid_dumpable to safe value' do - is_expected.to eq(2) + expect(chef_run).to apply_sysctl_param('fs.suid_dumpable').with( + value: '2' + ) end end @@ -360,7 +351,9 @@ let(:enable_core_dump) { false } it 'should set suid_dumpable to default value' do - is_expected.to eq(0) + expect(chef_run).to apply_sysctl_param('fs.suid_dumpable').with( + value: '0' + ) end end end From ec105397c53de38171c8382c937b07858cc67da2 Mon Sep 17 00:00:00 2001 From: Eric Kelson Date: Mon, 14 May 2018 07:19:14 -0400 Subject: [PATCH 21/24] =?UTF-8?q?added=20mail=5Fdir=20attribute=20and=20mo?= =?UTF-8?q?ved=20component=20attributes=20to=20attributes=E2=80=A6=20(#209?= =?UTF-8?q?)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * added mail_dir attribute and moved component attributes to attributes folder from recipe file * fixed spec test * fixed lint issues --- attributes/default.rb | 5 +++++ recipes/default.rb | 5 ----- recipes/login_defs.rb | 3 ++- spec/recipes/login_defs_spec.rb | 3 ++- templates/default/login.defs.erb | 2 +- 5 files changed, 10 insertions(+), 8 deletions(-) diff --git a/attributes/default.rb b/attributes/default.rb index 857a22d3..123105b4 100644 --- a/attributes/default.rb +++ b/attributes/default.rb @@ -55,6 +55,10 @@ default['os-hardening']['packages']['auditd'] = 'audit' 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 default['os-hardening']['authconfig']['shadow']['enable'] = true default['os-hardening']['authconfig']['md5']['enable'] = true @@ -71,6 +75,7 @@ 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']['pam']['passwdqc']['options'] = 'min=disabled,disabled,16,12,8' diff --git a/recipes/default.rb b/recipes/default.rb index 0b03c312..4b64d716 100644 --- a/recipes/default.rb +++ b/recipes/default.rb @@ -27,11 +27,6 @@ # override['os-hardening']['components']['sysctl'] = false # -# generic components, include them per default -%w[packages limits login_defs minimize_access pam profile securetty].each do |cp| - node.default['os-hardening']['components'][cp] = true -end - node.default['os-hardening']['components']['suid_sgid'] = node['os-hardening']['security']['suid_sgid']['enforce'] # components which are not suitable for containers diff --git a/recipes/login_defs.rb b/recipes/login_defs.rb index 50a1ddef..7c338b07 100644 --- a/recipes/login_defs.rb +++ b/recipes/login_defs.rb @@ -39,6 +39,7 @@ sys_uid_min: node['os-hardening']['auth']['sys_uid_min'], sys_uid_max: node['os-hardening']['auth']['sys_uid_max'], sys_gid_min: node['os-hardening']['auth']['sys_gid_min'], - sys_gid_max: node['os-hardening']['auth']['sys_gid_max'] + sys_gid_max: node['os-hardening']['auth']['sys_gid_max'], + mail_dir: node['os-hardening']['auth']['maildir'] ) end diff --git a/spec/recipes/login_defs_spec.rb b/spec/recipes/login_defs_spec.rb index 1fe7d37c..c3f54a30 100644 --- a/spec/recipes/login_defs_spec.rb +++ b/spec/recipes/login_defs_spec.rb @@ -47,7 +47,8 @@ sys_uid_min: 100, sys_uid_max: 999, sys_gid_min: 100, - sys_gid_max: 999 + sys_gid_max: 999, + mail_dir: '/var/mail' } ) end diff --git a/templates/default/login.defs.erb b/templates/default/login.defs.erb index e34dfd2d..c1b329cc 100644 --- a/templates/default/login.defs.erb +++ b/templates/default/login.defs.erb @@ -23,7 +23,7 @@ # # See default PAM configuration files provided for login, su, etc. # This is a temporary situation: setting these variables will soon move to `/etc/default/useradd` and the variables will then be no more supported -MAIL_DIR /var/mail +MAIL_DIR <%= @mail_dir %> #MAIL_FILE .mail # Enable logging and display of `/var/log/faillog` login failure info. This option conflicts with the `pam_tally` PAM module. From fe0f32db6d15dd13cb121e032a5c82231386e098 Mon Sep 17 00:00:00 2001 From: Benjamin Blakely Date: Tue, 6 Feb 2018 16:39:59 -0600 Subject: [PATCH 22/24] Initial (sans Arch) auditd management support. --- attributes/default.rb | 16 +++++++++ recipes/auditd.rb | 39 ++++++++++++++++++++++ templates/default/auditd.conf.erb | 33 ++++++++++++++++++ test/integration/default/controls/tests.rb | 2 -- 4 files changed, 88 insertions(+), 2 deletions(-) create mode 100644 templates/default/auditd.conf.erb diff --git a/attributes/default.rb b/attributes/default.rb index 123105b4..d071c6c5 100644 --- a/attributes/default.rb +++ b/attributes/default.rb @@ -228,3 +228,19 @@ # set default cpu vendor default['os-hardening']['security']['cpu_vendor'] = 'intel' + +# auditd config +default['os-hardening']['auditd']['flush'] = 'INCREMENTAL' +default['os-hardening']['auditd']['log_group'] = 'root' +default['os-hardening']['auditd']['priority_boost'] = '4' +default['os-hardening']['auditd']['freq'] = '20' +default['os-hardening']['auditd']['num_logs'] = '5' +default['os-hardening']['auditd']['disp_qos'] = 'lossy' +default['os-hardening']['auditd']['dispatcher'] = '/sbin/audispd' +default['os-hardening']['auditd']['name_format'] = 'NONE' +default['os-hardening']['auditd']['max_log_file'] = '6' +default['os-hardening']['auditd']['tcp_listen_queue'] = '5' +default['os-hardening']['auditd']['tcp_max_per_addr'] = '1' +default['os-hardening']['auditd']['tcp_client_max_idle'] = '0' +default['os-hardening']['auditd']['enable_krb5'] = 'no' +default['os-hardening']['auditd']['krb5_principal'] = 'auditd' diff --git a/recipes/auditd.rb b/recipes/auditd.rb index 34cfe29b..00ffc959 100644 --- a/recipes/auditd.rb +++ b/recipes/auditd.rb @@ -20,3 +20,42 @@ # package node['os-hardening']['packages']['auditd'] + +service "auditd" do + supports [:start, :stop, :restart, :reload, :status] + if (node['platform_family'] == 'rhel' && node['platform_version'].to_f >= 7) || + (node['platform_family'] == 'fedora' && node['platform_version'].to_f >= 27) + restart_command 'service auditd restart' + end + action [ :enable ] +end +unless (node['os-hardening']['auditd']['flush'].match? /^INCREMENTAL|INCREMENTAL_ASYNC$/ || + node['os-hardening']['auditd']['flush'].empty?) + Chef::Log.fatal('If specifying a value for auditd flush parameter, must be one of INCREMENTAL or INCREMENTAL_ASYNC') + raise +end + +template '/etc/audit/auditd.conf' do + source 'auditd.conf.erb' + mode '0400' + owner 'root' + group 'root' + variables( + flush: node['os-hardening']['auditd']['flush'], + log_group: node['os-hardening']['auditd']['log_group'], + priority_boost: node['os-hardening']['auditd']['priority_boost'], + freq: node['os-hardening']['auditd']['freq'], + num_logs: node['os-hardening']['auditd']['num_logs'], + disp_qos: node['os-hardening']['auditd']['disp_qos'], + dispatcher: node['os-hardening']['auditd']['dispatcher'], + name_format: node['os-hardening']['auditd']['name_format'], + max_log_file: node['os-hardening']['auditd']['max_log_file'], + tcp_listen_queue: node['os-hardening']['auditd']['tcp_listen_queue'], + tcp_max_per_addr: node['os-hardening']['auditd']['tcp_max_per_addr'], + tcp_client_max_idle: node['os-hardening']['auditd']['tcp_client_max_idle'], + enable_krb5: node['os-hardening']['auditd']['enable_krb5'], + krb5_principal: node['os-hardening']['auditd']['krb5_principal'] + ) + notifies :restart, 'service[auditd]' + action :create +end diff --git a/templates/default/auditd.conf.erb b/templates/default/auditd.conf.erb new file mode 100644 index 00000000..9a841b34 --- /dev/null +++ b/templates/default/auditd.conf.erb @@ -0,0 +1,33 @@ +<% node['config_disclaimer'].to_s.split("\n").each do |l| %> +# <%= l %> +<% end %> +# +#-- + +# Specified by linux-baseline +log_file = /var/log/audit/audit.log +log_format = RAW +flush = <%= @flush %> +max_log_file_action = keep_logs +space_left = 75 +action_mail_acct = root +space_left_action = SYSLOG +admin_space_left = 50 +admin_space_left_action = SUSPEND +disk_full_action = SUSPEND +disk_error_action = SUSPEND + +# Unspecified, auditd defaults unless overwritten +log_group = <%= @log_group %> +priority_boost = <%= @priority_boost %> +freq = <%= @freq %> +num_logs = <%= @num_logs %> +disp_qos = <%= @disp_qos %> +dispatcher = <%= @dispatcher %> +name_format = <%= @name_format %> +max_log_file = <%= @max_log_file %> +tcp_listen_queue = <%= @tcp_listen_queue %> +tcp_max_per_addr = <%= @tcp_max_per_addr %> +tcp_client_max_idle = <%= @tcp_client_max_idle %> +enable_krb5 = <%= @enable_krb5 %> +krb5_principal = <%= @krb5_principal %> diff --git a/test/integration/default/controls/tests.rb b/test/integration/default/controls/tests.rb index c1913a29..7b58667d 100644 --- a/test/integration/default/controls/tests.rb +++ b/test/integration/default/controls/tests.rb @@ -2,6 +2,4 @@ # skip entropy test, as our short living test VMs usually do not # have enough skip_control 'os-08' - # skip auditd tests, we do not have any implementation for audit management yet - skip_control 'package-08' end From a91787ae586c68ad587581dc169277d0d0694169 Mon Sep 17 00:00:00 2001 From: Benjamin Blakely Date: Tue, 6 Feb 2018 16:42:06 -0600 Subject: [PATCH 23/24] Newline for readability. --- recipes/auditd.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/recipes/auditd.rb b/recipes/auditd.rb index 00ffc959..132484f6 100644 --- a/recipes/auditd.rb +++ b/recipes/auditd.rb @@ -29,6 +29,7 @@ end action [ :enable ] end + unless (node['os-hardening']['auditd']['flush'].match? /^INCREMENTAL|INCREMENTAL_ASYNC$/ || node['os-hardening']['auditd']['flush'].empty?) Chef::Log.fatal('If specifying a value for auditd flush parameter, must be one of INCREMENTAL or INCREMENTAL_ASYNC') From b6c226b1808126504dca6442830af1859d2fa315 Mon Sep 17 00:00:00 2001 From: Benjamin Blakely Date: Wed, 7 Feb 2018 16:17:08 -0600 Subject: [PATCH 24/24] Fixed syntax error on string match --- recipes/auditd.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/recipes/auditd.rb b/recipes/auditd.rb index 132484f6..c21749f1 100644 --- a/recipes/auditd.rb +++ b/recipes/auditd.rb @@ -30,7 +30,7 @@ action [ :enable ] end -unless (node['os-hardening']['auditd']['flush'].match? /^INCREMENTAL|INCREMENTAL_ASYNC$/ || +unless (node['os-hardening']['auditd']['flush'].match(/^INCREMENTAL|INCREMENTAL_ASYNC$/) || node['os-hardening']['auditd']['flush'].empty?) Chef::Log.fatal('If specifying a value for auditd flush parameter, must be one of INCREMENTAL or INCREMENTAL_ASYNC') raise