Collecting Data From pfSense Using collectd

By · Published · pfsense, networking, php

So I've recently been on a graphing thing, wanting to collect all kind of data from my home network. And collectd seems to be a good candidate for doing that. With a huge number of plugins, it can collect and send just about anything you can think of to a time series database (I'm using InfluxDB for this).

But, there's a significant hole in my data collection: my pfSense firewall. Well, not anymore!

Unfortunately, with pfSense 2.3 moving to their own package library built on top of FreeBSD's pkg system, simply installing pfSense by typing pgk install collectd5 as worked in 2.2 won't work anymore. But you can still install things from the FreeBSD repositories directly.

To start, find the most recent collectd5 release here that is available in FreeBSD. Keep in mind that pfSense 2.3 is based of FreeBSD 10, so if you get an error about wrong architecture, be sure you're selecting the correct CPU architecture and FreeBSD version.

$ pkg add http://pkg.freebsd.org/freebsd:10:x86:64/latest/All/collectd5-5.5.2.txz

This should directly install collectd. Pretty neat. Setup proceeds as normal from there. Notably, though, in order to have collectd restart when your firewall restarts, be sure you edit /etc/rc.conf and add the following line:

collectd_enable=YES

Once it's installed, you can start it by using:

$ /usr/local/etc/rc.d/collectd start

Collecting CPU Temperature

collectd is primarily written to work on Linux systems. And pfSense itself is derived from FreeBSD, so some things don't work right. One of the the things I really wanted to closely monitor was the CPU temperature. My pfSense router is in an upstairs closet, so I want to be sure the temperature doesn't get too high.

Unfortunately, I was not able to get any of the native temperature sensing stuff in collectd working. But, you have another option. collectd helpfully includes an exec plugin that lets you execute a script to collect any data you can think of. And, you can find temperature data from sysctl. Knowing this, you could write a little script like this:

#!/usr/local/bin/php -q
<?php

$hostname = getenv("COLLECTD_HOSTNAME");
$interval = getenv("COLLECTD_INTERVAL");

$keys = ["dev.cpu.1.temperature", "dev.cpu.0.temperature"];

foreach ($keys as $key) {
    $temp = exec("sysctl $key");
    if (preg_match('!([0-9\.]+)C$!i', $temp, $matches)) {
        $temp = $matches[1];
        echo "PUTVAL \"$hostname/cpu_temp/gauge-$key\" interval=$interval N:$temp\n";
    }
}

fclose(STDOUT);

Then add your script to the /usr/local/etc/collectd.conf file:

LoadPlugin exec
<Plugin exec>
        Exec "non-privileged-username" "/path/to/your/script.php"
</Plugin>

You should now have temperature data flowing into collectd.

Collecting DHCP Leases

Similar to above, you can collect the total number of DHCP leases in use using another script:

#!/usr/local/bin/php -q
<?php

$hostname = getenv("COLLECTD_HOSTNAME");
$interval = getenv("COLLECTD_INTERVAL");
$content = file_get_contents("/var/dhcpd/var/db/dhcpd.leases");

$leases = [];
$lease_count = 0;

if (preg_match_all("/lease (?<ip>[\d\.]+) \{\s+starts \d (?<starts>[\d\/]+\s[\d\:]+);\s+ends \d (?<ends>[\d\/]+\s[\d\:]+);/is", $content, $matches)) {
    foreach($matches["ip"] as $key => $ip) {
        $end_date = strtotime($matches["ends"][$key]);
        if ($end_date > time()) {
            $leases[$ip] = [$ip, $matches["starts"][$key], $matches["ends"][$key]];
        }
    }

    $lease_count = count($leases);
}

echo "PUTVAL \"$hostname/dhcp/gauge-dhcp_leases\" interval=$interval N:$lease_count\n";
fclose(STDOUT);

And add it to collectd.conf:

LoadPlugin exec
<Plugin exec>
        Exec "non-privileged-username" "/path/to/your/temperature.php"
        Exec "non-privileged-username" "/path/to/your/dhcp.php"
</Plugin>

Collecting OpenVPN Users

The native OpenVPN plugin included with collectd works with pfSense, but you'll need to add a small line to your OpenVPN config. In the pfSense web GUI, go to VPN -> OpenVPN. Select your OpenVPN server and click Edit (the little pencil). Scroll down to Custom Options at the bottom and add the following line:

status /var/log/openvpn-status.log;

Restart OpenVPN. Now, go to your /usr/local/etc/collectd.conf file and add the following lines

LoadPlugin openvpn
<Plugin openvpn>
        StatusFile "/var/log/openvpn-status.log"
        ImprovedNamingSchema false
        CollectCompression true
        CollectIndividualUsers true
        CollectUserCount true
</Plugin>

And now you have OpenVPN user data going into collectd as well.

So that should give you a high-level overview of how to get collectd up and running and collecting data from pfSense. I'm feeding mine into InfluxDB, which I use Grafana on top of to create dashboards.

Now go forth and track all the things! :)

( Comments )

Did something I wrote help you out?

That's great! I don't earn any money from this site - I run no ads, sell no products and participate in no affiliate programs. I do this solely because it's fun; I enjoy writing and sharing what I learn.

All the same, if you found this article helpful and want to show your appreciation, here's my Amazon.com wishlist.


Related Posts

Scheduled Throttling with pfSense

Installing the Ubiquiti UniFi Controller Software on pfSense 2.2


comments powered by Disqus