Serveur de logs central
Lorsque le parc de machine d’un administrateur commence à devenir un peu trop grand, il est souvent très fastidieux de se rendre sur l’un et l’autre des serveurs, consulter leurs fichiers de logs locaux, tout ceci pour identifier un éventuel problème lié à la mauvaise communication entre ces serveurs, ou autre.
l’idéal est de disposer d’une console unique dans l’entreprise où les différents serveurs vont inscrire leurs diverses informations initialement destinés à des fichiers de log locaux. Une telle console permet de superviser rapidement l’ensemble des messages de l’ensemble des serveurs d’une entreprise.
Un élément essentiel qui peut par exemple se coupler à un superviseur Nagios pour une vue parfaite des resources de l’entreprise.
1) Introduction
11. Généralités
Il existe plusieurs formats de gestion de messages de logs, les plus connus sont SYSLOG (qui se décline en plusieurs normes) et WindowsEvent. Les formats SYSLOG sont généralement utilisés dans les mondes UNIX-like alors que les autres utilisent des formats propriétaires … (no comment).
Nous avons choisi de construire le Serveur de Logs Central (SLC) sous le format syslog dernière génération (norme RSYSLOG) et de convertir les autres formats vers celui-ci (syslog, syslog-ng et WindowsEvent) afin de faire remonter sur cette console tous les logs de l’entreprise sans discrimination.
1.2 Le serveur SYSLOG
Un serveur SysLog est un serveur comme un autre, il a la faculté d’écouter d’éventuels clients qui veulent lu idélivrer des messages de log sous divers formes (sockets UNIX, sockets IP, etc) et, selon la configuration que l’on en fera, stoquera ces messages en fonction de divers critères et sur différents médias (fichiers text, base de données, mails, …).
Nous avons choisi dans notre exemple d’utiliser le protocole syslog pour que celui-ci stoque tous les messages qui lui sont annoncés dans une base de données au format MySQL, permet de greffer éventuellement et facilement une interface web permettant d’administrer facilement ces différents messages?
Exemple de réalisation web pour l’entreprise XXX :
1.3 Bases de construction de cet exemple
Dans cet article, notre SLC est basé sur une distribution Linux openSuSE 11.3 64bits.
Les prérequis sont, parmi les packages standards de cette distribution (rien d’extraordinaire) :
- RSYSLOG
- MYSQL community edition
- php 5.x + module php_mysql
2) Les serveurs au format SYSLOG
2.1 Présentation d’un serveur RSYSLOG (dernière génération)
Le fichier de configuration du serveur RSyslog est généralement /etc/rsyslog.conf.
Prenons par exemple la configuration RSyslog pour un serveur de mails (postfix) :
$ModLoad immark.so $ModLoad imuxsock.so $ModLoad imklog.so $klogConsoleLogLevel 1 $WorkDirectory /var/log/rsyslog.work $ActionQueueType LinkedList $ActionQueueFileName srvrfwd $ActionResumeRetryCount -1 $ActionQueueSaveOnShutdown on
mail.info /var/log/mail.info
mail.warning @@logserver:514
mail.err @@logserver:514
if ($programname != 'postfix') \ then @@logserver:514 & ~
Dans cet exemple, le serveur “logserver” est le nom DNS de notre serveur central de logs, celui-ci est indiqué dans le fichier /etc/hosts du serveur local.
Ici nous demandons plusieurs choses, l’envoi en UDP (port 514 standard) de tous les messages syslog que reçoit le serveur Rsyslog local de ce serveur, ceci pour tous les messages de la facility “mail” et la criticité “warning” ou “err“. Cela signifie tous les messages de logs envoyés par les programmes qui se signent en “mail” et qui précisent que les messages sont de type warning ou error.
Les message de type “info” sont en revanche très nombreux sur un serveur smtp très solicité,nous ne préférons pas engorger le réseau avec ce type de flux et préférons continuer le stockage de ces informations dans un fichier local au serveur (il n’y a généralement pas d’information intéréssante à glaner dans les messages de type “info” => inutile de les faire remonter inutilement…)
Notons aussi la directive “workdirectory”, elle est très importante et consiste en un répertoire de spool dans lequel stoquer les messages dans le cas où le serveur central serait injoignale pendant un certain temps en afin de ne pas perdre ces messages.
Enfin, en plus de la politique précédente, dans les dernières lignes, notons que nous ne souhaitons pas recevoir sur le SLC les lessages provenant du serveur “postfix” mais que nous souhaitons recevoir tous les autres (messages systèmes, etc).
Généralement nous ne nous attarderons pas à “éliminer” certains messages de logs à envoyer vers le SLC mais de temps en temps, comme dans le cas d’un serveur de mails, d’un DNS, etc, il peut arrive de vouloir exclure une partie des messages dans un but de lisibilité et de performance.
2.2 Communication avec d’autres serveurs de Log
2.2.1 Rsyslog vers Rsyslog
Informations décrites en 2.1, voir descriptif du /etc/rsyslog.conf
2.2.1 syslog vers Rsyslog
Syslogd est la premire version des démons syslog, le fichier de conf est /etc/syslog.conf.
Le principe est le même, on donne des règles de log (fichiers locaux, mails, …) en fonction de falility (signature des programmes “mail”, “cron”, …) et des levels (info, warning, err, …).
Exemple de /etc/syslog.conf:
*.info;mail.none;authpriv.none;cron.none /var/log/messages authpriv.* /var/log/secure mail.* /var/log/maillog cron.* /var/log/cron *.emerg * uucp,news.crit /var/log/spooler local7.* /var/log/boot.log
Dans cet exemple, nous avons un syslog.conf classique qui ne logg que dans des fichiers locaux en fonction de <facility>.* ou de *.<level> au choix.
local7.* @@serveur.de.logs:544
Ou 544 est par défaut le port UDP sur lequel le serveur répondant au nom DNS serveur.de.logs devra écouter.
2.2.2 syslog-NG vers Rsyslog
Les serveurs syslog-NG (NextGeneration) trouvent leur configuration dans /etc/syslog-ng/syslog-ng.conf.
On trouve globalement 3 notions utile dans notre cas dans ces fichiers:
- “options” : le réglagage général du démon syslog-ng
- “source” : identification d’une source de message (facility, level, …)
- “destination” : que doit on faire de ces messages (écriture fichier local, renvoi vers un autre démon syslog, etc)
Exemple:
options {
use_dns(yes); <-- utilise les résolutions DNS (recommandé)
dns_cache(yes); <-- utilise un cache client DNS (très recommandé)
use_fqdn(yes); <-- utilise des full qualified domain name au lieu de noms courts
keep_hostname(yes); <-- hostname rewriting ?
check_hostname(no);
chain_hostnames(off);
sync(0); <-- nombre de lignes à buffersier avant de traiter un flux: 0
recommandé hautement si cvous ne souhaitez pas perdre de message
stats(43200);
};
source s_everything { <-- description d'une source potentielle de message et attribution
d'un nom "s_everything"
internal();
unix-stream("/dev/log"); <-- tout se qui écrit sur le périphérique /dev/log (ie: tout)
udp(); <-- on veut receptionner de l'UDP uniquement
};
destination d_logserver { tcp("logserver" port(514)); }; <-- destination "d_logserver"
log { source(s_everything); destination(d_logserver); }; <-- on log en fonction de la source
s_everything et de d_logserver
destination d_fichier { file("/var/log/messages.log"); }; <-- destination "d_fichier"
log { source(s_everything); destination(fichier); }; <-- on log en fonction de la source
s_everything et de d_fichier
Vous le voyez, vraiment rien de sorcier !
2.2.4 WindowsEvent vers Rsyslog
2.2.4.1 – Introduction
Bon, c’est évidement là que cela commence à pêcher… Car évidement, histoire de ne pas faire dans les standards établis, Microsoft a décidé d’employer un autre protocole de communication pour les messages de log exploités notemmenent dans le monde Windows par l’EventManager que tout le monde ne connait que trop bien.
Le messages ont des niveaux de criticité, des facility, sont présents dans des types de journaux, … un peu comme dans SysLog mais ne sont pas au format SysLog…
Il existe cependant dans le monde du libre et de l’OpenSource des tas de petits softs qui se chargent de traduire un format de message Windows en un format SYSLOG dans le but de l’envoyer vers un serveur SYSLOG, et cela fonctionne très bien!
Nous avons jeté notre dévolu sur l’agent SNARE développé par la société INTERSECTALLIANCE et qui est télévhargeable ici dans une version libre : http://sourceforge.net/projects/snare/
l’Agent SNARE pour Windows fait le café en matière de traduction de message Windows vers du SYSLOG, mais IntersectAlliance propose aussi une version commerciale si vous souhaitez avoir le sucre et le nuage de lait … A mon sens vraiment pas nécéssaire.
Par exemple, SNARE dans sa version gratuite ne sait pas écouter sur les ports TCP mais uniquement sur les ports UDP ce qui est loin d’être un drâme car toutes les versions des différents serveurs SYSLOG parlent l’UDP et que il n’est pas forcément recommandé de faire de l’UDP sur un serveur SYSLOG centralisé afin de ne pas se faire engorger en cas d’afflux massif de messages et de provoquer un deni de service…
2.2.4.1 – Installation de l’Agent SNARE
Là aussi c’est d’une difficulté déconcertante, du moment que vous disposez d’un index normalement constitué pour cliquer sur “Next”, tout se passera bien!
La configuration du logiciel agent SNARE sur votre serveur windows est par contre à peine plus complexe.
2.2.4.2 – Configuration de l’Agent SNARE
Une fois l’agent installé, vous disposez en local d’un petit serveur web qui vous permet de configurer l’agent, de déterminer l’emplacement du serveur SYSLOG Central, de déterminer les mappings Event Windows / Message Syslog que vous souhaitez ainsi exporter vers ce serveur, l’ensemble est sommes toute très bien fait.
Utilisez votre navigateur http préféré depuis votre serveur Windows et connectez vous sur http://localhost:6161 vous verrez alors apparaitre l’écran suivant :
Plusieurs options s’offrent à vous dans le menu de gauche :
A) NETWORK CONFIGURATION:
Ce menu vous permet de renseigner la localisation du serveur syslog central qui va recevoir les message traduits de l’EventViewer de Vindows.
Les principaux champs à renseigner sont :
Override detected DNS Name with : NOM_MACHINE <-- le 'hostname' syslog de votre machine Destination Snare Server address: logs.domaine.fr <-- le nom dns (ou ip) du serveur syslog central Destination Port: : 514 <-- port UDP standard Enable SYSLOG Header? : CHECKED <-- sinon cela ne sera pas un message syslog SYSLOG Facility : local7 <-- une facility à associer aux messages Win64 SYSLOG Priority : DYNAMIC <-- choisissez cette option absolument
Rem: Si “SYSLOG Priority” ne vaut pas “DYNAMIC”, alors tous vos messages auront tous la même priorité (bof)
Rem: “Syslog Facility” est la facility avec laquelle ce message va s’annoncer, vous pourrez en fonction de cette information traiter les messages d’une certaine façon et les différencier des autres. Généralement local7 n’est pas ou très peu utilisé.
Cliquez sur “CHANGE CONFIGURATION” pour que les paramètres soient enregistrés (mais pas encore pris en compte)
B) REMOTE CONTROL CONFIGURATION
Simplement pour restreindre l’utilisation de cette interface web au localhost, ie aux personnes habilitées à ouvrir une session RDP sur le serveur (Administrateurs généralement) :
Cochez simplement la case “Restrict remote control of SNARE agent to certain hosts” et indiquez “127.0.0.1″ (ou “localhost”) dans le champ “IP Address allowed to remote control SNARE”, l’interface est vérouillée.
C) OBJECTIVES CONFIGURATION
C’est cette partie qui va vous permette de définir le mapping entre un message Windows et un message au format SysLog.
Par défaut, vous verrez un certain nombre de message déjà configurés, symbolisés par une ligne dans un tableau html. Généralement ces messages ne conviennent pas et sont uniquement donnés à titre d’exemples, je vous conseille de les supprimer en cliquant autant de fois que nénessaire sur le bouton “DELETE” pour chaque ligne.
Une fois les lignes d’exemples supprimées, vous allez pouvoir ajouter vos propres lignes de mapping de message, c’est à dire de traduction de messages windows spécifiques en messages de type syslog et à envoyer vers votre serveur syslog central.
Cliquez sur “ADD“, la fenêtre suivante apparaît alors :
Voici la signification des difrérents champs “utiles” et les “best pratice” à appliquer :
Identify the high level event: Indique le type d'évènement Windows concerné (les logons/logoff, les arret/marche de services, ...), il convient, dans la pluspart des cas de choisir "ANY EVENT(S)"
Select the Event ID Match Type: Une notion d'inclusion / exclusion. Sauf dans certains cas complexes imposés par votre production, vous préfererez "INCLUDE"
Event ID Search Term: Des mots clés pour filtrer les messages Windows à intercepter. Nous allons dans la pluspart des cas choisir "*" ce qui signifie "tout les messages", mais vous pourriez être amenné, en fonction de vos applicatifs, à utiliser des wildcards plus complexes ("*toto*" <-- bon ok, c'est pas très complexe... mais ça fonctionnerait)
General Search Term: *
User Search Term: *
Identify the event types to be captured: Les "Success Audit" et "Failure Audit" ne présentent pas grand intérêt pour notre utilisation, par contre "INFORMATION", "WARNING" et "ERROR" nous intéressent plus particulièrement dans le cadre des messages SYSLOG. Selon la valeur indiquée dans le paramètre suivant (Select the Alert Level) nous cocherons l'une ou l'autre de ces options. L'idée est: quelle est la notion de criticité que nous souhaitons paralléliser avec la notion de criticité d'un message syslog.
Identify the event logs: Les journaux Windows concernés. Si nous sommes intéressé par tous les message de type "ERREUR", pourquoi se limiter à un journal ? Nous allons donc cocher tous les journaux. Seul un cas particulier exigé par votre production pourra vous amener à effectuer un choix différent.
Select the Alert Level: paramètre FONDAMENTAL. Il s'agit, en fonction de tout ce que nous avons catégorisé précédemment, et notamment avec l'option "Identify the event types to be captured" de faire un parallèle avec un niveau de criticité SYSLOG. Essayez de faire un parallèle correct entre les deux notions pour ne pas avoir de niveaux de criticité incohérents par rapport à l’importance du message Windows...
Une fois ces options indiquez, vous pourrez cliquer sur “CHANGE CONFIGURATION” pour la voir apparaître dans la liste des mappings de messages comme indiqué dans le début de ce chapitre (ouf enfin!)
C) APPLY THE LATEST CONFIGURATION
Une fois tout ceci fait, une fois toutes vos règles de mapping définies, celles-ci ne sont pour autant pas encore prise en compte par le démon SNARE, il faut pour cela se rendre dans la section “Apply the latest configuration” et cliquer sur “RELOAD SETTINGS“.
A partir de cet instant, vos mappings sont actifs et, normalement, SNARE doit envoyer toutes ces traductions de messages Windows vers votre serveur de logs SYSLOG central, vous pouvez vérifier cela en cliquant sur “LATEST EVENTS” dans le menu de gauche de l’interface web SNARE, vous verre zalors un écran du style :
Ce qui signifie alors que (probablement) tout va bien! Il ne vous reste plus qu’a constater la conne reception de ces messages dans cotre SLC.
3) Configuration du serveur SYSLOG central
Dernière brique à notre édifice, la construction du serveur SLC. Celle-ci ne s’écarte pas vraiment d’une configuration standard hormis le fait que nous allons la configurer pour que tous les messages reçus soient inscrits dans une base de données MySQL dont nous allons créer dans un premier lieur la structure.
3.1) Création de la base de données
Nous avons choisi ici le choix de MySQL car c’est le pokus simple à mettre en oeuvre et les structures de tables MyISAM s’appliquent tout à fait à ce genre de typologie en matière de stockage de données (très peu de requêtes croisées, très peu de jointures, beaucoup de balayage de tables simples).
Et puis en plus, pour le moment, dans sa version community, celle-ci est totalement gratuite et full founctionality. Ceci aurait été impossible à faire avec de l’Oracle par exemple sans que cela nous coûte très cher (même dans la version XE, la database ne doit pas exéder 4Gb, hors, dans notre cas, l’entreprise XXX qui utilise cette méthode depuis 1 mois pour son DataCenter possède déjà des tables de plus de 20Gb…)
CREATE DATABASE `syslog`; CREATE TABLE `client` ( `client` int(10) unsigned NOT NULL AUTO_INCREMENT, `libelle` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL, `login` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL, `password` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL, `ackSequence` text COLLATE utf8_unicode_ci, `allServersAccess` tinyint(4) DEFAULT '-1', `alerteSonore` tinyint(4) DEFAULT '-1', PRIMARY KEY (`client`) ) ENGINE=MyISAM AUTO_INCREMENT=11 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci CREATE TABLE `clientHost` ( `clientHost` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT, `client` INT(11) DEFAULT NULL, `ipaddr` VARCHAR(20) COLLATE utf8_unicode_ci DEFAULT NULL, `libelle` VARCHAR(255) COLLATE utf8_unicode_ci DEFAULT NULL, `abreviation` VARCHAR(20) COLLATE utf8_unicode_ci DEFAULT NULL, PRIMARY KEY (`clientHost`), KEY `IDX1` (`ipaddr`) ) ENGINE=MYISAM AUTO_INCREMENT=76 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci CREATE INDEX `idxx_clientHost_ipaddr ON clientHost(ipAddr); CREATE TABLE `clientLogsAck` ( `clientLogsAck` BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT, `client` BIGINT(20) DEFAULT '-1', `seq` BIGINT(20) DEFAULT '-1', `dateAck` DATE DEFAULT NULL, `timeAck` TIME DEFAULT NULL, PRIMARY KEY (`clientLogsAck`) ) ENGINE=MYISAM AUTO_INCREMENT=53016 DEFAULT CHARSET=latin1 CREATE TABLE `logsMasking` ( `logsMasking` BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT, `client` BIGINT(20) DEFAULT NULL, `wildcard` VARCHAR(255) DEFAULT NULL, `information` VARBINARY(255) DEFAULT NULL, `datecreation` DATETIME DEFAULT NULL, `ipaddr` VARCHAR(255) DEFAULT NULL, `actif` TINYINT(1) DEFAULT NULL, PRIMARY KEY (`logsMasking`) ) ENGINE=MYISAM AUTO_INCREMENT=71 DEFAULT CHARSET=latin1 CREATE TABLE `logs` ( `seq` BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT, `ipaddr` VARCHAR(20) COLLATE latin1_general_ci DEFAULT NULL, `host` VARCHAR(32) COLLATE latin1_general_ci DEFAULT NULL, `facility` VARCHAR(10) COLLATE latin1_general_ci DEFAULT NULL, `priority` VARCHAR(10) COLLATE latin1_general_ci DEFAULT NULL, `level` VARCHAR(10) COLLATE latin1_general_ci DEFAULT NULL, `tag` VARCHAR(10) COLLATE latin1_general_ci DEFAULT NULL, `date` DATE DEFAULT NULL, `time` TIME DEFAULT NULL, `program` VARCHAR(15) COLLATE latin1_general_ci DEFAULT NULL, `msg` TEXT COLLATE latin1_general_ci, `ack` TINYINT(4) DEFAULT '-1', PRIMARY KEY (`seq`), KEY `host` (`host`), KEY `program` (`program`), KEY `time` (`time`), KEY `date` (`date`), KEY `priority` (`priority`), KEY `facility` (`facility`), KEY `IDX2` (`ipaddr`) ) ENGINE=MYISAM AUTO_INCREMENT=89272745 DEFAULT CHARSET=latin1 COLLATE=latin1_general_ci CREATE INDEX `idx_logs_host ON `logs`(host); CREATE INDEX `idx_logs_program ON `logs`(program); CREATE INDEX `idx_logs_time ON `logs`(time); CREATE INDEX `idx_logs_date ON `logs`(date); CREATE INDEX `idx_logs_priotity ON `logs`(priotity); CREATE INDEX `idx_logs_facility ON `logs`(facility); CREATE INDEX `idx_logs_ipaddr ON `logs`(ipaddr); CREATE DATABASE `syslog_arch; CREATE TABLE `logsArchives` ( `logsArchives` BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT, `ipaddr` VARCHAR(20) COLLATE utf8_unicode_ci DEFAULT NULL, `host` VARCHAR(32) COLLATE utf8_unicode_ci DEFAULT NULL, `facility` VARCHAR(10) COLLATE utf8_unicode_ci DEFAULT NULL, `priority` VARCHAR(10) COLLATE utf8_unicode_ci DEFAULT NULL, `level` VARCHAR(10) COLLATE utf8_unicode_ci DEFAULT NULL, `tag` VARCHAR(10) COLLATE utf8_unicode_ci DEFAULT NULL, `date` DATE DEFAULT NULL, `time` TIME DEFAULT NULL, `program` VARCHAR(15) COLLATE utf8_unicode_ci DEFAULT NULL, `msg` TEXT COLLATE utf8_unicode_ci, `ack` TINYINT(4) DEFAULT NULL, PRIMARY KEY (`logsArchives`), KEY `host` (`host`), KEY `program` (`program`), KEY `time` (`time`), KEY `priority` (`priority`), KEY `facility` (`facility`), KEY `IDX2` (`ipaddr`) ) ENGINE=MYISAM AUTO_INCREMENT=3554442 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci CREATE INDEX `idx_logsArchives_host ON `logs`(host); CREATE INDEX `idx_logsArchives_program ON `logs`(program); CREATE INDEX `idx_logsArchives_time ON `logs`(time); CREATE INDEX `idx_logsArchives_date ON `logs`(date); CREATE INDEX `idx_logsArchives_priotity ON `logs`(priotity); CREATE INDEX `idx_logsArchives_facility ON `logs`(facility); CREATE INDEX `idx_logsArchives_ipaddr ON `logs`(ipaddr);
$Modload ommysql $ModLoad immark $ModLoad imuxsock $ModLoad imklog $ModLoad imudp.so $ModLoad imtcp.so *.info;mail.none;authpriv.none;cron.none -/var/log/messages authpriv.* /var/log/secure mail.* -/var/log/maillog cron.* -/var/log/cron *.emerg * uucp,news.crit -/var/log/spooler local7.* /var/log/boot.log $template syslog,"insert into logs(ipaddr, host, facility, priority, level, tag, date, time, program, msg) values ('%fromhost-ip%', '%HOSTNAME%', '%syslogfacility-text%', '%syslogpriority-text%', '%syslogseverity-text%', '%syslogtag%', '%timereported:::date-mysql%', '%timereported:::date-mysql%', '%programname%', '%msg%')", SQL *.* >127.0.0.1,syslog,syslogLogin,syslogPassword;syslogTpl $UDPServerRun 514 $UDPServerAddress 192.168.12.5 $InputTCPServerRun 514







