diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml new file mode 100644 index 0000000..33f4a5c --- /dev/null +++ b/.github/workflows/test.yml @@ -0,0 +1,27 @@ +name: Test + +on: + push: + branches: [ master ] + pull_request: + branches: [ master ] + schedule: + - cron: '0 6 * * *' + +jobs: + test: + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + ruby-version: ['2.6', '2.7', '3.0'] + + steps: + - uses: actions/checkout@v2 + - name: Set up Ruby + uses: ruby/setup-ruby@v1 + with: + ruby-version: ${{ matrix.ruby-version }} + bundler-cache: true # runs 'bundle install' and caches installed gems automatically + - name: Run tests + run: bundle exec rake diff --git a/.rubocop.yml b/.rubocop.yml index 31aeeb6..e836519 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -4,27 +4,33 @@ AllCops: - vendor/**/* Documentation: Enabled: false -AlignParameters: +Layout/ParameterAlignment: Enabled: true -Encoding: - Enabled: false HashSyntax: Enabled: true LineLength: Enabled: false EmptyLinesAroundBlockBody: Enabled: false +Style/Encoding: + Enabled: false MethodLength: Max: 40 NumericLiterals: MinDigits: 10 +Metrics/BlockLength: + Max: 45 # needed for 6.1.1 Metrics/CyclomaticComplexity: Max: 10 Metrics/PerceivedComplexity: Max: 10 Metrics/AbcSize: - Max: 29 -Metrics/BlockLength: - Max: 29 -AllCops: - TargetRubyVersion: 2.2 + Max: 30 +# Lint/AmbiguousBlockAssociation is incompatible with RSpec +# https://github.com/rubocop-hq/rubocop/issues/4222 +Lint/AmbiguousBlockAssociation: + Enabled: false +Lint/AmbiguousRegexpLiteral: + Enabled: false +Style/NumericPredicate: + Enabled: false diff --git a/Gemfile b/Gemfile index da0008c..a076fc4 100644 --- a/Gemfile +++ b/Gemfile @@ -1,12 +1,18 @@ -source 'https://rubygems.org' +# frozen_string_literal: true -gem 'highline', '~> 1.6.0' +source 'https://rubygems.org' -gem 'inspec', '~> 2' -gem 'rack', '1.6.4' +gem 'highline' +gem 'rack' gem 'rake' -gem 'rubocop', '~> 0.49.0' +gem 'rubocop' group :tools do - gem 'github_changelog_generator', '~> 1.14.0' + gem 'github_changelog_generator' + gem 'pry-coolline' +end + +source 'https://packagecloud.io/cinc-project/stable' do + gem 'chef-config' + gem 'cinc-auditor-bin' end diff --git a/Rakefile b/Rakefile index ebf65df..ed8b932 100755 --- a/Rakefile +++ b/Rakefile @@ -1,5 +1,4 @@ -#!/usr/bin/env rake -# encoding: utf-8 +# frozen_string_literal: true require 'rake/testtask' require 'rubocop/rake_task' @@ -20,23 +19,9 @@ task default: [:lint, 'test:check'] namespace :test do # run inspec check to verify that the profile is properly configured task :check do - dir = File.join(File.dirname(__FILE__)) - sh("bundle exec inspec check #{dir}") + require 'inspec' + puts "Checking profile with InSpec Version: #{Inspec::VERSION}" + profile = Inspec::Profile.for_target('.', backend: Inspec::Backend.create(Inspec::Config.mock)) + pp profile.check end end - -# Automatically generate a changelog for this project. Only loaded if -# the necessary gem is installed. By default its picking up the version from -# inspec.yml. You can override that behavior with `rake changelog to=1.2.0` -begin - require 'yaml' - metadata = YAML.load_file('inspec.yml') - v = ENV['to'] || metadata['version'] - puts "Generate changelog for version #{v}" - require 'github_changelog_generator/task' - GitHubChangelogGenerator::RakeTask.new :changelog do |config| - config.future_release = v - end -rescue LoadError - puts '>>>>> GitHub Changelog Generator not loaded, omitting tasks' -end diff --git a/Vagrantfile b/Vagrantfile index 2b625a2..de9e2e9 100644 --- a/Vagrantfile +++ b/Vagrantfile @@ -1,4 +1,5 @@ # encoding: utf-8 +# frozen_string_literal: true # -*- mode: ruby -*- # vi: set ft=ruby : diff --git a/controls/container_images.rb b/controls/container_images.rb index 229b436..8146ac4 100644 --- a/controls/container_images.rb +++ b/controls/container_images.rb @@ -23,7 +23,7 @@ title 'Container Images and Build File' # attributes -CONTAINER_USER = attribute('container_user') +CONTAINER_USER = input('container_user') # check if docker exists only_if('docker not found') do diff --git a/controls/container_runtime.rb b/controls/container_runtime.rb index 2a63bb9..ae27dc2 100644 --- a/controls/container_runtime.rb +++ b/controls/container_runtime.rb @@ -23,9 +23,9 @@ title 'Container Runtime' # attributes -CONTAINER_CAPADD = attribute('container_capadd') -APP_ARMOR_PROFILE = attribute('app_armor_profile') -SELINUX_PROFILE = attribute('selinux_profile') +CONTAINER_CAPADD = input('container_capadd') +APP_ARMOR_PROFILE = input('app_armor_profile') +SELINUX_PROFILE = input('selinux_profile') # check if docker exists only_if('docker not found') do @@ -153,13 +153,13 @@ info['Mounts'].each do |mounts| describe mounts['Source'] do it { should_not eq '/' } - it { should_not match(%r{\/boot}) } - it { should_not match(%r{\/dev}) } - it { should_not match(%r{\/etc}) } - it { should_not match(%r{\/lib}) } - it { should_not match(%r{\/proc}) } - it { should_not match(%r{\/sys}) } - it { should_not match(%r{\/usr}) } + it { should_not match(%r{/boot}) } + it { should_not match(%r{/dev}) } + it { should_not match(%r{/etc}) } + it { should_not match(%r{/lib}) } + it { should_not match(%r{/proc}) } + it { should_not match(%r{/sys}) } + it { should_not match(%r{/usr}) } end end end @@ -185,7 +185,7 @@ ref 'Why you don\'t need to run SSHd in your Docker containers', url: 'https://blog.docker.com/2014/06/why-you-dont-need-to-run-sshd-in-docker/' docker.containers.running?.ids.each do |id| - execute_command = 'docker exec ' + id + ' ps -e' + execute_command = "docker exec #{id} ps -e" describe command(execute_command) do its('stdout') { should_not match(/ssh/) } end @@ -209,8 +209,10 @@ docker.containers.running?.ids.each do |id| container_info = docker.object(id) next if container_info['NetworkSettings']['Ports'].nil? + container_info['NetworkSettings']['Ports'].each do |_, hosts| next if hosts.nil? + hosts.each do |host| describe host['HostPort'].to_i.between?(1, 1024) do it { should eq false } @@ -341,8 +343,10 @@ docker.containers.running?.ids.each do |id| container_info = docker.object(id) next if container_info['NetworkSettings']['Ports'].nil? + container_info['NetworkSettings']['Ports'].each do |_, hosts| next if hosts.nil? + hosts.each do |host| describe host['HostIp'].to_i.between?(1, 1024) do it { should_not eq '0.0.0.0' } diff --git a/controls/docker_daemon_configuration.rb b/controls/docker_daemon_configuration.rb index 73ecba4..8a69ace 100644 --- a/controls/docker_daemon_configuration.rb +++ b/controls/docker_daemon_configuration.rb @@ -23,16 +23,16 @@ title 'Docker Daemon Configuration' # attributes -DAEMON_TLSCACERT = attribute('daemon_tlscacert') -DAEMON_TLSCERT = attribute('daemon_tlscert') -DAEMON_TLSKEY = attribute('daemon_tlskey') -AUTHORIZATION_PLUGIN = attribute('authorization_plugin') -LOG_DRIVER = attribute('log_driver') -LOG_OPTS = attribute('log_opts') -SWARM_MODE = attribute('swarm_mode') -SWARM_MAX_MANAGER_NODES = attribute('swarm_max_manager_nodes') -SWARM_PORT = attribute('swarm_port') -SECCOMP_DEFAULT_PROFILE = attribute('seccomp_default_profile') +DAEMON_TLSCACERT = input('daemon_tlscacert') +DAEMON_TLSCERT = input('daemon_tlscert') +DAEMON_TLSKEY = input('daemon_tlskey') +AUTHORIZATION_PLUGIN = input('authorization_plugin') +LOG_DRIVER = input('log_driver') +LOG_OPTS = input('log_opts') +SWARM_MODE = input('swarm_mode') +SWARM_MAX_MANAGER_NODES = input('swarm_max_manager_nodes') +SWARM_PORT = input('swarm_port') +SECCOMP_DEFAULT_PROFILE = input('seccomp_default_profile') # check if docker exists only_if('docker not found') do @@ -168,8 +168,8 @@ ref 'Docker daemon deafult ulimits', url: 'https://docs.docker.com/engine/reference/commandline/daemon/#default-ulimits' describe json('/etc/docker/daemon.json') do - its(['default-ulimits', 'nproc']) { should eq('1024:2408') } - its(['default-ulimits', 'nofile']) { should eq('100': '200') } + its(%w[default-ulimits nproc]) { should eq('1024:2408') } + its(%w[default-ulimits nofile]) { should eq('100': '200') } end end diff --git a/controls/docker_daemon_configuration_files.rb b/controls/docker_daemon_configuration_files.rb index 8f6817f..dfad4d0 100644 --- a/controls/docker_daemon_configuration_files.rb +++ b/controls/docker_daemon_configuration_files.rb @@ -23,9 +23,9 @@ title 'Docker Daemon Configuration Files' # attributes -REGISTRY_CERT_PATH = attribute('registry_cert_path') -REGISTRY_NAME = attribute('registry_name') -REGISTRY_CA_FILE = attribute('registry_ca_file') +REGISTRY_CERT_PATH = input('registry_cert_path') +REGISTRY_NAME = input('registry_name') +REGISTRY_CA_FILE = input('registry_ca_file') # check if docker exists only_if('docker not found') do diff --git a/controls/host_configuration.rb b/controls/host_configuration.rb index 8c4b168..47e8c0b 100644 --- a/controls/host_configuration.rb +++ b/controls/host_configuration.rb @@ -22,9 +22,9 @@ title 'Host Configuration' -TRUSTED_USER = attribute('trusted_user') -MANAGEABLE_CONTAINER_NUMBER = attribute('managable_container_number') -BENCHMARK_VERSION = attribute('benchmark_version') +TRUSTED_USER = input('trusted_user') +MANAGEABLE_CONTAINER_NUMBER = input('managable_container_number') +BENCHMARK_VERSION = input('benchmark_version') # check if docker exists only_if('docker not found') do @@ -233,7 +233,7 @@ only_if { os.linux? } if docker_helper.path - rule = '-w ' + docker_helper.path + ' -p rwxa -k docker' + rule = "-w #{docker_helper.path} -p rwxa -k docker" describe auditd do its(:lines) { should include(rule) } end @@ -259,7 +259,7 @@ only_if { os.linux? } if docker_helper.socket - rule = '-w ' + docker_helper.socket + ' -p rwxa -k docker' + rule = "-w #{docker_helper.socket} -p rwxa -k docker" describe auditd do its(:lines) { should include(rule) } end diff --git a/inspec.yml b/inspec.yml index 7e14ad1..02b7965 100644 --- a/inspec.yml +++ b/inspec.yml @@ -7,7 +7,7 @@ copyright_email: hello@dev-sec.io license: Apache-2.0 summary: An InSpec Compliance Profile for the CIS Docker Benchmark version: 2.1.3 -inspec_version: '>= 2.3.23' +inspec_version: '>= 4.6.3' attributes: - name: container_user required: false diff --git a/libraries/docker_helper.rb b/libraries/docker_helper.rb index 6a30676..169e592 100644 --- a/libraries/docker_helper.rb +++ b/libraries/docker_helper.rb @@ -1,4 +1,5 @@ # encoding: utf-8 +# frozen_string_literal: true # Copyright 2016, Christoph Hartmann #