cookbook-ossec-ng/recipes/server.rb

182 lines
5.9 KiB
Ruby

# Ossec server provisioning recipe
# install the ossec-hids-server package and push the
# default configuration from the templates
include_recipe "yum-atomic"
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["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