Coming from nearly 5 years of relying on Nagios, I recently deployed LibreNMS on FreeBSD. It was a bit painful to get setup but it did what I needed it to do. I felt that it filled the void in my monitoring toolset. I set it to auto-update via it's daily.sh
cron job. After LibreNMS updated their code to include Laravel, it broke. I'm sure if I kept digging into logs, I could have revived it, but instead of reaching out to the developers and possibly receiving a, "we don't support FreeBSD," I decided to give Zabbix a try. I heard about it on the TechSNAP podcast and those guys couldn't say enough great things about it. Now that my SNMP monitoring was down, it seemed like a good time to give it a go.
A quick Google search immediately brought up a long list of deployment guides but honestly, the install was so smooth, I nearly didn't need any of them.
One common issue I run into is deploying in jails. When I do see FreeBSD-friendly write-ups, it's hit-or-miss if jail specific instructions are included. Fortunately, there were a few tips out there on just this install...
Here's an aggregate list of steps from various guides that helped deploy Zabbix in a FreeBSD jail.
Using pkg
, install the following packages:
pkg install zabbix34-server zabbix34-agent zabbix34-frontend nginx
Enable the server and agent in rc.conf.local
:
sysrc zabbix_server=YES
sysrc zabbix_agent=YES
sysrc nginx_enable=YES
Since this is in a jail with no loopback, modify the agent config to reflect the jail's IP. First, copy the sample:
cd /usr/local/etc/zabbix34/
cp zabbix_agentd.conf.sample zabbix_agentd.conf
Next, modify the config file:
############ GENERAL PARAMETERS #################
LogFile=/tmp/zabbix_agentd.log
SourceIP=192.168.1.11
Server=192.168.1.13
ListenIP=192.168.1.11
Hostname=server.example.net
Include=/usr/local/etc/zabbix34/zabbix_agentd.conf.d/*.conf
We include the last Include
statement to load the userparam_zfs.conf
file:
UserParameter=vfs.zpool.discovery,/usr/local/etc/zabbix34/scripts/zpool-discovery.sh
UserParameter=vfs.zfs.discovery,/usr/local/etc/zabbix34/scripts/zfs-discovery.sh
UserParameter=vfs.zfs.get[*],/sbin/zfs get -Hp -o value $2 $1 | sed -e 's/[x%]//'
UserParameter=vfs.zpool.get[*],/sbin/zpool get -Hp -o value $2 $1 | sed -e 's/[x%]//'
Next, create a scripts
directory for the two ZFS scripts:
mkdir /usr/local/etc/zabbix34/scripts
Place the following into zfs-discovery.sh
in the scripts directory:
#!/bin/sh
first=1
echo "{\"data\":["
for dataset in `/sbin/zfs list -H -o name` ; do
if [ $first -ne 1 ]; then
echo ","
fi
first=0
echo -n "{\"{#ZFS}\":\"${dataset}\"}"
done
echo
echo "]}"
Place the following into zpool-discovery.sh
in the scripts directory:
#!/bin/sh
first=1
echo "{\"data\":["
for pool in `/sbin/zpool list -H -o name` ; do
if [ $first -ne 1 ]; then
echo ","
fi
first=0
echo -n "{\"{#ZPOOL}\":\"${pool}\"}"
done
echo
echo "]}"
Ensure both files are owned by zabbix
user and executable:
chown -R zabbix /usr/local/etc/zabbix34/scripts
chmod +x /usr/local/etc/zabbix34/scripts/*
At this point you can start the agent:
service zabbix_agentd start
Next, make a copy of the sample config file:
cd /usr/local/etc/zabbix34/
cp zabbix_server.conf.sample zabbix_server.conf
Edit the zabbix_server.conf
file and make any necessary modifications. In this example, we will bind the service to the Jail's IP and increase the number of pollers:
SourceIP=192.168.1.13
LogType=file
LogFile=/tmp/zabbix_server.log
DBHost=db.example.net
DBName=zabbix
DBUser=zabbix
DBPassword=zabbixpw
StartPollers=50
StartPreprocessors=6
StartDiscoverers=10
Timeout=4
ExternalScripts=/usr/local/etc/zabbix34/externalscripts
LogSlowQueries=3000
At this point, the jail is setup as a Zabbix server, however, the jail will refuse to start the Zabbix service:
Can not create Semaphore [Function not implemented]
To solve this, modify sysctl
:
sysctl security.jail.sysvipc_allowed=1
and to make it survive a reboot, add the following to your /etc/sysctl.conf
:
security.jail.allow_raw_sockets=1
security.jail.sysvipc_allowed=1
Next, modify your jail's config file. In this example, we'll use an ezjail
config file:
export jail_zabbix_parameters="allow.raw_sockets=1 sysvshm=new sysvsem=new"
Lastly, modify your nginx
config for the Zabbix frontend:
user www;
worker_processes 1;
events {
worker_connections 1024;
}
http {
upstream php {
server unix:/var/run/php-fpm.socket;
}
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
server {
listen 80;
server_name localhost;
location / {
root /usr/local/www/zabbix34;
index index.php index.html index.htm;
}
location ~ \.php$ {
root /usr/local/www/zabbix34;
include fastcgi_params;
fastcgi_pass php;
fastcgi_index index.php;
fastcgi_param PHP_AUTH_USER $http_remote_user;
fastcgi_param SCRIPT_FILENAME /usr/local/www/zabbix34$fastcgi_script_name;
}
location ~ /\.ht {
deny all;
}
}
}
Restart your jail to allow the modified jail config to take affect, and you're ready to start monitoring!
Oh, ok, so you might have caught the $http_remote_user
in my nginx config file. That's because this nginx server sits behind a TLS proxy that passes my user certificate back to Zabbix. All the authentication happens on the first nginx proxy. If successful, it passes the request back to the Zabbix nginx instance and binds my username ($http_remote_user
) to PHP_AUTH_USER
. Then, in Zabbix, you can enable HTTP authentication. Make sure you have a username that matches your certificate!