Commit d691d493 authored by jtimberman's avatar jtimberman
Browse files

add ossec cookbook

parents
Description
====
Installs OSSEC from source in a server-agent installation. See:
http://www.ossec.net/main/manual/manual-installation/
Requirements
====
Tested on Ubuntu and ArchLinux.
Cookbooks
----
build-essential
Attributes
====
Default values are based on the defaults from OSSEC's own install.sh installation script.
* `node['ossec']['server_role']` - When using server/agent setup, this role is used to search for the OSSEC server, default `ossec_server`.
* `node['ossec']['checksum']` - SHA256 checksum of the source. Verified with SHA1 sum from OSSEC site.
* `node['ossec']['version']` - Version of OSSEC to download/install. Used in URL.
* `node['ossec']['url']` - URL to download the source.
* `node['ossec']['logs']` - Array of log files to analyze. Default is an empty array. These are in addition to the default logs in the ossec.conf.erb template.
* `node['ossec']['syscheck_freq']` - Frequency that syscheck is executed, default 22 hours (79200 seconds)
* `node['ossec']['server']['maxagents']` - Maximum number of agents, default setting is 256, but will be set to 1024 in the ossec::server recipe if used. Add as an override attribute in the `ossec_server` role if more nodes are required.
The `user` attributes are used to populate the config file (ossec.conf) and preload values for the installation script.
* `node['ossec']['user']['language']` - Language to use for installation, default en.
* `node['ossec']['user']['install_type']` - What kind of installation to perform, default is local. Using the client or server recipe will set this to `agent` or `server`, respectively.
* `node['ossec']['user']['dir']` - Installation directory for OSSEC, default `/var/ossec`.
* `node['ossec']['user']['delete_dir']` - Whether to delete the existing OSSEC installation directory, default true.
* `node['ossec']['user']['active_response']` - Whether to enable active response feature of OSSEC, default true. It is safe and recommended to leave this enabled.
* `node['ossec']['user']['syscheck']` - Whether to enable the integrity checking process, syscheck. Default true. It is safe and recommended to leave this enabled.
* `node['ossec']['user']['rootcheck']` - Whether to enable the rootkit checking process, rootcheck. Default true. It is safe and recommended to leave this enabled.
* `node['ossec']['user']['update']` - Whether an update installation should be done, default false.
* `node['ossec']['user']['update_rules']` - Whether to update rules files, default true.
* `node['ossec']['user']['binary_install']` - If true, use the binaries in the bin directory rather than compiling. Default false. The cookbook doesn't yet support binary installations.
* `node['ossec']['user']['agent_server_ip']` - The IP of the OSSEC server. The client recipe will attempt to determine this value via search. Default is nil, only required for agent installations.
* `node['ossec']['user']['enable_email']` - Enable or disable email alerting. Default is true.
* `node['ossec']['user']['email']` - Destination email address for OSSEC alerts. Default is `ossec@example.com` and should be changed via a role attribute.
* `node['ossec']['user']['smtp']` - Sets the SMTP relay to send email out. Default is 127.0.0.1, which assumes that a local MTA is set up (e.g., postfix).
* `node['ossec']['user']['remote_syslog']` - Whether to enable the remote syslog server on the OSSEC server. Default false, not relevant for non-server.
* `node['ossec']['user']['firewall_response']` - Enable or disable the firewall response which sets up firewall rules for blocking. Default is true.
* `node['ossec']['user']['pf']` - Enable PF firewall on BSD, default is false.
* `node['ossec']['user']['pf_table']` - The PF table to use on BSD. Default is false, set this to the desired table if enabling `pf`.
* `node['ossec']['user']['white_list']` - Array of additional IP addresses to white list. Default is empty.
Recipes
====
default
----
The default recipe downloads and installs the OSSEC source and makes sure the . Use only this recipe if setting up local-only installation. Th
agent
----
OSSEC uses the term `agent` instead of client. The agent recipe includes the `ossec::client` recipe.
client
----
Configures the system as an OSSEC agent to the OSSEC server.
server
----
Sets up a system to be an OSSEC server.
Usage
====
The cookbook can be used to install OSSEC in one of the three types:
* local - use the ossec::default recipe.
* server - use the ossec::server recipe.
* agent - use the ossec::client recipe
For local-only installations, add just `recipe[ossec]` to the node run list, or put it in a role (like a base role).
Server/Agent
----
This section describes how to use the cookbook for server/agent configurations.
The server will use SSH to distribute the OSSEC agent keys. Create a data bag `ossec`, with an item `ssh`. It should have the following structure:
{
"id": "ssh",
"pubkey": "",
"privkey": ""
}
Generate an ssh keypair and get the privkey and pubkey values. The output of the two ruby commands should be used as the privkey and pubkey values respectively in the data bag.
ssh-keygen -t rsa -f /tmp/id_rsa
ruby -e 'puts IO.read("/tmp/id_rsa")'
ruby -e 'puts IO.read("/tmp/id_rsa.pub")'
For the OSSEC server, create a role, `ossec_server`. Add attributes per above as needed to customize the installation.
% cat roles/ossec_server.rb
name "ossec_server"
description "OSSEC Server"
run_list("recipe[ossec::server]")
override_attributes(
"ossec" => {
"user" => {
"email" => "ossec@yourdomain.com",
"smtp" => "smtp.yourdomain.com"
}
}
)
For OSSEC agents, create a role, `ossec_client`.
% cat roles/ossec_client.rb
name "ossec_client"
description "OSSEC Client Agents"
run_list("recipe[ossec::client]")
override_attributes(
"ossec" => {
"user" => {
"email" => "ossec@yourdomain.com",
"smtp" => "smtp.yourdomain.com"
}
}
)
Customization
----
The main configuration file is maintained by Chef as a template, `ossec.conf.erb`. It should just work on most installations, but can be customized for the local environment. Notably, the rules, ignores and commands may be modified.
Further reading:
* [OSSEC Documentation](http://www.ossec.net/doc/index.html)
* [OSSEC Wiki](http://www.ossec.net/wiki/OSSEC)
License and Author
====
Copyright 2010, Opscode, Inc (<legal@opscode.com>)
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.
#
# Cookbook Name:: ossec
# Attributes:: default
#
# Copyright 2010, Opscode, Inc.
#
# 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.
#
# general settings
default['ossec']['server_role'] = "ossec_server"
default['ossec']['checksum'] = "e7bb4701a6b9a40f76d4e2c3c39106ded3c37f13ccc3ce476029da1f0e9c9f9e"
default['ossec']['version'] = "2.5.1"
default['ossec']['url'] = "http://www.ossec.net/files/ossec-hids-#{node['ossec']['version']}.tar.gz"
default['ossec']['logs'] = []
default['ossec']['syscheck_freq'] = 79200
# server-only
default['ossec']['server']['maxagents'] = 256
# used to populate config files and preload values for install
default['ossec']['user']['language'] = "en"
default['ossec']['user']['install_type'] = "local"
default['ossec']['user']['dir'] = "/var/ossec"
default['ossec']['user']['delete_dir'] = true
default['ossec']['user']['active_response'] = true
default['ossec']['user']['syscheck'] = true
default['ossec']['user']['rootcheck'] = true
default['ossec']['user']['update'] = false
default['ossec']['user']['update_rules'] = true
default['ossec']['user']['binary_install'] = false
default['ossec']['user']['agent_server_ip'] = nil
default['ossec']['user']['enable_email'] = true
default['ossec']['user']['email'] = "ossec@example.com"
default['ossec']['user']['smtp'] = "127.0.0.1"
default['ossec']['user']['remote_syslog'] = false
default['ossec']['user']['firewall_response'] = true
default['ossec']['user']['pf'] = false
default['ossec']['user']['pf_table'] = false
default['ossec']['user']['white_list'] = []
{
"name": "ossec",
"description": "Installs/Configures ossec",
"long_description": "Description\n====\n\nInstalls OSSEC from source in a server-agent installation. See:\n\nhttp://www.ossec.net/main/manual/manual-installation/\n\nRequirements\n====\n\nTested on Ubuntu and ArchLinux.\n\nCookbooks\n----\n\nbuild-essential\n\nAttributes\n====\n\nDefault values are based on the defaults from OSSEC's own install.sh installation script.\n\n* `node['ossec']['checksum']` - SHA256 checksum of the source. Verified with SHA1 sum from OSSEC site.\n* `node['ossec']['version']` - Version of OSSEC to download/install. Used in URL.\n* `node['ossec']['url']` - URL to download the source.\n* `node['ossec']['']` -\n\nThe following attributes are used to prepopulate the preloaded variables configuration.\n\n* `node['ossec']['user']` -\n\nRecipes\n====\n\ndefault\n----\n\nThe default recipe downloads and installs the OSSEC source.\n\nagent\n----\n\nOSSEC uses the term `agent` instead of client. The agent recipe includes the `ossec::client` recipe.\n\nclient\n----\n\nConfigures the system as an OSSEC agent to the OSSEC server.\n\nserver\n----\n\nSets up a system to be an OSSEC server.\n\nUsage\n====\n\nThe cookbook can be used to install OSSEC in one of the three types:\n\n* local - use the ossec::default recipe.\n* server - use the ossec::server recipe.\n* agent - use the ossec::client recipe\n\nFor the OSSEC server, create a role, `ossec_server`.\n\n % cat roles/ossec_server.rb\n\nFor OSSEC agents, create a role, `ossec_client`.\n\n % cat roles/ossec_client.rb\n\nLicense and Author\n====\n\nCopyright 2010, Opscode, Inc (<legal@opscode.com>)\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n",
"maintainer": "Opscode, Inc.",
"maintainer_email": "cookbooks@opscode.com",
"license": "Apache 2.0",
"platforms": {
},
"dependencies": {
"build-essential": [
]
},
"recommendations": {
},
"suggestions": {
},
"conflicting": {
},
"providing": {
},
"replacing": {
},
"attributes": {
},
"groupings": {
},
"recipes": {
},
"version": "0.9.0"
}
\ No newline at end of file
maintainer "Opscode, Inc."
maintainer_email "cookbooks@opscode.com"
license "Apache 2.0"
description "Installs/Configures ossec"
long_description IO.read(File.join(File.dirname(__FILE__), 'README.md'))
version "0.9.0"
depends "build-essential"
#
# Cookbook Name:: ossec
# Recipe:: agent
#
# Copyright 2010, Opscode, Inc.
#
# 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.
#
include_recipe "ossec::client"
#
# Cookbook Name:: ossec
# Recipe:: client
#
# Copyright 2010, Opscode, Inc.
#
# 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.
#
ossec_server = Array.new
if node.run_list.roles.include?(node['ossec']['server_role'])
ossec_server << node['ipaddress']
else
search(:node,"role:#{node['ossec']['server_role']} AND app_environment:#{node['app_environment']}") do |n|
ossec_server << n['ipaddress']
end
end
node.set['ossec']['user']['install_type'] = "agent"
node.set['ossec']['user']['agent_server_ip'] = ossec_server.first
node.save
include_recipe "ossec"
ossec_key = data_bag_item("ossec", "ssh")
user "ossecd" do
comment "OSSEC Distributor"
shell "/bin/bash"
system true
gid "ossec"
home node['ossec']['user']['dir']
end
directory "#{node['ossec']['user']['dir']}/.ssh" do
owner "ossecd"
group "ossec"
mode 0750
end
template "#{node['ossec']['user']['dir']}/.ssh/authorized_keys" do
source "ssh_key.erb"
owner "ossecd"
group "ossec"
mode 0600
variables(:key => ossec_key['pubkey'])
end
#
# Cookbook Name:: ossec
# Recipe:: default
#
# Copyright 2010, Opscode, Inc.
#
# 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.
#
include_recipe "build-essential"
ossec_dir = "ossec-hids-#{node['ossec']['version']}"
remote_file "#{Chef::Config[:file_cache_path]}/#{ossec_dir}.tar.gz" do
source node['ossec']['url']
checksum node['ossec']['checksum']
end
execute "tar zxvf #{ossec_dir}.tar.gz" do
cwd Chef::Config[:file_cache_path]
creates "#{Chef::Config[:file_cache_path]}/#{ossec_dir}"
end
template "#{Chef::Config[:file_cache_path]}/#{ossec_dir}/etc/preloaded-vars.conf" do
source "preloaded-vars.conf.erb"
variables :ossec => node['ossec']['user']
end
bash "install-ossec" do
cwd "#{Chef::Config[:file_cache_path]}/#{ossec_dir}"
code <<-EOH
echo "HEXTRA=-DMAX_AGENTS=#{node['ossec']['server']['maxagents']}" >> src/Config.OS
./install.sh
EOH
creates "#{node['ossec']['user']['dir']}/bin/ossec-control"
end
# not really a template, dist by ossec, so we don't need a copy in the cookbook
template "#{node['ossec']['user']['dir']}/bin/ossec-batch-manager.pl" do
source "#{Chef::Config[:file_cache_path]}/#{ossec_dir}/contrib/ossec-batch-manager.pl"
local true
owner "root"
group "ossec"
mode 0755
end
template "#{node['ossec']['user']['dir']}/etc/ossec.conf" do
source "ossec.conf.erb"
owner "root"
group "ossec"
mode 0440
variables(:ossec => node['ossec']['user'])
notifies :restart, "service[ossec]"
end
service "ossec" do
supports :status => true, :restart => true
action [:enable, :start]
end
#
# Cookbook Name:: ossec
# Recipe:: server
#
# Copyright 2010, Opscode, Inc.
#
# 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.
#
node.set['ossec']['user']['install_type'] = "server"
node.set['ossec']['server']['maxagents'] = 1024
node.save
include_recipe "ossec"
agent_manager = "#{node['ossec']['user']['dir']}/bin/ossec-batch-manager.pl"
ssh_hosts = Array.new
search(:node, "app_environment:#{node['app_environment']} NOT role:#{node['ossec']['server_role']}") do |n|
ssh_hosts << n['ipaddress'] if n['keys']
execute "#{agent_manager} -a --ip #{n['ipaddress']} -n #{n['hostname']}" do
not_if "grep '#{n['hostname']} #{n['ipaddress']}' #{node['ossec']['user']['dir']}/etc/client.keys"
end
end
template "/usr/local/bin/dist-ossec-keys.sh" do
source "dist-ossec-keys.sh.erb"
owner "root"
group "root"
mode 0755
variables(:ssh_hosts => ssh_hosts)
not_if { ssh_hosts.empty? }
end
ossec_key = data_bag_item("ossec", "ssh")
directory "#{node['ossec']['user']['dir']}/.ssh" do
owner "root"
group "ossec"
mode 0750
end
template "#{node['ossec']['user']['dir']}/.ssh/id_rsa" do
source "ssh_key.erb"
owner "root"
group "ossec"
mode 0600
variables(:key => ossec_key['privkey'])
end
cron "distribute-ossec-keys" do
minute "0"
command "/usr/local/bin/dist-ossec-keys.sh"
only_if { ::File.exists?("#{node['ossec']['user']['dir']}/etc/client.keys") }
end
#!/bin/sh
#
for host in <%= @ssh_hosts.join(' ') %>
do
key=`mktemp`
grep $host <%= node['ossec']['user']['dir'] %>/etc/client.keys > $key
scp -B -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no $key ossecd@$host:<%= node['ossec']['user']['dir'] %>/etc/client.keys >/dev/null 2>/dev/null
rm $key
done
<ossec_config>
<global>
<% if @ossec['enable_email'] -%>
<email_notification>yes</email_notification>
<% else -%>
<email_notification>no</email_notification>
<% end -%>
<email_to><%= @ossec['email'] %></email_to>
<smtp_server><%= @ossec['smtp'] %></smtp_server>
<email_from>ossecm@<%= node['fqdn'] %></email_from>
<% @ossec['white_list'].each do |wl| -%>
<white_list><%= wl %></white_list>
<% end -%>
</global>
<% if @ossec['install_type'] == 'agent' -%>
<client>
<server-ip><%= @ossec['agent_server_ip'] %></server-ip>
</client>
<% end -%>
<% unless @ossec['install_type'] == 'local' -%>
<remote>
<connection>secure</connection>
</remote>
<% end -%>
<rules>
<include>rules_config.xml</include>
<include>pam_rules.xml</include>
<include>sshd_rules.xml</include>
<include>telnetd_rules.xml</include>
<include>syslog_rules.xml</include>
<include>arpwatch_rules.xml</include>
<include>symantec-av_rules.xml</include>
<include>symantec-ws_rules.xml</include>
<include>pix_rules.xml</include>
<include>named_rules.xml</include>
<include>smbd_rules.xml</include>
<include>vsftpd_rules.xml</include>
<include>pure-ftpd_rules.xml</include>
<include>proftpd_rules.xml</include>
<include>ms_ftpd_rules.xml</include>
<include>ftpd_rules.xml</include>
<include>hordeimp_rules.xml</include>
<include>roundcube_rules.xml</include>
<include>wordpress_rules.xml</include>
<include>cimserver_rules.xml</include>
<include>vpopmail_rules.xml</include>
<include>vmpop3d_rules.xml</include>
<include>courier_rules.xml</include>
<include>web_rules.xml</include>
<include>apache_rules.xml</include>
<include>nginx_rules.xml</include>
<include>php_rules.xml</include>
<include>mysql_rules.xml</include>
<include>postgresql_rules.xml</include>
<include>ids_rules.xml</include>
<include>squid_rules.xml</include>
<include>firewall_rules.xml</include>
<include>cisco-ios_rules.xml</include>
<include>netscreenfw_rules.xml</include>
<include>sonicwall_rules.xml</include>
<include>postfix_rules.xml</include>
<include>sendmail_rules.xml</include>
<include>imapd_rules.xml</include>
<include>mailscanner_rules.xml</include>
<include>dovecot_rules.xml</include>
<include>ms-exchange_rules.xml</include>
<include>racoon_rules.xml</include>
<include>vpn_concentrator_rules.xml</include>
<include>spamd_rules.xml</include>
<include>msauth_rules.xml</include>
<include>mcafee_av_rules.xml</include>
<include>trend-osce_rules.xml</include>
<include>ms-se_rules.xml</include>
<!-- <include>policy_rules.xml</include> -->
<include>zeus_rules.xml</include>
<include>solaris_bsm_rules.xml</include>
<include>vmware_rules.xml</include>
<include>ms_dhcp_rules.xml</include>
<include>asterisk_rules.xml</include>
<include>ossec_rules.xml</include>
<include>attack_rules.xml</include>
<include>local_rules.xml</include>
</rules>
<% if @ossec['syscheck'] -%>
<syscheck>
<!-- Frequency that syscheck is executed - default to every 22 hours -->
<frequency><%= node['ossec']['syscheck_freq'] %></frequency>
<!-- Directories to check (perform all possible verifications) -->
<directories check_all="yes">/etc,/usr/bin,/usr/sbin</directories>
<directories check_all="yes">/bin,/sbin</directories>
<!-- Files/directories to ignore -->
<ignore>/etc/mtab</ignore>
<ignore>/etc/mnttab</ignore>
<ignore>/etc/hosts.deny</ignore>
<ignore>/etc/mail/statistics</ignore>
<ignore>/etc/random-seed</ignore>
<ignore>/etc/adjtime</ignore>
<ignore>/etc/httpd/logs</ignore>
<ignore>/etc/utmpx</ignore>
<ignore>/etc/wtmpx</ignore>
<ignore>/etc/cups/certs</ignore>
<ignore>/etc/dumpdates</ignore>
<ignore>/etc/svc/volatile</ignore>
<!-- Windows files to ignore -->
<ignore>C:\WINDOWS/System32/LogFiles</ignore>
<ignore>C:\WINDOWS/Debug</ignore>
<ignore>C:\WINDOWS/WindowsUpdate.log</ignore>
<ignore>C:\WINDOWS/iis6.log</ignore>
<ignore>C:\WINDOWS/system32/wbem/Logs</ignore>
<ignore>C:\WINDOWS/system32/wbem/Repository</ignore>
<ignore>C:\WINDOWS/Prefetch</ignore>
<ignore>C:\WINDOWS/PCHEALTH/HELPCTR/DataColl</ignore>
<ignore>C:\WINDOWS/SoftwareDistribution</ignore>
<ignore>C:\WINDOWS/Temp</ignore>
<ignore>C:\WINDOWS/system32/config</ignore>
<ignore>C:\WINDOWS/system32/spool</ignore>
<ignore>C:\WINDOWS/system32/CatRoot</ignore>
</syscheck>
<% end -%>
<% if @ossec['rootcheck'] -%>
<rootcheck>
<rootkit_files>/var/ossec/etc/shared/rootkit_files.txt</rootkit_files>
<rootkit_trojans>/var/ossec/etc/shared/rootkit_trojans.txt</rootkit_trojans>
<system_audit>/var/ossec/etc/shared/system_audit_rcl.txt</system_audit>
<system_audit>/var/ossec/etc/shared/cis_debian_linux_rcl.txt</system_audit>
<system_audit>/var/ossec/etc/shared/cis_rhel_linux_rcl.txt</system_audit>
<system_audit>/var/ossec/etc/shared/cis_rhel5_linux_rcl.txt</system_audit>
</rootcheck>
<% end -%>
<alerts>
<log_alert_level>1</log_alert_level>
<email_alert_level>7</email_alert_level>
</alerts>