Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
36ea797
Added SCAP lockdown for sshd_config file
carbonin Jul 27, 2015
d53d735
Added security file to linux_admin.rb requires
carbonin Jul 27, 2015
2829aca
Added SCAP security class for disabling service daemons
carbonin Jul 27, 2015
34e6e1d
Changed spec data directory from sshd_config to security
carbonin Jul 28, 2015
1257438
Added SysctlConf class to control edits to the /etc/sysctl.conf file
carbonin Jul 28, 2015
f51d5b4
Added SysctlConf to Security scap lockdown method
carbonin Jul 28, 2015
7a87983
Fixed hash alignment rubocop issue
carbonin Jul 28, 2015
36e070c
Added LimitsConf class which manages settings in the /etc/security/li…
carbonin Jul 28, 2015
d5b4aa2
Added Securetty class for modifying the /etc/securetty file
carbonin Jul 28, 2015
e15cd10
Moved common set_value method into Security::Common module
carbonin Jul 29, 2015
18e6fdc
Add new sshd spec to test for SCAP after moving set value to common spec
carbonin Jul 29, 2015
407ce0b
Added SCAP settings test to limits_conf spec and cleaned up other tests
carbonin Jul 29, 2015
bad9946
Added class to handle edits to the login.defs file
carbonin Jul 29, 2015
b9f5b59
Added Useradd class to manage the /etc/default/useradd file
carbonin Jul 29, 2015
296cfd1
Fully qualify Common module in Secuirty classes.
carbonin Jul 29, 2015
64f62b0
Add explicit require of security common module to ensure it is presen…
carbonin Jul 29, 2015
142ce15
Added class to handle editing of the audit.rules file
carbonin Jul 30, 2015
25c4f01
Added Modprobe class to write out to files in the /etc/modprobe.d dir…
carbonin Jul 30, 2015
21af188
Handle Modprobe cases where the target file doesn't exist
carbonin Jul 30, 2015
31969ec
Changed File.open block with puts to File.write
carbonin Jul 31, 2015
9a2e5b7
Made conf file constant consistant across classes
carbonin Jul 31, 2015
31c9309
Removed leading empty line in sysctl_conf_spec.rb
carbonin Jul 31, 2015
8e3ab08
Replaced File.open block and puts with File.write in security specs
carbonin Jul 31, 2015
d0d6def
Removed multi-line parameter lists
carbonin Jul 31, 2015
3e82d70
Changed single line each blocks to be on one line
carbonin Jul 31, 2015
b121e02
Added common text manipulation functionality to Security::Common
carbonin Jul 31, 2015
1d523cb
Refactored AuditRules class so we only write out the file once
carbonin Jul 31, 2015
397b473
Changed Modprobe class default file name
carbonin Jul 31, 2015
d641a04
Added new line character to regex to avoid adding empty lines in conf…
carbonin Jul 31, 2015
4361161
Make helper method in Security::Service private
carbonin Aug 3, 2015
1b6f4b4
Add apply_scap_settings for Securetty class
carbonin Aug 3, 2015
bd55a38
Change Security classes to use instance rather than class methods
carbonin Aug 3, 2015
622d6b2
Restart sshd service after changing config file
carbonin Aug 3, 2015
203712e
Change Security class method to instance method
carbonin Aug 3, 2015
b1d597a
Changed spec method convention from class to instance (using #)
carbonin Aug 3, 2015
153d82f
Align items in AuditRules constant
carbonin Aug 3, 2015
a8948be
Remove unnecessary restart_service method in SshdConfig class
carbonin Aug 3, 2015
c17840d
Cleaned up Security::Common.replace_config_line
carbonin Aug 3, 2015
4d5b5f2
Changed file existance check and delete to FileUtils.rm_f
carbonin Aug 3, 2015
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions lib/linux_admin.rb
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
require 'linux_admin/logical_volume'
require 'linux_admin/physical_volume'
require 'linux_admin/volume_group'
require 'linux_admin/security'

module LinuxAdmin
extend Common
Expand Down
14 changes: 14 additions & 0 deletions lib/linux_admin/security.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
module LinuxAdmin
class Security
require 'linux_admin/service'
def scap_lockdown
class_list = [SshdConfig, Service, SysctlConf, LimitsConf, Securetty, LoginDefs,
Useradd, AuditRules, Modprobe]
class_list.each { |c| c.new.public_send(:apply_scap_settings) }
AuditRules.new.reload_rules
LinuxAdmin::Service.new("sshd").restart
end
end
end
require 'linux_admin/security/common'
Dir.glob(File.join(File.dirname(__FILE__), "security", "*.rb")).each { |f| require f }
112 changes: 112 additions & 0 deletions lib/linux_admin/security/audit_rules.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
module LinuxAdmin
class Security
class AuditRules
include LinuxAdmin::Common
include Security::Common
CONF_FILE = "/etc/audit/rules.d/audit.rules"

SCAP_FILESYSTEM_RULES = [
["/etc/localtime", "wa", "audit_time_rules"],
["/etc/group", "wa", "audit_account_changes"],
["/etc/passwd", "wa", "audit_account_changes"],
["/etc/gshadow", "wa", "audit_account_changes"],
["/etc/shadow", "wa", "audit_account_changes"],
["/etc/security/opasswd", "wa", "audit_account_changes"],
["/etc/selinux/", "wa", "MAC-policy"],
["/etc/sudoers", "wa", "actions"],
["/sbin/insmod", "x", "modules"],
["/sbin/rmmod", "x", "modules"],
["/sbin/modprobe", "x", "modules"],
["/etc/issue", "wa", "audit_network_modifications"],
["/etc/issue.net", "wa", "audit_network_modifications"],
["/etc/hosts", "wa", "audit_network_modifications"],
["/etc/sysconfig/network", "wa", "audit_network_modifications"]
]

SCAP_SYSTEM_CALL_RULES = [
[
"always",
"exit",
%w(sethostname setdomainname),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, this seems strange to me. I'd prefer to see the [ ] syntax instead of the %w here.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have no preference, I did it this was to appease RuboCop.

{"arch" => "b64"},
"audit_network_modifications"
],
[
"always",
"exit",
%w(init_module delete_module),
{"arch" => "b64"},
"modules"
],
[
"always",
"exit",
%w(settimeofday clock_settime),
{"arch" => "b64"},
"audit_time_rules"
],
[
"always",
"exit",
["adjtimex"],
{"arch" => "b64"},
"audit_time_rules"
],
[
"always",
"exit",
%w(creat open openat truncate ftruncate),
{"arch" => "b64", "exit" => "-EACCES", "auid>" => "500", "auid!" => "4294967295"},
"access"
],
[
"always",
"exit",
%w(creat open openat truncate ftruncate),
{"arch" => "b64", "exit" => "-EPERM", "auid>" => "500", "auid!" => "4294967295"},
"access"
]
]

def apply_scap_settings(filename = CONF_FILE)
set_buffer_size(16_384, filename)
config_text = File.read(filename)

SCAP_FILESYSTEM_RULES.each do |r|
rule_text = filesystem_rule(*r)
config_text = replace_config_line(rule_text, rule_text, config_text)
end
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mostly style..but if you make these one-lined it might be cleaner.


SCAP_SYSTEM_CALL_RULES.each do |r|
rule_text = system_call_rule(*r)
config_text = replace_config_line(rule_text, rule_text, config_text)
end
File.write(filename, config_text)
end

def filesystem_rule(path, permissions, key_name)
rule = "-w #{path} -p #{permissions}"
key_name ? rule << " -k #{key_name}\n" : rule << "\n"
end

def system_call_rule(action, filter, calls, fields, key_name)
rule = "-a #{action},#{filter}"
fields.each { |f, v| rule << " -F #{f}=#{v}" }
calls.each { |c| rule << " -S #{c}" }
key_name ? rule << " -k #{key_name}\n" : rule << "\n"
end

def set_buffer_size(size, filename = CONF_FILE)
config_text = File.read(filename)
new_line = "-b #{size}\n"
new_text = replace_config_line(new_line, /^-b \d+\n/, config_text)

File.write(filename, new_text)
end

def reload_rules(filename = CONF_FILE)
run!(cmd(:auditctl), :params => {"-R" => [filename]})
end
end
end
end
11 changes: 11 additions & 0 deletions lib/linux_admin/security/common.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
module LinuxAdmin
class Security
module Common
def replace_config_line(new_line, rep_regex, file_text)
new_text = file_text.gsub!(rep_regex, new_line)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think you want the ! after the gsub since it will modify the original "file_text".

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I do in this case, because the other version will just return a copy of the original string rather than nil if no substitutions were made.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, wasn't sure if you were aware that it would modify the original.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I could do

String.new(file_text).gsub!(rep_regex, new_line)

because the caller of this method should expect a return, rather than using the passed in object. I think that will lead to less confusion as I'm only using this version because of the return behavior. What do you think?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Although I would still be returning the same string object in the case where there are no substitutions made ... That might be even more confusing.

return new_text if new_text
file_text << new_line
end
end
end
end
20 changes: 20 additions & 0 deletions lib/linux_admin/security/limits_conf.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
module LinuxAdmin
class Security
class LimitsConf
include Security::Common
CONF_FILE = "/etc/security/limits.conf"

def apply_scap_settings(filename = CONF_FILE)
config_text = File.read(filename)

new_line = "* hard core 0\n"
config_text = replace_config_line(new_line, /^[^#\n]* core .*\n/, config_text)

new_line = "* hard maxlogins 10\n"
config_text = replace_config_line(new_line, /^[^#\n]* maxlogins .*\n/, config_text)

File.write(filename, config_text)
end
end
end
end
20 changes: 20 additions & 0 deletions lib/linux_admin/security/login_defs.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
module LinuxAdmin
class Security
class LoginDefs
include Security::Common
CONF_FILE = "/etc/login.defs"

SCAP_SETTINGS = {
"PASS_MIN_DAYS" => 1
}

def apply_scap_settings(filename = CONF_FILE)
text = File.read(filename)
SCAP_SETTINGS.each do |k, v|
text = replace_config_line("#{k} #{v}\n", /^#*#{k}.*\n/, text)
end
File.write(filename, text)
end
end
end
end
37 changes: 37 additions & 0 deletions lib/linux_admin/security/modprobe.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
module LinuxAdmin
class Security
class Modprobe
include Security::Common
CONF_FILE = "/etc/modprobe.d/scap.conf"
SCAP_MODULES = %w(dccp sctp rds tipc)

def apply_scap_settings(filename = CONF_FILE)
SCAP_MODULES.each { |m| disable_module(m, filename) }
end

def disable_module(mod_name, filename)
begin
config_text = File.read(filename)
rescue Errno::ENOENT
# Okay if file doesn't exist we will create it
config_text = ""
end

new_line = "install #{mod_name} /bin/true\n"
new_text = replace_config_line(new_line, /^install #{mod_name}.*\n/, config_text)
File.write(filename, new_text)
end

def enable_module(mod_name, filename)
begin
config_text = File.read(filename)
rescue Errno::ENOENT
return
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't need the return

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If I take that return out wont we run lines 32 and 33? If the file doesn't exist, we don't want to do that.

end

new_text = replace_config_line("", /^install #{mod_name}.*\n/, config_text)
File.write(filename, new_text)
end
end
end
end
19 changes: 19 additions & 0 deletions lib/linux_admin/security/securetty.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
module LinuxAdmin
class Security
class Securetty
include Security::Common
CONF_FILE = "/etc/securetty"

def apply_scap_settings(filename = CONF_FILE)
remove_vcs(filename)
end

def remove_vcs(filename = CONF_FILE)
config_text = File.read(filename)
new_text = replace_config_line("", %r{^vc/\d+\n}, config_text)

File.write(filename, new_text)
end
end
end
end
20 changes: 20 additions & 0 deletions lib/linux_admin/security/service.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
module LinuxAdmin
class Security
class Service
require 'linux_admin/service'

def apply_scap_settings
disable_service("autofs")
disable_service("atd")
end

private

def disable_service(service_name)
serv = LinuxAdmin::Service.new(service_name)
serv.stop if serv.running?
serv.disable
end
end
end
end
26 changes: 26 additions & 0 deletions lib/linux_admin/security/sshd_config.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
module LinuxAdmin
class Security
class SshdConfig
require 'linux_admin/service'
include Security::Common
CONF_FILE = "/etc/ssh/sshd_config"

SCAP_SETTINGS = {
"PermitUserEnvironment" => "no",
"PermitEmptyPasswords" => "no",
"Ciphers" => "aes128-ctr,aes192-ctr,aes256-ctr,aes128-cbc,3des-cbc,aes192-cbc,aes256-cbc",
"ClientAliveInterval" => "900",
"ClientAliveCountMax" => "0"
}

def apply_scap_settings(filename = CONF_FILE)
config_text = File.read(filename)
SCAP_SETTINGS.each do |k, v|
new_line = "#{k} #{v}\n"
config_text = replace_config_line(new_line, /^#*#{k}.*\n/, config_text)
end
File.write(filename, config_text)
end
end
end
end
31 changes: 31 additions & 0 deletions lib/linux_admin/security/sysctl_conf.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
module LinuxAdmin
class Security
class SysctlConf
include Security::Common
CONF_FILE = "/etc/sysctl.conf"

SCAP_SETTINGS = {
"net.ipv4.conf.all.accept_redirects" => 0,
"net.ipv4.conf.all.secure_redirects" => 0,
"net.ipv4.conf.all.log_martians" => 1,
"net.ipv4.conf.default.secure_redirects" => 0,
"net.ipv4.conf.default.accept_redirects" => 0,
"net.ipv4.icmp_echo_ignore_broadcasts" => 1,
"net.ipv4.icmp_ignore_bogus_error_responses" => 1,
"net.ipv4.conf.all.rp_filter" => 1,
"net.ipv6.conf.default.accept_redirects" => 0,
"net.ipv4.conf.default.send_redirects" => 0,
"net.ipv4.conf.all.send_redirects" => 0
}

def apply_scap_settings(filename = CONF_FILE)
config_text = File.read(filename)
SCAP_SETTINGS.each do |k, v|
new_line = "#{k} = #{v}\n"
config_text = replace_config_line(new_line, /^[#;]*#{k}.*\n/, config_text)
end
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ugh, this file will be written over an over...wonder if we can mitigate that/

File.write(filename, config_text)
end
end
end
end
21 changes: 21 additions & 0 deletions lib/linux_admin/security/useradd.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
module LinuxAdmin
class Security
class Useradd
include Security::Common
CONF_FILE = "/etc/default/useradd"

SCAP_SETTINGS = {
"INACTIVE" => 35,
}

def apply_scap_settings(filename = CONF_FILE)
config_text = File.read(filename)
SCAP_SETTINGS.each do |k, v|
new_line = "#{k}=#{v}\n"
config_text = replace_config_line(new_line, /^#*#{k}.*\n/, config_text)
end
File.write(filename, config_text)
end
end
end
end
1 change: 1 addition & 0 deletions spec/data/security/audit.rules
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
-b 320
2 changes: 2 additions & 0 deletions spec/data/security/common
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
#CommentedNoOption no
NoOption no
1 change: 1 addition & 0 deletions spec/data/security/limits.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
* soft core 100
1 change: 1 addition & 0 deletions spec/data/security/login.defs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@

1 change: 1 addition & 0 deletions spec/data/security/modprobe_lockdown
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
install good_module /bin/true
4 changes: 4 additions & 0 deletions spec/data/security/securetty
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
vc/1
vc/10
tty1
hvc1
4 changes: 4 additions & 0 deletions spec/data/security/sshd_config
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#PermitUserEnvironment no
#PermitEmptyPasswords yes
ClientAliveInterval 100000
ClientAliveCountMax 0
3 changes: 3 additions & 0 deletions spec/data/security/sysctl.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#data.security.commented.zero = 0
;data.security.commented.semi.one = 1
data.security.one = 1
2 changes: 2 additions & 0 deletions spec/data/security/useradd
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
ZERO=0
#COMMENT_ZERO=0
Loading