Dans cet article, je vais vous présenter une solution pour envoyer l’ensemble des commandes exécutées avec le shell bash sur un serveur syslog distant. Cette option est possible en utilisant la variable d’environnement PROMPT_COMMAND ou nativement avec bash à condition de le recompiler. C’est cette deuxième solution que je vais vous présenter avec deux alternatives : recompiler bash et l’installer directement depuis les sources ou modifier le paquet Debian. Nous verrons également une configuration rsyslog client/serveur pour centraliser tous vos logs à un seul endroit.
Installer bash depuis les sources
Compilation de bash avec syslog
Voici les étapes nécessaires pour compiler bash 4.2 sur une Debian Squeeze :
- Installez le paquet build-essential.
- Récupérez les sources de bash :
wget ftp://ftp.gnu.org/gnu/bash/bash-4.2.tar.gz
- Décompressez l’archive et placez vous dans le répertoire de bash :
tar xvf bash-4.2.tar.gz && cd bash-4.2
- Créez un répertoire patchs et récupérez l’ensemble des patchs disponibles pour bash 4.2 :
mkdir patchs && cd patchs
ncftpget ftp://ftp.gnu.org/gnu/bash/bash-4.2-patches/bash42-???
cd ..
- Depuis la racine des sources, patchez bash avec tous ces patchs :
for p in patchs/*
do
patch -p0 < ${p}
done
- Éditez le fichier config-top.h pour décommenter la ligne
/* #define SYSLOG_HISTORY */
(tout en bas). - Vous pouvez ensuite compiler bash avec les options de votre choix. Par exemple, les options de compilation du paquet Debian :
./configure --with-curses --enable-largefile --prefix=/usr --infodir=/usr/share/info --mandir=/usr/share/man --enable-static-link --without-bash-malloc --bindir=/bin --host=`dpkg-architecture -qDEB_HOST_GNU_TYPE`
- Reste à lancer la compilation :
make && make install
Rajouter des diversions
Pour éviter d’écraser les fichiers du paquet bash ou au contraire d’avoir la version de bash syslog écrasé par un upgrade du paquet, vous pouvez utiliser des diversions. Avant de faire le make install
, lancez cette boucle qui va créer les diversions nécessaires :
DIVERT_FILES="/bin/bash
/usr/share/locale/en@quot/LC_MESSAGES/bash.mo
/usr/share/locale/af/LC_MESSAGES/bash.mo
/usr/share/locale/id/LC_MESSAGES/bash.mo
/usr/share/locale/tr/LC_MESSAGES/bash.mo
/usr/share/locale/fi/LC_MESSAGES/bash.mo
/usr/share/locale/eo/LC_MESSAGES/bash.mo
/usr/share/locale/lt/LC_MESSAGES/bash.mo
/usr/share/locale/pl/LC_MESSAGES/bash.mo
/usr/share/locale/vi/LC_MESSAGES/bash.mo
/usr/share/locale/ru/LC_MESSAGES/bash.mo
/usr/share/locale/de/LC_MESSAGES/bash.mo
/usr/share/locale/ca/LC_MESSAGES/bash.mo
/usr/share/locale/pt_BR/LC_MESSAGES/bash.mo
/usr/share/locale/et/LC_MESSAGES/bash.mo
/usr/share/locale/sv/LC_MESSAGES/bash.mo
/usr/share/locale/fr/LC_MESSAGES/bash.mo
/usr/share/locale/zh_TW/LC_MESSAGES/bash.mo
/usr/share/locale/ga/LC_MESSAGES/bash.mo
/usr/share/locale/es/LC_MESSAGES/bash.mo
/usr/share/locale/en@boldquot/LC_MESSAGES/bash.mo
/usr/share/locale/hu/LC_MESSAGES/bash.mo
/usr/share/locale/nl/LC_MESSAGES/bash.mo
/usr/share/locale/ro/LC_MESSAGES/bash.mo
/usr/share/locale/sk/LC_MESSAGES/bash.mo
/usr/share/locale/ja/LC_MESSAGES/bash.mo
/usr/share/locale/cs/LC_MESSAGES/bash.mo
/usr/share/locale/bg/LC_MESSAGES/bash.mo"
for file in $DIVERT_FILES
do
dpkg-divert -package "bash-syslog" -add -rename -divert ${file}_debian ${file}
done
Grâce à ces diversions, les fichiers originaux sont renommés en _debian et une mise à jour du paquet bash ne risque pas de modifier votre installation manuelle.
Si vous souhaitez revenir au bash standard, faites un make uninstall
et relancez la boucle précédente avec cette fois un remove
des diversions :
for file in $DIVERT_FILES
do
dpkg-divert -package "bash-syslog" -remove -rename -divert ${file}_debian ${file}
done
Modifier le paquet Debian
C’est à mon avis la meilleure solution : pas de risque de voir ses modifications écrasées par la mise à jour du paquet, pas besoin de faire des diversions mais pour rester simple, il faudra utiliser la version de la distribution. Les étapes nécessaires à partir d’une Debian Squeeze :
- Modifiez votre sources.list pour rajouter les paquets sources :
# deb-src
deb-src http://ftp.fr.debian.org/debian/ squeeze main contrib non-free
- Après un
apt-get update
, récupérez le paquet source bash avec unapt-get source bash
après vous être placé dans le répertoire /usr/local/src. - Installez également le paquet devscripts qui contient les outils nécessaires à la création de paquets Debian ainsi que toutes les dépendances liées à la compilation de bash :
apt-get install devscripts
apt-get build-dep bash
- Dans le répertoire créé, bash-4.1 à l’écriture de cet article, il y a un répertoire debian. Il faut rajouter un patch dans le répertoire patches et modifier le fichier rules utilisé pour la construction du paquet. Placez vous dans l’arborécence bash-4.1/debian/patches et créez le fichier enable-syslog.dpatch avec pour contenu :
for file in $DIVERT_FILES
do
dpkg-divert -package "bash-syslog" -remove -rename -divert ${file}_debian ${file}
done
Modifier le paquet Debian
C’est à mon avis la meilleure solution : pas de risque de voir ses modifications écrasées par la mise à jour du paquet, pas besoin de faire des diversions mais pour rester simple, il faudra utiliser la version de la distribution. Les étapes nécessaires à partir d’une Debian Squeeze :
- Modifiez votre sources.list pour rajouter les paquets sources :
# deb-src
deb-src http://ftp.fr.debian.org/debian/ squeeze main contrib non-free
- Après un
apt-get update
, récupérez le paquet source bash avec unapt-get source bash
après vous être placé dans le répertoire /usr/local/src. - Installez également le paquet devscripts qui contient les outils nécessaires à la création de paquets Debian ainsi que toutes les dépendances liées à la compilation de bash :
apt-get install devscripts
apt-get build-dep bash
- Dans le répertoire créé, bash-4.1 à l’écriture de cet article, il y a un répertoire debian. Il faut rajouter un patch dans le répertoire patches et modifier le fichier rules utilisé pour la construction du paquet. Placez vous dans l’arborécence bash-4.1/debian/patches et créez le fichier enable-syslog.dpatch avec pour contenu :
#! /bin/sh -e
if [ $# -eq 3 -a "$2" = '-d' ]; then
pdir="-d $3"
elif [ $# -ne 1 ]; then
echo >&2 "`basename $0`: script expects -patch|-unpatch as argument"
exit 1
fi
case "$1" in
-patch) patch $pdir -f --no-backup-if-mismatch -p1 < $0;;
-unpatch) patch $pdir -f --no-backup-if-mismatch -R -p1 < $0;;
*)
echo >&2 "`basename $0`: script expects -patch|-unpatch as argument"
exit 1
esac
exit 0
# DP: enable syslog
--- bash/config-top.h~ 2012-09-04 23:09:48.000000000 +0200
+++ bash/config-top.h 2012-09-04 23:09:59.000000000 +0200
@@ -101,7 +101,7 @@
/* Define if you want each line saved to the history list in bashhist.c:
bash_add_history() to be sent to syslog(). */
-/* #define SYSLOG_HISTORY */
+#define SYSLOG_HISTORY */
#if defined (SYSLOG_HISTORY)
# define SYSLOG_FACILITY LOG_USER
# define SYSLOG_LEVEL LOG_INFO
Vous pouvez également changer la facilité et le niveau d’alerte syslog. Par exemple pour utiliser la facilité local1, changez :
# define SYSLOG_FACILITY LOG_USER
en
# define SYSLOG_FACILITY LOG_LOCAL1
- Dans le répertoire bash-4.1/debian, éditez le fichier rules. Il faut rajouter notre patch à la liste des patchs à appliquer aux sources de bash : recherchez la variable
debian_patches
(à la ligne 500 pour bash-4.1). Rajoutez à la suite des patchsenable-syslog
. - Il faut ensuite générer ce nouveau paquet bash. Placez-vous dans le répertoire racine du paquet source bash-4.1. Pour éviter qu’il rentre en conflit avec celui livré par Debian, on rajoute un suffixe à la version du paquet ainsi qu’un petit commentaire pour le changelog du paquet :
dch --local +syslog "Enable syslog"
- On lance la fabrication du paquet avec
debuild -us -uc
. - C’est terminé : votre nouveau paquet est disponible dans /usr/local/src. Vous pouvez l’installer simplement avec
dpkg -i bash_4.1-3+syslog1_*.deb
.
Configurer Rsyslog
Après avoir installé votre nouveau bash, relancez un bash ou reconnectez vous sur votre serveur pour utiliser la nouvelle version. Après quelques commandes, vérifiez votre /var/log/syslog. Vous obtenez l’historique bash au format suivant :
Sep 4 23:46:30 test-bash -bash: HISTORY: PID=26396 UID=0 htop
Sep 4 23:46:33 test-bash -bash: HISTORY: PID=26396 UID=0 last
Sep 4 23:46:40 test-bash -bash: HISTORY: PID=26396 UID=0 ll /etc/
Sep 4 23:46:43 test-bash -bash: HISTORY: PID=26396 UID=0 less /var/log/syslog
Si vous souhaitez centraliser vos logs sur un serveur, il faut modifier la configuration rsyslog de votre client et de votre serveur.
Sur le client
Rajoutez le fichier /etc/rsyslog.d/bash-history.conf avec pour contenu :
# remplacez mon_loghost par l'@ip de votre serveur syslog
user.info @mon_loghost
Relancez ensuite rsyslog : service rsyslog restart
.
Sur le serveur
Sur votre serveur syslog, créez un fichier /etc/rsyslog.d/all-bash-history.conf avec le contenu suivant :
$template BashLogs,"/var/log/bash-history/history_%HOSTNAME%.log"
user.info ?BashLogs
& ~
Relancez ensuite rsyslog comme pour le client après avoir créé le répertoire /var/log/bash-history : service rsyslog restart
. Le répertoire /var/log/bash-history contiendra un fichier de log par serveur. Dans mon cas, j’obtiens le fichier /var/log/bash-history/history_test-bash.log qui contient :
Sep 4 23:55:46 192.168.1.10 -bash: HISTORY: PID=26396 UID=0 less /var/log/syslog
Sep 4 23:55:48 192.168.1.10 -bash: HISTORY: PID=26396 UID=0 top
Sep 4 23:58:14 192.168.1.10 -bash: HISTORY: PID=26396 UID=0 service rsyslog restart
Pour info, le - devant bash dans vos logs indique qu’il s’agît d’un shell de login.
J’espère que cet article sera utile à ceux qui cherchent un moyen de centraliser et d’auditer toutes les commandes exécutées sur un ensemble de serveurs. Bons tests 😉