FreeBSD, Munin, and lighttpd
I have a NAS at home (lovingly called nasty.home
) that runs FreeBSD 10.1-RC3, with Munin and lighttpd installed via ports. It took me some time to figure out how to get this combination to work the way I wanted, mostly due to inexperience with Munin and lighttpd. I wanted to document what I had done in the hopes that other people would find the information useful.
Configuring munin-node
The documentation for installing and setting up munin-node
is the first place I looked. I installed the default set of plugins with munin-node-configure --shell | sh -x
. Over the past few months, I have removed a few and added some others, including some of the ZFS plugins from the munin-contrib repository. I ended up using these plugins:
$ ls /usr/local/etc/munin/plugins
cpu netstat smart_ada5
df open_files swap
if_em0 processes systat
iostat smart_ada0 uptime
load smart_ada1 users
memory smart_ada2 zfs_stats_efficiency
munin_stats smart_ada3 zfs_stats_utilization
munin_update smart_ada4 zfs_usage_Z
The default configuration mostly works, with one exception. When I started using the smart_
plugin, it could not find the smartctl
command because the default config uses the wrong environment variable (env .smartctl
instead of env.smartpath
). The default config also does not give smartctl
enough permissions to access the devices, so my configuration looks like this:
$ cat /usr/local/etc/munin/plugin-conf.d/smart.conf
[smart_*]
user root
env.smartpath /usr/local/sbin/smartctl
Now it’s just a matter of making sure that the munin-node
service is running:
$ sudo sysrc munin_node_enable=YES
$ sudo service munin-node start
Configuring munin-master
As with munin-node
, the default configuration for munin-master
mostly works. I wanted to make Munin generate the HTML and graphs on demand with the munin-cgi-html
and munin-cgi-graph
CGI scripts, instead of letting the cron job do it. I had hoped it was be as simple to just change the graph_strategy
and html_strategy
:
$ cat /usr/local/etc/munin/munin-conf.d/cgi.conf
graph_strategy cgi
html_strategy cgi
… which it was, with one caveat (see below).
Configuring lighttpd
Munin puts its CGI and generated HTML in /usr/local/www/cgi-bin
and /usr/local/www/munin
, respectively. Note, however, that my /usr/local/www/munin
directory is empty (see above). The default configuration of lighttpd uses /usr/local/www/data
as the document-root. This directory is also empty. It’s up to me to put something useful there. I haven’t done this (yet!), so I get a 404 error for anything I try to browse on my NAS.
I wanted to access the Munin graphs using nasty.home/munin/
. I had found an example configuration that I used as a starting point, and the result turned out to be not too bad:
$ cat /usr/local/etc/lighttpd/conf.d/munin.conf
server.modules += ( "mod_alias", "mod_rewrite" )
include "conf.d/cgi.conf"
alias.url += ( "/munin/static" => "/usr/local/etc/munin/static" )
alias.url += ( "/munin-cgi" => "/usr/local/www/cgi-bin" )
$HTTP["url"] =~ "^/munin-cgi" {
cgi.assign = ( "" => "" )
}
url.rewrite-repeat += (
"^/munin/((?!static/).*\.png)$" => "/munin-cgi/munin-cgi-graph/$1",
"^/munin/((?!static/).*\.html)*$" => "/munin-cgi/munin-cgi-html/$1"
)
As you can see, I’m using plain, old CGI, since this “Just Works (tm)” with the default lighttpd install. The aliases tell lighttpd where to find static content and the CGI scripts, the rewrite rules which CGI script to call for a given URL. I had to make sure that the *.html rule matched both /munin/
and /munin/*.html
to ensure that the index was correctly generated for nasty.home/munin/
.
The final step was to tell lighttpd to load my conf file, which meant modifying the default configuration slightly:
$ diff -u /usr/local/etc/lighttpd/lighttpd.conf.sample /usr/local/etc/lighttpd/lighttpd.conf
--- lighttpd.conf.sample 2014-09-14 23:58:54.262130000 +0200
+++ lighttpd.conf 2014-10-27 21:42:10.252855767 +0100
@@ -457,3 +457,7 @@
# IPv4 listening socket
$SERVER["socket"] == "0.0.0.0:80" { }
+
+# local modifications
+server.breakagelog = "/var/log/lighttpd/breakage.log"
+include "conf.d/munin.conf"
Time to enable lighttpd and start it to give nasty.home/munin/
a try in my browser:
$ sudo sysrc lighttpd_enable=YES
$ sudo service lighttpd start
Does it work?
No. It should, but it doesn’t. Here’s the caveat I mentioned above: the Munin CGI scripts are run as the www
user, but want to log to the /var/log/munin/
directory, which is owned by the munin
user. I didn’t think about this at first. I was only after I examined the lighttpd breakage.log
that I figured it out:
$ sudo grep Permission\ denied /var/log/lighttpd/breakage.log | head -n 1
... munin-cgi-graph: Can't open /var/log/munin/munin-cgi-graph.log (Permission denied) at ...
Thankfully, newsyslog(8)
on FreeBSD is easy to configure to both create the log files with correct permissions and rotate them like all other system logs:
$ cat /usr/local/etc/newsyslog.conf.d/munin-cgi.conf
/var/log/munin/munin-cgi-graph.log www:www 644 7 * @T00 CNX
/var/log/munin/munin-cgi-html.log www:www 644 7 * @T00 CNX
The newsyslog rules are applied once an hour via cron(8)
, but it’s easy to apply them right away if you’re impatient (like I am):
$ sudo newsyslog
Surely it must work now?
Yes. Yes, it does. I still haven’t put anything useful in /usr/local/www/data
, so browsing to nasty.home/
returns a 404, but nasty.home/munin/
works, as well as all the URLs under it.
Rationale
If someone were to ask me why I put everything together the way I did, I’m not sure I could give a reasonable answer. I’m not sure why. I could have certainly used the cron
strategies when configuring munin-master
, and found a way to link/copy/move/change the output from /usr/local/www/munin
to /usr/local/www/data/munin
. There are certainly other ways to get the same result that I wanted. The configuration feels minimal, and I could easily replicate this on other machines if I wanted, both privately or for work.
In the end, the result works. And that’s what really matters.