When I first started working with Nagios Core long ago, it was quite difficult to find good documentation on setting up Nagios with Nginx. Even now, when I search on Google, there’s still not much documentation discussing it. Most of it is just a basic setup with Apache. Therefore, I just want to write this guide to document what I found, and it may help someone else encountering the same situation.

Prerequisite

  • An Ubuntu 24.04 server to install Nagios and Nginx.
  • Another Ubuntu server to test monitoring.
HostnameIP addressRole
nagios-server.srv.local192.168.68.54A monitoring server
web-01.srv.local192.168.68.99web server to test

Note: I’m running a local DNS that allows me to use domain instead of IP address. If you want to have local DNS server so that you won’t have to enter your IP address, please check out How to Set Up a Local DNS Server with Dnsmasq in Ubuntu 24.04 (Fast & Easy) to facilitate your testing.

A Brief of Nagios

If you are confused about the different Nagios versions on the market. Basically, there are two main ones:

  • Nagios Core: is an open-source project, free to use. It’s DIY monitoring tool, highly flexible. You’ll need to manually configure checks, write custom scripts, and integrate plugins yourself. That means a lot of effort. I think once it’s tuned, you’re good to go in the long run without looking back too often.
  • Nagios XI: is a paid commercial version (Standard & Enterprise editions), including Nagios Core but equipped with many supported features, a web interface, built-in wizards, advanced reporting, etc. It saves time and removes the manual effort of setup work.

Download and Install Necessary Packages

Dependencies Installation

On the nagios-server server, we need to install PHP 8.3, Nginx, and the packages needed to compile and configure Nagios; we run:

# Require to compile and configure Nagios
sudo apt-get update

sudo apt-get install -y autoconf gcc libc6 make wget curl unzip libgd-dev ufw

sudo apt-get install -y openssl libssl-dev

# Install PHP8.3 related packages. Mainly are PHP8.3-FPM and common extensions.
sudo apt install -y php8.3 php8.3-fpm php8.3-common php8.3-cli php8.3-mbstring php8.3-bcmath php8.3-fpm php8.3-mysql php8.3-zip php8.3-gd php8.3-curl php8.3-xml

# Install Nginx and fcgiwrap allows to execute CGI bin files
sudo apt install -y nginx fcgiwrap

Create a nagios-core directory to store its source code package, run:

# Go to your home directory
cd

# Create nagios-core directory to store Nagios-core related files
mkdir nagios-core

# Go into the newly created directory
cd nagios-core

Download and Extract Nagios Core

# Find the latest Nagios-core release and download it. 
wget -O nagioscore.tar.gz $(curl -s "https://api.github.com/repos/NagiosEnterprises/nagioscore/releases/latest" | grep '"browser_download_url":' | grep -o 'https://[^"]*')

# Extract Nagios source code package
tar xzf nagioscore.tar.gz

# Check downloaded package and the extracted Nagios source code folder
ls -l

You should have nagioscore.tar.gz package and the extracted nagios-* version folder with the corresponding latest release. At this moment, it’s nagios-4.5.9.

Output:

Configure and Compile Nagios Core

Go into the extracted Nagios source code folder (adjust the version to the latest version you have if needed):

cd nagios-4.5.9

Execute the Nagios Core configure script:

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

Output at the end:

Compile and install Nagios Core. We run the following commands:

# Compile the main program and CGI
sudo make all

# Create "nagios" user and group. And add "www-data" user to the "nagios" group
sudo make install-groups-users
sudo usermod -a -G nagios www-data

# Installs Nagios Core, it includes the binary files, CGIs, and HTML files.
sudo make install

# Set up the service or daemon files and also configures them to start on boot.
sudo make install-daemoninit

# Installs and configures the external command file
sudo make install-commandmode

# Installs Nagios sample configuration files
sudo make install-config

Configure Nginx site

Create Nginx site for the Nagios Admin page

We need to create an Nginx site to access the Nagios Admin page.

Run sudo nano /etc/nginx/sites-available/nagios.conf and add the following content (change server_name to your actual Nagios’s domain name):

server {
    server_name     nagios-server.srv.local;
    listen          80;

    root            /usr/local/nagios/share;
    access_log      /var/log/nginx/nagios.access.log;
    error_log       /var/log/nginx/nagios.error.log;

    auth_basic            "Nagios Auth";
    auth_basic_user_file  /usr/local/nagios/etc/htpasswd.users;


    index           index.php index.html index.htm;
    
    # Redirect anything from /nagios/ to /
    rewrite ^/nagios/(.*) /$1;

    location / {
        try_files $uri $uri/ index.php;
    }

    location ~ ^/?(.*\.php)$ {
        try_files       $uri = 404;
        fastcgi_pass    unix:/run/php/php8.3-fpm.sock;
        include         fastcgi.conf;
    }

    location ~ \.cgi$ {
        fastcgi_param   AUTH_USER $remote_user;
        fastcgi_param   REMOTE_USER $remote_user;
        include         fastcgi.conf;
        fastcgi_pass    unix:/run/fcgiwrap.socket;
    }
}

Press Ctrl + O and press Enter to save the content. Then press Ctrl + X to exit.

Note: I’m running a local DNS server, which resolves nagios-server.srv.local to 192.168.68.54 (nagios-server’s IP adress). Therefore, I can set this domain to server_name. You can edit your hosts file and add <nagios-server-ip-address> <nagios-server-hostname> so that you can access nagios server through domain name.

Next, we need to activate this site by creating a symlink to /etc/nginx/sites-enabled, we run:

sudo ln -s /etc/nginx/sites-available/nagios.conf /etc/nginx/sites-enabled/nagios.conf

Reload Nginx service, we run:

sudo systemctl reload nginx

Next, create a user nagiosadmin (change to your own name) for basic Nginx authentication when accessing the Nagios Admin page, simply run:

sudo sh -c "echo -n 'nagiosadmin:' >> /usr/local/nagios/etc/htpasswd.users"
sudo sh -c "openssl passwd -apr1 >> /usr/local/nagios/etc/htpasswd.users"

A password field is prompted. You just need to enter the password for the account. You can repeat the process to create additional users.

Output:

Additional CGI configuration

By default, CGI binary files are in /usr/local/nagios/sbin. If we set the Nginx root directive to look for files in /usr/local/nagios/share, the CGI paths will refer to /nagios/cgi-bin/*.cgi, such as http://nagios-server.srv.local/nagios/cgi-bin/status.cgi. This means it searches for /nagios/cgi-bin/*.cgi files in the /usr/local/nagios/share/ directory, which do not exist.

To make Nagios Web UI work correctly, we have to do two things:

  • Rewrite the URI with a prefix from /nagios/ to /. For example: /nagios/index.php -> /index.php. We’ve done this at rewrite directive in the /etc/nginx/sites-available/nagios.conf file above.
  • Make a symlink /usr/local/nagios/sbin to /usr/local/nagios/share/cgi-bin. We run the command below:
sudo ln -s /usr/local/nagios/sbin /usr/local/nagios/share/cgi-bin

Now, it’s ok to move on to the next part.

NOTED (Optional): If you don’t want to use rewrite in nginx. In the /usr/local/nagios/etc/cgi.cfg file, we can actually modify:

from:

url_html_path=/nagios

to

url_html_path=/

It has the same effect of what you have done with rewrite on Nginx. I just prefer to use Nginx rather than touching configuration file. SHOULD CHOOSE ONE OF THIS – DO NOT USE BOTH WAY.

Install Nagios-Plugins

We’re almost done. To make Nagios Core work properly, it requires installing Nagios-Plugins, run:

# Go back to home directory
cd

# Create nagios-plugin directory to store its source code
mkdir nagios-plugin

# Go into the newly created directory
cd nagios-plugin

# Find the latest Nagios-plugins release and download it. 
wget -O nagios-plugins.tar.gz $(curl -s "https://api.github.com/repos/nagios-plugins/nagios-plugins/releases/latest" | grep '"browser_download_url":' | grep -o 'https://[^"]*')

# Extract Nagios-plugins source code package
tar xzf nagios-plugins.tar.gz

# Check downloaded package and the extracted Nagios-plugins source code folder
ls -l

Output:

Now, go to nagios-plugins-2.4.12 (You may need to change this to the version you downloaded) folder to install the plugin.

cd nagios-plugins-2.4.12/

Run the following commands to compile and install:

# Need to specify user/group here. Otherwise it uses the default user who runs this script (which is root in my case as I use "sudo")
sudo ./configure --with-nagios-user=nagios --with-nagios-group=nagios

# Compile and install nagios-plugins
sudo make
sudo make install

Verify the Nagios configuration file to make sure Nagios setup is correct, run:

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

Output:

If you see a sentence like “Things look okay”. Then you’re good to go now.

Start the Nagios service and enable auto-start at boot

sudo systemctl start nagios
sudo systemctl enable nagios

Open your browser, and access http://nagios-server.srv.local (change to your corresponding domain name). Log in with username/password that we created above, here is the nagiosadmin user

Once we sign in, we will see the main page as shown below.

On the left menu, click on Services to see what it looks like for the nagios-server server.

Ok. Congratulations! You have installed and configured Nagios Core successfully.

NOTED: If you created a username other than nagiosadmin, you need to set that username in /usr/local/nagios/etc/cgi.cfg file by updating all the fields looking like below:

authorized_for_system_information=nagiosadmin, yourusername
authorized_for_configuration_information=nagiosadmin, yourusername
authorized_for_system_commands=nagiosadmin, yourusername
authorized_for_all_services=nagiosadmin, yourusername
authorized_for_all_hosts=nagiosadmin, yourusername
authorized_for_all_service_commands=nagiosadmin, yourusername
authorized_for_all_host_commands=nagiosadmin, yourusername

Or assign * to them to authorise any username (not recommended).

Test adding a new host

We will test by adding a new host to Nagios for monitoring. Our new host is web-01.srv.local.

To do this, we need to do the following:

  • Create /usr/local/nagios/etc/objects/servers directory where we store all *.cfg files (are the host/template/contact configuration files)
  • Create Nagios Host and Service Object Definition
  • Create Host and Service Template Definitions so that all Host and Service Object Definitions can use.
  • Create Contact and Contact Group Definitions.

Step 1: Create /usr/local/nagios/etc/objects/servers directory, we run:

sudo mkdir /usr/local/nagios/etc/objects/servers

We need to insert cfg_dir=/usr/local/nagios/etc/objects/servers to /usr/local/nagios/etc/nagios.cfg by running:

sudo sed -i '0,/^#cfg_dir/ {
  /^#cfg_dir/ a\
cfg_dir=/usr/local/nagios/etc/objects/servers
}' /usr/local/nagios/etc/nagios.cfg

Step 2: Create Nagios Host and Service Object Definitions

Run sudo nano /usr/local/nagios/etc/objects/servers/hosts.cfg and paste the content below:

# HOSTS DEFINITION - We create definition for each host we have                                                                                                                        
define host {
    use        all-servers   ; Name of host template to use
    host_name  web-01         ; Specify server's hostname
    alias      web-01         ; Can set to any meaningful name
    address    192.168.68.99  ; Specify server's IP
}

# SERVICES DEFINITION - We can add many sevice definitions based on what we want to check
define service {
    use                     hosts-service        ; Name of service template to use
    host_name               web-01
    service_description     PING                   ; This service is to check PING.
    check_command           check_ping!100.0,20%!500.0,60%
}


# HOST GROUP DEFINITION - Assign hosts to a corresponding group to manage                               
define hostgroup {
    hostgroup_name         web-servers-group
    alias                  Web Servers
    members                web-01
}

Press Ctrl + O and press Enter to save the content. Then press Ctrl + X to exit.

Step 3: Create Host and Service Template Definitions

Run sudo nano /usr/local/nagios/etc/objects/servers/hosts-template.cfg and paste the content:

# Set "all-servers" template for each host definition to use
define host {
    name                            all-servers    ; The name of this host template
    notifications_enabled           1       ; Host notifications are enabled
    event_handler_enabled           1       ; Host event handler is enabled
    flap_detection_enabled          1       ; Flap detection is enabled
    process_perf_data               1       ; Process performance data
    retain_status_information       1       ; Retain status information across program restarts
    retain_nonstatus_information    1       ; Retain non-status information across program restarts
    check_command                   check-host-alive ; Default command to check if servers are "alive"
    check_interval                  5       ; Actively check the server every 5 minutes
    max_check_attempts              10      ; Check each server 10 times (max)
    notification_interval           30      ; Resend notifications every 30 minutes 
    notification_period             24x7    ; Send notification out at any time - day or night
    notification_options            d,u     ; Only send notifications for specific host states
    contact_groups                  sysadmins  ; Notifications get sent to the sysadmins group
    register                        0       ; DONT REGISTER THIS DEFINITION - ITS NOT A REAL HOST, JUST A TEMPLATE!
}

Press Ctrl + O and press Enter to save the content. Then press Ctrl + X to exit.

Run sudo nano /usr/local/nagios/etc/objects/servers/services-template.cfg and paste the content:

# Set "hosts-service" template for each service definition to use
define service {

    name                            hosts-service         ; The 'name' of this service template
    active_checks_enabled           1                       ; Active service checks are enabled
    passive_checks_enabled          1                       ; Passive service checks are enabled/accepted
    parallelize_check               1                       ; Active service checks should be parallelized (disabling this can lead to major performance problems)
    obsess_over_service             1                       ; We should obsess over this service (if necessary)
    check_freshness                 0                       ; Default is to NOT check service 'freshness'
    notifications_enabled           1                       ; Service notifications are enabled
    event_handler_enabled           1                       ; Service event handler is enabled
    flap_detection_enabled          1                       ; Flap detection is enabled
    process_perf_data               1                       ; Process performance data
    retain_status_information       1                       ; Retain status information across program restarts
    retain_nonstatus_information    1                       ; Retain non-status information across program restarts
    is_volatile                     0                       ; The service is not volatile
    check_period                    24x7                    ; The service can be checked at any time of the day
    max_check_attempts              3                       ; Re-check the service up to 3 times in order to determine its final (hard) state
    check_interval                  10                      ; Check the service every 10 minutes under normal conditions
    retry_interval                  2                       ; Re-check the service every two minutes until a hard state can be determined
    contact_groups                  sysadmins                  ; Notifications get sent out to everyone in the 'sysadmins' group
    notification_options            w,u,c,r                 ; Send notifications about warning, unknown, critical, and recovery events
    notification_interval           60                      ; Re-notify about service problems every hour
    notification_period             24x7                    ; Notifications can be sent out at any time
    register                        0                       ; DON'T REGISTER THIS DEFINITION - ITS NOT A REAL SERVICE, JUST A TEMPLATE!
}

Press Ctrl + O and press Enter to save the content. Then press Ctrl + X to exit.

Step 4: Create Contact and Contact Group Definitions.

Run sudo nano /usr/local/nagios/etc/objects/servers/contact-template.cfg and paste the content:

define contact {
    contact_name            your-name             ; Short name of user
    use                     generic-contact         ; Inherit default values from generic-contact template (defined above)
    alias                   your-full-name            ; Full name of user
    email                   example@your-email.com ; <<***** CHANGE THIS TO YOUR EMAIL ADDRESS ******
}

define contactgroup {

    contactgroup_name       sysadmins
    alias                   Nagios System Administrators
    members                 your-name
}

Press Ctrl + O and press Enter to save the content. Then press Ctrl + X to exit.

Verify the Nagios Configuration files again:

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

Reload the Nagios service to apply the new configurations.

sudo systemctl reload nagios

We go back to the Nagios Admin page and click Services link on the left menu to check web-01 host.

Ok, we’ve finished this setup. Enjoy configuring your Nagios Monitoring tool.

My thoughts

Nagios setup is a tedious task. We can consider adding these steps to Puppet, Ansible, or a similar tool. Next time, if we want to reinstall the Nagios Server in a disaster case, it should automate configuration steps for us without us remembering the steps.

Also, you might find adding hosts to .cfg files manually is cumbersome. Imagine you have thousands of servers to manage? Sounds not good, right? I mean, it may not be useful in modern architectures, especially in dynamic environments such as cloud, etc., when we want to quickly relaunch servers/containers to, e.g. right-size the instance type.

With the DevOps mindset, we’d better think of a way to automate this. And one of the solutions is to use Consul Service Discovery. I wrote Automating Nagios Host and Service Discovery with Consul blog to show how it works. It’s not a new concept, but I just want to share in case you haven’t heard of it. Consul uses consul-template to automate host updates in .cfg files when it receives a signal of a change from a host. For example, in an AWS environment, when we launch a new server (EC2) or container, we need to install the Consul agent on this server/container so that it registers as a node to the Consul server (normally through Ansible/Puppet, etc). Nagios also has Consul Agent running on this, and it automatically queries the Consul server to pull the new node’s details and update the new server/container information in hosts.cfg file. Imagine you have thousands of servers to manage, this way saves you time significantly without updating those config files manually.

With that being said, I also wrote Puppet Series – Automating Nagios Setup and Auto-Discovery Using Consul to demonstrate the use case of Puppet in automating this article and Automating Nagios Host and Service Discovery with Consul in case you’re interested. I hope it can help you form some ideas to build up a robust system for yourself as well as your workplace. Thanks for reading!

References


Discover more from Turn DevOps Easier

Subscribe to get the latest posts sent to your email.

By Binh

Leave a Reply

Your email address will not be published. Required fields are marked *

Content on this page