Hi all,
This patch introduces again the ability for Zabbix to get information about the running IPFire services. This functionality was already submitted a long while ago but was rejected because the perl script behind it contained the same 'ugly code' as services.cgi contained back then. Meanwhile the code of services.cgi was updated by both me, adding more generic addon services discovery using new pakfire functions, and more recently by Michael with new general functions for finding pids and memory consumption of services.
So I now refactored my services-discovery-perl-script, that will be used by the zabbix-agent if the Zabbix server requests services information, to use the same methods as currently used in services.cgi, using those new functions, hoping that this feature now can be accepted into IPFire.
Note: I don't change the PAKVER in this patch, which should not be needed if this patch is applyed shortly after my previous patch updating zabbix_agentd to v6.0.33
Regards
Robin
- Adds Zabbix Agent userparameter `ipfire.services.get` for the agent to get details about configured IPFire services (builtin and addon-services) - Includes `ipfire_services.pl` script in sudoers for Zabbix Agent as it needs root permission to call addonctrl for addon service states. - Adapts lfs install script to install new script - Adds new script to rootfiles --- config/rootfiles/packages/zabbix_agentd | 1 + config/zabbix_agentd/ipfire_services.pl | 212 ++++++++++++++++++ config/zabbix_agentd/sudoers | 1 + .../zabbix_agentd/userparameter_ipfire.conf | 4 +- lfs/zabbix_agentd | 2 + 5 files changed, 219 insertions(+), 1 deletion(-) create mode 100755 config/zabbix_agentd/ipfire_services.pl
diff --git a/config/rootfiles/packages/zabbix_agentd b/config/rootfiles/packages/zabbix_agentd index 8e10cb4c8..ffa66f307 100644 --- a/config/rootfiles/packages/zabbix_agentd +++ b/config/rootfiles/packages/zabbix_agentd @@ -23,3 +23,4 @@ var/ipfire/zabbix_agentd/userparameters/userparameter_ipfire.conf var/ipfire/zabbix_agentd/userparameters/userparameter_ovpn.conf var/ipfire/zabbix_agentd/scripts var/ipfire/zabbix_agentd/scripts/ipfire_certificate_detail.sh +var/ipfire/zabbix_agentd/scripts/ipfire_services.pl diff --git a/config/zabbix_agentd/ipfire_services.pl b/config/zabbix_agentd/ipfire_services.pl new file mode 100755 index 000000000..c3233f6c9 --- /dev/null +++ b/config/zabbix_agentd/ipfire_services.pl @@ -0,0 +1,212 @@ +#!/usr/bin/perl +############################################################################### +# ipfire_services.pl - Retrieves available IPFire services information and +# return this as a JSON array suitable for easy processing +# by Zabbix server +# +# Author: robin.roevens (at) disroot.org +# Version: 3.0 +# +# Copyright (C) 2007-2024 IPFire Team info@ipfire.org +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see http://www.gnu.org/licenses/. +# +############################################################################### + +use strict; + +# enable only the following on debugging purpose +# use warnings; + +# Load General functions +require "/var/ipfire/general-functions.pl"; + +# Load Pakfire functions +require "/opt/pakfire/lib/functions.pl"; + +my $first = 1; + +print "["; + +# Built-in services +my %services = ( + # DHCP Server + 'DHCP Server' => { + "process" => "dhcpd", + }, + + # Web Server + 'Web Server' => { + "process" => "httpd", + }, + + # Cron Server + 'CRON Server' => { + "process" => "fcron", + }, + + # DNS Proxy + 'DNS Proxy Server' => { + "process" => "unbound", + }, + + # Syslog + 'Logging Server' => { + "process" => "syslogd", + }, + + # Kernel Logger + 'Kernel Logging Server' => { + "process" => "klogd", + }, + + # Time Server + 'NTP Server' => { + "process" => "ntpd", + }, + + # SSH Server + 'Secure Shell Server' => { + "process" => "sshd", + }, + + # IPsec + 'VPN' => { + "process" => "charon", + }, + + # Web Proxy + 'Web Proxy' => { + "process" => "squid", + }, + + # IPS + 'Intrusion Prevention System' => { + "process" => "suricata", + "pidfile" => "/var/run/suricata.pid", + }, + + # OpenVPN Roadwarrior + 'OpenVPN Roadwarrior Server' => { + "process" => "openvpn", + "pidfile" => "/var/run/openvpn.pid", + } +); + +foreach my $service (sort keys %services){ + my %config = %{ $services{$service} }; + + my $pidfile = $config{"pidfile"}; + my $process = $config{"process"}; + + # Collect all pids + my @pids = (); + + # Read the PID file or go search... + if (defined $pidfile) { + @pids = &General::read_pids("${pidfile}"); + } else { + @pids = &General::find_pids("${process}"); + } + + # Not Running + my $status = ""state":"0""; + + # Running? + if (scalar @pids) { + # Get memory consumption + my $mem = &General::get_memory_consumption(@pids); + + $status = ""state":1,"pids":[" . join(',', @pids) . "],"memory":$mem"; + } + + print "," if not $first; + $first = 0; + + print "{"; + print ""service":"$service","servicename":"$process",$status"; + print "}"; +} + +# Generate list of installed addon pak's +my %paklist = &Pakfire::dblist("installed"); + +foreach my $pak (keys %paklist) { + my %metadata = &Pakfire::getmetadata($pak, "installed"); + + # If addon contains services + if ("$metadata{'Services'}") { + foreach my $service (split(/ /, "$metadata{'Services'}")) { + print ","; + print "{"; + + print ""service":"Addon: $metadata{'Name'}","; + print ""servicename":"$service","; + + my $onboot = isautorun($pak, $service); + print ""onboot":$onboot,"; + + print &addonservicestats($pak, $service); + + print "}"; + } + } +} + +print "]"; + +sub isautorun() { + my ($pak, $service) = @_; + my @testcmd = &General::system_output("/usr/local/bin/addonctrl", "$pak", "boot-status", "$service"); + my $testcmd = @testcmd[0]; + my $status = 9; + + # Check if autorun for the given service is enabled. + if ( $testcmd =~ /enabled\ on\ boot/ ) { + $status = 1; + } elsif ( $testcmd =~ /disabled\ on\ boot/ ) { + $status = 0; + } + + # Return the status. + return $status; +} + +sub addonservicestats() { + my ($pak, $service) = @_; + my $testcmd = ''; + my $exename; + my @memory = (0); + + my @testcmd = &General::system_output("/usr/local/bin/addonctrl", "$pak", "status", "$service"); + my $testcmd = @testcmd[0]; + + my $status = ""state":0"; + if ( $testcmd =~ /is\ running/ && $testcmd !~ /is\ not\ running/){ + $testcmd =~ s/.* //gi; + $testcmd =~ s/[a-z_]//gi; + $testcmd =~ s/[[0-1];[0-9]+//gi; + $testcmd =~ s/[().]//gi; + $testcmd =~ s/ //gi; + $testcmd =~ s///gi; + + my @pids = split(/\s/,$testcmd); + + # Fetch the memory consumption + my $memory = &General::get_memory_consumption(@pids); + + $status = ""state":1,"pids":[" . join(',', @pids) . "],"memory":$memory"; + } + return $status; +} diff --git a/config/zabbix_agentd/sudoers b/config/zabbix_agentd/sudoers index 138c75635..78e175980 100644 --- a/config/zabbix_agentd/sudoers +++ b/config/zabbix_agentd/sudoers @@ -10,3 +10,4 @@ Defaults:zabbix !requiretty zabbix ALL=(ALL) NOPASSWD: /opt/pakfire/pakfire status, /usr/sbin/fping, /usr/local/bin/getipstat, /bin/cat /var/run/ovpnserver.log zabbix ALL=(ALL) NOPASSWD: /var/ipfire/zabbix_agentd/scripts/ipfire_certificate_detail.sh +zabbix ALL=(ALL) NOPASSWD: /var/ipfire/zabbix_agentd/scripts/ipfire_services.pl diff --git a/config/zabbix_agentd/userparameter_ipfire.conf b/config/zabbix_agentd/userparameter_ipfire.conf index d2d0c8307..cc0bd9f8e 100644 --- a/config/zabbix_agentd/userparameter_ipfire.conf +++ b/config/zabbix_agentd/userparameter_ipfire.conf @@ -9,4 +9,6 @@ UserParameter=ipfire.net.fw.hits.raw,sudo /usr/local/bin/getipstat -xf | grep "/ # Number of currently Active DHCP leases UserParameter=ipfire.dhcpd.clients,grep -s -E 'lease|bind' /var/state/dhcp/dhcpd.leases | sed ':a;/{$/{N;s/\n//;ba}' | grep "state active" | wc -l # Number of Captive Portal clients -UserParameter=ipfire.captive.clients,awk -F ',' 'length($2) == 17 {sum += 1} END {if (length(sum) == 0) print 0; else print sum}' /var/ipfire/captive/clients \ No newline at end of file +UserParameter=ipfire.captive.clients,awk -F ',' 'length($2) == 17 {sum += 1} END {if (length(sum) == 0) print 0; else print sum}' /var/ipfire/captive/clients +# Services list and state +UserParameter=ipfire.services.get,sudo /var/ipfire/zabbix_agentd/scripts/ipfire_services.pl \ No newline at end of file diff --git a/lfs/zabbix_agentd b/lfs/zabbix_agentd index 06956ad41..3e806c1da 100644 --- a/lfs/zabbix_agentd +++ b/lfs/zabbix_agentd @@ -117,6 +117,8 @@ $(TARGET) : $(patsubst %,$(DIR_DL)/%,$(objects)) -mkdir -pv /var/ipfire/zabbix_agentd/scripts install -v -m 755 $(DIR_SRC)/config/zabbix_agentd/ipfire_certificate_detail.sh \ /var/ipfire/zabbix_agentd/scripts/ipfire_certificate_detail.sh + install -v -m 755 $(DIR_SRC)/config/zabbix_agentd/ipfire_services.pl \ + /var/ipfire/zabbix_agentd/scripts/ipfire_services.pl
# Create directory for additional agent modules -mkdir -pv /usr/lib/zabbix