Introduction

Munin is a great monitoring tool, which gathers performance data from the plugins running on the nodes and presents them in graphs with web interface. Munin’s graphs and web pages are generated either statically by cron jobs or dynamically upon request via Munin CGI tools. For more information about the tool, its design, modules, configuration options and other useful stuff, visit the official Munin website: http://munin-monitoring.org/

Why using Munin CGI

Default setup on many distributions is that cron regularly starts group of Munin jobs. One of these regular jobs generates Munin’s web pages ( munin-html ) and another generates graphs ( munin-graph ). This approach is quite OK in a case when amount of monitored nodes is small. But with increasing number of nodes to monitor and plugins which provide the data, generation of all graphs and web pages is producing a lot of unnecessary load.

That’s when the time comes to think about using on-demand dynamic content instead of the static generation. With Munin CGI, only web pages and graphs which are actually needed – requested by user’s browser – are dynamically generated. CGI features are available for Munin since version 2.0. This article describes configuration of the Munin CGI with Apache web server running on Fedora 26. With some minor modifications, it should be of course compatible with other distributions as well.

Existing munin-cgi package

Well, there is already a munin-cgi package available on Fedora ( since Fedora 16 ). But this package currently does not provide simple “install and done” solution, which would transparently replace existing Munin with CGI enabled setup. Reason for this is maybe the fact, that new Munin Guide and also previous official Munin documentation have an example of CGI implementation for Apache configuration using a VirtualHost configuration.

The munin-cgi package mainly provides:

  • spawn-fcgi services: These services ( munin-fcgi-graph and munin-fcgi-html ) can be used as CGI workers for Apache, but usage of these would require reverse proxy setup and it would just add more complexity to the whole configuration. Furthermore fcgi services are configured according to Munin older documentation and do not have compatible user:group values.
  • munin-cgi.conf for Apache: Already mentioned Apache configuration for Munin CGI via separate VirtualHost.
  • cgi-tmp directory: Directory is correctly located, but it differs from cgitmppath set in configuration provided by munin package. Also SELinux context is not set correctly on this directory.

Transparent Munin CGI

Following configuration updates the default Munin configuration with Munin CGI via Apache and tries to do so with transparent replacement of the default Munin path and without influencing any other configuration.

Munin configuration

Munin configuration files from conf.d directory are by default ( actually because of includedir directive in munin.conf ) loaded after the main Munin configuration file in a sorted order and they can override configuration of directives in munin.conf. Following configuration file changes strategy for graphs and web pages, so they are generated by CGI and skipped by cron jobs. Also cgitmpdir is updated to the path of directory provided by munin-cgi package. This is the directory where temporary data will be stored by Munin CGI tools.

/etc/munin/conf.d/01-cgi.conf
graph_strategy cgi
html_strategy cgi
cgitmpdir /var/lib/munin/cgi-tmp

SELinux file system context

Because the SELinux policy does not map compatible file context type on CGI temporary directory, we will add a new file context mapping definition for it. This will allow for Munin CGI scripts to write to the directory when invoked via Apache and also Apache to read the data ( actual pages and graphs ) and provide it to the client.

sudo semanage fcontext -a -t munin_script_tmp_t '/var/lib/munin/cgi-tmp(/.*)?'
sudo restorecon -r /var/lib/munin/cgi-tmp

Apache configuration

Apache configuration file /etc/httpd/conf.d/munin-cgi.conf provided by munin-cgi package adds a new VirtualHost to Apache’s configuration. In a case there is no other VirtualHost set before munin-cgi.conf is loaded, this VirtualHost will become server’s default VirtualHost. Setup of Apache VirtualHosts is out of scope of this article, but point here is that either you setup your default VirtualHost before munin-cgi.conf, so this configuration will not affect your Apache setup that much. Or you can comment-out the whole default munin-cgi.conf content. You can create a new configuration file named as you like ( which I prefer ) or you may just add the following configuration to the end of existing munin-cgi.conf, right behind the last line ( </VirtualHost> ).

Following setup is done by the configuration:

  • ScriptAliases are defined, so requests to specific paths will end up being sent to Munin CGI tools
  • /munin-cgi/ path is allowed to execute CGI, handler is assigned to this path ( either FastCGI if available, otherwise CGI ) and authentication is set up in the same way as to standard /munin/ path
  • mod_rewrite is then used on /munin/ path requests to direct them to CGI enabled URLs
/etc/httpd/conf.d/munin-cgi-custom.conf
#
# ScriptAliases and FastCGI/CGI handlers
#
ScriptAlias /munin-cgi/munin-cgi-html /var/www/cgi-bin/munin-cgi-html
ScriptAlias /munin-cgi/munin-cgi-graph /var/www/cgi-bin/munin-cgi-graph

<Location "/munin-cgi/">
  Options ExecCGI
  <IfModule mod_fcgid.c>
    SetHandler fcgid-script
  </IfModule>
  <IfModule !mod_fcgid.c>
    SetHandler cgi-script
  </IfModule>

  AuthUserFile /etc/munin/munin-htpasswd
  AuthName "Munin"
  AuthType Basic
  require valid-user
</Location>

<Directory "/var/www/html/munin">
  RewriteEngine On
  RewriteBase "/munin/"
  RewriteCond %{REQUEST_URI} =/munin/ [or]
  RewriteCond %{REQUEST_URI} \.html$
  RewriteCond %{REQUEST_URI} !/static/[^/]+\.html$
  RewriteRule ^(.*)$ /munin-cgi/munin-cgi-html/$1 [PT,L]
  RewriteCond %{REQUEST_URI} /static/[^/]+$
  RewriteRule ^.*/static/([^/]+)$ /munin/static/$1 [PT,L]
</Directory>

Now httpd.service needs to be reloaded ( or rather restarted if changes were done to VirtualHost configuration in some way ) and Munin CGI should be in place. Just open your usual Munin path.

Additional notes

It should be possible to implement Munin CGI without need to have a munin-cgi package installed. The only missing requirement is directory that will be used as cgitmpdir, also with subdirectory munin-cgi-graph. As CGI runs under Apache, apache user needs to have a write access there ( using SELinux as noted in SELinux file system context and also by file system permissions for apache:apache ). I didn’t tested this approach, but it could work like this:

sudo mkdir -p /var/lib/munin/cgi-tmp/munin-cgi-graph
sudo chown apache:apache -R /var/lib/munin/cgi-tmp
sudo chmod o-rwx -R /var/lib/munin/cgi-tmp/munin-cgi-grap

If you would consider to use spawn-fcgi services instead of Apache CGI handlers, make sure they run under the web user ( apache ) and not under munin ( which is default from munin-cgi package ) and that permissions to all necessary directories are available for spawned threads. Also Apache configuration mentioned here is not be compatible with spawn-fcgi services and reverse proxy needs to be configured to pass the requests to fcgi services.

It is possible to have only web pages or only graphs generated by CGI and use cron job for the other one, but replacement of both ( pages and graphs ) by CGI brings the most of its benefits.

If you want to limit ( or improve ) performance of the Munin CGI, good starting point can be a documentation of the CGI implementation used. Usually it is a FastCGI and FcgidMaxProcesses can be a first parameter to look at.