Logs locaux et distants
Niveau :
Résumé : syslog-ng
Syslog-ng est un système de log qui est maintenant installé par défaut sur un certain nombre de distributions. Mais on l'utilise rarement au mieux de ses capacités.
Syslog-ng permet de faire un filtrage des logs, de centraliser un système de logs et d'avoir une configuration simple et plus souple.
Configuration de base
Le fichier de configuration de syslog-ng est très structuré. On y définit deux choses : des options et des logs.
Les options sont globales au système de log et les logs sont un ensemble de règles s'appliquant à une entrée de logs. Ces règles sont elles-mêmes définies par : des sources, des filtres, des destinations et éventuellement des flags.
Voila, je vous ai décrit la structure d'un fichier de configuration. Passons rapidement sur les éléments les plus importants, les logs.
Une entrée log se définit assez aisément comme suit :
source -> filtre -> destination
Syslog-ng sait lire un bon nombre de sources dont :
- un pipe unix
- un fichier spécial tel que /proc/kmsg sous linux
- un pipe
- un port tcp ou udp
Un filtre permet de ne garder qu'une partie des logs qu'on donne à syslog pour stockage. Syslog-ng sait filtrer en fonction de qui ou quoi a envoyé le message :
- en fonction du niveau de gravité
- en fonction de la "facility"
- en fonction d'expression régulières ...
Une "facility" est en fait une catégorie de logs. Un certain nombre (24) de ces catégories sont prédéfinies, il est possible d'en définir de nouvelles, mais rares sont ceux qui le font.
Syslog-ng sait écrire dans un bon nombre de destinations dont :
- un fichier
- un pipe
- une socket unix
- une commande
- un port udp ou tcp
- et même un terminal
Une destination peut être accompagnée d'un template, qui est en fait un format de log.
Voila, maintenant, vous savez-tout, c'est parti.
Écriture de nouveau logs
Si vous développez un nouveau logiciel qui doit fournir des logs, vous pouvez utilisez les fonctions suivantes :
#include <syslog.h> void openlog(const char *ident, int option, int facility); void syslog(int priority, const char *format, ...); void closelog(void);
Si vous développez en shell, vous allez utiliser logger.
Et enfin, si vous voulez tester votre installation, vous allez utiliser loggen fourni avec syslog-ng, exemple :
$ loggen -r 10 -I 10 -D localhost 514
Attention, cela génère beaucoup de logs et utilise la "facility" auth.
Configuration serveur
Tout comme l'ancien syslog, syslog-ng permet de fonctionner en mode client-serveur, mais de façon beaucoup plus complète (possibilité de changer de port, d'utiliser tcp et ipv6). Vous pouvez vouloir externaliser le système de log pour plusieurs raisons. On peut faciliter le traitement des logs en les stockant sur une base de données, on peut aussi sécuriser les logs pour les protéger contre un effacement et faciliter l'analyse post-mortem en cas de problème.
Stockage sur une base de données
Syslog-ng permet un un stockage des logs sur une base mysql. Ceci permet pour ceux qui traitent beaucoup de logs ou disposent de système de traitement personnels de leur faciliter le travail.
La méthode sera plus simple lorsque syslog-ng 3 sera dans les bacs, mais en attendant, il faut écrire soi même la ligne de commande permettant d'envoyer des logs à mysql.
Exemple :
#attention, c'est à vous de faire un .my.cnf contenant login et mot de passe pour éviter de les voir apparaitre en ligne de commande # Vous pouvez choisir le format de table que vous voulez destination d_mysql { program("mysql -B -s --reconnect database > /dev/null" template("INSERT INTO logs (host, facility, priority, level, tag, datetime, program, msg) VALUES ( '$HOST', '$FACILITY', '$PRIORITY', '$LEVEL', '$TAG', '$YEAR-$MONTH-$DAY $HOUR:$MIN:$SEC', '$PROGRAM', '$MSG' ); ") template-escape(yes) ); };
Et voilà, il ne vous reste plus qu'à effectuer votre traitement personnalisé en SQL.
Par contre, pour ceux qui espéraient se simplifier le traitement des logs apache ... vous avez perdu, apache n'utilise pas nativement syslog. Vous pouvez soit modifier la configuration apache pour le forcer à utiliser syslog (plus besoin de reloader apache pour le logrotate), soit lui dire d'envoyer ses logs directement à mysql, soit de charger les logs une fois par jour dans un serveur sql juste avant le traitement.
Centralisation sur un serveur distant
Il existe un protocole syslog (mis à jour depuis) définissant un moyen de communiquer des logs sur le réseau en UDP. Syslog-ng implémente ce protocole à la fois d'un point de vue client et d'un point de vue serveur. Vous pourrez ainsi garantir à votre patron que vous êtes capables de lui fournir les logs quoi qu'il arrive au serveur.
Coté client : il suffit de définit une destination de type udp et de créer une entrée logs pour envoyer les logs que vous avez sélectionné.
source distant_hosts { udp(); };
Coté serveur, qu'on appelle généralement loghost : il suffit de définir une source de type udp et de créer une entrée logs pour stocker tous ces logs quelque part.
destination loghost { udp("loghost.work.net" port (514)); };
Notez qu'il y a plusieurs inconvénients à utiliser udp : les paquets peuvent être perdus, le traffic transite en clair sur le réseau, et n'importe qui peut envoyer des paquets. Pour palier le premier problème, syslog-ng implémente un protocole TCP, pour les deux autres, il est possible de passer par des tunnels sécurisés.
Notez qu'il y a aussi un inconvénient à utiliser tcp : la machine qui reçoit les logs est un peu plus chargée car elle doit deviner d'elle même quand commence et quand se termine un log et donc gérer des morceaux de logs et le buffer associé.
Dans les deux cas pensez à implémenter un firewall local pour éviter les surprises.
Pour mettre en place un chiffrement des communications, voici un exemple de solution à base de stunnel.
Attention à votre configuration lorsque vous transmettez des logs, le format est modifié car ceux-ci sont traités plusieurs fois. Certaines options comme chain_hostnames peuvent vous en casser le parsing. Regarder aussi keep_hostname qu'il est préférable de mettre à yes sur les loghost et ne bidouillez pas trop vos template, sauf sur le loghost final.
Astuces
- Que vous soyez sur un loghost ou non, évitez d'utiliser les dns vous risquez de surcharger la machine
options { use_dns(no); };
- Si vous avez des serveurs un peu chargés ou des loghost qui font de l'archivage, il peut être intéressant d'utiliser un nom de fichier variable pour stocker vos logs : pas besoin de relancer syslog, pas besoin de renommer vos fichiers.
destination my_file { file("/var/log/file-$YEAR-$MONTH-$DAY"); };
- Essayez de bien définir les droits de lecture pour le groupe et les droits d'écriture pour le démon, pour permettre d'autoriser certains utilisateurs à lire les logs mais de leur interdire d'y écrire.
options { owner(root); group(adm); perm(0640); dir_owner(root); dir_group(adm); dir_perm(0750); };
- Si vous êtes fréquemment connectés sur vos machines ou vos loghosts, essayez de mettre en place une destination usertty(vous) pour les logs les plus graves.
destination tty { usertty("administrator"); };
- Si vous avez des machines utilisant un ancien démon syslog, il est toujours possible de l'utiliser pour envoyer des logs à distance à un serveur syslog-ng en udp. Exemple de configuration :
kern.* @loghost #(udp IPv4 port 514 uniquement)
- Si votre serveur de log est un tant soit peu chargé, essayez de jouer avec l'option flush_lines pour regrouper les écritures. Attention, cela veut dire qu'il se peut que les dernières lignes de logs ne soient pas encore écrites lorsque vous les lirez
options { flush_lines(10); # écrire les lignes si le buffer n'est pas plein après 1000ms flush_timeout(1000); };
- Si vous êtes un adepte de jabber, vous pouvez vous envoyer vos logs les plus importants directement par xmpp
Pour une référence sur la configuration, suivez mon doigt.
Tags:planet-libre, Système