Nagios Core is an open source monitoring engine that runs checks against hosts and services and alerts you when something changes state. Everything it monitors is declared in plain text object files, which makes it predictable and easy to keep under version control. In this tutorial you will compile Nagios Core 4.5 from source on Ubuntu 24.04, serve its web interface with Apache, add the standard monitoring plugins, and monitor a second Linux server through NRPE (Nagios Remote Plugin Executor).

Prerequisites

To follow this tutorial you need:

  • A server running Ubuntu 24.04 LTS for Nagios, for example a CubePath VPS, with at least 1 GB of RAM.
  • A second Linux server running Ubuntu 24.04 that you want to monitor. This guide calls it the remote host and uses remote_host_ip for its address.
  • A non-root user with sudo privileges on both servers.
  • UFW enabled on both servers with SSH allowed.

Throughout the guide, replace your_server_ip with the public IP of the Nagios server.

Step 1 - Installing build dependencies

Nagios Core is not packaged in its current 4.5 release for Ubuntu 24.04, so you will build it from the official source. Install the compiler, Apache, PHP (used by the web interface) and the libraries Nagios links against:

sudo apt update
sudo apt install -y autoconf gcc libc6 make wget unzip apache2 php libapache2-mod-php libgd-dev openssl libssl-dev mailutils

The mailutils package provides the mail command that the default notification commands use. Installing it before compiling lets the configure script detect it.

Step 2 - Downloading and compiling Nagios Core

Download the source archive for the release tag from GitHub. Check the Nagios Core releases page and adjust the version if a newer 4.5.x is available:

cd /tmp
NAGIOS_VER=4.5.9
wget -O nagioscore.tar.gz "https://github.com/NagiosEnterprises/nagioscore/archive/nagios-${NAGIOS_VER}.tar.gz"
tar xzf nagioscore.tar.gz
cd "nagioscore-nagios-${NAGIOS_VER}"

Run the configure script. The --with-httpd-conf option tells the installer where to place the Apache configuration for the web interface:

sudo ./configure --with-httpd-conf=/etc/apache2/sites-enabled

The script ends with a summary. Check that the web server user and the mail program were detected:

*** Configuration summary for nagios 4.5.9 ***:
...
             Web Interface Options:
             ------------------------
                    HTML URL:  http://localhost/nagios/
                     CGI URL:  http://localhost/nagios/cgi-bin/

Compile the binaries:

sudo make all

Create the nagios user and group, and add the Apache user to the nagios group so the web interface can submit commands (acknowledgements, scheduled downtime) to the daemon:

sudo make install-groups-users
sudo usermod -a -G nagios www-data

Install the binaries, the systemd unit, the command pipe, the sample configuration and the Apache configuration:

sudo make install
sudo make install-daemoninit
sudo make install-commandmode
sudo make install-config
sudo make install-webconf

Everything now lives under /usr/local/nagios: binaries in bin/, configuration in etc/, and CGIs in sbin/.

Step 3 - Configuring Apache and the admin account

The Nagios web interface uses CGI scripts and HTTP basic authentication. Enable the Apache modules it needs:

sudo a2enmod rewrite cgi

Create the nagiosadmin account. The sample configuration grants this exact username full access, so keep the name. You will be prompted for a password; choose a strong one:

sudo htpasswd -c /usr/local/nagios/etc/htpasswd.users nagiosadmin

Allow HTTP through the firewall and restart Apache:

sudo ufw allow Apache
sudo systemctl restart apache2

Step 4 - Installing the monitoring plugins

Nagios Core only schedules checks; the checks themselves are separate programs called plugins. Ubuntu packages the maintained plugin collection as monitoring-plugins, and nagios-nrpe-plugin provides check_nrpe, which you will use in Step 7:

sudo apt install -y monitoring-plugins
sudo apt install -y --no-install-recommends nagios-nrpe-plugin

These plugins are installed in /usr/lib/nagios/plugins. Nagios refers to the plugin directory through the $USER1$ macro, which is defined in resource.cfg. Open it:

sudo nano /usr/local/nagios/etc/resource.cfg

Change the $USER1$ line so it points to the packaged plugins:

$USER1$=/usr/lib/nagios/plugins

Run a plugin by hand to confirm it works:

/usr/lib/nagios/plugins/check_disk -w 20% -c 10% -p /
DISK OK - free space: / 21034 MiB (78% inode=91%);| /=5812MiB;22531;25347;0;28164

Step 5 - Starting Nagios and logging in

Before starting the daemon, validate the configuration. Nagios refuses to start with errors, and this command tells you exactly which file and line is wrong:

sudo /usr/local/nagios/bin/nagios -v /usr/local/nagios/etc/nagios.cfg
Total Warnings: 0
Total Errors:   0

Things look okay - No serious problems were detected during the pre-flight check

Enable and start the service:

sudo systemctl enable --now nagios
sudo systemctl status nagios
● nagios.service - Nagios Core 4.5.9
     Loaded: loaded (/usr/lib/systemd/system/nagios.service; enabled; preset: enabled)
     Active: active (running)

Open http://your_server_ip/nagios in your browser and log in as nagiosadmin. Under Current Status > Services you will see the localhost host with the sample checks (root partition, current load, users, SSH, HTTP and more) turning green within a few minutes.

Step 6 - Setting up NRPE on the remote host

Plugins like check_disk or check_load must run on the machine they measure. NRPE is a small daemon that runs these local checks on the remote host when the Nagios server asks for them over TCP port 5666.

Run the following commands on the remote host. Install the NRPE server and the plugins:

sudo apt update
sudo apt install -y nagios-nrpe-server monitoring-plugins

NRPE only answers requests from addresses listed in allowed_hosts. Open its configuration:

sudo nano /etc/nagios/nrpe.cfg

Find the allowed_hosts line and add the IP of the Nagios server:

allowed_hosts=127.0.0.1,::1,your_server_ip

The default file already defines check_users, check_load, check_zombie_procs and check_total_procs. Add your own commands in a separate file so package upgrades do not overwrite them:

sudo nano /etc/nagios/nrpe.d/custom.cfg
command[check_root_disk]=/usr/lib/nagios/plugins/check_disk -w 20% -c 10% -p /
command[check_mem_swap]=/usr/lib/nagios/plugins/check_swap -w 50% -c 20%

Restart NRPE and allow port 5666 only from the Nagios server:

sudo systemctl restart nagios-nrpe-server
sudo ufw allow from your_server_ip to any port 5666 proto tcp

Back on the Nagios server, confirm that it can reach the daemon and run a remote command:

/usr/lib/nagios/plugins/check_nrpe -H remote_host_ip
/usr/lib/nagios/plugins/check_nrpe -H remote_host_ip -c check_root_disk
NRPE v4.1.0
DISK OK - free space: / 36120 MiB (82% inode=95%);| /=7702MiB;35107;39495;0;43884

If you get CHECK_NRPE: Error - Could not connect, see the Troubleshooting section.

Step 7 - Adding the remote host to Nagios

The sample configuration ships a commented cfg_dir directive for per-server files. Open the main configuration on the Nagios server:

sudo nano /usr/local/nagios/etc/nagios.cfg

Uncomment this line:

cfg_dir=/usr/local/nagios/etc/servers

Create the directory:

sudo mkdir -p /usr/local/nagios/etc/servers

Nagios needs a command definition that calls check_nrpe. Open the commands file:

sudo nano /usr/local/nagios/etc/objects/commands.cfg

Add this block at the end:

define command {
    command_name    check_nrpe
    command_line    $USER1$/check_nrpe -H $HOSTADDRESS$ -c $ARG1$
}

Now describe the remote host and its services in their own file:

sudo nano /usr/local/nagios/etc/servers/web01.cfg
define host {
    use                     linux-server
    host_name               web01
    alias                   Web server 01
    address                 remote_host_ip
}

define service {
    use                     generic-service
    host_name               web01
    service_description     SSH
    check_command           check_ssh
}

define service {
    use                     generic-service
    host_name               web01
    service_description     Current Load
    check_command           check_nrpe!check_load
}

define service {
    use                     generic-service
    host_name               web01
    service_description     Root Partition
    check_command           check_nrpe!check_root_disk
}

define service {
    use                     generic-service
    host_name               web01
    service_description     Swap Usage
    check_command           check_nrpe!check_mem_swap
}

The linux-server and generic-service templates come from templates.cfg and set check intervals, retry counts and the admins contact group. check_ssh runs from the Nagios server itself, while the other three services run on the remote host through NRPE.

Validate the configuration and restart Nagios:

sudo /usr/local/nagios/bin/nagios -v /usr/local/nagios/etc/nagios.cfg
sudo systemctl restart nagios

Reload the web interface. The host web01 appears under Hosts, and its four services move from PENDING to OK after the first check cycle. To speed this up, open a service and click Re-schedule the next check of this service.

Step 8 - Configuring email notifications

Notifications go to the contacts in the admins group, which by default contains only nagiosadmin. Set a real address for that contact:

sudo nano /usr/local/nagios/etc/objects/contacts.cfg
define contact {
    contact_name            nagiosadmin
    use                     generic-contact
    alias                   Nagios Admin
    email                   you@your_domain
}

The default notify-host-by-email and notify-service-by-email commands pipe the alert into mail, which hands it to the local mail transfer agent. A working MTA is therefore required. Many cloud platforms restrict outbound port 25, so the reliable option is to configure Postfix as a relay through an authenticated SMTP provider on port 587.

Once mail delivery works, send a test from the server:

echo "Nagios mail test" | mail -s "Nagios test" you@your_domain

Validate and restart Nagios after editing the contact:

sudo /usr/local/nagios/bin/nagios -v /usr/local/nagios/etc/nagios.cfg
sudo systemctl restart nagios

To test the full alert path, stop NRPE on the remote host for a few minutes (sudo systemctl stop nagios-nrpe-server). After the retries configured in generic-service, the services go CRITICAL and you receive an email. Start NRPE again to get the recovery notification.

Troubleshooting

The web interface returns "Forbidden" or asks for a password in a loop. Check that /usr/local/nagios/etc/htpasswd.users exists and that the user is exactly nagiosadmin, which is the name authorized in cgi.cfg. Check sudo tail /var/log/apache2/error.log for the exact reason.

"Error: Could not stat() command file". The web interface cannot write to the command pipe. Confirm www-data is in the nagios group with id www-data, then restart Apache.

CHECK_NRPE: Error - Could not connect to remote_host_ip: Connection reset by peer. The Nagios server IP is missing from allowed_hosts on the remote host, or NRPE was not restarted after editing. Check with sudo journalctl -u nagios-nrpe-server.

CHECK_NRPE: Socket timeout. Port 5666 is blocked. Check sudo ufw status on the remote host and any external firewall between the servers.

NRPE: Command 'check_root_disk' not defined. The command name in the service does not match the one in /etc/nagios/nrpe.d/custom.cfg, or NRPE was not restarted.

Conclusion

You now have Nagios Core 4.5 running on Ubuntu 24.04 with the monitoring plugins, a password-protected web interface, and a remote server monitored through NRPE. Every new server follows the same pattern: install nagios-nrpe-server, allow the Nagios IP, and add a file under /usr/local/nagios/etc/servers/.

As next steps, protect the web interface with a TLS certificate, group servers with hostgroup definitions so services can be assigned to many hosts at once, and tune check_interval and max_check_attempts in templates.cfg to control how fast alerts fire.