Supervision de serveur NTP

Si vous avez un serveur NTP (Network Time Protocol) et que vous avez enregistré votre machine sur pool.ntp.org (ce qui est bien) vous avez sûrement remarqué qu’on peut consulter l’évolution de l’offset de son service via une représentation graphique.

REMARQUE : je n’ai pas créé de fil de digression sur ce tuto parce qu’à mon avis ça ne va pas faire vibrer les foules, si toutefois vous voulez en faire un pour causer je rajouterai le lien ici.

Voici une méthode pour avoir la représentation graphique des grandeurs significatives de son serveur NTP sur son service HTTP.
Elle est inspirée du tuto de lol sur iptraf http://forum.debian-fr.org/viewtopic.php?f=8&t=27644 (dont je vous conseille la lecture car je ne reviendrai pas sur ce qu’il a déjà dit) et de quelques recherches personnelles.

Elle requiert :

  • un service ntpd,
  • rrdtool,
  • un service http prenant en charge les scripts CGI.

1. Création de la base de données

On s’attachera seulement à la représentation de l’offset mais sachez que de nombreuses autres grandeurs sont accessibles et qu’il n’est pas compliqué de mondifier ce tuto pour en ajouter.

2. Mise à jour de la base de données

On crée un script /usr/local/bin/ntp_upgrade contenant

#! /bin/bash

OFFSET=`ntpq -c rv | awk 'BEGIN{ RS=","}{ print }' | grep offset | awk 'BEGIN{FS="="}{print $2}'`

rrdtool update /var/lib/rrd/ntp.rrd N:${OFFSET}

On lance ce script régulièrement via cron, toutes les 5mn par exemple

3. Génération de la page web affichant le graphe

C’est là qu’il faut avoir un serveur prenant en charge les CGI.
Dans le répertoire qui va bien on crée le script ntp_graph.cgi

#!/usr/bin/perl -w

use strict;
use RRDs;
use POSIX qw(uname);

my $host = (POSIX::uname())[1];
my $rrd = '/var/lib/rrd/ntp.rrd';

sub refresh_graph
{
	my $hour=$_[0];
	my $fulltime=3600*$hour;

	my $file="./ntp_offset.png";
	RRDs::graph("$file",
			"--end",
			"now",
			"--start",
			"end-$fulltime",
			"DEF:offset=$rrd:offset:AVERAGE",
			"CDEF:noffset=offset,1000,/",
			"LINE1:noffset#0000FF",
			);
}

sub main
{
        print "Content-Type: text/html\n\n";

        # envoi du header
        print <<HEADER;
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Analyse du service NTP de $host</title>
<meta http-equiv="Refresh" content="300" />
<meta http-equiv="Pragma" content="no-cache" />
<link rel="stylesheet" href="mailgraph.css" type="text/css" />
</head>
<body>
HEADER
        print "<h1>Analyse du service NTP de $host</h1>\n";

        # recuperation de la periode d'analyse
        my $time=$ENV{QUERY_STRING};
        $time =~ s/\/[^\/]+$//;
        $time =~ s/\//,/g;
        $time =~ s/(\~|\%7E)/tilde,/g;
        # test sur la valeur passee en argument : elle doit exister, etre positive et inferieure a 1 an
        if ( ($time == '') || ($time<0) || ($time>8760) )
        {
                print "Periode d'analyse par defaut (6 heures)";
                refresh_graph(6);
        }
        else
        {
                print "Periode d'analyse $time heures";
                refresh_graph($time);
        }
	# affichage du graphe
	print "<br><br>";
	print "<img src=\"./ntp_offset.png\">";
	print "<br><br>";

        print <<FOOTER;
<br>
Mettez ce que vous voulez</a>
<br>
</body></html>
FOOTER
}

main;

Ce script est conçu pour qu’on lui passe la durée d’analyse en heure via la requête http://machine.domaine.org/ouvousvoulez/ntp_graph.cgi?2, soit 2 heures. Si on ne passe pas d’argument l’analyse est faite sur 6 heures.

EDIT : j’ai pris la CSS de mailgraph parce que c’est plus chouette chez moi mais virez cette ligne au besoin.

Vous aurez alors une page avec un joli graphe comme celui-là

Salut,
Je serais bien allé rejoindre le pool malagache… pool.ntp.org/zone/mg
Mais je n’ai pas de courant pendant 6 heures par jour, je suppose que c’est rédhibitoire pour adhérer à pool.ntp.org :angry:

Merci pour ce truc très intéressant, je met dans mes favoris, pour plus tard…

:006

Dans la mesure où une note est donnée à ta machine en fonction de sa disponibilité ça ne sert pas à grand chose. Tu recevras des mails tous les jours te demandant si c’est normal que ta machine soit offline.

Je vais quand même leur poser la question… Il n’y a que trois serveurs sur Madagascar, ils seront peut-être preneurs tout de même ? 8) [size=50]Même si ça me gonfle de faire un email en anglais…[/size]

[quote]Hi Laurent,

Thank you for offering! Because of how many common ntp implementations work only servers that are on and available all the time can contribute.[/quote]

Dommage ! :confused:

Est-ce que le cgi ne pose pas un problème de sécurité?

Ca dépend de la configuration du serveur et du code.

J’avais fait plusieurs scripts pour surveiller les serveurs NTP.

#!/bin/sh while /bin/true ; do D=`date +%d` D=`expr \( $D \/ 7 \) \* 7 + 1` D=`echo $D | sed -e 's/^\(.\)$/0\1/'` FICHIER=NTP.serveurs`date +%Y%m`$D if [ -z $1 ] ; then PAYS=fr TOTAL=3 else PAYS=$1 TOTAL=$2 fi if [ ! -z $PAYS ] ; then PAYS=$PAYS"." fi echo -n > /tmp/.serveurs for i in `seq 0 $TOTAL` ; do host $i."$PAYS"pool.ntp.org | grep "has address" | awk '{print $4}' >> /tmp/.serveurs done touch $FICHIER cat $FICHIER >> /tmp/.serveurs sort -u /tmp/.serveurs > $FICHIER sleep 600 done permet de reconstituer sur une période la liste des serveur NTP d’un pays (pour voir si mes deux serveurs sont toujours dedans).

Ces scripts http://www.penninespringmusic.co.uk/rich/software/conntrack.tgz permettent de chasser les bozos i.e de bloquer les personnes envoyant requête sur requête…
Il permet également via un autre script d’avoir le flux NTP.

Salut,

Quelque chose que je ne comprends pas trop dans ton script.
Un host 0.fr.pool.ntp.org me renvoie

Donc pas de grep possible sur “has address”…'fin c’est juste de la syntaxe à revoir.
La sortie de host a changé depuis que tu as fait ton script ?

J’ai changé la ligne par :

Et ça fait le boulot pareil.

[quote=“antalgeek”]Salut,

Quelque chose que je ne comprends pas trop dans ton script.
Un host 0.fr.pool.ntp.org me renvoie

Donc pas de grep possible sur “has address”…'fin c’est juste de la syntaxe à revoir.
La sortie de host a changé depuis que tu as fait ton script ?

J’ai changé la ligne par :

Et ça fait le boulot pareil.[/quote]
francois@totoche:~$ host 0.fr.pool.ntp.org
0.fr.pool.ntp.org has address 81.93.183.116
0.fr.pool.ntp.org has address 88.191.80.230
0.fr.pool.ntp.org has address 212.85.158.10
francois@totoche:~$

sur un DNS perso…

:open_mouth:
Ben pourquoi il cause pas comme ça chez moi ?
Je ne me serais pas pris la tête sinon …

Je viens de faire l’essai sur ma squeeze et j’ai effectivement la sortie avec “has address”.
Faut tester la version d’une commande avant de scripter maintenant :confused:

Ce qu’il y a d’étonnant est que j’ai cette sortie sur etch, lenny et squeeze…

Je viens de voir que sous Lenny la commande host peut être fournie par :

  • paquet host, le fichier de contrôle indique ‘conflicts’ et ‘replace’ sur certaines versions de dnsutils,
  • paquet dnsutils,
  • paquet bind9-host.
    Sur mon serveur (sous lenny) j’ai bind9-host installé et il me renvoie bien un ‘has address’.
    Sur ma squeeze j’ai dnsutils installé et il me renvoie aussi un ‘has address’.
    Je me laisse aller à penser que sur le portable sur lequel j’ai scripté j’ai le paquet host.