Commit f502e4cd authored by James Le Cuirot's avatar James Le Cuirot
Browse files

Install from packages

…instead of from source. Unfortunately there are no packages currently
available for Arch.

A missing or empty agent_server_ip attribute or client.keys file now
prevents the service from attempting to start. See the README for
details.
parent bd20a816
......@@ -19,5 +19,12 @@ platforms:
suites:
- name: default
run_list: ["recipe[ossec]"]
attributes: {}
run_list:
- recipe[ossec]
- name: client
run_list:
- recipe[ossec::client]
- name: server
run_list:
- recipe[ossec::server]
data_bags_path: 'test/integration/default/data_bags'
......@@ -18,10 +18,8 @@ This cookbook doesn't configure Windows systems yet. For information on installi
- Chef 11+
#### Cookbooks
- build-essential
- apt
- apache2
- yum-atomic
Attributes
----------
......@@ -30,45 +28,49 @@ Default values are based on the defaults from OSSEC's own install.sh installatio
* `node['ossec']['server_role']` - When using server/agent setup, this role is used to search for the OSSEC server, default `ossec_server`.
* `node['ossec']['server_env']` - When using server/agent setup, this value will scope the role search to the specified environment, default nil.
* `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']['data_bag']['encrypted']` - Boolean value which indicates whether or not the OSSEC data bag is encrypted
* `node['ossec']['data_bag']['name']` - The name of the data bag to use
* `node['ossec']['data_bag']['ssh']` - The name of the data bag item which contains the OSSEC keys
* `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.
* `node['ossec']['disable_config_generation']` - Boolean that dictates whether this cookbook should drop the ossec.conf template or not. This is useful if you're using a wrapper cookbook and would like to generate your own template.
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']['install_type']` - This is set automatically to either `server`, `agent`, or `local` before writing ossec.conf. The OSSEC packages do not differentiate between server and local installations but the cookbook behaviour varies slightly.
* `node['ossec']['user']['dir']` - Installation directory for OSSEC, default `/var/ossec`. All existing packages use this directory so you should not change this.
* `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. Can take a string or an array of email addresses.
* `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
-------
###repository
Adds the OSSEC repository to the package manager. This recipe is included by others and should not be used directly. For highly customised setups, you should use `ossec::install_agent` or `ossec::install_server` instead.
###install_agent
Installs the agent packages but performs no explicit configuation.
###install_server
Install the server packages but performs no explicit configuation.
###common
Puts the configuration file in place and starts the (agent or server) service. This recipe is included by other recipes and generally should not be used directly.
Note that the service will not be started if the client.keys file is missing or empty. For agents, this results in an error. For servers, this prevents ossec-remoted from starting, resulting in agents being unable to connect. Once client.keys does exist with content, simply perform another chef-client run to start the service.
###default
The default recipe downloads and installs the OSSEC source and makes sure the configuration file is in place and the service is started. Use only this recipe if setting up local-only installation. The server and client recipes (below) will set their installation type and include this recipe.
Runs `ossec::install_server` and then configures for local-only use. Do not mix this recipe with the others below.
###agent
......@@ -76,11 +78,11 @@ OSSEC uses the term `agent` instead of client. The agent recipe includes the `os
###client
Configures the system as an OSSEC agent to the OSSEC server. This recipe will search for the server based on `node['ossec']['server_role']`. It will also set the `install_type` and `agent_server_ip` attributes. The ossecd user will be created with the SSH key so the server can distribute the agent key.
Configures the system as an OSSEC agent to the OSSEC server. This recipe will search for the server based on `node['ossec']['server_role']`. It will also set the `agent_server_ip` attribute. The ossec user will have an SSH key created so the server can distribute the agent key.
###server
Sets up a system to be an OSSEC server. This recipe will set the `node['ossec']['server']['maxagents']` value to 1024 if it is not set on the node (e.g., via a role). It will search for all nodes that have an `ossec` attribute and add them as an agent.
Sets up a system to be an OSSEC server. This recipe will search for all nodes that have an `ossec` attribute and add them as an agent.
To manage additional agents on the server that don't run chef, or for agentless OSSEC configuration (for example, routers), add a new node for them and create the `node['ossec']['agentless']` attribute as true. For example if we have a router named gw01.example.com with the IP `192.168.100.1`:
......
......@@ -20,9 +20,6 @@
# general settings
default['ossec']['server_role'] = 'ossec_server'
default['ossec']['server_env'] = nil
default['ossec']['checksum'] = '917989e23330d18b0d900e8722392cdbe4f17364a547508742c0fd005a1df7dd'
default['ossec']['version'] = '2.8.3'
default['ossec']['url'] = "http://www.ossec.net/files/ossec-hids-#{node['ossec']['version']}.tar.gz"
default['ossec']['logs'] = []
default['ossec']['syscheck_freq'] = 79_200
default['ossec']['disable_config_generation'] = false
......@@ -32,26 +29,18 @@ default['ossec']['data_bag']['encrypted'] = false
default['ossec']['data_bag']['name'] = 'ossec'
default['ossec']['data_bag']['ssh'] = 'ssh'
# 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'] = []
# ossec-batch-manager.pl location varies
default['ossec']['agent_manager'] = value_for_platform_family(
%w( rhel fedora suse ) => '/usr/share/ossec/contrib/ossec-batch-manager.pl',
'default' => "#{node['ossec']['user']['dir']}/contrib/ossec-batch-manager.pl"
)
......@@ -6,11 +6,11 @@ description 'Installs and onfigures ossec'
long_description IO.read(File.join(File.dirname(__FILE__), 'README.md'))
version '1.0.5'
%w( build-essential apt ).each do |pkg|
%w( apt yum-atomic ).each do |pkg|
depends pkg
end
%w( debian ubuntu arch redhat centos fedora scientific oracle amazon ).each do |os|
%w( debian ubuntu redhat centos fedora ).each do |os|
supports os
end
......
......@@ -30,10 +30,9 @@ else
end
end
node.set['ossec']['user']['install_type'] = 'agent'
node.set['ossec']['user']['agent_server_ip'] = ossec_server.first
include_recipe 'ossec'
include_recipe 'ossec::install_agent'
dbag_name = node['ossec']['data_bag']['name']
dbag_item = node['ossec']['data_bag']['ssh']
......@@ -43,30 +42,24 @@ else
ossec_key = data_bag_item(dbag_name, dbag_item)
end
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'
owner 'ossec'
group 'ossec'
mode 0750
end
template "#{node['ossec']['user']['dir']}/.ssh/authorized_keys" do
source 'ssh_key.erb'
owner 'ossecd'
owner 'ossec'
group 'ossec'
mode 0600
variables(key: ossec_key['pubkey'])
end
file "#{node['ossec']['user']['dir']}/etc/client.keys" do
owner 'ossecd'
owner 'ossec'
group 'ossec'
mode 0660
end
include_recipe 'ossec::common'
#
# Cookbook Name:: ossec
# Recipe:: common
#
# 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.
#
ruby_block 'ossec install_type' do
block do
if node.recipes.include?('ossec::default')
type = 'local'
else
type = nil
File.open('/etc/ossec-init.conf') do |file|
file.each_line do |line|
if line =~ /^TYPE="([^"]+)"/
type = Regexp.last_match(1)
break
end
end
end
end
node.set['ossec']['user']['install_type'] = type
end
end
template "#{node['ossec']['user']['dir']}/etc/ossec.conf" do
source 'ossec.conf.erb'
owner 'root'
group 'ossec'
mode 0440
manage_symlink_source true
variables lazy { { ossec: node['ossec']['user'] } }
not_if { node['ossec']['disable_config_generation'] }
notifies :restart, 'service[ossec]'
end
# Both the RPM and DEB packages enable and start the service
# immediately after installation, which isn't helpful. An empty
# client.keys file will cause a server not to listen and an agent to
# abort immediately. Explicitly stopping the service here after
# installation allows Chef to start it when client.keys has content.
service 'stop ossec' do
service_name 'ossec-hids' unless platform_family?('debian')
action :nothing
%w( disable stop ).each do |action|
subscribes action, 'package[ossec]', :immediately
end
end
service 'ossec' do
service_name 'ossec-hids' unless platform_family?('debian')
supports status: true, restart: true
action [:enable, :start]
not_if do
(node['ossec']['user']['install_type'] != 'local' && !File.size?("#{node['ossec']['user']['dir']}/etc/client.keys")) ||
(node['ossec']['user']['install_type'] == 'agent' && node['ossec']['user']['agent_server_ip'].nil?)
end
end
......@@ -17,63 +17,5 @@
# 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]'
not_if { node['ossec']['disable_config_generation'] }
end
case node['platform']
when 'arch'
template '/usr/lib/systemd/system/ossec.service' do
source 'ossec.service.erb'
owner 'root'
mode 0644
end
end
service 'ossec' do
supports status: true, restart: true
action [:enable, :start]
end
include_recipe 'ossec::install_server'
include_recipe 'ossec::common'
#
# Cookbook Name:: ossec
# Recipe:: install_agent
#
# Copyright 2015, 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::repository'
package 'ossec' do
package_name value_for_platform_family('debian' => 'ossec-hids-agent', 'default' => 'ossec-hids-client')
end
#
# Cookbook Name:: ossec
# Recipe:: install_server
#
# Copyright 2015, 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::repository'
package 'ossec' do
package_name value_for_platform_family('debian' => 'ossec-hids', 'default' => 'ossec-hids-server')
end
#
# Cookbook Name:: ossec
# Recipe:: repository
#
# Copyright 2015, 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.
#
case node['platform_family']
when 'fedora', 'rhel'
include_recipe 'yum-atomic'
when 'debian'
apt_repository 'ossec' do
uri 'http://ossec.wazuh.com/repos/apt/' + node['platform']
key 'http://ossec.wazuh.com/repos/apt/conf/ossec-key.gpg.key'
distribution node['lsb']['codename']
components ['main']
end
end
......@@ -17,23 +17,18 @@
# limitations under the License.
#
node.set['ossec']['user']['install_type'] = 'server'
node.set['ossec']['server']['maxagents'] = 1024
include_recipe 'ossec'
agent_manager = "#{node['ossec']['user']['dir']}/bin/ossec-batch-manager.pl"
include_recipe 'ossec::install_server'
ssh_hosts = []
search_string = 'ossec:[* TO *]'
search_string << " AND chef_environment:#{node['ossec']['server_env']}" if node['ossec']['server_env']
search_string << " NOT role:#{node['ossec']['server_role']}"
search_string << " AND NOT role:#{node['ossec']['server_role']} AND NOT fqdn:#{node['fqdn']}"
search(:node, search_string) do |n|
ssh_hosts << n['ipaddress'] if n['keys']
execute "#{agent_manager} -a --ip #{n['ipaddress']} -n #{n['fqdn'][0..31]}" do
execute "#{node['ossec']['agent_manager']} -a --ip #{n['ipaddress']} -n #{n['fqdn'][0..31]}" do
not_if "grep '#{n['fqdn'][0..31]} #{n['ipaddress']}' #{node['ossec']['user']['dir']}/etc/client.keys"
end
end
......@@ -69,6 +64,8 @@ template "#{node['ossec']['user']['dir']}/.ssh/id_rsa" do
variables(key: ossec_key['privkey'])
end
include_recipe 'ossec::common'
cron 'distribute-ossec-keys' do
minute '0'
command '/usr/local/bin/dist-ossec-keys.sh'
......
[Unit]
Description=OSSEC Host-based Intrusion Detection System
[Service]
Type=forking
ExecStart=<%= node['ossec']['user']['dir'] %>/bin/ossec-control start
ExecStop=<%= node['ossec']['user']['dir'] %>/bin/ossec-control stop
[Install]
WantedBy=basic.target
......@@ -5,6 +5,6 @@ for host in <%= @ssh_hosts.join(' ') %>
do
key=`mktemp`
grep $host <%= node['ossec']['user']['dir'] %>/etc/client.keys > $key
scp -i <%= node['ossec']['user']['dir'] %>/.ssh/id_rsa -B -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no $key ossecd@$host:<%= node['ossec']['user']['dir'] %>/etc/client.keys >/dev/null 2>/dev/null
scp -i <%= node['ossec']['user']['dir'] %>/.ssh/id_rsa -B -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no $key ossec@$host:<%= node['ossec']['user']['dir'] %>/etc/client.keys >/dev/null 2>/dev/null
rm $key
done
......@@ -15,18 +15,17 @@
<% end -%>
</global>
<% if @ossec['install_type'] == 'agent' -%>
<% case @ossec['install_type'] -%>
<% when 'agent' -%>
<client>
<server-ip><%= @ossec['agent_server_ip'] %></server-ip>
</client>
<% end -%>
<% unless @ossec['install_type'] == 'local' -%>
<% when 'server' -%>
<remote>
<connection>secure</connection>
</remote>
<% end -%>
<rules>
<include>rules_config.xml</include>
<include>pam_rules.xml</include>
......
USER_LANGUAGE="<%= @ossec['language'] %>"
USER_NO_STOP="y"
USER_INSTALL_TYPE="<%= @ossec['install_type'] %>"
USER_DIR="<%= @ossec['dir'] %>"
<% if @ossec['delete_dir'] -%>
USER_DELETE_DIR="y"
<% else -%>
USER_DELETE_DIR="n"
<% end -%>
<% if @ossec['active_response'] -%>
USER_ENABLE_ACTIVE_RESPONSE="y"
<% else -%>
USER_ENABLE_ACTIVE_RESPONSE="n"
<% end -%>
<% if @ossec['syscheck'] -%>
USER_ENABLE_SYSCHECK="y"
<% else -%>
USER_ENABLE_SYSCHECK="n"
<% end -%>
<% if @ossec['rootcheck'] -%>
USER_ENABLE_ROOTCHECK="y"
<% else -%>
USER_ENABLE_ROOTCHECK="n"
<% end -%>
<% if @ossec['update'] -%>
USER_UPDATE="y"
<% else -%>
USER_UPDATE="n"
<% end -%>
<% if @ossec['update_rules'] -%>
USER_UPDATE_RULES="y"
<% else -%>
USER_UPDATE_RULES="n"
<% end -%>
<% if @ossec['binary_install'] -%>
USER_BINARYINSTALL="x"
<% end -%>
USER_AGENT_SERVER_IP="<%= @ossec['agent_server_ip'] %>"
<% if @ossec['enable_email'] -%>
USER_ENABLE_EMAIL="y"
<% else -%>
USER_ENABLE_EMAIL="n"
<% end -%>
USER_EMAIL_ADDRESS="<%= @ossec['email'] %>"
USER_EMAIL_SMTP="<%= @ossec['smtp'] %>"
<% if @ossec['remote_syslog'] -%>
USER_ENABLE_SYSLOG="y"
<% else -%>
USER_ENABLE_SYSLOG="n"
<% end -%>
<% if @ossec['pf'] -%>
USER_ENABLE_FIREWALL_RESPONSE="y"
<% else -%>
USER_ENABLE_FIREWALL_RESPONSE="n"
<% end -%>
<% if @ossec['pf'] -%>
USER_ENABLE_PF="y"
USER_PF_TABLE="<%= @ossec['pf_table'] %>"
<% end -%>
<% unless @ossec['white_list'].empty? -%>
USER_WHITE_LIST="<%= @ossec['white_list'].join(' ') %>"
<% else -%>
USER_WHITE_LIST="<%= node['ipaddress'] %>"
<% end -%>
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment