Archives pour l'étiquette syslog

On continue avec syslog : web access log logstash redis elasticsearch kibana

Après la génération des access log au format JSON avec apache, puis la génération des acces log au format JSON avec varnish on  continue avec syslog : web access log logstash redis elasticsearch kibana

On continue avec syslog : web access log logstash redis elasticsearch kibana

 

Acte 3 scène 1: Rsyslog

Bien, donc sur le logmaster arrive donc plusieurs flux d’access log au format JSON. Ceux des serveurs apache (entre deux et six en fonction de l’activité) plus celui des serveurs varnish (un varnish pour le silo html un autre pour les static). On va cuisiner cela avec les lignes de configuration syslog sur le serveur logmaster.

# Apache access Logi & varnshs access log
$template MsgOnlyFormat,"%msg:::drop-last-lf%\n"
$template AppacheAccessFile,"/mnt/LogDataStore/apache2.json/%app-name%.json.access.log"
$template VarnishAccessFile,"/mnt/LogDataStore/varnish.json/%hostname%.varnish.json.access.log"
if $syslogfacility-text == 'local0' and $syslogseverity-text == 'notice' then @localhost:10514;MsgOnlyFormat

Alors la trame de log est d’abord nettoyer en supprimant le retour à la ligne en passant dans le template MsgOnlyFormat et envoyé en local sur le port 10514

Acte 3 scène 1: Logstash et Redis

Logstash

Sur le port 10514 un logstash écoute pour prendre en charge la trame de log. On va écouter beaucoup, filtrer par mal et enregistrer tout autant.

Voici le bout de configuration logstash en jeu

input {
 udp {
 port => 10514
 codec => "json"
 type => "access-log"
 }
}
filter {
 if [vips] !~ "closermag.fr" {
 drop {}
 }
}
output {
 #stdout { codec => rubydebug }
 redis {
   host => "localhost"
   data_type => "list"
   key => "logstash"
   codec => json
 }
}
  • Le logstash écoute donc en UDP sur un port qui n’entre pas en concurence avec rsyslog qui écoute lui aussi en UDP sur le même serveur mais sur le port 514.
  • Le logstash balance salement à la poubelle tout ce qui ne concerne pas closermag.fr (host au sens varnish ou ServerName au sens apache). Cela évite bien des parasitages quand les serveurs varnish sont mutualisé ce qui est le cas pour la distribution des statics.
  • Logstash  balance le tout dans un redis qui est la pour offrir une temporisation. En effet parfois un pic d’audience le midi ou le soir engendrais un engorgement plus loin dans la chaîne de traitement.

Redis

Le redis est configuré avec 2Go de mémoire pour stocker les trame de log et il écoute sur localhost comme sur la carte réseau disponible. Pour le reste, rien : pas d’esclave, pas de dump sur le disque.

Le début: web access log logstash redis elasticsearch kibana

Gérer et monitorer les web access log avec logstash redis elasticsearch et kibana.

 

Voila une belle série de buzz word non ? Trêve de plaisanterie ! Je vais dans une série de note expliquer la création d’une pile applicative ELK (logstash elasticsearch kibana) que j’ai monté pour surveiller et navigué dans le flux des access log sur site www.closermag.fr

Acte 1 scène 1: Le défi des web access log

A l’origine sont les access log de plusieurs serveurs apaches ainsi que de plusieurs serveur varnish. Plusieurs défis sont à relever  :

  1. Généré des access log complet dans un format facilitant leur utilisation par la chaîne applicative souhaité
  2. La plupart des serveurs étant des machines virtuelles il est nécessaire de ne pas écrire sur disque. Le disque est le sous système le plus lent d’un serveur. Dans le cas d’une machine virtuelle, quelques soit l’approche ou la technologie, c’est encore pire.
  3. Le routage des flux de log apache comme varnish et leur concaténation dans un ensemble unique.

Acte 1 scène 2 : Les apaches

Pour les serveurs apaches la gestion de log et de leur format est un chose parfaitement documenté, je ne vais pas revenir dessus. Les access log devant être finalement enregistré dans elasticsearch dont la structure de stockage et sa hiérarchie étant basé sur le format JSON pour quoi ne pas les générer directement dans ce format et les router tel quel ?

Voici dont le format de log apache créé sur cette base et utilisé. Plusieurs itération et correction ont été intégré.

LogFormat "{ \
 \"@timestamp\": \"%{%Y-%m-%dT%H:%M:%S%z}t\", \
 \"@version\": \"1\", \
 \"vips\":\"%v\", \
 \"tags\":[\"apache\"], \
 \"message\": \"%h %l %u %t \\\"%r\\\" %>s %b\", \
 \"clientip\": \"%{X-Forwarded-For}i\", \
 \"duration\": %D, \
 \"status\": %>s, \
 \"request\": \"%U%q\", \
 \"urlpath\": \"%U\", \
 \"urlquery\": \"%q\", \
 \"bytes\": %B, \
 \"method\": \"%m\", \
 \"referer\": \"%{Referer}i\", \
 \"useragent\": \"%{User-agent}i\" \
 }" log_apache_json

Notez que :

  1. Le champs tags indiquant le type de la source
  2. Le champs clientip prend les ip d’origine de la requête et non ceux des lodbalancers ou reverse proxy en amont
  3. Que la duré de réponse est fourni via le champs duration
  4. Que le volume de donnée de la réponse est fourni par le champ bytes

Nous générons donc les access log directement dans un format facilitant leur utilisation par la chaîne d’application souhaité.

Acte 1 scène 3 : Le routage

Pour ne pas toucher aux disques le mieux est encore de transmettre directement les logs au démon syslog. Avec nginx c’est facile avec apache un peu moins.

Il est possible de transmettre les log apache à syslog avec l’utilitaire logger. Seulement logger à quelque limitation et comme une trame de log au format JSON est longue et dépasse parfois 1024 bits … logger la coupe en deux et envois deux trames syslog pour une trame access log. Il faut donc trouver autre chose.

Perl

Dans l’échange sur serverfault concernant les limitations de logger la solution est donné : Sys::Syslog. Il suffit de créé soit même un nouvel utilitaire capable de prendre en charge un trame dépassant les 1024 bits.

#!/usr/bin/perl
use Sys::Syslog qw (:DEFAULT setlogsock);
 
setlogsock('unix');
 
$ident = $ARGV[0];
@facilityandpriority = split(/\./, $ARGV[1]);
$facility = @facilityandpriority[0];
$priority = @facilityandpriority[1];
 
# open our log socket
openlog($ident, '', $facility);
 
# log all our input
while () {
 syslog($priority, $_);
}
 
# close the log socket
closelog;

Vhost et rsyslog

Nous avons le format de log et l’utilitaire de couplage avec syslog. Il reste à coller les bout ensemble.

Dans le vhost ont appel le format de log créé et on l’envois vers l’utilitaire. On fait le choix d’une catégorie et d’un priorité syslog, ici local0 et notice

CustomLog "||/usr/local/bin/to_rsyslog.pl closermag.fr local0.notice" log_apache_json

Dans la configuration rsyslog on précise que tout ce qui porte l’étiquette local0.notice est à envoyé à un serveur logmaster.

local0.notice @logmaster:514
& stop

Je précise que après l’envois au serveur logmaster le message syslog ne doit pas poursuivre et traverser les autres règles de traitement avec l’instruction & stop . Attention cette syntaxe est pour la version 8 de rsyslog que j’utilise. Comme la trame ne passe pas au travers des autres règles elle n’est pas enregistré dans un fichier, localement, sur disque.

Xen Erreur : « netsnmp_assert __extension__ »

netsnmp_assert extension

Dans votre /var/log/syslog vous trouvez ce type de message toute les minutes ou 30 secondes ?

netsnmp_assert __extension__ <span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #7a0874; font-weight: bold;">&#123;</span> size_t __s1_len, __s2_len; <span style="color: #7a0874; font-weight: bold;">&#40;</span>__builtin_constant_p <span style="color: #7a0874; font-weight: bold;">&#40;</span>rowreq_ctx-<span style="color: #000000; font-weight: bold;">&gt;</span>data.ifentry-<span style="color: #000000; font-weight: bold;">&gt;</span>name<span style="color: #7a0874; font-weight: bold;">&#41;</span> <span style="color: #000000; font-weight: bold;">&amp;&amp;</span> __builtin_constant_p <span style="color: #7a0874; font-weight: bold;">&#40;</span>ifentry-<span style="color: #000000; font-weight: bold;">&gt;</span>name<span style="color: #7a0874; font-weight: bold;">&#41;</span> <span style="color: #000000; font-weight: bold;">&amp;&amp;</span> <span style="color: #7a0874; font-weight: bold;">&#40;</span>__s1_len = strlen <span style="color: #7a0874; font-weight: bold;">&#40;</span>rowreq_ctx-<span style="color: #000000; font-weight: bold;">&gt;</span>data.ifentry-<span style="color: #000000; font-weight: bold;">&gt;</span>name<span style="color: #7a0874; font-weight: bold;">&#41;</span>, __s2_len = strlen <span style="color: #7a0874; font-weight: bold;">&#40;</span>ifentry-<span style="color: #000000; font-weight: bold;">&gt;</span>name<span style="color: #7a0874; font-weight: bold;">&#41;</span>, <span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #000000; font-weight: bold;">!</span><span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #7a0874; font-weight: bold;">&#40;</span>size_t<span style="color: #7a0874; font-weight: bold;">&#41;</span><span style="color: #7a0874; font-weight: bold;">&#40;</span>const void <span style="color: #000000; font-weight: bold;">*</span><span style="color: #7a0874; font-weight: bold;">&#41;</span><span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #7a0874; font-weight: bold;">&#40;</span>rowreq_ctx-<span style="color: #000000; font-weight: bold;">&gt;</span>data.ifentry-<span style="color: #000000; font-weight: bold;">&gt;</span>name<span style="color: #7a0874; font-weight: bold;">&#41;</span> + <span style="color: #000000;">1</span><span style="color: #7a0874; font-weight: bold;">&#41;</span> - <span style="color: #7a0874; font-weight: bold;">&#40;</span>size_t<span style="color: #7a0874; font-weight: bold;">&#41;</span><span style="color: #7a0874; font-weight: bold;">&#40;</span>const void <span style="color: #000000; font-weight: bold;">*</span><span style="color: #7a0874; font-weight: bold;">&#41;</span><span style="color: #7a0874; font-weight: bold;">&#40;</span>rowreq_ctx-<span style="color: #000000; font-weight: bold;">&gt;</span>data.ifentry-<span style="color: #000000; font-weight: bold;">&gt;</span>name<span style="color: #7a0874; font-weight: bold;">&#41;</span> == <span style="color: #000000;">1</span><span style="color: #7a0874; font-weight: bold;">&#41;</span> <span style="color: #000000; font-weight: bold;">||</span> __s1_len <span style="color: #000000; font-weight: bold;">&gt;</span>= <span style="color: #000000;">4</span><span style="color: #7a0874; font-weight: bold;">&#41;</span> <span style="color: #000000; font-weight: bold;">&amp;&amp;</span> <span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #000000; font-weight: bold;">!</span><span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #7a0874; font-weight: bold;">&#40;</span>size_t<span style="color: #7a0874; font-weight: bold;">&#41;</span><span style="color: #7a0874; font-weight: bold;">&#40;</span>const void <span style="color: #000000; font-weight: bold;">*</span><span style="color: #7a0874; font-weight: bold;">&#41;</span><span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #7a0874; font-weight: bold;">&#40;</span>ifentry-<span style="color: #000000; font-weight: bold;">&gt;</span>name<span style="color: #7a0874; font-weight: bold;">&#41;</span> + <span style="color: #000000;">1</span><span style="color: #7a0874; font-weight: bold;">&#41;</span> - <span style="color: #7a0874; font-weight: bold;">&#40;</span>size_t<span style="color: #7a0874; font-weight: bold;">&#41;</span><span style="color: #7a0874; font-weight: bold;">&#40;</span>const void <span style="color: #000000; font-weight: bold;">*</span><span style="color: #7a0874; font-weight: bold;">&#41;</span><span style="color: #7a0874; font-weight: bold;">&#40;</span>ifentry-<span style="color: #000000; font-weight: bold;">&gt;</span>name<span style="color: #7a0874; font-weight: bold;">&#41;</span> == <span style="color: #000000;">1</span><span style="color: #7a0874; font-weight: bold;">&#41;</span> <span style="color: #000000; font-weight: bold;">||</span> __s2_len <span style="color: #000000; font-weight: bold;">&gt;</span>= <span style="color: #000000;">4</span><span style="color: #7a0874; font-weight: bold;">&#41;</span><span style="color: #7a0874; font-weight: bold;">&#41;</span> ? __builtin_strcmp <span style="color: #7a0874; font-weight: bold;">&#40;</span>rowreq_ctx-<span style="color: #000000; font-weight: bold;">&gt;</span>data.ifentry-<span style="color: #000000; font-weight: bold;">&gt;</span>name, ifentry-<span style="color: #000000; font-weight: bold;">&gt;</span>name<span style="color: #7a0874; font-weight: bold;">&#41;</span> : <span style="color: #7a0874; font-weight: bold;">&#40;</span>__builtin_constant_p <span style="color: #7a0874; font-weight: bold;">&#40;</span>rowreq_ctx-<span style="color: #000000; font-weight: bold;">&gt;</span>data.ifentry-<span style="color: #000000; font-weight: bold;">&gt;</span>name<span style="color: #7a0874; font-weight: bold;">&#41;</span> <span style="color: #000000; font-weight: bold;">&amp;&amp;</span> <span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #7a0874; font-weight: bold;">&#40;</span>size_t<span style="color: #7a0874; font-weight: bold;">&#41;</span><span style="color: #7a0874; font-weight: bold;">&#40;</span>const void <span style="color: #000000; font-weight: bold;">*</span><span style="color: #7a0874; font-weight: bold;">&#41;</span><span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #7a0874; font-weight: bold;">&#40;</span>rowreq_ctx-<span style="color: #000000; font-weight: bold;">&gt;</span>data.ifentry-<span style="color: #000000; font-weight: bold;">&gt;</span>name<span style="color: #7a0874; font-weight: bold;">&#41;</span> + <span style="color: #000000;">1</span><span style="color: #7a0874; font-weight: bold;">&#41;</span> - <span style="color: #7a0874; font-weight: bold;">&#40;</span>size_t<span style="color: #7a0874; font-weight: bold;">&#41;</span><span style="color: #7a0874; font-weight: bold;">&#40;</span>const void <span style="color: #000000; font-weight: bold;">*</span><span style="color: #7a0874; font-weight: bold;">&#41;</span><span style="color: #7a0874; font-weight: bold;">&#40;</span>rowreq_ctx-<span style="color: #000000; font-weight: bold;">&gt;</span>data.ifentry-<span style="color: #000000; font-weight: bold;">&gt;</span>name<span style="color: #7a0874; font-weight: bold;">&#41;</span> == <span style="color: #000000;">1</span><span style="color: #7a0874; font-weight: bold;">&#41;</span> <span style="color: #000000; font-weight: bold;">&amp;&amp;</span> <span style="color: #7a0874; font-weight: bold;">&#40;</span>__s1_len = strlen <span style="color: #7a0874; font-weight: bold;">&#40;</span>rowreq_ctx-<span style="color: #000000; font-weight: bold;">&gt;</span>data.ifentry-<span style="color: #000000; font-weight: bold;">&gt;</span>name<span style="color: #7a0874; font-weight: bold;">&#41;</span>, __s1_len <span style="color: #000000; font-weight: bold;">&lt;</span> <span style="color: #000000;">4</span><span style="color: #7a0874; font-weight: bold;">&#41;</span> ? <span style="color: #7a0874; font-weight: bold;">&#40;</span>__builtin_constant_p <span style="color: #7a0874; font-weight: bold;">&#40;</span>ifentry-<span style="color: #000000; font-weight: bold;">&gt;</span>name<span style="color: #7a0874; font-weight: bold;">&#41;</span> <span style="color: #000000; font-weight: bold;">&amp;&amp;</span> <span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #7a0874; font-weight: bold;">&#40;</span>size_t<span style="color: #7a0874; font-weight: bold;">&#41;</span><span style="color: #7a0874; font-weight: bold;">&#40;</span>const void <span style="color: #000000; font-weight: bold;">*</span><span style="color: #7a0874; font-weight: bold;">&#41;</span><span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #7a0874; font-weight: bold;">&#40;</span>ifentry-<span style="color: #000000; font-weight: bold;">&gt;</span>name<span style="color: #7a0874; font-weight: bold;">&#41;</span> + <span style="color: #000000;">1</span><span style="color: #7a0874; font-weight: bold;">&#41;</span> - <span style="color: #7a0874; font-weight: bold;">&#40;</span>size_t<span style="color: #7a0874; font-weight: bold;">&#41;</span><span style="color: #7a0874; font-weight: bold;">&#40;</span>const void <span style="color: #000000; font-weight: bold;">*</span><span style="color: #7a0874; font-weight: bold;">&#41;</span><span style="color: #7a0874; font-weight: bold;">&#40;</span>ifentry-<span style="color: #000000; font-weight: bold;">&gt;</span>name<span style="color: #7a0874; font-weight: bold;">&#41;</span> == <span style="color: #000000;">1</span><span style="color: #7a0874; font-weight: bold;">&#41;</span> ? __builtin_strcmp <span style="color: #7a0874; font-weight: bold;">&#40;</span>rowreq_c May <span style="color: #000000;">20</span> <span style="color: #000000;">10</span>:<span style="color: #000000;">58</span>:<span style="color: #000000;">43</span> elara snmpd<span style="color: #7a0874; font-weight: bold;">&#91;</span><span style="color: #000000;">3010</span><span style="color: #7a0874; font-weight: bold;">&#93;</span>: netsnmp_assert __extension__ <span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #7a0874; font-weight: bold;">&#123;</span> size_t __s1_len, __s2_len; <span style="color: #7a0874; font-weight: bold;">&#40;</span>__builtin_constant_p <span style="color: #7a0874; font-weight: bold;">&#40;</span>rowreq_ctx-<span style="color: #000000; font-weight: bold;">&gt;</span>data.ifentry-<span style="color: #000000; font-weight: bold;">&gt;</span>name<span style="color: #7a0874; font-weight: bold;">&#41;</span> <span style="color: #000000; font-weight: bold;">&amp;&amp;</span> __builtin_constant_p <span style="color: #7a0874; font-weight: bold;">&#40;</span>ifentry-<span style="color: #000000; font-weight: bold;">&gt;</span>name<span style="color: #7a0874; font-weight: bold;">&#41;</span> <span style="color: #000000; font-weight: bold;">&amp;&amp;</span> <span style="color: #7a0874; font-weight: bold;">&#40;</span>__s1_len = strlen <span style="color: #7a0874; font-weight: bold;">&#40;</span>rowreq_ctx-<span style="color: #000000; font-weight: bold;">&gt;</span>data.ifentry-<span style="color: #000000; font-weight: bold;">&gt;</span>name<span style="color: #7a0874; font-weight: bold;">&#41;</span>, __s2_len = strlen <span style="color: #7a0874; font-weight: bold;">&#40;</span>ifentry-<span style="color: #000000; font-weight: bold;">&gt;</span>name<span style="color: #7a0874; font-weight: bold;">&#41;</span>, <span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #000000; font-weight: bold;">!</span><span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #7a0874; font-weight: bold;">&#40;</span>size_t<span style="color: #7a0874; font-weight: bold;">&#41;</span><span style="color: #7a0874; font-weight: bold;">&#40;</span>const void <span style="color: #000000; font-weight: bold;">*</span><span style="color: #7a0874; font-weight: bold;">&#41;</span><span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #7a0874; font-weight: bold;">&#40;</span>rowreq_ctx-<span style="color: #000000; font-weight: bold;">&gt;</span>data.ifentry-<span style="color: #000000; font-weight: bold;">&gt;</span>name<span style="color: #7a0874; font-weight: bold;">&#41;</span> + <span style="color: #000000;">1</span><span style="color: #7a0874; font-weight: bold;">&#41;</span> - <span style="color: #7a0874; font-weight: bold;">&#40;</span>size_t<span style="color: #7a0874; font-weight: bold;">&#41;</span><span style="color: #7a0874; font-weight: bold;">&#40;</span>const void <span style="color: #000000; font-weight: bold;">*</span><span style="color: #7a0874; font-weight: bold;">&#41;</span><span style="color: #7a0874; font-weight: bold;">&#40;</span>rowreq_ctx-<span style="color: #000000; font-weight: bold;">&gt;</span>data.ifentry-<span style="color: #000000; font-weight: bold;">&gt;</span>name<span style="color: #7a0874; font-weight: bold;">&#41;</span> == <span style="color: #000000;">1</span><span style="color: #7a0874; font-weight: bold;">&#41;</span> <span style="color: #000000; font-weight: bold;">||</span> __s1_len <span style="color: #000000; font-weight: bold;">&gt;</span>= <span style="color: #000000;">4</span><span style="color: #7a0874; font-weight: bold;">&#41;</span> <span style="color: #000000; font-weight: bold;">&amp;&amp;</span> <span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #000000; font-weight: bold;">!</span><span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #7a0874; font-weight: bold;">&#40;</span>size_t<span style="color: #7a0874; font-weight: bold;">&#41;</span><span style="color: #7a0874; font-weight: bold;">&#40;</span>const void <span style="color: #000000; font-weight: bold;">*</span><span style="color: #7a0874; font-weight: bold;">&#41;</span><span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #7a0874; font-weight: bold;">&#40;</span>ifentry-<span style="color: #000000; font-weight: bold;">&gt;</span>name<span style="color: #7a0874; font-weight: bold;">&#41;</span> + <span style="color: #000000;">1</span><span style="color: #7a0874; font-weight: bold;">&#41;</span> - <span style="color: #7a0874; font-weight: bold;">&#40;</span>size_t<span style="color: #7a0874; font-weight: bold;">&#41;</span><span style="color: #7a0874; font-weight: bold;">&#40;</span>const void <span style="color: #000000; font-weight: bold;">*</span><span style="color: #7a0874; font-weight: bold;">&#41;</span><span style="color: #7a0874; font-weight: bold;">&#40;</span>ifentry-<span style="color: #000000; font-weight: bold;">&gt;</span>name<span style="color: #7a0874; font-weight: bold;">&#41;</span> == <span style="color: #000000;">1</span><span style="color: #7a0874; font-weight: bold;">&#41;</span> <span style="color: #000000; font-weight: bold;">||</span> __s2_len <span style="color: #000000; font-weight: bold;">&gt;</span>= <span style="color: #000000;">4</span><span style="color: #7a0874; font-weight: bold;">&#41;</span><span style="color: #7a0874; font-weight: bold;">&#41;</span> ? __builtin_strcmp <span style="color: #7a0874; font-weight: bold;">&#40;</span>rowreq_ctx-<span style="color: #000000; font-weight: bold;">&gt;</span>data.ifentry-<span style="color: #000000; font-weight: bold;">&gt;</span>name, ifentry-<span style="color: #000000; font-weight: bold;">&gt;</span>name<span style="color: #7a0874; font-weight: bold;">&#41;</span> : <span style="color: #7a0874; font-weight: bold;">&#40;</span>__builtin_constant_p <span style="color: #7a0874; font-weight: bold;">&#40;</span>rowreq_ctx-<span style="color: #000000; font-weight: bold;">&gt;</span>data.ifentry-<span style="color: #000000; font-weight: bold;">&gt;</span>name<span style="color: #7a0874; font-weight: bold;">&#41;</span> <span style="color: #000000; font-weight: bold;">&amp;&amp;</span> <span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #7a0874; font-weight: bold;">&#40;</span>size_t<span style="color: #7a0874; font-weight: bold;">&#41;</span><span style="color: #7a0874; font-weight: bold;">&#40;</span>const void <span style="color: #000000; font-weight: bold;">*</span><span style="color: #7a0874; font-weight: bold;">&#41;</span><span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #7a0874; font-weight: bold;">&#40;</span>rowreq_ctx-<span style="color: #000000; font-weight: bold;">&gt;</span>data.ifentry-<span style="color: #000000; font-weight: bold;">&gt;</span>name<span style="color: #7a0874; font-weight: bold;">&#41;</span> + <span style="color: #000000;">1</span><span style="color: #7a0874; font-weight: bold;">&#41;</span> - <span style="color: #7a0874; font-weight: bold;">&#40;</span>size_t<span style="color: #7a0874; font-weight: bold;">&#41;</span><span style="color: #7a0874; font-weight: bold;">&#40;</span>const void <span style="color: #000000; font-weight: bold;">*</span><span style="color: #7a0874; font-weight: bold;">&#41;</span><span style="color: #7a0874; font-weight: bold;">&#40;</span>rowreq_ctx-<span style="color: #000000; font-weight: bold;">&gt;</span>data.ifentry-<span style="color: #000000; font-weight: bold;">&gt;</span>name<span style="color: #7a0874; font-weight: bold;">&#41;</span> == <span style="color: #000000;">1</span><span style="color: #7a0874; font-weight: bold;">&#41;</span> <span style="color: #000000; font-weight: bold;">&amp;&amp;</span> <span style="color: #7a0874; font-weight: bold;">&#40;</span>__s1_len = strlen <span style="color: #7a0874; font-weight: bold;">&#40;</span>rowreq_ctx-<span style="color: #000000; font-weight: bold;">&gt;</span>data.ifentry-<span style="color: #000000; font-weight: bold;">&gt;</span>name<span style="color: #7a0874; font-weight: bold;">&#41;</span>, __s1_len <span style="color: #000000; font-weight: bold;">&lt;</span> <span style="color: #000000;">4</span><span style="color: #7a0874; font-weight: bold;">&#41;</span> ? <span style="color: #7a0874; font-weight: bold;">&#40;</span>__builtin_constant_p <span style="color: #7a0874; font-weight: bold;">&#40;</span>ifentry-<span style="color: #000000; font-weight: bold;">&gt;</span>name<span style="color: #7a0874; font-weight: bold;">&#41;</span> <span style="color: #000000; font-weight: bold;">&amp;&amp;</span> <span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #7a0874; font-weight: bold;">&#40;</span>size_t<span style="color: #7a0874; font-weight: bold;">&#41;</span><span style="color: #7a0874; font-weight: bold;">&#40;</span>const void <span style="color: #000000; font-weight: bold;">*</span><span style="color: #7a0874; font-weight: bold;">&#41;</span><span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #7a0874; font-weight: bold;">&#40;</span>ifentry-<span style="color: #000000; font-weight: bold;">&gt;</span>name<span style="color: #7a0874; font-weight: bold;">&#41;</span> + <span style="color: #000000;">1</span><span style="color: #7a0874; font-weight: bold;">&#41;</span> - <span style="color: #7a0874; font-weight: bold;">&#40;</span>size_t<span style="color: #7a0874; font-weight: bold;">&#41;</span><span style="color: #7a0874; font-weight: bold;">&#40;</span>const void <span style="color: #000000; font-weight: bold;">*</span><span style="color: #7a0874; font-weight: bold;">&#41;</span><span style="color: #7a0874; font-weight: bold;">&#40;</span>ifentry-<span style="color: #000000; font-weight: bold;">&gt;</span>name<span style="color: #7a0874; font-weight: bold;">&#41;</span> == <span style="color: #000000;">1</span><span style="color: #7a0874; font-weight: bold;">&#41;</span> ? __builtin_strcmp <span style="color: #7a0874; font-weight: bold;">&#40;</span>rowreq_c

La Cause

Il existe peu de littérature sur le net à propose de ce message d’erreur. Cependant un bug report existe chez RedHat à propos snmpd. Sur Debian Etch 4.0 la version de snmpd est la 5.2. Upgrader en 5.3 comme préconisé dans la solution a ce bug en compilant le tente moyen moyen.

Quelques messages sur sur les mailling-list de xensource.com rester sans réponse, dont celui ci Problem with dom0 and snmpd.

Solution de contournement

A défaut de pouvoir mettre à jour snmpd, on peux le faire taire. J’ai trouver ici le bon paramètre : Snmpd filling up /var/log/messages. Donc il est possible de limité l’écriture dans les log au chose hyper importante.

Dans /etc/default/snmpd j’ai modifier la ligne suivante.

<span style="color: #808080; font-style: italic;"># SNMPDOPTS='-Lsd -Lf /dev/null -u snmp -I -smux -p /var/run/snmpd.pid'</span>

par

<span style="color: #007800;">SNMPDOPTS=</span><span style="color: #ff0000;">'-LS 0-4 d -Lf /dev/null -u snmp -I -smux -p /var/run/snmpd.pid'</span>

Les paramètres « 0-4 » signifie que les « warning messages », « errors », « alerts » et « critical messages » sont logger par contre tout ce qui est « notice info » et « debug level messages » sont ignoré. Depuis cette modification c’est plus silencieux 🙂

Swatch et Syslog

Comment surveiller plus facilement mon systeme grâce à une utilisation plus fine des log ? Swatch répond facilement et rapidement a cette question. Swatch agie comme grep pour faire des recherche dans les logs. Il en extraie le contenue selectionné avec une présentation plus travaillée que la simple ligne de texte et lance des actions selon vos instruction.

Syslog

Dans une installation de base d’une woody les logs sont distribué dans différent fichiers dans le répertoire /var/log. Ceci à des avantages sur une organisation pour plusieurs personnes différentes on besoin d’accéder au log pour leur propres activités, les développeurs pour débuger leur création, l’administrateur mails pour comprendre pourquoi les chefs de projet du 5ème ne réceptionnent pas les emails de bigboss etc..

Dans mon cas je suis seul maître à bord, personne d’autre que moi n’a besoin des logs. J’ai donc décidé de centraliser mes logs dans deux fichiers seulement :

  1. /var/log/syslog pour l’ensemble des log sauf l’authentification des utilisateur.
  2. /var/log/auth.log pour les logs d’identification des utilisateurs.

Pour cela j’ai reconfigurer mon gestionnaire de log le bien nommé : syslog. Pour cela j’ai changé son fichier de configuration /etc/syslog.conf sans oublier de faire une sauvegarde du fichier original.

J’ai donc renseigné mon fichier de configuration de syslog comme ceci :

auth,authpriv.* /var/log/auth.log
*.*;auth.none;authpriv.none /dev/tty12
*.*;auth.none;authpriv.none /var/log/syslog
texte - 287 octets
syslog.conf
Mon fichiers de configuration de syslog

La première ligne indique d’enregistrer tout ce qui concerne l’identification dans /var/log/auth.log.
La seconde ligne indique d’envoyer tout les logs sauf ceux d’identification sur la console au tty12 (Ctrl+Alt+F12) de l’ordinateur.
La dernière ligne enregistre tout les logs sauf ceux d’identification dans le fichier /var/log/syslog

Installer Swatch

Pour installer swatch on utilise apt comme d’habitude. Prenons d’abord nos marques et recherchons le bon paquet :
apt-cache search swatch

Le résultat nous donne quatre occurrences, dont seul la première est la bonne :

swatch - log file viewer with regexp matching, highlighting, & hooks
swisswatch - the mother of all X Toolkit clocks
wmitime - yet another clock dock app for Window Maker
wmtz - A wmaker dock app that displays the time in different zones.

Comme je suis quelqu’un de prudent je vérifie bien que c’est le logiciel que je recherche et le bon paquetage. Prudence est mère de sureté, je demande donc les informations disponible sur le paquetage trouvé :
apt-cache show swatch

Cette vérification me donne une foule de renseignement dont le fait que la version debian de swatch inclue deux options particulières :

Package: swatch
Priority: optional
Section: admin
Installed-Size: 152
Maintainer: Rene Weber <rene_debmaint@elvenlord.com>
Architecture: all
Version: 3.0.4-1
Depends: perl5, libtimedate-perl, libtime-hires-perl, libdate-calc-perl, libfile-tail-perl
Filename: pool/main/s/swatch/swatch_3.0.4-1_all.deb
Size: 31460
MD5sum: f0e2a697d1ad7752029bd598fcef0988
Description: log file viewer with regexp matching, highlighting, & hooks
Swatch is designed to monitor system activity. It reads a configuration file which contains pattern(s) to look for and action(s) to perform when each pattern is found.

A typical action is echoing the matched line in a variety of colours and formats including reverse video, bold, underline, and normal, which swatch knows how to do internally. Other actions include sending mail or executing an arbitrary program on the line.

Swatch is written in Perl and uses Perl regular expressions for line matching.

This Debian version of swatch includes two directives not yet found in the "official" swatch -- "PERLCODE" and "threshold".

Après avoir montré patte blanche je l’installe :
apt-get install swatch

Swatch est maintenant installé il ne reste qu’a lui créé un fichier de configuration qui le renseignera sur ce qu’il doit rechercher dans les logs et comme il doit présenter le résultat.

swatch.conf

Le fichier de configuration de swatch est d’un syntaxe trés facile pour une utilisation basique. Il peut devenir très puissant et bien plus difficile a construire en utilisant les exprèssions régulière de Perl.

Chaque paragraphe du fichier de configuration débute par la chaine de carractère à rechercher :
watchfor /pattern/. Une pattern est une expression régulière reconnue par Perl (swatch est écrit en Perl). Ces expressions sont similaire à celles utilisée par grep, exemple :
watchfor /file system full/
Cette paterne ou chaîne de caractère correspond à la syntaxe exacte du message d’erreur envoyer dans les log quant une partition est pleine et d’un programme ou le noyau ne peut plus écrire dessus.

On peut aussi remplacer l’instruction watchfor par ignore de façon à pour filtrer des lignes non importantes qui auraient été mise en correspondance avec une chaîne recherché,ceci pour éviter les faux positif.

On informe ensuite de la, où des actions à entreprendre a la découverte de la chaîne recherché. Les principales actions sont les suivantes :

  • echo [mode] : affiche la ligne de logs contenant le motif. Plusieurs modes d’affichage sont disponibles : en couleurs, inversé, en gras…
  • bell [N] : affiche la ligne et fait retentir N fois une cloche
  • exec command : permet d’exécuter une commande. La ligne reconnue peut être fournie en argument de cette commande. les variable suivante sont disponible :
    • $N pour le nombre de champs dans le ligne.
    • $0 or $* pour la ligne en question.
  • mail [addresses=address:address :…][,subject=your_text_here] : permet d’envoyer la ligne et un commentaire à une où plusieurs personnes.
  • throttle hours:minutes:seconds,[use=message|regex] : permet de limiter le nombre de fois que l’action sera effectuée sur un motif reconnu. Cette option est utile pour gérer des logs du type « partition pleine » qui sont enregistrés plusieurs dizaine de fois par minute. Si use=message, la limite sera basé sur le pattern, si use=message, elle sera basée sur le message. continue
  • continue : permet de continuer la recherche de motifs sur la même ligne.
  • write [user:user :…] : permet d’envoyer une message a un utilisateur présent connecter sur la machine. Pratique pour polluer toute les xterm de root en cas d’urgence.
  • quit : Explicite, fin et sortie de swatch.

Chacune de ces actions peut ce voir ajouter les options suivants :

  • when=day_of_week:hour_of_day qui permet de spécifier un intervalle valide pour l’execution de cette action. Par exemple, on n’enverra un mail à l’administarteur du lundi au samedi, entre 8 heure et 17 heure :
    mail=admin@rsr.fr,when=1-6:8-17
  • threshold events:seconds,[repeat=no|yes]. Cette option limite l’action d’apres le nombre de fois ou une parterne est trouver durant une ériode précise. Par exemple :
    threshold 4:60"
    L’action ne sera réalisée que si la chaîne de caractère a été trouvée 4 fois dans les 60 dernière secondes. C’est je pense pratique pour les attaques en « brute force » ou les « flood ».
  • PERLCODE : Pour l’insertion de code Perl, les fameuses expression régulière. Cela permet entre autre la supstitution de variable comme dans cette exemple sur le nom des machines ce connectant en ppp sur votre serveur :
    PERLCODE=$syslog='^[A-Z][a-z]{2} [0-9]+([0-9]+:){2}[0-9]+';
    watchfor /${syslog} hostname pppd/

Attention au point virgule en fin de commande en Perl !

Re-voici notre exemple d’une entrée de fichier de configuration swatch :

watchfor /file system full/
echo bold
bell 3
throttle 01:00

Dans cet exemple les lignes de logs contenant le motif « file system full » seront affichées en gras et accompagnées de 3 sonneries. Seule une instance de ce message sera affichée par minute

watchfor /friends/
echo exec "play /home/agemis/Mail/.mail.wav"

Maintenant dans cet exemple chaque fois que le mot friends est trouver un fichier son est joué : you got a mail

watchfor /authentication failure/
echo bold, yellow, threshold 10:120
write root:admin, threshold 10:120
mail addresses=admin,subject=--- 10 wrong in last 2 minutes [user] ---, threshold 10:120
bell 5, threshold 10:120

Alors plus fort encore, ici en cas d’une identification rater les actions qui suive sont lancer mais uniquement si c’est la 10 fois que la chaîne de caractère est trouvé dans les deux dernière minutes.
Les actions sont :

    • Affichage de la ligne trouvée en gras et jaune
    • Envois d’une message sur les consoles ouvertes d’Admin et root
    • Envois d’un mail a admin
    • Cinq sonneries

J’ai regrouper les chaînes de caractères sensible que je connais avec différentes façons de gérer les alarmes dans un gros fichier de configuration. A vous de prendre exemple dessus ou de créé vos propre règle en fonction de vos besoins.

texte - 5.1 ko
swatch.conf
Fichier de configuration de conf

Utilisation de swatch

Il existe trois modes d’utilisation différents de swatch utilisable selon les besoins :

Pour inspecter en continue la queue d’un fichier de log afin de réagir au dernière ligne créées.
--tail-file=nom-de-fichier ou -t nom-de-fichier
Ce mode de fonctionnement est celui que j’utilise que j’affectionne. Il est facile ainsi de garder un xterm ouvert avec swatch de lancer, affichant à fur et à mesure les alertes. Le ligne de commande est donc :
swatch -c /etc/swatch.conf -t /var/log/syslog

Pour vérifier ou re-vérifier l’intégralité du fichier log pour avoir un historique des évènements.
--examine=nom-de-fichier ou -f nom-de-fichier
Ce mode de fonctionnement est parfais pour reprendre le fil des évènements suite a un crash ou simplement après une nuit de sommeil. La ligne de commande est donc :
swatch -c /etc/swatch.conf -f /var/log/syslog

Pour récupérer la sortie (STDOUT) d’un autre programme.
--read-pipe=nom-de-fichier ou -p nom-de-fichier Je ne connais pas d’exemple d’utilisation de ce mode, il est toujours possible d’avoir un service précis qui écrive les logs sur sa sortie standard. Un hack est aussi possible pour créé de toute pièce l’écriture sur le STDOUT dans le cas d’un service particulièrement sollicité. Voici un exemple pour tester ce mode :
swatch -c /etc/swatch.conf -p 'tail -f /var/log/syslog'
Noter que cette exemple n’apporte rien par rapport au premier mode expliqué.

Documentation

Softpanorama dossier « log auditing »
Syslog for the datacenter
Linux journal
Docmaster