Secure your Nagios monitoring with SSL certificates, advanced authentication, and comprehensive access controls. This guide covers Let's Encrypt integration, web interface hardening, and security monitoring setup.
Prerequisites
- Working Nagios Core 4.5 installation
- Domain name pointing to server
- Root or sudo access
- Apache web server installed
What this solves
Nagios Core provides powerful monitoring capabilities, but its default configuration lacks essential security features. This tutorial secures your Nagios installation with SSL encryption, hardens authentication mechanisms, implements granular access controls, and sets up comprehensive security logging. You'll protect sensitive monitoring data and ensure only authorized users can access your infrastructure insights.
Prerequisites
Before starting, ensure you have a working Nagios Core 4.5 installation. If you need to set up distributed monitoring, check out our guide on setting up Nagios Core distributed monitoring with NRPE. You'll also need a domain name pointing to your server for SSL certificate generation.
Step-by-step configuration
Install required packages
Install the packages needed for SSL certificates and security hardening.
sudo apt update
sudo apt install -y certbot python3-certbot-apache apache2-utils opensslConfigure Apache virtual host for SSL
Create a proper virtual host configuration to support SSL certificates.
ServerName nagios.example.com
DocumentRoot /usr/local/nagios/share
Redirect permanent / https://nagios.example.com/
ServerName nagios.example.com
DocumentRoot /usr/local/nagios/share
# SSL Configuration
SSLEngine on
SSLProtocol all -SSLv2 -SSLv3 -TLSv1 -TLSv1.1
SSLCipherSuite ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384
SSLHonorCipherOrder off
SSLSessionTickets off
# Security Headers
Header always set Strict-Transport-Security "max-age=63072000; includeSubDomains; preload"
Header always set X-Content-Type-Options nosniff
Header always set X-Frame-Options DENY
Header always set X-XSS-Protection "1; mode=block"
Header always set Referrer-Policy "strict-origin-when-cross-origin"
Header always set Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline'; img-src 'self' data:;"
# Nagios Configuration
ScriptAlias /nagios/cgi-bin "/usr/local/nagios/sbin"
Alias /nagios "/usr/local/nagios/share"
Options ExecCGI
AllowOverride None
Require valid-user
AuthType Basic
AuthName "Nagios Access"
AuthUserFile /usr/local/nagios/etc/htpasswd.users
Options None
AllowOverride None
Require valid-user
AuthType Basic
AuthName "Nagios Access"
AuthUserFile /usr/local/nagios/etc/htpasswd.users
Obtain SSL certificate with Let's Encrypt
Use Certbot to automatically obtain and configure SSL certificates.
sudo a2ensite nagios-ssl.conf
sudo a2enmod ssl headers rewrite
sudo systemctl reload apache2
Obtain SSL certificate
sudo certbot --apache -d nagios.example.com --non-interactive --agree-tos --email admin@example.com
Verify certificate installation
sudo certbot certificatesCreate secure user authentication
Set up user accounts with strong password requirements and role-based access.
# Create htpasswd file with strong encryption
sudo mkdir -p /usr/local/nagios/etc
sudo htpasswd -c -B /usr/local/nagios/etc/htpasswd.users nagiosadmin
Add additional users with different privilege levels
sudo htpasswd -B /usr/local/nagios/etc/htpasswd.users monitor-user
sudo htpasswd -B /usr/local/nagios/etc/htpasswd.users readonly-userConfigure user authorization and access controls
Define user permissions and access levels in Nagios configuration.
# Admin users (full access)
authorized_for_system_information=nagiosadmin
authorized_for_configuration_information=nagiosadmin
authorized_for_system_commands=nagiosadmin
authorized_for_all_services=nagiosadmin
authorized_for_all_hosts=nagiosadmin
authorized_for_all_service_commands=nagiosadmin
authorized_for_all_host_commands=nagiosadmin
Monitor users (read/write to services and hosts)
authorized_for_all_services=nagiosadmin,monitor-user
authorized_for_all_hosts=nagiosadmin,monitor-user
authorized_for_all_service_commands=nagiosadmin,monitor-user
authorized_for_all_host_commands=nagiosadmin,monitor-user
Read-only users (view only)
authorized_for_read_only=readonly-user
Security settings
use_authentication=1
use_ssl_authentication=0
default_user_name=
escape_html_tags=1
action_url_target=_blank
notes_url_target=_blank
lock_author_names=1
Disable potentially dangerous features for non-admin users
authorized_for_system_commands=nagiosadmin
authorized_for_configuration_information=nagiosadminHarden Nagios configuration files
Secure file permissions and disable unnecessary features.
# Set secure file permissions
sudo chown -R nagios:nagios /usr/local/nagios/etc/
sudo chmod 750 /usr/local/nagios/etc/
sudo chmod 640 /usr/local/nagios/etc/*.cfg
sudo chmod 600 /usr/local/nagios/etc/htpasswd.users
Secure log directories
sudo chown -R nagios:nagios /usr/local/nagios/var/
sudo chmod 755 /usr/local/nagios/var/
sudo chmod 644 /usr/local/nagios/var/*.logConfigure security logging and monitoring
Enable comprehensive logging for security events and access attempts.
# Enable detailed logging
log_file=/usr/local/nagios/var/nagios.log
log_rotation_method=d
log_archive_path=/usr/local/nagios/var/archives
use_syslog=1
log_notifications=1
log_service_retries=1
log_host_retries=1
log_event_handlers=1
log_initial_states=1
log_external_commands=1
log_passive_checks=1
Security-specific logging
enable_event_handlers=1
process_performance_data=1
retain_state_information=1
state_retention_file=/usr/local/nagios/var/retention.dat
Command logging for audit trail
command_check_interval=15s
command_file=/usr/local/nagios/var/rw/nagios.cmdSet up log rotation and monitoring
Configure automatic log rotation and monitoring of security events.
/usr/local/nagios/var/nagios.log {
daily
missingok
rotate 52
compress
delaycompress
notifempty
create 644 nagios nagios
postrotate
/bin/kill -HUP cat /usr/local/nagios/var/nagios.lock 2>/dev/null 2>/dev/null || true
endscript
}
/usr/local/nagios/var/archives/*.log {
monthly
missingok
rotate 12
compress
delaycompress
notifempty
create 644 nagios nagios
}Configure Apache security logging
Enable detailed Apache access and error logging for security monitoring.
# Add these lines inside the VirtualHost block
LogLevel info ssl:warn
ErrorLog ${APACHE_LOG_DIR}/nagios_error.log
CustomLog ${APACHE_LOG_DIR}/nagios_access.log combined
Additional security logging
LogFormat "%h %l %u %t \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\" %{SSL_PROTOCOL}x %{SSL_CIPHER}x" ssl_combined
CustomLog ${APACHE_LOG_DIR}/nagios_ssl.log ssl_combinedSet up automated certificate renewal
Configure automatic SSL certificate renewal to maintain security.
# Test certificate renewal
sudo certbot renew --dry-run
Create renewal hook script
sudo tee /etc/letsencrypt/renewal-hooks/post/reload-apache.sh << 'EOF'
#!/bin/bash
systemctl reload apache2
EOF
sudo chmod +x /etc/letsencrypt/renewal-hooks/post/reload-apache.sh
Verify cron job for auto-renewal
sudo systemctl status certbot.timer
sudo systemctl enable certbot.timerConfigure firewall rules
Restrict access to Nagios and ensure only necessary ports are open.
# Using UFW
sudo ufw allow 22/tcp comment 'SSH'
sudo ufw allow 80/tcp comment 'HTTP redirect'
sudo ufw allow 443/tcp comment 'HTTPS Nagios'
sudo ufw allow 5666/tcp comment 'NRPE'
sudo ufw --force enable
sudo ufw status numberedRestart and verify services
Restart all services and verify the secure configuration is working.
# Validate Nagios configuration
sudo /usr/local/nagios/bin/nagios -v /usr/local/nagios/etc/nagios.cfg
Restart services
sudo systemctl restart nagios
sudo systemctl restart apache2
Verify services are running
sudo systemctl status nagios
sudo systemctl status apache2
Check SSL configuration
sudo apache2ctl -SVerify your setup
Test your secure Nagios installation to ensure all security features are working correctly.
# Test SSL certificate
curl -I https://nagios.example.com/nagios/
Test HTTP to HTTPS redirect
curl -I http://nagios.example.com/nagios/
Check SSL security rating
ssl-cert-check -c /etc/letsencrypt/live/nagios.example.com/cert.pem
Verify authentication is working
curl -k -u nagiosadmin:yourpassword https://nagios.example.com/nagios/
Check log file permissions
ls -la /usr/local/nagios/var/
ls -la /usr/local/nagios/etc/Access your Nagios web interface at https://nagios.example.com/nagios/ and verify that:
- HTTP automatically redirects to HTTPS
- SSL certificate is valid and trusted
- Authentication prompt appears
- Different users have appropriate access levels
- Security headers are present in browser developer tools
Security monitoring and alerting
Configure security event monitoring
Set up monitoring for authentication failures and security events.
# Security monitoring service definitions
define service {
use generic-service
host_name localhost
service_description SSH Failed Logins
check_command check_ssh_failed_logins
check_interval 5
notification_interval 30
}
define service {
use generic-service
host_name localhost
service_description Apache Security Events
check_command check_apache_security
check_interval 5
notification_interval 30
}
define service {
use generic-service
host_name localhost
service_description SSL Certificate Expiry
check_command check_ssl_cert!nagios.example.com!443!30!7
check_interval 60
notification_interval 1440
}Create custom security check commands
Define commands to monitor security-related events and certificate status.
# Add these commands to your existing commands.cfg file
Check for SSH failed login attempts
define command {
command_name check_ssh_failed_logins
command_line /usr/local/nagios/libexec/check_log -F /var/log/auth.log -O /tmp/ssh_failed.tmp -q "Failed password"
}
Check Apache security events
define command {
command_name check_apache_security
command_line /usr/local/nagios/libexec/check_log -F /var/log/apache2/nagios_error.log -O /tmp/apache_security.tmp -q "error"
}
Check SSL certificate expiration
define command {
command_name check_ssl_cert
command_line /usr/local/nagios/libexec/check_http -H $ARG1$ -p $ARG2$ -S --certificate=$ARG3$,$ARG4$
}For more comprehensive monitoring options, consider our guide on optimizing systemd journal logging to improve log management performance.
Common issues
| Symptom | Cause | Fix |
|---|---|---|
| SSL certificate not trusted | Certificate chain incomplete | sudo certbot renew --force-renewal |
| 403 Forbidden error | Incorrect file permissions | sudo chown -R nagios:nagios /usr/local/nagios/share/ and chmod 755 |
| Authentication not working | htpasswd file permissions | sudo chmod 640 /usr/local/nagios/etc/htpasswd.users |
| HTTP not redirecting to HTTPS | Redirect directive missing | Add Redirect permanent to virtual host |
| CGI scripts not executing | Apache modules not enabled | sudo a2enmod cgi ssl headers |
| Users can't access certain features | Authorization not configured | Check authorized_for_* settings in cgi.cfg |
Advanced security hardening
For additional security measures, consider implementing these advanced configurations:
- Configure SELinux or AppArmor policies for enhanced access control
- Set up fail2ban integration to block suspicious access attempts
- Implement two-factor authentication for critical users
- Configure network segmentation to isolate monitoring traffic
- Set up centralized logging with secure remote syslog
For comprehensive network security policies, refer to our guide on configuring SELinux mandatory access controls.
Next steps
- Configure SNMP monitoring for network devices
- Set up Nagios high availability cluster with failover
- Integrate Nagios with Elasticsearch for advanced log analysis
- Configure mobile notifications with Pushover integration
Running this in production?
Automated install script
Run this to automate the entire setup
#!/usr/bin/env bash
set -euo pipefail
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m'
# Default values
DOMAIN=""
EMAIL=""
NAGIOS_USER="nagiosadmin"
# Print usage
usage() {
echo "Usage: $0 -d <domain> -e <email> [-u <nagios_user>]"
echo " -d: Domain name for SSL certificate (e.g., nagios.example.com)"
echo " -e: Email address for Let's Encrypt"
echo " -u: Nagios admin username (default: nagiosadmin)"
exit 1
}
# Parse arguments
while getopts "d:e:u:h" opt; do
case $opt in
d) DOMAIN="$OPTARG" ;;
e) EMAIL="$OPTARG" ;;
u) NAGIOS_USER="$OPTARG" ;;
h) usage ;;
*) usage ;;
esac
done
if [[ -z "$DOMAIN" || -z "$EMAIL" ]]; then
usage
fi
# Check if running as root or with sudo
if [[ $EUID -ne 0 ]]; then
echo -e "${RED}Error: This script must be run as root or with sudo${NC}"
exit 1
fi
# Detect distribution
if [[ ! -f /etc/os-release ]]; then
echo -e "${RED}Error: Cannot detect distribution${NC}"
exit 1
fi
. /etc/os-release
case "$ID" in
ubuntu|debian)
PKG_MGR="apt"
PKG_UPDATE="apt update"
PKG_INSTALL="apt install -y"
WEB_SERVICE="apache2"
WEB_CONFIG_DIR="/etc/apache2/sites-available"
WEB_ENABLE_CMD="a2ensite"
WEB_MODULES_CMD="a2enmod"
PACKAGES="certbot python3-certbot-apache apache2-utils openssl"
;;
almalinux|rocky|centos|rhel|ol|fedora)
PKG_MGR="dnf"
PKG_UPDATE="dnf update -y"
PKG_INSTALL="dnf install -y"
WEB_SERVICE="httpd"
WEB_CONFIG_DIR="/etc/httpd/conf.d"
WEB_ENABLE_CMD=""
WEB_MODULES_CMD=""
PACKAGES="certbot python3-certbot-apache httpd-tools openssl mod_ssl"
;;
amzn)
PKG_MGR="yum"
PKG_UPDATE="yum update -y"
PKG_INSTALL="yum install -y"
WEB_SERVICE="httpd"
WEB_CONFIG_DIR="/etc/httpd/conf.d"
WEB_ENABLE_CMD=""
WEB_MODULES_CMD=""
PACKAGES="certbot python3-certbot-apache httpd-tools openssl mod_ssl"
;;
*)
echo -e "${RED}Error: Unsupported distribution: $ID${NC}"
exit 1
;;
esac
# Cleanup function
cleanup() {
echo -e "${YELLOW}Cleaning up on error...${NC}"
systemctl reload $WEB_SERVICE 2>/dev/null || true
}
trap cleanup ERR
echo -e "${GREEN}Starting Nagios Core 4.5 SSL and Security Hardening${NC}"
# Check prerequisites
echo -e "${YELLOW}[1/8] Checking prerequisites...${NC}"
if [[ ! -d /usr/local/nagios ]]; then
echo -e "${RED}Error: Nagios Core installation not found at /usr/local/nagios${NC}"
exit 1
fi
if ! systemctl is-active --quiet $WEB_SERVICE; then
echo -e "${RED}Error: $WEB_SERVICE is not running${NC}"
exit 1
fi
# Install required packages
echo -e "${YELLOW}[2/8] Installing required packages...${NC}"
$PKG_UPDATE
$PKG_INSTALL $PACKAGES
# Create virtual host configuration
echo -e "${YELLOW}[3/8] Creating Apache virtual host configuration...${NC}"
if [[ "$ID" == "ubuntu" || "$ID" == "debian" ]]; then
VHOST_FILE="$WEB_CONFIG_DIR/nagios-ssl.conf"
else
VHOST_FILE="$WEB_CONFIG_DIR/nagios-ssl.conf"
fi
cat > "$VHOST_FILE" << EOF
<VirtualHost *:80>
ServerName $DOMAIN
DocumentRoot /usr/local/nagios/share
Redirect permanent / https://$DOMAIN/
</VirtualHost>
<VirtualHost *:443>
ServerName $DOMAIN
DocumentRoot /usr/local/nagios/share
# SSL Configuration
SSLEngine on
SSLProtocol all -SSLv2 -SSLv3 -TLSv1 -TLSv1.1
SSLCipherSuite ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384
SSLHonorCipherOrder off
SSLSessionTickets off
# Security Headers
Header always set Strict-Transport-Security "max-age=63072000; includeSubDomains; preload"
Header always set X-Content-Type-Options nosniff
Header always set X-Frame-Options DENY
Header always set X-XSS-Protection "1; mode=block"
Header always set Referrer-Policy "strict-origin-when-cross-origin"
Header always set Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline'; img-src 'self' data:;"
# Nagios Configuration
ScriptAlias /nagios/cgi-bin "/usr/local/nagios/sbin"
Alias /nagios "/usr/local/nagios/share"
<Directory "/usr/local/nagios/sbin">
Options ExecCGI
AllowOverride None
Require valid-user
AuthType Basic
AuthName "Nagios Access"
AuthUserFile /usr/local/nagios/etc/htpasswd.users
</Directory>
<Directory "/usr/local/nagios/share">
Options None
AllowOverride None
Require valid-user
AuthType Basic
AuthName "Nagios Access"
AuthUserFile /usr/local/nagios/etc/htpasswd.users
</Directory>
</VirtualHost>
EOF
chown root:root "$VHOST_FILE"
chmod 644 "$VHOST_FILE"
# Enable Apache modules and site
echo -e "${YELLOW}[4/8] Enabling Apache modules and configuration...${NC}"
if [[ "$ID" == "ubuntu" || "$ID" == "debian" ]]; then
$WEB_MODULES_CMD ssl headers rewrite
$WEB_ENABLE_CMD nagios-ssl.conf
fi
systemctl reload $WEB_SERVICE
# Obtain SSL certificate
echo -e "${YELLOW}[5/8] Obtaining SSL certificate...${NC}"
certbot --apache -d "$DOMAIN" --non-interactive --agree-tos --email "$EMAIL"
# Create secure user authentication
echo -e "${YELLOW}[6/8] Creating secure user authentication...${NC}"
mkdir -p /usr/local/nagios/etc
chown nagios:nagcmd /usr/local/nagios/etc
chmod 755 /usr/local/nagios/etc
echo -e "${GREEN}Creating admin user: $NAGIOS_USER${NC}"
echo -e "${YELLOW}Please enter a strong password (12+ characters with mixed case, numbers, symbols):${NC}"
htpasswd -c -B /usr/local/nagios/etc/htpasswd.users "$NAGIOS_USER"
chown nagios:nagcmd /usr/local/nagios/etc/htpasswd.users
chmod 640 /usr/local/nagios/etc/htpasswd.users
# Configure user authorization
echo -e "${YELLOW}[7/8] Configuring user authorization...${NC}"
CGI_CONFIG="/usr/local/nagios/etc/cgi.cfg"
if [[ -f "$CGI_CONFIG" ]]; then
# Backup original config
cp "$CGI_CONFIG" "$CGI_CONFIG.backup"
# Update authorization settings
sed -i "s/authorized_for_system_information=.*/authorized_for_system_information=$NAGIOS_USER/" "$CGI_CONFIG"
sed -i "s/authorized_for_configuration_information=.*/authorized_for_configuration_information=$NAGIOS_USER/" "$CGI_CONFIG"
sed -i "s/authorized_for_system_commands=.*/authorized_for_system_commands=$NAGIOS_USER/" "$CGI_CONFIG"
sed -i "s/authorized_for_all_services=.*/authorized_for_all_services=$NAGIOS_USER/" "$CGI_CONFIG"
sed -i "s/authorized_for_all_hosts=.*/authorized_for_all_hosts=$NAGIOS_USER/" "$CGI_CONFIG"
sed -i "s/authorized_for_all_service_commands=.*/authorized_for_all_service_commands=$NAGIOS_USER/" "$CGI_CONFIG"
sed -i "s/authorized_for_all_host_commands=.*/authorized_for_all_host_commands=$NAGIOS_USER/" "$CGI_CONFIG"
fi
# Configure firewall
if command -v ufw >/dev/null 2>&1; then
ufw allow 443/tcp
ufw allow 80/tcp
elif command -v firewall-cmd >/dev/null 2>&1; then
firewall-cmd --permanent --add-service=https
firewall-cmd --permanent --add-service=http
firewall-cmd --reload
fi
# Restart services
systemctl restart nagios
systemctl restart $WEB_SERVICE
# Verification
echo -e "${YELLOW}[8/8] Performing verification checks...${NC}"
# Check SSL certificate
if certbot certificates | grep -q "$DOMAIN"; then
echo -e "${GREEN}✓ SSL certificate installed successfully${NC}"
else
echo -e "${RED}✗ SSL certificate verification failed${NC}"
exit 1
fi
# Check services
if systemctl is-active --quiet nagios; then
echo -e "${GREEN}✓ Nagios service is running${NC}"
else
echo -e "${RED}✗ Nagios service is not running${NC}"
exit 1
fi
if systemctl is-active --quiet $WEB_SERVICE; then
echo -e "${GREEN}✓ $WEB_SERVICE service is running${NC}"
else
echo -e "${RED}✗ $WEB_SERVICE service is not running${NC}"
exit 1
fi
# Check configuration files
if [[ -f /usr/local/nagios/etc/htpasswd.users ]]; then
echo -e "${GREEN}✓ User authentication file created${NC}"
else
echo -e "${RED}✗ User authentication file missing${NC}"
exit 1
fi
echo -e "${GREEN}Nagios Core SSL and security hardening completed successfully!${NC}"
echo -e "${GREEN}Access your secure Nagios installation at: https://$DOMAIN/nagios${NC}"
echo -e "${YELLOW}Certificate will auto-renew. Check status with: certbot certificates${NC}"
Review the script before running. Execute with: bash install.sh