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_ipfor its address. - A non-root user with
sudoprivileges 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
WarningBasic authentication over plain HTTP sends the password in clear text. Before using this in production, point a domain at the server and add a TLS certificate, for example with Certbot and its Apache plugin.
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.
