Provide IPFire specific items for the Zabbix server to monitor: - Networking stats: - ipfire.net.gateway.pingtime: Internet Line Quality - ipfire.net.gateway.ping: Internet connection - ipfire.net.fw.hits[*]: Firewall hits - IPFire service states: - ipfire.services: JSON formatted state of all IPFire services using new ipfire_services.pl script.
Users can install the IPFire 2 Zabbix template-set provided here: https://share.zabbix.com/network-appliances/ipfire-2 to monitor these metrics. Or create their own template.
Signed-off-by: Robin Roevens robin.roevens@disroot.org --- config/rootfiles/packages/zabbix_agentd | 3 + config/zabbix_agentd/ipfire_services.pl | 221 ++++++++++++++++++ config/zabbix_agentd/sudoers | 2 +- .../template_module_ipfire_network_stats.conf | 4 + .../template_module_ipfire_services.conf | 2 + lfs/zabbix_agentd | 8 +- src/paks/zabbix_agentd/install.sh | 5 + src/paks/zabbix_agentd/uninstall.sh | 2 + 8 files changed, 245 insertions(+), 2 deletions(-) create mode 100755 config/zabbix_agentd/ipfire_services.pl create mode 100644 config/zabbix_agentd/template_module_ipfire_network_stats.conf create mode 100644 config/zabbix_agentd/template_module_ipfire_services.conf
diff --git a/config/rootfiles/packages/zabbix_agentd b/config/rootfiles/packages/zabbix_agentd index 6945c5ef7..aa3f1846b 100644 --- a/config/rootfiles/packages/zabbix_agentd +++ b/config/rootfiles/packages/zabbix_agentd @@ -3,9 +3,12 @@ etc/rc.d/init.d/zabbix_agentd etc/sudoers.d/zabbix.ipfirenew #etc/zabbix_agentd #etc/zabbix_agentd/scripts +etc/zabbix_agentd/scripts/ipfire_services.pl.ipfirenew etc/zabbix_agentd/zabbix_agentd.conf.ipfirenew #etc/zabbix_agentd/zabbix_agentd.d etc/zabbix_agentd/zabbix_agentd.d/template_app_pakfire.conf.ipfirenew +etc/zabbix_agentd/zabbix_agentd.d/template_module_ipfire_network_stats.conf.ipfirenew +etc/zabbix_agentd/zabbix_agentd.d/template_module_ipfire_services.conf.ipfirenew usr/bin/zabbix_get usr/bin/zabbix_sender #usr/lib/modules diff --git a/config/zabbix_agentd/ipfire_services.pl b/config/zabbix_agentd/ipfire_services.pl new file mode 100755 index 000000000..dbf8aec56 --- /dev/null +++ b/config/zabbix_agentd/ipfire_services.pl @@ -0,0 +1,221 @@ +#!/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: 1.0 +# +# Based on: services.cgi by IPFire Team +# Copyright (C) 2007-2021 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; + +# Maps a nice printable name to the changing part of the pid file, which +# is also the name of the program +my %servicenames =( + 'DHCP Server' => 'dhcpd', + 'Web Server' => 'httpd', + 'CRON Server' => 'fcron', + 'DNS Proxy Server' => 'unbound', + 'Logging Server' => 'syslogd', + 'Kernel Logging Server' => 'klogd', + 'NTP Server' => 'ntpd', + 'Secure Shell Server' => 'sshd', + 'VPN' => 'charon', + 'Web Proxy' => 'squid', + 'Intrusion Detection System' => 'suricata', + 'OpenVPN' => 'openvpn' +); + +# Hash to overwrite the process name of a process if it differs from the launch command. +my %overwrite_exename_hash = ( + "suricata" => "Suricata-Main" +); + +my $first = 1; + +print "["; + +# Built-in services +my $key = ''; +foreach $key (sort keys %servicenames){ + print "," if not $first; + $first = 0; + + print "{"; + print ""service":"$key","; + + my $shortname = $servicenames{$key}; + print &servicestats($shortname); + + print "}"; +} + +# Generate list of installed addon pak's +my @pak = `find /opt/pakfire/db/installed/meta-* 2>/dev/null | cut -d"-" -f2`; +foreach (@pak){ + chomp($_); + + # Check which of the paks are services + my @svc = `find /etc/init.d/$_ 2>/dev/null | cut -d"/" -f4`; + foreach (@svc){ + # blacklist some packages + # + # alsa has trouble with the volume saving and was not really stopped + # mdadm should not stopped with webif because this could crash the system + # + chomp($_); + if ( $_ eq 'squid' ) { + next; + } + if ( ($_ ne "alsa") && ($_ ne "mdadm") ) { + print ","; + print "{"; + + print ""service":"Addon: $_","; + print ""servicename":"$_","; + + my $onboot = isautorun($_); + print ""onboot":$onboot,"; + + print &addonservicestats($_); + + print "}"; + } + } +} + +print "]"; + +sub servicestats{ + my $cmd = $_[0]; + my $status = ""servicename":"$cmd","state":"0""; + my $pid = ''; + my $testcmd = ''; + my $exename; + my $memory; + + + $cmd =~ /(^[a-z]+)/; + + # Check if the exename needs to be overwritten. + # This happens if the expected process name string + # differs from the real one. This may happened if + # a service uses multiple processes or threads. + if (exists($overwrite_exename_hash{$cmd})) { + # Grab the string which will be reported by + # the process from the corresponding hash. + $exename = $overwrite_exename_hash{$1}; + } else { + # Directly expect the launched command as + # process name. + $exename = $1; + } + + if (open(FILE, "/var/run/${cmd}.pid")){ + $pid = <FILE>; chomp $pid; + close FILE; + if (open(FILE, "/proc/${pid}/status")){ + while (<FILE>){ + if (/^Name:\W+(.*)/) { + $testcmd = $1; + } + } + close FILE; + } + if (open(FILE, "/proc/${pid}/status")) { + while (<FILE>) { + my ($key, $val) = split(":", $_, 2); + if ($key eq 'VmRSS') { + $val =~ /\s*([0-9]*)\s+kB/; + # Convert kB to B + $memory = $1*1024; + last; + } + } + close(FILE); + } + if ($testcmd =~ /$exename/){ + $status = ""servicename":"$cmd","state":1,"pid":$pid,"memory":$memory"; + } + } + return $status; +} + +sub isautorun{ + my $cmd = $_[0]; + my $status = "0"; + my $init = `find /etc/rc.d/rc3.d/S??${cmd} 2>/dev/null`; + chomp ($init); + if ($init ne ''){ + $status = "1"; + } + $init = `find /etc/rc.d/rc3.d/off/S??${cmd} 2>/dev/null`; + chomp ($init); + if ($init ne ''){ + $status = "0"; + } + + return $status; +} + +sub addonservicestats{ + my $cmd = $_[0]; + my $status = "0"; + my $pid = ''; + my $testcmd = ''; + my $exename; + my @memory = (0); + + $testcmd = `sudo /usr/local/bin/addonctrl $_ status 2>/dev/null`; + + if ( $testcmd =~ /is\ running/ && $testcmd !~ /is\ not\ running/){ + $status = ""state":1"; + + $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 @pid = split(/\s/,$testcmd); + $status .=","pid":"$pid[0]""; + + my $memory = 0; + + foreach (@pid){ + chomp($_); + if (open(FILE, "/proc/$_/statm")){ + my $temp = <FILE>; + @memory = split(/ /,$temp); + } + $memory+=$memory[0]; + } + $memory*=1024; + $status .=","memory":$memory"; + }else{ + $status = ""state":0"; + } + return $status; +} diff --git a/config/zabbix_agentd/sudoers b/config/zabbix_agentd/sudoers index 1b362a4fd..340bb8e66 100644 --- a/config/zabbix_agentd/sudoers +++ b/config/zabbix_agentd/sudoers @@ -14,4 +14,4 @@ # Append / edit the following list of commands to fit your needs: # Defaults:zabbix !requiretty -zabbix ALL=(ALL) NOPASSWD: /opt/pakfire/pakfire status +zabbix ALL=(ALL) NOPASSWD: /opt/pakfire/pakfire status, /usr/local/bin/addonctrl, /sbin/iptables, /usr/sbin/fping diff --git a/config/zabbix_agentd/template_module_ipfire_network_stats.conf b/config/zabbix_agentd/template_module_ipfire_network_stats.conf new file mode 100644 index 000000000..f1658ed07 --- /dev/null +++ b/config/zabbix_agentd/template_module_ipfire_network_stats.conf @@ -0,0 +1,4 @@ +### Parameters for monitoring IPFire network statistics +UserParameter=ipfire.net.gateway.pingtime,sudo /usr/sbin/fping -c 3 gateway 2>&1 | tail -n 1 | awk '{print $NF}' | cut -d '/' -f2 +UserParameter=ipfire.net.gateway.ping,sudo /usr/sbin/fping -q -r 3 gateway; [ ! $? ]; echo $? +UserParameter=ipfire.net.fw.hits[*],sudo /sbin/iptables -vnxL $1 | grep "/* $2 */" | awk '{ print $$2 }'; diff --git a/config/zabbix_agentd/template_module_ipfire_services.conf b/config/zabbix_agentd/template_module_ipfire_services.conf new file mode 100644 index 000000000..5f95218e3 --- /dev/null +++ b/config/zabbix_agentd/template_module_ipfire_services.conf @@ -0,0 +1,2 @@ +### Parameter for monitoring IPFire services +UserParameter=ipfire.services,/etc/zabbix_agentd/scripts/ipfire_services.pl diff --git a/lfs/zabbix_agentd b/lfs/zabbix_agentd index badfde3ae..1debfeeb0 100644 --- a/lfs/zabbix_agentd +++ b/lfs/zabbix_agentd @@ -33,7 +33,7 @@ DIR_APP = $(DIR_SRC)/$(THISAPP) TARGET = $(DIR_INFO)/$(THISAPP) PROG = zabbix_agentd PAK_VER = 5 -DEPS = +DEPS = "fping"
############################################################################### # Top-level Rules @@ -97,6 +97,12 @@ $(TARGET) : $(patsubst %,$(DIR_DL)/%,$(objects)) /etc/zabbix_agentd/zabbix_agentd.conf.ipfirenew install -v -m 644 $(DIR_SRC)/config/zabbix_agentd/template_app_pakfire.conf \ /etc/zabbix_agentd/zabbix_agentd.d/template_app_pakfire.conf.ipfirenew + install -v -m 644 $(DIR_SRC)/config/zabbix_agentd/template_module_ipfire_network_stats.conf \ + /etc/zabbix_agentd/zabbix_agentd.d/template_module_ipfire_network_stats.conf.ipfirenew + install -v -m 644 $(DIR_SRC)/config/zabbix_agentd/template_module_ipfire_services.conf \ + /etc/zabbix_agentd/zabbix_agentd.d/template_module_ipfire_services.conf.ipfirenew + install -v -m 755 $(DIR_SRC)/config/zabbix_agentd/ipfire_services.pl \ + /etc/zabbix_agentd/scripts/ipfire_services.pl.ipfirenew
# Create directory for additional agent modules -mkdir -pv /usr/lib/zabbix diff --git a/src/paks/zabbix_agentd/install.sh b/src/paks/zabbix_agentd/install.sh index 4248a7ec1..ced915c81 100644 --- a/src/paks/zabbix_agentd/install.sh +++ b/src/paks/zabbix_agentd/install.sh @@ -66,8 +66,13 @@ restore_backup ${NAME} # Put zabbix configfiles in place setup_configfile /etc/zabbix_agentd/zabbix_agentd.conf setup_configfile /etc/zabbix_agentd/zabbix_agentd.d/template_app_pakfire.conf +setup_configfile /etc/zabbix_agentd/zabbix_agentd.d/template_module_ipfire_network_stats.conf +setup_configfile /etc/zabbix_agentd/zabbix_agentd.d/template_module_ipfire_services.conf setup_configfile /etc/sudoers.d/zabbix
+# Overwrite script if it exists as user should not modify it but it is included in backup +mv /etc/zabbix_agentd/scripts/ipfire_services.pl.ipfirenew /etc/zabbix_agentd/scripts/ipfire_services.pl + if $review_required; then echo "WARNING: New versions of some configfile(s) where provided as .ipfirenew-files." echo " They may need manual review in order to take advantage of new features" diff --git a/src/paks/zabbix_agentd/uninstall.sh b/src/paks/zabbix_agentd/uninstall.sh index 7a13880c5..ccbc8f7cf 100644 --- a/src/paks/zabbix_agentd/uninstall.sh +++ b/src/paks/zabbix_agentd/uninstall.sh @@ -26,6 +26,8 @@ stop_service ${NAME}
# Remove .ipfirenew files in advance so they won't be included in backup rm -rfv /etc/zabbix_agentd/*.ipfirenew /etc/zabbix_agentd/*/*.ipfirenew +# Remove script-file as it should not have been modified by user +rm -fv /etc/zabbix_agentd/scripts/ipfire_services.pl
make_backup ${NAME} remove_files