lundi, janvier 23, 2012

Donne moi l'heure, je te dirai qui tu es.

Je suis un peu un maniaque de l'heure, et j'aime bien à l'occasion ou professionnellement vérifier que les sites Web renvoient une heure correcte dans l'entête HTTP Date. C'est bien souvent un signe intéressant (mais ni nécessaire, ni suffisant) de la qualité de l'administration d'une plateforme.

Il y a en effet de multiples raisons pour que les serveurs Web soient tenus correctement synchronisés avec l'heure légale :
  • L'horodatage des journaux (HTTP, mais aussi applicatifs) afin de pouvoir déboguer ou enquêter après un incident de sécurité. Il n'y a rien de plus frustrant lors d'une enquête forensique d'être obligé de jongler avec les décalages horaires de systèmes entre eux (web, firewall, base de données, ...).
  • Le fonctionnement des caches Web, de l'expiration des sessions et parfois de la cryptographie peut nécessiter d'avoir une horloge pas trop désynchronisée entre serveur et clients.
  • Il peut y avoir des nécessités légales, notamment sur les sites marchands ou bancaires.

L'examen du champ Date envoyé par le serveur doit être fait avec prudence : en effet, le RFC 2616 sur HTTP 1.1 explique que ce champ est inséré par le serveur lors de la création du document, mais pas forcément celui de son envoi. Pour être raisonnablement sûr que la date renvoyée soit bien celle de l'horloge système du serveur, il faut donc :
  • Demander un document dynamique, par exemple avec un paramètre variable dans l'URL ;
  • Positionner les entêtes Cache-Control et Pragma pour demander à un cache éventuel de récupérer le document original ;
  • Tester que cela fonctionne en examinant les entêtes et vérifiant que la date varie convenablement avec le paramètre !
On peut alors comparer l'heure présente dans la réponse du serveur avec celle du serveur, en essayant de tenir compte du temps de transfert du réseau et de la préparation de la requête (résolution DNS, connexion TCP). Il faut noter que le champ Date n'offre qu'une précision à la seconde. Afin de garantir des transferts les plus courts possibles, il est quand c'est possible préférable d'utiliser la méthode HEAD afin de ne lire du réseau que les entêtes de la réponse.

J'ai voulu vérifier la bonne synchronisation d'un nombre raisonnable (80) de sites français, en le faisant sur la durée (plusieurs semaines) et de manière automatisée. J'ai divisé les sites cibles en 8 catégories un peu arbitraires : 
  • Les sites de l'Etat (Présidence de la République, ministères, assemblées) ;
  • Les sites des "Hautes Autorités" ou agences associées à l'Etat, florissantes depuis une dizaine d'années ;
  • D'autres services publics (Sécurité Sociale, Météo, ...) ;
  • Les sites des principaux partis politiques qui seront représentés à la prochaine élection présidentielle ;
  • La presse quotidienne nationale et régionale ; 
  • Les chaînes de télévision ayant une diffusion sur la TNT ;
  • Les opérateurs télécoms, FAI, l'AFNIC et quelques hébergeurs parmi les plus connus (liste un peu arbitraire) ;
  • Les principales banques de dépôt.
Les URLs des sites sont disponibles ici en format texte.

Le programme écrit en C utilise libcurl pour les requêtes HTTP et une base de données MySQL pour le stockages des sites, des paramètres et des résultats. Le programme et la base de données utilisée (sans les résultats) sont disponibles ici en licence WTFPL

Les résultats bruts peuvent être obtenus en interrogeant la base de données, en utilisant la requête SQL select sites.url,abs(avg(delta_time)),stddev(delta_time) from sites,results where sites.sites_id=results.sites_id group by results.sites_id order by 2. Les résultats sont bien meilleurs que ce à quoi je m'attendais : la plupart des sites ont un écart de moins de deux secondes avec l'heure du serveur effectuant les essais (lui même bien synchronisé par ntpd). 


Les sites les moins précis sont donnés ci-dessous. Les écarts de temps sont donnés en millisecondes :

| left(sites.url,40) | abs(avg(delta_time)) | stddev(delta_time) |
...
| http://www.prosodie.fr/?id={TS}          |            1085.8544 |           812.5083 |
| http://www.direct8.fr/actu-info/         |            1267.8511 |          2870.3213 |
| http://www.nrj12.fr/?id={TS}             |            1446.9191 |          1429.6998 |
| http://www.liberation.fr/?id={TS}        |            1540.4272 |           933.0153 |
| http://www.has-sante.fr/portail/jcms/j_5 |            1989.6861 |          1360.3114 |
| http://www.defense.gouv.fr/?id={TS}      |            2566.4304 |          1786.1356 |
| http://www.sante.gouv.fr/?id={TS}        |            2817.6602 |          1687.9689 |
| http://www.frontnational.com/?id={TS}    |            3022.6440 |          1720.3847 |
| http://www.humanite.fr/?id={TS}          |            4042.3495 |          5538.7156 |
| http://www.csa.fr?id={TS}                |            4681.3819 |          3369.7041 |
| http://www.hadopi.fr/?id={TS}            |            5691.7120 |          5018.6053 |
| http://www.afnic.fr/?ts={TS}             |            7170.0154 |          8571.1347 |
| http://www.gandi.net/?id={TS}            |            9327.2589 |          2562.1840 |
| http://www.industrie.gouv.fr/?id={TS}    |           17408.0421 |          1659.7796 |
| http://www.banquepopulaire.fr/scripts/gr |           46421.9612 |         29731.3730 |
| https://www.lcl.fr/?id={TS}              |          138442.5890 |         15340.1387 |
| http://www.online.net/?id={TS}           |          227520.5761 |         71500.8101 |
| http://www.cnil.fr/?tsid={TS}            |          233297.6472 |        113715.0501 |

On peut remarquer que deux banques figurent parmi les sites les moins synchrones ! Deux grands hébergeurs figurent également parmi les moutons noirs, ainsi que la CNIL (233s de décalage quand même) et l'Hadopi. Tous ces sites n'utilisent probablement pas de synchronisation NTP ...

Des observations également intéressantes peuvent être faites, notamment sur le site AFNIC, ou un serveur non synchronisé (sur 2 ou 3 serveurs cachés derriere www.afnic.fr) pollue la moyenne, ainsi que cela peut être vu dans le graphe obtenu grâce à l'exportation des données :
2586 > export site 87 afnic.txt
259 results exported to afnic.txt



On peut aussi observer la dérive sur 10 jours du serveur de la CNIL, ou là aussi deux serveurs (l'un en avance de 12 secondes, l'autre de 35) se mélangent probablement :


La dérive est également importante sur le serveur Prosodie, ou visiblement une synchronisation nocturne par tâche programmée remet les choses en l'ordre (ce qui n'est pas optimal et peut causer des problèmes système puisque non monotone) :

Il sera intéressant de constater comment les sites les plus synchrones vont digérer la seconde intercalaire (leap second) qui sera insérée le 30 Juin à minuit (si tant est que le serveur effectuant la mesure la gère bien ...).

Si vous êtes un des administrateurs des sites testés et que vous désirez être enlevés de cette étude (qui va continuer encore quelques semaines), ou que vous vouliez récupérer les données brutes vous concernant, écrivez moi à timesurvey at rominet dot net .