Skip to content
Open

Utils #640

Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
dfbc993
WIP: add new manifest, type and a provider
kibahop Feb 16, 2023
b8ee809
WIP: switch remote_agent from class to defined type for wider use cases
kibahop Feb 17, 2023
d1d8cde
A set of utilities for managing wazuh agents
kibahop Feb 27, 2023
f0e9c5c
Updates to functions and utils.
kibahop Mar 2, 2023
d7ca08d
WIP: updates, adjustments and new features.
kibahop Mar 4, 2023
899e724
Do forgotten linting for examples. Updates to functions, types and ut…
kibahop Mar 6, 2023
0b80a18
Some fixes and rubocop
kibahop Mar 16, 2023
6c07ca5
Provider and defs changes
kibahop Mar 17, 2023
9d0bdcb
wazuh: fact: remove safe navigator for old ruby, handle empty state v…
kibahop Mar 19, 2023
2c863f5
handle case string '' as empty in the fact
kibahop Mar 19, 2023
697c96b
wazuh: be spesific about remote server response
Mar 19, 2023
a705ee6
be explicit about remote state
kibahop Mar 19, 2023
a56116b
When looking up id, return string, not nil if not found
kibahop Mar 19, 2023
16c3574
Still expect string from remote status
kibahop Mar 19, 2023
376bc2d
Fix typo
kibahop Mar 19, 2023
e071409
Fix another typo
kibahop Mar 19, 2023
ecc9a38
Logic and bug fixes, cleanups
kibahop Mar 21, 2023
4b93fc0
Loosen restriction for agent name (might not wanted to be a hostname)
kibahop Mar 21, 2023
bd55520
A bit more troubleshooting info for random rare undefined method `[]'…
kibahop Mar 21, 2023
bce0f15
Still more attempt to catch the random nilclass error
kibahop Mar 21, 2023
362435d
More troubleshooting
Mar 21, 2023
f268c0e
Still troubleshooting
kibahop Mar 21, 2023
655c6b7
Also loosen agent_name in utils defined types to String
kibahop Mar 22, 2023
f6f2cf6
Fix wrong hash for wazuh::utils::agent_name
kibahop Mar 22, 2023
eaf90a4
Fix impossible default for a parameter
kibahop Mar 22, 2023
4376c5a
update utils
kibahop Mar 22, 2023
4a3554a
Add option to make remote checking optional and default to false.
kibahop Mar 23, 2023
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
16 changes: 16 additions & 0 deletions examples/supervise.pp
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#
# @summary Example to Restart agent based on limits in the hash
#
class wazuh::supervise { #lint:ignore:autoloader_layout

$when = {
'last_ack_since' => 300,
'last_keepalive_since' => 300,
'status' => 'disconnected',
}

wazuh::utils::agent_supervise { 'keep control':
when => $when,
}

}
30 changes: 30 additions & 0 deletions examples/wazuh_actions.pp
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
#
# @summmary Example wazuh_actions
#
class wazuh_actions { #lint:ignore:autoloader_layout

wazuh::utils::agent_actions { 'start_wazuh_service':
action => start,
}

wazuh::utils::agent_actions { 'stop_wazuh_service':
action => stop,
require => Wazuh::Utils::Agent_actions['start_wazuh_service'],
}

wazuh::utils::agent_actions { 'disable_wazuh_service':
action => disable,
require => Wazuh::Utils::Agent_actions['start_wazuh_service'],
}

wazuh::utils::agent_actions { 'enable_wazuh_service':
action => enable,
require => Wazuh::Utils::Agent_actions['disable_wazuh_service'],
}

wazuh::utils::agent_actions { 'restart_wazuh_service':
action => restart,
require => Wazuh::Utils::Agent_actions['enable_wazuh_service'],
}
}

55 changes: 55 additions & 0 deletions examples/wazuh_ensure_name.pp
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
#
# @summary Example to change agent name
#
class wazuh_ensure_name { #lint:ignore:autoloader_layout

$new_name = 'brand-new-agent.example.com'
$current_name = $facts['wazuh']['agent']['name']

notify { "current wazuh name fact: ${facts['wazuh']['agent']['name']}":
}

notify { "new wazuh name: ${new_name}":
require => Notify["current wazuh name fact: ${facts['wazuh']['agent']['name']}"],
before => Notify["new wazuh name fact: ${facts['wazuh']['agent']['name']}"],
}

# does the name differ from current name?
if $new_name != $current_name {

# prevent current agent from reconnecting in the middle
wazuh::utils::agent_actions { "${current_name}_stop":
action => stop,
require => Notify["new wazuh name: ${new_name}"]
}

# remove current name from the manager
# (custom function runs on puppet server)
wazuh::utils::api_remove_agent { $current_name:
api_username => 'wazuh',
api_password => 'wazuh',
api_host => 'wazuh.example.com',
api_host_port => 55000,
agent_name => $current_name,
require => Wazuh::Utils::Agent_actions["${current_name}_stop"],
}

# reauth with a brand new name
wazuh::utils::local_agent_name { $new_name:
agent_name => $new_name,
auth_server_name => 'wazuh.example.com',
auth_password => 'changeme',
require => Wazuh::Utils::Api_remove_agent[$current_name],
}

# start the service again
wazuh::utils::agent_actions { "${new_name}_start":
action => start,
require => Wazuh::Utils::Local_agent_name[$new_name],
notify => Notify["new wazuh name fact: ${facts['wazuh']['agent']['name']}"]
}

}

notify { "new wazuh name fact: ${facts['wazuh']['agent']['name']}": }
}
14 changes: 14 additions & 0 deletions examples/wazuh_nametest.pp
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#
# @summary Agent name change example
#
class wazuh_nametest { #lint:ignore:autoloader_layout

# $agent_name = 'my-brand-new-agent.example.com'
$agent_name = 'wazuh-agent.example.com'

wazuh::utils::local_agent_name { $agent_name:
auth_server_name => 'wazuh.example.com',
auth_password => 'changeme',
agent_name => $agent_name,
}
}
15 changes: 15 additions & 0 deletions examples/wazuh_remove.pp
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#
# @summary Example to remove agent from manager
#
class wazuh_remove { #lint:ignore:autoloader_layout

$agent_name = 'wazuh-agent.example.com'

wazuh::utils::api_remove_agent { $agent_name:
agent_name => $agent_name,
api_username => 'wazuh',
api_password => 'wazuh',
api_host => 'wazuh.example.com',
api_host_port => 55000,
}
}
14 changes: 14 additions & 0 deletions lib/facter/ossec_conf_exists.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# frozen_string_literal: true

# @summary Check if Wazuh configuration file exist
#
# @author Petri Lammi [email protected]
#
# @example
#
# notify { $facts['wazuh']['state']['status']:
Facter.add('ossec_conf_exists') do
setcode do
File.exist?('/var/ossec/etc/ossec.conf')
end
end
113 changes: 113 additions & 0 deletions lib/facter/wazuh_facts.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
# frozen_string_literal: true

# @summary Produces a structured wazuh fact
#
# @author Petri Lammi [email protected]
#
# @example
#
# notify { $facts['wazuh']['state']['status']: }

Facter.add(:wazuh) do
confine kernel: 'Linux'
confine ossec_conf_exists: true

setcode do
@keyfile = String.new('/var/ossec/etc/client.keys')
@authd_pass_file = String.new('/var/ossec/etc/authd.pass')

def wazuh_agent_data(index)
if File.exist?(@keyfile)
File.read(@keyfile).split[index]
else
nil
end
end

wazuh_agent_id = wazuh_agent_data(0)
wazuh_agent_name = wazuh_agent_data(1)
wazuh_agent_ip = wazuh_agent_data(2)
wazuh_agent_key = wazuh_agent_data(3)

def wazuh_agent_version
cmd = String.new
case Facter.value('osfamily')
when 'RedHat'
cmd = '/bin/rpm -q wazuh-agent --queryformat "%{VERSION}"'
when 'Debian'
cmd = '/usr/bin/dpkg-query -W -f="\\${Version}" wazuh-agent'
end
Facter::Core::Execution.execute(cmd)
end

def password_hash
if File.exist?(@authd_pass_file)
password = File.read(@authd_pass_file).chomp
hash = Digest::SHA256.hexdigest(password)
else
nil
end
hash
end

wazuh_agent_hash = {
id: wazuh_agent_id,
name: wazuh_agent_name,
ip_address: wazuh_agent_ip,
key: wazuh_agent_key,
version: wazuh_agent_version,
password_hash: password_hash
}

def get_ossec_conf_value(key)
if File.exist?(@keyfile)
IO.readlines('/var/ossec/etc/ossec.conf').grep(%r{^.*<#{key}>}).map { |line|
line.match(%r{^.*<#{key}>(.*)</#{key}>}).captures.first.strip
}.compact.first
else
nil
end
end

def wazuh_server_name
get_ossec_conf_value('address') || nil
end

def wazuh_server_port
get_ossec_conf_value('port').to_i || nil
end

wazuh_server_hash = {
name: wazuh_server_name,
port: wazuh_server_port
}

wazuh_state_hash = {}
state_file_path = '/var/ossec/var/run/wazuh-agentd.state'
if File.exist?(state_file_path)
File.foreach(state_file_path) do |line|
key, value = line.strip.split('=')
case key
when 'last_keepalive'
# calculate seconds since last keepalive
seconds_since_keepalive = value.gsub("'", '').empty? ? 0 : (Time.now - Time.parse(value)).to_i
wazuh_state_hash['last_keepalive_since'] = seconds_since_keepalive
when 'last_ack'
# calculate seconds since last ack
seconds_since_ack = value.gsub("'", '').empty? ? 0 : (Time.now - Time.parse(value)).to_i
wazuh_state_hash['last_ack_since'] = seconds_since_ack
when 'status'
wazuh_state_hash['status'] = value.gsub("'", '')
end
end
end

wazuh_hash = {
agent: wazuh_agent_hash,
server: wazuh_server_hash,
state: wazuh_state_hash
}

wazuh_hash
end
end
20 changes: 20 additions & 0 deletions lib/puppet/functions/wazuh/api_agent_exists.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# frozen_string_literal: true

#
# @summary A custom function to check the existense of an agent
#
# @author Kibahop <[email protected]>
#
require_relative 'apihelper'

Puppet::Functions.create_function(:'wazuh::api_agent_exists') do
dispatch :api_agent_exists? do
param 'Hash', :config
return_type 'Boolean'
end

def api_agent_exists?(config)
api_helper = ApiHelper.new(config)
api_helper.agent_exists?
end
end
21 changes: 21 additions & 0 deletions lib/puppet/functions/wazuh/api_agent_id.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# frozen_string_literal: true

#
# @summary A custom fact to check the status of an agent on the manager side
#
# @author Kibahop <[email protected]>
#
require_relative 'apihelper'

Puppet::Functions.create_function(:'wazuh::api_agent_id') do
dispatch :api_agent_id do
param 'Hash', :config
return_type 'String'
end

def api_agent_id(config)
Puppet.debug(:config)
api_helper = ApiHelper.new(config)
api_helper.agent_id
end
end
21 changes: 21 additions & 0 deletions lib/puppet/functions/wazuh/api_agent_name.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# frozen_string_literal: true

#
# @summary A custom fact to check the status of an agent on the manager side
#
# @author Kibahop <[email protected]>
#
require_relative 'apihelper'

Puppet::Functions.create_function(:'wazuh::api_agent_name') do
dispatch :api_agent_name do
param 'Hash', :config
return_type 'String'
end

def api_agent_name(config)
Puppet.debug(:config)
api_helper = ApiHelper.new(config)
api_helper.agent_name
end
end
19 changes: 19 additions & 0 deletions lib/puppet/functions/wazuh/api_agent_remove.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# frozen_string_literal: true

#
# @summary A custom fact to remove a Wazuh agent via API.
#
# @author Kibahop <[email protected]>
#
require_relative 'apihelper'

Puppet::Functions.create_function(:'wazuh::api_agent_remove') do
dispatch :api_agent_remove do
param 'Hash', :config
end

def api_agent_remove(config)
api_helper = ApiHelper.new(config)
api_helper.agent_remove
end
end
21 changes: 21 additions & 0 deletions lib/puppet/functions/wazuh/api_agent_status.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# frozen_string_literal: true

#
# @summary A custom fact to check the status of an agent on the manager side
#
# @author Kibahop <[email protected]>
#
require_relative 'apihelper'

Puppet::Functions.create_function(:'wazuh::api_agent_status') do
dispatch :api_agent_status do
param 'Hash', :config
return_type 'String'
end

def api_agent_status(config)
Puppet.debug(:config)
api_helper = ApiHelper.new(config)
api_helper.agent_status
end
end
Loading