devops7 min read

Nagios Tutorial: Learn Monitoring from Scratch (2026)

Nagios Tutorial: Learn Monitoring from Scratch (2026)

Published:  |  Category: Devops  |  Reading time: ~15 min
Nagios Tutorial: Learn Monitoring from Scratch (2026)

The first time a server went down at 3 AM and I had no idea until a user emailed, I promised myself I would never be blindsided again. Nagios was the tool that gave me visibility into my infrastructure. It checks hosts and services at configurable intervals, alerts when something is wrong, and escalates if nobody responds. For over two decades, Nagios has been the backbone of infrastructure monitoring. While newer tools like Prometheus have emerged, Nagios remains widely deployed — especially in environments with legacy systems, SNMP-based network gear, or compliance requirements that demand a proven track record. This tutorial covers Nagios from installation to advanced plugin development and distributed monitoring.

Nagios Core Architecture and Installation

Nagios Core runs on a central monitoring server that executes checks, processes results, and sends notifications. The architecture has four layers: the monitoring engine (Nagios Core), plugins (executables that perform checks), the web interface (Nagios XI for enterprise or third-party front-ends like Thruk or NagiosQL for community), and notification handlers. On Ubuntu, I install Nagios Core from source or use the EPEL/Tools repositories. The configuration directory structure is important: objects directory stores host, service, contact, and command definitions; the main nagios.cfg references these. The Nagios daemon runs as a service and reloads when configuration changes. After installation, verify the configuration with nagios -v /etc/nagios/nagios.cfg before restarting. I learned the hard way to always validate — a broken config stops monitoring dead.

sudo apt update && sudo apt install -y nagios4 nagios4-core nagios4-plugins
sudo htpasswd -c /etc/nagios4/htpasswd.users nagiosadmin
sudo nagios4 -v /etc/nagios4/nagios.cfg
sudo systemctl restart nagios4
sudo systemctl status nagios4

Hosts, Services, and Check Commands

The fundamental monitoring objects in Nagios are hosts and services. A host represents a device — server, router, switch, printer. Services are attributes of hosts — CPU load, disk usage, HTTP response, ping latency. Each check runs a plugin command and returns a status code: OK (0), WARNING (1), CRITICAL (2), or UNKNOWN (3). I define command objects that specify the plugin path and arguments, then reference them in service definitions. The check commands are Nagios plugins — standard executables that follow a consistent interface: check_http, check_ping, check_ssh, check_load, check_disk, check_procs. Plugins accept --help for usage. Nagios can also handle passive checks — external systems send results to Nagios via the NSCA protocol. I use passive checks for asynchronous monitoring like batch job completion and log file errors.

define host {
  use        linux-server
  host_name  web-01
  address    10.0.1.10
}

define service {
  use                 generic-service
  host_name           web-01
  service_description HTTP
  check_command       check_http!-H web-01 -u /health -w 3 -c 5
  check_interval      5
  retry_interval      1
  max_check_attempts  3
}

define command {
  command_name    check_http
  command_line    /usr/lib/nagios/plugins/check_http '$ARG1$'
}

Monitoring Remote Hosts with NRPE

NRPE (Nagios Remote Plugin Executor) allows Nagios to monitor remote hosts by executing plugins on the target machine. An NRPE agent runs on the remote host, listens on port 5666, and executes checks when requested by the Nagios server. I configure NRPE on every managed Linux server with basic checks: disk usage, CPU load, memory, process count, and SSH service. The nrpe.cfg file defines allowed hosts and command definitions. For security, I restrict NRPE to the Nagios server's IP, use SSL/TLS, and run checks as a non-root user via sudo for privileged commands. In 2026, many deployments use NRPE over SSH as an alternative transport. The check_nrpe plugin communicates with the remote NRPE agent and returns results to Nagios. I verify connectivity manually before adding hosts to the Nagios config.

# On remote host: /etc/nagios/nrpe.cfg
allowed_hosts=10.0.0.100
command[check_disk]=/usr/lib/nagios/plugins/check_disk -w 20% -c 10% -p /dev/sda1
command[check_load]=/usr/lib/nagios/plugins/check_load -w 5,4,3 -c 7,6,5
command[check_mem]=/usr/lib/nagios/plugins/check_mem -w 80 -c 95

# On Nagios server service definition
define service {
  host_name           db-01
  service_description Disk Usage
  check_command       check_nrpe!check_disk
  use                 generic-service
}

Notifications, Escalations, and Contacts

Notifications are how Nagios tells you something is wrong. Contact objects define who gets notified and via which method — email, SMS, Slack webhook, PagerDuty. The contact group aggregates multiple contacts for team-based alerting. I configure different notification periods for on-call vs off-hours. Escalations ensure alerts are not ignored: if a critical host remains down after 30 minutes, the escalation notifies the engineering manager; after 60 minutes, the incident response team. The notification_interval setting controls how often Nagios re-notifies until the problem is acknowledged or resolved. I set up notifications for OK-to-WARNING, WARNING-to-CRITICAL, and CRITICAL-to-OK state transitions. Recurring downtime — for maintenance windows — is defined via the scheduled downtime feature in the web UI or configuration files.

define contact {
  contact_name            oncall
  alias                   On-Call Engineer
  email                   oncall@example.com
  pager                   555-0100@sms.example.com
  service_notification_period 24x7
  host_notification_period    24x7
  service_notification_options w,u,c,r
  host_notification_options    d,u,r
  service_notification_commands notify-by-email, notify-by-slack
}

define contactgroup {
  contactgroup_name  admins
  alias              Infrastructure Administrators
  members            oncall, backup-engineer
}

Plugin Development and Custom Checks

Nagios plugins can be any executable that returns a status code and prints a status line. Shell scripts, Python, Perl, Ruby, and compiled C programs all work. I write custom plugins for application-specific checks — verifying API health, checking queue depth, validating certificate expiry dates. A plugin prints a one-line summary starting with OK, WARNING, CRITICAL, or UNKNOWN, followed by a pipe-delimited performance data section for graphing. The exit code determines the status. The Nagios Plugins Development Guidelines recommend using the monitoring-plugins library for C, but I find Python with argparse the most productive. Performance data in the format |key=value;warn;crit;min;max enables graphing through PNP4Nagios or checkmk. Custom plugins go in the /usr/lib/nagios/plugins directory and must be executable by the nagios user.

#!/usr/bin/env python3
import sys, argparse, requests

parser = argparse.ArgumentParser()
parser.add_argument('-u', '--url', required=True)
parser.add_argument('-w', '--warning', type=int, default=500)
args = parser.parse_args()

try:
    r = requests.get(args.url, timeout=10)
    latency = r.elapsed.total_seconds() * 1000
    if r.status_code == 200:
        print(f"OK - {args.url} returned {r.status_code} | latency={latency}")
        sys.exit(0)
    else:
        print(f"CRITICAL - {args.url} returned {r.status_code} | latency={latency}")
        sys.exit(2)
except Exception as e:
    print(f"CRITICAL - {args.url}: {e}")
    sys.exit(2)

Performance Graphing and Distributed Monitoring

Nagios itself does not graph data, but it outputs performance data that graphing tools consume. PNP4Nagios creates RRD-based graphs from Nagios performance data automatically. InfluxDB and Grafana also integrate well — Nagios writes metrics to InfluxDB via the check_influxdb plugin or a custom handler, and Grafana visualizes dashboards. For organizations with hundreds of hosts, a single Nagios server becomes a bottleneck. Distributed monitoring uses a central Nagios server that receives results from satellite Nagios instances or monitoring proxies. Mod-Gearman and NSCA distribute checks across multiple workers. The satellite servers run checks on remote networks and forward results to the central server. This architecture supports thousands of hosts across multiple data centers. I also configure redundant Nagios servers with passive checks — if the primary fails, the secondary takes over monitoring.

# PNP4Nagios configuration in nagios.cfg
process_performance_data=1
service_perfdata_file=/var/log/nagios4/service-perfdata
service_perfdata_file_template=DATATYPE::SERVICEPERFDATA\tTIMET::$TIMET$\tHOST::$HOSTNAME$\tSERVICE::$SERVICEDESC$\tOUTPUT::$SERVICEOUTPUT$\tPERFDATA::$SERVICEPERFDATA$

# Distributed: passive check forwarding
define service {
  host_name               remote-server
  service_description     Ping
  active_checks_enabled   0
  passive_checks_enabled  1
  check_freshness         1
  freshness_threshold     300
  check_command   check_ping!-H remote-server -w 50 -c 100
}

Frequently Asked Questions

Is Nagios still relevant in the era of Prometheus and Datadog?

Yes. Nagios excels at traditional infrastructure monitoring — checking if services are up, disk space is available, and network devices respond to SNMP. Many enterprises maintain Nagios alongside Prometheus because Nagios is better at SNMP-based monitoring of network gear and has a larger ecosystem of plugins. For cloud-native environments, Prometheus is generally preferred, but Nagios remains a critical part of many monitoring stacks.

How many hosts can a single Nagios server monitor?

A well-tuned Nagios Core instance can monitor 500 to 1000 hosts with basic checks. Performance depends on check intervals, plugin complexity, and hardware. NRPE adds latency due to SSH overhead. For larger environments, use distributed monitoring with satellite servers or switch to Nagios XI which has built-in performance optimizations.

What is the difference between active and passive checks?

Active checks are initiated by Nagios — the server runs a plugin at a scheduled interval and processes the result. Passive checks receive results from external sources — services send their status to Nagios via NSCA or the command file. Passive checks are essential for asynchronous monitoring like nightly batch jobs or log-based alerts that cannot be polled.

How do I upgrade Nagios Core without downtime?

Nagios Core upgrades require a service restart, which briefly disrupts monitoring. To minimize gaps: run a second Nagios instance as a passive standby, redirect the web UI to the standby during the upgrade, then switch back. Alternatively, use a distributed setup where satellite servers continue monitoring during the central server upgrade.

Originally published on Ayodhyyya. Last updated June 1, 2026.