From 49385e26680bfa87c777bf724a4512431fc5662a Mon Sep 17 00:00:00 2001 From: Patrick Meier Date: Thu, 26 Nov 2015 10:57:53 +0100 Subject: [PATCH] removed serverspec from lockdown folder and added inspec to it Signed-off-by: Patrick Meier --- lockdown/inspec/os_spec.rb | 164 +++++++++++++ lockdown/inspec/sysctl_spec.rb | 352 ++++++++++++++++++++++++++++ lockdown/serverspec/modules_spec.rb | 32 --- lockdown/serverspec/os_spec.rb | 108 --------- lockdown/serverspec/spec_helper.rb | 63 ----- lockdown/serverspec/sysctl_spec.rb | 207 ---------------- 6 files changed, 516 insertions(+), 410 deletions(-) create mode 100644 lockdown/inspec/os_spec.rb create mode 100644 lockdown/inspec/sysctl_spec.rb delete mode 100644 lockdown/serverspec/modules_spec.rb delete mode 100644 lockdown/serverspec/os_spec.rb delete mode 100644 lockdown/serverspec/spec_helper.rb delete mode 100644 lockdown/serverspec/sysctl_spec.rb diff --git a/lockdown/inspec/os_spec.rb b/lockdown/inspec/os_spec.rb new file mode 100644 index 0000000..f9762be --- /dev/null +++ b/lockdown/inspec/os_spec.rb @@ -0,0 +1,164 @@ +# encoding: utf-8 +# +# Copyright 2015, Patrick Münch +# +# 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. +# +# author: Christoph Hartmann +# author: Dominik Richter +# author: Patrick Münch + +control '01' do + impact 1.0 + title "Trusted hosts login" + desc "Rhosts/hosts.equiv files are a weak implemenation of authentication. Disabling the .rhosts and hosts.equiv support helps to prevent users from subverting the system's normal access control mechanisms of the system." + describe command('find / -name \'.rhosts\'') do + its('stdout') { should be_empty } + end + describe command('find / -name \'hosts.equiv\' ') do + its('stdout') { should be_empty } + end +end + +control '02' do + impact 1.0 + title "Check owner and permissions for /etc/shadow " + desc "Check periodically the owner and permissions for /etc/shadow" + describe file('/etc/shadow') do + it { should exist } + it { should be_file } + it { should be_owned_by 'root' } + its('group') { should eq 'root' } + it { should_not be_executable } + it { should be_writable.by('owner') } + it { should be_readable.by('owner') } + it { should_not be_readable.by('group') } + it { should_not be_readable.by('other') } + end +end + +control '03' do + impact 1.0 + title "Check owner and permissions for /etc/passwd " + desc "Check periodically the owner and permissions for /etc/passwd" + describe file('/etc/passwd') do + it { should exist } + it { should be_file } + it { should be_owned_by 'root' } + its('group') { should eq 'root' } + it { should_not be_executable } + it { should be_writable.by('owner') } + it { should_not be_writable.by('group') } + it { should_not be_writable.by('other') } + it { should be_readable.by('owner') } + it { should be_readable.by('group') } + it { should be_readable.by('other') } + end +end + +control '04' do + impact 1.0 + title "Dot in PATH variable" + desc "Do not include the current working directory in PATH variable. This makes it easier for an attacker to gain extensive rigths by executing a Trojan program" + describe os_env('PATH') do + its('split') { should_not include('') } + its('split') { should_not include('.') } + end +end + +control '05' do + impact 1.0 + title "Check login.defs" + desc "Check owner and permissions for login.defs. Also check the configured PATH variable and umask in login.defs" + describe file('/etc/login.defs') do + it { should exist } + it { should be_file } + it { should be_owned_by 'root' } + its('group') { should eq 'root' } + it { should_not be_executable } + it { should_not be_writable } + it { should be_readable.by('owner') } + it { should be_readable.by('group') } + it { should be_readable.by('other') } + end + describe login_defs do + its('ENV_SUPATH') { should include('/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin') } + its('ENV_PATH') { should include('/usr/local/bin:/usr/bin:/bin') } + its('UMASK') { should include('027') } + its('PASS_MAX_DAYS') { should eq '60' } + its('PASS_MIN_DAYS') { should eq '7' } + its('PASS_WARN_AGE') { should eq '7' } + its('LOGIN_RETRIES') { should eq '5' } + its('LOGIN_TIMEOUT') { should eq '60' } + its('UID_MIN') { should eq '1000' } + its('GID_MIN') { should eq '1000' } + its('SYS_UID_MIN') { should eq '100' } + its('SYS_UID_MAX') { should eq '999' } + its('SYS_GID_MIN') { should eq '100' } + its('SYS_GID_MAX') { should eq '999' } + its('ENCRYPT_METHOD') { should eq 'SHA512' } + end +end + +control '06' do + impact 1.0 + title "Check for SUID/ SGID blacklist " + desc "Find blacklisted SUID and SGID files to ensure that no rogue SUID and SGID files have been introduced into the 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/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 + ] + + output = command('find / -perm -4000 -o -perm -2000 -type f ! -path \'/proc/*\' -print 2>/dev/null | grep -v \'^find:\'') + diff = output.stdout.split(/\r?\n/) & blacklist + describe diff do + it {should be_empty} + end +end + +control '07' do + impact 1.0 + title "Unique uid and gid" + desc "Check for unique uids gids" + describe passwd do + its('uids') { should_not contain_duplicates } + end + describe etc_group do + its('gids') { should_not contain_duplicates } + end +end diff --git a/lockdown/inspec/sysctl_spec.rb b/lockdown/inspec/sysctl_spec.rb new file mode 100644 index 0000000..ad2bd0f --- /dev/null +++ b/lockdown/inspec/sysctl_spec.rb @@ -0,0 +1,352 @@ +# encoding: utf-8 +# +# Copyright 2015, Patrick Münch +# +# 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. +# +# author: Christoph Hartmann +# author: Dominik Richter +# author: Patrick Münch + +control '01' do + impact 1.0 + title "IPv4 Forwarding" + desc "If you're not intending for your system to forward traffic between interfaces, or if you only have a single interface, the forwarding function must be disable." + describe kernel_parameter('net.ipv4.ip_forward') do + its(:value) { should eq 0 } + end + describe kernel_parameter('net.ipv4.conf.all.forwarding') do + its(:value) { should eq 0 } + end +end + +control '02' do + impact 1.0 + title "Reverse path filtering" + desc "The rp_filter can reject incoming packets if their source address doesn't match the network interface that they're arriving on, which helps to prevent IP spoofing." + describe kernel_parameter('net.ipv4.conf.all.rp_filter') do + its(:value) { should eq 1 } + end + describe kernel_parameter('net.ipv4.conf.default.rp_filter') do + its(:value) { should eq 1 } + end +end + +control '03' do + impact 1.0 + title "ICMP ignore bogus error responses" + desc "Sometimes routers send out invalid responses to broadcast frames. This is a violation of RFC 1122 and the kernel will logged this. To avoid filling up your logfile with unnecessary stuff, you can tell the kernel not to issue these warnings" + describe kernel_parameter('net.ipv4.icmp_ignore_bogus_error_responses') do + its(:value) { should eq 1 } + end +end + +control '04' do + impact 1.0 + title "ICMP echo ignore broadcasts" + desc "Blocking ICMP ECHO requests to broadcast addresses" + describe kernel_parameter('net.ipv4.icmp_echo_ignore_broadcasts') do + its(:value) { should eq 1 } + end +end + +control '05' do + impact 1.0 + title "ICMP ratelimit" + desc "icmp_ratelimit defines how many packets that match the icmp_ratemask per second" + describe kernel_parameter('net.ipv4.icmp_ratelimit') do + its(:value) { should eq 100 } + end +end + +control '06' do + impact 1.0 + title "ICMP ratemask" + desc "Ratemask is a logical OR of all ICMP codes to rate limit" + describe kernel_parameter('net.ipv4.icmp_ratemask') do + its(:value) { should eq 88089 } + end +end + +control '07' do + impact 1.0 + title "TCP timestamps" + desc "It is possible to estimate the current uptime of a Linux system. It's preferable to disable TCP timestamps on your systems." + describe kernel_parameter('net.ipv4.tcp_timestamps') do + its(:value) { should eq 0 } + end +end + +control '08' do + impact 1.0 + title "ARP ignore" + desc "Reply only if the target IP address is local address configured on the incoming interface." + describe kernel_parameter('net.ipv4.conf.all.arp_ignore') do + its(:value) { should eq 1 } + end +end + +control '09' do + impact 1.0 + title "ARP announce" + desc "Always use the best local address for this target. In this mode we ignore the source address in the IP packet and try to select local address that we prefer for talks with the target host." + describe kernel_parameter('net.ipv4.conf.all.arp_announce') do + its(:value) { should eq 2 } + end +end + +control '10' do + impact 1.0 + title "TCP RFC1337 Protect Against TCP Time-Wait" + desc "This enables a fix for time-wait assassination hazards in tcp, described in RFC 1337. If enabled, this causes the kernel to drop RST packets for sockets in the time-wait state." + describe kernel_parameter('net.ipv4.tcp_rfc1337') do + its(:value) { should eq 1 } + end +end + +control '11' do + impact 1.0 + title "Protection against SYN flood attacks" + desc "A SYN-Attack is a denial of service (DoS) attack that consumes resources on your system forcing you to reboot." + describe kernel_parameter('net.ipv4.tcp_syncookies') do + its(:value) { should eq 1 } + end +end + +control '12' do + impact 1.0 + title "Shared Media IP Architecture" + desc "Send(router) or accept(host) RFC1620 shared media redirects. If it is not set the kernel does not assume that different subnets on this device can communicate directly." + describe kernel_parameter('net.ipv4.conf.all.shared_media') do + its(:value) { should eq 1 } + end + describe kernel_parameter('net.ipv4.conf.default.shared_media') do + its(:value) { should eq 1 } + end +end + +control '13' do + impact 1.0 + title "Disable Source Routing" + desc "The accept_source_route option causes network interfaces to accept packets with the Strict Source Route (SSR) or Loose Source Routing (LSR) option set. An attacker is able to send a source routed packet into the network, then he could intercept the replies and your server might not know that it is not communicating with a trusted server" + describe kernel_parameter('net.ipv4.conf.all.accept_source_route') do + its(:value) { should eq 0 } + end + describe kernel_parameter('net.ipv4.conf.default.accept_source_route') do + its(:value) { should eq 0 } + end +end + +control '14' do + impact 1.0 + title "Disable acceptance of all IPv4 redirected packets" + desc "Disable acceptance of all redirected packets these prevents Man-in-the-Middle attacks." + describe kernel_parameter('net.ipv4.conf.default.accept_redirects') do + its(:value) { should eq 0 } + end + describe kernel_parameter('net.ipv4.conf.all.accept_redirects') do + its(:value) { should eq 0 } + end +end + +control '15' do + impact 1.0 + title "Disable acceptance of all secure redirected packets" + desc "Disable acceptance of all secure redirected packets these prevents Man-in-the-Middle attacks." + describe kernel_parameter('net.ipv4.conf.all.secure_redirects') do + its(:value) { should eq 0 } + end + describe kernel_parameter('net.ipv4.conf.default.secure_redirects') do + its(:value) { should eq 0 } + end +end + +control '16' do + impact 1.0 + title "Disable sending of redirects packets" + desc "Disable sending of redirects packets" + describe kernel_parameter('net.ipv4.conf.all.send_redirects') do + its(:value) { should eq 0 } + end + describe kernel_parameter('net.ipv4.conf.all.send_redirects') do + its(:value) { should eq 0 } + end +end + +control '17' do + impact 1.0 + title "Disable log martians" + desc "log_martians can cause a denial of service attack to the host" + describe kernel_parameter('net.ipv4.conf.all.log_martians') do + its(:value) { should eq 0 } + end +end + +control '18' do + impact 1.0 + title "Disable IPv6 if it is not needed" + desc "Disable IPv6 if it is not needed" + describe kernel_parameter('net.ipv6.conf.all.disable_ipv6') do + its(:value) { should eq 1 } + end +end + +control '19' do + impact 1.0 + title "IPv6 Forwarding" + desc "If you're not intending for your system to forward traffic between interfaces, or if you only have a single interface, the forwarding function must be disable." + describe kernel_parameter('net.ipv6.conf.all.forwarding') do + its(:value) { should eq 0 } + end +end + +control '20' do + impact 1.0 + title "Disable acceptance of all IPv6 redirected packets" + desc "Disable acceptance of all redirected packets these prevents Man-in-the-Middle attacks." + describe kernel_parameter('net.ipv6.conf.default.accept_redirects') do + its(:value) { should eq 0 } + end + describe kernel_parameter('net.ipv6.conf.all.accept_redirects') do + its(:value) { should eq 0 } + end +end + +control '21' do + impact 1.0 + title "Disable acceptance of IPv6 router solicitations messages" + desc "The router solicitations setting determines how many router solicitations are sent when bringing up the interface. If addresses are statically assigned, there is no need to send any solicitations." + describe kernel_parameter('net.ipv6.conf.default.router_solicitations') do + its(:value) { should eq 0 } + end +end + +control '22' do + impact 1.0 + title "Disable Accept Router Preference from router advertisement" + desc "Disable Accept Router Preference from router advertisement" + describe kernel_parameter('net.ipv6.conf.default.accept_ra_rtr_pref') do + its(:value) { should eq 0 } + end +end + +control '23' do + impact 1.0 + title "Disable learning Prefix Information from router advertisement" + desc "The accept_ra_pinfo setting controls whether the system will accept prefix info from the router." + describe kernel_parameter('net.ipv6.conf.default.accept_ra_pinfo') do + its(:value) { should eq 0 } + end +end + +control '24' do + impact 1.0 + title "Disable learning Hop limit from router advertisement" + desc "The accept_ra_defrtr setting controls whether the system will accept Hop Limit settings from a router advertisement. Setting it to 0 prevents a router from changing your default IPv6 Hop Limit for outgoing packets." + describe kernel_parameter('net.ipv6.conf.default.accept_ra_defrtr') do + its(:value) { should eq 0 } + end +end + +control '25' do + impact 1.0 + title "Disable the system’s acceptance of router advertisement" + desc "Setting controls whether the system will accept router advertisement" + describe kernel_parameter('net.ipv6.conf.all.accept_ra') do + its(:value) { should eq 0 } + end + describe kernel_parameter('net.ipv6.conf.default.accept_ra') do + its(:value) { should eq 0 } + end +end + +control '26' do + impact 1.0 + title "Disable IPv6 autoconfiguration" + desc "The autoconf setting controls whether router advertisements can cause the system to assign a global unicast address to an interface." + describe kernel_parameter('net.ipv6.conf.default.autoconf') do + its(:value) { should eq 0 } + end +end + +control '27' do + impact 1.0 + title "Disable neighbor solicitations to send out per address" + desc "The dad_transmits setting determines how many neighbor solicitations to send out per address (global and link-local) when bringing up an interface to ensure the desired address is unique on the network." + describe kernel_parameter('net.ipv6.conf.default.dad_transmits') do + its(:value) { should eq 0 } + end +end + +control '28' do + impact 1.0 + title "Assign one global unicast IPv6 addresses to each interface" + desc "The max_addresses setting determines how many global unicast IPv6 addresses can be assigned to each interface. The default is 16, but it should be set to exactly the number of statically configured global addresses required." + describe kernel_parameter('net.ipv6.conf.default.max_addresses') do + its(:value) { should eq 1 } + end +end + +control '29' do + impact 1.0 + title "Disable loading kernel modules" + desc "The sysctl key kernel.modules_disabled is very straightforward. If it contains a “1” it will disable loading new modules, where a “0” will still allow loading them. Using this option will be a great protection against loading malicious kernel modules." + describe kernel_parameter('kernel.modules_disabled') do + its(:value) { should eq 1 } + end +end + +control '30' do + impact 1.0 + title "Magic SysRq" + desc "Kernel.sysreg is a 'magical' key combo you can hit which the kernel will respond to regardless of whatever else it is doing, unless it is completely locked up." + describe kernel_parameter('kernel.sysrq') do + its(:value) { should eq 0 } + end +end + +control '31' do + impact 1.0 + title "Disable Core Dumps" + desc "Ensure that core dumps can never be made by setuid programs" + describe kernel_parameter('fs.suid_dumpable') do + its(:value) { should eq 0 } + end +end + +control '32' do + impact 1.0 + title "kernel.randomize_va_space" + desc "kernel.randomize_va_space" + describe kernel_parameter('kernel.randomize_va_space') do + its(:value) { should eq 2 } + end +end + +control '33' do + impact 1.0 + title "CPU No execution Flag or Kernel ExecShield" + desc "Kernel features and CPU flags provide a protection against buffer overflows. The CPU NX Flag and the kernel parameter exec-shield prevents code execution on a per memory page basis. If the CPU supports the NX-Flag then this should be used instead of the kernel parameter exec-shield." + flags = parse_config_file('/proc/cpuinfo', {assignment_re: /^([^:]*?)\s+:\s+(.*?)$/ }).flags.split(' ') + describe '/proc/cpuinfo' do + it 'Flags should include NX' do + expect( flags ).to include('nx') + end + end + unless flags.include?('nx') + # if no nx flag is present, we require exec-shield + describe kernel_parameter('kernel.exec-shield') do + its(:value) { should eq 1 } + end + end +end diff --git a/lockdown/serverspec/modules_spec.rb b/lockdown/serverspec/modules_spec.rb deleted file mode 100644 index 2f4a07c..0000000 --- a/lockdown/serverspec/modules_spec.rb +++ /dev/null @@ -1,32 +0,0 @@ -# encoding: utf-8 -# -# 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. -# - -require 'spec_helper' - -describe 'preloaded modules' do - describe file('/etc/initramfs-tools/modules') do - before do - if RSpec.configuration.os[:family] != 'Debian' - pending 'initramfs creation not ported to this platform yet' - end - end - - its(:content) { should match(/^ghash-clmulni-intel/) } - its(:content) { should match(/^aesni-intel/) } - its(:content) { should match(/^kvm-intel/) } - end -end diff --git a/lockdown/serverspec/os_spec.rb b/lockdown/serverspec/os_spec.rb deleted file mode 100644 index 31bbb8d..0000000 --- a/lockdown/serverspec/os_spec.rb +++ /dev/null @@ -1,108 +0,0 @@ -# encoding: utf-8 -# -# 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. -# - -require 'spec_helper' - -describe command('find / -name \'.rhosts\' | wc -l ') do - its(:stdout) { should match(/^0/) } -end - -describe command('find / -name \'hosts.equiv\' | wc -l ') do - its(:stdout) { should match(/^0/) } -end - -describe file('/etc/shadow') do - it { should be_mode 600 } - it { should be_owned_by 'root' } -end - -describe command('echo $PATH | grep -ci \'\.\'') do - its(:stdout) { should match(/^0/) } -end - -describe file('/etc/login.defs') do - its(:content) { should match(%r{^ENV_SUPATH\s+PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin}) } - its(:content) { should match(%r{^ENV_PATH\s+PATH=/usr/local/bin:/usr/bin:/bin}) } - its(:content) { should match(/^UMASK +027/) } -end - -describe 'SUID/ SGID whitelist check' do - it 'found only whitelist suid/sgid' do - 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 su-tools - '/usr/bin/schroot', - # 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 - ] - actual = command('find / -perm -4000 -o -perm -2000 -type f ! -path \'/proc/*\' -print 2>/dev/null | grep -v \'^find:\'').stdout.split(/\r?\n/) - (actual - whitelist).count.should be 0 - end -end - -describe 'Unique uid' do - it 'check for unique uids' do - actual = command('cat /etc/passwd | cut -d \':\' -f 3').stdout.split(/\r?\n/) - hm = actual.each_with_object(Hash.new(0)) { |d, counts| counts[d] += 1 } - hm.each do |k, v| - str = "User: UID #{k} instances: " - ("#{str}#{v}").should eq("#{str}1") - end - end -end diff --git a/lockdown/serverspec/spec_helper.rb b/lockdown/serverspec/spec_helper.rb deleted file mode 100644 index 78e701b..0000000 --- a/lockdown/serverspec/spec_helper.rb +++ /dev/null @@ -1,63 +0,0 @@ -# encoding: utf-8 -# -# 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. -# - -if ENV['STANDALONE_SPEC'] - - require 'serverspec' - require 'pathname' - require 'net/ssh' - require 'highline/import' - - set :backend, :ssh - - RSpec.configure do |c| - - if ENV['ASK_SUDO_PASSWORD'] - c.sudo_password = ask('Enter sudo password: ') { |q| q.echo = false } - else - c.sudo_password = ENV['SUDO_PASSWORD'] - end - - options = {} - - if ENV['ASK_LOGIN_PASSWORD'] - options[:password] = ask("\nEnter login password: ") { |q| q.echo = false } - else - options[:password] = ENV['LOGIN_PASSWORD'] - end - - if ENV['ASK_LOGIN_USERNAME'] - options[:user] = ask("\nEnter login username: ") { |q| q.echo = false } - else - options[:user] = ENV['LOGIN_USERNAME'] || ENV['user'] || Etc.getlogin - end - - if options[:user].nil? - puts 'specify login user env LOGIN_USERNAME= or user=' - exit 1 - end - - c.host = ENV['TARGET_HOST'] - c.ssh_options = options.merge(Net::SSH::Config.for(c.host)) - - end - -else - require 'serverspec' - - set :backend, :exec -end diff --git a/lockdown/serverspec/sysctl_spec.rb b/lockdown/serverspec/sysctl_spec.rb deleted file mode 100644 index 6d3738a..0000000 --- a/lockdown/serverspec/sysctl_spec.rb +++ /dev/null @@ -1,207 +0,0 @@ -# encoding: utf-8 -# -# 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. -# - -require 'spec_helper' - -describe 'IP V4 networking' do - - context linux_kernel_parameter('net.ipv4.ip_forward') do - its(:value) { should eq 0 } - end - - context linux_kernel_parameter('net.ipv4.conf.all.forwarding') do - its(:value) { should eq 0 } - end - - context linux_kernel_parameter('net.ipv4.conf.all.rp_filter') do - its(:value) { should eq 1 } - end - - context linux_kernel_parameter('net.ipv4.conf.default.rp_filter') do - its(:value) { should eq 1 } - end - - context linux_kernel_parameter('net.ipv4.icmp_echo_ignore_broadcasts') do - its(:value) { should eq 1 } - end - - context linux_kernel_parameter('net.ipv4.icmp_ignore_bogus_error_responses') do - its(:value) { should eq 1 } - end - - context linux_kernel_parameter('net.ipv4.icmp_ratelimit') do - its(:value) { should eq 100 } - end - - context linux_kernel_parameter('net.ipv4.icmp_ratemask') do - its(:value) { should eq 88089 } - end - - context linux_kernel_parameter('net.ipv4.tcp_timestamps') do - its(:value) { should eq 0 } - end - - context linux_kernel_parameter('net.ipv4.conf.all.arp_ignore') do - its(:value) { should eq 1 } - end - - context linux_kernel_parameter('net.ipv4.conf.all.arp_announce') do - its(:value) { should eq 2 } - end - - context linux_kernel_parameter('net.ipv4.tcp_rfc1337') do - its(:value) { should eq 1 } - end - - context linux_kernel_parameter('net.ipv4.tcp_syncookies') do - its(:value) { should eq 1 } - end - - context linux_kernel_parameter('net.ipv4.conf.all.shared_media') do - its(:value) { should eq 1 } - end - - context linux_kernel_parameter('net.ipv4.conf.default.shared_media') do - its(:value) { should eq 1 } - end - - context linux_kernel_parameter('net.ipv4.conf.all.accept_source_route') do - its(:value) { should eq 0 } - end - - context linux_kernel_parameter('net.ipv4.conf.default.accept_source_route') do - its(:value) { should eq 0 } - end - - context linux_kernel_parameter('net.ipv4.conf.default.accept_redirects') do - its(:value) { should eq 0 } - end - - context linux_kernel_parameter('net.ipv4.conf.all.accept_redirects') do - its(:value) { should eq 0 } - end - - context linux_kernel_parameter('net.ipv4.conf.all.secure_redirects') do - its(:value) { should eq 0 } - end - - context linux_kernel_parameter('net.ipv4.conf.default.secure_redirects') do - its(:value) { should eq 0 } - end - - context linux_kernel_parameter('net.ipv4.conf.all.send_redirects') do - its(:value) { should eq 0 } - end - - context linux_kernel_parameter('net.ipv4.conf.all.send_redirects') do - its(:value) { should eq 0 } - end - - # log_martians can cause a denial of service attack to the host - context linux_kernel_parameter('net.ipv4.conf.all.log_martians') do - its(:value) { should eq 0 } - end - -end - -describe 'IP V6 Networking' do - - context linux_kernel_parameter('net.ipv6.conf.all.disable_ipv6') do - its(:value) { should eq 1 } - end - - context linux_kernel_parameter('net.ipv6.conf.all.forwarding') do - its(:value) { should eq 0 } - end - - context linux_kernel_parameter('net.ipv6.conf.default.accept_redirects') do - its(:value) { should eq 0 } - end - - context linux_kernel_parameter('net.ipv6.conf.all.accept_redirects') do - its(:value) { should eq 0 } - end - -end - -describe 'NSA 2.5.3.2.5 Limit Network-Transmitted Configuration' do - - context linux_kernel_parameter('net.ipv6.conf.default.router_solicitations') do - its(:value) { should eq 0 } - end - - context linux_kernel_parameter('net.ipv6.conf.default.accept_ra_rtr_pref') do - its(:value) { should eq 0 } - end - - context linux_kernel_parameter('net.ipv6.conf.default.accept_ra_pinfo') do - its(:value) { should eq 0 } - end - - context linux_kernel_parameter('net.ipv6.conf.default.accept_ra_defrtr') do - its(:value) { should eq 0 } - end - - context linux_kernel_parameter('net.ipv6.conf.default.autoconf') do - its(:value) { should eq 0 } - end - - context linux_kernel_parameter('net.ipv6.conf.default.dad_transmits') do - its(:value) { should eq 0 } - end - - context linux_kernel_parameter('net.ipv6.conf.default.max_addresses') do - its(:value) { should eq 1 } - end - -end - -describe 'System sysctl' do - - context linux_kernel_parameter('kernel.modules_disabled') do - its(:value) { should eq 1 } - end - - context linux_kernel_parameter('kernel.sysrq') do - its(:value) { should eq 0 } - end - - context linux_kernel_parameter('fs.suid_dumpable') do - its(:value) { should eq 0 } - end -end - -describe 'ExecShield' do - - # check if we find the nx flag - if command('cat /proc/cpuinfo').return_stdout?(/^flags.*?:.*? nx( .*?)?$/) - true - else - # if no nx flag is present, we require exec-shield - context 'No nx flag detected' do - it 'require kernel.exec-shield' do - context linux_kernel_parameter('kernel.exec-shield') do - its(:value) { should eq 1 } - end - end - end - end - - context linux_kernel_parameter('kernel.randomize_va_space') do - its(:value) { should eq 2 } - end -end