Monday, March 23, 2026

Linux | Install and Configure Nagios Core on RHEL 10 / Rocky Linux 10

 Install and Configure Nagios Core on RHEL 10 / Rocky Linux 10

Nagios Core is a "battle-tested," open-source monitoring engine designed for high-reliability infrastructure tracking. This guide covers the source-installation of Version 4.5.11 (the latest stable release as of early 2026) on modern RHEL-based systems.

Key Highlights:

Functionality: Monitors hosts (servers, switches) and services (HTTP, SSH, SNMP) with a robust alerting system for failures and recoveries.

Architecture: Uses a lightweight, C-based core with a plugin-based model, making it highly extensible for custom monitoring needs.

Modern OS Support: Specifically tailored for RHEL 10, Rocky Linux 10, and AlmaLinux 10, addressing the latest security and compiler requirements.

Core Components: Includes the Apache-based web interface, essential Nagios Plugins, and email notification integration via SMTP.

Prerequisites

Before starting, make sure you have the following in place:
- A server running RHEL 10, Rocky Linux 10, or AlmaLinux 10 with at least 2 GB RAM
- Root or sudo access
- A working DNS name or static IP for the Nagios server
- Internet access to download source packages
- Ports 80 (HTTP) and 443 (HTTPS) open in the firewall
- An SMTP-capable mail setup for alert notifications (Postfix or external relay)

Switch to the root user for the rest of this guide:

sudo -i

Step 1. Install Nagios Core Dependencies

Nagios Core is compiled from source, so we need development tools plus libraries for the web interface and plugins. Install all required packages in one command:

dnf install -y gcc glibc glibc-common make gettext automake autoconf wget \
  openssl-devel net-snmp net-snmp-utils epel-release \
  perl-Net-SNMP postfix unzip httpd php php-fpm gd gd-devel \
  perl perl-devel

Enable and start Apache and PHP-FPM so the web interface is ready once Nagios is installed:

systemctl enable --now httpd php-fpm

Step 2. Create Nagios User and Group
Nagios runs under its own dedicated user. The nagcmd group allows the web interface to issue external commands (acknowledge alerts, schedule downtime, etc.):
useradd nagios
groupadd nagcmd
usermod -aG nagcmd nagios
usermod -aG nagcmd apache

Step 3. Download and Compile Nagios Core

Download the latest Nagios Core 4.5.11 source tarball and extract it:

cd /tmp
wget https://github.com/NagiosEnterprises/nagioscore/releases/download/nagios-4.5.11/nagios-4.5.11.tar.gz
tar xzf nagios-4.5.11.tar.gz
cd nagios-4.5.11

Run the configure script, specifying the command group we created earlier:

./configure --with-command-group=nagcmd

The configuration summary should show all checks passed. Now compile and install Nagios along with its init scripts, command mode, and sample configuration:

make all
make install
make install-init
make install-commandmode
make install-config

Install the Apache configuration file for the Nagios web interface:

make install-webconf

Step 4. Set Up the Nagios Web Interface Password

Create the nagiosadmin user for web interface authentication. Replace the password when prompted:

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

You will be prompted to enter and confirm a password. This is the login you use to access the Nagios dashboard.

Restart Apache to pick up the new Nagios configuration:

systemctl restart httpd

Step 5. Install Nagios Plugins

Nagios Core by itself has no monitoring capability – it relies on Nagios Plugins to perform the actual checks. Download and compile the latest plugins release (2.4.12):

cd /tmp
wget https://github.com/nagios-plugins/nagios-plugins/releases/download/release-2.4.12/nagios-plugins-2.4.12.tar.gz
tar xzf nagios-plugins-2.4.12.tar.gz
cd nagios-plugins-2.4.12

Configure and compile the plugins:

./configure --with-nagios-user=nagios --with-nagios-group=nagios
make
make install
After installation, the plugins are placed in /usr/local/nagios/libexec/. Verify they exist:

ls /usr/local/nagios/libexec/ | head -20

You should see a list of check plugins like check_pingcheck_httpcheck_disk, and many more.

Step 6. Configure Apache Web Interface for Nagios

The default configuration maps /nagios to the Nagios web directory and requires authentication. The key directives are:
ScriptAlias /nagios/cgi-bin "/usr/local/nagios/sbin" 
<Directory "/usr/local/nagios/sbin">
   Options ExecCGI
   AllowOverride None
   AuthName "Nagios Access"
   AuthType Basic
   AuthUserFile /usr/local/nagios/etc/htpasswd.users
   Require valid-user 
</Directory>
Alias /nagios "/usr/local/nagios/share" 
<Directory "/usr/local/nagios/share">
   Options None
   AllowOverride None
   AuthName "Nagios Access"
   AuthType Basic
   AuthUserFile /usr/local/nagios/etc/htpasswd.users
   Require valid-user
</Directory>

 If you need to change the web path or add SSL, edit this file. For now, the defaults work for initial setup. If SELinux is in enforcing mode, allow Apache to connect to the Nagios CGI scripts:

setsebool -P httpd_can_network_connect 1

Step 7. Configure Nagios Core (nagios.cfg)

The main Nagios configuration file is /usr/local/nagios/etc/nagios.cfg. The sample config installed earlier works out of the box, but there are a few settings worth reviewing. Open the file:

vi /usr/local/nagios/etc/nagios.cfg

Key settings to verify or adjust:

# Where object config files are loaded from
cfg_dir=/usr/local/nagios/etc/servers

# Log file location
log_file=/usr/local/nagios/var/nagios.log

# External commands (needed for web UI actions like ack/downtime)
check_external_commands=1

# How often Nagios checks for external commands (seconds)
command_check_interval=-1

# Admin email and pager for notifications
admin_email=admin@example.com
admin_pager=admin-pager@example.com
The cfg_dir line tells Nagios to load all .cfg files from the /usr/local/nagios/etc/servers/ directory. Create this directory now – we will add host definitions there:

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

Verify the configuration is valid before starting Nagios:

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

The output should end with “Things look okay” and zero errors. If you see warnings or errors, fix the referenced config files before proceeding.

Step 8. Add Hosts and Services to Monitor

Nagios monitors targets through host and service object definitions. Each remote host gets its own config file in /usr/local/nagios/etc/servers/. Here is an example for a web server at 10.0.1.50. Create the file:

vi /usr/local/nagios/etc/servers/webserver01.cfg

Add the following host and service definitions:

define host {
    use                     linux-server
    host_name               webserver01
    alias                   Web Server 01
    address                 10.0.1.50
    max_check_attempts      5
    check_period            24x7
    notification_interval   30
    notification_period     24x7
}

define service {
    use                     generic-service
    host_name               webserver01
    service_description     PING
    check_command           check_ping!100.0,20%!500.0,60%
}

define service {
    use                     generic-service
    host_name               webserver01
    service_description     HTTP
    check_command           check_http
}
define service {
    use                     generic-service
    host_name               webserver01
    service_description     SSH
    check_command           check_ssh
}

define service {
    use                     generic-service
    host_name               webserver01
    service_description     Disk Usage
    check_command           check_local_disk!20%!10%!/
}
This defines the host and four services: ping connectivity, HTTP response, SSH availability, and local disk usage. The check_ping thresholds mean warning at 100ms/20% loss and critical at 500ms/60% loss.
For monitoring remote Linux hosts with detailed checks (CPU, memory, disk), install NRPE on the target server. See our guide on adding remote hosts to Nagios for monitoring for the full NRPE setup.
After adding host files, validate the configuration again:

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

Step 9. Configure Email Notifications

Nagios sends alert emails through the local mail system. Make sure Postfix is installed and running:

systemctl enable --now postfix

Nagios notification commands are defined in /usr/local/nagios/etc/objects/commands.cfg. The default commands use /usr/bin/mail to send host and service alerts. Open the contacts configuration:

vi /usr/local/nagios/etc/objects/contacts.cfg

Update the nagiosadmin contact with your real email address:
define contact {
    contact_name            nagiosadmin
    use                     generic-contact
    alias                   Nagios Admin
    email                   your-email@example.com
}

define contactgroup {
    contactgroup_name       admins
    alias                   Nagios Administrators
    members                 nagiosadmin
}
Replace your-email@example.com with the address where you want to receive alerts. You can add multiple contacts by creating additional define contact blocks and adding them to the admins group.
Test email delivery from the command line to confirm Postfix is working:

echo "Nagios test email" | mail -s "Nagios Alert Test" your-email@example.com

If you are using an external SMTP relay (Gmail, Amazon SES, etc.), configure Postfix as a relay host in /etc/postfix/main.cf instead of sending directly.

Step 10. Configure Firewall for Nagios

Open HTTP and HTTPS ports in firewalld so you can access the Nagios web interface:

firewall-cmd --permanent --add-service=http
firewall-cmd --permanent --add-service=https
firewall-cmd --reload

Confirm the rules are active:

firewall-cmd --list-services

The output should include http and https in the list of allowed services. If you are running Nagios behind a reverse proxy or on a non-standard port, adjust accordingly.
If you also plan to use NRPE for remote host checks, open TCP port 5666 on the remote hosts (not the Nagios server).

Step 11. Start Nagios and Verify the Monitoring Dashboard

Enable and start the Nagios service:

systemctl enable --now nagios

Check that Nagios is running:

systemctl status nagios

The output should show active (running) with no errors. If the service fails to start, check /usr/local/nagios/var/nagios.log for details.
Open your browser and navigate to:

http://your-server-ip/nagios

Log in with the nagiosadmin credentials you created in Step 4. The dashboard shows the Tactical Overview with host and service status summaries. Click “Hosts” in the left menu to see monitored hosts, and “Services” for individual service checks.

Give Nagios a few minutes to run the initial round of checks. Hosts and services will transition from “PENDING” to their actual status (OK, WARNING, CRITICAL, or UNKNOWN).

Nagios Configuration Files Reference

Nagios has several configuration files spread across its installation directory. This table summarizes the key files you will work with:

File Path
/usr/local/nagios/etc/nagios.cfg
Purpose: Main configuration file – controls global settings, loaded config dirs, logging

/usr/local/nagios/etc/cgi.cfg
Purpose: Web interface CGI settings – controls who can view/modify what in the dashboard

/usr/local/nagios/etc/objects/commands.cfg
Purpose: Check and notification command definitions

/usr/local/nagios/etc/objects/contacts.cfg
Purpose: Contact and contact group definitions for notifications

/usr/local/nagios/etc/objects/timeperiods.cfg
Purpose: Time period definitions (24×7, work hours, etc.)

/usr/local/nagios/etc/objects/templates.cfg
Purpose: Host and service templates (linux-server, generic-service, etc.)

/usr/local/nagios/etc/servers/
Purpose: Directory for your custom host/service definitions

/usr/local/nagios/etc/htpasswd.users
Purpose: Web interface user authentication file

/etc/httpd/conf.d/nagios.conf
Purpose: Apache configuration for the Nagios web UI

/usr/local/nagios/var/nagios.log
Purpose: Main Nagios log file for troubleshooting

Closure:

Nagios Core 4.5.11 Finalization

Status: Nagios Core 4.5.11 is operational, providing a stable engine for monitoring hosts, services, and network devices with integrated email alerting.

Production Hardening:

- Security: Secure the web interface by adding TLS/SSL certificates (via Let's Encrypt) to Apache.

- Deep Monitoring: Deploy NRPE (Nagios Remote Plugin Executor) or NCPA 3.2.3 on remote servers (like your Canada SIP node) to monitor local metrics like disk usage and specific process health.

- Efficiency: Configure Escalation Policies to ensure critical alerts are rerouted to senior admins if not acknowledged within a set timeframe.

Future Expansion:

- Integrate with Prometheus/Grafana if you require modern, high-density performance graphs alongside Nagios's classic alerting.

- Consider Nagios XI 2026R1 if you eventually need web-based configuration wizards and advanced "Smart Dashboards."

Linux | Install and Configure Netdata Monitoring on RHEL 10 / Rocky Linux 10

 Install and Configure Netdata Monitoring on RHEL 10 / Rocky Linux 10

Since today is March 23, 2026, staying updated with the latest monitoring tools like Netdata v2.9.0 is a smart move for your infrastructure. While Zabbix is great for long-term trends and alerts, Netdata is unbeatable for "per-second" real-time troubleshooting.

Netdata Real-Time Monitoring Guide

- Core Capability: Netdata is a lightweight, high-performance tool that collects thousands of metrics per second with zero-configuration, providing an instant, interactive dashboard.

- System Support: It runs efficiently on RHEL 10, Rocky Linux 10, AlmaLinux 10, FreeBSD, macOS, and Kubernetes.

Key Installation Steps:

- Kickstart Installation: Uses a single-line script for rapid deployment.

- Dashboard & Alarms: Out-of-the-box health checks and visual data representation.

- Application Monitoring: Automatically detects and monitors web servers, databases, and containers.

- Security & Access: Configuration includes firewall rules and securing the dashboard using an Nginx Reverse Proxy.

System Requirements & Preparation

- OS & Hardware: A server running RHEL 10, Rocky Linux 10, or AlmaLinux 10 with at least 1 CPU core and 1 GB RAM.

- Connectivity: A stable internet connection is required for the kickstart installation and package downloads.

- Security & Networking: * Port 19999/TCP: Must be open to access the native Netdata dashboard.

Ports 80/443: Should be used if you follow the recommended path of setting up an Nginx reverse proxy for better security.

Access: Root or sudo privileges are mandatory for the installation and configuration of system alarms.

Step 1. Install Netdata on RHEL 10 / Rocky Linux 10
Netdata provides a kickstart script that detects your distribution and installs the appropriate packages automatically. This is the officially recommended installation method. Run the following command as root or with sudo:

wget -O /tmp/netdata-kickstart.sh https://get.netdata.cloud/kickstart.sh && sh /tmp/netdata-kickstart.sh --dont-wait

 The --dont-wait flag skips the confirmation prompt. If you prefer curl over wget:

curl https://get.netdata.cloud/kickstart.sh > /tmp/netdata-kickstart.sh && sh /tmp/netdata-kickstart.sh --dont-wait

The installer downloads dependencies, compiles Netdata if needed, and sets up the systemd service. Once installation finishes, you should see a summary confirming Netdata is installed:
Successfully installed netdata
 --- You can now access Netdata at http://localhost:19999
Verify the installed version:
netdata -v
This should return the current version:
netdata v2.9.0
Step 2. Start and Enable Netdata Service
The kickstart script usually starts Netdata automatically, but confirm the service is running and enabled to survive reboots:
sudo systemctl enable --now netdata
Check the service status to verify it is active and running:
sudo systemctl status netdata
The output should show active (running) with the main PID and memory usage:
● netdata.service - Real time performance monitoring
     Loaded: loaded (/usr/lib/systemd/system/netdata.service; enabled; preset: disabled)
     Active: active (running) since Sat 2026-03-22 10:15:32 UTC; 5s ago
   Main PID: 12345 (netdata)
      Tasks: 45 (limit: 23456)
     Memory: 120.4M
        CPU: 2.134s
     CGroup: /system.slice/netdata.service
Step 3. Access the Netdata Dashboard
Netdata serves its web dashboard on port 19999 by default. Open your browser and navigate to:
http://your-server-ip:19999

Replace your-server-ip with your server’s actual IP address – for example, http://192.168.1.50:19999. The dashboard loads instantly and starts displaying real-time metrics with per-second granularity. You will see system overview charts for CPU, memory, disk I/O, and network traffic right on the landing page.

If the dashboard does not load, check that the firewall allows port 19999 (covered in Step 8) and that the Netdata service is running.

Step 4. Configure Netdata

The main Netdata configuration file is /etc/netdata/netdata.conf. This file controls the agent’s behavior including data retention, memory usage, listening address, and update frequency. The recommended way to edit it is through the built-in editor script:
sudo /etc/netdata/edit-config netdata.conf
Key settings you may want to adjust in the (global) section:
[global]
    # Change the default listening port (default: 19999)
    default port = 19999

    # Bind to a specific IP (default: all interfaces)
    bind to = 0.0.0.0

    # Data collection frequency in seconds (default: 1)
    update every = 1

    # History length in seconds - 3600 = 1 hour of data at 1-second granularity
    history = 3600
For production servers that need longer retention, increase the history value. Setting it to 86400 retains 24 hours of per-second data but uses more RAM. Alternatively, configure the database engine mode for disk-based storage in the [db] section:
[db]
    # dbengine stores data on disk, allowing much longer retention
    mode = dbengine

    # Disk space limit in MB for tier 0 (per-second data)
    dbengine multihost disk space MB = 1024
After making changes, restart Netdata to apply:
sudo systemctl restart netdata

Step 5. Monitor System Metrics

Netdata provides a zero-configuration, high-fidelity monitoring dashboard that updates every second. It categorizes system health into four critical sections:

- CPU: Tracks per-core usage, system/user time, and Steal time (vital for identifying VM resource contention).

- Memory: Offers a granular breakdown of RAM (Used, Cached, Free), Swap usage, and kernel memory health.

- Disk I/O: Monitors throughput, IOPS, and latency, which is essential for database performance (like your GlobalTVBD SQL backend).

- Network: Visualizes bandwidth, packets per second, and TCP connection states to identify network saturation or potential attacks.

Key Feature: Netdata includes an integrated time-picker for anomaly investigation and can export data to Prometheus/Grafana for long-term storage and advanced visualization.

Step 6. Configure Alarms and Notifications

Netdata ships with hundreds of pre-configured health alarms covering CPU usage, memory pressure, disk space, network errors, and more. Alarm configuration files live in /etc/netdata/health.d/. List the available alarm definitions:
ls /etc/netdata/health.d/
To create a custom alarm – for example, alert when disk space on the root partition drops below 20% – edit or create a health config:
sudo /etc/netdata/edit-config health.d/disk_space_custom.conf
Add the following alarm definition:
alarm: disk_space_root_low
    on: disk.space
lookup: average -1m percentage of used
 every: 1m
  warn: $this > 80
  crit: $this > 90
  info: Root disk space usage is high
This triggers a warning when disk usage exceeds 80% and a critical alert above 90%. After adding the alarm, reload the health configuration without restarting Netdata:
sudo netdatacli reload-health
To view current active alarms from the command line:
curl -s http://localhost:19999/api/v1/alarms | python3 -m json.tool | head -50
For email notifications, configure the alarm notification settings:
sudo /etc/netdata/edit-config health_alarm_notify.conf
Set the email recipient and sender in the notification config:
# Enable email notifications
SEND_EMAIL="YES"

# Default recipient for all alarms
DEFAULT_RECIPIENT_EMAIL="admin@example.com"

# Sender address
EMAIL_SENDER="netdata@example.com"
Netdata also supports notifications through Slack, PagerDuty, Telegram, Discord, and many other platforms. Check the Netdata configuration documentation for all available notification methods.

Step 7. Monitor Applications – MySQL, Nginx, Docker
Netdata auto-detects many running applications and starts collecting metrics from them. For services that require authentication or custom endpoints, you need to configure the corresponding collector.

Monitor MySQL / MariaDB
Netdata uses the go.d/mysql collector. Create a MySQL user for Netdata:
mysql -u root -p
Run these SQL statements to create a read-only monitoring user:
CREATE USER 'netdata'@'localhost' IDENTIFIED BY 'StrongPassword123';
GRANT USAGE, REPLICATION CLIENT, PROCESS ON *.* TO 'netdata'@'localhost';
FLUSH PRIVILEGES;
EXIT;
Then configure the MySQL collector:
sudo /etc/netdata/edit-config go.d/mysql.conf
Add the connection details:
jobs:
  - name: local_mysql
    dsn: netdata:StrongPassword123@tcp(127.0.0.1:3306)/
Restart Netdata to pick up the new collector config. The dashboard will show MySQL metrics including queries per second, connections, buffer pool usage, and replication lag.

Monitor Nginx
Netdata monitors Nginx through the stub_status module. Enable the status endpoint in your Nginx configuration by adding a server block or location:
sudo vi /etc/nginx/conf.d/stub_status.conf
Add this server block:
server {
    listen 127.0.0.1:80;
    server_name 127.0.0.1;

    location /stub_status {
        stub_status;
        allow 127.0.0.1;
        deny all;
    }
}
Reload Nginx and Netdata will auto-detect the status endpoint. You will see active connections, requests per second, and connection states in the dashboard.

Monitor Docker Containers
Netdata monitors Docker containers automatically when it has access to the Docker socket. Add the netdata user to the docker group:
sudo usermod -aG docker netdata
sudo systemctl restart netdata
After restarting, Netdata displays per-container metrics including CPU usage, memory consumption, network I/O, and block I/O. Each container appears as a separate section in the dashboard.

Step 8. Configure Firewall for Netdata
RHEL 10 and Rocky Linux 10 use firewalld by default. Open port 19999/TCP to access the Netdata dashboard from remote machines. If you plan to use an Nginx reverse proxy (Step 9), you can skip this and open only ports 80/443 instead.

To allow direct access to the Netdata dashboard on port 19999:
sudo firewall-cmd --permanent --add-port=19999/tcp
sudo firewall-cmd --reload
Verify the port is open in the firewalld configuration:
sudo firewall-cmd --list-ports
The output should include 19999/tcp in the active ports list:
19999/tcp
Step 9. Secure Netdata with Nginx Reverse Proxy
Running Netdata behind an Nginx reverse proxy adds TLS encryption and basic authentication. This is the recommended setup for production servers where the dashboard is exposed beyond the local network.

First, install Nginx and the httpd-tools package for password file generation:
sudo dnf install -y nginx httpd-tools
Create a password file for basic authentication:
sudo htpasswd -c /etc/nginx/.htpasswd netdata_admin
Enter a strong password when prompted. Next, bind Netdata to localhost only so it is not directly accessible from the network. Edit the Netdata config:
sudo /etc/netdata/edit-config netdata.conf
Set the bind address to localhost in the [web] section:
[web]
    bind to = 127.0.0.1
Restart Netdata to apply the binding change:
sudo systemctl restart netdata
Create the Nginx virtual host configuration for Netdata:
sudo vi /etc/nginx/conf.d/netdata.conf
Add the following reverse proxy configuration. Replace netdata.example.com with your actual domain or server IP:
upstream netdata_backend {
    server 127.0.0.1:19999;
    keepalive 64;
}

server {
    listen 80;
    server_name netdata.example.com;

    auth_basic "Netdata Monitoring";
    auth_basic_user_file /etc/nginx/.htpasswd;

    location / {
        proxy_set_header X-Forwarded-Host $host;
        proxy_set_header X-Forwarded-Server $host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_pass http://netdata_backend;
        proxy_http_version 1.1;
        proxy_pass_request_headers on;
        proxy_set_header Connection "keep-alive";
        proxy_store off;
    }
}
Test the Nginx configuration and start the service:
sudo nginx -t
sudo systemctl enable --now nginx
Open HTTP and HTTPS ports in the firewall and remove the direct Netdata port if you opened it earlier:
sudo firewall-cmd --permanent --add-service=http
sudo firewall-cmd --permanent --add-service=https
sudo firewall-cmd --permanent --remove-port=19999/tcp
sudo firewall-cmd --reload
Access the dashboard through the proxy at http://netdata.example.com. The browser will prompt for the username and password you created with htpasswd. For TLS, add a certificate from Let’s Encrypt or your preferred CA to the Nginx server block.

Step 10: Connect to Netdata Cloud

Netdata Cloud is a free service that provides a centralized dashboard for monitoring multiple Netdata agents across different servers. It does not store your metrics – the data stays on your servers. Netdata Cloud provides a unified view, cross-server correlation, and role-based access control.

If you did not connect during installation, claim the agent to your Netdata Cloud account:
- Sign up or log in at app.netdata.cloud
- Create a Space and a Room (or use the defaults)
- Click “Connect Nodes” and copy the claiming command

The claiming command looks like this (use the exact token from your Netdata Cloud account):
sudo netdata-claim.sh -token=YOUR_CLOUD_TOKEN -rooms=YOUR_ROOM_ID -url=https://app.netdata.cloud
After claiming, the agent appears in your Netdata Cloud dashboard within a few seconds. You can now monitor this server alongside all your other Netdata nodes from a single interface. Netdata Cloud also provides composite charts that aggregate metrics from multiple servers – useful for monitoring clusters.

To verify the agent is connected, check the claiming status:
sudo netdatacli aclk-state
The output should show ACLK state: online if the connection to Netdata Cloud is active. If you run Netdata with Grafana, you can also export Netdata metrics to Grafana dashboards for custom visualization.

Closure:

Netdata is successfully deployed on your RHEL 10 / Rocky Linux 10 server, providing real-time system and container monitoring. To ensure it is production-ready, follow these final hardening steps:

- Security: Use an Nginx Reverse Proxy with Basic Auth to protect the dashboard. Add TLS certificates (SSL) for encrypted access.

- Performance: Tune the dbengine settings to balance your data retention needs with your available disk space.

- Scalability: Integrate with Prometheus for long-term historical data storage.

- Proactive Care: Enable Alarm Notifications (Email/Telegram) to catch performance spikes before they impact your users.

Linux | Install and Configure Asterisk PBX on Ubuntu 24.04 / Debian 13

Linux | Install and Configure Asterisk PBX on Ubuntu 24.04 / Debian 13

Asterisk is a powerful, open-source communications framework that transforms a standard Linux server into a comprehensive Private Branch Exchange (PBX). Key highlights of this guide include:

Capabilities: It supports SIP trunking, IVR, voicemail, and conferencing without the burden of per-seat licensing fees.

Version & Support: This guide focuses on Asterisk 22 LTS, the current Long-Term Support release, ensuring full support through October 2028.

Technical Scope: The tutorial covers installing Asterisk from source on Ubuntu 24.04 and Debian 13, including:

- Compiling with PJSIP support.
- Configuring SIP endpoints and dialplans.
- Firewall configuration and softphone testing.


System Requirements & Preparation

OS & Hardware: A server running Ubuntu 24.04 LTS or Debian 13 with a minimum of 2 CPU cores and 1 GB RAM.

Connectivity: A Public IP address is required for remote SIP clients or trunking (essential for your Canada-to-Bangladesh link).

Security & Firewall: The following ports must be open to allow signaling and voice traffic:

- 5060/UDP (Standard SIP)
- 5061/TCP (Encrypted SIP/TLS)
- 10000-20000/UDP (RTP Media/Voice streams)

Domain & SSL (Optional): A registered domain name is recommended if you plan to implement TLS/SRTP for secure, encrypted calling in production.

 Root or sudo privileges are required to perform the installation.

sudo -i

Step 1. Install Asterisk Build Dependencies

Asterisk is compiled from source, so we need development libraries and build tools. Start by updating the package index and installing the required packages.

apt update && apt upgrade -y 

Install the core build tools and libraries Asterisk needs for compilation:

apt install -y build-essential git curl wget subversion \
  libncurses5-dev libssl-dev libxml2-dev libsqlite3-dev \
  uuid-dev libjansson-dev libedit-dev pkg-config \
  autoconf automake libtool unixodbc-dev libcurl4-openssl-dev \
  libspeex-dev libspeexdsp-dev libogg-dev libvorbis-dev \
  libsrtp2-dev libopus-dev libresample1-dev sox mpg123 \
  xmlstarlet bison flex 

 These cover everything from TLS support (libssl-dev) to codec libraries (opus, speex, vorbis) and the SRTP stack needed for encrypted media.

Step 2. Download and Compile Asterisk 22 LTS

Download the latest Asterisk 22 LTS tarball from the official download server. The asterisk-22-current link always points to the newest 22.x release.

cd /usr/src
wget https://downloads.asterisk.org/pub/telephony/asterisk/asterisk-22-current.tar.gz
tar xzf asterisk-22-current.tar.gz
cd asterisk-22.*/
Run the prerequisite installation script to pull in any remaining dependencies specific to your distribution:
contrib/scripts/install_prereq install
The script detects your OS and installs any missing packages automatically. Next, configure the build with PJSIP support (the modern SIP stack that replaces the legacy chan_sip):
./configure --with-jansson-bundled --with-pjproject-bundled
The --with-pjproject-bundled flag builds PJSIP from the version bundled with Asterisk, which avoids library version conflicts with system packages. When the configure script finishes, you should see a summary showing all detected libraries.

Select which modules to build. The menuselect tool lets you enable or disable specific modules, codecs, and applications:
make menuselect.makeopts
menuselect/menuselect --enable CORE-SOUNDS-EN-WAV --enable CORE-SOUNDS-EN-G722 \
  --enable MOH-OPSOUND-WAV --enable MOH-OPSOUND-G722 \
  --enable EXTRA-SOUNDS-EN-WAV --enable EXTRA-SOUNDS-EN-G722 \
  menuselect.makeopts
This enables HD audio prompts (G.722) and music-on-hold files. Now compile Asterisk:
make -j$(nproc)

Compilation takes 10-15 minutes depending on your hardware. The -j$(nproc) flag uses all available CPU cores to speed things up. 

Step 3. Install Asterisk on Ubuntu / Debian

Once compilation finishes without errors, install the binaries, modules, and sample configuration files:

make install
make samples
make config
make install-logrotate

Here is what each target does:

- make install – copies binaries and modules to /usr/sbin/ and /usr/lib/asterisk/
- make samples – installs sample configuration files to /etc/asterisk/
- make config – installs the systemd service unit
- make install-logrotate – sets up log rotation so /var/log/asterisk/ does not fill your disk

Create a dedicated system user for Asterisk. Running as a non-root user is a basic security requirement:

groupadd asterisk
useradd -r -d /var/lib/asterisk -g asterisk asterisk
chown -R asterisk:asterisk /etc/asterisk /var/lib/asterisk /var/log/asterisk /var/spool/asterisk /var/run/asterisk /usr/lib/asterisk

Tell Asterisk to run as this user by editing the main configuration file:

vi /etc/asterisk/asterisk.conf

Find the (options) section and set the run user and group:

[options]
runuser = asterisk
rungroup = asterisk

Step 4. Configure PJSIP for SIP Connectivity

Asterisk 22 uses res_pjsip as its SIP channel driver. The legacy chan_sip module is deprecated and should not be used for new deployments. All SIP configuration goes in pjsip.conf – see the official PJSIP configuration guide for the full reference.

Open the PJSIP configuration file:
vi /etc/asterisk/pjsip.conf
Replace the contents with a clean base configuration. Update external_media_address and external_signaling_address with your server’s public IP:
[global]
type = global
user_agent = Asterisk PBX

; === Transport - UDP on port 5060 ===
[transport-udp]
type = transport
protocol = udp
bind = 0.0.0.0:5060
external_media_address = 192.168.100.100
external_signaling_address = 192.168.100.100
local_net = 192.168.101.0/24
local_net = 10.0.0.0/8

; === Transport - TCP on port 5060 ===
[transport-tcp]
type = transport
protocol = tcp
bind = 0.0.0.0:5060

; === Transport - TLS on port 5061 (production recommended) ===
;[transport-tls]
;type = transport
;protocol = tls
;bind = 0.0.0.0:5061
;cert_file = /etc/asterisk/keys/asterisk.crt
;priv_key_file = /etc/asterisk/keys/asterisk.key
;method = tlsv1_2
The external_media_address and external_signaling_address settings tell Asterisk what IP to advertise in SIP headers when behind NAT. The local_net entries define your private subnets so Asterisk knows when a client is local versus remote. Replace 192.168.100.100 with your actual public IP. The TLS transport is commented out – uncomment it and provide valid certificates for production use.

Step 5. Configure the Dialplan (extensions.conf)

The dialplan controls what happens when a call comes in or an extension is dialed. Open the extensions configuration:
vi /etc/asterisk/extensions.conf
Replace the contents with a basic internal calling dialplan:
[general]
static = yes
writeprotect = no

[globals]

[internal]
; Internal extensions - dial any 3-digit extension (100-199)
exten => _1XX,1,NoOp(Dialing extension ${EXTEN})
 same => n,Dial(PJSIP/${EXTEN},30,tTr)
 same => n,Voicemail(${EXTEN}@default,u)
 same => n,Hangup()

; Voicemail access - dial *97
exten => *97,1,VoiceMailMain(${CALLERID(num)}@default)
 same => n,Hangup()

; Echo test - dial *60 to verify audio path
exten => *60,1,Answer()
 same => n,Echo()
 same => n,Hangup()
This dialplan creates a context called (internal) where any 3-digit extension from 100 to 199 rings for 30 seconds, then sends unanswered calls to voicemail. The *97 extension lets users check voicemail, and *60 provides an echo test for verifying audio works in both directions.

Step 6. Create SIP Endpoints

Each SIP phone or softphone needs an endpoint, authentication, and AOR (Address of Record) entry in pjsip.conf. Add these blocks to the end of your /etc/asterisk/pjsip.conf file for two sample extensions:
vi /etc/asterisk/pjsip.conf
Append the following endpoint definitions:
; === Extension 100 ===
[100]
type = endpoint
context = internal
disallow = all
allow = ulaw
allow = alaw
allow = g722
allow = opus
auth = 100-auth
aors = 100-aor
direct_media = no
rtp_symmetric = yes
force_rport = yes
rewrite_contact = yes

[100-auth]
type = auth
auth_type = userpass
username = 100
password = ChangeMeNow100!

[100-aor]
type = aor
max_contacts = 3
remove_existing = yes
qualify_frequency = 30

; === Extension 101 ===
[101]
type = endpoint
context = internal
disallow = all
allow = ulaw
allow = alaw
allow = g722
allow = opus
auth = 101-auth
aors = 101-aor
direct_media = no
rtp_symmetric = yes
force_rport = yes
rewrite_contact = yes

[101-auth]
type = auth
auth_type = userpass
username = 101
password = ChangeMeNow101!

[101-aor]
type = aor
max_contacts = 3
remove_existing = yes
qualify_frequency = 30
Key settings explained:

  • direct_media = no – forces media through Asterisk, which is essential when clients are behind NAT
  • rtp_symmetric = yes and force_rport = yes – handle NAT traversal for both RTP and SIP signaling
  • rewrite_contact = yes – rewrites the Contact header to the source address, fixing registration behind NAT
  • qualify_frequency = 30 – sends OPTIONS pings every 30 seconds to keep NAT mappings alive and detect offline phones
  • max_contacts = 3 – allows the same extension to register from up to 3 devices simultaneously
Change the passwords to strong unique values before going to production. Never use default or weak passwords on a SIP server – automated scanners constantly probe port 5060.

Step 7. Start and Enable the Asterisk Service
Configure the RTP port range before starting Asterisk. Open the RTP configuration:

vi /etc/asterisk/rtp.conf
Set the port range for media traffic:
[general]
rtpstart = 10000
rtpend = 20000

Now enable and start the Asterisk service:
systemctl enable asterisk
systemctl start asterisk
Verify Asterisk is running and check the version:
systemctl status asterisk
The service should show active (running). You can also check the version from the Asterisk CLI:
asterisk -rx "core show version"
This confirms Asterisk is running and shows the exact build version. To connect to the live Asterisk console for troubleshooting:
asterisk -rvvv
The v flags control verbosity level. Use -rvvvvv for maximum debug output when troubleshooting SIP registration issues.

Step 8. Configure Firewall for Asterisk PBX
Asterisk needs specific ports open for SIP signaling and RTP media. If you are running UFW (the default on Ubuntu), add these rules:
ufw allow 5060/udp comment "SIP signaling"
ufw allow 5060/tcp comment "SIP signaling TCP"
ufw allow 5061/tcp comment "SIP TLS"
ufw allow 10000:20000/udp comment "RTP media"
ufw reload
For Debian systems using nftables or iptables directly:
iptables -A INPUT -p udp --dport 5060 -j ACCEPT
iptables -A INPUT -p tcp --dport 5060 -j ACCEPT
iptables -A INPUT -p tcp --dport 5061 -j ACCEPT
iptables -A INPUT -p udp --dport 10000:20000 -j ACCEPT
iptables-save > /etc/iptables/rules.v4
Verify the ports are listening:
ss -ulnp | grep asterisk
You should see Asterisk listening on port 5060 for both UDP and TCP.

Production hardening suggestion: Do not expose SIP port 5060 to the entire internet. Use firewall rules to restrict access to known SIP trunk provider IP ranges and your office/VPN networks. SIP brute-force attacks are constant and aggressive. Consider using Kamailio as a SIP proxy in front of Asterisk for large deployments that need load balancing and advanced routing.

Step 9. Test with a SIP Client

Register a SIP softphone to verify the setup works. Popular free SIP clients include Linphone (Linux/Windows/Mac/mobile), MicroSIP (Windows), and Onaip (Android/iOS).

Configure the softphone with these settings:

- SIP Server / Domain: your server’s IP address or hostname
- Username: 100
- Password: ChangeMeNow100! (or whatever you set in pjsip.conf)
- Transport: UDP
- Port: 5060    

After registering, check the registration status from the Asterisk console:

asterisk -rx "pjsip show endpoints"

You should see your registered endpoint with status “Avail” (available). To verify audio, dial *60 from the softphone – this runs the echo test. Everything you say should echo back to you after a short delay.

If registration fails, check the Asterisk log for details:

tail -50 /var/log/asterisk/messages

Common registration issues include wrong passwords, firewall blocking port 5060, or NAT settings misconfigured in the transport section. Make sure external_signaling_address in pjsip.conf matches your server’s actual public IP.

To test internal calling, register a second softphone as extension 101 and dial 100 from it. The phone on extension 100 should ring for 30 seconds as defined in the dialplan.

Step 10. Install FreePBX Web GUI (Optional)

If you prefer managing Asterisk through a web interface instead of config files, FreePBX provides a full-featured GUI on top of Asterisk. It handles extensions, trunks, IVR menus, ring groups, and call recording through a browser.

Install the web server and PHP dependencies FreePBX needs:

apt install -y apache2 mariadb-server mariadb-client \
  php php-cli php-mysql php-gd php-curl php-mbstring \
  php-xml php-zip php-bcmath php-intl \
  nodejs npm
Enable and start the database and web server:
systemctl enable --now mariadb apache2
Download and install the latest FreePBX release:
cd /usr/src
wget https://github.com/FreePBX/framework/archive/refs/heads/release/17.0.zip -O freepbx-17.zip
unzip freepbx-17.zip
cd framework-release-17.0
./install -n --dbuser=root

After installation completes, open http://your-server-ip/admin in a browser to access the FreePBX dashboard. Set an admin password on first login.

If you only need a web GUI for basic PBX management, FreePBX is the standard choice. For advanced setups that integrate with XMPP chat servers or require custom AGI scripting, working directly with Asterisk config files gives you more control.

Closure:

Your Asterisk 22 LTS is now operational on Ubuntu 24.04 or Debian 13. With the core framework in place, you can now transition from a basic setup to a production-ready communication system.

Key Expansion Options:

- Feature Richness: Integrate SIP trunks from your ITSP (like the AWS SIP stack), configure IVRs, voicemail-to-email, and call recording.

- Security & Encryption: For production, TLS/SRTP is essential for encrypting both signaling and voice media.

- Proactive Defense: Implement Fail2Ban to automatically block SIP brute-force attempts.

- Monitoring & Maintenance: Use AMI (Asterisk Manager Interface) or SNMP for real-time monitoring, and ensure regular database backups are scheduled.