zabbix_agentd: Add IPFire services.get item

Message ID 20240910212924.1685603-2-robin.roevens@disroot.org
State Staged
Commit a66263b4f5c746c3c7f7c320e45c3ac78811c7a8
Headers
Series zabbix_agentd: Add IPFire services.get item |

Commit Message

Robin Roevens Sept. 10, 2024, 9:12 p.m. UTC
  - 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
  

Patch

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