186 lines
6 KiB
Ruby
186 lines
6 KiB
Ruby
# Ossec server provisioning recipe
|
|
# install the ossec-hids-server package and push the
|
|
# default configuration from the templates
|
|
|
|
if node['platform_family'] == "rhel"
|
|
include_recipe "yum-atomic"
|
|
elsif node['platform_family'] == "debian"
|
|
include_recipe "apt-atomic"
|
|
end
|
|
|
|
|
|
class Chef::Recipe
|
|
include OssecCore
|
|
end
|
|
|
|
|
|
package "ossec-hids-server"
|
|
|
|
# Get all the agents at once, more efficient
|
|
if Chef::Config[:solo]
|
|
Chef::Log.warn('This recipe uses search. Chef Solo does not support search')
|
|
else
|
|
ossec_agents = search(:node,
|
|
"roles:ossec-agent "\
|
|
"AND chef_environment:#{node.chef_environment}")
|
|
|
|
# set local command/active-response flags
|
|
ossec_set_filtered_flags!("command", "active-response", "syslog_files")
|
|
ossec_set_syscheck_flags!("ignore")
|
|
|
|
# resolve searches in server rules
|
|
ossec_hostname_search()
|
|
|
|
# resolve email_alerts location searches
|
|
ossec_event_location_search()
|
|
|
|
# initialize the agent hash on the first run
|
|
if node["ossec"]["agents"].nil?
|
|
node.normal["ossec"]["agents"] = {}
|
|
end
|
|
|
|
ossec_agents.each do |agent|
|
|
# don't process thy self
|
|
if agent["ipaddress"] == node["ipaddress"]
|
|
next
|
|
end
|
|
|
|
agent_hash = ossec_agent_create_parameters(agent, node)
|
|
|
|
# this agent is running fine, go to the next one
|
|
if ossec_agent_is_active?(agent_hash[:id])
|
|
node.normal["ossec"]["agents"][agent_hash[:id]]["status"] = "active"
|
|
next
|
|
end
|
|
|
|
# check that the agent ID still point to the same IP and hostname
|
|
# otherwise, delete the record from the ossec server
|
|
if not ossec_verify_agent(agent_hash, node)
|
|
Chef::Log.info("OSSEC: deleting server record for agent '#{agent_hash[:id]}'")
|
|
node.normal["ossec"]["agents"].delete(agent_hash[:id])
|
|
end
|
|
|
|
# if this agent doesn't have a valid key, generate one
|
|
if not ossec_agent_has_valid_key?(agent_hash, node)
|
|
Chef::Log.info("OSSEC: agent '#{agent_hash[:id]}' needs a key. Generating one.")
|
|
agent_hash[:key] = ossec_generate_agent_key(agent_hash)
|
|
agent_hash[:rid] = "todo"
|
|
agent_hash[:status] = "key_exists"
|
|
end
|
|
|
|
# save agent parameters
|
|
agent_hash.each do |k,v|
|
|
node.normal["ossec"]["agents"][agent_hash[:id]][k] = v
|
|
end
|
|
|
|
# Don't continue if the agent has a valid key but doesn't know it yet
|
|
if not ossec_agent_knows_key?(agent_hash, agent)
|
|
Chef::Log.info("OSSEC: agent '#{agent_hash[:id]}' didn't pick up its key yet.")
|
|
next
|
|
end
|
|
|
|
# Check if it needs a queue cleanup
|
|
if ossec_agent_needs_rid?(agent_hash[:id], agent)
|
|
ruby_block "ossec queue rid" do
|
|
block do
|
|
if File.exists?("/var/ossec/queue/rids/#{agent_hash[:id]}")
|
|
File.delete("/var/ossec/queue/rids/#{agent_hash[:id]}")
|
|
Chef::Log.info("OSSEC: deleted queue for agent '#{agent_hash[:id]}'")
|
|
else
|
|
Chef::Log.info("OSSEC: No queue for agent '#{agent_hash[:id]}.'")
|
|
end
|
|
node.normal["ossec"]["agents"][agent_hash[:id]]["rid"] = "done"
|
|
end
|
|
notifies :restart, "service[ossec-server]", :delayed
|
|
end
|
|
# done with this agent, go to the next one
|
|
next
|
|
end
|
|
|
|
# If after all that, the agent is still not active, mark it as so
|
|
if not ossec_agent_is_active?(agent_hash[:id])
|
|
if ossec_agent_is_zombie?(agent_hash[:id])
|
|
node.normal["ossec"]["agents"][agent_hash[:id]]["status"] = "zombie"
|
|
# if the agent is a zombie, perform a rid of its queue on the next run
|
|
Chef::Log.info("OSSEC: agent #{agent_hash[:id]} is a zombie. " +
|
|
"Request queue deletion")
|
|
node.normal["ossec"]["agents"][agent_hash[:id]]["rid"] = "todo"
|
|
else
|
|
node.normal["ossec"]["agents"][agent_hash[:id]]["status"] = "disconnected"
|
|
Chef::Log.info("OSSEC: agent #{agent_hash[:id]} connection failed. " +
|
|
"Performing restart")
|
|
#cmd = Chef::ShellOut.new("/var/ossec/bin/agent_control -R #{agent_hash[:id]}")
|
|
cmd = Mixlib::ShellOut.new("/var/ossec/bin/agent_control -R #{agent_hash[:id]}")
|
|
cmd_ret = cmd.run_command
|
|
end
|
|
end
|
|
end
|
|
|
|
# Remove the attributes of an agent from the ossec server if the agent doesn't
|
|
# exist on Chef and the last keep_alive is more than 7 days old
|
|
node["ossec"]["agents"].each do |agent_id, params|
|
|
if params[:status].eql?('key_exists')
|
|
next
|
|
end
|
|
|
|
agent = ossec_agents.select{ |n| (n[:ossec][:agents].has_key?(agent_id) \
|
|
&& n[:ossec][:agent][:enable])
|
|
}.first
|
|
|
|
if not agent.nil?
|
|
next
|
|
end
|
|
if ossec_agent_should_be_removed?(agent_id)
|
|
Chef::Log.info("OSSEC: Removing old agent '#{agent_id}' - '#{params[:name]}'")
|
|
node.normal["ossec"]["agents"].delete(agent_id)
|
|
else
|
|
Chef::Log.info("OSSEC: agent '#{agent_id}' - '#{params[:name]}' is candidate for removal")
|
|
node.normal["ossec"]["agents"][agent_id]["status"] = 'candidate_for_removal'
|
|
end
|
|
end
|
|
end
|
|
|
|
template "/var/ossec/etc/client.keys" do
|
|
mode '0440'
|
|
owner "root"
|
|
group "ossec"
|
|
end
|
|
|
|
template "/var/ossec/rules/local_rules.xml" do
|
|
owner "root"
|
|
group "root"
|
|
notifies :restart, "service[ossec-server]", :delayed
|
|
end
|
|
|
|
template "/var/ossec/etc/local_decoder.xml" do
|
|
owner "root"
|
|
group "root"
|
|
notifies :restart, "service[ossec-server]", :delayed
|
|
end
|
|
|
|
template "/var/ossec/etc/ossec.conf" do
|
|
source "ossec-server.conf.erb"
|
|
owner "ossec"
|
|
group "ossec"
|
|
manage_symlink_source true
|
|
variables(
|
|
:ossec_agents => ossec_agents
|
|
)
|
|
notifies :restart, "service[ossec-server]", :delayed
|
|
end
|
|
|
|
template "/var/ossec/etc/internal_options.conf" do
|
|
mode "0444"
|
|
owner "root"
|
|
group "root"
|
|
notifies :restart, "service[ossec-server]", :delayed
|
|
end
|
|
|
|
service "ossec-server" do
|
|
#provider Chef::Provider::Service::Init
|
|
service_name node["ossec"]["server"]["service_name"]
|
|
supports :start => true, :stop => true, :restart => true, :status => true
|
|
action [ :start ]
|
|
only_if { File.exist?("/var/ossec/etc/ossec.conf") }
|
|
end
|
|
|