Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
RobinR1 committed Oct 20, 2020
0 parents commit 948b15e
Show file tree
Hide file tree
Showing 9 changed files with 1,530 additions and 0 deletions.
339 changes: 339 additions & 0 deletions LICENSE

Large diffs are not rendered by default.

51 changes: 51 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
# Template App IPFire by Zabbix Agent Active

## Overview

For Zabbix version: 5.0
This template-set monitors an IPFire appliance/instance and supports monitoring of:
- IPFire general stats (Available entropy, state of RNG)
- IPFire services (default IPFire services and possible Addon services)
- Pakfire status (Installed version, Available update(s))
- Network stats (Line quality, Open Connections, Firewall hits)
Use in conjunction with a default Template OS Linux-template for CPU/Memory/Storage monitoring of the IPFire appliance/instance.
Also an extra Zabbix agent userparameter is included to support `vfs.dev.discovery` on Zabbix agent <4.4 as IPFire currently ships with Zabbix agent v4.2. Install this userparameter to enable the Template Module Linux block devices-template included with Zabbix Server 4.4+ to monitor block device performance.

This template was tested on:

- IPFire 2.25 - Core update 150, but should work on earlier versions

## Setup

- Install IPFire addon `zabbix_agentd` using Pakfire
- Remove `userparameter_pakfire.conf` from the folder with Zabbix agent configuration, if it exists.
- Copy
- `template_app_pakfire.conf`
- `template_module_ipfire_network_stats.conf`
- `template_module_ipfire_services.conf`
- optional: `template_module_linux_block_devices.conf` - if Zabbix agent version is <4.4 but you use Template OS Linux from Zabbix Server 4.4+.
into the folder with Zabbix agent configuration (`/etc/zabbix_agentd/zabbix_agentd.d/` by default on IPFire)
- Copy `ipfire_services.pl` into the folder with Zabbix agent scripts (`/etc/zabbix_agentd/zabbix_agentd.d` by default on IPFire) and make it executable for user `zabbix`.
- Copy `zabbix` into the folder with sudoers configuration (`/etc/sudoers.d`) to allow Zabbix agent to run pakfire status, addonctrl and iptables as root user.
- Restart Zabbix agent.

## Zabbix configuration

No specific Zabbix configuration is required

### Macros used
|Name|Description|Default|
|----|-----------|-------|
|{$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` |

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.

## 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 services.cgi script which is used as a base for the ipfire_services.pl script included here.

## Feedback

Please report any issues with the template at https://github.com/RobinR1/zbx-template-ipfire/issues
197 changes: 197 additions & 0 deletions scripts/ipfire_services.pl
Original file line number Diff line number Diff line change
@@ -0,0 +1,197 @@
#!/usr/bin/perl

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 fromt 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;

$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;
}

17 changes: 17 additions & 0 deletions sudoers.d/zabbix
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# 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.
#
# Append / edit the following list of commands to fit your needs:
#
Defaults:zabbix !requiretty
zabbix ALL=(ALL) NOPASSWD: /opt/pakfire/pakfire status, /usr/local/bin/addonctrl, /sbin/iptables
Loading

0 comments on commit 948b15e

Please sign in to comment.