Consolidation des logs avec rsyslog, MySQL et LogAnalyser

Debian Lenny et Wheezy, Ubuntu Server 10.04

Dès qu’on a plus d’un serveur à gérer il est intéressant de pouvoir centraliser les logs des différentes machines pour en simplifier l’administration. C’est relativement facile avec rsyslog. Ce mini tuto va nous permettre de monter un serveur de logs sous Debian, les logs étant stockées dans une base MySQL.

Configuration du serveur de logs

Si ce n’est pas encore fait, installer et configurer les paquets mysql-client et mysql-server. On installe ensuite les paquets requis par rsyslog :

aptitude install rsyslog rsyslog-doc rsyslog-mysql

La configuration de rsyslog-mysql se fait automatiquement à la fin de l’installation par dbconfig. Avec les options par défaut on aboutit à la création d’une base MySQL nommée Syslog, contenant 2 tables SystemEvents et SystemEventsProperties. L’utilisateur rsyslog@localhost aura le contrôle total sur cette base. Ces informations de connexion sont stockées dans /etc/rsyslog.d/mysql.conf :

### Configuration file for rsyslog-mysql
### Changes are preserved
 
$ModLoad ommysql
*.* :ommysql:localhost,Syslog,rsyslog,motdepasse

On active ensuite la réception des logs distantes en éditant /etc/rsyslog.conf et en décommentant les lignes correspondantes :

# provides UDP syslog reception
$ModLoad imudp
$UDPServerRun 514
 
# provides TCP syslog reception
$ModLoad imtcp
$InputTCPServerRun 514

On redémarre le démon rsyslog :

/etc/init.d/rsyslog restart

Le serveur est maintenant configuré pour enregistrer les logs dans la base, et il écoute sur le port 514 les messages entrant. On peut vérifier que la table MySQL est bien alimentée avec les logs locales :

mysql -u rsyslog -p -Bsr -e "SELECT Message FROM SystemEvents LIMIT 0,20" Syslog

Attention, si le serveur de logs se trouve derrière un routeur, il faudra penser a activer les règles NAT qui vont bien (redirection du traffic UDP et TCP 514->514 vers le serveur de logs).

Configuration des serveurs distants

Il faut maintenant configurer les autres serveurs pour qu’ils envoient leurs logs au serveur de log. Dans l’exemple j’utilise ici aussi rsyslog mais ça fonctionne aussi avec syslog ou syslog-ng (avec un paramétrage différent).

Installation du paquet :

aptitude install rsyslog

Création d’un répertoire de travail

mkdir /var/spool/rsyslog

On ajoute les lignes suivantes à la fin du fichier /etc/rsyslog.conf (adapter l’adresse du serveur ;-)):

# Envoi des logs au serveur de logs
$WorkDirectory /var/spool/rsyslog  # default location for work (spool) files
$ActionQueueType LinkedList   # use asynchronous processing
$ActionQueueFileName srvrfwd  # set file name, also enables disk mode
$ActionResumeRetryCount -1    # infinite retries on insert failure
$ActionQueueSaveOnShutdown on # save in-memory data if rsyslog shuts down
*.*       @@adresse.du.serveur.de.logs:514

On redémarre le démon, et c’est tout :

/etc/init.d/rsyslog restart

Installation de LogAnalyser

Retour au serveur de logs pour installer l’interface web Adiscon LogAnalyser qui va nous permettre de visualiser et d’analyser nos messages syslog. On suppose qu’un serveur Apache et PHP 5 sont déjà installés sur le serveur. A l’heure où j’écris la dernière version stable de LogAnalyser est la 3.2.1.

Téléchargement et décompression de l’archive:

wget http://download.adiscon.com/loganalyzer/loganalyzer-3.2.1.tar.gz
tar -xvzf loganalyzer-3.2.1.tar.gz

On crée un répertoire loganalyser à la racine du serveur web:

mkdir /var/www/loganalyser

On copie les fichiers LogAnalyser requis dans ce répertoire:

cp -a loganalyzer-3.2.1/src/* /var/www/loganalyser

On rend le user Apache propriétaire du dossier:

chown -R www-data:www-data /var/www/loganalyser

Avec un navigateur on se rend ensuite à l’adresse http://adresse.du.serveur.de.logs/loganalyser et on configure LogAnalyser en suivant les instructions de l’assistant.
Consulter le fichier /var/www/loganalyser/INSTALL pour des instructions détaillées si besoin.

Une remarque pour conclure, la table MySQL SystemEvents peut se remplir rapidement et devenir très volumineuse. Un petit script de purge placé en cron permettra d’éviter les mauvaises surprises:

#!/bin/bash
# Purge mensuelle des logs de la base MySQL Syslog
RETENTION=180 # Durée de rétention des logs (en jours)
# Initialisation variables
SCRIPT="${0##*/}"
SCRIPT="${SCRIPT%%.*}"
MYSQL_HOST="localhost"
MYSQL_DB="Syslog"
MYSQL_USER="rsyslog"
MYSQL_PASSWD="mot_de_passe"
TMP_LOG="/tmp/$SCRIPT.log"
LOG_DIR="/var/log"
LOG_FILE="$SCRIPT.log"
ADMIN=root
 
echo "+++$(date) Debut $SCRIPT" > $TMP_LOG
echo "(I) Purge des logs antérieures à $RETENTION jours" >> $TMP_LOG
# Fonction sortie du script
sortie() {
	# Enregistre la fin de traitement dans la log
	echo "+++$(date) Fin $SCRIPT" >> $TMP_LOG
	cat $TMP_LOG >> $LOG_DIR/$LOG_FILE
	if [ $1 = 0 ]; then
	  mail -s "Rapport $SCRIPT" $ADMIN < $TMP_LOG
	else
	  mail -s "Erreur execution $SCRIPT" $ADMIN < $TMP_LOG
	fi
	rm -f $TMP_LOG
	exit $1
}
# Comptage des enregistrements à supprimer
sql="SELECT COUNT(*) FROM SystemEvents WHERE DATEDIFF(NOW(), DeviceReportedTime) > $RETENTION"
compteur=`mysql -h $MYSQL_HOST -u $MYSQL_USER -p$MYSQL_PASSWD -e "$sql" -B -s $MYSQL_DB`
if [ "$compteur" = "0" ]; then
	echo "(I) Il n'y a pas d'enregistrements plus vieux que $RETENTION jours" >> $TMP_LOG
else
	echo "(I) Il y a $compteur enregistrements à supprimer" >> $TMP_LOG
	# Suppression des enregistrements MySQL
	sql="DELETE FROM SystemEvents WHERE DATEDIFF(NOW(), DeviceReportedTime) > $RETENTION"
	mysql -h $MYSQL_HOST -u $MYSQL_USER -p$MYSQL_PASSWD -e "$sql" -B -s $MYSQL_DB
	cr=$?
	if [ $cr -gt 0 ]; then
		echo "(E) Erreur lors de la suppression des enregistrements. Code retour $cr" >> $TMP_LOG
		sortie 1
	else
		echo "(I) L'opération s'est déroulée correctement" >> $TMP_LOG
	fi
fi
sortie 0

Edit du 8 mars 2012
Voir ce billet pour les optimisations de la base MySQL.

Liens

Using the syslog receiver module
Reliable Forwarding of syslog Messages with Rsyslog
Writing syslog messages to MySQL

No votes yet.
Please wait...

10 réactions sur “Consolidation des logs avec rsyslog, MySQL et LogAnalyser”

  1. François

    Bonjour Bernard,
    c’est une bonne idée si toutes les bases du serveur sont en utf-8. Pour moi le chemin du fichier de config global est /etc/mysql/my.cnf
    S’il y a d’autres bases qui utilisent le jeu de caractères par défaut de MySQL, une solution serait peut-être de changer le jeu de caractères des tables concernées, par exemple :

    ALTER TABLE SystemEvents DEFAULT CHARACTER SET utf8

    Je ne peux (mal)heureusement pas tester si ça fonctionne, chez moi tous les messages syslog sont en anglais. Je sais, je suis lâche.

    Edit: Je viens de voir qu’il y a un « Default Character Encoding » dans LogAnalyser. Ça ne suffirais pas?

    No votes yet.
    Please wait...
  2. LE TRAON

    Un petit plus pour RSYSLOG et la prise en compte des message syslog émis en langue française.
    Ajouter dans /etc/mysqldmy.cnf dans la ligne dans la section
    [mysqld]
    init_connect=’SET NAMES utf8′

    No votes yet.
    Please wait...
  3. François

    >adrienIT
    Bonjour,
    heureux d’apprendre que ce vieux post continue à rendre service 😉
    Pour ssh je n’ai pas rencontré ce problème, est-ce que les logs ssh apparaissent bien dans /var/log/auth.log?

    No votes yet.
    Please wait...
  4. adrienIT

    Bonjour,

    Désolé de deterrer ce post ^^
    Merci pour votre tuto qui m’a ete d’une grande aide. Sauriez vous me dire pourquoi les logs ssh ne s’affiche pas dans loganalyzer ? tous mes .conf sont identiques aux votre. Cordialement (je suissous debian 7 avec loganalyzer 3.6.6

    No votes yet.
    Please wait...
  5. François

    Bizarre, bizarre… J’ai un ubuntu server 10.04 qui envoie ses logs sans histoire, avec le paramétrage décrit dans le tuto. Tu n’aurais pas un firewall sur ton serveur de logs qui filtre le port 514? Pas de message dans syslog au démarrage de rsyslog?

    No votes yet.
    Please wait...
  6. Thomas

    C’est sur un réseau local (LAN)
    Pour le moment uniquement séparé par un switch administrable, les deux machines se voient (ping)
    J’ai installé sur un ubuntu 12.04 server le rsyslog et je l’ai configuré comme dans le tuto
    Ca fonctionne bien en local, j’ai bien mes logs qui apparaissent (je peux les consulter depuis le lan sur le serveur web de la machine)
    Concernant les serveurs distants j’ai essayé avec ubuntu server 8.04 LTS en installant rsyslog et en rajoutant les lignes indiqués à la fin du fichier /etc/rsyslog.conf, (et en complétant avec l’adresse ip de mon serveur rsyslog) et j’ai essayé la même manipulation avec un ubuntu desktop 12.04 mais rien n’y fait.

    No votes yet.
    Please wait...
  7. François

    >Thomas
    Il faudrait que tu m’en dises un peu plus sur ta config. Tout en réseau local ou pas? Tu as bien ouvert les ports sur le(s) firewall(s) et fait les redirections NAT éventuelles si tu es derrière un routeur?

    No votes yet.
    Please wait...
  8. Thomas

    Bonjour,
    Merci pour ce tuto, pour ma part la partie local fonctionne très bien autant au niveau rsyslog qu’avec loganaliser, mais je n’arrive pas à recevoir des logs de serveurs distant.
    Sur mon serveur linux ubuntu en version 8.04 LTS, j’ai installé rsyslog, et configuré comme indiqué, sur mon serveur client en local, mes logs se remplisse mais rien n’est envoyé.
    Une idée sur le soucis?
    Merci d’avance.

    No votes yet.
    Please wait...
  9. François

    >vilsafur
    Désolé de la réponse tardive, d’autant que je ne me suis pas penché sur la question. Il te faudrait un soft qui convertit les évènements Windows en logs syslog et les envoie à ton serveur rsyslog, un petit coup de Google m’a ramené quelques pistes que tu pourrais explorer, attention tout n’est pas freeware :
    NTsyslog
    Snare
    EventReporter

    No votes yet.
    Please wait...
  10. vilsafur

    Bonjour,

    Merci pour ton tuto ainsi que celui sur l’optimisation de loganalyser.

    Cependant j’ai une petite question, comment rapatrier les logs des systèmes windows sur le serveur rsyslog mis en place?

    merci d’avance pour ta réponse

    No votes yet.
    Please wait...

Laisser une réponse