-
Notifications
You must be signed in to change notification settings - Fork 1.8k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #293 from RobinR1/ipfire
Add template for monitoring IPFire
- Loading branch information
Showing
10 changed files
with
3,326 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
# IPFire by Zabbix Agent Active | ||
|
||
## Description | ||
|
||
This template monitors an [IPFire](https://www.ipfire.org/) [appliance](https://www.lightningwirelabs.com/products/ipfire/appliances) or [instance](https://www.ipfire.org/download) | ||
|
||
## Overview | ||
|
||
For Zabbix version: 6.0 | ||
|
||
Supports monitoring of: | ||
- IPFire general stats (Number of current DHCPd clients) | ||
- IPFire services (default IPFire services and possible Addon services) | ||
- Pakfire status (Installed version, Available update(s)) | ||
- Network stats (Line quality, Open Connections, Firewall hits) | ||
- OpenVPN clients and stats (OpenVPN client discovery, OpenVPN client properties, Traffic stats) | ||
|
||
Use in conjunction with a default Template OS Linux-template for CPU/Memory/Storage monitoring of the IPFire appliance/instance. | ||
|
||
This template was created for: | ||
|
||
- IPFire 2.27 - Core update 179 | ||
|
||
**Warning**: This template will *NOT* work on earlier versions of IPFire due to changes to the Zabbix Agent addon. | ||
|
||
## Author | ||
|
||
Robin Roevens | ||
|
||
## Setup | ||
|
||
- Install and configure [IPFire addon `zabbix_agentd`](https://wiki.ipfire.org/addons/zabbix_agentd) using Pakfire | ||
- Make sure the IPFire builtin specific userparameters are enabled in `/etc/zabbix_agentd/zabbix_agentd.conf` (which should be by default) | ||
- Copy `template_ipfire_services.conf` into the folder with Zabbix agent configuration (`/etc/zabbix_agentd/zabbix_agentd.d/` on IPFire) | ||
- Copy `ipfire_services.pl` into the folder with Zabbix agent scripts (`/etc/zabbix_agentd/scripts/` on IPFire) and make it executable for user `root`. | ||
- Unless you have your own custom sudoers config for zabbix; Copy `zabbix_agentd_user` into the folder with sudoers configuration (`/etc/sudoers.d`) to allow Zabbix agent to run `ipfire_services.pl` as root user. | ||
Otherwise, make sure the contents of `zabbix_agentd_user` from this template are added to your custom `/etc/sudoers.d/zabbix_agentd_user` file. | ||
- Restart Zabbix agent. | ||
|
||
## Zabbix configuration | ||
|
||
No specific Zabbix configuration is required | ||
|
||
### Macros used | ||
|Name|Description|Default| | ||
|----|-----------|-------| | ||
|{$IPFIRE.CONN.MAX.WARN} |<p>Max percentage of max open connections used before triggering warning</p>|`95` | | ||
|{$IPFIRE.CONN.MAX.RESOLVE} |<p>Percentage of max open connections used before resolving trigger</p>|`85` | | ||
|{$IPFIRE.FW_CHAIN.MATCHES} |<p>Only discover firewall chains matching this regex</p>|`^.*$` | | ||
|{$IPFIRE.FW_CHAIN.NOT_MATCHES} |<p>Do not discover firewall chains matching this regex</p>|`CHANGE_IF_NEEDED` | | ||
|{$IPFIRE.SERVICE.TRIGGER} |<p>Whether Zabbix needs to trigger when an IPFire service is down. This variable can be used with context to exclude specific services.</p>|`1` | | ||
|{$IPFIRE.SERVICENAME.MATCHES} |<p>All services matching this regex will be discovered</p>|`^.*$` | | ||
|{$IPFIRE.SERVICENAME.NOT_MATCHES} |<p>Services matching this regex will not be discovered</p>|`CHANGE_IF_NEEDED` | | ||
|{$IPFIRE.OVPN.COMMONNAME.MATCHES} |<p>OpenVPN clients with common name matching this regex will be discovered</p>|`^.*$` | | ||
|{$IPFIRE.OVPN.COMMONNAME.NOTMATCHES} |<p>OpenVPN clients with common name matching this regex will not be discovered</p>|`CHANGE_IF_NEEDED` | | ||
|{$IPFIRE.OVPN.STATE.MATCHES} |<p>OpenVPN clients with a state (on/off) matching this regex will be discovered.</p>|`on` | | ||
|
||
#### Notes about $IPFIRE.SERVICE.TRIGGER | ||
This template does not 'detect' if you have manually disabled a service in IPFire, so by default it will alarm you when any service is down. This is done on purpose so that you will also be notified if a service is unintentionly disabled. | ||
|
||
To disable the trigger for a specific service (because it is disabled or you just don't want notifications about that service) add a host macro `{$IPFIRE.SERVICE.TRIGGER:"<service>"}` to the IPFire host and set it to `0`. | ||
|
||
For example to disable the OpenVPN service trigger add `{$IPFIRE.SERVICE.TRIGGER:"openvpn"}` to the host. Check the discovered IPFire service item-keys for the correct service-name of each service. | ||
|
||
Or you could opt to use the variables `{$IPFIRE.SERVICENAME.MATCHES}` and/or `{$IPFIRE.SERVICENAME.NOT_MATCHES}` to filter out services | ||
you don't want to be monitored at all. | ||
|
||
## Credits | ||
|
||
[Alexander Koch](https://community.ipfire.org/t/looking-for-the-zabbix-agent-template/1459/2) for the app Pakfire template. | ||
|
||
[IPFire Team](https://www.ipfire.org) for the IPFire distro and for accepting my contributions to allow easier/better monitoring using Zabbix Agent. | ||
|
||
## Feedback | ||
|
||
Please report any issues with the template at https://github.com/RobinR1/zbx-template-ipfire/issues |
232 changes: 232 additions & 0 deletions
232
Network_Appliances/template_ipfire/6.0/files/scripts/ipfire_services.pl
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,232 @@ | ||
#!/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: 2.0 | ||
# | ||
# Based on: services.cgi by IPFire Team | ||
# Copyright (C) 2007-2021 IPFire Team <[email protected]> | ||
# | ||
# 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 pakfire "library" | ||
require "/opt/pakfire/lib/functions.pl"; | ||
|
||
# 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 %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($service); | ||
print "\"onboot\":$onboot,"; | ||
|
||
print &addonservicestats($service); | ||
|
||
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]; | ||
|
||
# Init directory. | ||
my $initdir = "/etc/rc.d/rc3.d/"; | ||
|
||
return &find_init("$cmd", "$initdir") ? 1 : 0; | ||
} | ||
|
||
sub find_init { | ||
my ($cmd, $dir) = @_; | ||
|
||
# Open given init directory. | ||
opendir (INITDIR, "$dir") || die "Cannot opendir $dir: $!"; | ||
|
||
# Read-in init files from directory. | ||
my @inits = readdir(INITDIR); | ||
|
||
# Close directory handle. | ||
closedir(INITDIR); | ||
|
||
# Loop through the directory. | ||
foreach my $init (@inits) { | ||
# Check if the current processed file belongs to the given command. | ||
if ($init =~ /S\d+\d+$cmd\z/) { | ||
# Found, return "1" - True. | ||
return "1"; | ||
} | ||
} | ||
|
||
# Nothing found, return nothing. | ||
return; | ||
} | ||
|
||
sub addonservicestats { | ||
my $cmd = $_[0]; | ||
my $status = "0"; | ||
my $pid = ''; | ||
my $testcmd = ''; | ||
my $exename; | ||
my @memory = (0); | ||
|
||
$testcmd = `/usr/local/bin/addonctrl $cmd 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; | ||
} |
15 changes: 15 additions & 0 deletions
15
Network_Appliances/template_ipfire/6.0/files/sudoers.d/zabbix_agentd_user
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
# Include file for sudoers file | ||
# | ||
# This is needed for some userparameters to be able to execute commands that only run as root (using sudo) | ||
# e.g. /usr/bin/openssl or /usr/sbin/smartctl | ||
# | ||
# USE AT YOU'RE OWN RISK. USING THIS WRONG CAN RESULT IN A SECURITY BREACH! | ||
# | ||
# Some hints: | ||
# - It is strongly recommended to edit this file only using the visudo -f <filename> command. If you mess up this file, | ||
# you might end up locking yourself out of your system! | ||
# - Append the full path incl. parameters to each command, using "," as separator. | ||
# - Only add commands you really need. Zabbix should not have more rights than it has to. | ||
# | ||
|
||
zabbix ALL=(ALL) NOPASSWD: /etc/zabbix_agentd/scripts/ipfire_services.pl |
2 changes: 2 additions & 0 deletions
2
Network_Appliances/template_ipfire/6.0/files/zabbix_agentd.d/template_ipfire_services.conf
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
### Parameter for monitoring IPFire services | ||
UserParameter=ipfire.services,sudo /etc/zabbix_agentd/scripts/ipfire_services.pl |
Oops, something went wrong.