Naemon is a fork of Nagios with improved performance and additional features. It is a monitoring solution with privileged visibility into infrastructure and command execution capabilities. Proper security hardening is essential to protect the monitoring system and prevent unauthorized access. This guide covers security measures for production Naemon deployments.
Naemon architecture includes these security-sensitive components:
Key security concerns include web interface protection, plugin execution security, remote command execution, Livestatus access, and credential management.
Configure firewall rules for Naemon:
# Naemon Web Interface (Apache/Nginx)
ufw allow from 10.0.0.0/8 to any port 80 proto tcp
ufw allow from 10.0.0.0/8 to any port 443 proto tcp
# NRPE Agent
ufw allow from 10.0.1.0/24 to any port 5666 proto tcp
# Livestatus (if exposed)
ufw allow from 127.0.0.1 to any port 6557 proto tcp
# Block external access
ufw deny from any to any port 5666 proto tcp
ufw deny from any to any port 6557 proto tcp
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: naemon-network-policy
spec:
podSelector:
matchLabels:
app: naemon
ingress:
- from:
- namespaceSelector:
matchLabels:
name: monitoring
ports:
- protocol: TCP
port: 80
- protocol: TCP
port: 443
- protocol: TCP
port: 5666
Configure web server binding:
# /etc/apache2/sites-available/naemon.conf
<VirtualHost 10.0.1.100:443>
ServerName naemon.company.com
DocumentRoot /usr/share/naemon/html
SSLEngine on
SSLCertificateFile /etc/ssl/certs/naemon.crt
SSLCertificateKeyFile /etc/ssl/private/naemon.key
<Directory /usr/share/naemon/html>
Require ip 10.0.0.0/8 192.168.0.0/16
Options None
AllowOverride None
</Directory>
</VirtualHost>
Configure Livestatus binding:
# /etc/naemon/modules/livestatus.cfg
load module=/usr/lib/naemon/livestatus.so
livestatus_socket=tcp:127.0.0.1:6557
Configure HTTP authentication:
# /etc/apache2/conf-available/naemon.conf
<Directory /usr/share/naemon/html>
AuthType Basic
AuthName "Naemon Access"
AuthUserFile /etc/naemon/htpasswd
Require valid-user
Require ip 10.0.0.0/8
</Directory>
Manage users:
# Create admin user
htpasswd -c /etc/naemon/htpasswd naemonadmin
# Add additional users
htpasswd /etc/naemon/htpasswd username
If using Thruk web interface:
# /etc/thruk/thruk.conf
auth_type = "Apache"
auth_realm = "Naemon Monitoring"
auth_cookie_name = "thruk_auth"
auth_cookie_key = "${COOKIE_KEY}"
# Session settings
session_timeout = 3600
Configure Thruk roles:
# /etc/thruk/thruk.conf
# Role definitions
roles = {
'admin' => {
'master' => 1,
},
'operator' => {
'read' => 1,
'write' => ['ack', 'downtime', 'schedule_check'],
},
'viewer' => {
'read' => 1,
},
}
# User mappings
users = {
'admin' => ['admin', 'ops-lead'],
'operator' => ['operator1', 'operator2'],
'viewer' => ['viewer1', 'viewer2'],
}
Configure notification contacts:
# /etc/naemon/objects/contacts.cfg
define contact {
contact_name admin
alias System Administrator
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-service-by-email
host_notification_commands notify-host-by-email
email admin@company.com
}
define contactgroup {
contactgroup_name admins
alias Naemon Administrators
members admin,ops-lead
}
Configure external authentication:
mod_auth_openidc:
LoadModule auth_openidc_module modules/mod_auth_openidc.so
OIDCProviderMetadataURL https://sso.company.com/.well-known/openid-configuration
OIDCClientID naemon
OIDCClientSecret ${OIDC_CLIENT_SECRET}
OIDCRedirectURI https://naemon.company.com/redirect_uri
<Location /naemon>
AuthType openid-connect
Require valid-user
</Location>
Configure HTTPS:
# /etc/apache2/sites-available/naemon-ssl.conf
<VirtualHost *:443>
ServerName naemon.company.com
DocumentRoot /usr/share/naemon/html
SSLEngine on
SSLCertificateFile /etc/ssl/certs/naemon.crt
SSLCertificateKeyFile /etc/ssl/private/naemon.key
SSLCertificateChainFile /etc/ssl/certs/ca-bundle.crt
SSLProtocol all -SSLv2 -SSLv3 -TLSv1 -TLSv1.1
SSLCipherSuite ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256
SSLHonorCipherOrder on
# Security headers
Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains"
Header always set X-Frame-Options "SAMEORIGIN"
Header always set X-Content-Type-Options "nosniff"
Header always set X-XSS-Protection "1; mode=block"
<Directory /usr/share/naemon/html>
Options None
AllowOverride None
Require valid-user
</Directory>
</VirtualHost>
Enable TLS for NRPE:
# /etc/naemon/nrpe.cfg
ssl_enabled=1
ssl_cert=/etc/naemon/ssl/nrpe.crt
ssl_key=/etc/naemon/ssl/nrpe.key
ssl_ca_cert=/etc/naemon/ssl/ca.crt
ssl_cipher_list="ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256"
ssl_legacy_options=0
ssl_client_cert_verify=1
Secure Livestatus connections:
# /etc/naemon/modules/livestatus.cfg
load module=/usr/lib/naemon/livestatus.so
livestatus_socket=ssl:127.0.0.1:6557
livestatus_ssl_cert=/etc/naemon/ssl/livestatus.crt
livestatus_ssl_key=/etc/naemon/ssl/livestatus.key
livestatus_ssl_ca_cert=/etc/naemon/ssl/ca.crt
Secure CGI access:
# /etc/naemon/cgi.cfg
use_authentication=1
default_user_name=naemonviewer
authorized_for_system_information=admin,ops-lead
authorized_for_configuration_information=admin
authorized_for_system_commands=admin
authorized_for_all_services=admin,ops-lead
authorized_for_all_hosts=admin,ops-lead
authorized_for_all_service_commands=admin
authorized_for_all_host_commands=admin
Restrict plugin execution:
# /etc/naemon/resource.cfg
# Only allow specific plugin directories
$USER1$=/usr/lib/naemon/plugins
$USER2$=/usr/local/lib/naemon/plugins
# Never store passwords in resource.cfg
# Use environment variables or secret management
Secure plugin permissions:
# Set restrictive permissions on plugins
chown root:naemon /usr/lib/naemon/plugins/*
chmod 750 /usr/lib/naemon/plugins/*
# Special handling for sensitive plugins
chown root:root /usr/lib/naemon/plugins/check_mysql
chmod 700 /usr/lib/naemon/plugins/check_mysql
Secure external commands:
# /etc/naemon/naemon.cfg
# Enable external commands
check_external_commands=1
command_check_interval=15s
command_file=/var/cache/naemon/rw/naemon.cmd
# Secure command file
# chown naemon:www-data /var/cache/naemon/rw/naemon.cmd
# chmod 660 /var/cache/naemon/rw/naemon.cmd
Secure Livestatus queries:
# /etc/naemon/modules/livestatus.cfg
# Restrict access
livestatus_allowed_clients=127.0.0.1,10.0.1.0/24
# Enable authentication
livestatus_auth_required=1
Protect Naemon configuration:
# Set restrictive permissions
chown -R naemon:naemon /etc/naemon/
chmod -R 750 /etc/naemon/
# Protect sensitive files
chmod 600 /etc/naemon/objects/contacts.cfg
chmod 600 /etc/naemon/resource.cfg
Never store plaintext credentials:
# Bad - Never do this
# define command {
# command_name check_mysql
# command_line $USER1$/check_mysql -u root -pPassword123
# }
# Good - Use environment variables
define command {
command_name check_mysql
command_line /usr/local/bin/check_mysql_secure.sh $ARG1$
}
Secure wrapper script:
#!/bin/bash
# /usr/local/bin/check_mysql_secure.sh
MYSQL_PASSWORD=$(cat /etc/naemon/.mysql_password | gpg -d)
exec /usr/lib/naemon/plugins/check_mysql -u "$1" -p "$MYSQL_PASSWORD"
Secure Naemon backups:
#!/bin/bash
# Secure backup script
BACKUP_DIR="/secure/backups/naemon"
DATE=$(date +%Y%m%d)
tar -czf ${BACKUP_DIR}/naemon-config-${DATE}.tar.gz \
/etc/naemon/ \
/var/lib/naemon/
# Encrypt backup
gpg -e --recipient security@company.com ${BACKUP_DIR}/naemon-config-${DATE}.tar.gz
# Set restrictive permissions
chmod 600 ${BACKUP_DIR}/naemon-config-${DATE}.tar.gz.gpg
# Remove unencrypted backup
rm ${BACKUP_DIR}/naemon-config-${DATE}.tar.gz
Enable logging:
# /etc/naemon/naemon.cfg
log_file=/var/log/naemon/naemon.log
debug_level=63
debug_verbosity=2
debug_file=/var/log/naemon/naemon.debug
# Log rotation
log_rotation_method=d
log_archive_path=/var/log/naemon/archives
Configure web server access logging:
# /etc/apache2/sites-available/naemon.conf
CustomLog /var/log/apache2/naemon_access.log combined
ErrorLog /var/log/apache2/naemon_error.log
Create Naemon alerts for security events:
# /etc/naemon/objects/security.cfg
define service {
host_name naemon-server
service_description Failed Login Attempts
check_command check_log!5!/var/log/apache2/naemon_access.log!"authentication failure"
max_check_attempts 3
check_interval 5
notification_interval 30
notification_period 24x7
contacts security-team
}
define service {
host_name naemon-server
service_description Configuration Changes
check_command check_file_age!/etc/naemon/naemon.cfg!3600!7200
contacts ops-team
}
Forward logs to SIEM:
# /etc/rsyslog.d/naemon.conf
:programname, isequal, "naemon" /var/log/naemon/syslog.log
:programname, isequal, "naemon" @siem.company.com:514