5 juillet 2011
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
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 :
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?
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′
>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?
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
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?
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.
>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?
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.
>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
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