Installation du serveur

L’interface web de Nagios a besoin pour fonctionner d’un serveur web supportant PHP. Nous allons donc l’installer en premier.

Apache/PHP

Installation

pacman -S apache php php-apache

Configuration

Apache

On va modifier le fichier de configuration principal d’Apache, /etc/httpd/conf/httpd.conf. Il contiendra ceci :

ServerRoot "/etc/httpd"

Listen 80

LoadModule authz_host_module modules/mod_authz_host.so
LoadModule include_module modules/mod_include.so
LoadModule negotiation_module modules/mod_negotiation.so
LoadModule alias_module modules/mod_alias.so
LoadModule mime_module modules/mod_mime.so
LoadModule ssl_module modules/mod_ssl.so
LoadModule log_config_module modules/mod_log_config.so
LoadModule setenvif_module modules/mod_setenvif.so
LoadModule dir_module modules/mod_dir.so
LoadModule authn_file_module modules/mod_authn_file.so
LoadModule auth_basic_module modules/mod_auth_basic.so
LoadModule authz_user_module modules/mod_authz_user.so
LoadModule cgi_module modules/mod_cgi.so
LoadModule php5_module modules/libphp5.so

<IfModule !mpm_netware_module>
<IfModule !mpm_winnt_module>
User http
Group http
</IfModule>
</IfModule>

ServerAdmin root@nagios.arda

DocumentRoot "/srv/http"

<Directory "/srv/http">
    Options FollowSymLinks
    AllowOverride None
    Order allow,deny
    Allow from all
</Directory>

<Directory />
    Options FollowSymLinks
    AllowOverride None
    Order deny,allow
    Deny from all
</Directory>

<FilesMatch "^\.ht">
    Order allow,deny
    Deny from all
    Satisfy All
</FilesMatch>

ErrorLog "/var/log/httpd/error_log"
LogLevel warn

<IfModule log_config_module>
    LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined
    LogFormat "%h %l %u %t \"%r\" %>s %b" common
    <IfModule logio_module>
      LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" %I %O" combinedio
    </IfModule>
    CustomLog "/var/log/httpd/access_log" common
</IfModule>

<IfModule alias_module>
    ScriptAlias /cgi-bin/ "/srv/http/cgi-bin/"
</IfModule>

<Directory "/srv/http/cgi-bin">
    AllowOverride None
    Options None
    Order allow,deny
    Allow from all
    AddHandler cgi-script .cgi
</Directory>

DefaultType text/plain

<IfModule mime_module>
    TypesConfig conf/mime.types
    AddType application/x-compress .Z
    AddType application/x-gzip .gz .tgz
</IfModule>

Include conf/extra/httpd-multilang-errordoc.conf
Include conf/extra/httpd-languages.conf
Include conf/extra/httpd-default.conf
Include conf/extra/httpd-ssl.conf
Include conf/extra/php5_module.conf
Include conf/extra/nagios.conf

<IfModule ssl_module>
SSLRandomSeed startup builtin
SSLRandomSeed connect builtin
</IfModule>
HTTPS

Il est recommandé de chiffrer la connexion d’accès à Nagios ou au moins l’authentification. On va donc activer HTTPS. On se place dans le dossier /etc/httpd/conf et on exécute ces commandes :

openssl genrsa -des3 -out server.key 1024
openssl req -new -key server.key -out server.csr
cp server.key server.key.org
openssl rsa -in server.key.org -out server.key
openssl x509 -req -days 3650 -in server.csr -signkey server.key -out server.crt
PHP

On édite le /etc/php/php.ini. Il faut modifier l’option open_basedir de manière à y ajouter :/usr/share/nagios. Elle devrait ressembler à ça :

open_basedir = /srv/http/:/home/:/tmp/:/usr/share/pear/:/usr/share/nagios

Ensuite, on décommente la ligne ;extension=gd.so pour activer l’extension GD.

Nagios

Installation

On installe deux paquets depuis AUR, en utilisant par exemple yaourt.

yaourt -S nagios nagios-plugins

On ajoute ensuite l’utilisateur nagios créé au group httpd.

usermod -G nagios -a http

Configuration

Le plus simple est de prendre les fichiers de configuration par défaut et de les modifier quand il y en a besoin. Pour ce faire on se place dans le dossier /etc/nagios et on exécute :

cp /etc/nagios/cgi.cfg.sample /etc/nagios/cgi.cfg
cp /etc/nagios/resource.cfg.sample /etc/nagios/resource.cfg
cp /etc/nagios/nagios.cfg.sample /etc/nagios/nagios.cfg
cp /etc/nagios/objects/commands.cfg.sample /etc/nagios/objects/commands.cfg
cp /etc/nagios/objects/contacts.cfg.sample /etc/nagios/objects/contacts.cfg
cp /etc/nagios/objects/localhost.cfg.sample /etc/nagios/objects/localhost.cfg
cp /etc/nagios/objects/templates.cfg.sample /etc/nagios/objects/templates.cfg
cp /etc/nagios/objects/timeperiods.cfg.sample /etc/nagios/objects/timeperiods.cfg
Définition du dossier des clients

Dans le fichier /etc/nagios/nagios.cfg, on décommente les lignes cfg_dir=/etc/nagios/servers et suivantes si besoin. On peut maintenant placer dans le dossier /etc/nagios/servers (et les autres) un fichier pour chaque machine à surveiller.

Protection

Il est nécéssaire de protéger l’accès à l’interface web de Nagios. Pour cela on créé un fichier htpasswd de cette façon :

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

Ici, le nom d’utilisateur sera donc nagiosadmin, avec le mot de passe défini.

Activation

Les serveurs sont prêts, il suffit d’ajouter nagios et httpd à la liste des démons à démarrer dans le rc.conf. Le serveur est accessible sur la machine en HTTP ou en HTTPS sur leurs ports respectifs et sur l’URL /nagios/.

Notifications par e-mail

En cas d’alerte, Nagios envoie des notifications par e-mail mais quelques manipulations sont nécessaires pour qu’elles soient bien reçues. Il faut d’abord installer le paquet postfix, puis l’ajouter aux démons à démarrer dans le rc.conf et le lancer. Ensuite, on édite le fichier /etc/nagios/objects/commands.cfg pour modifier les commandes notify-host-by-email et notify-service-by-email. Pour chacune de ces commandes on ajoute à command_line l’option -r nagios@iut-fbleau.fr, où l’adresse e-mail correspond à l’adresse de provenance des mails envoyés par Nagios. Pour éviter que le mail soit bloqué, il est important que l’adresse IP publique utilisée par le serveur Nagios corresponde à l’entrée A ou une des entrées MX du domaine indiqué.

On édite ensuite le fichier /etc/nagios/objects/contacts.cfg pour modifier le champ email de l’utilisateur nagiosadmin. Il est configuré pour recevoir tous les messages d’alerte à n’importe quel moment.

Client Linux

Base

La configuration la plus simple consiste à surveiller le fonctionnement des services réseaux d’une machine et de vérifier si elle répond au ping. On créé par exemple le fichier /etc/nagios/servers/iluvatar.cfg et on y place ceci :

define host {
use linux-server
host_name iluvatar.arda
alias Iluvatar
address 172.16.1.30
}

On redémarre ensuite le démon nagios. La machine est maintenant présente dans la liste des hôtes mais on a encore aucune information sur elle.

Ping et SSH

En s’inspirant du fichier /etc/nagios/objects/localhost.cfg, on ajoute les lignes suivantes au fichier .cfg de la machine créé précédemment dans le dossier /etc/nagios/servers/.

define service{
        use                             local-service
        host_name                       iluvatar.arda
        service_description             PING
        check_command                   check_ping!100.0,20%!500.0,60%
        }

define service{
        use                             local-service
        host_name                       iluvatar.arda
        service_description             SSH
        check_command                   check_ssh
        }

On redémarre de nouveau Nagios. Cette fois, deux services s’affichent pour l’hôte.

LDAPS

Le paquet nagios-plugins installé plus tôt fournit des binaires situés dans le dossier /usr/share/nagios/libexec/ et utilisables par LDAP ou à la console lors de tests. Il faut cependant déclarer les commandes manuellement. Pour la surveillance d’un serveur LDAPS, on ajoute ces lignes au fichier /etc/nagios/objects/commands.cfg :

# 'check_ldaps' command definition
# -b : base DC
# -p : port
# -$ARG3 : protocol version
define command{
     command_name check_ldaps
     command_line /usr/share/nagios/libexec/check_ldaps -H $HOSTNAME$ -b $ARG1$ -p $ARG2$ -$ARG3$
}

Ensuite, on ajoute ce service au fichier .cfg de la machine :

define service{
        use                             local-service
        host_name                       iluvatar.arda
        service_description             LDAPS
        check_command                   check_ldaps!dc=arda!636!3
        }
Important Le programme check_ldaps va se connecter au serveur en utilisant le nom d’hôte indiqué dans le champ host_name du fichier .cfg. Il est important que ce champ contienne le nom DNS complet du serveur, car celui-ci sera comparé au champ CN du certificat utilisé pour le chiffrement.

Si on utilise un certificat auto-signé, il faut indiquer au programme de l’accepter malgré tout. Pour cela on modifie le fichier /etc/openldap/ldap.conf du serveur Nagios comme sur un client LDAP habituel. Il devrait ressembler à ça :

BASE    dc=arda
URI     ldaps://iluvatar.arda:636

TLS_CACERT /etc/openldap/ssl/slapdcert.pem
TLS_REQCERT allow

Le fichier /etc/openldap/ssl/slapdcert.pem contenant le certificat du serveur LDAPS.

Nombre de connexions sur LDAP

On vient de voir comment vérifier qu’un serveur LDAP fonctionne. On peut aller un peu plus loin en vérifiant le nombre de connexions ouvertes vers lui, afin de mieux prévoir l’approche d’une situation dangereuse ou critique. Cette information ne peut être obtenue que par un utilisateur connecté au serveur. On pourrait utiliser NRPE, décrit dans la section suivante, mais on va plutôt utiliser le check_by_ssh.

Sur le serveur Nagios

Pour simplifier la mise en place de SSH pour l’utilisateur Nagios, on lui définit un répertoire personnel :

usermod -d /etc/nagios nagios

On créé le dossier /etc/nagios/.ssh et on utilise la commande ssh_keygen pour y placer une clé SSH sans mot de passe. On utilise ensuite les commandes suivantes :

ssh -oUserKnownHostsFile=/etc/nagios/.ssh/known_hosts utilisateur@machine exit
ssh-copy-id -i /etc/nagios/.ssh/id_rsa utilisateur@machine

La première commande permet d’ajouter la clé publique du serveur au fichier known_hosts de l’utilisateur Nagios. La seconde copie la clé publique dans le fichier authorized_keys sur le serveur. On change ensuite le propriétaire du dossier /etc/nagios/.ssh ainsi que les trois fichiers qui y sont présents pour nagios:nagios.

On ajoute ensuite au fichier /etc/nagios/objects/commands.cfg :

define command{
        command_name check_ldaps_connections
        command_line $USER1$/check_by_ssh -H $HOSTNAME$ -l $ARG1$ -i $ARG2$ $ARG3$
}

On utilise ensuite la commande de cette façon, dans le .cfg d’un hôte :

define service{
        use                             local-service,graphed-service
        host_name                       iluvatar.arda
        service_description             Connexions LDAP
        check_command                   check_ldaps_connections!root!/etc/nagios/.ssh/id_rsa!/root/nagios/ldap_connexions.sh
}

On modifie si besoin le nom de l’utilisateur par lequel Nagios va se connecter au serveur (ici root), et par conséquent le chemin vers le script à exécuter (qu’on créé au paragraphe suivant).

Sur le client Linux

On modifie tout d’abord le .ssh/authorized_keys de l’utilisateur par lequel Nagios va se connecter. La dernière ligne correspond normalement à la clé qu’on vient d’ajouter. On ajoute from="172.16.x.y" au tout début de cette ligne en indiquant l’adresse IP du serveur Nagios. On permet ainsi de restreindre l’utilisation de cette clé en cas de fuite.

On place ensuite dans le dossier /root/nagios (ou celui choisi au paragraphe précédent) le script ldap_connexions.sh suivant :

#!/bin/bash

nb=`/bin/netstat | /bin/grep ":ldap" | /usr/bin/wc -l`

if (( $nb > 800 )); then
 status="CRITICAL"
 retval=2

elif (( $nb > 500 )); then
 status="WARNING"
 retval=1

else
 status="OK"
 retval=0
fi

echo "Connexions LDAPS $status - $nb|connexions=$nb"
exit $retval

On le rend enfin exécutable.

Samba

Les plugins standards de Nagios ne permettent pas de vérifier l'état d’un serveur Samba. On va donc utiliser un plugin tiers disponible à cette adresse : http://exchange.nagios.org/directory/Plugins/System-Metrics/File-System/SMB/check_smb/details.

Il s’agit d’un script bash qui utilise la commande smbclient. Il faut donc installer le paquet samba pour qu’il fonctionne. On place ce script avec les autres dans le dossier /usr/share/nagios/libexec/, on le rend exécutable et on lui donne nagios:nagios comme propriétaire. On ajoute ensuite ces lignes au fichier /etc/nagios/objects/commands.cfg :

# check_smb
define command{
        command_name check_smb
        command_line $USER1$/check_smb -H $HOSTNAME$
}

On l’utilise ensuite comme n’importe quelle commande. Pour notre fichier .cfg, cela donne :

define service{
        use                             local-service
        host_name                       iluvatar.arda
        service_description             Etat Samba
        check_command                   check_smb
}

Services locaux avec NRPE

RàF

Client concentrateur réseau

Pour l’ajout d’un concentrateur réseau à Nagios, on va s’inspirer du fichier /etc/nagios/objects/switch.cfg.sample. On créé par exemple le fichier /etc/nagios/switches/switch1.cfg avec ce contenu :

define host{
        use             generic-switch
        host_name       switch1
        alias           switch1 (J8873A)
        address         172.16.1.200
        hostgroups      switches
        }

define hostgroup{
        hostgroup_name  switches
        alias           Network Switches
        }

define service{
        use                     generic-service
        host_name               switch1
        service_description     PING
        check_command           check_ping!200.0,20%!600.0,60%
        normal_check_interval   5
        retry_check_interval    1
        }

define service{
        use                     generic-service
        host_name               switch1
        service_description     Uptime
        check_command           check_snmp!-C public -o sysUpTime.0
        }

Dans cet exemple on a défini un service utilisant SNMP pour obtenir le temps d’activité du concentrateur, mais on peut utiliser SNMP pour obtenir beaucoup d’autres informations.

Concentrateurs HP Procurve

Il existe un plugin utilisant SNMP qui permet de récupérer de nombreuses données intéressantes depuis un concentrateur HP Procurve. On peut le récupérer depuis cette adresse : http://exchange.nagios.org/directory/Plugins/Hardware/Network-Gear/HP/Monitoring-HP-2DProcurve/details.

Le plugin contient deux fichiers. Le premier, checkcommands_HPPro.cfg, définit des commandes et peut être copié dans le fichier /etc/nagios/objects/commands.cfg ou placé dans un dossier /etc/nagios/plugins/. Dans ce dernier cas, on devra d’abord ajouter une ligne cfg_dir=/etc/nagios/plugins au nagios.cfg. Le second fichier, services_HPPro.cfg, est un fichier d’exemple définissant des services. Il peut être copié dans le .cfg d’un hôte, il faut dans ce cas modifier les lignes host_name avec le nom de l’hôte. On peut également le placer dans le dossier /etc/nagios/plugins, et modifier les lignes host_name avec les noms des hôtes pour lesquels activer ce service en les séparant par une virgule.

Mesure du traffic

Il est possible d’obtenir via SNMP le nombre d’octets qui sont entrés sur chaque port d’un concentrateur. En effectuant plusieurs mesures et en calculant la différence entre ces deux mesures, on peut obtenir la quantité de trafic réseau entre deux moments. À cette fin, je propose un script simple effectuant ce travail, dont voici la source :

#!/bin/bash

# Dossier où stocker les mesures
DIR=/var/nagios/check_snmp_traffic

if [ "$1" == "" ]
then
 echo "Indiquer l'hôte en premier paramètre."
 exit 3
fi

CMD="/usr/bin/snmpwalk $1 -c public IF-MIB::ifInOctets -m ALL -v 2c | cut -d' ' -f4"

# On change le séparateur de champ
IFS=$'\n'

# On mesure les résultats et on les convertit en listes
list1=( `cat $DIR/$1` )
eval $CMD > $DIR/$1
list2=( `cat $DIR/$1` )

if [ "$list1" == "" ]
then
 echo "OK - First measure done"
 exit
fi

total=0
# $i compteur de 0 à nombre de ports - 1
for i in `seq 0 $((${#list1[@]} - 1))`
do
 # Différence entre les deux mesures pour un port
 diff=$((${list2[$i]} - ${list1[$i]}))
 # Prévention des cas négatifs (overflow des entiers 32bits)
 if (( "$diff" > 0 ))
 then
  total=$(($total + $diff))
 fi
done

echo "OK - $total bytes since last check|traffic=${total}B"
Note Ce script ne définit aucun seuil d’alerte ou seuil critique. Il est d’un niveau amateur et les données qu’il fournit ne devraient être utilisées qu'à titre indicatif.

Comme toujours, on place ce script dans le dossier /usr/share/nagios/libexec, on le rend exécutable et on fait de nagios:nagios son propriétaire. Avant de l’utiliser, on créé le dossier /var/nagios/check_snmp_traffic où il placera un fichier contenant les dernières mesures. Pour l’utiliser, on ajoute ceci au fichier /etc/nagios/objects/commands.cfg :

define command{
        command_name check_snmp_traffic
        command_line /usr/share/nagios/libexec/check_snmp_traffic.sh $HOSTADDRESS$
}

Pour l’activer sur un hôte, on place simplement ceci dans son fichier .cfg :

define service{
        use                     generic-service
        host_name               switch1
        service_description     Traffic
        check_command           check_snmp_traffic
}

Affichage de graphiques

Les données collectées par Nagios peuvent être enregistrées pour effectuer des statistiques et des comparaisons. À cette fin, l’outil Nagiosgraph permet de générer des graphiques et de les intégrer dans l’interface de Nagios.

Installation

On l’installe en téléchargeant l’archive depuis le site officiel : http://nagiosgraph.sourceforge.net/.

Note Les paquets perl-gd et rrdtool seront nécessaires pour continuer.

Dans le dossier de l’archive décompressée, on exécute le script install.pl. Il est capable de détecter l’environnement Apache/Nagios et la plupart des choix par défaut seront corrects. En date du 16 septembre 2011, je relève les modifications auxquelles j’ai du procéder :

  • username or userid of web server user? [www-data] → modifier par http

  • Modify the Nagios configuration? [n] → on peut répondre y, des sauvegardes des fichiers modifiés seront effectuées au cas où

  • Path of Nagios commands file? → devrait être /etc/nagios/objects/commands.cfg

  • Modify the Apache configuration? [n] → on peut répondre y également

  • Path of Apache configuration file? → devrait être /etc/httpd/conf/httpd.conf

Nagiosgraph est installé. On redémarre Nagios et Apache pour appliquer les modifications à leurs configurations.

Utilisation

La plupart des services Nagios, en plus d’un message de status, renvoient des "Performance Data". Celles-ci sont automatiquement utilisées par Nagiosgraph pour établir les graphiques. L’interface de Nagiosgraph est accessible à l’URL /nagiosgraph/cgi-bin/show.cgi, mais on peut également activer une icône de raccourci pour n’importe quel service. Pour cela, on modifie le service dans la configuration de Nagios, en ajoutant graphed-service à la ligne use. Un exemple :

define service{
        use                     generic-service,graphed-service
        host_name               switch1
        service_description     Traffic
        normal_check_interval   1
        retry_check_interval    1
        check_command           check_snmp_traffic
}
Mise à jour en temps réel des graphiques

La plupart des pages Nagios sont mises à jour automatiquement, de façon qu’il n’est pas nécessaire d’actualiser la page pour avoir les dernières informations. Ce n’est pas le cas avec Nagiosgraph mais il est possible d’obtenir un comportement similaire en ajoutant du code Javascript à la page. Pour cela on a besoin de l’extension GreaseMonkey pour Firefox.

Je propose cet userscript simple qui permet de mettre à jour le premier graphique d’une page Nagiosgraph toutes les 30 secondes. Il peut être ajouté automatiquement en cliquant sur ce lien. Il faudra ensuite se rendre dans les paramètres de Greasemonkey pour modifier l’URL d’application de ce script. Source :

// ==UserScript==
// @name           Auto-refresh
// @namespace      Nagiosgraph
// @include        https://172.16.1.56/nagiosgraph/cgi-bin/show.cgi?*
// ==/UserScript==

window.setInterval(function(){
        img = document.getElementById('period_data_day').children[0].children[0].children[0];
        img.src = img.src.replace(/&foo=[^&]*/, '') + '&foo=' + new Date().getTime();
}, 30000);