Nagios Core on Gentoo/Raspberry Pi with Nginx

I haven't posted in a while due to a change in my work. I'm currently working in
the Server and Storage team at my workplace for a 6 month secondment. The role
is much more aligned with my enjoyment of using GNU/Linux.

---

**Note** These notes are incomplete, but I'm posting them anyway.

One of the responsibilities I've picked up is maintaining our Nagios monitoring
system. While I won't go into too much detail about that here, I thought I'd
install it at home to monitor things and get a bit more experience on it.

Thankfully [ebuilds exist](https://packages.gentoo.org/net-analyzer/nagios-core)
in Gentoo which means I don't have to compile it myself. Unfortunately,
the integrations with web servers doesn't cover nginx.

Nagios-Core will be installed on a Raspberry Pi running NGinx. If your already
running Apache, or lighttp, then your in luck, as the ebuilds for Nagios-Core
support those out of the box. The setup for the rest of that won't be covered
here.

**Assumptions** This guide will assume you are already serving content from
nginx and it won't cover initial setup and install.

Nginx
-----

The default USE flags and modules built for nginx should cover what is required
for nagios, but just to be sure, these will be needed:

        fastcgi scgi

PHP
---

Modern versions of Nagios, use a bit of PHP, so we are going to need php
compiled with the following USE flags

        fpm

FPM is a method of invoking php through a unix socket so as not to have to spawn
new child processes every time someone hits a .php file.

Glue packages
-------------

We need a spawner and fastcgi wrapper to launch cgi scripts for the nagios site.

        emerge www-misc/fcgiwrap www-servers/spawn-fcgi

Both these applications were hard masked on arm64, but they are running fine for
me.

Nagios Core
-----------

I didn't use any special use flags for nagis core.

Setting it all up
-----------------

Getting info
============

To get this working you need a few bits of info

Where is nagios cgi scripts installed to? 
    
        equery files net-analyzer/nagios-core | grep cgi | head -1
        /usr/lib64/nagios/cgi-bin/

Where are the html files?

        equery files net-analuyer/nagios-core | grep htdocs | head -1
        /usr/share/nagios/htdocs

fpm config
==========

When php was compiled with the `fpm` USE flag we should have an php fpm service
file and configuration files. We could make fpm listen on a service or to a unix
socket. On my system, everything will be hosted together so using a unix socket
will be the most ideal.

Edit the config at `/etc/php/fpm-php7.3/fpm.d` and set the `listen` value like
so:

        listen = /var/run/php7-fpm.socket

This is the socket file that we will configure nginx to connect to later so that
it can run php stuff.

Next skip through the file a bit to find the `listen.owner` and `listen.group`
settings. Set them both to **nginx**

Save and close that config file and go edit `/etc/php/fpm-php7.3/php.ini`
Find and uncomment out `;cgi.fix_pathinfo=1` and change it to equal **0**.

I'm using systemd, so I ran `systemctl enable php-fpm@7.3 --now` to start and
enable the service at boot. Take a peek in /var/run/

        ls -l /var/run/php7-fpm.socket
        srw-rw---- 1 nginx nginx 0 Jan 27 10:08 /var/run/php7-fpm.socket  

Notice it is owned by nginx.

Fastcgi
=======

Fastcgi will be responible for serving cgi bin files for nagios. These are
nagios programs written in C. To do so, Nginx talks to a spawner which spawns
fcgiwrap which in turn runs the programs.

spawn-fcgi doesn't really have a configuration file from what I can tell. When
merged onto my system, it's configuration is handled by the init.d service
script reading variables from /etc/conf.d/spawn-fcgi and setting command line
options.

To simplify things, I just created a simple systemd service unit and hard coded
the options I needed into it. Here is the service file I came up with:

        [Unit]
        Description=Simple spawn-fcgi service

        [Service]
        Type=simple
        ExecStart=/usr/bin/spawn-fcgi -n -U 999 -G 235 -s /var/run/fcgiwrap.socket /usr/sbin/fcgiwrap

        [Install]
        WantedBy=multi-user.target

Explanation of parameters:

* `-n` don't fork
* `-U 999` set socket user permissions to UID 999 which is Nginx
* `-G 235` set socket group permissions to GID 235 which is Nginx
* `-s /var/run/fcgiwrap.socket` create a unix socket at this path
* `/usr/sbin/fcgiwrap` spawn this fcgi binary

Start and enable this service with `systemctl enable spawn-fcgi --now` should
produce a socket file similar to the php7 one created earlier. This will be used
in our nginx config later.

Nginx Config
============

My nginx config is all in one file, so adjust my changes as per your needs.
The first change we need to make is inside the `http` declaration. We need to
specify the two upstream servers (in this case servers on the local system via
sockets). One for php and one for cgi-bin.

Each one will reference the sockets we created earlier.

        upstream php {
            server unix:/var/run/php7-fpm.socket;
        }

        upstream fcgiwrap {
            server unix:/var/run/fcgiwrap.socket;
        }

The default nginx config will have a server declaration for your site. Nested
in here you will need the following location declarations. The location
declaration `/nagios` and will result in being able to access nagios by
navigating to the website url like so: randomsite.com/nagios

		location ~ /nagios/ {
			alias /usr/share/nagios/htdocs;
			auth_basic "Nagios Restricted Access";
			auth_basic_user_file /etc/nagios/htpasswd.users;

_note here the path to htdocs was discovered earlier_

			index index.php index.html;
			location ^~ /nagios/cgi-bin {
					alias /usr/lib64/nagios/cgi-bin;
					include /etc/nginx/fastcgi_params;
					fastcgi_param AUTH_USER $remote_user;
					fastcgi_param REMOTE_USER $remote_user;
					fastcgi_param SCRIPT_FILENAME $request_filename;
					fastcgi_pass unix:/var/run/fcgiwrap.socket;
					fastcgi_param PATH_INFO $fastcgi_script_name;
			}
			location ~ .php$ {
					proxy_set_header REMOTE_USER $remote_user;
					include fastcgi_params;
					fastcgi_param AUTH_USER $remote_user;
					fastcgi_param REMOTE_USER $remote_user;
					fastcgi_param SCRIPT_FILENAME $request_filename;
					fastcgi_param SCRIPT_NAME $fastcgi_script_name;
					fastcgi_pass unix:/var/run/php7-fpm.socket;
					fastcgi_param PATH_INFO $fastcgi_script_name;
			}
		}

		location /nagios/stylesheets {
				alias /usr/share/nagios/htdocs/stylesheets;
		}

What's happening here:

* location ~ /nagios/ causes the uri to match `/nagios/` as a case sensitive
  regular expression. Without the `~`, an article like this with it's name
  starting with nagios might also fall into that location
* location ^~ is a non regular expression match of the uri
* fastcgi_param directives are passing parameters from the browser to the cgi
  script.
* fastcgi_pass passes the request to the socket setup as an upstream server.

Read more about locations on [digitalocean][1]

Tags: gentoo, linux, nagios

[1]: https://www.digitalocean.com/community/tutorials/understanding-nginx-server-and-location-block-selection-algorithms
